diff --git a/pec930_sdk-v1.0.1/.DS_Store b/pec930_sdk-v1.0.1/.DS_Store new file mode 100644 index 0000000..f2a4265 Binary files /dev/null and b/pec930_sdk-v1.0.1/.DS_Store differ diff --git a/pec930_sdk-v1.0.1/.gitignore b/pec930_sdk-v1.0.1/.gitignore new file mode 100644 index 0000000..08e1437 --- /dev/null +++ b/pec930_sdk-v1.0.1/.gitignore @@ -0,0 +1,110 @@ +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf +*.depend +*.layout +obj/* +bin/* +*.tar +*.bit +*.ltx +*.rpt +*.7z +*.gz +*cscope* +GPATH +GRTAGS +GTAGS +ID +tags +*.axf +*.iex +*.uvguix.* +*.uvoptx +*.crf +*.htm +*.lnp +*.dep +*.bin +*.lst +*.list +*.swp +*.swo +*.txt +*.depend +*.elay +*.Bak +*.scvd +**/Project.sct +**/JLinkLog.txt +*.log +*.orig +**/~$* +*.sct +*.target_clock +**/JLinkSettings.ini +**/Dbg_RAM.ini +**/SVD/*.h +*.SFR +*.sfd +*.pack +**/pack/* +**/out/* +**/output/* +*_org* +*~ +**/.cache/ +**/Debug/ +**/Release/ +**/.metadata/ +**/.settings/ + diff --git a/pec930_sdk-v1.0.1/Apps/.DS_Store b/pec930_sdk-v1.0.1/Apps/.DS_Store new file mode 100644 index 0000000..da1056f Binary files /dev/null and b/pec930_sdk-v1.0.1/Apps/.DS_Store differ diff --git a/pec930_sdk-v1.0.1/Apps/app_demo_project/.DS_Store b/pec930_sdk-v1.0.1/Apps/app_demo_project/.DS_Store new file mode 100644 index 0000000..79b2fa4 Binary files /dev/null and b/pec930_sdk-v1.0.1/Apps/app_demo_project/.DS_Store differ diff --git a/pec930_sdk-v1.0.1/Apps/app_demo_project/.cproject b/pec930_sdk-v1.0.1/Apps/app_demo_project/.cproject new file mode 100644 index 0000000..364917a --- /dev/null +++ b/pec930_sdk-v1.0.1/Apps/app_demo_project/.cproject @@ -0,0 +1,309 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Apps/app_demo_project/.project b/pec930_sdk-v1.0.1/Apps/app_demo_project/.project new file mode 100644 index 0000000..d82ec1b --- /dev/null +++ b/pec930_sdk-v1.0.1/Apps/app_demo_project/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-2-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-2-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-2-PROJECT_LOC/Tools/scripts/Profiles + + + + + 1762843010815 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Apps/app_demo_project/Project.nuproject b/pec930_sdk-v1.0.1/Apps/app_demo_project/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Apps/app_demo_project/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Apps/app_demo_project/component.mk b/pec930_sdk-v1.0.1/Apps/app_demo_project/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Apps/app_demo_project/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Apps/app_demo_project/inc/isr.h b/pec930_sdk-v1.0.1/Apps/app_demo_project/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Apps/app_demo_project/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Apps/app_demo_project/inc/main.h b/pec930_sdk-v1.0.1/Apps/app_demo_project/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Apps/app_demo_project/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Apps/app_demo_project/readme.md b/pec930_sdk-v1.0.1/Apps/app_demo_project/readme.md new file mode 100644 index 0000000..d4feae0 --- /dev/null +++ b/pec930_sdk-v1.0.1/Apps/app_demo_project/readme.md @@ -0,0 +1,8 @@ +demo_project +--- + +This example is a demo project to descript `how to log message` + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. diff --git a/pec930_sdk-v1.0.1/Apps/app_demo_project/src/isr.c b/pec930_sdk-v1.0.1/Apps/app_demo_project/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Apps/app_demo_project/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Apps/app_demo_project/src/main.c b/pec930_sdk-v1.0.1/Apps/app_demo_project/src/main.c new file mode 100644 index 0000000..7c42930 --- /dev/null +++ b/pec930_sdk-v1.0.1/Apps/app_demo_project/src/main.c @@ -0,0 +1,67 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= +uint32_t __FASTCODE fastcode_proc(void) +{ + log_color(SLOG_CYAN, "run at fast area: $pc= x%08X\n", (uint32_t)&fastcode_proc); + return 0; +} + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("This is a app demo project\n"); + msg("log debug message: $pc= x%08X\n", __get_pc()); + log_color(SLOG_GREEN, "color green\n"); + log_color(SLOG_YELLOW, "color yellow\n"); + + fastcode_proc(); + + while(1) + { + __NOP(); + } + return 0; +} diff --git a/pec930_sdk-v1.0.1/CHANGELOG.md b/pec930_sdk-v1.0.1/CHANGELOG.md new file mode 100644 index 0000000..45e98b9 --- /dev/null +++ b/pec930_sdk-v1.0.1/CHANGELOG.md @@ -0,0 +1,36 @@ +# CHANGELOG +--- + +## v1.0.1 + +### Bug Fixes + ++ [PWR] Support to focus a wake-up type ++ [PWR] Review the configuration flow of wake-up with interrupt signal ++ [LPTIM] Fix reset flow when init and deinit + +### Features + ++ [ALL] Modify project files to involve libSysDev_PEC930.a ++ [ICE] Add an example of Unlock-ICE mechanism + +## v1.0.0 + +### Bug Fixes + ++ [LVD] Fix function name to call lvd driver ++ [GPIO] Fix the configuration of interrupt ++ [I2C] Add disable interrupt when deinit function ++ [WDG] Refactor hal-driver and examples for friendly usage ++ [AMISC] Review the configuration of voltage source of HSI ++ [UART] Delete dummy register field of UART ++ [GPIO] Fix configuration when disable interrupt ++ [AMISC] Fix the configuration of V15 output of hal-driver ++ [ADC] delete clock divider option to fit hardware limitation + +### Features + ++ [SPI] Add examples of interrupt of SPI master and slave ++ [COMP] Add example and hal-driver of COMP + +## v1.0.0-RC1 diff --git a/pec930_sdk-v1.0.1/Common/common.mk b/pec930_sdk-v1.0.1/Common/common.mk new file mode 100644 index 0000000..7e52ce6 --- /dev/null +++ b/pec930_sdk-v1.0.1/Common/common.mk @@ -0,0 +1,16 @@ +# +# common Makefile +# + + + +C_SOURCES += \ + $(srctree)/Common/printf.c \ + $(srctree)/Common/syslog.c + +C_INCLUDES += -I$(srctree)/Common + + +CFLAGS += +CXXFLAGS += +LDFLAGS += diff --git a/pec930_sdk-v1.0.1/Common/hal_conf.h b/pec930_sdk-v1.0.1/Common/hal_conf.h new file mode 100644 index 0000000..cf71351 --- /dev/null +++ b/pec930_sdk-v1.0.1/Common/hal_conf.h @@ -0,0 +1,192 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_conf.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/10 + * @license + * @description + */ + +#ifndef __hal_conf_H_wV9UWaWV_lh0O_HTIV_ssSG_umphyc0TVXKd__ +#define __hal_conf_H_wV9UWaWV_lh0O_HTIV_ssSG_umphyc0TVXKd__ + +#ifdef __cplusplus +extern "C" { +#endif + + +//============================================================================= +// Constant Definition +//============================================================================= +/** + * Uncomment 'USE_FULL_ASSERT' to expanse the "assert_param" macro + * in the HAL drivers code + * ps. User should implement the funciton + * 'void assert_failed(char *func, uint32_t line)' at applicaion layer + */ +// #define USE_FULL_ASSERT 1 + +/** + * The list of modules to be used in the HAL drivers + */ +#define CONFIG_ENABLE_HAL_SYSCFG +#define CONFIG_ENABLE_HAL_PWR +#define CONFIG_ENABLE_HAL_FLASH +#define CONFIG_ENABLE_HAL_GPIO +#define CONFIG_ENABLE_HAL_UART +#define CONFIG_ENABLE_HAL_I2C +#define CONFIG_ENABLE_HAL_SPI +#define CONFIG_ENABLE_HAL_LPTIM +#define CONFIG_ENABLE_HAL_TIM0 +#define CONFIG_ENABLE_HAL_TIM1 +#define CONFIG_ENABLE_HAL_TIM2 +#define CONFIG_ENABLE_HAL_WDG +#define CONFIG_ENABLE_HAL_ADC +#define CONFIG_ENABLE_HAL_AMISC +#define CONFIG_ENABLE_HAL_COMP +#define CONFIG_ENABLE_HAL_OPAMP +#define CONFIG_ENABLE_HAL_CRC +#define CONFIG_ENABLE_HAL_DSP +#define CONFIG_ENABLE_HAL_EPWM + +/** + * System-clock Definition + */ +#if !defined(SYS_HIRC_VALUE) +#define SYS_HIRC_MHZ (60ul) +#define SYS_HIRC_VALUE (SYS_HIRC_MHZ * 1000ul * 1000ul) +#endif + +#if !defined(SYS_OSC_VALUE) +#define SYS_OSC_VALUE (8 * 1000ul * 1000ul) +#endif + +#if !defined(SYS_LIRC_VALUE) +#define SYS_LIRC_VALUE 32768ul +#endif + +#define SYS_TIMER_FREQ SYS_LIRC_VALUE +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +#ifdef CONFIG_ENABLE_HAL_SYSCFG +/* Reset and Clock Control module */ +#include "hal_syscfg.h" +#endif /* CONFIG_ENABLE_HAL_SYSCFG */ + +#ifdef CONFIG_ENABLE_HAL_PWR +/* Power Management Unit module */ +#include "hal_pwr.h" +#endif /* CONFIG_ENABLE_HAL_PWR */ + +#ifdef CONFIG_ENABLE_HAL_FLASH +/* Embedded Flash module */ +#include "hal_flash.h" +#endif /* CONFIG_ENABLE_HAL_FLASH */ + +#ifdef CONFIG_ENABLE_HAL_GPIO +/* General-purpose I/O module */ +#include "hal_gpio.h" +#endif /* CONFIG_ENABLE_HAL_GPIO */ + +#ifdef CONFIG_ENABLE_HAL_UART +/* Universal Asynchronous Rx/Tx module */ +#include "hal_uart.h" +#endif /* CONFIG_ENABLE_HAL_UART */ + +#ifdef CONFIG_ENABLE_HAL_I2C +/* Inter-Integrated Circuit module */ +#include "hal_i2c.h" +#endif /* CONFIG_ENABLE_HAL_I2C */ + +#ifdef CONFIG_ENABLE_HAL_SPI +/* Serial Peripheral Interface-Bus module */ +#include "hal_spi.h" +#endif /* CONFIG_ENABLE_HAL_SPI */ + +#ifdef CONFIG_ENABLE_HAL_LPTIM +/* Low-Power Timer module */ +#include "hal_lptim.h" +#endif /* CONFIG_ENABLE_HAL_LPTIM */ + +#ifdef CONFIG_ENABLE_HAL_TIM0 +/* Tim0 module */ +#include "hal_lptim.h" +#endif /* CONFIG_ENABLE_HAL_TIM0 */ + +#ifdef CONFIG_ENABLE_HAL_TIM1 +/* Tim1 module */ +#include "hal_lptim.h" +#endif /* CONFIG_ENABLE_HAL_TIM1 */ + +#ifdef CONFIG_ENABLE_HAL_TIM2 +/* Timer module */ +#include "hal_tim.h" +#endif /* CONFIG_ENABLE_HAL_TIM2 */ + +#ifdef CONFIG_ENABLE_HAL_WDG +/* Watch Dog module */ +#include "hal_wdg.h" +#endif /* CONFIG_ENABLE_HAL_WDG */ + +#ifdef CONFIG_ENABLE_HAL_ADC +/* Analog-to-Digital Converter module */ +#include "hal_adc.h" +#endif /* CONFIG_ENABLE_HAL_ADC */ + +#ifdef CONFIG_ENABLE_HAL_AMISC +/* Analog MISC controller module */ +#include "hal_amisc.h" +#endif /* CONFIG_ENABLE_HAL_AMISC */ + +#ifdef CONFIG_ENABLE_HAL_COMP +/* Voltage Compare module */ +#include "hal_comp.h" +#endif /* CONFIG_ENABLE_HAL_COMP */ + +#ifdef CONFIG_ENABLE_HAL_OPAMP +/* OP-Amplifiers with Programmable Gain Amplifier mode */ +#include "hal_opamp.h" +#endif /* CONFIG_ENABLE_HAL_OPAMP */ + +#ifdef CONFIG_ENABLE_HAL_CRC +/* Cyclic Redundancy Check module */ +#include "hal_crc.h" +#endif /* CONFIG_ENABLE_HAL_CRC */ + +#ifdef CONFIG_ENABLE_HAL_DSP +/* Peripheral DSP module */ +#include "hal_dsp.h" +#endif /* CONFIG_ENABLE_HAL_DSP */ + +#ifdef CONFIG_ENABLE_HAL_EPWM +/* Enhance PWM module */ +#include "hal_tim.h" +#endif /* CONFIG_ENABLE_HAL_EPWM */ + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Common/printf.c b/pec930_sdk-v1.0.1/Common/printf.c new file mode 100644 index 0000000..c27acb9 --- /dev/null +++ b/pec930_sdk-v1.0.1/Common/printf.c @@ -0,0 +1,1081 @@ +/////////////////////////////////////////////////////////////////////////////// +// \author (c) Marco Paland (info@paland.com) +// 2014-2019, PALANDesign Hannover, Germany +// +// \license The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// \brief Tiny printf, sprintf and (v)snprintf implementation, optimized for speed on +// embedded systems with a very limited resources. These routines are thread +// safe and reentrant! +// Use this instead of the bloated standard/newlib printf cause these use +// malloc for printf (and may not be thread safe). +// +/////////////////////////////////////////////////////////////////////////////// + +#include +#include + +#include "printf.h" + +#if !defined(CONFIG_HAS_SYSLOG_FLOAT) + #define PRINTF_DISABLE_SUPPORT_FLOAT +#endif + +#define PRINTF_DISABLE_SUPPORT_EXPONENTIAL +#define PRINTF_DISABLE_SUPPORT_LONG_LONG +#define PRINTF_DISABLE_SUPPORT_PTRDIFF_T + +// define this globally (e.g. gcc -DPRINTF_INCLUDE_CONFIG_H ...) to include the +// printf_config.h header file +// default: undefined +#ifdef PRINTF_INCLUDE_CONFIG_H +#include "printf_config.h" +#endif + +#if defined(__GNUC__) +#pragma GCC push_options +#pragma GCC optimize ("Os") +#endif + +// 'ntoa' conversion buffer size, this must be big enough to hold one converted +// numeric number including padded zeros (dynamically created on stack) +// default: 32 byte +#ifndef PRINTF_NTOA_BUFFER_SIZE +#define PRINTF_NTOA_BUFFER_SIZE 32U +#endif + +// 'ftoa' conversion buffer size, this must be big enough to hold one converted +// float number including padded zeros (dynamically created on stack) +// default: 32 byte +#ifndef PRINTF_FTOA_BUFFER_SIZE +#define PRINTF_FTOA_BUFFER_SIZE 32U +#endif + +// support for the floating point type (%f) +// default: activated +#ifndef PRINTF_DISABLE_SUPPORT_FLOAT +#define PRINTF_SUPPORT_FLOAT +#endif + +// support for exponential floating point notation (%e/%g) +// default: activated +#ifndef PRINTF_DISABLE_SUPPORT_EXPONENTIAL +#define PRINTF_SUPPORT_EXPONENTIAL +#endif + +// define the default floating point precision +// default: 6 digits +#ifndef PRINTF_DEFAULT_FLOAT_PRECISION +#define PRINTF_DEFAULT_FLOAT_PRECISION 6U +#endif + +// define the largest float suitable to print with %f +// default: 1e9 +#ifndef PRINTF_MAX_FLOAT +#define PRINTF_MAX_FLOAT 1e9 +#endif + +// support for the long long types (%llu or %p) +// default: activated +#ifndef PRINTF_DISABLE_SUPPORT_LONG_LONG +#define PRINTF_SUPPORT_LONG_LONG +#endif + +// support for the ptrdiff_t type (%t) +// ptrdiff_t is normally defined in as long or long long type +// default: activated +#ifndef PRINTF_DISABLE_SUPPORT_PTRDIFF_T +#define PRINTF_SUPPORT_PTRDIFF_T +#endif + +/////////////////////////////////////////////////////////////////////////////// + +// internal flag definitions +#define FLAGS_ZEROPAD (1U << 0U) +#define FLAGS_LEFT (1U << 1U) +#define FLAGS_PLUS (1U << 2U) +#define FLAGS_SPACE (1U << 3U) +#define FLAGS_HASH (1U << 4U) +#define FLAGS_UPPERCASE (1U << 5U) +#define FLAGS_CHAR (1U << 6U) +#define FLAGS_SHORT (1U << 7U) +#define FLAGS_LONG (1U << 8U) +#define FLAGS_LONG_LONG (1U << 9U) +#define FLAGS_PRECISION (1U << 10U) +#define FLAGS_ADAPT_EXP (1U << 11U) + + +// import float.h for DBL_MAX +#if defined(PRINTF_SUPPORT_FLOAT) +#include +#endif + + +// output function type +typedef void (*out_fct_type)(char character, void* buffer, size_t idx, size_t maxlen); + + +// wrapper (used as buffer) for output function type +typedef struct +{ + void (*fct)(char character, void* arg); + void* arg; +} out_fct_wrap_type; + + +// internal buffer output +static inline void _out_buffer(char character, void* buffer, size_t idx, size_t maxlen) +{ + if (idx < maxlen) + { + ((char*)buffer)[idx] = character; + } +} + + +// internal null output +static inline void _out_null(char character, void* buffer, size_t idx, size_t maxlen) +{ + (void)character; + (void)buffer; + (void)idx; + (void)maxlen; +} + + +// internal _putchar wrapper +static inline void _out_char(char character, void* buffer, size_t idx, size_t maxlen) +{ + (void)buffer; + (void)idx; + (void)maxlen; + if (character) + { + _putchar(character); + } +} + + +// internal output function wrapper +static inline void _out_fct(char character, void* buffer, size_t idx, size_t maxlen) +{ + (void)idx; + (void)maxlen; + if (character) + { + // buffer is the output fct pointer + ((out_fct_wrap_type*)buffer)->fct(character, ((out_fct_wrap_type*)buffer)->arg); + } +} + + +// internal secure strlen +// \return The length of the string (excluding the terminating 0) limited by 'maxsize' +static inline unsigned int _strnlen_s(const char* str, size_t maxsize) +{ + const char* s; + for (s = str; *s && maxsize--; ++s); + return (unsigned int)(s - str); +} + + +// internal test if char is a digit (0-9) +// \return true if char is a digit +static inline bool _is_digit(char ch) +{ + return (ch >= '0') && (ch <= '9'); +} + + +// internal ASCII string to unsigned int conversion +static unsigned int _atoi(const char** str) +{ + unsigned int i = 0U; + while (_is_digit(**str)) + { + i = i * 10U + (unsigned int)(*((*str)++) - '0'); + } + return i; +} + + +// output the specified string in reverse, taking care of any zero-padding +static size_t _out_rev(out_fct_type out, char* buffer, size_t idx, size_t maxlen, const char* buf, size_t len, unsigned int width, unsigned int flags) +{ + const size_t start_idx = idx; + + // pad spaces up to given width + if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) + { + for (size_t i = len; i < width; i++) + { + out(' ', buffer, idx++, maxlen); + } + } + + // reverse string + while (len) + { + out(buf[--len], buffer, idx++, maxlen); + } + + // append pad spaces up to given width + if (flags & FLAGS_LEFT) + { + while (idx - start_idx < width) + { + out(' ', buffer, idx++, maxlen); + } + } + + return idx; +} + + +// internal itoa format +static size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, size_t maxlen, char* buf, size_t len, bool negative, unsigned int base, unsigned int prec, unsigned int width, unsigned int flags) +{ + // pad leading zeros + if (!(flags & FLAGS_LEFT)) + { + if (width && (flags & FLAGS_ZEROPAD) && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) + { + width--; + } + while ((len < prec) && (len < PRINTF_NTOA_BUFFER_SIZE)) + { + buf[len++] = '0'; + } + while ((flags & FLAGS_ZEROPAD) && (len < width) && (len < PRINTF_NTOA_BUFFER_SIZE)) + { + buf[len++] = '0'; + } + } + + // handle hash + if (flags & FLAGS_HASH) + { + if (!(flags & FLAGS_PRECISION) && len && ((len == prec) || (len == width))) + { + len--; + if (len && (base == 16U)) + { + len--; + } + } + if ((base == 16U) && !(flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) + { + buf[len++] = 'x'; + } + else if ((base == 16U) && (flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) + { + buf[len++] = 'X'; + } + else if ((base == 2U) && (len < PRINTF_NTOA_BUFFER_SIZE)) + { + buf[len++] = 'b'; + } + if (len < PRINTF_NTOA_BUFFER_SIZE) + { + buf[len++] = '0'; + } + } + + if (len < PRINTF_NTOA_BUFFER_SIZE) + { + if (negative) + { + buf[len++] = '-'; + } + else if (flags & FLAGS_PLUS) + { + buf[len++] = '+'; // ignore the space if the '+' exists + } + else if (flags & FLAGS_SPACE) + { + buf[len++] = ' '; + } + } + + return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags); +} + + +// internal itoa for 'long' type +static size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long value, bool negative, unsigned long base, unsigned int prec, unsigned int width, unsigned int flags) +{ + char buf[PRINTF_NTOA_BUFFER_SIZE]; + size_t len = 0U; + + // no hash for 0 values + if (!value) + { + flags &= ~FLAGS_HASH; + } + + // write if precision != 0 and value is != 0 + if (!(flags & FLAGS_PRECISION) || value) + { + do + { + const char digit = (char)(value % base); + buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; + value /= base; + } + while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); + } + + return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); +} + + +// internal itoa for 'long long' type +#if defined(PRINTF_SUPPORT_LONG_LONG) +static size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long long value, bool negative, unsigned long long base, unsigned int prec, unsigned int width, unsigned int flags) +{ + char buf[PRINTF_NTOA_BUFFER_SIZE]; + size_t len = 0U; + + // no hash for 0 values + if (!value) + { + flags &= ~FLAGS_HASH; + } + + // write if precision != 0 and value is != 0 + if (!(flags & FLAGS_PRECISION) || value) + { + do + { + const char digit = (char)(value % base); + buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; + value /= base; + } + while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); + } + + return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); +} +#endif // PRINTF_SUPPORT_LONG_LONG + + +#if defined(PRINTF_SUPPORT_FLOAT) + +#if defined(PRINTF_SUPPORT_EXPONENTIAL) +// forward declaration so that _ftoa can switch to exp notation for values > PRINTF_MAX_FLOAT +static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags); +#endif + + +// internal ftoa for fixed decimal floating point +static size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) +{ + char buf[PRINTF_FTOA_BUFFER_SIZE]; + size_t len = 0U; + double diff = 0.0; + + // powers of 10 + static const double pow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; + + // test for special values + if (value != value) + return _out_rev(out, buffer, idx, maxlen, "nan", 3, width, flags); + if (value < -DBL_MAX) + return _out_rev(out, buffer, idx, maxlen, "fni-", 4, width, flags); + if (value > DBL_MAX) + return _out_rev(out, buffer, idx, maxlen, (flags & FLAGS_PLUS) ? "fni+" : "fni", (flags & FLAGS_PLUS) ? 4U : 3U, width, flags); + + // test for very large values + // standard printf behavior is to print EVERY whole number digit -- which could be 100s of characters overflowing your buffers == bad + if ((value > PRINTF_MAX_FLOAT) || (value < -PRINTF_MAX_FLOAT)) + { +#if defined(PRINTF_SUPPORT_EXPONENTIAL) + return _etoa(out, buffer, idx, maxlen, value, prec, width, flags); +#else + return 0U; +#endif + } + + // test for negative + bool negative = false; + if (value < 0) + { + negative = true; + value = 0 - value; + } + + // set default precision, if not set explicitly + if (!(flags & FLAGS_PRECISION)) + { + prec = PRINTF_DEFAULT_FLOAT_PRECISION; + } + // limit precision to 9, cause a prec >= 10 can lead to overflow errors + while ((len < PRINTF_FTOA_BUFFER_SIZE) && (prec > 9U)) + { + buf[len++] = '0'; + prec--; + } + + int whole = (int)value; + double tmp = (value - whole) * pow10[prec]; + unsigned long frac = (unsigned long)tmp; + diff = tmp - frac; + + if (diff > 0.5) + { + ++frac; + // handle rollover, e.g. case 0.99 with prec 1 is 1.0 + if (frac >= pow10[prec]) + { + frac = 0; + ++whole; + } + } + else if (diff < 0.5) + { + } + else if ((frac == 0U) || (frac & 1U)) + { + // if halfway, round up if odd OR if last digit is 0 + ++frac; + } + + if (prec == 0U) + { + diff = value - (double)whole; + if ((!(diff < 0.5) || (diff > 0.5)) && (whole & 1)) + { + // exactly 0.5 and ODD, then round up + // 1.5 -> 2, but 2.5 -> 2 + ++whole; + } + } + else + { + unsigned int count = prec; + // now do fractional part, as an unsigned number + while (len < PRINTF_FTOA_BUFFER_SIZE) + { + --count; + buf[len++] = (char)(48U + (frac % 10U)); + if (!(frac /= 10U)) + { + break; + } + } + // add extra 0s + while ((len < PRINTF_FTOA_BUFFER_SIZE) && (count-- > 0U)) + { + buf[len++] = '0'; + } + if (len < PRINTF_FTOA_BUFFER_SIZE) + { + // add decimal + buf[len++] = '.'; + } + } + + // do whole part, number is reversed + while (len < PRINTF_FTOA_BUFFER_SIZE) + { + buf[len++] = (char)(48 + (whole % 10)); + if (!(whole /= 10)) + { + break; + } + } + + // pad leading zeros + if (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD)) + { + if (width && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) + { + width--; + } + while ((len < width) && (len < PRINTF_FTOA_BUFFER_SIZE)) + { + buf[len++] = '0'; + } + } + + if (len < PRINTF_FTOA_BUFFER_SIZE) + { + if (negative) + { + buf[len++] = '-'; + } + else if (flags & FLAGS_PLUS) + { + buf[len++] = '+'; // ignore the space if the '+' exists + } + else if (flags & FLAGS_SPACE) + { + buf[len++] = ' '; + } + } + + return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags); +} + + +#if defined(PRINTF_SUPPORT_EXPONENTIAL) +// internal ftoa variant for exponential floating-point type, contributed by Martijn Jasperse +static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) +{ + // check for NaN and special values + if ((value != value) || (value > DBL_MAX) || (value < -DBL_MAX)) + { + return _ftoa(out, buffer, idx, maxlen, value, prec, width, flags); + } + + // determine the sign + const bool negative = value < 0; + if (negative) + { + value = -value; + } + + // default precision + if (!(flags & FLAGS_PRECISION)) + { + prec = PRINTF_DEFAULT_FLOAT_PRECISION; + } + + // determine the decimal exponent + // based on the algorithm by David Gay (https://www.ampl.com/netlib/fp/dtoa.c) + union + { + uint64_t U; + double F; + } conv; + + conv.F = value; + int exp2 = (int)((conv.U >> 52U) & 0x07FFU) - 1023; // effectively log2 + conv.U = (conv.U & ((1ULL << 52U) - 1U)) | (1023ULL << 52U); // drop the exponent so conv.F is now in [1,2) + // now approximate log10 from the log2 integer part and an expansion of ln around 1.5 + int expval = (int)(0.1760912590558 + exp2 * 0.301029995663981 + (conv.F - 1.5) * 0.289529654602168); + // now we want to compute 10^expval but we want to be sure it won't overflow + exp2 = (int)(expval * 3.321928094887362 + 0.5); + const double z = expval * 2.302585092994046 - exp2 * 0.6931471805599453; + const double z2 = z * z; + conv.U = (uint64_t)(exp2 + 1023) << 52U; + // compute exp(z) using continued fractions, see https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex + conv.F *= 1 + 2 * z / (2 - z + (z2 / (6 + (z2 / (10 + z2 / 14))))); + // correct for rounding errors + if (value < conv.F) + { + expval--; + conv.F /= 10; + } + + // the exponent format is "%+03d" and largest value is "307", so set aside 4-5 characters + unsigned int minwidth = ((expval < 100) && (expval > -100)) ? 4U : 5U; + + // in "%g" mode, "prec" is the number of *significant figures* not decimals + if (flags & FLAGS_ADAPT_EXP) + { + // do we want to fall-back to "%f" mode? + if ((value >= 1e-4) && (value < 1e6)) + { + if ((int)prec > expval) + { + prec = (unsigned)((int)prec - expval - 1); + } + else + { + prec = 0; + } + flags |= FLAGS_PRECISION; // make sure _ftoa respects precision + // no characters in exponent + minwidth = 0U; + expval = 0; + } + else + { + // we use one sigfig for the whole part + if ((prec > 0) && (flags & FLAGS_PRECISION)) + { + --prec; + } + } + } + + // will everything fit? + unsigned int fwidth = width; + if (width > minwidth) + { + // we didn't fall-back so subtract the characters required for the exponent + fwidth -= minwidth; + } + else + { + // not enough characters, so go back to default sizing + fwidth = 0U; + } + if ((flags & FLAGS_LEFT) && minwidth) + { + // if we're padding on the right, DON'T pad the floating part + fwidth = 0U; + } + + // rescale the float value + if (expval) + { + value /= conv.F; + } + + // output the floating part + const size_t start_idx = idx; + idx = _ftoa(out, buffer, idx, maxlen, negative ? -value : value, prec, fwidth, flags & ~FLAGS_ADAPT_EXP); + + // output the exponent part + if (minwidth) + { + // output the exponential symbol + out((flags & FLAGS_UPPERCASE) ? 'E' : 'e', buffer, idx++, maxlen); + // output the exponent value + idx = _ntoa_long(out, buffer, idx, maxlen, (expval < 0) ? -expval : expval, expval < 0, 10, 0, minwidth-1, FLAGS_ZEROPAD | FLAGS_PLUS); + // might need to right-pad spaces + if (flags & FLAGS_LEFT) + { + while (idx - start_idx < width) out(' ', buffer, idx++, maxlen); + } + } + return idx; +} +#endif // PRINTF_SUPPORT_EXPONENTIAL +#endif // PRINTF_SUPPORT_FLOAT + + +// internal vsnprintf +static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const char* format, va_list va) +{ + unsigned int flags, width, precision, n; + size_t idx = 0U; + + if (!buffer) + { + // use null output function + out = _out_null; + } + + while (*format) + { + // format specifier? %[flags][width][.precision][length] + if (*format != '%') + { + // no + out(*format, buffer, idx++, maxlen); + format++; + continue; + } + else + { + // yes, evaluate it + format++; + } + + // evaluate flags + flags = 0U; + do + { + switch (*format) + { + case '0': + flags |= FLAGS_ZEROPAD; + format++; + n = 1U; + break; + case '-': + flags |= FLAGS_LEFT; + format++; + n = 1U; + break; + case '+': + flags |= FLAGS_PLUS; + format++; + n = 1U; + break; + case ' ': + flags |= FLAGS_SPACE; + format++; + n = 1U; + break; + case '#': + flags |= FLAGS_HASH; + format++; + n = 1U; + break; + default : + n = 0U; + break; + } + } + while (n); + + // evaluate width field + width = 0U; + if (_is_digit(*format)) + { + width = _atoi(&format); + } + else if (*format == '*') + { + const int w = va_arg(va, int); + if (w < 0) + { + flags |= FLAGS_LEFT; // reverse padding + width = (unsigned int)-w; + } + else + { + width = (unsigned int)w; + } + format++; + } + + // evaluate precision field + precision = 0U; + if (*format == '.') + { + flags |= FLAGS_PRECISION; + format++; + if (_is_digit(*format)) + { + precision = _atoi(&format); + } + else if (*format == '*') + { + const int prec = (int)va_arg(va, int); + precision = prec > 0 ? (unsigned int)prec : 0U; + format++; + } + } + + // evaluate length field + switch (*format) + { + case 'l' : + flags |= FLAGS_LONG; + format++; + if (*format == 'l') + { + flags |= FLAGS_LONG_LONG; + format++; + } + break; + case 'h' : + flags |= FLAGS_SHORT; + format++; + if (*format == 'h') + { + flags |= FLAGS_CHAR; + format++; + } + break; +#if defined(PRINTF_SUPPORT_PTRDIFF_T) + case 't' : + flags |= (sizeof(ptrdiff_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); + format++; + break; +#endif + case 'j' : + flags |= (sizeof(intmax_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); + format++; + break; + case 'z' : + flags |= (sizeof(size_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); + format++; + break; + default : + break; + } + + // evaluate specifier + switch (*format) + { + case 'd' : + case 'i' : + case 'u' : + case 'x' : + case 'X' : + case 'o' : + case 'b' : + { + // set the base + unsigned int base; + if (*format == 'x' || *format == 'X') + { + base = 16U; + } + else if (*format == 'o') + { + base = 8U; + } + else if (*format == 'b') + { + base = 2U; + } + else + { + base = 10U; + flags &= ~FLAGS_HASH; // no hash for dec format + } + // uppercase + if (*format == 'X') + { + flags |= FLAGS_UPPERCASE; + } + + // no plus or space flag for u, x, X, o, b + if ((*format != 'i') && (*format != 'd')) + { + flags &= ~(FLAGS_PLUS | FLAGS_SPACE); + } + + // ignore '0' flag when precision is given + if (flags & FLAGS_PRECISION) + { + flags &= ~FLAGS_ZEROPAD; + } + + // convert the integer + if ((*format == 'i') || (*format == 'd')) + { + // signed + if (flags & FLAGS_LONG_LONG) + { +#if defined(PRINTF_SUPPORT_LONG_LONG) + const long long value = va_arg(va, long long); + idx = _ntoa_long_long(out, buffer, idx, maxlen, (unsigned long long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); +#endif + } + else if (flags & FLAGS_LONG) + { + const long value = va_arg(va, long); + idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); + } + else + { + const int value = (flags & FLAGS_CHAR) ? (char)va_arg(va, int) : (flags & FLAGS_SHORT) ? (short int)va_arg(va, int) : va_arg(va, int); + idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned int)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); + } + } + else + { + // unsigned + if (flags & FLAGS_LONG_LONG) + { +#if defined(PRINTF_SUPPORT_LONG_LONG) + idx = _ntoa_long_long(out, buffer, idx, maxlen, va_arg(va, unsigned long long), false, base, precision, width, flags); +#endif + } + else if (flags & FLAGS_LONG) + { + idx = _ntoa_long(out, buffer, idx, maxlen, va_arg(va, unsigned long), false, base, precision, width, flags); + } + else + { + const unsigned int value = (flags & FLAGS_CHAR) ? (unsigned char)va_arg(va, unsigned int) : (flags & FLAGS_SHORT) ? (unsigned short int)va_arg(va, unsigned int) : va_arg(va, unsigned int); + idx = _ntoa_long(out, buffer, idx, maxlen, value, false, base, precision, width, flags); + } + } + format++; + break; + } +#if defined(PRINTF_SUPPORT_FLOAT) + case 'f' : + case 'F' : + if (*format == 'F') flags |= FLAGS_UPPERCASE; + idx = _ftoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); + format++; + break; +#if defined(PRINTF_SUPPORT_EXPONENTIAL) + case 'e': + case 'E': + case 'g': + case 'G': + if ((*format == 'g')||(*format == 'G')) flags |= FLAGS_ADAPT_EXP; + if ((*format == 'E')||(*format == 'G')) flags |= FLAGS_UPPERCASE; + idx = _etoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); + format++; + break; +#endif // PRINTF_SUPPORT_EXPONENTIAL +#endif // PRINTF_SUPPORT_FLOAT + case 'c' : + { + unsigned int l = 1U; + // pre padding + if (!(flags & FLAGS_LEFT)) + { + while (l++ < width) + { + out(' ', buffer, idx++, maxlen); + } + } + // char output + out((char)va_arg(va, int), buffer, idx++, maxlen); + // post padding + if (flags & FLAGS_LEFT) + { + while (l++ < width) + { + out(' ', buffer, idx++, maxlen); + } + } + format++; + break; + } + + case 's' : + { + const char* p = va_arg(va, char*); + unsigned int l = _strnlen_s(p, precision ? precision : (size_t)-1); + // pre padding + if (flags & FLAGS_PRECISION) + { + l = (l < precision ? l : precision); + } + if (!(flags & FLAGS_LEFT)) + { + while (l++ < width) + { + out(' ', buffer, idx++, maxlen); + } + } + // string output + while ((*p != 0) && (!(flags & FLAGS_PRECISION) || precision--)) + { + out(*(p++), buffer, idx++, maxlen); + } + // post padding + if (flags & FLAGS_LEFT) + { + while (l++ < width) + { + out(' ', buffer, idx++, maxlen); + } + } + format++; + break; + } + + case 'p' : + { + width = sizeof(void*) * 2U; + flags |= FLAGS_ZEROPAD | FLAGS_UPPERCASE; +#if defined(PRINTF_SUPPORT_LONG_LONG) + const bool is_ll = sizeof(uintptr_t) == sizeof(long long); + if (is_ll) + { + idx = _ntoa_long_long(out, buffer, idx, maxlen, (uintptr_t)va_arg(va, void*), false, 16U, precision, width, flags); + } + else + { +#endif + idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)((uintptr_t)va_arg(va, void*)), false, 16U, precision, width, flags); +#if defined(PRINTF_SUPPORT_LONG_LONG) + } +#endif + format++; + break; + } + + case '%' : + out('%', buffer, idx++, maxlen); + format++; + break; + + default : + out(*format, buffer, idx++, maxlen); + format++; + break; + } + } + + // termination + out((char)0, buffer, idx < maxlen ? idx : maxlen - 1U, maxlen); + + // return written chars without terminating \0 + return (int)idx; +} + + +/////////////////////////////////////////////////////////////////////////////// + +int sys_printf(const char* format, ...) +{ + va_list va; + va_start(va, format); + char buffer[1]; + const int ret = _vsnprintf(_out_char, buffer, (size_t)-1, format, va); + va_end(va); + return ret; +} + + +int sys_sprintf(char* buffer, const char* format, ...) +{ + va_list va; + va_start(va, format); + const int ret = _vsnprintf(_out_buffer, buffer, (size_t)-1, format, va); + va_end(va); + return ret; +} + + +int sys_snprintf(char* buffer, size_t count, const char* format, ...) +{ + va_list va; + va_start(va, format); + const int ret = _vsnprintf(_out_buffer, buffer, count, format, va); + va_end(va); + return ret; +} + + +int sys_vprintf(const char* format, va_list va) +{ + char buffer[1]; + return _vsnprintf(_out_char, buffer, (size_t)-1, format, va); +} + + +int sys_vsnprintf(char* buffer, size_t count, const char* format, va_list va) +{ + return _vsnprintf(_out_buffer, buffer, count, format, va); +} + + +int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...) +{ + va_list va; + va_start(va, format); + const out_fct_wrap_type out_fct_wrap = { out, arg }; + const int ret = _vsnprintf(_out_fct, (char*)(uintptr_t)&out_fct_wrap, (size_t)-1, format, va); + va_end(va); + return ret; +} + + +#if defined(__GNUC__) +#pragma GCC pop_options +#endif \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Common/printf.h b/pec930_sdk-v1.0.1/Common/printf.h new file mode 100644 index 0000000..9e13287 --- /dev/null +++ b/pec930_sdk-v1.0.1/Common/printf.h @@ -0,0 +1,116 @@ +/////////////////////////////////////////////////////////////////////////////// +// \author (c) Marco Paland (info@paland.com) +// 2014-2019, PALANDesign Hannover, Germany +// +// \license The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// \brief Tiny printf, sprintf and snprintf implementation, optimized for speed on +// embedded systems with a very limited resources. +// Use this instead of bloated standard/newlib printf. +// These routines are thread safe and reentrant. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _PRINTF_H_ +#define _PRINTF_H_ + +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Output a character to a custom device like UART, used by the printf() function + * This function is declared here only. You have to write your custom implementation somewhere + * \param character Character to output + */ +void _putchar(char character); + + +/** + * Tiny printf implementation + * You have to implement _putchar if you use printf() + * To avoid conflicts with the regular printf() API it is overridden by macro defines + * and internal underscore-appended functions like printf_() are used + * \param format A string that specifies the format of the output + * \return The number of characters that are written into the array, not counting the terminating null character + */ +#define printf sys_printf +int sys_printf(const char* format, ...); + + +/** + * Tiny sprintf implementation + * Due to security reasons (buffer overflow) YOU SHOULD CONSIDER USING (V)SNPRINTF INSTEAD! + * \param buffer A pointer to the buffer where to store the formatted string. MUST be big enough to store the output! + * \param format A string that specifies the format of the output + * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character + */ +#define sprintf sys_sprintf +int sys_sprintf(char* buffer, const char* format, ...); + + +/** + * Tiny snprintf/vsnprintf implementation + * \param buffer A pointer to the buffer where to store the formatted string + * \param count The maximum number of characters to store in the buffer, including a terminating null character + * \param format A string that specifies the format of the output + * \param va A value identifying a variable arguments list + * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character + * If the formatted string is truncated the buffer size (count) is returned + */ +#define snprintf sys_snprintf +#define vsnprintf sys_vsnprintf +int sys_snprintf(char* buffer, size_t count, const char* format, ...); +int sys_vsnprintf(char* buffer, size_t count, const char* format, va_list va); + + +/** + * Tiny vprintf implementation + * \param format A string that specifies the format of the output + * \param va A value identifying a variable arguments list + * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character + */ +#define vprintf sys_vprintf +int sys_vprintf(const char* format, va_list va); + + +/** + * printf with output function + * You may use this as dynamic alternative to printf() with its fixed _putchar() output + * \param out An output function which takes one character and an argument pointer + * \param arg An argument pointer for user data passed to output function + * \param format A string that specifies the format of the output + * \return The number of characters that are sent to the output function, not counting the terminating null character + */ +int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...); + + +#ifdef __cplusplus +} +#endif + + +#endif // _PRINTF_H_ diff --git a/pec930_sdk-v1.0.1/Common/syslog.c b/pec930_sdk-v1.0.1/Common/syslog.c new file mode 100644 index 0000000..5c70b48 --- /dev/null +++ b/pec930_sdk-v1.0.1/Common/syslog.c @@ -0,0 +1,126 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file syslog.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_LOG_MSG_DEVICE UART0 +#define CONFIG_LOG_DEVICE_TX_IO_PORTx GPIOA +#define CONFIG_LOG_DEVICE_TX_IO_PINx GPIO_Pin_15 +#define CONFIG_LOG_DEVICE_TX_IO_AF GPIO_AF_1 +#define CONFIG_LOG_DEVICE_RESET() __HAL_SYSCFG_RESET_UART0() +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= +void _putchar(char character) +{ + UART_SendData(CONFIG_LOG_MSG_DEVICE, character); + UART_WaitTxFifoEmpty(CONFIG_LOG_MSG_DEVICE); + return; +} + +//============================================================================= +// Public Function Definition +//============================================================================= +void syslog_init(void) +{ + GPIO_InitTypeDef gpio_init = {0}; + UART_InitTypeDef uart_init = {0}; + + /* configure GPIO Pin mux of UART Tx */ + gpio_init.GPIO_Pin = CONFIG_LOG_DEVICE_TX_IO_PINx; + gpio_init.GPIO_AF_Mode = CONFIG_LOG_DEVICE_TX_IO_AF; + gpio_init.GPIO_Mode = GPIO_Mode_AF; + GPIO_Init(CONFIG_LOG_DEVICE_TX_IO_PORTx, &gpio_init); + + uart_init.BaudRate = SLOG_SERIAL_BPS; + uart_init.WordLength = UART_WordLength_8b; + uart_init.StopBits = UART_StopBits_1; + uart_init.Parity = UART_Parity_No; + uart_init.Mode = UART_Mode_TxRx; + UART_Init(CONFIG_LOG_MSG_DEVICE, &uart_init); + + UART_Start(CONFIG_LOG_MSG_DEVICE); + return; +} + +void syslog_deinit(void) +{ + GPIO_DeInit(CONFIG_LOG_DEVICE_TX_IO_PORTx, CONFIG_LOG_DEVICE_TX_IO_PINx); + CONFIG_LOG_DEVICE_RESET(); + return; +} + +void +syslog_dump_mem( + char *prefix, + uint32_t *pAddr, + int bytes, + int has_out_u32le) +{ + if( has_out_u32le ) + { + uintptr_t addr = (uintptr_t)pAddr; + uint32_t cnt = (bytes + 0x3) >> 2; + uint32_t *pCur = (uint32_t*)pAddr; + + for(int i = 0; i < cnt; i++) + { + if( (i & 0x3) == 2 ) + printf(" -"); + else if( !(i & 0x3) ) + { + printf("\n%s%08X |", prefix, addr); + addr += 16; + } + + printf(" %08X", pCur[i]); + } + printf("\n\n"); + } + else + { + uintptr_t addr = (uintptr_t)pAddr; + uint8_t *pCur = (uint8_t*)pAddr; + + for(int i = 0; i < bytes; i++) + { + if( (i & 0xF) == 8 ) + printf(" -"); + else if( !(i & 0xF) ) + { + printf("\n%s%08X |", prefix, addr); + addr += 16; + } + + printf(" %02X", pCur[i]); + } + printf("\n\n"); + } + + return; +} diff --git a/pec930_sdk-v1.0.1/Common/syslog.h b/pec930_sdk-v1.0.1/Common/syslog.h new file mode 100644 index 0000000..7ae4708 --- /dev/null +++ b/pec930_sdk-v1.0.1/Common/syslog.h @@ -0,0 +1,108 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file syslog.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __syslog_H_wWjHKLEN_l9U5_H1mZ_sZEW_uX5M5YmrWbVp__ +#define __syslog_H_wWjHKLEN_l9U5_H1mZ_sZEW_uX5M5YmrWbVp__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include "printf.h" +//============================================================================= +// Constant Definition +//============================================================================= +/** + * System Log message through uart with baudrate 'SLOG_SERIAL_BPS' + */ +#define SLOG_SERIAL_BPS 115200 + +#define SLOG_BLACK "\033[30m" +#define SLOG_RED "\033[31m" +#define SLOG_GREEN "\033[32m" +#define SLOG_YELLOW "\033[33m" +#define SLOG_BLUE "\033[34m" +#define SLOG_MAGENTA "\033[35m" +#define SLOG_CYAN "\033[36m" +#define SLOG_WHITE "\033[97m" +#define SLOG_DEFAULT "\033[39m" +#define SLOG_RESET "\033[m" + +#define SLOG_RED2 "\33[91m" +#define SLOG_GREEN2 "\33[92m" +#define SLOG_YELLOW2 "\33[93m" +#define SLOG_BLUE2 "\33[94m" +#define SLOG_VIOLET2 "\33[95m" +#define SLOG_BEIGE2 "\33[96m" +//============================================================================= +// Macro Definition +//============================================================================= +#define stringize(s) #s +#define _toStr(a) stringize(a) + +#define err(str, ...) printf(SLOG_RED "[error] " str SLOG_RESET, ##__VA_ARGS__) + +#if defined(NDEBUG) + /* release */ + #define info(str, ...) + #define msg(str, ...) + #define dbg(str, ...) + #define log_color(COLOR, str, ...) + +#else + #define info(str, ...) printf(SLOG_YELLOW str SLOG_RESET, ##__VA_ARGS__) + #define msg(str, ...) printf(str, ##__VA_ARGS__) + #define dbg(str, ...) printf(str, ##__VA_ARGS__) + #define log_color(COLOR, str, ...) printf(COLOR str SLOG_RESET, ##__VA_ARGS__) +#endif /* NDEBUG */ +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +void syslog_init(void); +void syslog_deinit(void); + +/** + * \brief Dump memory data through system log + * + * \param [in] prefix the prefix text + * \param [in] pAddr the target memory address + * \param [in] bytes the dumped length + * \param [in] has_out_u32le layout with 32-bits little-endian or not + * \return + * None + */ +void +syslog_dump_mem( + char *prefix, + uint32_t *pAddr, + int bytes, + int has_out_u32le); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Docs/.DS_Store b/pec930_sdk-v1.0.1/Docs/.DS_Store new file mode 100644 index 0000000..68f3fb3 Binary files /dev/null and b/pec930_sdk-v1.0.1/Docs/.DS_Store differ diff --git a/pec930_sdk-v1.0.1/Docs/Schematic/PEC930_EV_BOARD_SSOP24(010).pdf b/pec930_sdk-v1.0.1/Docs/Schematic/PEC930_EV_BOARD_SSOP24(010).pdf new file mode 100644 index 0000000..da8974c Binary files /dev/null and b/pec930_sdk-v1.0.1/Docs/Schematic/PEC930_EV_BOARD_SSOP24(010).pdf differ diff --git a/pec930_sdk-v1.0.1/Docs/image/ICE_normal_view.jpg b/pec930_sdk-v1.0.1/Docs/image/ICE_normal_view.jpg new file mode 100644 index 0000000..18df783 Binary files /dev/null and b/pec930_sdk-v1.0.1/Docs/image/ICE_normal_view.jpg differ diff --git a/pec930_sdk-v1.0.1/Docs/image/IDE_close_proj.jpg b/pec930_sdk-v1.0.1/Docs/image/IDE_close_proj.jpg new file mode 100644 index 0000000..e4ad850 Binary files /dev/null and b/pec930_sdk-v1.0.1/Docs/image/IDE_close_proj.jpg differ diff --git a/pec930_sdk-v1.0.1/Docs/image/IDE_debug_view.jpg b/pec930_sdk-v1.0.1/Docs/image/IDE_debug_view.jpg new file mode 100644 index 0000000..4f9927e Binary files /dev/null and b/pec930_sdk-v1.0.1/Docs/image/IDE_debug_view.jpg differ diff --git a/pec930_sdk-v1.0.1/Docs/image/IDE_delet_recent_proj.jpg b/pec930_sdk-v1.0.1/Docs/image/IDE_delet_recent_proj.jpg new file mode 100644 index 0000000..c88038d Binary files /dev/null and b/pec930_sdk-v1.0.1/Docs/image/IDE_delet_recent_proj.jpg differ diff --git a/pec930_sdk-v1.0.1/Drivers/.DS_Store b/pec930_sdk-v1.0.1/Drivers/.DS_Store new file mode 100644 index 0000000..6ded2c5 Binary files /dev/null and b/pec930_sdk-v1.0.1/Drivers/.DS_Store differ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/.DS_Store b/pec930_sdk-v1.0.1/Drivers/PEC930/.DS_Store new file mode 100644 index 0000000..6e2769c Binary files /dev/null and b/pec930_sdk-v1.0.1/Drivers/PEC930/.DS_Store differ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/BSP/.DS_Store b/pec930_sdk-v1.0.1/Drivers/PEC930/BSP/.DS_Store new file mode 100644 index 0000000..a862071 Binary files /dev/null and b/pec930_sdk-v1.0.1/Drivers/PEC930/BSP/.DS_Store differ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/BSP/StarterKit/starterkit.c b/pec930_sdk-v1.0.1/Drivers/PEC930/BSP/StarterKit/starterkit.c new file mode 100644 index 0000000..423cda5 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/BSP/StarterKit/starterkit.c @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file starterkit.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "starterkit.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/BSP/StarterKit/starterkit.h b/pec930_sdk-v1.0.1/Drivers/PEC930/BSP/StarterKit/starterkit.h new file mode 100644 index 0000000..c1763ae --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/BSP/StarterKit/starterkit.h @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file starterkit.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __starterkit_H_wdeYMM70_lNLW_HSdS_sZLf_uhvq7CKQjo90__ +#define __starterkit_H_wdeYMM70_lNLW_HSdS_sZLf_uhvq7CKQjo90__ + +#ifdef __cplusplus +extern "C" { +#endif + + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/Device/.DS_Store b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/.DS_Store new file mode 100644 index 0000000..f74337f Binary files /dev/null and b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/.DS_Store differ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/.DS_Store b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/.DS_Store new file mode 100644 index 0000000..b6c143e Binary files /dev/null and b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/.DS_Store differ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/SVD/PEC930.svd b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/SVD/PEC930.svd new file mode 100644 index 0000000..d5c1291 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/SVD/PEC930.svd @@ -0,0 +1,10421 @@ + + + Padauk-tech + PEC930 + 1.0 + RISC-V 32-bits CPU + 8 + 32 + 32 + read-write + + 0x00000000 + 0xFFFFFFFF + + + EFLASH_MEM + Embedded flash memory + 0x00000000 + + 0 + 0x8000 + registers + + + + DATA0 + The first address + 0x00 + 32 + 0 + 0xFFFFFFFF + + + DATA_END + The endt address + 0x7FFC + 32 + 0 + 0xFFFFFFFF + + + + + SRAM_MEM + SRAM memory + 0x20000000 + + 0 + 0x1000 + registers + + + + DATA0 + The first address + 0x00 + 32 + 0 + 0xFFFFFFFF + + + DATA_END + The endt address + 0xFFC + 32 + 0 + 0xFFFFFFFF + + + + + NVR_MEM + Non-Volatile Region + 0x00200000 + + 0 + 0x2000 + registers + + + + DATA0 + The first address + 0x00 + 32 + 0 + 0xFFFFFFFF + + + DATA_END + The endt address + 0x1FFC + 32 + 0 + 0xFFFFFFFF + + + + + CORET + RISC-V core of SoC + 0x18000000 + + 0 + 0xC + registers + + + SysSW + System Software interrupt + 3 + + + SysTimer + System Timer interrupt + 7 + + + BusError + Bus error interrupt + 17 + + + PerfMon + Performance Monitor + 18 + + + + revd + NA + 0x00 + 32 + 0 + 0xFFFFFFFF + + + + + UID + Universally Unique Identifier + 0x00201F00 + + 0 + 0xC + registers + + + + UID1 + Unique Identifier 1 + 0x00 + 32 + 0 + 0xFFFFFFFF + read-only + + + UID2 + Unique Identifier 2 + 0x04 + 32 + 0 + 0xFFFFFFFF + read-only + + + UID3 + Unique Identifier 3 + 0x08 + 32 + 0 + 0xFFFFFFFF + read-only + + + + + FLASH + Flash Controller Module + 0x4000F800 + + 0 + 0x200 + registers + + + + + CMD + Flash Command Register + 0x000 + 32 + 0x0 + 0x0000FFFF + read-write + + + START + Flash command start + 0 + 1 + read-write + + + CMD + Flash command ID + 1 + 3 + read-write + + + PROG + Flash 32-bits program + 0 + + + ERASE_SECTOR + Flash sector erase + 1 + + + ERASE_CHIP + Flash chip erase + 2 + + + + + NWS + Flash waits cycles after OP + 5 + 3 + read-write + + + UNLOCK + Unlock Flash P/E operations + 8 + 1 + read-write + + + ACME + Enable Flash Access Counter + 9 + 1 + read-write + + + ACMR + Reset Flash Access Counter + 10 + 1 + read-write + + + AINC + Flash enable auto address increase or not + 13 + 1 + read-write + + + KEY + Auth key 0xA5A5 + 16 + 16 + write-only + + + + + SR + Flash Status Register + 0x004 + 32 + 0x0 + 0xFFFFFFFF + read-write + + + CMD_END + Flash idle flag (0:busy), write 1 to clear + 0 + 1 + read-write + + + KEY_ERR + Flash error flag (0:success), W1C + 1 + 1 + read-write + + + ACC_ERR + Flash access error flag, W1C + 2 + 1 + read-write + + + ADDR_ERR + Flash addressing error flag, W1C + 3 + 1 + read-write + + + HCM + Flash access count full flag, W1C + 6 + 1 + read-write + + + HSI_TC_ERR + HSI_TC's complement do not match in sysinfo area + 7 + 1 + read-only + + + PROTCT_R2_ERR + Protect_R2's complement do not match in sysinfo area + 8 + 1 + read-only + + + PROTCT_R1_ERR + Protect_R1's complement do not match in sysinfo area + 9 + 1 + read-only + + + RSTIO_AF_ERR + RSTIO_AF's complement do not match in sysinfo area + 10 + 1 + read-only + + + LDO_TRIM_ERR + LDO_TRIM's complement do not match in sysinfo area + 11 + 1 + read-only + + + VBUF_TRIM_ERR + VBUF_TRIM's complement do not match in sysinfo area + 12 + 1 + read-only + + + LSI_TRIM_ERR + LSI_TRIM's complement do not match in sysinfo area + 13 + 1 + read-only + + + HSI_TRIM_ERR + HSI_TRIM's complement do not match in sysinfo area + 14 + 1 + read-only + + + + + AR + Flash Address Register + 0x00C + 32 + 0x0 + 0xFFFFFFFF + read-write + + + DR + Flash Data Register + 0x010 + 32 + 0x0 + 0xFFFFFFFF + read-write + + + ACM + Flash Access Count Register + 0x20 + 32 + 0x0 + 0xFFFFFFFF + read-only + + + DIV + Flash clock division + 0x028 + 32 + 0x0 + 0xFFFFFFFF + read-write + + + DIV + Flash Clock DIV + 0 + 8 + read-write + + + + + + + GPIO + General Purpose IO + 0x40011000 + + 0 + 0x64 + registers + + + + + DAT + GPIO Data Register + 0 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + LAT + GPIO output data latch register + 0x04 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + ITS1 + GPIO interrupt type set register + 0x08 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + ITC1 + GPIO interrupt type clear register + 0x0C + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + OES + GPIO output enable set register + 0x10 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + OEC + GPIO output enable clear register + 0x14 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + INES + GPIO input enable set register + 0x18 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + INEC + GPIO intput enable clear register + 0x1C + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + IES + GPIO pin interrupt enable register + 0x20 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + IEC + GPIO pin interrupt clear register + 0x24 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + ITS0 + GPIO pin interrupt type select register + 0x28 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + ITC0 + GPIO pin interrupt type clear register + 0x2C + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + PLS + GPIO pin interrupt polarity set register + 0x30 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + PLC + GPIO pin interrupt polarity clear register + 0x34 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + IST + GPIO pin interrupt flag status register + 0x38 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + PUS + GPIO input pull-up set register + 0x3C + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + PUC + GPIO input pull-up clear register + 0x40 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + ODS + GPIO output open-drain set register + 0x44 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + ODC + GPIO output open-drain clear register + 0x48 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + PDS + GPIO input pull-down set register + 0x4C + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + PDC + GPIO input pull-down clear register + 0x50 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + OSRS + GPIO Open Sink Set register + 0x54 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + OSRC + GPIO Open Sink Clear register + 0x58 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + CTS + GPIO Schmitt-Trigger Set register + 0x5C + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + CTC + GPIO Schmitt-Trigger Clear register + 0x60 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + + + GPIOA + 0x40011000 + + GPIOA + 27 + + + + GPIOB + 0x40012000 + + GPIOB + 28 + + + + AFIO + Alternate Function I/O + AFIO + 0x40011070 + + 0x0 + 0x10 + registers + + + + PAAFR + GPIO PortA AF control register + 0x0 + 0x20 + read-write + 0x00000000 + + + PA0 + Pin index + 0 + 3 + read-write + + + PA1 + Pin index + 3 + 3 + read-write + + + PA2 + Pin index + 6 + 3 + read-write + + + PA3 + Pin index + 9 + 3 + read-write + + + PA4 + Pin index + 12 + 3 + read-write + + + PA5 + Pin index + 15 + 3 + read-write + + + PA14 + Pin index + 18 + 3 + read-write + + + PA15 + Pin index + 21 + 3 + read-write + + + + + PBAFR + GPIO PortB AF control register + 0x4 + 0x20 + read-write + 0x00000000 + + + PB0 + Pin index + 0 + 3 + + + PB1 + Pin index + 3 + 3 + + + PB2 + Pin index + 6 + 3 + + + PB3 + Pin index + 9 + 3 + + + PB4 + Pin index + 12 + 3 + + + PB5 + Pin index + 15 + 3 + + + + + FN1_AFR + Peripheral Alternate Func control register + 0x8 + 0x20 + read-write + 0x00000000 + + + BKIN + Peripheral Alternate Func selection + 0 + 4 + + + ECAP0 + Peripheral Alternate Func selection + 4 + 3 + + + ECAP1 + Peripheral Alternate Func selection + 7 + 3 + + + ECAP2 + Peripheral Alternate Func selection + 10 + 3 + + + EPETR + Peripheral Alternate Func selection + 13 + 4 + + + + + FN2_AFR + Peripheral Alternate Func control register + 0xC + 0x20 + read-write + 0x00000000 + + + TCAP0 + Peripheral Alternate Func control register + 0 + 3 + + + TCAP1 + Peripheral Alternate Func control register + 3 + 3 + + + TCAP2 + Peripheral Alternate Func control register + 6 + 3 + + + T2ETR + Peripheral Alternate Func control register + 9 + 4 + + + I2C_PULL0 + Peripheral Alternate Func control register + 13 + 1 + + + I2C_PULL1 + Peripheral Alternate Func control register + 14 + 1 + + + I2C_PULL2 + Peripheral Alternate Func control register + 15 + 1 + + + I2C_PULL3 + Peripheral Alternate Func control register + 16 + 1 + + + I2C_PULL4 + Peripheral Alternate Func control register + 17 + 1 + + + I2C_PULL5 + Peripheral Alternate Func control register + 18 + 1 + + + I2C_PULL6 + Peripheral Alternate Func control register + 19 + 1 + + + I2C_PULL7 + Peripheral Alternate Func control register + 20 + 1 + + + + + + + SYSCFG + System Configuration controller + 0x4001F000 + + 0 + 0x400 + registers + + + + PMUCR + Power Management Unit Control Register + 0x04 + 32 + 0 + 0xFFFFFFFF + read-write + + + PMUEN + Enable pmu + 0 + 1 + read-write + + + + + MCOCR + MCU Clock Output Control Register + 0x0C + 32 + 0 + 0xFFFFFFFF + read-write + + + MCOSEL + Select output clock + 0 + 3 + read-write + + + HSI + HSI RC clock + 0 + + + HSE + HSE OSC clock + 1 + + + CLKDIV + HSI Clock Divider + 2 + + + LSI + LSI RC clock + 3 + + + FCLK + F clock + 4 + + + GND + Peripheral clock + 7 + + + + + DivEn + Enable MCO outupt pre-scalar + 6 + 1 + read-write + + + DivSel + Select outupt pre-scalar + 7 + 1 + read-write + + + Divider + The pre-scalar value + 8 + 8 + read-write + + + SWRstEn + Trigger software reset + 16 + 8 + read-write + + + OFF + Software reset off + 0 + + + ON + Software reset on + 0x5a + + + + + + + SYSRSTSR + System Reset Status Register + 0x10 + 32 + 0 + 0xFFFFFFFF + read-write + + + SWRST + Software reset (Write clear) + 0 + 1 + read-write + + + WDGRST + Watchdog reset (Write clear) + 1 + 1 + read-write + + + LOCKUPRST + Lock-up reset (Write clear) + 2 + 1 + read-write + + + PORRST + Power reset (Write clear) + 8 + 1 + read-write + + + PADRST + nRST Pad reset (Write clear) + 9 + 1 + read-write + + + LVDRST + LVD reset (Write clear) + 11 + 1 + read-write + + + REBOOTRST + Reboot reset (Write clear) + 12 + 1 + read-write + + + + + REBOOT_UNLOCK + Unlock reboot to latch paraments + 0x14 + 32 + 0 + 0xFFFFFFFF + read-write + + + AUTHKEY + Reboot signature: 0xAB56 + 0 + 16 + read-write + + + + + SYSRSTCR + System Reset Control Register + 0x18 + 32 + 0 + 0xFFFFFFFF + read-write + + + REBOOTEN + Trigger system Re-boot + 10 + 1 + read-write + + + + + DEBUGENCR + Debug enable Control Register + 0x1C + 32 + 0 + 0xFFFFFFFF + read-write + + + TIM0 + Tim0 debug mode + 2 + 1 + read-write + + + TIM1 + Tim1 debug mode + 3 + 1 + read-write + + + LPTIM + LPTIM debug mode + 4 + 1 + read-write + + + EPWM + EPWM debug mode + 6 + 1 + read-write + + + TIM2 + TIM2 debug mode + 11 + 1 + read-write + + + WDG + WDG debug mode(def: enable) + 14 + 1 + read-write + + + AUTHKEY + Reboot signature: 0x8A57 + 16 + 16 + write-only + + + + + SYSCLKCR + System Clock Control Register + 0x20 + 32 + 0 + 0xFFFFFFFF + read-write + + + CLKSW + System Clock Source Switch + 0 + 3 + read-write + + + HSI + HSI RC clock source + 0 + + + HSE + HSE OSC clock source + 1 + + + CLKDIV + Clock Divider source + 2 + + + LSI + LSI RC clock source + 3 + + + + + CLKDIV + Clock Divider, factors = (CLKDIV + 1) + 8 + 4 + read-write + + + LSIAON + LSI always on + 23 + 1 + read-write + + + SYSTICKCR + Sytem tick Control Register + 24 + 2 + read-write + + + LSI + Systick from LSI + 0 + + + HSI_DIV2 + Systick from HSI Divide 2 + 1 + + + HSI_DIV4 + Systick from HSI Divide 4 + 2 + + + HSI_DIV8 + Systick from HSI Divide 8 + 3 + + + + + + + PRSTEN + Peripheral Reset Control Register + 0x24 + 32 + 0 + 0xFFFFFFFF + read-write + + + UART0 + Reset enable (It should generate pulse signal to reset) + 0 + 1 + read-write + + + TIM0 + Reset enable (It should generate pulse signal to reset) + 2 + 1 + read-write + + + TIM1 + Reset enable (It should generate pulse signal to reset) + 3 + 1 + read-write + + + LPTIM + Reset enable (It should generate pulse signal to reset) + 4 + 1 + read-write + + + ADC + Reset enable (It should generate pulse signal to reset) + 5 + 1 + read-write + + + EPWM + Reset enable (It should generate pulse signal to reset) + 6 + 1 + read-write + + + DSP + Reset enable (It should generate pulse signal to reset) + 7 + 1 + read-write + + + COMP0 + Reset enable (It should generate pulse signal to reset) + 8 + 1 + read-write + + + SPI + Reset enable (It should generate pulse signal to reset) + 10 + 1 + read-write + + + TIM2 + Reset enable (It should generate pulse signal to reset) + 11 + 1 + read-write + + + I2C + Reset enable (It should generate pulse signal to reset) + 12 + 1 + read-write + + + COMP1 + Reset enable (It should generate pulse signal to reset) + 13 + 1 + read-write + + + WDG + Reset enable (It should generate pulse signal to reset) + 14 + 1 + read-write + + + AMISC + Reset enable (It should generate pulse signal to reset) + 15 + 1 + read-write + + + + + PCLKEN + Peripheral Clock Enable Control Register + 0x28 + 32 + 0 + 0xFFFFFFFF + read-write + + + UART0 + PCLK enable Uart 0 + 0 + 1 + read-write + + + TIM0 + PCLK enable TIM0 + 2 + 1 + read-write + + + TIM1 + PCLK enable TIM1 + 3 + 1 + read-write + + + LPTIM + PCLK enable LPTIM + 4 + 1 + read-write + + + ADC + PCLK enable ADC + 5 + 1 + read-write + + + EPWM + PCLK enable EPWM + 6 + 1 + read-write + + + DSP + PCLK enable DSP + 7 + 1 + read-write + + + COMP0 + PCLK enable COMP0 + 8 + 1 + read-write + + + SPI + PCLK enable SPI + 10 + 1 + read-write + + + TIM2 + PCLK enable TIM2 + 11 + 1 + read-write + + + I2C + PCLK enable I2C + 12 + 1 + read-write + + + COMP1 + PCLK enable COMP1 + 13 + 1 + read-write + + + WDG + PCLK enable WDG + 14 + 1 + read-write + + + AMISC + PCLK enable analog misc. + 15 + 1 + read-write + + + + + ICEIOCR + ICE I/O Control Register + 0x2C + 32 + 0 + 0xFFFFFFFF + read-write + + + JTAGIOEN + I/O force on jTag pins. 0: normal I/O, 1: ICE pins + 0 + 1 + read-write + + + DBG_CTRL_EN + Enable debug control + 1 + 1 + read-write + + + DBG_EN + Enable debug + 2 + 1 + read-write + + + AUTHKEY + auth-key 0xE653 + 16 + 16 + read-write + + + + + RSTPINCR + Reset pin control register + 0x30 + 32 + 0 + 0xFFFFFFFF + read-write + + + RSTPINAF + Reset Pin switch to general I/O + 0 + 16 + read-write + + + ON + Enable reset pin + 0xA563 + + + OFF + Disable reset pin (Pin changes to I/O) + 0 + + + + + + + TIM2_CON_SEL + TIM2 selection + 0x34 + 32 + 0 + 0xFFFFFFFF + read-write + + + CH1 + selection + 0 + 3 + read-write + + + PAD + From PAD + 0 + + + UART + From UART0_RXD + 1 + + + IIC + From IIC_SDA + 2 + + + OSC32K + From OSC_32K + 4 + + + + + CH2 + selection + 4 + 3 + read-write + + + PAD + From PAD + 0 + + + UART + From UART0_RXD + 1 + + + IIC + From IIC_SDA + 2 + + + OSC32K + From OSC_32K + 4 + + + + + CH3 + selection + 8 + 3 + read-write + + + PAD + From PAD + 0 + + + UART + From UART0_RXD + 1 + + + IIC + From IIC_SDA + 2 + + + OSC32K + From OSC_32K + 4 + + + + + CH4 + selection + 12 + 3 + read-write + + + PAD + From PAD + 0 + + + UART + From UART0_RXD + 1 + + + IIC + From IIC_SDA + 2 + + + OSC32K + From OSC_32K + 4 + + + + + BREAK_SEL + TIM IP Config + 17 + 1 + read-write + + + COMP0A_SEL + COMP0A selection + 18 + 1 + read-write + + + COMP1A_SEL + COMP1A selection + 19 + 1 + read-write + + + VC_CH1_INV + VCOUT_SEL + 20 + 1 + read-write + + + 0 + COMP + 0 + + + 1 + COMP Inverse + 1 + + + + + VC_CH1 + VCOUT_SEL + 21 + 1 + read-write + + + 0 + COMP(Used in conjunction with Vc_ch1_inv)) + 0 + + + 1 + CH1_CON[2:0] + 1 + + + + + VC_CH2_INV + VCOUT_SEL + 22 + 1 + read-write + + + 0 + COMP + 0 + + + 1 + COMP Inverse + 1 + + + + + VC_CH2 + VCOUT_SEL + 23 + 1 + read-write + + + 0 + COMP(Used in conjunction with Vc_CH2_inv)) + 0 + + + 1 + CH2_CON[6:4] + 1 + + + + + VC_CH3_INV + VCOUT_SEL + 24 + 1 + read-write + + + 0 + COMP + 0 + + + 1 + COMP Inverse + 1 + + + + + VC_CH3 + VCOUT_SEL + 25 + 1 + read-write + + + 0 + COMP(Used in conjunction with Vc_CH3_inv)) + 0 + + + 1 + CH3_CON[[10:8] + 1 + + + + + VC_CH4_INV + VCOUT_SEL + 26 + 1 + read-write + + + 0 + COMP + 0 + + + 1 + COMP Inverse + 1 + + + + + VC_CH4 + VCOUT_SEL + 27 + 1 + read-write + + + 0 + COMP(Used in conjunction with Vc_CH4_inv)) + 0 + + + 1 + CH4_CON[14:12] + 1 + + + + + COMP0D_SEL + COMP0D selection + 28 + 1 + read-write + + + COMP1D_SEL + COMP1D selection + 29 + 1 + read-write + + + + + EPWM_CON_SEL + EPWM selection + 0x38 + 32 + 0 + 0xFFFFFFFF + read-write + + + CH1 + selection + 0 + 3 + read-write + + + PAD + From PAD + 0 + + + UART + From UART0_RXD + 1 + + + IIC + From IIC_SDA + 2 + + + OSC32K + From OSC_32K + 4 + + + + + CH2 + selection + 4 + 3 + read-write + + + PAD + From PAD + 0 + + + UART + From UART0_RXD + 1 + + + IIC + From IIC_SDA + 2 + + + OSC32K + From OSC_32K + 4 + + + + + CH3 + selection + 8 + 3 + read-write + + + PAD + From PAD + 0 + + + UART + From UART0_RXD + 1 + + + IIC + From IIC_SDA + 2 + + + OSC32K + From OSC_32K + 4 + + + + + CH4 + selection + 12 + 3 + read-write + + + PAD + From PAD + 0 + + + UART + From UART0_RXD + 1 + + + IIC + From IIC_SDA + 2 + + + OSC32K + From OSC_32K + 4 + + + + + BREAK_SEL + EPWM IP Config + 16 + 1 + read-write + + + BREAK_OSSI0_DISOUT + EPWM IP Config + 17 + 1 + read-write + + + COMP0A_SEL + COMP0A Selection + 18 + 1 + read-write + + + COMP1A_SEL + COMP1A Selection + 19 + 1 + read-write + + + VC_CH1_INV + VCOUT_SEL + 20 + 1 + read-write + + + 0 + COMP + 0 + + + 1 + COMP Inverse + 1 + + + + + VC_CH1 + VCOUT_SEL + 21 + 1 + read-write + + + 0 + COMP(Used in conjunction with Vc_ch1_inv)) + 0 + + + 1 + CH1_CON[2:0] + 1 + + + + + VC_CH2_INV + VCOUT_SEL + 22 + 1 + read-write + + + 0 + COMP + 0 + + + 1 + COMP Inverse + 1 + + + + + VC_CH2 + VCOUT_SEL + 23 + 1 + read-write + + + 0 + COMP(Used in conjunction with Vc_CH2_inv)) + 0 + + + 1 + CH2_CON[6:4] + 1 + + + + + VC_CH3_INV + VCOUT_SEL + 24 + 1 + read-write + + + 0 + COMP + 0 + + + 1 + COMP Inverse + 1 + + + + + VC_CH3 + VCOUT_SEL + 25 + 1 + read-write + + + 0 + COMP(Used in conjunction with Vc_CH3_inv)) + 0 + + + 1 + CH3_CON[[10:8] + 1 + + + + + VC_CH4_INV + VCOUT_SEL + 26 + 1 + read-write + + + 0 + COMP + 0 + + + 1 + COMP Inverse + 1 + + + + + VC_CH4 + VCOUT_SEL + 27 + 1 + read-write + + + 0 + COMP(Used in conjunction with Vc_CH4_inv)) + 0 + + + 1 + CH4_CON[14:12] + 1 + + + + + COMP0D_SEL + COMP0D Selection + 28 + 1 + read-write + + + COMP1D_SEL + COMP1D Selection + 29 + 1 + read-write + + + LVD_SEL + LVD Selection + 30 + 1 + read-write + + + WDG_SEL + Watchdog Selection + 31 + 1 + read-write + + + + + PRSTEN1 + peripheral modules reset + 0x40 + 32 + 0 + 0xFFFFFFFF + read-write + + + GPIOA + GPIO reset enable (It should generate pulse signal to reset) + 0 + 1 + read-write + + + GPIOB + GPIO reset enable (It should generate pulse signal to reset) + 1 + 1 + read-write + + + CRC + CRC reset enable (It should generate pulse signal to reset) + 7 + 1 + read-write + + + + + HCLKEN + Enable clock of Modules of AHB + 0x44 + 32 + 0 + 0xFFFFFFFF + read-write + + + GPIOA + GPIO clock enable + 0 + 1 + read-write + + + GPIOB + GPIO clock enable + 1 + 1 + read-write + + + CRC + CRC clock enable + 7 + 1 + read-write + + + + + EVT_SEL + Event select + 0x48 + 32 + 0 + 0xFFFFFFFF + read-write + + + IRQSEL + Link interrupt source as event (bit-order is IRQ number) + 0 + 32 + read-write + + + + + NMICR + NMI Control Register + 0x4C + 32 + 0 + 0xFFFFFFFF + read-write + + + SEL + Connect IRQ number to NMI + 0 + 5 + read-write + + + EN + Enable to connect IRQ sourec to NMI + 5 + 3 + read-write + + + ON + Enable interrupt link to NMI + 0x5 + + + OFF + Disable interrupt link to NMI + 0 + + + + + + + CHIPID + Chip ID register + 0x100 + 32 + 0 + 0xFFFFFFFF + read-only + + + + + UART + Universal Asynchronous Rx/Tx + 0x40002000 + + 0 + 0x200 + registers + + + + DAT + UART TX/RX Data Register (FIFO: 8) + 0x0 + 32 + 0x0 + 0xFFFFFFFF + read-write + + + DAT + 8/9 bits data + 0 + 9 + read-write + + + FE + Frame error flag + 9 + 1 + read-write + + + + + CR + UART Control Register + 0x4 + 32 + 0x0 + 0xFFFFFFFF + + + MODE + Mode select + 0 + 3 + read-write + + + 8D + 8-bits data + 1 + + + 7D1P + 7-bits data + 1-bit parity + 3 + + + 9D + 9-bits data + 4 + + + 8D1W + 8-bits data + 1-bit wake-up + 5 + + + 8D1P + 8-bits data + 1-bit parity + 7 + + + + + STOPB + width of STOP bits + 3 + 2 + read-write + + + 0_5B + 0.5 bit stop + 0 + + + 1B + 1 bit stop + 1 + + + 1_5B + 1.5 bits stop + 2 + + + 2B + 2 bits stop + 3 + + + + + PAR + Parity check + 5 + 1 + read-write + + + EVEN + Even parity check + 0 + + + ODD + Odd parity check + 1 + + + + + LPB + Enable Loop back mode + 6 + 1 + read-write + + + RUN + Baudrate generator run + 7 + 1 + read-write + + + RXEN + RX enable + 8 + 1 + read-write + + + RXPOL + RX data polarity inverse control + 16 + 1 + read-write + + + TXPOL + TX data polarity inverse control + 17 + 1 + read-write + + + + + BR + UART Baudrate Control Register + 0x8 + 32 + 0x0 + 0xFFFFFFFF + + + BR + Baud-Rate + 0 + 16 + read-write + + + + + IE + UART Interrupt Enable Register + 0x0C + 32 + 0x0 + 0xFFFFFFFF + + + RXNEE + RX FIFO not empty interrupt enable + 0 + 1 + read-write + + + TXEE + TX FIFO empty interrupt enable + 1 + 1 + read-write + + + TXHEE + TX FIFO half-empty interrupt enable + 2 + 1 + read-write + + + PERRE + Parity error interrupt enable + 3 + 1 + read-write + + + FERRE + Frame error interrupt enable + 4 + 1 + read-write + + + OVERRE + RX overflow interrupt enable + 5 + 1 + read-write + + + TONEE + TX time-out interrupt enable + 6 + 1 + read-write + + + TOIDLEE + TX idle time-out interrupt enable + 7 + 1 + read-write + + + RXHFE + RX FIFO half-full interrupt enable + 8 + 1 + read-write + + + RXFE + RX FIFO full interrupt enable + 9 + 1 + read-write + + + TXENDE + TX end interrupt enable + 10 + 1 + read-write + + + TXFE + TX FIFO full interrupt enable + 11 + 1 + read-write + + + RXPE + RX AUTO parity + 12 + 1 + read-write + + + + + SR + UART Status Register + 0x10 + 32 + 0x0 + 0xFFFFFFFF + + + RXNE + RX FIFO not empty + 0 + 1 + read-only + + + TXE + TX FIFO empty + 1 + 1 + read-only + + + TXHE + TX FIFO half-empty + 2 + 1 + read-only + + + PERR + Parity error flag (W1C) + 3 + 1 + read-write + oneToClear + + + FERR + Frame error flag (W1C) + 4 + 1 + read-write + oneToClear + + + OVERR + RX overflow flag (W1C) + 5 + 1 + read-write + oneToClear + + + TONE + Clean RX FIFO time-out + 6 + 1 + read-only + + + TOIDLE + TX idle time-out + 7 + 1 + read-only + + + RXHF + RX FIFO half-full + 8 + 1 + read-only + + + RXF + RX FIFO full + 9 + 1 + read-only + + + TXEND + TX end + 10 + 1 + read-only + + + TXF + TX FIFO full + 11 + 1 + read-only + + + + + GTR + UART Frame Guard-time Register + 0x14 + 32 + 0x0 + 0xFFFFFFFF + + + GT + Frame Guard-Time + 0 + 8 + read-write + + + + + TOR + UART Time-Out Control Register + 0x18 + 32 + 0x0 + 0xFFFFFFFF + + + TO + Time-Out value + 0 + 8 + read-write + + + + + TXFR + Reset UART TX FIFO with any value + 0x1C + 32 + 0x0 + 0xFFFFFFFF + write-only + + + RXFR + Reset UART RX FIFO with any value + 0x20 + 32 + 0x0 + 0xFFFFFFFF + write-only + + + + + UART0 + 0x40002000 + + UART0 + 25 + + + + I2C + Inter-Integrated Circuit + 0x40003000 + + 0 + 0x200 + registers + + + + CTLSET + Register + 0 + 32 + 0x0 + 0xFFFFFFFF + + + CR0 + CLK SET + 0 + 1 + + + CR1 + CLK SET + 1 + 1 + + + AA + answer control + 2 + 1 + + + SI + interrupt flag + 3 + 1 + + + STO + stop control + 4 + 1 + + + STA + start control + 5 + 1 + + + EN + enable + 6 + 1 + + + CR2 + clk control + 7 + 1 + + + + + STAT + Register + 0X04 + 32 + 0x1F + 0xFFFFFFFF + + + STAT + BUS STATUS + 3 + 5 + + + + + DATA + Register + 0X08 + 32 + 0x0 + 0xFFFFFFFF + + + DATA + SEND OR RECEIVE DATA + 0 + 8 + + + + + ADDR + Register + 0X0C + 32 + 0x0 + 0xFFFFFFFF + + + GC + radio enable + 0 + 1 + + + ADDR + addre + 1 + 7 + + + FILTERDELAY + FILTERDELAY + 16 + 4 + + + FILTERDELAY_EN + FILTERDELAY_EN + 24 + 8 + + + + + CTLCLR + Register + 0X18 + 32 + 0x0 + 0xFFFFFFFF + + + CR0 + CLEAT CR0 + 0 + 1 + + + CR1 + CLEAT CR1 + 1 + 1 + + + AA + CLEAT 11 + 2 + 1 + + + SI + CLEAT SI + 3 + 1 + + + STO + CLEAT STO + 4 + 1 + + + STA + CLEAT STA + 5 + 1 + + + EN + CLEAT EN + 6 + 1 + + + CR2 + CLEAT CR2 + 7 + 1 + + + + + + + I2C0 + 0x40003000 + + I2C0 + 26 + + + + SPI + Serial Peripheral Interface Bus + 0x40003800 + + 0 + 0x200 + registers + + + + + CFG + Register + 0x0 + 32 + 0x00020000 + 0xFFFFFFFF + + + MODE + mode select + 0 + 1 + + + CPOL + clock polarity + 1 + 1 + + + CPHA + clock phase + 2 + 1 + + + DB + baud rate + 3 + 3 + + + TXWDSZ + tx data size + 6 + 2 + + + LSB + transmit control + 8 + 1 + + + SS_OUT + periphare select + 10 + 1 + + + MCS + handler section select + 14 + 1 + + + MSE + handler mode select + 15 + 1 + + + MSTC + handler command start + 16 + 1 + + + MODEF + mode fail enable + 17 + 1 + + + + + STA + Register + 0x04 + 32 + 0x04 + 0xFFFFFFFF + + + RECVOV + RX overbrim flag + 0 + 1 + + + MDF + mode false + 1 + 1 + + + TXNFUL + TX FIFO no full + 2 + 1 + + + TXFUL + TX FIFO full + 3 + 1 + + + RXNEP + RX not empty + 4 + 1 + + + RXFUL + RX full + 5 + 1 + + + TXUFL + TX underflow + 6 + 1 + + + BUSY + module busy + 7 + 1 + + + + + INTEN + Register + 0x08 + 32 + 0x0 + 0xFFFFFFFF + + + INTEN + interrupt enable + 0 + 7 + + + + + INTDIS + Register + 0x0C + 32 + 0x0 + 0xFFFFFFFF + + + INTEN + close interrupt + 0 + 7 + + + + + INTMASK + Register + 0x10 + 32 + 0x0 + 0xFFFFFFFF + + + INTEN + interrupt mask + 0 + 7 + + + + + EN + Register + 0x14 + 32 + 0x0 + 0xFFFFFFFF + + + EN + spi module enable + 0 + 1 + + + + + DELAY + Register + 0x18 + 32 + 0x0 + 0xFFFFFFFF + + + d_int + + 0 + 8 + + + d_affter + + 8 + 8 + + + d_btwn + + 16 + 8 + + + d_nss + + 24 + 8 + + + + + TX + Register + 0x1C + 32 + 0x0 + 0xFFFFFFFF + + + RX + Register + 0x20 + 32 + 0x0 + 0xFFFFFFFF + + + IDLECNT + Register + 0x24 + 32 + 0xff + 0xFFFFFFFF + + + IDLECNT + + 0 + 8 + + + + + TXTH + Register + 0x28 + 32 + 0x0 + 0xFFFFFFFF + + + TXTHOLD + cause no full interrupt + 0 + 32 + + + + + RXTH + Register + 0x2C + 32 + 0x0 + 0xFFFFFFFF + + + RXTHOLD + cause no empty interrupt + 0 + 32 + + + + + + + SPI0 + 0x40003800 + + SPI0 + 24 + + + + WDG + Watchdog + 0x40004000 + + 0 + 0x410 + registers + + + WDG + 23 + + + + + LOAD + WDT LOAD Register + 0x000 + 32 + 0xFFFFFFFF + 0xFFFFFFFF + read-write + + + + VALUE + WDT Counter Register + 0x004 + 32 + 0xFFFFFFFF + 0xFFFFFFFF + read-only + + + + CR + WDT Control Register + 0x008 + 32 + 0x0 + 0xFFFFFFFF + read-write + + + INTE + Enable interrupt + 0 + 1 + read-write + + + IRQ_OFF + WDT disable interrupt + 0 + + + IRQ_ON + WDT enable interrupt + 1 + + + + + RSTE + Enable Reset + 1 + 1 + read-write + + + DBGE + Enable Debug Pending + 2 + 1 + read-write + + + + + + INTCLR + WDT interrupt clear Register + 0x00C + 32 + 0x0 + 0xFFFFFFFF + write-only + + + + RIS + WDT original interrupt flag Register + 0x010 + 32 + 0x0 + 0xFFFFFFFF + read-only + + + RIF + original interrupt flag + 0 + 1 + read-only + + + + + + MIS + WDT MASK interrupt flag Register + 0x014 + 32 + 0x0 + 0xFFFFFFFF + read-only + + + MIF + MASK interrupt flag + 0 + 1 + read-only + + + + + + LOCK + WDT LOCK Register + 0x400 + 32 + 0x0 + 0xFFFFFFFF + read-write + + + LOCK + WDT LOCK Control + 0 + 1 + read-write + + + + + + + ADC + Analog-to-Digital Converter + 0x40004800 + + 0 + 0x200 + registers + + + + + CON0 + AD Control Register + 0 + 32 + 0xC0400000 + 0xFFFFFFFF + + + M + ADC input channel select + 0 + 4 + read-write + + + AIN0 + Input channel + 0 + + + AIN1 + Input channel + 1 + + + AIN2 + Input channel + 2 + + + AIN3 + Input channel + 3 + + + AIN4 + Input channel + 4 + + + AIN5 + Input channel + 5 + + + AIN6 + Input channel + 6 + + + AIN7 + Input channel + 7 + + + AIN8 + Input channel + 8 + + + AIN9 + Input channel + 9 + + + AIN10 + Input channel + 10 + + + AIN11 + Input channel + 11 + + + AIN12 + Input channel + 12 + + + AIN13 + Input channel + 13 + + + AIN14 + Input channel + 14 + + + AIN15 + Input channel + 15 + + + + + EN + ADC module enable + 5 + 1 + read-write + + + START + AD conversion start + 7 + 1 + read-write + + + CLK + ADC clock divider (800KHz ~ 16MHz) + 8 + 3 + read-write + + + Div2 + PCLK/2 + 0 + + + Div4 + PCLK/4 + 1 + + + Div8 + PCLK/8 + 2 + + + Div16 + PCLK/16 + 3 + + + Div32 + PCLK/32 + 4 + + + Div64 + PCLK/64 + 5 + + + Div3_75 + PCLK/3.75 + 6 + + + Div3_5 + PCLK/3.5 + 7 + + + + + TRIG_EN + Enable H/w trigger + 11 + 1 + read-write + + + CONTINUE + Enable continue mode + 12 + 1 + read-write + + + ALIGN + ADC result align moe + 13 + 1 + read-write + + + RIGHT + right align + 0 + + + LEFT + left align + 1 + + + + + ENCONT + 1: Never Stop Conversion in continue mode + 15 + 1 + read-write + + + INT_EN + Enable ADC interrupt + 16 + 4 + read-write + + + DISABLE + Disable interrupt + 0 + + + DONE + Interrupt when conversion done + 1 + + + GT_THR + Result is greater then threshold + 2 + + + LT_THR + Result is littler then threshold + 4 + + + EQ_THR + Result is equal to threshold + 8 + + + + + TZO + zero offset change + 20 + 3 + read-write + + + LSB_MINUS_4 + -4 LSB + 0 + + + LSB_MINUS_3 + -3 LSB + 1 + + + LSB_MINUS_2 + -2 LSB + 2 + + + LSB_MINUS_1 + -1 LSB + 3 + + + LSB + keep LSB value + 4 + + + LSB_PLUS_1 + +1 LSB + 5 + + + LSB_PLUS_2 + +2 LSB + 6 + + + LSB_PLUS_3 + +3 LSB + 7 + + + + + BAKEN + Enable backup the previous conversion value + 29 + 1 + read-write + + + PWD + Power down analog physical module + 30 + 1 + read-write + + + RST + Reset analog physical module + 31 + 1 + read-write + + + + + + STAT + ADC State Registter + 0x4 + 32 + 0x00030040 + 0xFFFFFFFF + + + DONE + ADC done(auto clear after read reg DATx) + 0 + 1 + read-only + + + INT_CLR + ADC clear interrupt flag, 1:clear + 1 + 1 + read-write + + + COMP_RESULT + Result of Comparison(auto clear after read reg DATx) + 4 + 2 + read-only + + + NONE + Auto-clear after read reg DATx + 0 + + + GT_THR + Result is greater then threshold + 1 + + + LT_THR + Result is littler then threshold + 2 + + + EQ_THR + Result is equal to threshold + 3 + + + + + EOC_CHECK_DIS + Disable End-of-Conversion checking + 6 + 1 + read-write + + + TS_SET + Set Ts cycles + 16 + 5 + read-write + + + DLY_SET + Set delay cycles with ADC clock + 21 + 3 + read-write + + + DLY_12 + Deley 12 cycles + 0 + + + DLY_14 + Deley 14 cycles + 1 + + + DLY_18 + Deley 18 cycles + 2 + + + DLY_24 + Deley 24 cycles + 3 + + + DLY_26 + Deley 26 cycles + 4 + + + + + EOC_CNT + Count of End-of-Conversion + 24 + 4 + read-only + + + START_CNT + Count of Start + 28 + 4 + read-only + + + + + + DAT0 + ADC Result0 Register + 0x8 + 32 + 0x0 + 0xFFFFFFFF + + + DATA + ADC result data + 0 + 16 + read-only + + + CMPTH + Comparison threshold + 16 + 12 + read-write + + + + + + DAT1 + ADC Result1 Register + 0xC + 32 + 0x0 + 0xFFFFFFFF + + + DATA + ADC result data + 0 + 16 + read-only + + + CMPTH + Comparison threshold + 16 + 12 + read-write + + + + + + DAT2 + ADC Result2 Register + 0x10 + 32 + 0x0 + 0xFFFFFFFF + + + DATA + ADC result data + 0 + 16 + read-only + + + CMPTH + Comparison threshold + 16 + 12 + read-write + + + + + + DAT3 + ADC Result3 Register + 0x14 + 32 + 0x0 + 0xFFFFFFFF + + + DATA + ADC result data + 0 + 16 + read-only + + + CMPTH + Comparison threshold + 16 + 12 + read-write + + + + + + DAT4 + ADC Result4 Register + 0x18 + 32 + 0x0 + 0xFFFFFFFF + + + DATA + ADC result data + 0 + 16 + read-only + + + CMPTH + Comparison threshold + 16 + 12 + read-write + + + + + + DAT5 + ADC Result5 Register + 0x1C + 32 + 0x0 + 0xFFFFFFFF + + + DATA + ADC result data + 0 + 16 + read-only + + + CMPTH + Comparison threshold + 16 + 12 + read-write + + + + + + DAT6 + ADC Result6 Register + 0x20 + 32 + 0x0 + 0xFFFFFFFF + + + DATA + ADC result data + 0 + 16 + read-only + + + CMPTH + Comparison threshold + 16 + 12 + read-write + + + + + + DAT7 + ADC Result7 Register + 0x24 + 32 + 0x0 + 0xFFFFFFFF + + + DATA + ADC result data + 0 + 16 + read-only + + + CMPTH + Comparison threshold + 16 + 12 + read-write + + + + + + DAT8 + ADC Result8 Register + 0x28 + 32 + 0x0 + 0xFFFFFFFF + + + DATA + ADC result data + 0 + 16 + read-only + + + CMPTH + Comparison threshold + 16 + 12 + read-write + + + + + + DAT9 + ADC Result9 Register + 0x2C + 32 + 0x0 + 0xFFFFFFFF + + + DATA + ADC result data + 0 + 16 + read-only + + + CMPTH + Comparison threshold + 16 + 12 + read-write + + + + + + DAT10 + ADC Result10 Register + 0x30 + 32 + 0x0 + 0xFFFFFFFF + + + DATA + ADC result data + 0 + 16 + read-only + + + CMPTH + Comparison threshold + 16 + 12 + read-write + + + + + + DAT11 + ADC Result11 Register + 0x34 + 32 + 0x0 + 0xFFFFFFFF + + + DATA + ADC result data + 0 + 16 + read-only + + + CMPTH + Comparison threshold + 16 + 12 + read-write + + + + + + DAT12 + ADC Result12 Register + 0x38 + 32 + 0x0 + 0xFFFFFFFF + + + DATA + ADC result data + 0 + 16 + read-only + + + CMPTH + Comparison threshold + 16 + 12 + read-write + + + + + + DAT13 + ADC Result13 Register + 0x3C + 32 + 0x0 + 0xFFFFFFFF + + + DATA + ADC result data + 0 + 16 + read-only + + + CMPTH + Comparison threshold + 16 + 12 + read-write + + + + + + DAT14 + ADC Result14 Register + 0x40 + 32 + 0x0 + 0xFFFFFFFF + + + DATA + ADC result data + 0 + 16 + read-only + + + CMPTH + Comparison threshold + 16 + 12 + read-write + + + + + + DAT15 + ADC Result13 Register + 0x44 + 32 + 0x0 + 0xFFFFFFFF + + + DATA + ADC result data + 0 + 16 + read-only + + + CMPTH + Comparison threshold + 16 + 12 + read-write + + + + + CHSEL + ADC channel selection Register + 0x48 + 32 + 0x0 + 0xFFFFFFFF + + + CH_SEL + Channel 0~15 + 0 + 16 + read-write + + + CH_CNT + Selected Channel Count + 16 + 4 + read-write + + + DISC_INTSEL + Select interrupt condition when DISCEN==1 + 21 + 1 + read-write + + + DISCNUM + Discontinuous mode channel count (DISCNUM+1) + 22 + 3 + read-write + + + DISCEN + Discontinuous mode Enable + 25 + 1 + read-write + + + TRIG_SEL16 + Trigger Selection 16 + 26 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + TIM0_OVERFLOW + TIM0 overflow trigger + 1 + + + + + TRIG_SEL17 + Trigger Selection 17 + 28 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + PIN + PB1/PB2 trigger + 1 + + + + + EXTRIG_SEL + External Trigger Selection + 30 + 2 + read-write + + + PB1_RISING + PB1 rising trigger + 0 + + + PB1_FALLING + PB1 falling trigger + 1 + + + PB2_RISING + PB2 rising trigger + 2 + + + PB2_FALLING + PB2 falling trigger + 3 + + + + + + + TRGSEL + ADC Trigger selection Register + 0x4C + 32 + 0x0 + 0xFFFFFFFF + + + TRIG_SEL0 + Trigger Selection 0 + 0 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + EPWM_CH1_RISING + EPWM0P(CH1) Rising + 1 + + + + + TRIG_SEL1 + Trigger Selection 1 + 2 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + EPWM_CH2_RISING + EPWM0P(CH2) Rising + 1 + + + + + TRIG_SEL2 + Trigger Selection 2 + 4 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + EPWM_CH3_RISING + EPWM0P(CH3) Rising + 1 + + + + + TRIG_SEL3 + Trigger Selection 3 + 6 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + EPWM_CH1_FALLING + EPWM0P(CH1) Falling + 1 + + + + + TRIG_SEL4 + Trig Selection 4 + 8 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + EPWM_CH2_FALLING + EPWM0P(CH2) Falling + 1 + + + + + TRIG_SEL5 + Trigger Selection 5 + 10 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + EPWM_CH3_FALLING + EPWM0P(CH3) Falling + 1 + + + + + TRIG_SEL6 + Trigger Selection 6 + 12 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + COMP0_RISING + COMP0 Rising + 1 + + + + + TRIG_SEL7 + Trigger Selection 7 + 14 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + COMP0_FALLING + COMP0 Falling + 1 + + + + + TRIG_SEL8 + Trigger Selection 8 + 16 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + COMP1_RISING + COMP1 Rising + 1 + + + + + TRIG_SEL9 + Trigger Selection 9 + 18 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + COMP1_FALLING + COMP1 Falling + 1 + + + + + TRIG_SEL10 + Trig Selection 10 + 20 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + EPWM_UDF + EPWM Counter Underflow + 1 + + + + + TRIG_SEL11 + Trigger Selection 11 + 22 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + EPWM_OVF + EPWM Counter Overflow + 1 + + + + + TRIG_SEL12 + Trigger Selection 12 + 24 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + EPWM_CCR4_UP + EPWM CCR4 up-count + 1 + + + + + TRIG_SEL13 + Trigger Selection 13 + 26 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + EPWM_CCDR4_UP + EPWM CCDR4 up-count + 1 + + + + + TRIG_SEL14 + Trigger Selection 14 + 28 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + EPWM_CCR4_DN + EPWM CCR4 down-count + 1 + + + + + TRIG_SEL15 + Trig Selection 15 + 30 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + EPWM_CCDR4_DN + EPWM CCDR4 down-count + 1 + + + + + + + BKSEL + Brake Source (from ADC) Control Register + 0x50 + 32 + 0x0 + 0xFFFFFFFF + + + BK1_CH + Select a channel as brake source 1 + 0 + 4 + read-write + + + BK1_FLT + Filter the brake source 1 + 4 + 2 + read-write + + + OFF + Disable filter the brake from ADC source 1 + 0 + + + MATCH_2 + Brake if result matches 2-times + 1 + + + MATCH_4 + Brake if result matches 4-times + 2 + + + MATCH_7 + Brake if result matches 7-times + 3 + + + + + BK1_EN + Enable ondition of brake + 6 + 2 + read-write + + + OFF + Disable brake from ADC source 1 + 0 + + + GT_THR + Result is greater then threshold + 1 + + + LT_THR + Result is littler then threshold + 2 + + + EQ_THR + Result is equal to threshold + 3 + + + + + BK2_CH + Select a channel as brake source 2 + 8 + 4 + read-write + + + BK2_FLT + Filter the brake source 2 + 12 + 2 + read-write + + + OFF + Disable filter the brake from ADC source 2 + 0 + + + MATCH_2 + Brake if result matches 2-times + 1 + + + MATCH_4 + Brake if result matches 4-times + 2 + + + MATCH_7 + Brake if result matches 7-times + 3 + + + + + BK2_EN + Enable ondition of brake + 14 + 2 + read-write + + + OFF + Disable brake from ADC source 1 + 0 + + + GT_THR + Result is greater then threshold + 1 + + + LT_THR + Result is littler then threshold + 2 + + + EQ_THR + Result is equal to threshold + 3 + + + + + + + BAKDAT + Data Register of ADC Conversion backup value + 0x54 + 32 + 0x0 + 0xFFFFFFFF + + + BAKDAT + backup Data + 0 + 16 + read-only + + + + + + + ADC0 + 0x40004800 + + ADC0 + 31 + + + + AMISC + Analog MISC controller + 0x40005800 + + 0 + 0x34 + registers + + + LVD + 33 + + + + LVD_LVR_CR + LVD/LVR Control Register + 0x00 + 32 + 0 + 0xFFFFFFFF + read-write + + + LVD_EN + LVD enable + 0 + 1 + read-write + + + LDO_LP_EN + LDO lower power enable + 1 + 1 + read-write + + + LVD_F_SEL + LVD Filter Selection + 2 + 2 + read-write + + + LVD_SEL + LVD selection + 5 + 3 + read-write + + + 2V + 2.0V + 0x0 + + + 2_2V + 2.2V + 0x1 + + + 2_4V + 2.4V + 0x2 + + + 2_7V + 2.7V + 0x3 + + + 3V + 3.0V + 0x4 + + + 3_7V + 3.7V + 0x5 + + + 4V + 4.0V + 0x6 + + + 4_3V + 4.3V + 0x7 + + + + + LVR_EN + LVR enable + 8 + 1 + read-write + + + LVD_INT_EN + LVD interrupt enable + 9 + 1 + read-write + + + TEMP_EN + Temperature enable + 10 + 1 + read-write + + + LVD_STATE + LVD state, 0: VDD < LVD_SEL, 1: VDD > LVD_SEL + 11 + 1 + read-only + + + LVR_SEL + LVR selection + 13 + 3 + read-write + + + 2V + 2.0V + 0x0 + + + 2_4V + 2.4V + 0x1 + + + 2_7V + 2.7V + 0x2 + + + 3V + 3V + 0x3 + + + 3_7V + 3.7V + 0x4 + + + + + + + VBUF_CR + Vbuf Control Register + 0x04 + 32 + 0 + 0xFFFFFFFF + read-write + + + VBUF_EN + VBUF enable + 0 + 1 + read-write + + + ANA2IO_EN + Test analog signal to I/O + 4 + 1 + read-write + + + ANA2PGA_EN + Test analog signal to PGA0 + 5 + 1 + read-write + + + ANA_SEL + Test analog signal selection + 6 + 7 + read-write + + + NONE + None + 0x0 + + + TEMP + temp out + 0x1 + + + DAC0 + DAC 0 + 0x2 + + + DAC1 + DAC 1 + 0x4 + + + VBuf_1p5v + vbuf 1p5v out + 0x8 + + + VDDL + vddl + 0x10 + + + VSS + vss + 0x20 + + + VDD + vdd + 0x40 + + + + + + + DAC_CR + DAC Control Register + 0x10 + 32 + 0 + 0xFFFFFFFF + read-write + + + DAC0Step + The step of voltage + 0 + 10 + read-write + + + DAC1Step + The step of voltage + 10 + 10 + read-write + + + DAC0_EN + DAC0 enable + 20 + 1 + read-write + + + DAC1_EN + DAC1 enable + 21 + 1 + read-write + + + + + HSI_CR + HSI (OSCHF) Control Register + 0x20 + 32 + 0 + 0xFFFFFFFF + read-write + + + LDO_SEL + HSI power source selection + 0 + 16 + read-write + + + LDO + ldo_oschf Disable abd vddl_oschf from ldo + 0x8080 + + + Normal + do_oschf Enable and vddl_oschf from ldo_oschf + 0x0101 + + + + + HSI_EN + HSI enable, set 0x80(disable), set 0x1(enable) + 24 + 8 + read-write + + + + + LSI_CR + LSI (OSCLF) Control Register + 0x24 + 32 + 0 + 0xFFFFFFFF + read-write + + + LSI_EN + LSI enable, set 0x80(disable), set 0x1(enable) + 24 + 8 + read-write + + + + + ADC_AIN_CR + ADC AIN Control Register + 0x30 + 32 + 0 + 0xFFFFFFFF + read-write + + + ANA2ADC_EN + Enable ADC AIN15 from internal source + 0 + 1 + read-write + + + + + + + HWTRIM + H/w configure trim values + 0x40005860 + + 0 + 0x20 + registers + + + + + LDO_TRIM + LDO trim value + 0x00 + 32 + 0x0 + 0xFFFFFFFF + read-only + + + LDO_TRIM + LDO trim value + 0 + 5 + read-only + + + LDO_LP_TRIM + LDO lower power trim value + 5 + 5 + read-only + + + LDO_TUNE + Ldo high temp leakage current compensation + 10 + 2 + read-only + + + STRENGTH + strength + 0x0 + + + WEAK + weak + 0x1 + + + MIDDLEddle + middle + 0x2 + + + OFF + off + 0x3 + + + + + + + + VBUF_TRIM + Vbuf trim value + 0x04 + 32 + 0 + 0xFFFFFFFF + read-only + + + VBUF_TRIM + VBUF voltage trim value + 0 + 7 + read-only + + + + + HSI_TRIM + High Speed Internal clock (OSCHF) trim value + 0x08 + 32 + 0 + 0xFFFFFFFF + read-only + + + HSI_D_CFG + HSI low trim config + 0 + 9 + read-only + + + HSI_FSEL_CFG + HSI high trim config + 9 + 7 + read-only + + + HSI_TC + The TC of HSI trim value + 16 + 2 + read-only + + + + + + LSI_TRIM + Low Speed Internal clock (OSCLF) trim value + 0x0C + 32 + 0 + 0xFFFFFFFF + read-only + + + LSI_TRIM + The LSI trim value, 0xB3= 32KHz + 0 + 8 + read-only + + + + + MISC_CFG + The miscellaneous configuration + 0x10 + 32 + 0 + 0xFFFFFFFF + read-only + + + EXT_nRST_EN + External reset pin enable + 0 + 1 + read-only + + + + + + + + + CRC + Cyclic redundancy check + 0x4001E000 + + 0 + 0x200 + registers + + + + CR + Control Register + 0x00 + 32 + 0 + 0xFFFFFFFF + + + POLYSEL + CRC polynomial codes select + 0 + 1 + read-write + + + CRC16 + x16 + x12 + x5 + 1 + 1 + + + CRC32 + x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1 + 0 + + + + + VERF + flag of verificaion CRC value + 1 + 1 + read-only + + + + + DIN + CRC Data input Register + 0x04 + 32 + 0 + 0xFFFFFFFF + + + DIN + Input Data + 0 + 32 + read-write + + + + + DOUT + Result output register + 0x08 + 32 + 0x0 + 0xFFFFFFFF + + + DOUT + CRC value + 0 + 32 + read-write + + + + + + + DSP + DSP hardware speedup + 0x40008000 + + 0 + 0x400 + registers + + + + + CR + DSP ACCEL Control Register + 0x00 + 32 + 0x0 + 0xFFFFFFFF + read-write + + + MODE + Mode selection + 0 + 3 + read-write + + + DIV + 32-bits Divide Mode + 1 + + + SQRT + square root mode + 4 + + + + + + + SR + DSP ACCEL Status Register + 0x04 + 32 + 0x0 + 0xFFFFFFFF + read-only + + + DONE + DSP End + 0 + 1 + read-only + + + + + SDAT1 + DSP ACCEL Source Data1 + 0x08 + 32 + 0x00000000 + 0xFFFFFFFF + read-write + + + SDAT2 + DSP ACCEL Source Data2 + 0x10 + 32 + 0x00000000 + 0xFFFFFFFF + read-write + + + RSLT1 + DSP ACCEL Result 1 + 0x018 + 32 + 0x00000000 + 0xFFFFFFFF + read-only + + + RSLT2 + DSP ACCEL Result 2 + 0x20 + 32 + 0x00000000 + 0xFFFFFFFF + read-only + + + + + OPAMP + OP-Amplifiers with PGA mode + 0x40005880 + + 0 + 0x8 + registers + + + + PGA_CR + Control Register + 0x00 + 32 + 0 + 0xFFFFFFFF + read-write + + + PGA_EN + Enable PGA + 0 + 1 + read-write + + + PGA_IO_EN + Enable PGA output to I/O + 1 + 1 + read-write + + + PGA_GAIN + PGA gain selection + 2 + 6 + read-write + + + x1 + Multiple of gain + 0x1 + + + x2 + Multiple of gain + 0x6 + + + x3 + Multiple of gain + 0xA + + + x4 + Multiple of gain + 0xE + + + x5 + Multiple of gain + 0x12 + + + x6 + Multiple of gain + 0x16 + + + x7 + Multiple of gain + 0x1A + + + x8 + Multiple of gain + 0x1E + + + x9 + Multiple of gain + 0x22 + + + x10 + Multiple of gain + 0x26 + + + x11 + Multiple of gain + 0x2A + + + x12 + Multiple of gain + 0x2E + + + x13 + Multiple of gain + 0x32 + + + x14 + Multiple of gain + 0x36 + + + x15 + Multiple of gain + 0x3A + + + x16 + Multiple of gain + 0x3E + + + + + PGA_VIN_SEL + PGA N terminal selection + 10 + 1 + read-write + + + PGA_VIP_SEL + PGA P terminal selection + 11 + 1 + read-write + + + + + + + OPAMP0 + 0x40005880 + + + OPAMP1 + 0x40005888 + + + COMP + Analog Comparator + 0x40008800 + + 0 + 0x800 + registers + + + + CTRL + COMP Control Register + 0x00 + 32 + 0 + 0xFFFFFFFF + read-write + + + EN + COMP Enable + 0 + 1 + read-write + + + COUT + COMP Output + 1 + 1 + read-only + + + VIN_SEL + Comp n terminal input selection + 2 + 2 + read-write + + + IO + selction IO Pin + 1 + + + DAC + selction DAC + 2 + + + + + FIL_CTRL + Filter selction + 4 + 4 + read-write + + + BYPASS + No filter + 0x0 + + + SAMPLE_2 + sample 2 times + 0x1 + + + SAMPLE_4 + sample 4 times + 0x2 + + + SAMPLE_8 + sample 8 times + 0x3 + + + SAMPLE_16 + sample 16 times + 0x4 + + + SAMPLE_32 + sample 32 times + 0x5 + + + SAMPLE_64 + sample 64 times + 0x6 + + + SAMPLE_128 + sample 128 times + 0x7 + + + SAMPLE_256 + sample 256 times + 0x8 + + + + + HYS_EN + hysteresis enable + 8 + 1 + read-write + + + OUT_EN + Comp output signal + 11 + 1 + read-write + + + NONE + No signal output + 0 + + + IO + select IO output + 1 + + + + + POL_SEL + Select output polarity + 12 + 1 + read-write + + + NORMAL + Normal polarity output + 0 + + + INVERT + Inverted + 1 + + + + + + + VIPSEL + COMP P terminal DAC Register + 0x04 + 32 + 0 + 0xFFFFFFFF + read-write + + + VIP_SEL + Comp p terminal input selection + 0 + 5 + read-write + + + IO3 + I/O PA15 + 0x10 + + + IO2 + I/O PA14 + 0x08 + + + IO1 + I/O PA11 + 0x04 + + + IO0 + I/O PA8 + 0x02 + + + PGA + Select PGA + 0x01 + + + + + + + IR + COMP Interrupt Register + 0x08 + 32 + 0 + 0xFFFFFFFF + read-write + + + FIE + Enable Comp Interrupt with Falling + 0 + 1 + read-write + + + RIE + Enable Comp Interrupt with Rising + 1 + 1 + read-write + + + + + IF + COMP Interrupt Flag Register + 0x0C + 32 + 0 + 0xFFFFFFFF + read-write + + + FIF + Interrupt Falling Flag, W1C + 0 + 1 + read-write + + + RIF + Interrupt Rising Flag, W1C + 1 + 1 + read-write + + + + + INITCNT + COMP set initial delay register + 0x10 + 32 + 0X0000003C + 0xFFFFFFFF + read-write + + + INIT_DELAY + Comp Set Delay + 0 + 10 + read-write + + + + + + + COMP0 + 0x40008800 + + COMP0 + 29 + + + + COMP1 + 0x40009800 + + COMP1 + 30 + + + + TIM + Timer Controller Module + 0x4000C000 + + 0 + 0x400 + registers + + + + CR1 + Control Register 1 + 0 + 32 + 0x0 + 0xFFFFFFFF + + + CEN + Counter enable + 0 + 1 + + + UDIS + Update disable + 1 + 1 + + + URS + Update request source + 2 + 1 + + + OPM + One pulse spurce + 3 + 1 + + + DIR + Direction + 4 + 1 + + + CMS + Center-aligned mode selection + 5 + 2 + + + EDGE + edge mode + 0 + + + CENTER1 + center mode 1: count-up will trigger interrupt + 1 + + + CENTER2 + center mode 2: count-down will trigger interrupt + 2 + + + CENTER3 + center mode 3: count-up and count-down will trigger interrupt + 3 + + + + + ARPE + Auto-reload preload enable + 7 + 1 + + + CKD + Clock division + 8 + 2 + + + 0 + Tdts = tck_in + 0 + + + 1 + Tdts = tck_in*2 + 1 + + + 2 + Tdts = tck_in*4 + 2 + + + 3 + reserve + 3 + + + + + ASYMEN + Asymmetric mode enable + 10 + 1 + + + + + CR2 + Control Register 2 + 0x04 + 32 + 0x0 + 0xFFFFFFFF + + + CCPC + Capture/compare preloaded control + 0 + 1 + + + CCUS + Capture/compare control update selection + 2 + 1 + + + MMS + Master mode selection + 4 + 3 + + + RESET + UG Trigger TRGO + 0 + + + ENABLE + CEN Trigger TRGO + 1 + + + UPDATE + UPDATE Trigger TRGO + 2 + + + COMPARE + COMPARE/CAPTURE Trigger TRGO + 3 + + + OC1REF + OC1REF Trigger TRGO + 4 + + + OC2REF + OC2REF Trigger TRGO + 5 + + + OC3REF + OC3REF Trigger TRGO + 6 + + + OC4REF + OC4REF Trigger TRGO + 7 + + + + + TI1S + TI1 selection + 7 + 1 + + + OIS1 + Output Idle state 1 + 8 + 1 + + + OIS1N + Output Idle state 1 + 9 + 1 + + + OIS2 + Output Idle state 2 + 10 + 1 + + + OIS2N + Output Idle state 2 + 11 + 1 + + + OIS3 + Output Idle state 3 + 12 + 1 + + + OIS3N + Output Idle state 3 + 13 + 1 + + + OIS4 + Output Idle state 4 + 14 + 1 + + + + + SMCR + Slave Mode control Register + 0X08 + 32 + 0x0 + 0xFFFFFFFF + + + SMS + Slave mode selection + 0 + 3 + + + DISABLE + close Slave mode + 0 + + + Encode1 + Encode mode 1: + 1 + + + Encode2 + Encode mode 2 + 2 + + + Encode3 + Encode mode 3 + 3 + + + RESET + Reset mode + 4 + + + WINDOW + Window mode + 5 + + + TRIGGER + trigger mode + 6 + + + EXTCLK + External clock mode 1 + 7 + + + + + TS + Trigger selection + 4 + 3 + + + ITR0 + ITR0 + 0 + + + ITR1 + ITR1: + 1 + + + ITR2 + ITR2 + 2 + + + ITR3 + ITR3 + 3 + + + TI1F_ED + TI1F_ED + 4 + + + T1FP1 + T1FP1 + 5 + + + T1FP2 + T1FP2 + 6 + + + ETRF + ETRF + 7 + + + + + MSM + Master/slave mode + 7 + 1 + + + ETF + External trigger filter + 8 + 4 + + + 0 + No filter + 0 + + + 1 + fsampling = fclk_int,N=2 + 1 + + + 2 + fsampling = fclk_int,N=4 + 2 + + + 3 + fsampling = fclk_int,N=8 + 3 + + + 4 + fsampling = Fdts/2,N=6 + 4 + + + 5 + fsampling = Fdts/2,N=8 + 5 + + + 6 + fsampling = Fdts/4,N=6 + 6 + + + 7 + fsampling = Fdts/4,N=8 + 7 + + + 8 + fsampling = Fdts/8,N=6 + 8 + + + 9 + fsampling = Fdts/8,N=8 + 9 + + + 10 + fsampling = Fdts/16,N=5 + 10 + + + 11 + fsampling = Fdts/16,N=6 + 11 + + + 12 + fsampling = Fdts/16,N=8 + 12 + + + 13 + fsampling = Fdts/32,N=5 + 13 + + + 14 + fsampling = Fdts/32,N=6 + 14 + + + 15 + fsampling = Fdts/32,N=8 + 15 + + + + + ETPS + External trigger prescaler + 12 + 2 + + + ECE + External clock enable + 14 + 1 + + + ETP + External trigger polarity + 15 + 1 + + + + + DIER + interrupt enbale register + 0X0C + 32 + 0x0 + 0xFFFFFFFF + + + UIE + Update interrupt enable + 0 + 1 + + + CC1IE + Capture/Compare 1 interrupt enable + 1 + 1 + + + CC2IE + Capture/Compare 2 interrupt enable + 2 + 1 + + + CC3IE + Capture/Compare 3 interrupt enable + 3 + 1 + + + CC4IE + Capture/Compare 4 interrupt enable + 4 + 1 + + + COMIE + COM interrupt enable + 5 + 1 + + + TIE + Trigger interrupt enable + 6 + 1 + + + BIE + Break interrupt enable + 7 + 1 + + + CCD1IE + Capture/Compare 1 interrupt enable + 8 + 1 + + + CCD2IE + Capture/Compare 2 interrupt enable + 9 + 1 + + + CCD3IE + Capture/Compare 3 interrupt enable + 10 + 1 + + + OVIE + Overflow interrupt enable + 11 + 1 + + + UDIE + Underflow interrupt enable + 12 + 1 + + + CCD4IE + Capture/Compare 4 interrupt enable + 13 + 1 + + + + + SR + state Register + 0X10 + 32 + 0x0 + 0xFFFFFFFF + + + UIF + Update interrupt flag + 0 + 1 + + + CC1IF + Capture/Compare 1 interrupt flag + 1 + 1 + + + CC2IF + Capture/Compare 2 interrupt flag + 2 + 1 + + + CC3IF + Capture/Compare 3 interrupt flag + 3 + 1 + + + CC4IF + Capture/Compare 4 interrupt flag + 4 + 1 + + + COMIF + COM interrupt flag + 5 + 1 + + + TIF + Trigger interrupt flag + 6 + 1 + + + BIF + Break interrupt flag + 7 + 1 + + + CC1OF + CC1OF + 9 + 1 + read-write + + + CC2OF + CC2OF + 10 + 1 + read-write + + + CC3OF + CC3OF + 11 + 1 + read-write + + + CC4OF + CC4OF + 12 + 1 + read-write + + + CCD1IF + Capture/Compare 1 interrupt flag + 13 + 1 + + + CCD2IF + Capture/Compare 2 interrupt flag + 14 + 1 + + + CCD3IF + Capture/Compare 3 interrupt flag + 15 + 1 + + + OVIF + Overflow interrupt flag + 16 + 1 + + + UDIF + Underflow interrupt flag + 17 + 1 + + + CCD4IF + Break interrupt flag + 18 + 1 + + + + + EGR + event generation Register + 0X14 + 32 + 0x0 + 0xFFFFFFFF + + + UG + Update generation + 0 + 1 + + + CC1G + Capture/Compare 1 generation + 1 + 1 + + + CC2G + Capture/Compare 2 generation + 2 + 1 + + + CC3G + Capture/Compare 3 generation + 3 + 1 + + + CC4G + Capture/Compare 4 generation + 4 + 1 + + + COMG + Capture/Compare control update generation + 5 + 1 + + + TG + Trigger generation + 6 + 1 + + + BG + Break generation + 7 + 1 + + + + + CCMR1_OUTPUT + Capture or Compare mode Register (Output mode) + 0X18 + 32 + 0x0 + 0xFFFFFFFF + + + CC1S + Capture/Compare 1 selection + 0 + 2 + + + OC1FE + Output Compare 1 fast enable + 2 + 1 + + + OC1PE + Output Compare 1 preload enable + 3 + 1 + + + OC1M + Output Compare 1 mode + 4 + 3 + + + OC1CE + Output Compare 1 clear enable + 7 + 1 + + + CC2S + Capture/Compare 2 selection + 8 + 2 + + + OC2FE + Output Compare 2 fast enable + 10 + 1 + + + OC2PE + Output Compare 2 preload enable + 11 + 1 + + + OC2M + Output Compare 2 mode + 12 + 3 + + + OC2CE + Output Compare 2 clear enable + 15 + 1 + + + + + CCMR1_INPUT + Capture or Compare mode Register (Input mode) + CCMR1_OUTPUT + 0X18 + 32 + 0x0 + 0xFFFFFFFF + + + CC1S + Capture or Compare 1 Select + 0 + 2 + read-write + + + IC1PSC + Input capture 1 prescaler + 2 + 2 + read-write + + + IC1F + Input capture 1 filter + 4 + 4 + read-write + + + CC2S + Capture or Compare 2 Select + 8 + 2 + read-write + + + IC2PSC + Input capture 2 prescaler + 10 + 2 + read-write + + + IC2F + Input capture 2 filter + 12 + 4 + read-write + + + + + CCMR2_OUTPUT + Capture or Compare mode Register (output mode) + 0X1C + 32 + 0x0 + 0xFFFFFFFF + + + CC3S + Capture/Compare 3 selection + 0 + 2 + + + OC3FE + Output Compare 3 fast enable + 2 + 1 + + + OC3PE + Output Compare 3 preload enable + 3 + 1 + + + OC3M + Output Compare 3 mode + 4 + 3 + + + OC3CE + Output Compare 3 clear enable + 7 + 1 + + + CC4S + Capture/Compare 4 selection + 8 + 2 + + + OC4FE + Output Compare 4 fast enable + 10 + 1 + + + OC4PE + Output Compare 4 preload enable + 11 + 1 + + + OC4M + Output Compare 4 mode + 12 + 3 + + + OC4CE + Output Compare 4 clear enable + 15 + 1 + + + + + CCMR2_INPUT + Capture or Compare mode Register (input mode) + CCMR2_OUTPUT + 0X1C + 32 + 0x0 + 0xFFFFFFFF + + + CC3S + Capture or Compare 3 Select + 0 + 2 + read-write + + + IC3PSC + Input capture 3 prescaler + 2 + 2 + read-write + + + IC3F + Input capture 3 filter + 4 + 4 + read-write + + + CC4S + Capture or Compare 4 Select + 8 + 2 + read-write + + + IC4PSC + Input capture 4 prescaler + 10 + 2 + read-write + + + IC4F + Input capture 4 filter + 12 + 4 + read-write + + + + + CCER + Capture or Compare enable Register + 0X20 + 32 + 0x0 + 0xFFFFFFFF + + + CC1E + Capture/Compare 1 output enable + 0 + 1 + + + CC1P + Capture/Compare 1 output polarity + 1 + 1 + + + CC1NE + Capture/Compare 1 complementary output enable + 2 + 1 + + + CC1NP + Capture/Compare 1 complementary output polarity + 3 + 1 + + + CC2E + Capture/Compare 2 output enable + 4 + 1 + + + CC2P + Capture/Compare 2 output polarity + 5 + 1 + + + CC2NE + Capture/Compare 2 complementary output enable + 6 + 1 + + + CC2NP + Capture/Compare 2 complementary output polarity + 7 + 1 + + + CC3E + Capture/Compare 3 output enable + 8 + 1 + + + CC3P + Capture/Compare 3 output polarity + 9 + 1 + + + CC3NE + Capture/Compare 3 complementary output enable + 10 + 1 + + + CC3NP + Capture/Compare 3 complementary output polarity + 11 + 1 + + + CC4E + Capture/Compare 4 output enable + 12 + 1 + + + CC4P + Capture/Compare 4 output polarity + 13 + 1 + + + + + CNT + EPWM counter register + 0X24 + 32 + 0x0 + 0xFFFFFFFF + + + CNT + Counter value + 0 + 16 + + + + + PSC + Prescaler counter register + 0X28 + 32 + 0x0 + 0xFFFFFFFF + + + PSC + Prescaler value + 0 + 16 + + + + + ARR + Auto reload counter register + 0X2C + 32 + 0x0 + 0xFFFFFFFF + + + ARR + Auto reload value + 0 + 16 + + + + + RCR + Repetition counter register + 0X30 + 32 + 0x0 + 0xFFFFFFFF + + + REP + Repetition counter value + 0 + 8 + + + + + CCR1 + CR1 capture or compare value + 0X34 + 32 + 0x0 + 0xFFFFFFFF + + + CCR1 + Capture/Compare 1 value + 0 + 20 + + + + + CCR2 + CR2 capture or compare value + 0X38 + 32 + 0x0 + 0xFFFFFFFF + + + CCR2 + Capture/Compare 2 value + 0 + 20 + + + + + CCR3 + capture or compare value + 0X3C + 32 + 0x0 + 0xFFFFFFFF + + + CCR3 + Capture/Compare 3 value + 0 + 20 + + + + + CCR4 + match output control + 0X40 + 32 + 0x0 + 0xFFFFFFFF + + + CCR4 + Capture/Compare 4 value + 0 + 20 + + + + + BDTR + Braking ande dead zone control Register + 0X44 + 32 + 0x0 + 0xFFFFFFFF + + + DTG + Dead-time generator setup + 0 + 8 + + + LOCK + Lock Configuration + 8 + 2 + + + OSSI + Off-state selection for Idle mode + 10 + 1 + + + OSSR + Off-state selection for Run mode + 11 + 1 + + + BKE + Break enable + 12 + 1 + + + BKP + Break polarity + 13 + 1 + + + AOE + Automatic output enable + 14 + 1 + + + MOE + Main output enable + 15 + 1 + + + DTGF + Asymmetric Dead-time generator setup + 16 + 8 + + + DTAE + Asymmetric Dead-time enable + 24 + 1 + + + + + CCDR1 + CR1 down capture or compare value + 0X50 + 32 + 0x0 + 0xFFFFFFFF + + + CCDR1 + Down Capture/Compare 1 value + 0 + 20 + + + + + CCDR2 + CR2 down capture or compare value + 0X54 + 32 + 0x0 + 0xFFFFFFFF + + + CCDR2 + Down Capture/Compare 2 value + 0 + 20 + + + + + CCDR3 + CR3 down capture or compare value + 0X58 + 32 + 0x0 + 0xFFFFFFFF + + + CCDR3 + Down Capture/Compare 3 value + 0 + 20 + + + + + CCDR4 + CR4 down capture or compare value + 0X5C + 32 + 0x0 + 0xFFFFFFFF + + + CCDR4 + Down Capture/Compare 4 value + 0 + 20 + + + + + + + EPWM + 0x4000C000 + + EPWM + 32 + + + + TIM2 + 0x40001000 + + TIM2 + 21 + + + + LPTIM + Low-Power Timer + 0x4000C800 + + 0 + 0x400 + registers + + + LPTIM + 22 + + + + + IR + LPTIM Interrupt Flag Register + 0x000 + 32 + 0x00 + 0xFFFFFFFF + read-write + + + MR0 + MR0 match flag, writer 1 to clear + 0 + 1 + read-write + + + + + + TCR + LPTIM Control Register + 0x004 + 32 + 0x0 + 0xFFFFFFFF + read-write + + + CEN + LPTIM Module Enable + 0 + 1 + read-write + + + CRST + LPTIM Module Reset + 1 + 1 + read-write + + + CLKS + LPTIM Clock Selection + 2 + 2 + read-write + + + SysClk + System Clock + 0 + + + LSI + LIRC 32KHz + 1 + + + + + TRIGSEL + Trigger LPTIM selector + 4 + 3 + read-write + + + Normal + Normal trigger + 0 + + + EPWMCh0P + EPWM CH0 (ouput) rising trigger + 1 + + + EPWMCh1P + EPWM CH1 (ouput) rising trigger + 2 + + + EPWMCh2P + EPWM CH2 (ouput) rising trigger + 3 + + + EPWMCh0N + EPWM CH0 (ouput) falling trigger + 4 + + + EPWMCh1N + EPWM CH1 (ouput) falling trigger + 5 + + + EPWMCh2N + EPWM CH2 (ouput) falling trigger + 6 + + + + + + + + TC + LPTIM Current Counter value Register + 0x008 + 32 + 0x0 + 0xFFFFFFFF + read-write + + + TC + Current Counter value + 0 + 16 + read-write + + + + + + PR + LPTIM Prescaler Register + 0x00C + 32 + 0x0 + 0xFFFFFFFF + read-write + + + PR + Prescaler value, fTIM=fsys/(PR+1) + 0 + 8 + read-write + + + + + + PC + Prescaler current value Register + 0x010 + 32 + 0x0 + 0xFFFFFFFF + read-write + + + PC + Prescaler current value + 0 + 8 + read-write + + + + + + MCR + LPTIM match control Register + 0x014 + 32 + 0x0 + 0xFFFFFFFF + read-write + + + MR0INT + Enable interrupt when match counter + 0 + 1 + read-write + + + MR0RST + Enable reset when match counter + 1 + 1 + read-write + + + MR0STOP + Enable stop when match counter + 2 + 1 + read-write + + + + + + MR0 + Match Register 0 + 0x018 + 32 + 0x0 + 0xFFFFFFFF + read-write + + + MR0 + Match compare value + 0 + 16 + read-write + + + + + + + TIM0 + 0x40000000 + + TIM0 + 19 + + + + TIM1 + 0x40000800 + + TIM1 + 20 + + + + diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/device.h b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/device.h new file mode 100644 index 0000000..00c400b --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/device.h @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file device.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __device_H_wqIH3HdS_l3C8_Hgh6_syur_ubmEVDiPX8aR__ +#define __device_H_wqIH3HdS_l3C8_Hgh6_syur_ubmEVDiPX8aR__ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(CONFIG_USE_PEC930) + #include "pec930.h" +#else + #error "Please select first the target device !" +#endif + +//============================================================================= +// Constant Definition +//============================================================================= +typedef void (*isr_t)(void); + +typedef void (*cb_trap_t)(void); +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/pec930.h b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/pec930.h new file mode 100644 index 0000000..857d08c --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/pec930.h @@ -0,0 +1,6072 @@ +/* + * Copyright (c) 2024-2025 Paduak-Tech. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file PEC930.h + * @brief CMSIS HeaderFile + * @version 1.0 + * @date 11. December 2025 + * @note Generated by SVDConv V3.3.38 on Thursday, 11.12.2025 14:57:34 + * from File './PEC930.svd', + * last modified on Thursday, 11.12.2025 06:57:28 + */ + + + +/** @addtogroup Padauk-tech + * @{ + */ + + +/** @addtogroup PEC930 + * @{ + */ + + +#ifndef PEC930_H +#define PEC930_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @addtogroup Configuration_of_CMSIS + * @{ + */ + + + +/* =========================================================================================================================== */ +/* ================ Interrupt Number Definition ================ */ +/* =========================================================================================================================== */ + +typedef enum { +/* =========================================== PEC930 Specific Interrupt Numbers =========================================== */ + SysSW_IRQn = 3, /*!< 3 System Software interrupt */ + SysTimer_IRQn = 7, /*!< 7 System Timer interrupt */ + BusError_IRQn = 17, /*!< 17 Bus error interrupt */ + PerfMon_IRQn = 18, /*!< 18 Performance Monitor */ + TIM0_IRQn = 19, /*!< 19 TIM0 */ + TIM1_IRQn = 20, /*!< 20 TIM1 */ + TIM2_IRQn = 21, /*!< 21 TIM2 */ + LPTIM_IRQn = 22, /*!< 22 LPTIM */ + WDG_IRQn = 23, /*!< 23 WDG */ + SPI0_IRQn = 24, /*!< 24 SPI0 */ + UART0_IRQn = 25, /*!< 25 UART0 */ + I2C0_IRQn = 26, /*!< 26 I2C0 */ + GPIOA_IRQn = 27, /*!< 27 GPIOA */ + GPIOB_IRQn = 28, /*!< 28 GPIOB */ + COMP0_IRQn = 29, /*!< 29 COMP0 */ + COMP1_IRQn = 30, /*!< 30 COMP1 */ + ADC0_IRQn = 31, /*!< 31 ADC0 */ + EPWM_IRQn = 32, /*!< 32 EPWM */ + LVD_IRQn = 33 /*!< 33 LVD */ +} IRQn_Type; + + + +/* =========================================================================================================================== */ +/* ================ Processor and Core Peripheral Section ================ */ +/* =========================================================================================================================== */ + +/* =========================== Configuration of the Nuclei N/NX Processor and Core Peripherals =========================== */ +/* set the defines according your Device */ +/* define the correct core revision */ +#define __NUCLEI_N_REV 0x0100 /*!< Core Revision r1p0 */ +#define __NUCLEI_CPU_REV 0x020C00 /*!< Nuclei CPU Core Revision, version X.Y.Z, this is for the CPU Core Version, you get from Nuclei, eg. N300 v3.10.1, it should be 0x030A01 */ +#define __NUCLEI_CPU_SERIES 0x0200 /*!< Nuclei CPU Series, such as 200/300/600/900, eg. 900 will be 0x0900 */ + +#define BOOT_HARTID 0 +#define ECLIC_EXTERNAL_IRQ_OFFSET 19 + +/*!< Set to 0, 1, or 2, 0 not present, 1 single floating point unit present, 2 double floating point unit present */ +#if !defined(__riscv_flen) + #define __FPU_PRESENT 0 +#elif __riscv_flen == 32 + #define __FPU_PRESENT 1 +#else + #define __FPU_PRESENT 2 +#endif + +#if defined(__riscv_dsp) + #define __DSP_PRESENT 1 /*!< Set to 1 if Partial SIMD(DSP) extension is present */ +#else + #define __DSP_PRESENT 0 /*!< Set to 1 if Partial SIMD(DSP) extension is present */ +#endif + +/** + * Branch Prediction Unit of CORE + */ +#if defined(CONFIG_HAS_BPU) + #define __BPU_PRESENT 0 +#endif + +/** + * CPU IREGION Base Address + */ +#define __IREGION_BASEADDR 0x18000000UL + +/** + * If your hart index is different to your hartid, you must define this __HARTID_OFFSET macro. + * For example, if your cpu has 4 harts, and hartid start from 3, so the __HARTID_OFFSET should set to 3. + * Which means hartid 3-6 means hart index 0-3, this is useful for the timer software interrupt and timer interrupt trigger register location + */ +#ifndef __HARTID_OFFSET +#define __HARTID_OFFSET 0 +#endif + +/** + * Exception Configuration + */ +#define __EXCP_PRESENT 1 + +/* define the correct core features for the SoC */ +#define __ECLIC_PRESENT 1 /*!< Set to 1 if ECLIC is present */ +#if (__ECLIC_PRESENT) + #define __ECLIC_BASEADDR (__IREGION_BASEADDR + IREGION_ECLIC_OFS) /*!< Set to ECLIC baseaddr of your device */ + #define __ECLIC_INTCTLBITS 3 /*!< Set to 1 - 8, the number of hardware bits are actually implemented in the clicintctl registers. */ + #define __ECLIC_INTNUM (ECLIC_EXTERNAL_IRQ_OFFSET + 15) /*!< Set to 1 - 1005, the external interrupt number of ECLIC Unit */ +#endif /* __ECLIC_PRESENT */ + +#define __PLIC_PRESENT 0 + +#define __SYSTIMER_PRESENT 1 /*!< Set to 1 if System Timer is present */ +#if (__SYSTIMER_PRESENT) + #define __SYSTIMER_BASEADDR (__IREGION_BASEADDR + IREGION_TIMER_OFS) /*!< Set to SysTimer baseaddr of your device */ + #define __SYSTIMER_HARTID BOOT_HARTID /*!< Define the system timer hart index of the cpu */ +#endif /* __SYSTIMER_PRESENT */ + +/** + * Physical Memory Protection + */ +#define __PMP_PRESENT 0 /*!< Set to 1 if PMP is present */ +#if (__PMP_PRESENT) + #define __PMP_ENTRY_NUM 0 /*!< Set to 8 or 16, the number of PMP entries */ +#endif /* __PMP_PRESENT */ + +#define __ICACHE_PRESENT 0 /*!< Set to 1 if I-Cache is present */ +#define __DCACHE_PRESENT 0 /*!< Set to 1 if D-Cache is present */ +#define __CCM_PRESENT 0 +#define __NICE_PRESENT 0 +#define __VNICE_PRESENT 0 +#define __INC_INTRINSIC_API 0 /*!< Set to 1 if intrinsic api header files need to be included */ + + +/** + * SMP Configuration + */ +#define __SMPCC_PRESENT 0 +#if (__SMPCC_PRESENT) + #define __SMPCC_BASEADDR (__IREGION_BASEADDR + IREGION_SMP_OFS) +#endif + +#define __CIDU_PRESENT 0 +#if (__CIDU_PRESENT) + #define __CIDU_BASEADDR (__IREGION_BASEADDR + IREGION_IDU_OFS) +#endif /* __CIDU_PRESENT */ + +#define __TEE_PRESENT 0 +#if (__TEE_PRESENT) + #define __SPMP_PRESENT 0 + #define __SMPU_PRESENT 0 + #define __SPMP_ENTRY_NUM 0 +#endif /* __TEE_PRESENT */ + + +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ +#define __Vendor_EXCEPTION 0 /*!< Set to 1 if vendor exception hander is present */ + + + +/** @} */ /* End of group Configuration_of_CMSIS */ + +#include "nmsis_core.h" /*!< rv32 processor and core peripherals */ +#include "system_dev.h" /*!< System device */ + +#ifndef __IM /*!< Fallback for older CMSIS versions */ + #define __IM __I +#endif +#ifndef __OM /*!< Fallback for older CMSIS versions */ + #define __OM __O +#endif +#ifndef __IOM /*!< Fallback for older CMSIS versions */ + #define __IOM __IO +#endif + + +/* ======================================== Start of section using anonymous unions ======================================== */ +#if defined (__GNUC__) + /* anonymous unions are enabled by default */ +#else + #warning Not supported compiler type +#endif + + +/* =========================================================================================================================== */ +/* ================ Device Specific Peripheral Section ================ */ +/* =========================================================================================================================== */ + + +/** @addtogroup Device_Peripheral_peripherals + * @{ + */ + + + +/* =========================================================================================================================== */ +/* ================ EFLASH_MEM ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Embedded flash memory (EFLASH_MEM) + */ + +typedef struct { /*!< (@ 0x00000000) EFLASH_MEM Structure */ + __IOM uint32_t DATA0; /*!< (@ 0x00000000) The first address */ + __IM uint32_t RESERVED[8190]; + __IOM uint32_t DATA_END; /*!< (@ 0x00007FFC) The endt address */ +} EFLASH_MEM_Type; /*!< Size = 32768 (0x8000) */ + + + +/* =========================================================================================================================== */ +/* ================ SRAM_MEM ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief SRAM memory (SRAM_MEM) + */ + +typedef struct { /*!< (@ 0x20000000) SRAM_MEM Structure */ + __IOM uint32_t DATA0; /*!< (@ 0x00000000) The first address */ + __IM uint32_t RESERVED[1022]; + __IOM uint32_t DATA_END; /*!< (@ 0x00000FFC) The endt address */ +} SRAM_MEM_Type; /*!< Size = 4096 (0x1000) */ + + + +/* =========================================================================================================================== */ +/* ================ NVR_MEM ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Non-Volatile Region (NVR_MEM) + */ + +typedef struct { /*!< (@ 0x00200000) NVR_MEM Structure */ + __IOM uint32_t DATA0; /*!< (@ 0x00000000) The first address */ + __IM uint32_t RESERVED[2046]; + __IOM uint32_t DATA_END; /*!< (@ 0x00001FFC) The endt address */ +} NVR_MEM_Type; /*!< Size = 8192 (0x2000) */ + + + +/* =========================================================================================================================== */ +/* ================ CORET ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief RISC-V core of SoC (CORET) + */ + +typedef struct { /*!< (@ 0x18000000) CORET Structure */ + __IOM uint32_t revd; /*!< (@ 0x00000000) NA */ +} CORET_Type; /*!< Size = 4 (0x4) */ + + + +/* =========================================================================================================================== */ +/* ================ UID ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Universally Unique Identifier (UID) + */ + +typedef struct { /*!< (@ 0x00201F00) UID Structure */ + __IM uint32_t UID1; /*!< (@ 0x00000000) Unique Identifier 1 */ + __IM uint32_t UID2; /*!< (@ 0x00000004) Unique Identifier 2 */ + __IM uint32_t UID3; /*!< (@ 0x00000008) Unique Identifier 3 */ +} UID_Type; /*!< Size = 12 (0xc) */ + + + +/* =========================================================================================================================== */ +/* ================ FLASH ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Flash Controller Module (FLASH) + */ + +typedef struct { /*!< (@ 0x4000F800) FLASH Structure */ + + union { + __IOM uint32_t CMD; /*!< (@ 0x00000000) Flash Command Register */ + + struct { + __IOM uint32_t START : 1; /*!< [0..0] Flash command start */ + __IOM uint32_t CMD : 3; /*!< [3..1] Flash command ID */ + uint32_t : 1; + __IOM uint32_t NWS : 3; /*!< [7..5] Flash waits cycles after OP */ + __IOM uint32_t UNLOCK : 1; /*!< [8..8] Unlock Flash P/E operations */ + __IOM uint32_t ACME : 1; /*!< [9..9] Enable Flash Access Counter */ + __IOM uint32_t ACMR : 1; /*!< [10..10] Reset Flash Access Counter */ + uint32_t : 2; + __IOM uint32_t AINC : 1; /*!< [13..13] Flash enable auto address increase or not */ + uint32_t : 2; + __OM uint32_t KEY : 16; /*!< [31..16] Auth key 0xA5A5 */ + } CMD_b; + } ; + + union { + __IOM uint32_t SR; /*!< (@ 0x00000004) Flash Status Register */ + + struct { + __IOM uint32_t CMD_END : 1; /*!< [0..0] Flash idle flag (0:busy), write 1 to clear */ + __IOM uint32_t KEY_ERR : 1; /*!< [1..1] Flash error flag (0:success), W1C */ + __IOM uint32_t ACC_ERR : 1; /*!< [2..2] Flash access error flag, W1C */ + __IOM uint32_t ADDR_ERR : 1; /*!< [3..3] Flash addressing error flag, W1C */ + uint32_t : 2; + __IOM uint32_t HCM : 1; /*!< [6..6] Flash access count full flag, W1C */ + __IM uint32_t HSI_TC_ERR : 1; /*!< [7..7] HSI_TC's complement do not match in sysinfo area */ + __IM uint32_t PROTCT_R2_ERR : 1; /*!< [8..8] Protect_R2's complement do not match in sysinfo area */ + __IM uint32_t PROTCT_R1_ERR : 1; /*!< [9..9] Protect_R1's complement do not match in sysinfo area */ + __IM uint32_t RSTIO_AF_ERR : 1; /*!< [10..10] RSTIO_AF's complement do not match in sysinfo area */ + __IM uint32_t LDO_TRIM_ERR : 1; /*!< [11..11] LDO_TRIM's complement do not match in sysinfo area */ + __IM uint32_t VBUF_TRIM_ERR : 1; /*!< [12..12] VBUF_TRIM's complement do not match in sysinfo area */ + __IM uint32_t LSI_TRIM_ERR : 1; /*!< [13..13] LSI_TRIM's complement do not match in sysinfo area */ + __IM uint32_t HSI_TRIM_ERR : 1; /*!< [14..14] HSI_TRIM's complement do not match in sysinfo area */ + uint32_t : 17; + } SR_b; + } ; + __IM uint32_t RESERVED; + __IOM uint32_t AR; /*!< (@ 0x0000000C) Flash Address Register */ + __IOM uint32_t DR; /*!< (@ 0x00000010) Flash Data Register */ + __IM uint32_t RESERVED1[3]; + __IM uint32_t ACM; /*!< (@ 0x00000020) Flash Access Count Register */ + __IM uint32_t RESERVED2; + + union { + __IOM uint32_t DIV; /*!< (@ 0x00000028) Flash clock division */ + + struct { + __IOM uint32_t DIV : 8; /*!< [7..0] Flash Clock DIV */ + uint32_t : 24; + } DIV_b; + } ; +} FLASH_Type; /*!< Size = 44 (0x2c) */ + + + +/* =========================================================================================================================== */ +/* ================ GPIO ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief General Purpose IO (GPIO) + */ + +typedef struct { /*!< (@ 0x40011000) GPIO Structure */ + + union { + __IOM uint32_t DAT; /*!< (@ 0x00000000) GPIO Data Register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } DAT_b; + } ; + + union { + __IOM uint32_t LAT; /*!< (@ 0x00000004) GPIO output data latch register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } LAT_b; + } ; + + union { + __IOM uint32_t ITS1; /*!< (@ 0x00000008) GPIO interrupt type set register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } ITS1_b; + } ; + + union { + __IOM uint32_t ITC1; /*!< (@ 0x0000000C) GPIO interrupt type clear register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } ITC1_b; + } ; + + union { + __IOM uint32_t OES; /*!< (@ 0x00000010) GPIO output enable set register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } OES_b; + } ; + + union { + __IOM uint32_t OEC; /*!< (@ 0x00000014) GPIO output enable clear register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } OEC_b; + } ; + + union { + __IOM uint32_t INES; /*!< (@ 0x00000018) GPIO input enable set register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } INES_b; + } ; + + union { + __IOM uint32_t INEC; /*!< (@ 0x0000001C) GPIO intput enable clear register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } INEC_b; + } ; + + union { + __IOM uint32_t IES; /*!< (@ 0x00000020) GPIO pin interrupt enable register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } IES_b; + } ; + + union { + __IOM uint32_t IEC; /*!< (@ 0x00000024) GPIO pin interrupt clear register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } IEC_b; + } ; + + union { + __IOM uint32_t ITS0; /*!< (@ 0x00000028) GPIO pin interrupt type select register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } ITS0_b; + } ; + + union { + __IOM uint32_t ITC0; /*!< (@ 0x0000002C) GPIO pin interrupt type clear register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } ITC0_b; + } ; + + union { + __IOM uint32_t PLS; /*!< (@ 0x00000030) GPIO pin interrupt polarity set register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } PLS_b; + } ; + + union { + __IOM uint32_t PLC; /*!< (@ 0x00000034) GPIO pin interrupt polarity clear register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } PLC_b; + } ; + + union { + __IOM uint32_t IST; /*!< (@ 0x00000038) GPIO pin interrupt flag status register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } IST_b; + } ; + + union { + __IOM uint32_t PUS; /*!< (@ 0x0000003C) GPIO input pull-up set register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } PUS_b; + } ; + + union { + __IOM uint32_t PUC; /*!< (@ 0x00000040) GPIO input pull-up clear register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } PUC_b; + } ; + + union { + __IOM uint32_t ODS; /*!< (@ 0x00000044) GPIO output open-drain set register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } ODS_b; + } ; + + union { + __IOM uint32_t ODC; /*!< (@ 0x00000048) GPIO output open-drain clear register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } ODC_b; + } ; + + union { + __IOM uint32_t PDS; /*!< (@ 0x0000004C) GPIO input pull-down set register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } PDS_b; + } ; + + union { + __IOM uint32_t PDC; /*!< (@ 0x00000050) GPIO input pull-down clear register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } PDC_b; + } ; + + union { + __IOM uint32_t OSRS; /*!< (@ 0x00000054) GPIO Open Sink Set register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } OSRS_b; + } ; + + union { + __IOM uint32_t OSRC; /*!< (@ 0x00000058) GPIO Open Sink Clear register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } OSRC_b; + } ; + + union { + __IOM uint32_t CTS; /*!< (@ 0x0000005C) GPIO Schmitt-Trigger Set register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } CTS_b; + } ; + + union { + __IOM uint32_t CTC; /*!< (@ 0x00000060) GPIO Schmitt-Trigger Clear register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } CTC_b; + } ; +} GPIO_Type; /*!< Size = 100 (0x64) */ + + + +/* =========================================================================================================================== */ +/* ================ AFIO ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Alternate Function I/O (AFIO) + */ + +typedef struct { /*!< (@ 0x40011070) AFIO Structure */ + + union { + __IOM uint32_t PAAFR; /*!< (@ 0x00000000) GPIO PortA AF control register */ + + struct { + __IOM uint32_t PA0 : 3; /*!< [2..0] Pin index */ + __IOM uint32_t PA1 : 3; /*!< [5..3] Pin index */ + __IOM uint32_t PA2 : 3; /*!< [8..6] Pin index */ + __IOM uint32_t PA3 : 3; /*!< [11..9] Pin index */ + __IOM uint32_t PA4 : 3; /*!< [14..12] Pin index */ + __IOM uint32_t PA5 : 3; /*!< [17..15] Pin index */ + __IOM uint32_t PA14 : 3; /*!< [20..18] Pin index */ + __IOM uint32_t PA15 : 3; /*!< [23..21] Pin index */ + uint32_t : 8; + } PAAFR_b; + } ; + + union { + __IOM uint32_t PBAFR; /*!< (@ 0x00000004) GPIO PortB AF control register */ + + struct { + __IOM uint32_t PB0 : 3; /*!< [2..0] Pin index */ + __IOM uint32_t PB1 : 3; /*!< [5..3] Pin index */ + __IOM uint32_t PB2 : 3; /*!< [8..6] Pin index */ + __IOM uint32_t PB3 : 3; /*!< [11..9] Pin index */ + __IOM uint32_t PB4 : 3; /*!< [14..12] Pin index */ + __IOM uint32_t PB5 : 3; /*!< [17..15] Pin index */ + uint32_t : 14; + } PBAFR_b; + } ; + + union { + __IOM uint32_t FN1_AFR; /*!< (@ 0x00000008) Peripheral Alternate Func control register */ + + struct { + __IOM uint32_t BKIN : 4; /*!< [3..0] Peripheral Alternate Func selection */ + __IOM uint32_t ECAP0 : 3; /*!< [6..4] Peripheral Alternate Func selection */ + __IOM uint32_t ECAP1 : 3; /*!< [9..7] Peripheral Alternate Func selection */ + __IOM uint32_t ECAP2 : 3; /*!< [12..10] Peripheral Alternate Func selection */ + __IOM uint32_t EPETR : 4; /*!< [16..13] Peripheral Alternate Func selection */ + uint32_t : 15; + } FN1_AFR_b; + } ; + + union { + __IOM uint32_t FN2_AFR; /*!< (@ 0x0000000C) Peripheral Alternate Func control register */ + + struct { + __IOM uint32_t TCAP0 : 3; /*!< [2..0] Peripheral Alternate Func control register */ + __IOM uint32_t TCAP1 : 3; /*!< [5..3] Peripheral Alternate Func control register */ + __IOM uint32_t TCAP2 : 3; /*!< [8..6] Peripheral Alternate Func control register */ + __IOM uint32_t T2ETR : 4; /*!< [12..9] Peripheral Alternate Func control register */ + __IOM uint32_t I2C_PULL0 : 1; /*!< [13..13] Peripheral Alternate Func control register */ + __IOM uint32_t I2C_PULL1 : 1; /*!< [14..14] Peripheral Alternate Func control register */ + __IOM uint32_t I2C_PULL2 : 1; /*!< [15..15] Peripheral Alternate Func control register */ + __IOM uint32_t I2C_PULL3 : 1; /*!< [16..16] Peripheral Alternate Func control register */ + __IOM uint32_t I2C_PULL4 : 1; /*!< [17..17] Peripheral Alternate Func control register */ + __IOM uint32_t I2C_PULL5 : 1; /*!< [18..18] Peripheral Alternate Func control register */ + __IOM uint32_t I2C_PULL6 : 1; /*!< [19..19] Peripheral Alternate Func control register */ + __IOM uint32_t I2C_PULL7 : 1; /*!< [20..20] Peripheral Alternate Func control register */ + uint32_t : 11; + } FN2_AFR_b; + } ; +} AFIO_Type; /*!< Size = 16 (0x10) */ + + + +/* =========================================================================================================================== */ +/* ================ SYSCFG ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief System Configuration controller (SYSCFG) + */ + +typedef struct { /*!< (@ 0x4001F000) SYSCFG Structure */ + __IM uint32_t RESERVED; + + union { + __IOM uint32_t PMUCR; /*!< (@ 0x00000004) Power Management Unit Control Register */ + + struct { + __IOM uint32_t PMUEN : 1; /*!< [0..0] Enable pmu */ + uint32_t : 31; + } PMUCR_b; + } ; + __IM uint32_t RESERVED1; + + union { + __IOM uint32_t MCOCR; /*!< (@ 0x0000000C) MCU Clock Output Control Register */ + + struct { + __IOM uint32_t MCOSEL : 3; /*!< [2..0] Select output clock */ + uint32_t : 3; + __IOM uint32_t DivEn : 1; /*!< [6..6] Enable MCO outupt pre-scalar */ + __IOM uint32_t DivSel : 1; /*!< [7..7] Select outupt pre-scalar */ + __IOM uint32_t Divider : 8; /*!< [15..8] The pre-scalar value */ + __IOM uint32_t SWRstEn : 8; /*!< [23..16] Trigger software reset */ + uint32_t : 8; + } MCOCR_b; + } ; + + union { + __IOM uint32_t SYSRSTSR; /*!< (@ 0x00000010) System Reset Status Register */ + + struct { + __IOM uint32_t SWRST : 1; /*!< [0..0] Software reset (Write clear) */ + __IOM uint32_t WDGRST : 1; /*!< [1..1] Watchdog reset (Write clear) */ + __IOM uint32_t LOCKUPRST : 1; /*!< [2..2] Lock-up reset (Write clear) */ + uint32_t : 5; + __IOM uint32_t PORRST : 1; /*!< [8..8] Power reset (Write clear) */ + __IOM uint32_t PADRST : 1; /*!< [9..9] nRST Pad reset (Write clear) */ + uint32_t : 1; + __IOM uint32_t LVDRST : 1; /*!< [11..11] LVD reset (Write clear) */ + __IOM uint32_t REBOOTRST : 1; /*!< [12..12] Reboot reset (Write clear) */ + uint32_t : 19; + } SYSRSTSR_b; + } ; + + union { + __IOM uint32_t REBOOT_UNLOCK; /*!< (@ 0x00000014) Unlock reboot to latch paraments */ + + struct { + __IOM uint32_t AUTHKEY : 16; /*!< [15..0] Reboot signature: 0xAB56 */ + uint32_t : 16; + } REBOOT_UNLOCK_b; + } ; + + union { + __IOM uint32_t SYSRSTCR; /*!< (@ 0x00000018) System Reset Control Register */ + + struct { + uint32_t : 10; + __IOM uint32_t REBOOTEN : 1; /*!< [10..10] Trigger system Re-boot */ + uint32_t : 21; + } SYSRSTCR_b; + } ; + + union { + __IOM uint32_t DEBUGENCR; /*!< (@ 0x0000001C) Debug enable Control Register */ + + struct { + uint32_t : 2; + __IOM uint32_t TIM0 : 1; /*!< [2..2] Tim0 debug mode */ + __IOM uint32_t TIM1 : 1; /*!< [3..3] Tim1 debug mode */ + __IOM uint32_t LPTIM : 1; /*!< [4..4] LPTIM debug mode */ + uint32_t : 1; + __IOM uint32_t EPWM : 1; /*!< [6..6] EPWM debug mode */ + uint32_t : 4; + __IOM uint32_t TIM2 : 1; /*!< [11..11] TIM2 debug mode */ + uint32_t : 2; + __IOM uint32_t WDG : 1; /*!< [14..14] WDG debug mode(def: enable) */ + uint32_t : 1; + __OM uint32_t AUTHKEY : 16; /*!< [31..16] Reboot signature: 0x8A57 */ + } DEBUGENCR_b; + } ; + + union { + __IOM uint32_t SYSCLKCR; /*!< (@ 0x00000020) System Clock Control Register */ + + struct { + __IOM uint32_t CLKSW : 3; /*!< [2..0] System Clock Source Switch */ + uint32_t : 5; + __IOM uint32_t CLKDIV : 4; /*!< [11..8] Clock Divider, factors = (CLKDIV + 1) */ + uint32_t : 11; + __IOM uint32_t LSIAON : 1; /*!< [23..23] LSI always on */ + __IOM uint32_t SYSTICKCR : 2; /*!< [25..24] Sytem tick Control Register */ + uint32_t : 6; + } SYSCLKCR_b; + } ; + + union { + __IOM uint32_t PRSTEN; /*!< (@ 0x00000024) Peripheral Reset Control Register */ + + struct { + __IOM uint32_t UART0 : 1; /*!< [0..0] Reset enable (It should generate pulse signal to reset) */ + uint32_t : 1; + __IOM uint32_t TIM0 : 1; /*!< [2..2] Reset enable (It should generate pulse signal to reset) */ + __IOM uint32_t TIM1 : 1; /*!< [3..3] Reset enable (It should generate pulse signal to reset) */ + __IOM uint32_t LPTIM : 1; /*!< [4..4] Reset enable (It should generate pulse signal to reset) */ + __IOM uint32_t ADC : 1; /*!< [5..5] Reset enable (It should generate pulse signal to reset) */ + __IOM uint32_t EPWM : 1; /*!< [6..6] Reset enable (It should generate pulse signal to reset) */ + __IOM uint32_t DSP : 1; /*!< [7..7] Reset enable (It should generate pulse signal to reset) */ + __IOM uint32_t COMP0 : 1; /*!< [8..8] Reset enable (It should generate pulse signal to reset) */ + uint32_t : 1; + __IOM uint32_t SPI : 1; /*!< [10..10] Reset enable (It should generate pulse signal to reset) */ + __IOM uint32_t TIM2 : 1; /*!< [11..11] Reset enable (It should generate pulse signal to reset) */ + __IOM uint32_t I2C : 1; /*!< [12..12] Reset enable (It should generate pulse signal to reset) */ + __IOM uint32_t COMP1 : 1; /*!< [13..13] Reset enable (It should generate pulse signal to reset) */ + __IOM uint32_t WDG : 1; /*!< [14..14] Reset enable (It should generate pulse signal to reset) */ + __IOM uint32_t AMISC : 1; /*!< [15..15] Reset enable (It should generate pulse signal to reset) */ + uint32_t : 16; + } PRSTEN_b; + } ; + + union { + __IOM uint32_t PCLKEN; /*!< (@ 0x00000028) Peripheral Clock Enable Control Register */ + + struct { + __IOM uint32_t UART0 : 1; /*!< [0..0] PCLK enable Uart 0 */ + uint32_t : 1; + __IOM uint32_t TIM0 : 1; /*!< [2..2] PCLK enable TIM0 */ + __IOM uint32_t TIM1 : 1; /*!< [3..3] PCLK enable TIM1 */ + __IOM uint32_t LPTIM : 1; /*!< [4..4] PCLK enable LPTIM */ + __IOM uint32_t ADC : 1; /*!< [5..5] PCLK enable ADC */ + __IOM uint32_t EPWM : 1; /*!< [6..6] PCLK enable EPWM */ + __IOM uint32_t DSP : 1; /*!< [7..7] PCLK enable DSP */ + __IOM uint32_t COMP0 : 1; /*!< [8..8] PCLK enable COMP0 */ + uint32_t : 1; + __IOM uint32_t SPI : 1; /*!< [10..10] PCLK enable SPI */ + __IOM uint32_t TIM2 : 1; /*!< [11..11] PCLK enable TIM2 */ + __IOM uint32_t I2C : 1; /*!< [12..12] PCLK enable I2C */ + __IOM uint32_t COMP1 : 1; /*!< [13..13] PCLK enable COMP1 */ + __IOM uint32_t WDG : 1; /*!< [14..14] PCLK enable WDG */ + __IOM uint32_t AMISC : 1; /*!< [15..15] PCLK enable analog misc. */ + uint32_t : 16; + } PCLKEN_b; + } ; + + union { + __IOM uint32_t ICEIOCR; /*!< (@ 0x0000002C) ICE I/O Control Register */ + + struct { + __IOM uint32_t JTAGIOEN : 1; /*!< [0..0] I/O force on jTag pins. 0: normal I/O, 1: ICE pins */ + __IOM uint32_t DBG_CTRL_EN : 1; /*!< [1..1] Enable debug control */ + __IOM uint32_t DBG_EN : 1; /*!< [2..2] Enable debug */ + uint32_t : 13; + __IOM uint32_t AUTHKEY : 16; /*!< [31..16] auth-key 0xE653 */ + } ICEIOCR_b; + } ; + + union { + __IOM uint32_t RSTPINCR; /*!< (@ 0x00000030) Reset pin control register */ + + struct { + __IOM uint32_t RSTPINAF : 16; /*!< [15..0] Reset Pin switch to general I/O */ + uint32_t : 16; + } RSTPINCR_b; + } ; + + union { + __IOM uint32_t TIM2_CON_SEL; /*!< (@ 0x00000034) TIM2 selection */ + + struct { + __IOM uint32_t CH1 : 3; /*!< [2..0] selection */ + uint32_t : 1; + __IOM uint32_t CH2 : 3; /*!< [6..4] selection */ + uint32_t : 1; + __IOM uint32_t CH3 : 3; /*!< [10..8] selection */ + uint32_t : 1; + __IOM uint32_t CH4 : 3; /*!< [14..12] selection */ + uint32_t : 2; + __IOM uint32_t BREAK_SEL : 1; /*!< [17..17] TIM IP Config */ + __IOM uint32_t COMP0A_SEL : 1; /*!< [18..18] COMP0A selection */ + __IOM uint32_t COMP1A_SEL : 1; /*!< [19..19] COMP1A selection */ + __IOM uint32_t VC_CH1_INV : 1; /*!< [20..20] VCOUT_SEL */ + __IOM uint32_t VC_CH1 : 1; /*!< [21..21] VCOUT_SEL */ + __IOM uint32_t VC_CH2_INV : 1; /*!< [22..22] VCOUT_SEL */ + __IOM uint32_t VC_CH2 : 1; /*!< [23..23] VCOUT_SEL */ + __IOM uint32_t VC_CH3_INV : 1; /*!< [24..24] VCOUT_SEL */ + __IOM uint32_t VC_CH3 : 1; /*!< [25..25] VCOUT_SEL */ + __IOM uint32_t VC_CH4_INV : 1; /*!< [26..26] VCOUT_SEL */ + __IOM uint32_t VC_CH4 : 1; /*!< [27..27] VCOUT_SEL */ + __IOM uint32_t COMP0D_SEL : 1; /*!< [28..28] COMP0D selection */ + __IOM uint32_t COMP1D_SEL : 1; /*!< [29..29] COMP1D selection */ + uint32_t : 2; + } TIM2_CON_SEL_b; + } ; + + union { + __IOM uint32_t EPWM_CON_SEL; /*!< (@ 0x00000038) EPWM selection */ + + struct { + __IOM uint32_t CH1 : 3; /*!< [2..0] selection */ + uint32_t : 1; + __IOM uint32_t CH2 : 3; /*!< [6..4] selection */ + uint32_t : 1; + __IOM uint32_t CH3 : 3; /*!< [10..8] selection */ + uint32_t : 1; + __IOM uint32_t CH4 : 3; /*!< [14..12] selection */ + uint32_t : 1; + __IOM uint32_t BREAK_SEL : 1; /*!< [16..16] EPWM IP Config */ + __IOM uint32_t BREAK_OSSI0_DISOUT : 1; /*!< [17..17] EPWM IP Config */ + __IOM uint32_t COMP0A_SEL : 1; /*!< [18..18] COMP0A Selection */ + __IOM uint32_t COMP1A_SEL : 1; /*!< [19..19] COMP1A Selection */ + __IOM uint32_t VC_CH1_INV : 1; /*!< [20..20] VCOUT_SEL */ + __IOM uint32_t VC_CH1 : 1; /*!< [21..21] VCOUT_SEL */ + __IOM uint32_t VC_CH2_INV : 1; /*!< [22..22] VCOUT_SEL */ + __IOM uint32_t VC_CH2 : 1; /*!< [23..23] VCOUT_SEL */ + __IOM uint32_t VC_CH3_INV : 1; /*!< [24..24] VCOUT_SEL */ + __IOM uint32_t VC_CH3 : 1; /*!< [25..25] VCOUT_SEL */ + __IOM uint32_t VC_CH4_INV : 1; /*!< [26..26] VCOUT_SEL */ + __IOM uint32_t VC_CH4 : 1; /*!< [27..27] VCOUT_SEL */ + __IOM uint32_t COMP0D_SEL : 1; /*!< [28..28] COMP0D Selection */ + __IOM uint32_t COMP1D_SEL : 1; /*!< [29..29] COMP1D Selection */ + __IOM uint32_t LVD_SEL : 1; /*!< [30..30] LVD Selection */ + __IOM uint32_t WDG_SEL : 1; /*!< [31..31] Watchdog Selection */ + } EPWM_CON_SEL_b; + } ; + __IM uint32_t RESERVED2; + + union { + __IOM uint32_t PRSTEN1; /*!< (@ 0x00000040) peripheral modules reset */ + + struct { + __IOM uint32_t GPIOA : 1; /*!< [0..0] GPIO reset enable (It should generate pulse signal to + reset) */ + __IOM uint32_t GPIOB : 1; /*!< [1..1] GPIO reset enable (It should generate pulse signal to + reset) */ + uint32_t : 5; + __IOM uint32_t CRC : 1; /*!< [7..7] CRC reset enable (It should generate pulse signal to + reset) */ + uint32_t : 24; + } PRSTEN1_b; + } ; + + union { + __IOM uint32_t HCLKEN; /*!< (@ 0x00000044) Enable clock of Modules of AHB */ + + struct { + __IOM uint32_t GPIOA : 1; /*!< [0..0] GPIO clock enable */ + __IOM uint32_t GPIOB : 1; /*!< [1..1] GPIO clock enable */ + uint32_t : 5; + __IOM uint32_t CRC : 1; /*!< [7..7] CRC clock enable */ + uint32_t : 24; + } HCLKEN_b; + } ; + + union { + __IOM uint32_t EVT_SEL; /*!< (@ 0x00000048) Event select */ + + struct { + __IOM uint32_t IRQSEL : 32; /*!< [31..0] Link interrupt source as event (bit-order is IRQ number) */ + } EVT_SEL_b; + } ; + + union { + __IOM uint32_t NMICR; /*!< (@ 0x0000004C) NMI Control Register */ + + struct { + __IOM uint32_t SEL : 5; /*!< [4..0] Connect IRQ number to NMI */ + __IOM uint32_t EN : 3; /*!< [7..5] Enable to connect IRQ sourec to NMI */ + uint32_t : 24; + } NMICR_b; + } ; + __IM uint32_t RESERVED3[44]; + __IM uint32_t CHIPID; /*!< (@ 0x00000100) Chip ID register */ +} SYSCFG_Type; /*!< Size = 260 (0x104) */ + + + +/* =========================================================================================================================== */ +/* ================ UART ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Universal Asynchronous Rx/Tx (UART) + */ + +typedef struct { /*!< (@ 0x40002000) UART Structure */ + + union { + __IOM uint32_t DAT; /*!< (@ 0x00000000) UART TX/RX Data Register (FIFO: 8) */ + + struct { + __IOM uint32_t DAT : 9; /*!< [8..0] 8/9 bits data */ + __IOM uint32_t FE : 1; /*!< [9..9] Frame error flag */ + uint32_t : 22; + } DAT_b; + } ; + + union { + __IOM uint32_t CR; /*!< (@ 0x00000004) UART Control Register */ + + struct { + __IOM uint32_t MODE : 3; /*!< [2..0] Mode select */ + __IOM uint32_t STOPB : 2; /*!< [4..3] width of STOP bits */ + __IOM uint32_t PAR : 1; /*!< [5..5] Parity check */ + __IOM uint32_t LPB : 1; /*!< [6..6] Enable Loop back mode */ + __IOM uint32_t RUN : 1; /*!< [7..7] Baudrate generator run */ + __IOM uint32_t RXEN : 1; /*!< [8..8] RX enable */ + uint32_t : 7; + __IOM uint32_t RXPOL : 1; /*!< [16..16] RX data polarity inverse control */ + __IOM uint32_t TXPOL : 1; /*!< [17..17] TX data polarity inverse control */ + uint32_t : 14; + } CR_b; + } ; + + union { + __IOM uint32_t BR; /*!< (@ 0x00000008) UART Baudrate Control Register */ + + struct { + __IOM uint32_t BR : 16; /*!< [15..0] Baud-Rate */ + uint32_t : 16; + } BR_b; + } ; + + union { + __IOM uint32_t IE; /*!< (@ 0x0000000C) UART Interrupt Enable Register */ + + struct { + __IOM uint32_t RXNEE : 1; /*!< [0..0] RX FIFO not empty interrupt enable */ + __IOM uint32_t TXEE : 1; /*!< [1..1] TX FIFO empty interrupt enable */ + __IOM uint32_t TXHEE : 1; /*!< [2..2] TX FIFO half-empty interrupt enable */ + __IOM uint32_t PERRE : 1; /*!< [3..3] Parity error interrupt enable */ + __IOM uint32_t FERRE : 1; /*!< [4..4] Frame error interrupt enable */ + __IOM uint32_t OVERRE : 1; /*!< [5..5] RX overflow interrupt enable */ + __IOM uint32_t TONEE : 1; /*!< [6..6] TX time-out interrupt enable */ + __IOM uint32_t TOIDLEE : 1; /*!< [7..7] TX idle time-out interrupt enable */ + __IOM uint32_t RXHFE : 1; /*!< [8..8] RX FIFO half-full interrupt enable */ + __IOM uint32_t RXFE : 1; /*!< [9..9] RX FIFO full interrupt enable */ + __IOM uint32_t TXENDE : 1; /*!< [10..10] TX end interrupt enable */ + __IOM uint32_t TXFE : 1; /*!< [11..11] TX FIFO full interrupt enable */ + __IOM uint32_t RXPE : 1; /*!< [12..12] RX AUTO parity */ + uint32_t : 19; + } IE_b; + } ; + + union { + __IOM uint32_t SR; /*!< (@ 0x00000010) UART Status Register */ + + struct { + __IM uint32_t RXNE : 1; /*!< [0..0] RX FIFO not empty */ + __IM uint32_t TXE : 1; /*!< [1..1] TX FIFO empty */ + __IM uint32_t TXHE : 1; /*!< [2..2] TX FIFO half-empty */ + __IOM uint32_t PERR : 1; /*!< [3..3] Parity error flag (W1C) */ + __IOM uint32_t FERR : 1; /*!< [4..4] Frame error flag (W1C) */ + __IOM uint32_t OVERR : 1; /*!< [5..5] RX overflow flag (W1C) */ + __IM uint32_t TONE : 1; /*!< [6..6] Clean RX FIFO time-out */ + __IM uint32_t TOIDLE : 1; /*!< [7..7] TX idle time-out */ + __IM uint32_t RXHF : 1; /*!< [8..8] RX FIFO half-full */ + __IM uint32_t RXF : 1; /*!< [9..9] RX FIFO full */ + __IM uint32_t TXEND : 1; /*!< [10..10] TX end */ + __IM uint32_t TXF : 1; /*!< [11..11] TX FIFO full */ + uint32_t : 20; + } SR_b; + } ; + + union { + __IOM uint32_t GTR; /*!< (@ 0x00000014) UART Frame Guard-time Register */ + + struct { + __IOM uint32_t GT : 8; /*!< [7..0] Frame Guard-Time */ + uint32_t : 24; + } GTR_b; + } ; + + union { + __IOM uint32_t TOR; /*!< (@ 0x00000018) UART Time-Out Control Register */ + + struct { + __IOM uint32_t TO : 8; /*!< [7..0] Time-Out value */ + uint32_t : 24; + } TOR_b; + } ; + __OM uint32_t TXFR; /*!< (@ 0x0000001C) Reset UART TX FIFO with any value */ + __OM uint32_t RXFR; /*!< (@ 0x00000020) Reset UART RX FIFO with any value */ +} UART_Type; /*!< Size = 36 (0x24) */ + + + +/* =========================================================================================================================== */ +/* ================ I2C ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Inter-Integrated Circuit (I2C) + */ + +typedef struct { /*!< (@ 0x40003000) I2C Structure */ + + union { + __IOM uint32_t CTLSET; /*!< (@ 0x00000000) Register */ + + struct { + __IOM uint32_t CR0 : 1; /*!< [0..0] CLK SET */ + __IOM uint32_t CR1 : 1; /*!< [1..1] CLK SET */ + __IOM uint32_t AA : 1; /*!< [2..2] answer control */ + __IOM uint32_t SI : 1; /*!< [3..3] interrupt flag */ + __IOM uint32_t STO : 1; /*!< [4..4] stop control */ + __IOM uint32_t STA : 1; /*!< [5..5] start control */ + __IOM uint32_t EN : 1; /*!< [6..6] enable */ + __IOM uint32_t CR2 : 1; /*!< [7..7] clk control */ + uint32_t : 24; + } CTLSET_b; + } ; + + union { + __IOM uint32_t STAT; /*!< (@ 0x00000004) Register */ + + struct { + uint32_t : 3; + __IOM uint32_t STAT : 5; /*!< [7..3] BUS STATUS */ + uint32_t : 24; + } STAT_b; + } ; + + union { + __IOM uint32_t DATA; /*!< (@ 0x00000008) Register */ + + struct { + __IOM uint32_t DATA : 8; /*!< [7..0] SEND OR RECEIVE DATA */ + uint32_t : 24; + } DATA_b; + } ; + + union { + __IOM uint32_t ADDR; /*!< (@ 0x0000000C) Register */ + + struct { + __IOM uint32_t GC : 1; /*!< [0..0] radio enable */ + __IOM uint32_t ADDR : 7; /*!< [7..1] addre */ + uint32_t : 8; + __IOM uint32_t FILTERDELAY : 4; /*!< [19..16] FILTERDELAY */ + uint32_t : 4; + __IOM uint32_t FILTERDELAY_EN : 8; /*!< [31..24] FILTERDELAY_EN */ + } ADDR_b; + } ; + __IM uint32_t RESERVED[2]; + + union { + __IOM uint32_t CTLCLR; /*!< (@ 0x00000018) Register */ + + struct { + __IOM uint32_t CR0 : 1; /*!< [0..0] CLEAT CR0 */ + __IOM uint32_t CR1 : 1; /*!< [1..1] CLEAT CR1 */ + __IOM uint32_t AA : 1; /*!< [2..2] CLEAT 11 */ + __IOM uint32_t SI : 1; /*!< [3..3] CLEAT SI */ + __IOM uint32_t STO : 1; /*!< [4..4] CLEAT STO */ + __IOM uint32_t STA : 1; /*!< [5..5] CLEAT STA */ + __IOM uint32_t EN : 1; /*!< [6..6] CLEAT EN */ + __IOM uint32_t CR2 : 1; /*!< [7..7] CLEAT CR2 */ + uint32_t : 24; + } CTLCLR_b; + } ; +} I2C_Type; /*!< Size = 28 (0x1c) */ + + + +/* =========================================================================================================================== */ +/* ================ SPI ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Serial Peripheral Interface Bus (SPI) + */ + +typedef struct { /*!< (@ 0x40003800) SPI Structure */ + + union { + __IOM uint32_t CFG; /*!< (@ 0x00000000) Register */ + + struct { + __IOM uint32_t MODE : 1; /*!< [0..0] mode select */ + __IOM uint32_t CPOL : 1; /*!< [1..1] clock polarity */ + __IOM uint32_t CPHA : 1; /*!< [2..2] clock phase */ + __IOM uint32_t DB : 3; /*!< [5..3] baud rate */ + __IOM uint32_t TXWDSZ : 2; /*!< [7..6] tx data size */ + __IOM uint32_t LSB : 1; /*!< [8..8] transmit control */ + uint32_t : 1; + __IOM uint32_t SS_OUT : 1; /*!< [10..10] periphare select */ + uint32_t : 3; + __IOM uint32_t MCS : 1; /*!< [14..14] handler section select */ + __IOM uint32_t MSE : 1; /*!< [15..15] handler mode select */ + __IOM uint32_t MSTC : 1; /*!< [16..16] handler command start */ + __IOM uint32_t MODEF : 1; /*!< [17..17] mode fail enable */ + uint32_t : 14; + } CFG_b; + } ; + + union { + __IOM uint32_t STA; /*!< (@ 0x00000004) Register */ + + struct { + __IOM uint32_t RECVOV : 1; /*!< [0..0] RX overbrim flag */ + __IOM uint32_t MDF : 1; /*!< [1..1] mode false */ + __IOM uint32_t TXNFUL : 1; /*!< [2..2] TX FIFO no full */ + __IOM uint32_t TXFUL : 1; /*!< [3..3] TX FIFO full */ + __IOM uint32_t RXNEP : 1; /*!< [4..4] RX not empty */ + __IOM uint32_t RXFUL : 1; /*!< [5..5] RX full */ + __IOM uint32_t TXUFL : 1; /*!< [6..6] TX underflow */ + __IOM uint32_t BUSY : 1; /*!< [7..7] module busy */ + uint32_t : 24; + } STA_b; + } ; + + union { + __IOM uint32_t INTEN; /*!< (@ 0x00000008) Register */ + + struct { + __IOM uint32_t INTEN : 7; /*!< [6..0] interrupt enable */ + uint32_t : 25; + } INTEN_b; + } ; + + union { + __IOM uint32_t INTDIS; /*!< (@ 0x0000000C) Register */ + + struct { + __IOM uint32_t INTEN : 7; /*!< [6..0] close interrupt */ + uint32_t : 25; + } INTDIS_b; + } ; + + union { + __IOM uint32_t INTMASK; /*!< (@ 0x00000010) Register */ + + struct { + __IOM uint32_t INTEN : 7; /*!< [6..0] interrupt mask */ + uint32_t : 25; + } INTMASK_b; + } ; + + union { + __IOM uint32_t EN; /*!< (@ 0x00000014) Register */ + + struct { + __IOM uint32_t EN : 1; /*!< [0..0] spi module enable */ + uint32_t : 31; + } EN_b; + } ; + + union { + __IOM uint32_t DELAY; /*!< (@ 0x00000018) Register */ + + struct { + __IOM uint32_t d_int : 8; /*!< [7..0] d_int */ + __IOM uint32_t d_affter : 8; /*!< [15..8] d_affter */ + __IOM uint32_t d_btwn : 8; /*!< [23..16] d_btwn */ + __IOM uint32_t d_nss : 8; /*!< [31..24] d_nss */ + } DELAY_b; + } ; + __IOM uint32_t TX; /*!< (@ 0x0000001C) Register */ + __IOM uint32_t RX; /*!< (@ 0x00000020) Register */ + + union { + __IOM uint32_t IDLECNT; /*!< (@ 0x00000024) Register */ + + struct { + __IOM uint32_t IDLECNT : 8; /*!< [7..0] IDLECNT */ + uint32_t : 24; + } IDLECNT_b; + } ; + + union { + __IOM uint32_t TXTH; /*!< (@ 0x00000028) Register */ + + struct { + __IOM uint32_t TXTHOLD : 32; /*!< [31..0] cause no full interrupt */ + } TXTH_b; + } ; + + union { + __IOM uint32_t RXTH; /*!< (@ 0x0000002C) Register */ + + struct { + __IOM uint32_t RXTHOLD : 32; /*!< [31..0] cause no empty interrupt */ + } RXTH_b; + } ; +} SPI_Type; /*!< Size = 48 (0x30) */ + + + +/* =========================================================================================================================== */ +/* ================ WDG ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Watchdog (WDG) + */ + +typedef struct { /*!< (@ 0x40004000) WDG Structure */ + __IOM uint32_t LOAD; /*!< (@ 0x00000000) WDT LOAD Register */ + __IM uint32_t VALUE; /*!< (@ 0x00000004) WDT Counter Register */ + + union { + __IOM uint32_t CR; /*!< (@ 0x00000008) WDT Control Register */ + + struct { + __IOM uint32_t INTE : 1; /*!< [0..0] Enable interrupt */ + __IOM uint32_t RSTE : 1; /*!< [1..1] Enable Reset */ + __IOM uint32_t DBGE : 1; /*!< [2..2] Enable Debug Pending */ + uint32_t : 29; + } CR_b; + } ; + __OM uint32_t INTCLR; /*!< (@ 0x0000000C) WDT interrupt clear Register */ + + union { + __IM uint32_t RIS; /*!< (@ 0x00000010) WDT original interrupt flag Register */ + + struct { + __IM uint32_t RIF : 1; /*!< [0..0] original interrupt flag */ + uint32_t : 31; + } RIS_b; + } ; + + union { + __IM uint32_t MIS; /*!< (@ 0x00000014) WDT MASK interrupt flag Register */ + + struct { + __IM uint32_t MIF : 1; /*!< [0..0] MASK interrupt flag */ + uint32_t : 31; + } MIS_b; + } ; + __IM uint32_t RESERVED[250]; + + union { + __IOM uint32_t LOCK; /*!< (@ 0x00000400) WDT LOCK Register */ + + struct { + __IOM uint32_t LOCK : 1; /*!< [0..0] WDT LOCK Control */ + uint32_t : 31; + } LOCK_b; + } ; +} WDG_Type; /*!< Size = 1028 (0x404) */ + + + +/* =========================================================================================================================== */ +/* ================ ADC ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Analog-to-Digital Converter (ADC) + */ + +typedef struct { /*!< (@ 0x40004800) ADC Structure */ + + union { + __IOM uint32_t CON0; /*!< (@ 0x00000000) AD Control Register */ + + struct { + __IOM uint32_t M : 4; /*!< [3..0] ADC input channel select */ + uint32_t : 1; + __IOM uint32_t EN : 1; /*!< [5..5] ADC module enable */ + uint32_t : 1; + __IOM uint32_t START : 1; /*!< [7..7] AD conversion start */ + __IOM uint32_t CLK : 3; /*!< [10..8] ADC clock divider (800KHz ~ 16MHz) */ + __IOM uint32_t TRIG_EN : 1; /*!< [11..11] Enable H/w trigger */ + __IOM uint32_t CONTINUE : 1; /*!< [12..12] Enable continue mode */ + __IOM uint32_t ALIGN : 1; /*!< [13..13] ADC result align moe */ + uint32_t : 1; + __IOM uint32_t ENCONT : 1; /*!< [15..15] 1: Never Stop Conversion in continue mode */ + __IOM uint32_t INT_EN : 4; /*!< [19..16] Enable ADC interrupt */ + __IOM uint32_t TZO : 3; /*!< [22..20] zero offset change */ + uint32_t : 6; + __IOM uint32_t BAKEN : 1; /*!< [29..29] Enable backup the previous conversion value */ + __IOM uint32_t PWD : 1; /*!< [30..30] Power down analog physical module */ + __IOM uint32_t RST : 1; /*!< [31..31] Reset analog physical module */ + } CON0_b; + } ; + + union { + __IOM uint32_t STAT; /*!< (@ 0x00000004) ADC State Registter */ + + struct { + __IM uint32_t DONE : 1; /*!< [0..0] ADC done(auto clear after read reg DATx) */ + __IOM uint32_t INT_CLR : 1; /*!< [1..1] ADC clear interrupt flag, 1:clear */ + uint32_t : 2; + __IM uint32_t COMP_RESULT : 2; /*!< [5..4] Result of Comparison(auto clear after read reg DATx) */ + __IOM uint32_t EOC_CHECK_DIS : 1; /*!< [6..6] Disable End-of-Conversion checking */ + uint32_t : 9; + __IOM uint32_t TS_SET : 5; /*!< [20..16] Set Ts cycles */ + __IOM uint32_t DLY_SET : 3; /*!< [23..21] Set delay cycles with ADC clock */ + __IM uint32_t EOC_CNT : 4; /*!< [27..24] Count of End-of-Conversion */ + __IM uint32_t START_CNT : 4; /*!< [31..28] Count of Start */ + } STAT_b; + } ; + + union { + __IOM uint32_t DAT0; /*!< (@ 0x00000008) ADC Result0 Register */ + + struct { + __IM uint32_t DATA : 16; /*!< [15..0] ADC result data */ + __IOM uint32_t CMPTH : 12; /*!< [27..16] Comparison threshold */ + uint32_t : 4; + } DAT0_b; + } ; + + union { + __IOM uint32_t DAT1; /*!< (@ 0x0000000C) ADC Result1 Register */ + + struct { + __IM uint32_t DATA : 16; /*!< [15..0] ADC result data */ + __IOM uint32_t CMPTH : 12; /*!< [27..16] Comparison threshold */ + uint32_t : 4; + } DAT1_b; + } ; + + union { + __IOM uint32_t DAT2; /*!< (@ 0x00000010) ADC Result2 Register */ + + struct { + __IM uint32_t DATA : 16; /*!< [15..0] ADC result data */ + __IOM uint32_t CMPTH : 12; /*!< [27..16] Comparison threshold */ + uint32_t : 4; + } DAT2_b; + } ; + + union { + __IOM uint32_t DAT3; /*!< (@ 0x00000014) ADC Result3 Register */ + + struct { + __IM uint32_t DATA : 16; /*!< [15..0] ADC result data */ + __IOM uint32_t CMPTH : 12; /*!< [27..16] Comparison threshold */ + uint32_t : 4; + } DAT3_b; + } ; + + union { + __IOM uint32_t DAT4; /*!< (@ 0x00000018) ADC Result4 Register */ + + struct { + __IM uint32_t DATA : 16; /*!< [15..0] ADC result data */ + __IOM uint32_t CMPTH : 12; /*!< [27..16] Comparison threshold */ + uint32_t : 4; + } DAT4_b; + } ; + + union { + __IOM uint32_t DAT5; /*!< (@ 0x0000001C) ADC Result5 Register */ + + struct { + __IM uint32_t DATA : 16; /*!< [15..0] ADC result data */ + __IOM uint32_t CMPTH : 12; /*!< [27..16] Comparison threshold */ + uint32_t : 4; + } DAT5_b; + } ; + + union { + __IOM uint32_t DAT6; /*!< (@ 0x00000020) ADC Result6 Register */ + + struct { + __IM uint32_t DATA : 16; /*!< [15..0] ADC result data */ + __IOM uint32_t CMPTH : 12; /*!< [27..16] Comparison threshold */ + uint32_t : 4; + } DAT6_b; + } ; + + union { + __IOM uint32_t DAT7; /*!< (@ 0x00000024) ADC Result7 Register */ + + struct { + __IM uint32_t DATA : 16; /*!< [15..0] ADC result data */ + __IOM uint32_t CMPTH : 12; /*!< [27..16] Comparison threshold */ + uint32_t : 4; + } DAT7_b; + } ; + + union { + __IOM uint32_t DAT8; /*!< (@ 0x00000028) ADC Result8 Register */ + + struct { + __IM uint32_t DATA : 16; /*!< [15..0] ADC result data */ + __IOM uint32_t CMPTH : 12; /*!< [27..16] Comparison threshold */ + uint32_t : 4; + } DAT8_b; + } ; + + union { + __IOM uint32_t DAT9; /*!< (@ 0x0000002C) ADC Result9 Register */ + + struct { + __IM uint32_t DATA : 16; /*!< [15..0] ADC result data */ + __IOM uint32_t CMPTH : 12; /*!< [27..16] Comparison threshold */ + uint32_t : 4; + } DAT9_b; + } ; + + union { + __IOM uint32_t DAT10; /*!< (@ 0x00000030) ADC Result10 Register */ + + struct { + __IM uint32_t DATA : 16; /*!< [15..0] ADC result data */ + __IOM uint32_t CMPTH : 12; /*!< [27..16] Comparison threshold */ + uint32_t : 4; + } DAT10_b; + } ; + + union { + __IOM uint32_t DAT11; /*!< (@ 0x00000034) ADC Result11 Register */ + + struct { + __IM uint32_t DATA : 16; /*!< [15..0] ADC result data */ + __IOM uint32_t CMPTH : 12; /*!< [27..16] Comparison threshold */ + uint32_t : 4; + } DAT11_b; + } ; + + union { + __IOM uint32_t DAT12; /*!< (@ 0x00000038) ADC Result12 Register */ + + struct { + __IM uint32_t DATA : 16; /*!< [15..0] ADC result data */ + __IOM uint32_t CMPTH : 12; /*!< [27..16] Comparison threshold */ + uint32_t : 4; + } DAT12_b; + } ; + + union { + __IOM uint32_t DAT13; /*!< (@ 0x0000003C) ADC Result13 Register */ + + struct { + __IM uint32_t DATA : 16; /*!< [15..0] ADC result data */ + __IOM uint32_t CMPTH : 12; /*!< [27..16] Comparison threshold */ + uint32_t : 4; + } DAT13_b; + } ; + + union { + __IOM uint32_t DAT14; /*!< (@ 0x00000040) ADC Result14 Register */ + + struct { + __IM uint32_t DATA : 16; /*!< [15..0] ADC result data */ + __IOM uint32_t CMPTH : 12; /*!< [27..16] Comparison threshold */ + uint32_t : 4; + } DAT14_b; + } ; + + union { + __IOM uint32_t DAT15; /*!< (@ 0x00000044) ADC Result13 Register */ + + struct { + __IM uint32_t DATA : 16; /*!< [15..0] ADC result data */ + __IOM uint32_t CMPTH : 12; /*!< [27..16] Comparison threshold */ + uint32_t : 4; + } DAT15_b; + } ; + + union { + __IOM uint32_t CHSEL; /*!< (@ 0x00000048) ADC channel selection Register */ + + struct { + __IOM uint32_t CH_SEL : 16; /*!< [15..0] Channel 0~15 */ + __IOM uint32_t CH_CNT : 4; /*!< [19..16] Selected Channel Count */ + uint32_t : 1; + __IOM uint32_t DISC_INTSEL : 1; /*!< [21..21] Select interrupt condition when DISCEN==1 */ + __IOM uint32_t DISCNUM : 3; /*!< [24..22] Discontinuous mode channel count (DISCNUM+1) */ + __IOM uint32_t DISCEN : 1; /*!< [25..25] Discontinuous mode Enable */ + __IOM uint32_t TRIG_SEL16 : 2; /*!< [27..26] Trigger Selection 16 */ + __IOM uint32_t TRIG_SEL17 : 2; /*!< [29..28] Trigger Selection 17 */ + __IOM uint32_t EXTRIG_SEL : 2; /*!< [31..30] External Trigger Selection */ + } CHSEL_b; + } ; + + union { + __IOM uint32_t TRGSEL; /*!< (@ 0x0000004C) ADC Trigger selection Register */ + + struct { + __IOM uint32_t TRIG_SEL0 : 2; /*!< [1..0] Trigger Selection 0 */ + __IOM uint32_t TRIG_SEL1 : 2; /*!< [3..2] Trigger Selection 1 */ + __IOM uint32_t TRIG_SEL2 : 2; /*!< [5..4] Trigger Selection 2 */ + __IOM uint32_t TRIG_SEL3 : 2; /*!< [7..6] Trigger Selection 3 */ + __IOM uint32_t TRIG_SEL4 : 2; /*!< [9..8] Trig Selection 4 */ + __IOM uint32_t TRIG_SEL5 : 2; /*!< [11..10] Trigger Selection 5 */ + __IOM uint32_t TRIG_SEL6 : 2; /*!< [13..12] Trigger Selection 6 */ + __IOM uint32_t TRIG_SEL7 : 2; /*!< [15..14] Trigger Selection 7 */ + __IOM uint32_t TRIG_SEL8 : 2; /*!< [17..16] Trigger Selection 8 */ + __IOM uint32_t TRIG_SEL9 : 2; /*!< [19..18] Trigger Selection 9 */ + __IOM uint32_t TRIG_SEL10 : 2; /*!< [21..20] Trig Selection 10 */ + __IOM uint32_t TRIG_SEL11 : 2; /*!< [23..22] Trigger Selection 11 */ + __IOM uint32_t TRIG_SEL12 : 2; /*!< [25..24] Trigger Selection 12 */ + __IOM uint32_t TRIG_SEL13 : 2; /*!< [27..26] Trigger Selection 13 */ + __IOM uint32_t TRIG_SEL14 : 2; /*!< [29..28] Trigger Selection 14 */ + __IOM uint32_t TRIG_SEL15 : 2; /*!< [31..30] Trig Selection 15 */ + } TRGSEL_b; + } ; + + union { + __IOM uint32_t BKSEL; /*!< (@ 0x00000050) Brake Source (from ADC) Control Register */ + + struct { + __IOM uint32_t BK1_CH : 4; /*!< [3..0] Select a channel as brake source 1 */ + __IOM uint32_t BK1_FLT : 2; /*!< [5..4] Filter the brake source 1 */ + __IOM uint32_t BK1_EN : 2; /*!< [7..6] Enable ondition of brake */ + __IOM uint32_t BK2_CH : 4; /*!< [11..8] Select a channel as brake source 2 */ + __IOM uint32_t BK2_FLT : 2; /*!< [13..12] Filter the brake source 2 */ + __IOM uint32_t BK2_EN : 2; /*!< [15..14] Enable ondition of brake */ + uint32_t : 16; + } BKSEL_b; + } ; + + union { + __IOM uint32_t BAKDAT; /*!< (@ 0x00000054) Data Register of ADC Conversion backup value */ + + struct { + __IM uint32_t BAKDAT : 16; /*!< [15..0] backup Data */ + uint32_t : 16; + } BAKDAT_b; + } ; +} ADC_Type; /*!< Size = 88 (0x58) */ + + + +/* =========================================================================================================================== */ +/* ================ AMISC ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Analog MISC controller (AMISC) + */ + +typedef struct { /*!< (@ 0x40005800) AMISC Structure */ + + union { + __IOM uint32_t LVD_LVR_CR; /*!< (@ 0x00000000) LVD/LVR Control Register */ + + struct { + __IOM uint32_t LVD_EN : 1; /*!< [0..0] LVD enable */ + __IOM uint32_t LDO_LP_EN : 1; /*!< [1..1] LDO lower power enable */ + __IOM uint32_t LVD_F_SEL : 2; /*!< [3..2] LVD Filter Selection */ + uint32_t : 1; + __IOM uint32_t LVD_SEL : 3; /*!< [7..5] LVD selection */ + __IOM uint32_t LVR_EN : 1; /*!< [8..8] LVR enable */ + __IOM uint32_t LVD_INT_EN : 1; /*!< [9..9] LVD interrupt enable */ + __IOM uint32_t TEMP_EN : 1; /*!< [10..10] Temperature enable */ + __IM uint32_t LVD_STATE : 1; /*!< [11..11] LVD state, 0: VDD < LVD_SEL, 1: VDD > LVD_SEL */ + uint32_t : 1; + __IOM uint32_t LVR_SEL : 3; /*!< [15..13] LVR selection */ + uint32_t : 16; + } LVD_LVR_CR_b; + } ; + + union { + __IOM uint32_t VBUF_CR; /*!< (@ 0x00000004) Vbuf Control Register */ + + struct { + __IOM uint32_t VBUF_EN : 1; /*!< [0..0] VBUF enable */ + uint32_t : 3; + __IOM uint32_t ANA2IO_EN : 1; /*!< [4..4] Test analog signal to I/O */ + __IOM uint32_t ANA2PGA_EN : 1; /*!< [5..5] Test analog signal to PGA0 */ + __IOM uint32_t ANA_SEL : 7; /*!< [12..6] Test analog signal selection */ + uint32_t : 19; + } VBUF_CR_b; + } ; + __IM uint32_t RESERVED[2]; + + union { + __IOM uint32_t DAC_CR; /*!< (@ 0x00000010) DAC Control Register */ + + struct { + __IOM uint32_t DAC0Step : 10; /*!< [9..0] The step of voltage */ + __IOM uint32_t DAC1Step : 10; /*!< [19..10] The step of voltage */ + __IOM uint32_t DAC0_EN : 1; /*!< [20..20] DAC0 enable */ + __IOM uint32_t DAC1_EN : 1; /*!< [21..21] DAC1 enable */ + uint32_t : 10; + } DAC_CR_b; + } ; + __IM uint32_t RESERVED1[3]; + + union { + __IOM uint32_t HSI_CR; /*!< (@ 0x00000020) HSI (OSCHF) Control Register */ + + struct { + __IOM uint32_t LDO_SEL : 16; /*!< [15..0] HSI power source selection */ + uint32_t : 8; + __IOM uint32_t HSI_EN : 8; /*!< [31..24] HSI enable, set 0x80(disable), set 0x1(enable) */ + } HSI_CR_b; + } ; + + union { + __IOM uint32_t LSI_CR; /*!< (@ 0x00000024) LSI (OSCLF) Control Register */ + + struct { + uint32_t : 24; + __IOM uint32_t LSI_EN : 8; /*!< [31..24] LSI enable, set 0x80(disable), set 0x1(enable) */ + } LSI_CR_b; + } ; + __IM uint32_t RESERVED2[2]; + + union { + __IOM uint32_t ADC_AIN_CR; /*!< (@ 0x00000030) ADC AIN Control Register */ + + struct { + __IOM uint32_t ANA2ADC_EN : 1; /*!< [0..0] Enable ADC AIN15 from internal source */ + uint32_t : 31; + } ADC_AIN_CR_b; + } ; +} AMISC_Type; /*!< Size = 52 (0x34) */ + + + +/* =========================================================================================================================== */ +/* ================ HWTRIM ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief H/w configure trim values (HWTRIM) + */ + +typedef struct { /*!< (@ 0x40005860) HWTRIM Structure */ + + union { + __IM uint32_t LDO_TRIM; /*!< (@ 0x00000000) LDO trim value */ + + struct { + __IM uint32_t LDO_TRIM : 5; /*!< [4..0] LDO trim value */ + __IM uint32_t LDO_LP_TRIM : 5; /*!< [9..5] LDO lower power trim value */ + __IM uint32_t LDO_TUNE : 2; /*!< [11..10] Ldo high temp leakage current compensation */ + uint32_t : 20; + } LDO_TRIM_b; + } ; + + union { + __IM uint32_t VBUF_TRIM; /*!< (@ 0x00000004) Vbuf trim value */ + + struct { + __IM uint32_t VBUF_TRIM : 7; /*!< [6..0] VBUF voltage trim value */ + uint32_t : 25; + } VBUF_TRIM_b; + } ; + + union { + __IM uint32_t HSI_TRIM; /*!< (@ 0x00000008) High Speed Internal clock (OSCHF) trim value */ + + struct { + __IM uint32_t HSI_D_CFG : 9; /*!< [8..0] HSI low trim config */ + __IM uint32_t HSI_FSEL_CFG : 7; /*!< [15..9] HSI high trim config */ + __IM uint32_t HSI_TC : 2; /*!< [17..16] The TC of HSI trim value */ + uint32_t : 14; + } HSI_TRIM_b; + } ; + + union { + __IM uint32_t LSI_TRIM; /*!< (@ 0x0000000C) Low Speed Internal clock (OSCLF) trim value */ + + struct { + __IM uint32_t LSI_TRIM : 8; /*!< [7..0] The LSI trim value, 0xB3= 32KHz */ + uint32_t : 24; + } LSI_TRIM_b; + } ; + + union { + __IM uint32_t MISC_CFG; /*!< (@ 0x00000010) The miscellaneous configuration */ + + struct { + __IM uint32_t EXT_nRST_EN : 1; /*!< [0..0] External reset pin enable */ + uint32_t : 31; + } MISC_CFG_b; + } ; +} HWTRIM_Type; /*!< Size = 20 (0x14) */ + + + +/* =========================================================================================================================== */ +/* ================ CRC ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Cyclic redundancy check (CRC) + */ + +typedef struct { /*!< (@ 0x4001E000) CRC Structure */ + + union { + __IOM uint32_t CR; /*!< (@ 0x00000000) Control Register */ + + struct { + __IOM uint32_t POLYSEL : 1; /*!< [0..0] CRC polynomial codes select */ + __IM uint32_t VERF : 1; /*!< [1..1] flag of verificaion CRC value */ + uint32_t : 30; + } CR_b; + } ; + + union { + __IOM uint32_t DIN; /*!< (@ 0x00000004) CRC Data input Register */ + + struct { + __IOM uint32_t DIN : 32; /*!< [31..0] Input Data */ + } DIN_b; + } ; + + union { + __IOM uint32_t DOUT; /*!< (@ 0x00000008) Result output register */ + + struct { + __IOM uint32_t DOUT : 32; /*!< [31..0] CRC value */ + } DOUT_b; + } ; +} CRC_Type; /*!< Size = 12 (0xc) */ + + + +/* =========================================================================================================================== */ +/* ================ DSP ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief DSP hardware speedup (DSP) + */ + +typedef struct { /*!< (@ 0x40008000) DSP Structure */ + + union { + __IOM uint32_t CR; /*!< (@ 0x00000000) DSP ACCEL Control Register */ + + struct { + __IOM uint32_t MODE : 3; /*!< [2..0] Mode selection */ + uint32_t : 29; + } CR_b; + } ; + + union { + __IM uint32_t SR; /*!< (@ 0x00000004) DSP ACCEL Status Register */ + + struct { + __IM uint32_t DONE : 1; /*!< [0..0] DSP End */ + uint32_t : 31; + } SR_b; + } ; + __IOM uint32_t SDAT1; /*!< (@ 0x00000008) DSP ACCEL Source Data1 */ + __IM uint32_t RESERVED; + __IOM uint32_t SDAT2; /*!< (@ 0x00000010) DSP ACCEL Source Data2 */ + __IM uint32_t RESERVED1; + __IM uint32_t RSLT1; /*!< (@ 0x00000018) DSP ACCEL Result 1 */ + __IM uint32_t RESERVED2; + __IM uint32_t RSLT2; /*!< (@ 0x00000020) DSP ACCEL Result 2 */ +} DSP_Type; /*!< Size = 36 (0x24) */ + + + +/* =========================================================================================================================== */ +/* ================ OPAMP ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief OP-Amplifiers with PGA mode (OPAMP) + */ + +typedef struct { /*!< (@ 0x40005880) OPAMP Structure */ + + union { + __IOM uint32_t PGA_CR; /*!< (@ 0x00000000) Control Register */ + + struct { + __IOM uint32_t PGA_EN : 1; /*!< [0..0] Enable PGA */ + __IOM uint32_t PGA_IO_EN : 1; /*!< [1..1] Enable PGA output to I/O */ + __IOM uint32_t PGA_GAIN : 6; /*!< [7..2] PGA gain selection */ + uint32_t : 2; + __IOM uint32_t PGA_VIN_SEL : 1; /*!< [10..10] PGA N terminal selection */ + __IOM uint32_t PGA_VIP_SEL : 1; /*!< [11..11] PGA P terminal selection */ + uint32_t : 20; + } PGA_CR_b; + } ; +} OPAMP_Type; /*!< Size = 4 (0x4) */ + + + +/* =========================================================================================================================== */ +/* ================ COMP ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Analog Comparator (COMP) + */ + +typedef struct { /*!< (@ 0x40008800) COMP Structure */ + + union { + __IOM uint32_t CTRL; /*!< (@ 0x00000000) COMP Control Register */ + + struct { + __IOM uint32_t EN : 1; /*!< [0..0] COMP Enable */ + __IM uint32_t COUT : 1; /*!< [1..1] COMP Output */ + __IOM uint32_t VIN_SEL : 2; /*!< [3..2] Comp n terminal input selection */ + __IOM uint32_t FIL_CTRL : 4; /*!< [7..4] Filter selction */ + __IOM uint32_t HYS_EN : 1; /*!< [8..8] hysteresis enable */ + uint32_t : 2; + __IOM uint32_t OUT_EN : 1; /*!< [11..11] Comp output signal */ + __IOM uint32_t POL_SEL : 1; /*!< [12..12] Select output polarity */ + uint32_t : 19; + } CTRL_b; + } ; + + union { + __IOM uint32_t VIPSEL; /*!< (@ 0x00000004) COMP P terminal DAC Register */ + + struct { + __IOM uint32_t VIP_SEL : 5; /*!< [4..0] Comp p terminal input selection */ + uint32_t : 27; + } VIPSEL_b; + } ; + + union { + __IOM uint32_t IR; /*!< (@ 0x00000008) COMP Interrupt Register */ + + struct { + __IOM uint32_t FIE : 1; /*!< [0..0] Enable Comp Interrupt with Falling */ + __IOM uint32_t RIE : 1; /*!< [1..1] Enable Comp Interrupt with Rising */ + uint32_t : 30; + } IR_b; + } ; + + union { + __IOM uint32_t IF; /*!< (@ 0x0000000C) COMP Interrupt Flag Register */ + + struct { + __IOM uint32_t FIF : 1; /*!< [0..0] Interrupt Falling Flag, W1C */ + __IOM uint32_t RIF : 1; /*!< [1..1] Interrupt Rising Flag, W1C */ + uint32_t : 30; + } IF_b; + } ; + + union { + __IOM uint32_t INITCNT; /*!< (@ 0x00000010) COMP set initial delay register */ + + struct { + __IOM uint32_t INIT_DELAY : 10; /*!< [9..0] Comp Set Delay */ + uint32_t : 22; + } INITCNT_b; + } ; +} COMP_Type; /*!< Size = 20 (0x14) */ + + + +/* =========================================================================================================================== */ +/* ================ TIM ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Timer Controller Module (TIM) + */ + +typedef struct { /*!< (@ 0x4000C000) TIM Structure */ + + union { + __IOM uint32_t CR1; /*!< (@ 0x00000000) Control Register 1 */ + + struct { + __IOM uint32_t CEN : 1; /*!< [0..0] Counter enable */ + __IOM uint32_t UDIS : 1; /*!< [1..1] Update disable */ + __IOM uint32_t URS : 1; /*!< [2..2] Update request source */ + __IOM uint32_t OPM : 1; /*!< [3..3] One pulse spurce */ + __IOM uint32_t DIR : 1; /*!< [4..4] Direction */ + __IOM uint32_t CMS : 2; /*!< [6..5] Center-aligned mode selection */ + __IOM uint32_t ARPE : 1; /*!< [7..7] Auto-reload preload enable */ + __IOM uint32_t CKD : 2; /*!< [9..8] Clock division */ + __IOM uint32_t ASYMEN : 1; /*!< [10..10] Asymmetric mode enable */ + uint32_t : 21; + } CR1_b; + } ; + + union { + __IOM uint32_t CR2; /*!< (@ 0x00000004) Control Register 2 */ + + struct { + __IOM uint32_t CCPC : 1; /*!< [0..0] Capture/compare preloaded control */ + uint32_t : 1; + __IOM uint32_t CCUS : 1; /*!< [2..2] Capture/compare control update selection */ + uint32_t : 1; + __IOM uint32_t MMS : 3; /*!< [6..4] Master mode selection */ + __IOM uint32_t TI1S : 1; /*!< [7..7] TI1 selection */ + __IOM uint32_t OIS1 : 1; /*!< [8..8] Output Idle state 1 */ + __IOM uint32_t OIS1N : 1; /*!< [9..9] Output Idle state 1 */ + __IOM uint32_t OIS2 : 1; /*!< [10..10] Output Idle state 2 */ + __IOM uint32_t OIS2N : 1; /*!< [11..11] Output Idle state 2 */ + __IOM uint32_t OIS3 : 1; /*!< [12..12] Output Idle state 3 */ + __IOM uint32_t OIS3N : 1; /*!< [13..13] Output Idle state 3 */ + __IOM uint32_t OIS4 : 1; /*!< [14..14] Output Idle state 4 */ + uint32_t : 17; + } CR2_b; + } ; + + union { + __IOM uint32_t SMCR; /*!< (@ 0x00000008) Slave Mode control Register */ + + struct { + __IOM uint32_t SMS : 3; /*!< [2..0] Slave mode selection */ + uint32_t : 1; + __IOM uint32_t TS : 3; /*!< [6..4] Trigger selection */ + __IOM uint32_t MSM : 1; /*!< [7..7] Master/slave mode */ + __IOM uint32_t ETF : 4; /*!< [11..8] External trigger filter */ + __IOM uint32_t ETPS : 2; /*!< [13..12] External trigger prescaler */ + __IOM uint32_t ECE : 1; /*!< [14..14] External clock enable */ + __IOM uint32_t ETP : 1; /*!< [15..15] External trigger polarity */ + uint32_t : 16; + } SMCR_b; + } ; + + union { + __IOM uint32_t DIER; /*!< (@ 0x0000000C) interrupt enbale register */ + + struct { + __IOM uint32_t UIE : 1; /*!< [0..0] Update interrupt enable */ + __IOM uint32_t CC1IE : 1; /*!< [1..1] Capture/Compare 1 interrupt enable */ + __IOM uint32_t CC2IE : 1; /*!< [2..2] Capture/Compare 2 interrupt enable */ + __IOM uint32_t CC3IE : 1; /*!< [3..3] Capture/Compare 3 interrupt enable */ + __IOM uint32_t CC4IE : 1; /*!< [4..4] Capture/Compare 4 interrupt enable */ + __IOM uint32_t COMIE : 1; /*!< [5..5] COM interrupt enable */ + __IOM uint32_t TIE : 1; /*!< [6..6] Trigger interrupt enable */ + __IOM uint32_t BIE : 1; /*!< [7..7] Break interrupt enable */ + __IOM uint32_t CCD1IE : 1; /*!< [8..8] Capture/Compare 1 interrupt enable */ + __IOM uint32_t CCD2IE : 1; /*!< [9..9] Capture/Compare 2 interrupt enable */ + __IOM uint32_t CCD3IE : 1; /*!< [10..10] Capture/Compare 3 interrupt enable */ + __IOM uint32_t OVIE : 1; /*!< [11..11] Overflow interrupt enable */ + __IOM uint32_t UDIE : 1; /*!< [12..12] Underflow interrupt enable */ + __IOM uint32_t CCD4IE : 1; /*!< [13..13] Capture/Compare 4 interrupt enable */ + uint32_t : 18; + } DIER_b; + } ; + + union { + __IOM uint32_t SR; /*!< (@ 0x00000010) state Register */ + + struct { + __IOM uint32_t UIF : 1; /*!< [0..0] Update interrupt flag */ + __IOM uint32_t CC1IF : 1; /*!< [1..1] Capture/Compare 1 interrupt flag */ + __IOM uint32_t CC2IF : 1; /*!< [2..2] Capture/Compare 2 interrupt flag */ + __IOM uint32_t CC3IF : 1; /*!< [3..3] Capture/Compare 3 interrupt flag */ + __IOM uint32_t CC4IF : 1; /*!< [4..4] Capture/Compare 4 interrupt flag */ + __IOM uint32_t COMIF : 1; /*!< [5..5] COM interrupt flag */ + __IOM uint32_t TIF : 1; /*!< [6..6] Trigger interrupt flag */ + __IOM uint32_t BIF : 1; /*!< [7..7] Break interrupt flag */ + uint32_t : 1; + __IOM uint32_t CC1OF : 1; /*!< [9..9] CC1OF */ + __IOM uint32_t CC2OF : 1; /*!< [10..10] CC2OF */ + __IOM uint32_t CC3OF : 1; /*!< [11..11] CC3OF */ + __IOM uint32_t CC4OF : 1; /*!< [12..12] CC4OF */ + __IOM uint32_t CCD1IF : 1; /*!< [13..13] Capture/Compare 1 interrupt flag */ + __IOM uint32_t CCD2IF : 1; /*!< [14..14] Capture/Compare 2 interrupt flag */ + __IOM uint32_t CCD3IF : 1; /*!< [15..15] Capture/Compare 3 interrupt flag */ + __IOM uint32_t OVIF : 1; /*!< [16..16] Overflow interrupt flag */ + __IOM uint32_t UDIF : 1; /*!< [17..17] Underflow interrupt flag */ + __IOM uint32_t CCD4IF : 1; /*!< [18..18] Break interrupt flag */ + uint32_t : 13; + } SR_b; + } ; + + union { + __IOM uint32_t EGR; /*!< (@ 0x00000014) event generation Register */ + + struct { + __IOM uint32_t UG : 1; /*!< [0..0] Update generation */ + __IOM uint32_t CC1G : 1; /*!< [1..1] Capture/Compare 1 generation */ + __IOM uint32_t CC2G : 1; /*!< [2..2] Capture/Compare 2 generation */ + __IOM uint32_t CC3G : 1; /*!< [3..3] Capture/Compare 3 generation */ + __IOM uint32_t CC4G : 1; /*!< [4..4] Capture/Compare 4 generation */ + __IOM uint32_t COMG : 1; /*!< [5..5] Capture/Compare control update generation */ + __IOM uint32_t TG : 1; /*!< [6..6] Trigger generation */ + __IOM uint32_t BG : 1; /*!< [7..7] Break generation */ + uint32_t : 24; + } EGR_b; + } ; + + union { + union { + __IOM uint32_t CCMR1_OUTPUT; /*!< (@ 0x00000018) Capture or Compare mode Register (Output mode) */ + + struct { + __IOM uint32_t CC1S : 2; /*!< [1..0] Capture/Compare 1 selection */ + __IOM uint32_t OC1FE : 1; /*!< [2..2] Output Compare 1 fast enable */ + __IOM uint32_t OC1PE : 1; /*!< [3..3] Output Compare 1 preload enable */ + __IOM uint32_t OC1M : 3; /*!< [6..4] Output Compare 1 mode */ + __IOM uint32_t OC1CE : 1; /*!< [7..7] Output Compare 1 clear enable */ + __IOM uint32_t CC2S : 2; /*!< [9..8] Capture/Compare 2 selection */ + __IOM uint32_t OC2FE : 1; /*!< [10..10] Output Compare 2 fast enable */ + __IOM uint32_t OC2PE : 1; /*!< [11..11] Output Compare 2 preload enable */ + __IOM uint32_t OC2M : 3; /*!< [14..12] Output Compare 2 mode */ + __IOM uint32_t OC2CE : 1; /*!< [15..15] Output Compare 2 clear enable */ + uint32_t : 16; + } CCMR1_OUTPUT_b; + } ; + + union { + __IOM uint32_t CCMR1_INPUT; /*!< (@ 0x00000018) Capture or Compare mode Register (Input mode) */ + + struct { + __IOM uint32_t CC1S : 2; /*!< [1..0] Capture or Compare 1 Select */ + __IOM uint32_t IC1PSC : 2; /*!< [3..2] Input capture 1 prescaler */ + __IOM uint32_t IC1F : 4; /*!< [7..4] Input capture 1 filter */ + __IOM uint32_t CC2S : 2; /*!< [9..8] Capture or Compare 2 Select */ + __IOM uint32_t IC2PSC : 2; /*!< [11..10] Input capture 2 prescaler */ + __IOM uint32_t IC2F : 4; /*!< [15..12] Input capture 2 filter */ + uint32_t : 16; + } CCMR1_INPUT_b; + } ; + }; + + union { + union { + __IOM uint32_t CCMR2_OUTPUT; /*!< (@ 0x0000001C) Capture or Compare mode Register (output mode) */ + + struct { + __IOM uint32_t CC3S : 2; /*!< [1..0] Capture/Compare 3 selection */ + __IOM uint32_t OC3FE : 1; /*!< [2..2] Output Compare 3 fast enable */ + __IOM uint32_t OC3PE : 1; /*!< [3..3] Output Compare 3 preload enable */ + __IOM uint32_t OC3M : 3; /*!< [6..4] Output Compare 3 mode */ + __IOM uint32_t OC3CE : 1; /*!< [7..7] Output Compare 3 clear enable */ + __IOM uint32_t CC4S : 2; /*!< [9..8] Capture/Compare 4 selection */ + __IOM uint32_t OC4FE : 1; /*!< [10..10] Output Compare 4 fast enable */ + __IOM uint32_t OC4PE : 1; /*!< [11..11] Output Compare 4 preload enable */ + __IOM uint32_t OC4M : 3; /*!< [14..12] Output Compare 4 mode */ + __IOM uint32_t OC4CE : 1; /*!< [15..15] Output Compare 4 clear enable */ + uint32_t : 16; + } CCMR2_OUTPUT_b; + } ; + + union { + __IOM uint32_t CCMR2_INPUT; /*!< (@ 0x0000001C) Capture or Compare mode Register (input mode) */ + + struct { + __IOM uint32_t CC3S : 2; /*!< [1..0] Capture or Compare 3 Select */ + __IOM uint32_t IC3PSC : 2; /*!< [3..2] Input capture 3 prescaler */ + __IOM uint32_t IC3F : 4; /*!< [7..4] Input capture 3 filter */ + __IOM uint32_t CC4S : 2; /*!< [9..8] Capture or Compare 4 Select */ + __IOM uint32_t IC4PSC : 2; /*!< [11..10] Input capture 4 prescaler */ + __IOM uint32_t IC4F : 4; /*!< [15..12] Input capture 4 filter */ + uint32_t : 16; + } CCMR2_INPUT_b; + } ; + }; + + union { + __IOM uint32_t CCER; /*!< (@ 0x00000020) Capture or Compare enable Register */ + + struct { + __IOM uint32_t CC1E : 1; /*!< [0..0] Capture/Compare 1 output enable */ + __IOM uint32_t CC1P : 1; /*!< [1..1] Capture/Compare 1 output polarity */ + __IOM uint32_t CC1NE : 1; /*!< [2..2] Capture/Compare 1 complementary output enable */ + __IOM uint32_t CC1NP : 1; /*!< [3..3] Capture/Compare 1 complementary output polarity */ + __IOM uint32_t CC2E : 1; /*!< [4..4] Capture/Compare 2 output enable */ + __IOM uint32_t CC2P : 1; /*!< [5..5] Capture/Compare 2 output polarity */ + __IOM uint32_t CC2NE : 1; /*!< [6..6] Capture/Compare 2 complementary output enable */ + __IOM uint32_t CC2NP : 1; /*!< [7..7] Capture/Compare 2 complementary output polarity */ + __IOM uint32_t CC3E : 1; /*!< [8..8] Capture/Compare 3 output enable */ + __IOM uint32_t CC3P : 1; /*!< [9..9] Capture/Compare 3 output polarity */ + __IOM uint32_t CC3NE : 1; /*!< [10..10] Capture/Compare 3 complementary output enable */ + __IOM uint32_t CC3NP : 1; /*!< [11..11] Capture/Compare 3 complementary output polarity */ + __IOM uint32_t CC4E : 1; /*!< [12..12] Capture/Compare 4 output enable */ + __IOM uint32_t CC4P : 1; /*!< [13..13] Capture/Compare 4 output polarity */ + uint32_t : 18; + } CCER_b; + } ; + + union { + __IOM uint32_t CNT; /*!< (@ 0x00000024) EPWM counter register */ + + struct { + __IOM uint32_t CNT : 16; /*!< [15..0] Counter value */ + uint32_t : 16; + } CNT_b; + } ; + + union { + __IOM uint32_t PSC; /*!< (@ 0x00000028) Prescaler counter register */ + + struct { + __IOM uint32_t PSC : 16; /*!< [15..0] Prescaler value */ + uint32_t : 16; + } PSC_b; + } ; + + union { + __IOM uint32_t ARR; /*!< (@ 0x0000002C) Auto reload counter register */ + + struct { + __IOM uint32_t ARR : 16; /*!< [15..0] Auto reload value */ + uint32_t : 16; + } ARR_b; + } ; + + union { + __IOM uint32_t RCR; /*!< (@ 0x00000030) Repetition counter register */ + + struct { + __IOM uint32_t REP : 8; /*!< [7..0] Repetition counter value */ + uint32_t : 24; + } RCR_b; + } ; + + union { + __IOM uint32_t CCR1; /*!< (@ 0x00000034) CR1 capture or compare value */ + + struct { + __IOM uint32_t CCR1 : 20; /*!< [19..0] Capture/Compare 1 value */ + uint32_t : 12; + } CCR1_b; + } ; + + union { + __IOM uint32_t CCR2; /*!< (@ 0x00000038) CR2 capture or compare value */ + + struct { + __IOM uint32_t CCR2 : 20; /*!< [19..0] Capture/Compare 2 value */ + uint32_t : 12; + } CCR2_b; + } ; + + union { + __IOM uint32_t CCR3; /*!< (@ 0x0000003C) capture or compare value */ + + struct { + __IOM uint32_t CCR3 : 20; /*!< [19..0] Capture/Compare 3 value */ + uint32_t : 12; + } CCR3_b; + } ; + + union { + __IOM uint32_t CCR4; /*!< (@ 0x00000040) match output control */ + + struct { + __IOM uint32_t CCR4 : 20; /*!< [19..0] Capture/Compare 4 value */ + uint32_t : 12; + } CCR4_b; + } ; + + union { + __IOM uint32_t BDTR; /*!< (@ 0x00000044) Braking ande dead zone control Register */ + + struct { + __IOM uint32_t DTG : 8; /*!< [7..0] Dead-time generator setup */ + __IOM uint32_t LOCK : 2; /*!< [9..8] Lock Configuration */ + __IOM uint32_t OSSI : 1; /*!< [10..10] Off-state selection for Idle mode */ + __IOM uint32_t OSSR : 1; /*!< [11..11] Off-state selection for Run mode */ + __IOM uint32_t BKE : 1; /*!< [12..12] Break enable */ + __IOM uint32_t BKP : 1; /*!< [13..13] Break polarity */ + __IOM uint32_t AOE : 1; /*!< [14..14] Automatic output enable */ + __IOM uint32_t MOE : 1; /*!< [15..15] Main output enable */ + __IOM uint32_t DTGF : 8; /*!< [23..16] Asymmetric Dead-time generator setup */ + __IOM uint32_t DTAE : 1; /*!< [24..24] Asymmetric Dead-time enable */ + uint32_t : 7; + } BDTR_b; + } ; + __IM uint32_t RESERVED[2]; + + union { + __IOM uint32_t CCDR1; /*!< (@ 0x00000050) CR1 down capture or compare value */ + + struct { + __IOM uint32_t CCDR1 : 20; /*!< [19..0] Down Capture/Compare 1 value */ + uint32_t : 12; + } CCDR1_b; + } ; + + union { + __IOM uint32_t CCDR2; /*!< (@ 0x00000054) CR2 down capture or compare value */ + + struct { + __IOM uint32_t CCDR2 : 20; /*!< [19..0] Down Capture/Compare 2 value */ + uint32_t : 12; + } CCDR2_b; + } ; + + union { + __IOM uint32_t CCDR3; /*!< (@ 0x00000058) CR3 down capture or compare value */ + + struct { + __IOM uint32_t CCDR3 : 20; /*!< [19..0] Down Capture/Compare 3 value */ + uint32_t : 12; + } CCDR3_b; + } ; + + union { + __IOM uint32_t CCDR4; /*!< (@ 0x0000005C) CR4 down capture or compare value */ + + struct { + __IOM uint32_t CCDR4 : 20; /*!< [19..0] Down Capture/Compare 4 value */ + uint32_t : 12; + } CCDR4_b; + } ; +} TIM_Type; /*!< Size = 96 (0x60) */ + + + +/* =========================================================================================================================== */ +/* ================ LPTIM ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Low-Power Timer (LPTIM) + */ + +typedef struct { /*!< (@ 0x4000C800) LPTIM Structure */ + + union { + __IOM uint32_t IR; /*!< (@ 0x00000000) LPTIM Interrupt Flag Register */ + + struct { + __IOM uint32_t MR0 : 1; /*!< [0..0] MR0 match flag, writer 1 to clear */ + uint32_t : 31; + } IR_b; + } ; + + union { + __IOM uint32_t TCR; /*!< (@ 0x00000004) LPTIM Control Register */ + + struct { + __IOM uint32_t CEN : 1; /*!< [0..0] LPTIM Module Enable */ + __IOM uint32_t CRST : 1; /*!< [1..1] LPTIM Module Reset */ + __IOM uint32_t CLKS : 2; /*!< [3..2] LPTIM Clock Selection */ + __IOM uint32_t TRIGSEL : 3; /*!< [6..4] Trigger LPTIM selector */ + uint32_t : 25; + } TCR_b; + } ; + + union { + __IOM uint32_t TC; /*!< (@ 0x00000008) LPTIM Current Counter value Register */ + + struct { + __IOM uint32_t TC : 16; /*!< [15..0] Current Counter value */ + uint32_t : 16; + } TC_b; + } ; + + union { + __IOM uint32_t PR; /*!< (@ 0x0000000C) LPTIM Prescaler Register */ + + struct { + __IOM uint32_t PR : 8; /*!< [7..0] Prescaler value, fTIM=fsys/(PR+1) */ + uint32_t : 24; + } PR_b; + } ; + + union { + __IOM uint32_t PC; /*!< (@ 0x00000010) Prescaler current value Register */ + + struct { + __IOM uint32_t PC : 8; /*!< [7..0] Prescaler current value */ + uint32_t : 24; + } PC_b; + } ; + + union { + __IOM uint32_t MCR; /*!< (@ 0x00000014) LPTIM match control Register */ + + struct { + __IOM uint32_t MR0INT : 1; /*!< [0..0] Enable interrupt when match counter */ + __IOM uint32_t MR0RST : 1; /*!< [1..1] Enable reset when match counter */ + __IOM uint32_t MR0STOP : 1; /*!< [2..2] Enable stop when match counter */ + uint32_t : 29; + } MCR_b; + } ; + + union { + __IOM uint32_t MR0; /*!< (@ 0x00000018) Match Register 0 */ + + struct { + __IOM uint32_t MR0 : 16; /*!< [15..0] Match compare value */ + uint32_t : 16; + } MR0_b; + } ; +} LPTIM_Type; /*!< Size = 28 (0x1c) */ + + +/** @} */ /* End of group Device_Peripheral_peripherals */ + + +/* =========================================================================================================================== */ +/* ================ Device Specific Peripheral Address Map ================ */ +/* =========================================================================================================================== */ + + +/** @addtogroup Device_Peripheral_peripheralAddr + * @{ + */ + +#define EFLASH_MEM_BASE 0x00000000UL +#define SRAM_MEM_BASE 0x20000000UL +#define NVR_MEM_BASE 0x00200000UL +#define CORET_BASE 0x18000000UL +#define UID_BASE 0x00201F00UL +#define FLASH_BASE 0x4000F800UL +#define GPIO_BASE 0x40011000UL +#define GPIOA_BASE 0x40011000UL +#define GPIOB_BASE 0x40012000UL +#define AFIO_BASE 0x40011070UL +#define SYSCFG_BASE 0x4001F000UL +#define UART_BASE 0x40002000UL +#define UART0_BASE 0x40002000UL +#define I2C_BASE 0x40003000UL +#define I2C0_BASE 0x40003000UL +#define SPI_BASE 0x40003800UL +#define SPI0_BASE 0x40003800UL +#define WDG_BASE 0x40004000UL +#define ADC_BASE 0x40004800UL +#define ADC0_BASE 0x40004800UL +#define AMISC_BASE 0x40005800UL +#define HWTRIM_BASE 0x40005860UL +#define CRC_BASE 0x4001E000UL +#define DSP_BASE 0x40008000UL +#define OPAMP_BASE 0x40005880UL +#define OPAMP0_BASE 0x40005880UL +#define OPAMP1_BASE 0x40005888UL +#define COMP_BASE 0x40008800UL +#define COMP0_BASE 0x40008800UL +#define COMP1_BASE 0x40009800UL +#define TIM_BASE 0x4000C000UL +#define EPWM_BASE 0x4000C000UL +#define TIM2_BASE 0x40001000UL +#define LPTIM_BASE 0x4000C800UL +#define TIM0_BASE 0x40000000UL +#define TIM1_BASE 0x40000800UL + +/** @} */ /* End of group Device_Peripheral_peripheralAddr */ + + +/* =========================================================================================================================== */ +/* ================ Peripheral declaration ================ */ +/* =========================================================================================================================== */ + + +/** @addtogroup Device_Peripheral_declaration + * @{ + */ + +#define EFLASH_MEM ((EFLASH_MEM_Type*) EFLASH_MEM_BASE) +#define SRAM_MEM ((SRAM_MEM_Type*) SRAM_MEM_BASE) +#define NVR_MEM ((NVR_MEM_Type*) NVR_MEM_BASE) +#define CORET ((CORET_Type*) CORET_BASE) +#define UID ((UID_Type*) UID_BASE) +#define FLASH ((FLASH_Type*) FLASH_BASE) +#define GPIO ((GPIO_Type*) GPIO_BASE) +#define GPIOA ((GPIO_Type*) GPIOA_BASE) +#define GPIOB ((GPIO_Type*) GPIOB_BASE) +#define AFIO ((AFIO_Type*) AFIO_BASE) +#define SYSCFG ((SYSCFG_Type*) SYSCFG_BASE) +#define UART ((UART_Type*) UART_BASE) +#define UART0 ((UART_Type*) UART0_BASE) +#define I2C ((I2C_Type*) I2C_BASE) +#define I2C0 ((I2C_Type*) I2C0_BASE) +#define SPI ((SPI_Type*) SPI_BASE) +#define SPI0 ((SPI_Type*) SPI0_BASE) +#define WDG ((WDG_Type*) WDG_BASE) +#define ADC ((ADC_Type*) ADC_BASE) +#define ADC0 ((ADC_Type*) ADC0_BASE) +#define AMISC ((AMISC_Type*) AMISC_BASE) +#define HWTRIM ((HWTRIM_Type*) HWTRIM_BASE) +#define CRC ((CRC_Type*) CRC_BASE) +#define DSP ((DSP_Type*) DSP_BASE) +#define OPAMP ((OPAMP_Type*) OPAMP_BASE) +#define OPAMP0 ((OPAMP_Type*) OPAMP0_BASE) +#define OPAMP1 ((OPAMP_Type*) OPAMP1_BASE) +#define COMP ((COMP_Type*) COMP_BASE) +#define COMP0 ((COMP_Type*) COMP0_BASE) +#define COMP1 ((COMP_Type*) COMP1_BASE) +#define TIM ((TIM_Type*) TIM_BASE) +#define EPWM ((TIM_Type*) EPWM_BASE) +#define TIM2 ((TIM_Type*) TIM2_BASE) +#define LPTIM ((LPTIM_Type*) LPTIM_BASE) +#define TIM0 ((LPTIM_Type*) TIM0_BASE) +#define TIM1 ((LPTIM_Type*) TIM1_BASE) + +/** @} */ /* End of group Device_Peripheral_declaration */ + + +/* ========================================= End of section using anonymous unions ========================================= */ +#if defined (__GNUC__) + /* anonymous unions are enabled by default */ +#endif + + +/* =========================================================================================================================== */ +/* ================ Pos/Mask Peripheral Section ================ */ +/* =========================================================================================================================== */ + + +/** @addtogroup PosMask_peripherals + * @{ + */ + + + +/* =========================================================================================================================== */ +/* ================ EFLASH_MEM ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= DATA0 ========================================================= */ +/* ======================================================= DATA_END ======================================================== */ + + +/* =========================================================================================================================== */ +/* ================ SRAM_MEM ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= DATA0 ========================================================= */ +/* ======================================================= DATA_END ======================================================== */ + + +/* =========================================================================================================================== */ +/* ================ NVR_MEM ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= DATA0 ========================================================= */ +/* ======================================================= DATA_END ======================================================== */ + + +/* =========================================================================================================================== */ +/* ================ CORET ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= revd ========================================================== */ + + +/* =========================================================================================================================== */ +/* ================ UID ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= UID1 ========================================================== */ +/* ========================================================= UID2 ========================================================== */ +/* ========================================================= UID3 ========================================================== */ + + +/* =========================================================================================================================== */ +/* ================ FLASH ================ */ +/* =========================================================================================================================== */ + +/* ========================================================== CMD ========================================================== */ +#define FLASH_CMD_START_Pos (0UL) /*!< START (Bit 0) */ +#define FLASH_CMD_START_Msk (0x1UL) /*!< START (Bitfield-Mask: 0x01) */ +#define FLASH_CMD_CMD_Pos (1UL) /*!< CMD (Bit 1) */ +#define FLASH_CMD_CMD_Msk (0xeUL) /*!< CMD (Bitfield-Mask: 0x07) */ +#define FLASH_CMD_NWS_Pos (5UL) /*!< NWS (Bit 5) */ +#define FLASH_CMD_NWS_Msk (0xe0UL) /*!< NWS (Bitfield-Mask: 0x07) */ +#define FLASH_CMD_UNLOCK_Pos (8UL) /*!< UNLOCK (Bit 8) */ +#define FLASH_CMD_UNLOCK_Msk (0x100UL) /*!< UNLOCK (Bitfield-Mask: 0x01) */ +#define FLASH_CMD_ACME_Pos (9UL) /*!< ACME (Bit 9) */ +#define FLASH_CMD_ACME_Msk (0x200UL) /*!< ACME (Bitfield-Mask: 0x01) */ +#define FLASH_CMD_ACMR_Pos (10UL) /*!< ACMR (Bit 10) */ +#define FLASH_CMD_ACMR_Msk (0x400UL) /*!< ACMR (Bitfield-Mask: 0x01) */ +#define FLASH_CMD_AINC_Pos (13UL) /*!< AINC (Bit 13) */ +#define FLASH_CMD_AINC_Msk (0x2000UL) /*!< AINC (Bitfield-Mask: 0x01) */ +#define FLASH_CMD_KEY_Pos (16UL) /*!< KEY (Bit 16) */ +#define FLASH_CMD_KEY_Msk (0xffff0000UL) /*!< KEY (Bitfield-Mask: 0xffff) */ +/* ========================================================== SR =========================================================== */ +#define FLASH_SR_CMD_END_Pos (0UL) /*!< CMD_END (Bit 0) */ +#define FLASH_SR_CMD_END_Msk (0x1UL) /*!< CMD_END (Bitfield-Mask: 0x01) */ +#define FLASH_SR_KEY_ERR_Pos (1UL) /*!< KEY_ERR (Bit 1) */ +#define FLASH_SR_KEY_ERR_Msk (0x2UL) /*!< KEY_ERR (Bitfield-Mask: 0x01) */ +#define FLASH_SR_ACC_ERR_Pos (2UL) /*!< ACC_ERR (Bit 2) */ +#define FLASH_SR_ACC_ERR_Msk (0x4UL) /*!< ACC_ERR (Bitfield-Mask: 0x01) */ +#define FLASH_SR_ADDR_ERR_Pos (3UL) /*!< ADDR_ERR (Bit 3) */ +#define FLASH_SR_ADDR_ERR_Msk (0x8UL) /*!< ADDR_ERR (Bitfield-Mask: 0x01) */ +#define FLASH_SR_HCM_Pos (6UL) /*!< HCM (Bit 6) */ +#define FLASH_SR_HCM_Msk (0x40UL) /*!< HCM (Bitfield-Mask: 0x01) */ +#define FLASH_SR_HSI_TC_ERR_Pos (7UL) /*!< HSI_TC_ERR (Bit 7) */ +#define FLASH_SR_HSI_TC_ERR_Msk (0x80UL) /*!< HSI_TC_ERR (Bitfield-Mask: 0x01) */ +#define FLASH_SR_PROTCT_R2_ERR_Pos (8UL) /*!< PROTCT_R2_ERR (Bit 8) */ +#define FLASH_SR_PROTCT_R2_ERR_Msk (0x100UL) /*!< PROTCT_R2_ERR (Bitfield-Mask: 0x01) */ +#define FLASH_SR_PROTCT_R1_ERR_Pos (9UL) /*!< PROTCT_R1_ERR (Bit 9) */ +#define FLASH_SR_PROTCT_R1_ERR_Msk (0x200UL) /*!< PROTCT_R1_ERR (Bitfield-Mask: 0x01) */ +#define FLASH_SR_RSTIO_AF_ERR_Pos (10UL) /*!< RSTIO_AF_ERR (Bit 10) */ +#define FLASH_SR_RSTIO_AF_ERR_Msk (0x400UL) /*!< RSTIO_AF_ERR (Bitfield-Mask: 0x01) */ +#define FLASH_SR_LDO_TRIM_ERR_Pos (11UL) /*!< LDO_TRIM_ERR (Bit 11) */ +#define FLASH_SR_LDO_TRIM_ERR_Msk (0x800UL) /*!< LDO_TRIM_ERR (Bitfield-Mask: 0x01) */ +#define FLASH_SR_VBUF_TRIM_ERR_Pos (12UL) /*!< VBUF_TRIM_ERR (Bit 12) */ +#define FLASH_SR_VBUF_TRIM_ERR_Msk (0x1000UL) /*!< VBUF_TRIM_ERR (Bitfield-Mask: 0x01) */ +#define FLASH_SR_LSI_TRIM_ERR_Pos (13UL) /*!< LSI_TRIM_ERR (Bit 13) */ +#define FLASH_SR_LSI_TRIM_ERR_Msk (0x2000UL) /*!< LSI_TRIM_ERR (Bitfield-Mask: 0x01) */ +#define FLASH_SR_HSI_TRIM_ERR_Pos (14UL) /*!< HSI_TRIM_ERR (Bit 14) */ +#define FLASH_SR_HSI_TRIM_ERR_Msk (0x4000UL) /*!< HSI_TRIM_ERR (Bitfield-Mask: 0x01) */ +/* ========================================================== AR =========================================================== */ +/* ========================================================== DR =========================================================== */ +/* ========================================================== ACM ========================================================== */ +/* ========================================================== DIV ========================================================== */ +#define FLASH_DIV_DIV_Pos (0UL) /*!< DIV (Bit 0) */ +#define FLASH_DIV_DIV_Msk (0xffUL) /*!< DIV (Bitfield-Mask: 0xff) */ + + +/* =========================================================================================================================== */ +/* ================ GPIO ================ */ +/* =========================================================================================================================== */ + +/* ========================================================== DAT ========================================================== */ +#define GPIO_DAT_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_DAT_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_DAT_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_DAT_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_DAT_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_DAT_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_DAT_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_DAT_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_DAT_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_DAT_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_DAT_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_DAT_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_DAT_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_DAT_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_DAT_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_DAT_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_DAT_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_DAT_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_DAT_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_DAT_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_DAT_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_DAT_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_DAT_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_DAT_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_DAT_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_DAT_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_DAT_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_DAT_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_DAT_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_DAT_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_DAT_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_DAT_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================== LAT ========================================================== */ +#define GPIO_LAT_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_LAT_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_LAT_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_LAT_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_LAT_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_LAT_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_LAT_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_LAT_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_LAT_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_LAT_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_LAT_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_LAT_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_LAT_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_LAT_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_LAT_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_LAT_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_LAT_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_LAT_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_LAT_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_LAT_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_LAT_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_LAT_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_LAT_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_LAT_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_LAT_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_LAT_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_LAT_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_LAT_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_LAT_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_LAT_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_LAT_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_LAT_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================= ITS1 ========================================================== */ +#define GPIO_ITS1_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_ITS1_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS1_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_ITS1_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS1_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_ITS1_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS1_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_ITS1_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS1_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_ITS1_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS1_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_ITS1_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS1_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_ITS1_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS1_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_ITS1_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS1_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_ITS1_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS1_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_ITS1_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS1_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_ITS1_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS1_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_ITS1_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS1_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_ITS1_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS1_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_ITS1_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS1_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_ITS1_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS1_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_ITS1_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================= ITC1 ========================================================== */ +#define GPIO_ITC1_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_ITC1_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC1_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_ITC1_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC1_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_ITC1_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC1_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_ITC1_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC1_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_ITC1_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC1_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_ITC1_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC1_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_ITC1_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC1_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_ITC1_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC1_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_ITC1_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC1_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_ITC1_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC1_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_ITC1_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC1_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_ITC1_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC1_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_ITC1_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC1_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_ITC1_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC1_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_ITC1_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC1_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_ITC1_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================== OES ========================================================== */ +#define GPIO_OES_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_OES_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_OES_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_OES_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_OES_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_OES_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_OES_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_OES_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_OES_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_OES_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_OES_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_OES_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_OES_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_OES_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_OES_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_OES_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_OES_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_OES_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_OES_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_OES_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_OES_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_OES_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_OES_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_OES_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_OES_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_OES_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_OES_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_OES_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_OES_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_OES_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_OES_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_OES_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================== OEC ========================================================== */ +#define GPIO_OEC_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_OEC_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_OEC_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_OEC_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_OEC_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_OEC_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_OEC_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_OEC_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_OEC_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_OEC_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_OEC_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_OEC_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_OEC_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_OEC_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_OEC_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_OEC_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_OEC_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_OEC_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_OEC_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_OEC_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_OEC_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_OEC_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_OEC_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_OEC_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_OEC_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_OEC_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_OEC_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_OEC_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_OEC_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_OEC_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_OEC_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_OEC_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================= INES ========================================================== */ +#define GPIO_INES_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_INES_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_INES_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_INES_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_INES_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_INES_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_INES_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_INES_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_INES_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_INES_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_INES_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_INES_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_INES_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_INES_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_INES_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_INES_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_INES_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_INES_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_INES_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_INES_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_INES_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_INES_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_INES_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_INES_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_INES_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_INES_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_INES_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_INES_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_INES_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_INES_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_INES_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_INES_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================= INEC ========================================================== */ +#define GPIO_INEC_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_INEC_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_INEC_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_INEC_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_INEC_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_INEC_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_INEC_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_INEC_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_INEC_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_INEC_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_INEC_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_INEC_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_INEC_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_INEC_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_INEC_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_INEC_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_INEC_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_INEC_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_INEC_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_INEC_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_INEC_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_INEC_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_INEC_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_INEC_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_INEC_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_INEC_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_INEC_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_INEC_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_INEC_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_INEC_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_INEC_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_INEC_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================== IES ========================================================== */ +#define GPIO_IES_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_IES_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_IES_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_IES_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_IES_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_IES_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_IES_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_IES_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_IES_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_IES_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_IES_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_IES_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_IES_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_IES_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_IES_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_IES_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_IES_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_IES_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_IES_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_IES_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_IES_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_IES_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_IES_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_IES_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_IES_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_IES_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_IES_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_IES_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_IES_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_IES_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_IES_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_IES_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================== IEC ========================================================== */ +#define GPIO_IEC_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_IEC_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_IEC_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_IEC_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_IEC_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_IEC_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_IEC_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_IEC_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_IEC_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_IEC_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_IEC_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_IEC_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_IEC_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_IEC_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_IEC_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_IEC_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_IEC_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_IEC_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_IEC_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_IEC_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_IEC_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_IEC_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_IEC_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_IEC_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_IEC_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_IEC_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_IEC_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_IEC_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_IEC_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_IEC_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_IEC_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_IEC_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================= ITS0 ========================================================== */ +#define GPIO_ITS0_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_ITS0_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS0_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_ITS0_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS0_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_ITS0_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS0_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_ITS0_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS0_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_ITS0_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS0_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_ITS0_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS0_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_ITS0_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS0_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_ITS0_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS0_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_ITS0_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS0_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_ITS0_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS0_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_ITS0_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS0_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_ITS0_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS0_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_ITS0_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS0_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_ITS0_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS0_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_ITS0_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS0_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_ITS0_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================= ITC0 ========================================================== */ +#define GPIO_ITC0_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_ITC0_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC0_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_ITC0_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC0_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_ITC0_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC0_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_ITC0_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC0_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_ITC0_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC0_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_ITC0_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC0_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_ITC0_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC0_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_ITC0_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC0_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_ITC0_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC0_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_ITC0_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC0_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_ITC0_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC0_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_ITC0_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC0_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_ITC0_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC0_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_ITC0_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC0_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_ITC0_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC0_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_ITC0_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================== PLS ========================================================== */ +#define GPIO_PLS_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_PLS_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_PLS_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_PLS_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_PLS_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_PLS_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_PLS_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_PLS_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_PLS_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_PLS_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_PLS_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_PLS_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_PLS_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_PLS_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_PLS_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_PLS_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_PLS_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_PLS_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_PLS_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_PLS_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_PLS_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_PLS_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_PLS_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_PLS_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_PLS_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_PLS_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_PLS_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_PLS_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_PLS_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_PLS_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_PLS_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_PLS_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================== PLC ========================================================== */ +#define GPIO_PLC_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_PLC_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_PLC_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_PLC_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_PLC_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_PLC_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_PLC_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_PLC_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_PLC_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_PLC_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_PLC_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_PLC_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_PLC_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_PLC_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_PLC_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_PLC_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_PLC_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_PLC_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_PLC_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_PLC_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_PLC_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_PLC_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_PLC_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_PLC_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_PLC_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_PLC_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_PLC_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_PLC_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_PLC_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_PLC_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_PLC_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_PLC_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================== IST ========================================================== */ +#define GPIO_IST_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_IST_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_IST_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_IST_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_IST_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_IST_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_IST_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_IST_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_IST_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_IST_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_IST_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_IST_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_IST_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_IST_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_IST_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_IST_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_IST_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_IST_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_IST_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_IST_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_IST_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_IST_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_IST_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_IST_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_IST_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_IST_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_IST_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_IST_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_IST_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_IST_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_IST_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_IST_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================== PUS ========================================================== */ +#define GPIO_PUS_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_PUS_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_PUS_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_PUS_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_PUS_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_PUS_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_PUS_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_PUS_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_PUS_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_PUS_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_PUS_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_PUS_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_PUS_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_PUS_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_PUS_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_PUS_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_PUS_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_PUS_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_PUS_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_PUS_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_PUS_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_PUS_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_PUS_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_PUS_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_PUS_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_PUS_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_PUS_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_PUS_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_PUS_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_PUS_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_PUS_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_PUS_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================== PUC ========================================================== */ +#define GPIO_PUC_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_PUC_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_PUC_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_PUC_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_PUC_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_PUC_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_PUC_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_PUC_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_PUC_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_PUC_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_PUC_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_PUC_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_PUC_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_PUC_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_PUC_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_PUC_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_PUC_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_PUC_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_PUC_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_PUC_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_PUC_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_PUC_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_PUC_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_PUC_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_PUC_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_PUC_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_PUC_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_PUC_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_PUC_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_PUC_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_PUC_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_PUC_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================== ODS ========================================================== */ +#define GPIO_ODS_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_ODS_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_ODS_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_ODS_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_ODS_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_ODS_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_ODS_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_ODS_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_ODS_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_ODS_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_ODS_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_ODS_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_ODS_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_ODS_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_ODS_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_ODS_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_ODS_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_ODS_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_ODS_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_ODS_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_ODS_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_ODS_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_ODS_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_ODS_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_ODS_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_ODS_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_ODS_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_ODS_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_ODS_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_ODS_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_ODS_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_ODS_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================== ODC ========================================================== */ +#define GPIO_ODC_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_ODC_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_ODC_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_ODC_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_ODC_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_ODC_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_ODC_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_ODC_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_ODC_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_ODC_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_ODC_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_ODC_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_ODC_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_ODC_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_ODC_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_ODC_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_ODC_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_ODC_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_ODC_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_ODC_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_ODC_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_ODC_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_ODC_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_ODC_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_ODC_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_ODC_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_ODC_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_ODC_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_ODC_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_ODC_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_ODC_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_ODC_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================== PDS ========================================================== */ +#define GPIO_PDS_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_PDS_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_PDS_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_PDS_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_PDS_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_PDS_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_PDS_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_PDS_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_PDS_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_PDS_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_PDS_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_PDS_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_PDS_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_PDS_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_PDS_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_PDS_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_PDS_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_PDS_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_PDS_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_PDS_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_PDS_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_PDS_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_PDS_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_PDS_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_PDS_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_PDS_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_PDS_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_PDS_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_PDS_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_PDS_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_PDS_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_PDS_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================== PDC ========================================================== */ +#define GPIO_PDC_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_PDC_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_PDC_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_PDC_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_PDC_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_PDC_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_PDC_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_PDC_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_PDC_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_PDC_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_PDC_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_PDC_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_PDC_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_PDC_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_PDC_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_PDC_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_PDC_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_PDC_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_PDC_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_PDC_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_PDC_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_PDC_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_PDC_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_PDC_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_PDC_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_PDC_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_PDC_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_PDC_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_PDC_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_PDC_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_PDC_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_PDC_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================= OSRS ========================================================== */ +#define GPIO_OSRS_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_OSRS_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRS_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_OSRS_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRS_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_OSRS_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRS_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_OSRS_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRS_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_OSRS_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRS_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_OSRS_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRS_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_OSRS_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRS_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_OSRS_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRS_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_OSRS_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRS_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_OSRS_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRS_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_OSRS_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRS_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_OSRS_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRS_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_OSRS_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRS_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_OSRS_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRS_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_OSRS_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRS_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_OSRS_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================= OSRC ========================================================== */ +#define GPIO_OSRC_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_OSRC_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRC_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_OSRC_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRC_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_OSRC_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRC_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_OSRC_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRC_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_OSRC_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRC_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_OSRC_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRC_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_OSRC_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRC_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_OSRC_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRC_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_OSRC_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRC_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_OSRC_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRC_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_OSRC_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRC_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_OSRC_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRC_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_OSRC_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRC_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_OSRC_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRC_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_OSRC_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRC_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_OSRC_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================== CTS ========================================================== */ +#define GPIO_CTS_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_CTS_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_CTS_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_CTS_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_CTS_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_CTS_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_CTS_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_CTS_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_CTS_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_CTS_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_CTS_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_CTS_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_CTS_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_CTS_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_CTS_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_CTS_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_CTS_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_CTS_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_CTS_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_CTS_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_CTS_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_CTS_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_CTS_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_CTS_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_CTS_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_CTS_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_CTS_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_CTS_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_CTS_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_CTS_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_CTS_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_CTS_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================== CTC ========================================================== */ +#define GPIO_CTC_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_CTC_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_CTC_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_CTC_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_CTC_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_CTC_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_CTC_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_CTC_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_CTC_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_CTC_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_CTC_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_CTC_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_CTC_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_CTC_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_CTC_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_CTC_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_CTC_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_CTC_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_CTC_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_CTC_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_CTC_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_CTC_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_CTC_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_CTC_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_CTC_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_CTC_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_CTC_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_CTC_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_CTC_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_CTC_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_CTC_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_CTC_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ + + +/* =========================================================================================================================== */ +/* ================ AFIO ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= PAAFR ========================================================= */ +#define AFIO_PAAFR_PA0_Pos (0UL) /*!< PA0 (Bit 0) */ +#define AFIO_PAAFR_PA0_Msk (0x7UL) /*!< PA0 (Bitfield-Mask: 0x07) */ +#define AFIO_PAAFR_PA1_Pos (3UL) /*!< PA1 (Bit 3) */ +#define AFIO_PAAFR_PA1_Msk (0x38UL) /*!< PA1 (Bitfield-Mask: 0x07) */ +#define AFIO_PAAFR_PA2_Pos (6UL) /*!< PA2 (Bit 6) */ +#define AFIO_PAAFR_PA2_Msk (0x1c0UL) /*!< PA2 (Bitfield-Mask: 0x07) */ +#define AFIO_PAAFR_PA3_Pos (9UL) /*!< PA3 (Bit 9) */ +#define AFIO_PAAFR_PA3_Msk (0xe00UL) /*!< PA3 (Bitfield-Mask: 0x07) */ +#define AFIO_PAAFR_PA4_Pos (12UL) /*!< PA4 (Bit 12) */ +#define AFIO_PAAFR_PA4_Msk (0x7000UL) /*!< PA4 (Bitfield-Mask: 0x07) */ +#define AFIO_PAAFR_PA5_Pos (15UL) /*!< PA5 (Bit 15) */ +#define AFIO_PAAFR_PA5_Msk (0x38000UL) /*!< PA5 (Bitfield-Mask: 0x07) */ +#define AFIO_PAAFR_PA14_Pos (18UL) /*!< PA14 (Bit 18) */ +#define AFIO_PAAFR_PA14_Msk (0x1c0000UL) /*!< PA14 (Bitfield-Mask: 0x07) */ +#define AFIO_PAAFR_PA15_Pos (21UL) /*!< PA15 (Bit 21) */ +#define AFIO_PAAFR_PA15_Msk (0xe00000UL) /*!< PA15 (Bitfield-Mask: 0x07) */ +/* ========================================================= PBAFR ========================================================= */ +#define AFIO_PBAFR_PB0_Pos (0UL) /*!< PB0 (Bit 0) */ +#define AFIO_PBAFR_PB0_Msk (0x7UL) /*!< PB0 (Bitfield-Mask: 0x07) */ +#define AFIO_PBAFR_PB1_Pos (3UL) /*!< PB1 (Bit 3) */ +#define AFIO_PBAFR_PB1_Msk (0x38UL) /*!< PB1 (Bitfield-Mask: 0x07) */ +#define AFIO_PBAFR_PB2_Pos (6UL) /*!< PB2 (Bit 6) */ +#define AFIO_PBAFR_PB2_Msk (0x1c0UL) /*!< PB2 (Bitfield-Mask: 0x07) */ +#define AFIO_PBAFR_PB3_Pos (9UL) /*!< PB3 (Bit 9) */ +#define AFIO_PBAFR_PB3_Msk (0xe00UL) /*!< PB3 (Bitfield-Mask: 0x07) */ +#define AFIO_PBAFR_PB4_Pos (12UL) /*!< PB4 (Bit 12) */ +#define AFIO_PBAFR_PB4_Msk (0x7000UL) /*!< PB4 (Bitfield-Mask: 0x07) */ +#define AFIO_PBAFR_PB5_Pos (15UL) /*!< PB5 (Bit 15) */ +#define AFIO_PBAFR_PB5_Msk (0x38000UL) /*!< PB5 (Bitfield-Mask: 0x07) */ +/* ======================================================== FN1_AFR ======================================================== */ +#define AFIO_FN1_AFR_BKIN_Pos (0UL) /*!< BKIN (Bit 0) */ +#define AFIO_FN1_AFR_BKIN_Msk (0xfUL) /*!< BKIN (Bitfield-Mask: 0x0f) */ +#define AFIO_FN1_AFR_ECAP0_Pos (4UL) /*!< ECAP0 (Bit 4) */ +#define AFIO_FN1_AFR_ECAP0_Msk (0x70UL) /*!< ECAP0 (Bitfield-Mask: 0x07) */ +#define AFIO_FN1_AFR_ECAP1_Pos (7UL) /*!< ECAP1 (Bit 7) */ +#define AFIO_FN1_AFR_ECAP1_Msk (0x380UL) /*!< ECAP1 (Bitfield-Mask: 0x07) */ +#define AFIO_FN1_AFR_ECAP2_Pos (10UL) /*!< ECAP2 (Bit 10) */ +#define AFIO_FN1_AFR_ECAP2_Msk (0x1c00UL) /*!< ECAP2 (Bitfield-Mask: 0x07) */ +#define AFIO_FN1_AFR_EPETR_Pos (13UL) /*!< EPETR (Bit 13) */ +#define AFIO_FN1_AFR_EPETR_Msk (0x1e000UL) /*!< EPETR (Bitfield-Mask: 0x0f) */ +/* ======================================================== FN2_AFR ======================================================== */ +#define AFIO_FN2_AFR_TCAP0_Pos (0UL) /*!< TCAP0 (Bit 0) */ +#define AFIO_FN2_AFR_TCAP0_Msk (0x7UL) /*!< TCAP0 (Bitfield-Mask: 0x07) */ +#define AFIO_FN2_AFR_TCAP1_Pos (3UL) /*!< TCAP1 (Bit 3) */ +#define AFIO_FN2_AFR_TCAP1_Msk (0x38UL) /*!< TCAP1 (Bitfield-Mask: 0x07) */ +#define AFIO_FN2_AFR_TCAP2_Pos (6UL) /*!< TCAP2 (Bit 6) */ +#define AFIO_FN2_AFR_TCAP2_Msk (0x1c0UL) /*!< TCAP2 (Bitfield-Mask: 0x07) */ +#define AFIO_FN2_AFR_T2ETR_Pos (9UL) /*!< T2ETR (Bit 9) */ +#define AFIO_FN2_AFR_T2ETR_Msk (0x1e00UL) /*!< T2ETR (Bitfield-Mask: 0x0f) */ +#define AFIO_FN2_AFR_I2C_PULL0_Pos (13UL) /*!< I2C_PULL0 (Bit 13) */ +#define AFIO_FN2_AFR_I2C_PULL0_Msk (0x2000UL) /*!< I2C_PULL0 (Bitfield-Mask: 0x01) */ +#define AFIO_FN2_AFR_I2C_PULL1_Pos (14UL) /*!< I2C_PULL1 (Bit 14) */ +#define AFIO_FN2_AFR_I2C_PULL1_Msk (0x4000UL) /*!< I2C_PULL1 (Bitfield-Mask: 0x01) */ +#define AFIO_FN2_AFR_I2C_PULL2_Pos (15UL) /*!< I2C_PULL2 (Bit 15) */ +#define AFIO_FN2_AFR_I2C_PULL2_Msk (0x8000UL) /*!< I2C_PULL2 (Bitfield-Mask: 0x01) */ +#define AFIO_FN2_AFR_I2C_PULL3_Pos (16UL) /*!< I2C_PULL3 (Bit 16) */ +#define AFIO_FN2_AFR_I2C_PULL3_Msk (0x10000UL) /*!< I2C_PULL3 (Bitfield-Mask: 0x01) */ +#define AFIO_FN2_AFR_I2C_PULL4_Pos (17UL) /*!< I2C_PULL4 (Bit 17) */ +#define AFIO_FN2_AFR_I2C_PULL4_Msk (0x20000UL) /*!< I2C_PULL4 (Bitfield-Mask: 0x01) */ +#define AFIO_FN2_AFR_I2C_PULL5_Pos (18UL) /*!< I2C_PULL5 (Bit 18) */ +#define AFIO_FN2_AFR_I2C_PULL5_Msk (0x40000UL) /*!< I2C_PULL5 (Bitfield-Mask: 0x01) */ +#define AFIO_FN2_AFR_I2C_PULL6_Pos (19UL) /*!< I2C_PULL6 (Bit 19) */ +#define AFIO_FN2_AFR_I2C_PULL6_Msk (0x80000UL) /*!< I2C_PULL6 (Bitfield-Mask: 0x01) */ +#define AFIO_FN2_AFR_I2C_PULL7_Pos (20UL) /*!< I2C_PULL7 (Bit 20) */ +#define AFIO_FN2_AFR_I2C_PULL7_Msk (0x100000UL) /*!< I2C_PULL7 (Bitfield-Mask: 0x01) */ + + +/* =========================================================================================================================== */ +/* ================ SYSCFG ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= PMUCR ========================================================= */ +#define SYSCFG_PMUCR_PMUEN_Pos (0UL) /*!< PMUEN (Bit 0) */ +#define SYSCFG_PMUCR_PMUEN_Msk (0x1UL) /*!< PMUEN (Bitfield-Mask: 0x01) */ +/* ========================================================= MCOCR ========================================================= */ +#define SYSCFG_MCOCR_MCOSEL_Pos (0UL) /*!< MCOSEL (Bit 0) */ +#define SYSCFG_MCOCR_MCOSEL_Msk (0x7UL) /*!< MCOSEL (Bitfield-Mask: 0x07) */ +#define SYSCFG_MCOCR_DivEn_Pos (6UL) /*!< DivEn (Bit 6) */ +#define SYSCFG_MCOCR_DivEn_Msk (0x40UL) /*!< DivEn (Bitfield-Mask: 0x01) */ +#define SYSCFG_MCOCR_DivSel_Pos (7UL) /*!< DivSel (Bit 7) */ +#define SYSCFG_MCOCR_DivSel_Msk (0x80UL) /*!< DivSel (Bitfield-Mask: 0x01) */ +#define SYSCFG_MCOCR_Divider_Pos (8UL) /*!< Divider (Bit 8) */ +#define SYSCFG_MCOCR_Divider_Msk (0xff00UL) /*!< Divider (Bitfield-Mask: 0xff) */ +#define SYSCFG_MCOCR_SWRstEn_Pos (16UL) /*!< SWRstEn (Bit 16) */ +#define SYSCFG_MCOCR_SWRstEn_Msk (0xff0000UL) /*!< SWRstEn (Bitfield-Mask: 0xff) */ +/* ======================================================= SYSRSTSR ======================================================== */ +#define SYSCFG_SYSRSTSR_SWRST_Pos (0UL) /*!< SWRST (Bit 0) */ +#define SYSCFG_SYSRSTSR_SWRST_Msk (0x1UL) /*!< SWRST (Bitfield-Mask: 0x01) */ +#define SYSCFG_SYSRSTSR_WDGRST_Pos (1UL) /*!< WDGRST (Bit 1) */ +#define SYSCFG_SYSRSTSR_WDGRST_Msk (0x2UL) /*!< WDGRST (Bitfield-Mask: 0x01) */ +#define SYSCFG_SYSRSTSR_LOCKUPRST_Pos (2UL) /*!< LOCKUPRST (Bit 2) */ +#define SYSCFG_SYSRSTSR_LOCKUPRST_Msk (0x4UL) /*!< LOCKUPRST (Bitfield-Mask: 0x01) */ +#define SYSCFG_SYSRSTSR_PORRST_Pos (8UL) /*!< PORRST (Bit 8) */ +#define SYSCFG_SYSRSTSR_PORRST_Msk (0x100UL) /*!< PORRST (Bitfield-Mask: 0x01) */ +#define SYSCFG_SYSRSTSR_PADRST_Pos (9UL) /*!< PADRST (Bit 9) */ +#define SYSCFG_SYSRSTSR_PADRST_Msk (0x200UL) /*!< PADRST (Bitfield-Mask: 0x01) */ +#define SYSCFG_SYSRSTSR_LVDRST_Pos (11UL) /*!< LVDRST (Bit 11) */ +#define SYSCFG_SYSRSTSR_LVDRST_Msk (0x800UL) /*!< LVDRST (Bitfield-Mask: 0x01) */ +#define SYSCFG_SYSRSTSR_REBOOTRST_Pos (12UL) /*!< REBOOTRST (Bit 12) */ +#define SYSCFG_SYSRSTSR_REBOOTRST_Msk (0x1000UL) /*!< REBOOTRST (Bitfield-Mask: 0x01) */ +/* ===================================================== REBOOT_UNLOCK ===================================================== */ +#define SYSCFG_REBOOT_UNLOCK_AUTHKEY_Pos (0UL) /*!< AUTHKEY (Bit 0) */ +#define SYSCFG_REBOOT_UNLOCK_AUTHKEY_Msk (0xffffUL) /*!< AUTHKEY (Bitfield-Mask: 0xffff) */ +/* ======================================================= SYSRSTCR ======================================================== */ +#define SYSCFG_SYSRSTCR_REBOOTEN_Pos (10UL) /*!< REBOOTEN (Bit 10) */ +#define SYSCFG_SYSRSTCR_REBOOTEN_Msk (0x400UL) /*!< REBOOTEN (Bitfield-Mask: 0x01) */ +/* ======================================================= DEBUGENCR ======================================================= */ +#define SYSCFG_DEBUGENCR_TIM0_Pos (2UL) /*!< TIM0 (Bit 2) */ +#define SYSCFG_DEBUGENCR_TIM0_Msk (0x4UL) /*!< TIM0 (Bitfield-Mask: 0x01) */ +#define SYSCFG_DEBUGENCR_TIM1_Pos (3UL) /*!< TIM1 (Bit 3) */ +#define SYSCFG_DEBUGENCR_TIM1_Msk (0x8UL) /*!< TIM1 (Bitfield-Mask: 0x01) */ +#define SYSCFG_DEBUGENCR_LPTIM_Pos (4UL) /*!< LPTIM (Bit 4) */ +#define SYSCFG_DEBUGENCR_LPTIM_Msk (0x10UL) /*!< LPTIM (Bitfield-Mask: 0x01) */ +#define SYSCFG_DEBUGENCR_EPWM_Pos (6UL) /*!< EPWM (Bit 6) */ +#define SYSCFG_DEBUGENCR_EPWM_Msk (0x40UL) /*!< EPWM (Bitfield-Mask: 0x01) */ +#define SYSCFG_DEBUGENCR_TIM2_Pos (11UL) /*!< TIM2 (Bit 11) */ +#define SYSCFG_DEBUGENCR_TIM2_Msk (0x800UL) /*!< TIM2 (Bitfield-Mask: 0x01) */ +#define SYSCFG_DEBUGENCR_WDG_Pos (14UL) /*!< WDG (Bit 14) */ +#define SYSCFG_DEBUGENCR_WDG_Msk (0x4000UL) /*!< WDG (Bitfield-Mask: 0x01) */ +#define SYSCFG_DEBUGENCR_AUTHKEY_Pos (16UL) /*!< AUTHKEY (Bit 16) */ +#define SYSCFG_DEBUGENCR_AUTHKEY_Msk (0xffff0000UL) /*!< AUTHKEY (Bitfield-Mask: 0xffff) */ +/* ======================================================= SYSCLKCR ======================================================== */ +#define SYSCFG_SYSCLKCR_CLKSW_Pos (0UL) /*!< CLKSW (Bit 0) */ +#define SYSCFG_SYSCLKCR_CLKSW_Msk (0x7UL) /*!< CLKSW (Bitfield-Mask: 0x07) */ +#define SYSCFG_SYSCLKCR_CLKDIV_Pos (8UL) /*!< CLKDIV (Bit 8) */ +#define SYSCFG_SYSCLKCR_CLKDIV_Msk (0xf00UL) /*!< CLKDIV (Bitfield-Mask: 0x0f) */ +#define SYSCFG_SYSCLKCR_LSIAON_Pos (23UL) /*!< LSIAON (Bit 23) */ +#define SYSCFG_SYSCLKCR_LSIAON_Msk (0x800000UL) /*!< LSIAON (Bitfield-Mask: 0x01) */ +#define SYSCFG_SYSCLKCR_SYSTICKCR_Pos (24UL) /*!< SYSTICKCR (Bit 24) */ +#define SYSCFG_SYSCLKCR_SYSTICKCR_Msk (0x3000000UL) /*!< SYSTICKCR (Bitfield-Mask: 0x03) */ +/* ======================================================== PRSTEN ========================================================= */ +#define SYSCFG_PRSTEN_UART0_Pos (0UL) /*!< UART0 (Bit 0) */ +#define SYSCFG_PRSTEN_UART0_Msk (0x1UL) /*!< UART0 (Bitfield-Mask: 0x01) */ +#define SYSCFG_PRSTEN_TIM0_Pos (2UL) /*!< TIM0 (Bit 2) */ +#define SYSCFG_PRSTEN_TIM0_Msk (0x4UL) /*!< TIM0 (Bitfield-Mask: 0x01) */ +#define SYSCFG_PRSTEN_TIM1_Pos (3UL) /*!< TIM1 (Bit 3) */ +#define SYSCFG_PRSTEN_TIM1_Msk (0x8UL) /*!< TIM1 (Bitfield-Mask: 0x01) */ +#define SYSCFG_PRSTEN_LPTIM_Pos (4UL) /*!< LPTIM (Bit 4) */ +#define SYSCFG_PRSTEN_LPTIM_Msk (0x10UL) /*!< LPTIM (Bitfield-Mask: 0x01) */ +#define SYSCFG_PRSTEN_ADC_Pos (5UL) /*!< ADC (Bit 5) */ +#define SYSCFG_PRSTEN_ADC_Msk (0x20UL) /*!< ADC (Bitfield-Mask: 0x01) */ +#define SYSCFG_PRSTEN_EPWM_Pos (6UL) /*!< EPWM (Bit 6) */ +#define SYSCFG_PRSTEN_EPWM_Msk (0x40UL) /*!< EPWM (Bitfield-Mask: 0x01) */ +#define SYSCFG_PRSTEN_DSP_Pos (7UL) /*!< DSP (Bit 7) */ +#define SYSCFG_PRSTEN_DSP_Msk (0x80UL) /*!< DSP (Bitfield-Mask: 0x01) */ +#define SYSCFG_PRSTEN_COMP0_Pos (8UL) /*!< COMP0 (Bit 8) */ +#define SYSCFG_PRSTEN_COMP0_Msk (0x100UL) /*!< COMP0 (Bitfield-Mask: 0x01) */ +#define SYSCFG_PRSTEN_SPI_Pos (10UL) /*!< SPI (Bit 10) */ +#define SYSCFG_PRSTEN_SPI_Msk (0x400UL) /*!< SPI (Bitfield-Mask: 0x01) */ +#define SYSCFG_PRSTEN_TIM2_Pos (11UL) /*!< TIM2 (Bit 11) */ +#define SYSCFG_PRSTEN_TIM2_Msk (0x800UL) /*!< TIM2 (Bitfield-Mask: 0x01) */ +#define SYSCFG_PRSTEN_I2C_Pos (12UL) /*!< I2C (Bit 12) */ +#define SYSCFG_PRSTEN_I2C_Msk (0x1000UL) /*!< I2C (Bitfield-Mask: 0x01) */ +#define SYSCFG_PRSTEN_COMP1_Pos (13UL) /*!< COMP1 (Bit 13) */ +#define SYSCFG_PRSTEN_COMP1_Msk (0x2000UL) /*!< COMP1 (Bitfield-Mask: 0x01) */ +#define SYSCFG_PRSTEN_WDG_Pos (14UL) /*!< WDG (Bit 14) */ +#define SYSCFG_PRSTEN_WDG_Msk (0x4000UL) /*!< WDG (Bitfield-Mask: 0x01) */ +#define SYSCFG_PRSTEN_AMISC_Pos (15UL) /*!< AMISC (Bit 15) */ +#define SYSCFG_PRSTEN_AMISC_Msk (0x8000UL) /*!< AMISC (Bitfield-Mask: 0x01) */ +/* ======================================================== PCLKEN ========================================================= */ +#define SYSCFG_PCLKEN_UART0_Pos (0UL) /*!< UART0 (Bit 0) */ +#define SYSCFG_PCLKEN_UART0_Msk (0x1UL) /*!< UART0 (Bitfield-Mask: 0x01) */ +#define SYSCFG_PCLKEN_TIM0_Pos (2UL) /*!< TIM0 (Bit 2) */ +#define SYSCFG_PCLKEN_TIM0_Msk (0x4UL) /*!< TIM0 (Bitfield-Mask: 0x01) */ +#define SYSCFG_PCLKEN_TIM1_Pos (3UL) /*!< TIM1 (Bit 3) */ +#define SYSCFG_PCLKEN_TIM1_Msk (0x8UL) /*!< TIM1 (Bitfield-Mask: 0x01) */ +#define SYSCFG_PCLKEN_LPTIM_Pos (4UL) /*!< LPTIM (Bit 4) */ +#define SYSCFG_PCLKEN_LPTIM_Msk (0x10UL) /*!< LPTIM (Bitfield-Mask: 0x01) */ +#define SYSCFG_PCLKEN_ADC_Pos (5UL) /*!< ADC (Bit 5) */ +#define SYSCFG_PCLKEN_ADC_Msk (0x20UL) /*!< ADC (Bitfield-Mask: 0x01) */ +#define SYSCFG_PCLKEN_EPWM_Pos (6UL) /*!< EPWM (Bit 6) */ +#define SYSCFG_PCLKEN_EPWM_Msk (0x40UL) /*!< EPWM (Bitfield-Mask: 0x01) */ +#define SYSCFG_PCLKEN_DSP_Pos (7UL) /*!< DSP (Bit 7) */ +#define SYSCFG_PCLKEN_DSP_Msk (0x80UL) /*!< DSP (Bitfield-Mask: 0x01) */ +#define SYSCFG_PCLKEN_COMP0_Pos (8UL) /*!< COMP0 (Bit 8) */ +#define SYSCFG_PCLKEN_COMP0_Msk (0x100UL) /*!< COMP0 (Bitfield-Mask: 0x01) */ +#define SYSCFG_PCLKEN_SPI_Pos (10UL) /*!< SPI (Bit 10) */ +#define SYSCFG_PCLKEN_SPI_Msk (0x400UL) /*!< SPI (Bitfield-Mask: 0x01) */ +#define SYSCFG_PCLKEN_TIM2_Pos (11UL) /*!< TIM2 (Bit 11) */ +#define SYSCFG_PCLKEN_TIM2_Msk (0x800UL) /*!< TIM2 (Bitfield-Mask: 0x01) */ +#define SYSCFG_PCLKEN_I2C_Pos (12UL) /*!< I2C (Bit 12) */ +#define SYSCFG_PCLKEN_I2C_Msk (0x1000UL) /*!< I2C (Bitfield-Mask: 0x01) */ +#define SYSCFG_PCLKEN_COMP1_Pos (13UL) /*!< COMP1 (Bit 13) */ +#define SYSCFG_PCLKEN_COMP1_Msk (0x2000UL) /*!< COMP1 (Bitfield-Mask: 0x01) */ +#define SYSCFG_PCLKEN_WDG_Pos (14UL) /*!< WDG (Bit 14) */ +#define SYSCFG_PCLKEN_WDG_Msk (0x4000UL) /*!< WDG (Bitfield-Mask: 0x01) */ +#define SYSCFG_PCLKEN_AMISC_Pos (15UL) /*!< AMISC (Bit 15) */ +#define SYSCFG_PCLKEN_AMISC_Msk (0x8000UL) /*!< AMISC (Bitfield-Mask: 0x01) */ +/* ======================================================== ICEIOCR ======================================================== */ +#define SYSCFG_ICEIOCR_JTAGIOEN_Pos (0UL) /*!< JTAGIOEN (Bit 0) */ +#define SYSCFG_ICEIOCR_JTAGIOEN_Msk (0x1UL) /*!< JTAGIOEN (Bitfield-Mask: 0x01) */ +#define SYSCFG_ICEIOCR_DBG_CTRL_EN_Pos (1UL) /*!< DBG_CTRL_EN (Bit 1) */ +#define SYSCFG_ICEIOCR_DBG_CTRL_EN_Msk (0x2UL) /*!< DBG_CTRL_EN (Bitfield-Mask: 0x01) */ +#define SYSCFG_ICEIOCR_DBG_EN_Pos (2UL) /*!< DBG_EN (Bit 2) */ +#define SYSCFG_ICEIOCR_DBG_EN_Msk (0x4UL) /*!< DBG_EN (Bitfield-Mask: 0x01) */ +#define SYSCFG_ICEIOCR_AUTHKEY_Pos (16UL) /*!< AUTHKEY (Bit 16) */ +#define SYSCFG_ICEIOCR_AUTHKEY_Msk (0xffff0000UL) /*!< AUTHKEY (Bitfield-Mask: 0xffff) */ +/* ======================================================= RSTPINCR ======================================================== */ +#define SYSCFG_RSTPINCR_RSTPINAF_Pos (0UL) /*!< RSTPINAF (Bit 0) */ +#define SYSCFG_RSTPINCR_RSTPINAF_Msk (0xffffUL) /*!< RSTPINAF (Bitfield-Mask: 0xffff) */ +/* ===================================================== TIM2_CON_SEL ====================================================== */ +#define SYSCFG_TIM2_CON_SEL_CH1_Pos (0UL) /*!< CH1 (Bit 0) */ +#define SYSCFG_TIM2_CON_SEL_CH1_Msk (0x7UL) /*!< CH1 (Bitfield-Mask: 0x07) */ +#define SYSCFG_TIM2_CON_SEL_CH2_Pos (4UL) /*!< CH2 (Bit 4) */ +#define SYSCFG_TIM2_CON_SEL_CH2_Msk (0x70UL) /*!< CH2 (Bitfield-Mask: 0x07) */ +#define SYSCFG_TIM2_CON_SEL_CH3_Pos (8UL) /*!< CH3 (Bit 8) */ +#define SYSCFG_TIM2_CON_SEL_CH3_Msk (0x700UL) /*!< CH3 (Bitfield-Mask: 0x07) */ +#define SYSCFG_TIM2_CON_SEL_CH4_Pos (12UL) /*!< CH4 (Bit 12) */ +#define SYSCFG_TIM2_CON_SEL_CH4_Msk (0x7000UL) /*!< CH4 (Bitfield-Mask: 0x07) */ +#define SYSCFG_TIM2_CON_SEL_BREAK_SEL_Pos (17UL) /*!< BREAK_SEL (Bit 17) */ +#define SYSCFG_TIM2_CON_SEL_BREAK_SEL_Msk (0x20000UL) /*!< BREAK_SEL (Bitfield-Mask: 0x01) */ +#define SYSCFG_TIM2_CON_SEL_COMP0A_SEL_Pos (18UL) /*!< COMP0A_SEL (Bit 18) */ +#define SYSCFG_TIM2_CON_SEL_COMP0A_SEL_Msk (0x40000UL) /*!< COMP0A_SEL (Bitfield-Mask: 0x01) */ +#define SYSCFG_TIM2_CON_SEL_COMP1A_SEL_Pos (19UL) /*!< COMP1A_SEL (Bit 19) */ +#define SYSCFG_TIM2_CON_SEL_COMP1A_SEL_Msk (0x80000UL) /*!< COMP1A_SEL (Bitfield-Mask: 0x01) */ +#define SYSCFG_TIM2_CON_SEL_VC_CH1_INV_Pos (20UL) /*!< VC_CH1_INV (Bit 20) */ +#define SYSCFG_TIM2_CON_SEL_VC_CH1_INV_Msk (0x100000UL) /*!< VC_CH1_INV (Bitfield-Mask: 0x01) */ +#define SYSCFG_TIM2_CON_SEL_VC_CH1_Pos (21UL) /*!< VC_CH1 (Bit 21) */ +#define SYSCFG_TIM2_CON_SEL_VC_CH1_Msk (0x200000UL) /*!< VC_CH1 (Bitfield-Mask: 0x01) */ +#define SYSCFG_TIM2_CON_SEL_VC_CH2_INV_Pos (22UL) /*!< VC_CH2_INV (Bit 22) */ +#define SYSCFG_TIM2_CON_SEL_VC_CH2_INV_Msk (0x400000UL) /*!< VC_CH2_INV (Bitfield-Mask: 0x01) */ +#define SYSCFG_TIM2_CON_SEL_VC_CH2_Pos (23UL) /*!< VC_CH2 (Bit 23) */ +#define SYSCFG_TIM2_CON_SEL_VC_CH2_Msk (0x800000UL) /*!< VC_CH2 (Bitfield-Mask: 0x01) */ +#define SYSCFG_TIM2_CON_SEL_VC_CH3_INV_Pos (24UL) /*!< VC_CH3_INV (Bit 24) */ +#define SYSCFG_TIM2_CON_SEL_VC_CH3_INV_Msk (0x1000000UL) /*!< VC_CH3_INV (Bitfield-Mask: 0x01) */ +#define SYSCFG_TIM2_CON_SEL_VC_CH3_Pos (25UL) /*!< VC_CH3 (Bit 25) */ +#define SYSCFG_TIM2_CON_SEL_VC_CH3_Msk (0x2000000UL) /*!< VC_CH3 (Bitfield-Mask: 0x01) */ +#define SYSCFG_TIM2_CON_SEL_VC_CH4_INV_Pos (26UL) /*!< VC_CH4_INV (Bit 26) */ +#define SYSCFG_TIM2_CON_SEL_VC_CH4_INV_Msk (0x4000000UL) /*!< VC_CH4_INV (Bitfield-Mask: 0x01) */ +#define SYSCFG_TIM2_CON_SEL_VC_CH4_Pos (27UL) /*!< VC_CH4 (Bit 27) */ +#define SYSCFG_TIM2_CON_SEL_VC_CH4_Msk (0x8000000UL) /*!< VC_CH4 (Bitfield-Mask: 0x01) */ +#define SYSCFG_TIM2_CON_SEL_COMP0D_SEL_Pos (28UL) /*!< COMP0D_SEL (Bit 28) */ +#define SYSCFG_TIM2_CON_SEL_COMP0D_SEL_Msk (0x10000000UL) /*!< COMP0D_SEL (Bitfield-Mask: 0x01) */ +#define SYSCFG_TIM2_CON_SEL_COMP1D_SEL_Pos (29UL) /*!< COMP1D_SEL (Bit 29) */ +#define SYSCFG_TIM2_CON_SEL_COMP1D_SEL_Msk (0x20000000UL) /*!< COMP1D_SEL (Bitfield-Mask: 0x01) */ +/* ===================================================== EPWM_CON_SEL ====================================================== */ +#define SYSCFG_EPWM_CON_SEL_CH1_Pos (0UL) /*!< CH1 (Bit 0) */ +#define SYSCFG_EPWM_CON_SEL_CH1_Msk (0x7UL) /*!< CH1 (Bitfield-Mask: 0x07) */ +#define SYSCFG_EPWM_CON_SEL_CH2_Pos (4UL) /*!< CH2 (Bit 4) */ +#define SYSCFG_EPWM_CON_SEL_CH2_Msk (0x70UL) /*!< CH2 (Bitfield-Mask: 0x07) */ +#define SYSCFG_EPWM_CON_SEL_CH3_Pos (8UL) /*!< CH3 (Bit 8) */ +#define SYSCFG_EPWM_CON_SEL_CH3_Msk (0x700UL) /*!< CH3 (Bitfield-Mask: 0x07) */ +#define SYSCFG_EPWM_CON_SEL_CH4_Pos (12UL) /*!< CH4 (Bit 12) */ +#define SYSCFG_EPWM_CON_SEL_CH4_Msk (0x7000UL) /*!< CH4 (Bitfield-Mask: 0x07) */ +#define SYSCFG_EPWM_CON_SEL_BREAK_SEL_Pos (16UL) /*!< BREAK_SEL (Bit 16) */ +#define SYSCFG_EPWM_CON_SEL_BREAK_SEL_Msk (0x10000UL) /*!< BREAK_SEL (Bitfield-Mask: 0x01) */ +#define SYSCFG_EPWM_CON_SEL_BREAK_OSSI0_DISOUT_Pos (17UL) /*!< BREAK_OSSI0_DISOUT (Bit 17) */ +#define SYSCFG_EPWM_CON_SEL_BREAK_OSSI0_DISOUT_Msk (0x20000UL) /*!< BREAK_OSSI0_DISOUT (Bitfield-Mask: 0x01) */ +#define SYSCFG_EPWM_CON_SEL_COMP0A_SEL_Pos (18UL) /*!< COMP0A_SEL (Bit 18) */ +#define SYSCFG_EPWM_CON_SEL_COMP0A_SEL_Msk (0x40000UL) /*!< COMP0A_SEL (Bitfield-Mask: 0x01) */ +#define SYSCFG_EPWM_CON_SEL_COMP1A_SEL_Pos (19UL) /*!< COMP1A_SEL (Bit 19) */ +#define SYSCFG_EPWM_CON_SEL_COMP1A_SEL_Msk (0x80000UL) /*!< COMP1A_SEL (Bitfield-Mask: 0x01) */ +#define SYSCFG_EPWM_CON_SEL_VC_CH1_INV_Pos (20UL) /*!< VC_CH1_INV (Bit 20) */ +#define SYSCFG_EPWM_CON_SEL_VC_CH1_INV_Msk (0x100000UL) /*!< VC_CH1_INV (Bitfield-Mask: 0x01) */ +#define SYSCFG_EPWM_CON_SEL_VC_CH1_Pos (21UL) /*!< VC_CH1 (Bit 21) */ +#define SYSCFG_EPWM_CON_SEL_VC_CH1_Msk (0x200000UL) /*!< VC_CH1 (Bitfield-Mask: 0x01) */ +#define SYSCFG_EPWM_CON_SEL_VC_CH2_INV_Pos (22UL) /*!< VC_CH2_INV (Bit 22) */ +#define SYSCFG_EPWM_CON_SEL_VC_CH2_INV_Msk (0x400000UL) /*!< VC_CH2_INV (Bitfield-Mask: 0x01) */ +#define SYSCFG_EPWM_CON_SEL_VC_CH2_Pos (23UL) /*!< VC_CH2 (Bit 23) */ +#define SYSCFG_EPWM_CON_SEL_VC_CH2_Msk (0x800000UL) /*!< VC_CH2 (Bitfield-Mask: 0x01) */ +#define SYSCFG_EPWM_CON_SEL_VC_CH3_INV_Pos (24UL) /*!< VC_CH3_INV (Bit 24) */ +#define SYSCFG_EPWM_CON_SEL_VC_CH3_INV_Msk (0x1000000UL) /*!< VC_CH3_INV (Bitfield-Mask: 0x01) */ +#define SYSCFG_EPWM_CON_SEL_VC_CH3_Pos (25UL) /*!< VC_CH3 (Bit 25) */ +#define SYSCFG_EPWM_CON_SEL_VC_CH3_Msk (0x2000000UL) /*!< VC_CH3 (Bitfield-Mask: 0x01) */ +#define SYSCFG_EPWM_CON_SEL_VC_CH4_INV_Pos (26UL) /*!< VC_CH4_INV (Bit 26) */ +#define SYSCFG_EPWM_CON_SEL_VC_CH4_INV_Msk (0x4000000UL) /*!< VC_CH4_INV (Bitfield-Mask: 0x01) */ +#define SYSCFG_EPWM_CON_SEL_VC_CH4_Pos (27UL) /*!< VC_CH4 (Bit 27) */ +#define SYSCFG_EPWM_CON_SEL_VC_CH4_Msk (0x8000000UL) /*!< VC_CH4 (Bitfield-Mask: 0x01) */ +#define SYSCFG_EPWM_CON_SEL_COMP0D_SEL_Pos (28UL) /*!< COMP0D_SEL (Bit 28) */ +#define SYSCFG_EPWM_CON_SEL_COMP0D_SEL_Msk (0x10000000UL) /*!< COMP0D_SEL (Bitfield-Mask: 0x01) */ +#define SYSCFG_EPWM_CON_SEL_COMP1D_SEL_Pos (29UL) /*!< COMP1D_SEL (Bit 29) */ +#define SYSCFG_EPWM_CON_SEL_COMP1D_SEL_Msk (0x20000000UL) /*!< COMP1D_SEL (Bitfield-Mask: 0x01) */ +#define SYSCFG_EPWM_CON_SEL_LVD_SEL_Pos (30UL) /*!< LVD_SEL (Bit 30) */ +#define SYSCFG_EPWM_CON_SEL_LVD_SEL_Msk (0x40000000UL) /*!< LVD_SEL (Bitfield-Mask: 0x01) */ +#define SYSCFG_EPWM_CON_SEL_WDG_SEL_Pos (31UL) /*!< WDG_SEL (Bit 31) */ +#define SYSCFG_EPWM_CON_SEL_WDG_SEL_Msk (0x80000000UL) /*!< WDG_SEL (Bitfield-Mask: 0x01) */ +/* ======================================================== PRSTEN1 ======================================================== */ +#define SYSCFG_PRSTEN1_GPIOA_Pos (0UL) /*!< GPIOA (Bit 0) */ +#define SYSCFG_PRSTEN1_GPIOA_Msk (0x1UL) /*!< GPIOA (Bitfield-Mask: 0x01) */ +#define SYSCFG_PRSTEN1_GPIOB_Pos (1UL) /*!< GPIOB (Bit 1) */ +#define SYSCFG_PRSTEN1_GPIOB_Msk (0x2UL) /*!< GPIOB (Bitfield-Mask: 0x01) */ +#define SYSCFG_PRSTEN1_CRC_Pos (7UL) /*!< CRC (Bit 7) */ +#define SYSCFG_PRSTEN1_CRC_Msk (0x80UL) /*!< CRC (Bitfield-Mask: 0x01) */ +/* ======================================================== HCLKEN ========================================================= */ +#define SYSCFG_HCLKEN_GPIOA_Pos (0UL) /*!< GPIOA (Bit 0) */ +#define SYSCFG_HCLKEN_GPIOA_Msk (0x1UL) /*!< GPIOA (Bitfield-Mask: 0x01) */ +#define SYSCFG_HCLKEN_GPIOB_Pos (1UL) /*!< GPIOB (Bit 1) */ +#define SYSCFG_HCLKEN_GPIOB_Msk (0x2UL) /*!< GPIOB (Bitfield-Mask: 0x01) */ +#define SYSCFG_HCLKEN_CRC_Pos (7UL) /*!< CRC (Bit 7) */ +#define SYSCFG_HCLKEN_CRC_Msk (0x80UL) /*!< CRC (Bitfield-Mask: 0x01) */ +/* ======================================================== EVT_SEL ======================================================== */ +#define SYSCFG_EVT_SEL_IRQSEL_Pos (0UL) /*!< IRQSEL (Bit 0) */ +#define SYSCFG_EVT_SEL_IRQSEL_Msk (0xffffffffUL) /*!< IRQSEL (Bitfield-Mask: 0xffffffff) */ +/* ========================================================= NMICR ========================================================= */ +#define SYSCFG_NMICR_SEL_Pos (0UL) /*!< SEL (Bit 0) */ +#define SYSCFG_NMICR_SEL_Msk (0x1fUL) /*!< SEL (Bitfield-Mask: 0x1f) */ +#define SYSCFG_NMICR_EN_Pos (5UL) /*!< EN (Bit 5) */ +#define SYSCFG_NMICR_EN_Msk (0xe0UL) /*!< EN (Bitfield-Mask: 0x07) */ +/* ======================================================== CHIPID ========================================================= */ + + +/* =========================================================================================================================== */ +/* ================ UART ================ */ +/* =========================================================================================================================== */ + +/* ========================================================== DAT ========================================================== */ +#define UART_DAT_DAT_Pos (0UL) /*!< DAT (Bit 0) */ +#define UART_DAT_DAT_Msk (0x1ffUL) /*!< DAT (Bitfield-Mask: 0x1ff) */ +#define UART_DAT_FE_Pos (9UL) /*!< FE (Bit 9) */ +#define UART_DAT_FE_Msk (0x200UL) /*!< FE (Bitfield-Mask: 0x01) */ +/* ========================================================== CR =========================================================== */ +#define UART_CR_MODE_Pos (0UL) /*!< MODE (Bit 0) */ +#define UART_CR_MODE_Msk (0x7UL) /*!< MODE (Bitfield-Mask: 0x07) */ +#define UART_CR_STOPB_Pos (3UL) /*!< STOPB (Bit 3) */ +#define UART_CR_STOPB_Msk (0x18UL) /*!< STOPB (Bitfield-Mask: 0x03) */ +#define UART_CR_PAR_Pos (5UL) /*!< PAR (Bit 5) */ +#define UART_CR_PAR_Msk (0x20UL) /*!< PAR (Bitfield-Mask: 0x01) */ +#define UART_CR_LPB_Pos (6UL) /*!< LPB (Bit 6) */ +#define UART_CR_LPB_Msk (0x40UL) /*!< LPB (Bitfield-Mask: 0x01) */ +#define UART_CR_RUN_Pos (7UL) /*!< RUN (Bit 7) */ +#define UART_CR_RUN_Msk (0x80UL) /*!< RUN (Bitfield-Mask: 0x01) */ +#define UART_CR_RXEN_Pos (8UL) /*!< RXEN (Bit 8) */ +#define UART_CR_RXEN_Msk (0x100UL) /*!< RXEN (Bitfield-Mask: 0x01) */ +#define UART_CR_RXPOL_Pos (16UL) /*!< RXPOL (Bit 16) */ +#define UART_CR_RXPOL_Msk (0x10000UL) /*!< RXPOL (Bitfield-Mask: 0x01) */ +#define UART_CR_TXPOL_Pos (17UL) /*!< TXPOL (Bit 17) */ +#define UART_CR_TXPOL_Msk (0x20000UL) /*!< TXPOL (Bitfield-Mask: 0x01) */ +/* ========================================================== BR =========================================================== */ +#define UART_BR_BR_Pos (0UL) /*!< BR (Bit 0) */ +#define UART_BR_BR_Msk (0xffffUL) /*!< BR (Bitfield-Mask: 0xffff) */ +/* ========================================================== IE =========================================================== */ +#define UART_IE_RXNEE_Pos (0UL) /*!< RXNEE (Bit 0) */ +#define UART_IE_RXNEE_Msk (0x1UL) /*!< RXNEE (Bitfield-Mask: 0x01) */ +#define UART_IE_TXEE_Pos (1UL) /*!< TXEE (Bit 1) */ +#define UART_IE_TXEE_Msk (0x2UL) /*!< TXEE (Bitfield-Mask: 0x01) */ +#define UART_IE_TXHEE_Pos (2UL) /*!< TXHEE (Bit 2) */ +#define UART_IE_TXHEE_Msk (0x4UL) /*!< TXHEE (Bitfield-Mask: 0x01) */ +#define UART_IE_PERRE_Pos (3UL) /*!< PERRE (Bit 3) */ +#define UART_IE_PERRE_Msk (0x8UL) /*!< PERRE (Bitfield-Mask: 0x01) */ +#define UART_IE_FERRE_Pos (4UL) /*!< FERRE (Bit 4) */ +#define UART_IE_FERRE_Msk (0x10UL) /*!< FERRE (Bitfield-Mask: 0x01) */ +#define UART_IE_OVERRE_Pos (5UL) /*!< OVERRE (Bit 5) */ +#define UART_IE_OVERRE_Msk (0x20UL) /*!< OVERRE (Bitfield-Mask: 0x01) */ +#define UART_IE_TONEE_Pos (6UL) /*!< TONEE (Bit 6) */ +#define UART_IE_TONEE_Msk (0x40UL) /*!< TONEE (Bitfield-Mask: 0x01) */ +#define UART_IE_TOIDLEE_Pos (7UL) /*!< TOIDLEE (Bit 7) */ +#define UART_IE_TOIDLEE_Msk (0x80UL) /*!< TOIDLEE (Bitfield-Mask: 0x01) */ +#define UART_IE_RXHFE_Pos (8UL) /*!< RXHFE (Bit 8) */ +#define UART_IE_RXHFE_Msk (0x100UL) /*!< RXHFE (Bitfield-Mask: 0x01) */ +#define UART_IE_RXFE_Pos (9UL) /*!< RXFE (Bit 9) */ +#define UART_IE_RXFE_Msk (0x200UL) /*!< RXFE (Bitfield-Mask: 0x01) */ +#define UART_IE_TXENDE_Pos (10UL) /*!< TXENDE (Bit 10) */ +#define UART_IE_TXENDE_Msk (0x400UL) /*!< TXENDE (Bitfield-Mask: 0x01) */ +#define UART_IE_TXFE_Pos (11UL) /*!< TXFE (Bit 11) */ +#define UART_IE_TXFE_Msk (0x800UL) /*!< TXFE (Bitfield-Mask: 0x01) */ +#define UART_IE_RXPE_Pos (12UL) /*!< RXPE (Bit 12) */ +#define UART_IE_RXPE_Msk (0x1000UL) /*!< RXPE (Bitfield-Mask: 0x01) */ +/* ========================================================== SR =========================================================== */ +#define UART_SR_RXNE_Pos (0UL) /*!< RXNE (Bit 0) */ +#define UART_SR_RXNE_Msk (0x1UL) /*!< RXNE (Bitfield-Mask: 0x01) */ +#define UART_SR_TXE_Pos (1UL) /*!< TXE (Bit 1) */ +#define UART_SR_TXE_Msk (0x2UL) /*!< TXE (Bitfield-Mask: 0x01) */ +#define UART_SR_TXHE_Pos (2UL) /*!< TXHE (Bit 2) */ +#define UART_SR_TXHE_Msk (0x4UL) /*!< TXHE (Bitfield-Mask: 0x01) */ +#define UART_SR_PERR_Pos (3UL) /*!< PERR (Bit 3) */ +#define UART_SR_PERR_Msk (0x8UL) /*!< PERR (Bitfield-Mask: 0x01) */ +#define UART_SR_FERR_Pos (4UL) /*!< FERR (Bit 4) */ +#define UART_SR_FERR_Msk (0x10UL) /*!< FERR (Bitfield-Mask: 0x01) */ +#define UART_SR_OVERR_Pos (5UL) /*!< OVERR (Bit 5) */ +#define UART_SR_OVERR_Msk (0x20UL) /*!< OVERR (Bitfield-Mask: 0x01) */ +#define UART_SR_TONE_Pos (6UL) /*!< TONE (Bit 6) */ +#define UART_SR_TONE_Msk (0x40UL) /*!< TONE (Bitfield-Mask: 0x01) */ +#define UART_SR_TOIDLE_Pos (7UL) /*!< TOIDLE (Bit 7) */ +#define UART_SR_TOIDLE_Msk (0x80UL) /*!< TOIDLE (Bitfield-Mask: 0x01) */ +#define UART_SR_RXHF_Pos (8UL) /*!< RXHF (Bit 8) */ +#define UART_SR_RXHF_Msk (0x100UL) /*!< RXHF (Bitfield-Mask: 0x01) */ +#define UART_SR_RXF_Pos (9UL) /*!< RXF (Bit 9) */ +#define UART_SR_RXF_Msk (0x200UL) /*!< RXF (Bitfield-Mask: 0x01) */ +#define UART_SR_TXEND_Pos (10UL) /*!< TXEND (Bit 10) */ +#define UART_SR_TXEND_Msk (0x400UL) /*!< TXEND (Bitfield-Mask: 0x01) */ +#define UART_SR_TXF_Pos (11UL) /*!< TXF (Bit 11) */ +#define UART_SR_TXF_Msk (0x800UL) /*!< TXF (Bitfield-Mask: 0x01) */ +/* ========================================================== GTR ========================================================== */ +#define UART_GTR_GT_Pos (0UL) /*!< GT (Bit 0) */ +#define UART_GTR_GT_Msk (0xffUL) /*!< GT (Bitfield-Mask: 0xff) */ +/* ========================================================== TOR ========================================================== */ +#define UART_TOR_TO_Pos (0UL) /*!< TO (Bit 0) */ +#define UART_TOR_TO_Msk (0xffUL) /*!< TO (Bitfield-Mask: 0xff) */ +/* ========================================================= TXFR ========================================================== */ +/* ========================================================= RXFR ========================================================== */ + + +/* =========================================================================================================================== */ +/* ================ I2C ================ */ +/* =========================================================================================================================== */ + +/* ======================================================== CTLSET ========================================================= */ +#define I2C_CTLSET_CR0_Pos (0UL) /*!< CR0 (Bit 0) */ +#define I2C_CTLSET_CR0_Msk (0x1UL) /*!< CR0 (Bitfield-Mask: 0x01) */ +#define I2C_CTLSET_CR1_Pos (1UL) /*!< CR1 (Bit 1) */ +#define I2C_CTLSET_CR1_Msk (0x2UL) /*!< CR1 (Bitfield-Mask: 0x01) */ +#define I2C_CTLSET_AA_Pos (2UL) /*!< AA (Bit 2) */ +#define I2C_CTLSET_AA_Msk (0x4UL) /*!< AA (Bitfield-Mask: 0x01) */ +#define I2C_CTLSET_SI_Pos (3UL) /*!< SI (Bit 3) */ +#define I2C_CTLSET_SI_Msk (0x8UL) /*!< SI (Bitfield-Mask: 0x01) */ +#define I2C_CTLSET_STO_Pos (4UL) /*!< STO (Bit 4) */ +#define I2C_CTLSET_STO_Msk (0x10UL) /*!< STO (Bitfield-Mask: 0x01) */ +#define I2C_CTLSET_STA_Pos (5UL) /*!< STA (Bit 5) */ +#define I2C_CTLSET_STA_Msk (0x20UL) /*!< STA (Bitfield-Mask: 0x01) */ +#define I2C_CTLSET_EN_Pos (6UL) /*!< EN (Bit 6) */ +#define I2C_CTLSET_EN_Msk (0x40UL) /*!< EN (Bitfield-Mask: 0x01) */ +#define I2C_CTLSET_CR2_Pos (7UL) /*!< CR2 (Bit 7) */ +#define I2C_CTLSET_CR2_Msk (0x80UL) /*!< CR2 (Bitfield-Mask: 0x01) */ +/* ========================================================= STAT ========================================================== */ +#define I2C_STAT_STAT_Pos (3UL) /*!< STAT (Bit 3) */ +#define I2C_STAT_STAT_Msk (0xf8UL) /*!< STAT (Bitfield-Mask: 0x1f) */ +/* ========================================================= DATA ========================================================== */ +#define I2C_DATA_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define I2C_DATA_DATA_Msk (0xffUL) /*!< DATA (Bitfield-Mask: 0xff) */ +/* ========================================================= ADDR ========================================================== */ +#define I2C_ADDR_GC_Pos (0UL) /*!< GC (Bit 0) */ +#define I2C_ADDR_GC_Msk (0x1UL) /*!< GC (Bitfield-Mask: 0x01) */ +#define I2C_ADDR_ADDR_Pos (1UL) /*!< ADDR (Bit 1) */ +#define I2C_ADDR_ADDR_Msk (0xfeUL) /*!< ADDR (Bitfield-Mask: 0x7f) */ +#define I2C_ADDR_FILTERDELAY_Pos (16UL) /*!< FILTERDELAY (Bit 16) */ +#define I2C_ADDR_FILTERDELAY_Msk (0xf0000UL) /*!< FILTERDELAY (Bitfield-Mask: 0x0f) */ +#define I2C_ADDR_FILTERDELAY_EN_Pos (24UL) /*!< FILTERDELAY_EN (Bit 24) */ +#define I2C_ADDR_FILTERDELAY_EN_Msk (0xff000000UL) /*!< FILTERDELAY_EN (Bitfield-Mask: 0xff) */ +/* ======================================================== CTLCLR ========================================================= */ +#define I2C_CTLCLR_CR0_Pos (0UL) /*!< CR0 (Bit 0) */ +#define I2C_CTLCLR_CR0_Msk (0x1UL) /*!< CR0 (Bitfield-Mask: 0x01) */ +#define I2C_CTLCLR_CR1_Pos (1UL) /*!< CR1 (Bit 1) */ +#define I2C_CTLCLR_CR1_Msk (0x2UL) /*!< CR1 (Bitfield-Mask: 0x01) */ +#define I2C_CTLCLR_AA_Pos (2UL) /*!< AA (Bit 2) */ +#define I2C_CTLCLR_AA_Msk (0x4UL) /*!< AA (Bitfield-Mask: 0x01) */ +#define I2C_CTLCLR_SI_Pos (3UL) /*!< SI (Bit 3) */ +#define I2C_CTLCLR_SI_Msk (0x8UL) /*!< SI (Bitfield-Mask: 0x01) */ +#define I2C_CTLCLR_STO_Pos (4UL) /*!< STO (Bit 4) */ +#define I2C_CTLCLR_STO_Msk (0x10UL) /*!< STO (Bitfield-Mask: 0x01) */ +#define I2C_CTLCLR_STA_Pos (5UL) /*!< STA (Bit 5) */ +#define I2C_CTLCLR_STA_Msk (0x20UL) /*!< STA (Bitfield-Mask: 0x01) */ +#define I2C_CTLCLR_EN_Pos (6UL) /*!< EN (Bit 6) */ +#define I2C_CTLCLR_EN_Msk (0x40UL) /*!< EN (Bitfield-Mask: 0x01) */ +#define I2C_CTLCLR_CR2_Pos (7UL) /*!< CR2 (Bit 7) */ +#define I2C_CTLCLR_CR2_Msk (0x80UL) /*!< CR2 (Bitfield-Mask: 0x01) */ + + +/* =========================================================================================================================== */ +/* ================ SPI ================ */ +/* =========================================================================================================================== */ + +/* ========================================================== CFG ========================================================== */ +#define SPI_CFG_MODE_Pos (0UL) /*!< MODE (Bit 0) */ +#define SPI_CFG_MODE_Msk (0x1UL) /*!< MODE (Bitfield-Mask: 0x01) */ +#define SPI_CFG_CPOL_Pos (1UL) /*!< CPOL (Bit 1) */ +#define SPI_CFG_CPOL_Msk (0x2UL) /*!< CPOL (Bitfield-Mask: 0x01) */ +#define SPI_CFG_CPHA_Pos (2UL) /*!< CPHA (Bit 2) */ +#define SPI_CFG_CPHA_Msk (0x4UL) /*!< CPHA (Bitfield-Mask: 0x01) */ +#define SPI_CFG_DB_Pos (3UL) /*!< DB (Bit 3) */ +#define SPI_CFG_DB_Msk (0x38UL) /*!< DB (Bitfield-Mask: 0x07) */ +#define SPI_CFG_TXWDSZ_Pos (6UL) /*!< TXWDSZ (Bit 6) */ +#define SPI_CFG_TXWDSZ_Msk (0xc0UL) /*!< TXWDSZ (Bitfield-Mask: 0x03) */ +#define SPI_CFG_LSB_Pos (8UL) /*!< LSB (Bit 8) */ +#define SPI_CFG_LSB_Msk (0x100UL) /*!< LSB (Bitfield-Mask: 0x01) */ +#define SPI_CFG_SS_OUT_Pos (10UL) /*!< SS_OUT (Bit 10) */ +#define SPI_CFG_SS_OUT_Msk (0x400UL) /*!< SS_OUT (Bitfield-Mask: 0x01) */ +#define SPI_CFG_MCS_Pos (14UL) /*!< MCS (Bit 14) */ +#define SPI_CFG_MCS_Msk (0x4000UL) /*!< MCS (Bitfield-Mask: 0x01) */ +#define SPI_CFG_MSE_Pos (15UL) /*!< MSE (Bit 15) */ +#define SPI_CFG_MSE_Msk (0x8000UL) /*!< MSE (Bitfield-Mask: 0x01) */ +#define SPI_CFG_MSTC_Pos (16UL) /*!< MSTC (Bit 16) */ +#define SPI_CFG_MSTC_Msk (0x10000UL) /*!< MSTC (Bitfield-Mask: 0x01) */ +#define SPI_CFG_MODEF_Pos (17UL) /*!< MODEF (Bit 17) */ +#define SPI_CFG_MODEF_Msk (0x20000UL) /*!< MODEF (Bitfield-Mask: 0x01) */ +/* ========================================================== STA ========================================================== */ +#define SPI_STA_RECVOV_Pos (0UL) /*!< RECVOV (Bit 0) */ +#define SPI_STA_RECVOV_Msk (0x1UL) /*!< RECVOV (Bitfield-Mask: 0x01) */ +#define SPI_STA_MDF_Pos (1UL) /*!< MDF (Bit 1) */ +#define SPI_STA_MDF_Msk (0x2UL) /*!< MDF (Bitfield-Mask: 0x01) */ +#define SPI_STA_TXNFUL_Pos (2UL) /*!< TXNFUL (Bit 2) */ +#define SPI_STA_TXNFUL_Msk (0x4UL) /*!< TXNFUL (Bitfield-Mask: 0x01) */ +#define SPI_STA_TXFUL_Pos (3UL) /*!< TXFUL (Bit 3) */ +#define SPI_STA_TXFUL_Msk (0x8UL) /*!< TXFUL (Bitfield-Mask: 0x01) */ +#define SPI_STA_RXNEP_Pos (4UL) /*!< RXNEP (Bit 4) */ +#define SPI_STA_RXNEP_Msk (0x10UL) /*!< RXNEP (Bitfield-Mask: 0x01) */ +#define SPI_STA_RXFUL_Pos (5UL) /*!< RXFUL (Bit 5) */ +#define SPI_STA_RXFUL_Msk (0x20UL) /*!< RXFUL (Bitfield-Mask: 0x01) */ +#define SPI_STA_TXUFL_Pos (6UL) /*!< TXUFL (Bit 6) */ +#define SPI_STA_TXUFL_Msk (0x40UL) /*!< TXUFL (Bitfield-Mask: 0x01) */ +#define SPI_STA_BUSY_Pos (7UL) /*!< BUSY (Bit 7) */ +#define SPI_STA_BUSY_Msk (0x80UL) /*!< BUSY (Bitfield-Mask: 0x01) */ +/* ========================================================= INTEN ========================================================= */ +#define SPI_INTEN_INTEN_Pos (0UL) /*!< INTEN (Bit 0) */ +#define SPI_INTEN_INTEN_Msk (0x7fUL) /*!< INTEN (Bitfield-Mask: 0x7f) */ +/* ======================================================== INTDIS ========================================================= */ +#define SPI_INTDIS_INTEN_Pos (0UL) /*!< INTEN (Bit 0) */ +#define SPI_INTDIS_INTEN_Msk (0x7fUL) /*!< INTEN (Bitfield-Mask: 0x7f) */ +/* ======================================================== INTMASK ======================================================== */ +#define SPI_INTMASK_INTEN_Pos (0UL) /*!< INTEN (Bit 0) */ +#define SPI_INTMASK_INTEN_Msk (0x7fUL) /*!< INTEN (Bitfield-Mask: 0x7f) */ +/* ========================================================== EN =========================================================== */ +#define SPI_EN_EN_Pos (0UL) /*!< EN (Bit 0) */ +#define SPI_EN_EN_Msk (0x1UL) /*!< EN (Bitfield-Mask: 0x01) */ +/* ========================================================= DELAY ========================================================= */ +#define SPI_DELAY_d_int_Pos (0UL) /*!< d_int (Bit 0) */ +#define SPI_DELAY_d_int_Msk (0xffUL) /*!< d_int (Bitfield-Mask: 0xff) */ +#define SPI_DELAY_d_affter_Pos (8UL) /*!< d_affter (Bit 8) */ +#define SPI_DELAY_d_affter_Msk (0xff00UL) /*!< d_affter (Bitfield-Mask: 0xff) */ +#define SPI_DELAY_d_btwn_Pos (16UL) /*!< d_btwn (Bit 16) */ +#define SPI_DELAY_d_btwn_Msk (0xff0000UL) /*!< d_btwn (Bitfield-Mask: 0xff) */ +#define SPI_DELAY_d_nss_Pos (24UL) /*!< d_nss (Bit 24) */ +#define SPI_DELAY_d_nss_Msk (0xff000000UL) /*!< d_nss (Bitfield-Mask: 0xff) */ +/* ========================================================== TX =========================================================== */ +/* ========================================================== RX =========================================================== */ +/* ======================================================== IDLECNT ======================================================== */ +#define SPI_IDLECNT_IDLECNT_Pos (0UL) /*!< IDLECNT (Bit 0) */ +#define SPI_IDLECNT_IDLECNT_Msk (0xffUL) /*!< IDLECNT (Bitfield-Mask: 0xff) */ +/* ========================================================= TXTH ========================================================== */ +#define SPI_TXTH_TXTHOLD_Pos (0UL) /*!< TXTHOLD (Bit 0) */ +#define SPI_TXTH_TXTHOLD_Msk (0xffffffffUL) /*!< TXTHOLD (Bitfield-Mask: 0xffffffff) */ +/* ========================================================= RXTH ========================================================== */ +#define SPI_RXTH_RXTHOLD_Pos (0UL) /*!< RXTHOLD (Bit 0) */ +#define SPI_RXTH_RXTHOLD_Msk (0xffffffffUL) /*!< RXTHOLD (Bitfield-Mask: 0xffffffff) */ + + +/* =========================================================================================================================== */ +/* ================ WDG ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= LOAD ========================================================== */ +/* ========================================================= VALUE ========================================================= */ +/* ========================================================== CR =========================================================== */ +#define WDG_CR_INTE_Pos (0UL) /*!< INTE (Bit 0) */ +#define WDG_CR_INTE_Msk (0x1UL) /*!< INTE (Bitfield-Mask: 0x01) */ +#define WDG_CR_RSTE_Pos (1UL) /*!< RSTE (Bit 1) */ +#define WDG_CR_RSTE_Msk (0x2UL) /*!< RSTE (Bitfield-Mask: 0x01) */ +#define WDG_CR_DBGE_Pos (2UL) /*!< DBGE (Bit 2) */ +#define WDG_CR_DBGE_Msk (0x4UL) /*!< DBGE (Bitfield-Mask: 0x01) */ +/* ======================================================== INTCLR ========================================================= */ +/* ========================================================== RIS ========================================================== */ +#define WDG_RIS_RIF_Pos (0UL) /*!< RIF (Bit 0) */ +#define WDG_RIS_RIF_Msk (0x1UL) /*!< RIF (Bitfield-Mask: 0x01) */ +/* ========================================================== MIS ========================================================== */ +#define WDG_MIS_MIF_Pos (0UL) /*!< MIF (Bit 0) */ +#define WDG_MIS_MIF_Msk (0x1UL) /*!< MIF (Bitfield-Mask: 0x01) */ +/* ========================================================= LOCK ========================================================== */ +#define WDG_LOCK_LOCK_Pos (0UL) /*!< LOCK (Bit 0) */ +#define WDG_LOCK_LOCK_Msk (0x1UL) /*!< LOCK (Bitfield-Mask: 0x01) */ + + +/* =========================================================================================================================== */ +/* ================ ADC ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= CON0 ========================================================== */ +#define ADC_CON0_M_Pos (0UL) /*!< M (Bit 0) */ +#define ADC_CON0_M_Msk (0xfUL) /*!< M (Bitfield-Mask: 0x0f) */ +#define ADC_CON0_EN_Pos (5UL) /*!< EN (Bit 5) */ +#define ADC_CON0_EN_Msk (0x20UL) /*!< EN (Bitfield-Mask: 0x01) */ +#define ADC_CON0_START_Pos (7UL) /*!< START (Bit 7) */ +#define ADC_CON0_START_Msk (0x80UL) /*!< START (Bitfield-Mask: 0x01) */ +#define ADC_CON0_CLK_Pos (8UL) /*!< CLK (Bit 8) */ +#define ADC_CON0_CLK_Msk (0x700UL) /*!< CLK (Bitfield-Mask: 0x07) */ +#define ADC_CON0_TRIG_EN_Pos (11UL) /*!< TRIG_EN (Bit 11) */ +#define ADC_CON0_TRIG_EN_Msk (0x800UL) /*!< TRIG_EN (Bitfield-Mask: 0x01) */ +#define ADC_CON0_CONTINUE_Pos (12UL) /*!< CONTINUE (Bit 12) */ +#define ADC_CON0_CONTINUE_Msk (0x1000UL) /*!< CONTINUE (Bitfield-Mask: 0x01) */ +#define ADC_CON0_ALIGN_Pos (13UL) /*!< ALIGN (Bit 13) */ +#define ADC_CON0_ALIGN_Msk (0x2000UL) /*!< ALIGN (Bitfield-Mask: 0x01) */ +#define ADC_CON0_ENCONT_Pos (15UL) /*!< ENCONT (Bit 15) */ +#define ADC_CON0_ENCONT_Msk (0x8000UL) /*!< ENCONT (Bitfield-Mask: 0x01) */ +#define ADC_CON0_INT_EN_Pos (16UL) /*!< INT_EN (Bit 16) */ +#define ADC_CON0_INT_EN_Msk (0xf0000UL) /*!< INT_EN (Bitfield-Mask: 0x0f) */ +#define ADC_CON0_TZO_Pos (20UL) /*!< TZO (Bit 20) */ +#define ADC_CON0_TZO_Msk (0x700000UL) /*!< TZO (Bitfield-Mask: 0x07) */ +#define ADC_CON0_BAKEN_Pos (29UL) /*!< BAKEN (Bit 29) */ +#define ADC_CON0_BAKEN_Msk (0x20000000UL) /*!< BAKEN (Bitfield-Mask: 0x01) */ +#define ADC_CON0_PWD_Pos (30UL) /*!< PWD (Bit 30) */ +#define ADC_CON0_PWD_Msk (0x40000000UL) /*!< PWD (Bitfield-Mask: 0x01) */ +#define ADC_CON0_RST_Pos (31UL) /*!< RST (Bit 31) */ +#define ADC_CON0_RST_Msk (0x80000000UL) /*!< RST (Bitfield-Mask: 0x01) */ +/* ========================================================= STAT ========================================================== */ +#define ADC_STAT_DONE_Pos (0UL) /*!< DONE (Bit 0) */ +#define ADC_STAT_DONE_Msk (0x1UL) /*!< DONE (Bitfield-Mask: 0x01) */ +#define ADC_STAT_INT_CLR_Pos (1UL) /*!< INT_CLR (Bit 1) */ +#define ADC_STAT_INT_CLR_Msk (0x2UL) /*!< INT_CLR (Bitfield-Mask: 0x01) */ +#define ADC_STAT_COMP_RESULT_Pos (4UL) /*!< COMP_RESULT (Bit 4) */ +#define ADC_STAT_COMP_RESULT_Msk (0x30UL) /*!< COMP_RESULT (Bitfield-Mask: 0x03) */ +#define ADC_STAT_EOC_CHECK_DIS_Pos (6UL) /*!< EOC_CHECK_DIS (Bit 6) */ +#define ADC_STAT_EOC_CHECK_DIS_Msk (0x40UL) /*!< EOC_CHECK_DIS (Bitfield-Mask: 0x01) */ +#define ADC_STAT_TS_SET_Pos (16UL) /*!< TS_SET (Bit 16) */ +#define ADC_STAT_TS_SET_Msk (0x1f0000UL) /*!< TS_SET (Bitfield-Mask: 0x1f) */ +#define ADC_STAT_DLY_SET_Pos (21UL) /*!< DLY_SET (Bit 21) */ +#define ADC_STAT_DLY_SET_Msk (0xe00000UL) /*!< DLY_SET (Bitfield-Mask: 0x07) */ +#define ADC_STAT_EOC_CNT_Pos (24UL) /*!< EOC_CNT (Bit 24) */ +#define ADC_STAT_EOC_CNT_Msk (0xf000000UL) /*!< EOC_CNT (Bitfield-Mask: 0x0f) */ +#define ADC_STAT_START_CNT_Pos (28UL) /*!< START_CNT (Bit 28) */ +#define ADC_STAT_START_CNT_Msk (0xf0000000UL) /*!< START_CNT (Bitfield-Mask: 0x0f) */ +/* ========================================================= DAT0 ========================================================== */ +#define ADC_DAT0_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define ADC_DAT0_DATA_Msk (0xffffUL) /*!< DATA (Bitfield-Mask: 0xffff) */ +#define ADC_DAT0_CMPTH_Pos (16UL) /*!< CMPTH (Bit 16) */ +#define ADC_DAT0_CMPTH_Msk (0xfff0000UL) /*!< CMPTH (Bitfield-Mask: 0xfff) */ +/* ========================================================= DAT1 ========================================================== */ +#define ADC_DAT1_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define ADC_DAT1_DATA_Msk (0xffffUL) /*!< DATA (Bitfield-Mask: 0xffff) */ +#define ADC_DAT1_CMPTH_Pos (16UL) /*!< CMPTH (Bit 16) */ +#define ADC_DAT1_CMPTH_Msk (0xfff0000UL) /*!< CMPTH (Bitfield-Mask: 0xfff) */ +/* ========================================================= DAT2 ========================================================== */ +#define ADC_DAT2_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define ADC_DAT2_DATA_Msk (0xffffUL) /*!< DATA (Bitfield-Mask: 0xffff) */ +#define ADC_DAT2_CMPTH_Pos (16UL) /*!< CMPTH (Bit 16) */ +#define ADC_DAT2_CMPTH_Msk (0xfff0000UL) /*!< CMPTH (Bitfield-Mask: 0xfff) */ +/* ========================================================= DAT3 ========================================================== */ +#define ADC_DAT3_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define ADC_DAT3_DATA_Msk (0xffffUL) /*!< DATA (Bitfield-Mask: 0xffff) */ +#define ADC_DAT3_CMPTH_Pos (16UL) /*!< CMPTH (Bit 16) */ +#define ADC_DAT3_CMPTH_Msk (0xfff0000UL) /*!< CMPTH (Bitfield-Mask: 0xfff) */ +/* ========================================================= DAT4 ========================================================== */ +#define ADC_DAT4_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define ADC_DAT4_DATA_Msk (0xffffUL) /*!< DATA (Bitfield-Mask: 0xffff) */ +#define ADC_DAT4_CMPTH_Pos (16UL) /*!< CMPTH (Bit 16) */ +#define ADC_DAT4_CMPTH_Msk (0xfff0000UL) /*!< CMPTH (Bitfield-Mask: 0xfff) */ +/* ========================================================= DAT5 ========================================================== */ +#define ADC_DAT5_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define ADC_DAT5_DATA_Msk (0xffffUL) /*!< DATA (Bitfield-Mask: 0xffff) */ +#define ADC_DAT5_CMPTH_Pos (16UL) /*!< CMPTH (Bit 16) */ +#define ADC_DAT5_CMPTH_Msk (0xfff0000UL) /*!< CMPTH (Bitfield-Mask: 0xfff) */ +/* ========================================================= DAT6 ========================================================== */ +#define ADC_DAT6_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define ADC_DAT6_DATA_Msk (0xffffUL) /*!< DATA (Bitfield-Mask: 0xffff) */ +#define ADC_DAT6_CMPTH_Pos (16UL) /*!< CMPTH (Bit 16) */ +#define ADC_DAT6_CMPTH_Msk (0xfff0000UL) /*!< CMPTH (Bitfield-Mask: 0xfff) */ +/* ========================================================= DAT7 ========================================================== */ +#define ADC_DAT7_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define ADC_DAT7_DATA_Msk (0xffffUL) /*!< DATA (Bitfield-Mask: 0xffff) */ +#define ADC_DAT7_CMPTH_Pos (16UL) /*!< CMPTH (Bit 16) */ +#define ADC_DAT7_CMPTH_Msk (0xfff0000UL) /*!< CMPTH (Bitfield-Mask: 0xfff) */ +/* ========================================================= DAT8 ========================================================== */ +#define ADC_DAT8_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define ADC_DAT8_DATA_Msk (0xffffUL) /*!< DATA (Bitfield-Mask: 0xffff) */ +#define ADC_DAT8_CMPTH_Pos (16UL) /*!< CMPTH (Bit 16) */ +#define ADC_DAT8_CMPTH_Msk (0xfff0000UL) /*!< CMPTH (Bitfield-Mask: 0xfff) */ +/* ========================================================= DAT9 ========================================================== */ +#define ADC_DAT9_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define ADC_DAT9_DATA_Msk (0xffffUL) /*!< DATA (Bitfield-Mask: 0xffff) */ +#define ADC_DAT9_CMPTH_Pos (16UL) /*!< CMPTH (Bit 16) */ +#define ADC_DAT9_CMPTH_Msk (0xfff0000UL) /*!< CMPTH (Bitfield-Mask: 0xfff) */ +/* ========================================================= DAT10 ========================================================= */ +#define ADC_DAT10_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define ADC_DAT10_DATA_Msk (0xffffUL) /*!< DATA (Bitfield-Mask: 0xffff) */ +#define ADC_DAT10_CMPTH_Pos (16UL) /*!< CMPTH (Bit 16) */ +#define ADC_DAT10_CMPTH_Msk (0xfff0000UL) /*!< CMPTH (Bitfield-Mask: 0xfff) */ +/* ========================================================= DAT11 ========================================================= */ +#define ADC_DAT11_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define ADC_DAT11_DATA_Msk (0xffffUL) /*!< DATA (Bitfield-Mask: 0xffff) */ +#define ADC_DAT11_CMPTH_Pos (16UL) /*!< CMPTH (Bit 16) */ +#define ADC_DAT11_CMPTH_Msk (0xfff0000UL) /*!< CMPTH (Bitfield-Mask: 0xfff) */ +/* ========================================================= DAT12 ========================================================= */ +#define ADC_DAT12_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define ADC_DAT12_DATA_Msk (0xffffUL) /*!< DATA (Bitfield-Mask: 0xffff) */ +#define ADC_DAT12_CMPTH_Pos (16UL) /*!< CMPTH (Bit 16) */ +#define ADC_DAT12_CMPTH_Msk (0xfff0000UL) /*!< CMPTH (Bitfield-Mask: 0xfff) */ +/* ========================================================= DAT13 ========================================================= */ +#define ADC_DAT13_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define ADC_DAT13_DATA_Msk (0xffffUL) /*!< DATA (Bitfield-Mask: 0xffff) */ +#define ADC_DAT13_CMPTH_Pos (16UL) /*!< CMPTH (Bit 16) */ +#define ADC_DAT13_CMPTH_Msk (0xfff0000UL) /*!< CMPTH (Bitfield-Mask: 0xfff) */ +/* ========================================================= DAT14 ========================================================= */ +#define ADC_DAT14_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define ADC_DAT14_DATA_Msk (0xffffUL) /*!< DATA (Bitfield-Mask: 0xffff) */ +#define ADC_DAT14_CMPTH_Pos (16UL) /*!< CMPTH (Bit 16) */ +#define ADC_DAT14_CMPTH_Msk (0xfff0000UL) /*!< CMPTH (Bitfield-Mask: 0xfff) */ +/* ========================================================= DAT15 ========================================================= */ +#define ADC_DAT15_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define ADC_DAT15_DATA_Msk (0xffffUL) /*!< DATA (Bitfield-Mask: 0xffff) */ +#define ADC_DAT15_CMPTH_Pos (16UL) /*!< CMPTH (Bit 16) */ +#define ADC_DAT15_CMPTH_Msk (0xfff0000UL) /*!< CMPTH (Bitfield-Mask: 0xfff) */ +/* ========================================================= CHSEL ========================================================= */ +#define ADC_CHSEL_CH_SEL_Pos (0UL) /*!< CH_SEL (Bit 0) */ +#define ADC_CHSEL_CH_SEL_Msk (0xffffUL) /*!< CH_SEL (Bitfield-Mask: 0xffff) */ +#define ADC_CHSEL_CH_CNT_Pos (16UL) /*!< CH_CNT (Bit 16) */ +#define ADC_CHSEL_CH_CNT_Msk (0xf0000UL) /*!< CH_CNT (Bitfield-Mask: 0x0f) */ +#define ADC_CHSEL_DISC_INTSEL_Pos (21UL) /*!< DISC_INTSEL (Bit 21) */ +#define ADC_CHSEL_DISC_INTSEL_Msk (0x200000UL) /*!< DISC_INTSEL (Bitfield-Mask: 0x01) */ +#define ADC_CHSEL_DISCNUM_Pos (22UL) /*!< DISCNUM (Bit 22) */ +#define ADC_CHSEL_DISCNUM_Msk (0x1c00000UL) /*!< DISCNUM (Bitfield-Mask: 0x07) */ +#define ADC_CHSEL_DISCEN_Pos (25UL) /*!< DISCEN (Bit 25) */ +#define ADC_CHSEL_DISCEN_Msk (0x2000000UL) /*!< DISCEN (Bitfield-Mask: 0x01) */ +#define ADC_CHSEL_TRIG_SEL16_Pos (26UL) /*!< TRIG_SEL16 (Bit 26) */ +#define ADC_CHSEL_TRIG_SEL16_Msk (0xc000000UL) /*!< TRIG_SEL16 (Bitfield-Mask: 0x03) */ +#define ADC_CHSEL_TRIG_SEL17_Pos (28UL) /*!< TRIG_SEL17 (Bit 28) */ +#define ADC_CHSEL_TRIG_SEL17_Msk (0x30000000UL) /*!< TRIG_SEL17 (Bitfield-Mask: 0x03) */ +#define ADC_CHSEL_EXTRIG_SEL_Pos (30UL) /*!< EXTRIG_SEL (Bit 30) */ +#define ADC_CHSEL_EXTRIG_SEL_Msk (0xc0000000UL) /*!< EXTRIG_SEL (Bitfield-Mask: 0x03) */ +/* ======================================================== TRGSEL ========================================================= */ +#define ADC_TRGSEL_TRIG_SEL0_Pos (0UL) /*!< TRIG_SEL0 (Bit 0) */ +#define ADC_TRGSEL_TRIG_SEL0_Msk (0x3UL) /*!< TRIG_SEL0 (Bitfield-Mask: 0x03) */ +#define ADC_TRGSEL_TRIG_SEL1_Pos (2UL) /*!< TRIG_SEL1 (Bit 2) */ +#define ADC_TRGSEL_TRIG_SEL1_Msk (0xcUL) /*!< TRIG_SEL1 (Bitfield-Mask: 0x03) */ +#define ADC_TRGSEL_TRIG_SEL2_Pos (4UL) /*!< TRIG_SEL2 (Bit 4) */ +#define ADC_TRGSEL_TRIG_SEL2_Msk (0x30UL) /*!< TRIG_SEL2 (Bitfield-Mask: 0x03) */ +#define ADC_TRGSEL_TRIG_SEL3_Pos (6UL) /*!< TRIG_SEL3 (Bit 6) */ +#define ADC_TRGSEL_TRIG_SEL3_Msk (0xc0UL) /*!< TRIG_SEL3 (Bitfield-Mask: 0x03) */ +#define ADC_TRGSEL_TRIG_SEL4_Pos (8UL) /*!< TRIG_SEL4 (Bit 8) */ +#define ADC_TRGSEL_TRIG_SEL4_Msk (0x300UL) /*!< TRIG_SEL4 (Bitfield-Mask: 0x03) */ +#define ADC_TRGSEL_TRIG_SEL5_Pos (10UL) /*!< TRIG_SEL5 (Bit 10) */ +#define ADC_TRGSEL_TRIG_SEL5_Msk (0xc00UL) /*!< TRIG_SEL5 (Bitfield-Mask: 0x03) */ +#define ADC_TRGSEL_TRIG_SEL6_Pos (12UL) /*!< TRIG_SEL6 (Bit 12) */ +#define ADC_TRGSEL_TRIG_SEL6_Msk (0x3000UL) /*!< TRIG_SEL6 (Bitfield-Mask: 0x03) */ +#define ADC_TRGSEL_TRIG_SEL7_Pos (14UL) /*!< TRIG_SEL7 (Bit 14) */ +#define ADC_TRGSEL_TRIG_SEL7_Msk (0xc000UL) /*!< TRIG_SEL7 (Bitfield-Mask: 0x03) */ +#define ADC_TRGSEL_TRIG_SEL8_Pos (16UL) /*!< TRIG_SEL8 (Bit 16) */ +#define ADC_TRGSEL_TRIG_SEL8_Msk (0x30000UL) /*!< TRIG_SEL8 (Bitfield-Mask: 0x03) */ +#define ADC_TRGSEL_TRIG_SEL9_Pos (18UL) /*!< TRIG_SEL9 (Bit 18) */ +#define ADC_TRGSEL_TRIG_SEL9_Msk (0xc0000UL) /*!< TRIG_SEL9 (Bitfield-Mask: 0x03) */ +#define ADC_TRGSEL_TRIG_SEL10_Pos (20UL) /*!< TRIG_SEL10 (Bit 20) */ +#define ADC_TRGSEL_TRIG_SEL10_Msk (0x300000UL) /*!< TRIG_SEL10 (Bitfield-Mask: 0x03) */ +#define ADC_TRGSEL_TRIG_SEL11_Pos (22UL) /*!< TRIG_SEL11 (Bit 22) */ +#define ADC_TRGSEL_TRIG_SEL11_Msk (0xc00000UL) /*!< TRIG_SEL11 (Bitfield-Mask: 0x03) */ +#define ADC_TRGSEL_TRIG_SEL12_Pos (24UL) /*!< TRIG_SEL12 (Bit 24) */ +#define ADC_TRGSEL_TRIG_SEL12_Msk (0x3000000UL) /*!< TRIG_SEL12 (Bitfield-Mask: 0x03) */ +#define ADC_TRGSEL_TRIG_SEL13_Pos (26UL) /*!< TRIG_SEL13 (Bit 26) */ +#define ADC_TRGSEL_TRIG_SEL13_Msk (0xc000000UL) /*!< TRIG_SEL13 (Bitfield-Mask: 0x03) */ +#define ADC_TRGSEL_TRIG_SEL14_Pos (28UL) /*!< TRIG_SEL14 (Bit 28) */ +#define ADC_TRGSEL_TRIG_SEL14_Msk (0x30000000UL) /*!< TRIG_SEL14 (Bitfield-Mask: 0x03) */ +#define ADC_TRGSEL_TRIG_SEL15_Pos (30UL) /*!< TRIG_SEL15 (Bit 30) */ +#define ADC_TRGSEL_TRIG_SEL15_Msk (0xc0000000UL) /*!< TRIG_SEL15 (Bitfield-Mask: 0x03) */ +/* ========================================================= BKSEL ========================================================= */ +#define ADC_BKSEL_BK1_CH_Pos (0UL) /*!< BK1_CH (Bit 0) */ +#define ADC_BKSEL_BK1_CH_Msk (0xfUL) /*!< BK1_CH (Bitfield-Mask: 0x0f) */ +#define ADC_BKSEL_BK1_FLT_Pos (4UL) /*!< BK1_FLT (Bit 4) */ +#define ADC_BKSEL_BK1_FLT_Msk (0x30UL) /*!< BK1_FLT (Bitfield-Mask: 0x03) */ +#define ADC_BKSEL_BK1_EN_Pos (6UL) /*!< BK1_EN (Bit 6) */ +#define ADC_BKSEL_BK1_EN_Msk (0xc0UL) /*!< BK1_EN (Bitfield-Mask: 0x03) */ +#define ADC_BKSEL_BK2_CH_Pos (8UL) /*!< BK2_CH (Bit 8) */ +#define ADC_BKSEL_BK2_CH_Msk (0xf00UL) /*!< BK2_CH (Bitfield-Mask: 0x0f) */ +#define ADC_BKSEL_BK2_FLT_Pos (12UL) /*!< BK2_FLT (Bit 12) */ +#define ADC_BKSEL_BK2_FLT_Msk (0x3000UL) /*!< BK2_FLT (Bitfield-Mask: 0x03) */ +#define ADC_BKSEL_BK2_EN_Pos (14UL) /*!< BK2_EN (Bit 14) */ +#define ADC_BKSEL_BK2_EN_Msk (0xc000UL) /*!< BK2_EN (Bitfield-Mask: 0x03) */ +/* ======================================================== BAKDAT ========================================================= */ +#define ADC_BAKDAT_BAKDAT_Pos (0UL) /*!< BAKDAT (Bit 0) */ +#define ADC_BAKDAT_BAKDAT_Msk (0xffffUL) /*!< BAKDAT (Bitfield-Mask: 0xffff) */ + + +/* =========================================================================================================================== */ +/* ================ AMISC ================ */ +/* =========================================================================================================================== */ + +/* ====================================================== LVD_LVR_CR ======================================================= */ +#define AMISC_LVD_LVR_CR_LVD_EN_Pos (0UL) /*!< LVD_EN (Bit 0) */ +#define AMISC_LVD_LVR_CR_LVD_EN_Msk (0x1UL) /*!< LVD_EN (Bitfield-Mask: 0x01) */ +#define AMISC_LVD_LVR_CR_LDO_LP_EN_Pos (1UL) /*!< LDO_LP_EN (Bit 1) */ +#define AMISC_LVD_LVR_CR_LDO_LP_EN_Msk (0x2UL) /*!< LDO_LP_EN (Bitfield-Mask: 0x01) */ +#define AMISC_LVD_LVR_CR_LVD_F_SEL_Pos (2UL) /*!< LVD_F_SEL (Bit 2) */ +#define AMISC_LVD_LVR_CR_LVD_F_SEL_Msk (0xcUL) /*!< LVD_F_SEL (Bitfield-Mask: 0x03) */ +#define AMISC_LVD_LVR_CR_LVD_SEL_Pos (5UL) /*!< LVD_SEL (Bit 5) */ +#define AMISC_LVD_LVR_CR_LVD_SEL_Msk (0xe0UL) /*!< LVD_SEL (Bitfield-Mask: 0x07) */ +#define AMISC_LVD_LVR_CR_LVR_EN_Pos (8UL) /*!< LVR_EN (Bit 8) */ +#define AMISC_LVD_LVR_CR_LVR_EN_Msk (0x100UL) /*!< LVR_EN (Bitfield-Mask: 0x01) */ +#define AMISC_LVD_LVR_CR_LVD_INT_EN_Pos (9UL) /*!< LVD_INT_EN (Bit 9) */ +#define AMISC_LVD_LVR_CR_LVD_INT_EN_Msk (0x200UL) /*!< LVD_INT_EN (Bitfield-Mask: 0x01) */ +#define AMISC_LVD_LVR_CR_TEMP_EN_Pos (10UL) /*!< TEMP_EN (Bit 10) */ +#define AMISC_LVD_LVR_CR_TEMP_EN_Msk (0x400UL) /*!< TEMP_EN (Bitfield-Mask: 0x01) */ +#define AMISC_LVD_LVR_CR_LVD_STATE_Pos (11UL) /*!< LVD_STATE (Bit 11) */ +#define AMISC_LVD_LVR_CR_LVD_STATE_Msk (0x800UL) /*!< LVD_STATE (Bitfield-Mask: 0x01) */ +#define AMISC_LVD_LVR_CR_LVR_SEL_Pos (13UL) /*!< LVR_SEL (Bit 13) */ +#define AMISC_LVD_LVR_CR_LVR_SEL_Msk (0xe000UL) /*!< LVR_SEL (Bitfield-Mask: 0x07) */ +/* ======================================================== VBUF_CR ======================================================== */ +#define AMISC_VBUF_CR_VBUF_EN_Pos (0UL) /*!< VBUF_EN (Bit 0) */ +#define AMISC_VBUF_CR_VBUF_EN_Msk (0x1UL) /*!< VBUF_EN (Bitfield-Mask: 0x01) */ +#define AMISC_VBUF_CR_ANA2IO_EN_Pos (4UL) /*!< ANA2IO_EN (Bit 4) */ +#define AMISC_VBUF_CR_ANA2IO_EN_Msk (0x10UL) /*!< ANA2IO_EN (Bitfield-Mask: 0x01) */ +#define AMISC_VBUF_CR_ANA2PGA_EN_Pos (5UL) /*!< ANA2PGA_EN (Bit 5) */ +#define AMISC_VBUF_CR_ANA2PGA_EN_Msk (0x20UL) /*!< ANA2PGA_EN (Bitfield-Mask: 0x01) */ +#define AMISC_VBUF_CR_ANA_SEL_Pos (6UL) /*!< ANA_SEL (Bit 6) */ +#define AMISC_VBUF_CR_ANA_SEL_Msk (0x1fc0UL) /*!< ANA_SEL (Bitfield-Mask: 0x7f) */ +/* ======================================================== DAC_CR ========================================================= */ +#define AMISC_DAC_CR_DAC0Step_Pos (0UL) /*!< DAC0Step (Bit 0) */ +#define AMISC_DAC_CR_DAC0Step_Msk (0x3ffUL) /*!< DAC0Step (Bitfield-Mask: 0x3ff) */ +#define AMISC_DAC_CR_DAC1Step_Pos (10UL) /*!< DAC1Step (Bit 10) */ +#define AMISC_DAC_CR_DAC1Step_Msk (0xffc00UL) /*!< DAC1Step (Bitfield-Mask: 0x3ff) */ +#define AMISC_DAC_CR_DAC0_EN_Pos (20UL) /*!< DAC0_EN (Bit 20) */ +#define AMISC_DAC_CR_DAC0_EN_Msk (0x100000UL) /*!< DAC0_EN (Bitfield-Mask: 0x01) */ +#define AMISC_DAC_CR_DAC1_EN_Pos (21UL) /*!< DAC1_EN (Bit 21) */ +#define AMISC_DAC_CR_DAC1_EN_Msk (0x200000UL) /*!< DAC1_EN (Bitfield-Mask: 0x01) */ +/* ======================================================== HSI_CR ========================================================= */ +#define AMISC_HSI_CR_LDO_SEL_Pos (0UL) /*!< LDO_SEL (Bit 0) */ +#define AMISC_HSI_CR_LDO_SEL_Msk (0xffffUL) /*!< LDO_SEL (Bitfield-Mask: 0xffff) */ +#define AMISC_HSI_CR_HSI_EN_Pos (24UL) /*!< HSI_EN (Bit 24) */ +#define AMISC_HSI_CR_HSI_EN_Msk (0xff000000UL) /*!< HSI_EN (Bitfield-Mask: 0xff) */ +/* ======================================================== LSI_CR ========================================================= */ +#define AMISC_LSI_CR_LSI_EN_Pos (24UL) /*!< LSI_EN (Bit 24) */ +#define AMISC_LSI_CR_LSI_EN_Msk (0xff000000UL) /*!< LSI_EN (Bitfield-Mask: 0xff) */ +/* ====================================================== ADC_AIN_CR ======================================================= */ +#define AMISC_ADC_AIN_CR_ANA2ADC_EN_Pos (0UL) /*!< ANA2ADC_EN (Bit 0) */ +#define AMISC_ADC_AIN_CR_ANA2ADC_EN_Msk (0x1UL) /*!< ANA2ADC_EN (Bitfield-Mask: 0x01) */ + + +/* =========================================================================================================================== */ +/* ================ HWTRIM ================ */ +/* =========================================================================================================================== */ + +/* ======================================================= LDO_TRIM ======================================================== */ +#define HWTRIM_LDO_TRIM_LDO_TRIM_Pos (0UL) /*!< LDO_TRIM (Bit 0) */ +#define HWTRIM_LDO_TRIM_LDO_TRIM_Msk (0x1fUL) /*!< LDO_TRIM (Bitfield-Mask: 0x1f) */ +#define HWTRIM_LDO_TRIM_LDO_LP_TRIM_Pos (5UL) /*!< LDO_LP_TRIM (Bit 5) */ +#define HWTRIM_LDO_TRIM_LDO_LP_TRIM_Msk (0x3e0UL) /*!< LDO_LP_TRIM (Bitfield-Mask: 0x1f) */ +#define HWTRIM_LDO_TRIM_LDO_TUNE_Pos (10UL) /*!< LDO_TUNE (Bit 10) */ +#define HWTRIM_LDO_TRIM_LDO_TUNE_Msk (0xc00UL) /*!< LDO_TUNE (Bitfield-Mask: 0x03) */ +/* ======================================================= VBUF_TRIM ======================================================= */ +#define HWTRIM_VBUF_TRIM_VBUF_TRIM_Pos (0UL) /*!< VBUF_TRIM (Bit 0) */ +#define HWTRIM_VBUF_TRIM_VBUF_TRIM_Msk (0x7fUL) /*!< VBUF_TRIM (Bitfield-Mask: 0x7f) */ +/* ======================================================= HSI_TRIM ======================================================== */ +#define HWTRIM_HSI_TRIM_HSI_D_CFG_Pos (0UL) /*!< HSI_D_CFG (Bit 0) */ +#define HWTRIM_HSI_TRIM_HSI_D_CFG_Msk (0x1ffUL) /*!< HSI_D_CFG (Bitfield-Mask: 0x1ff) */ +#define HWTRIM_HSI_TRIM_HSI_FSEL_CFG_Pos (9UL) /*!< HSI_FSEL_CFG (Bit 9) */ +#define HWTRIM_HSI_TRIM_HSI_FSEL_CFG_Msk (0xfe00UL) /*!< HSI_FSEL_CFG (Bitfield-Mask: 0x7f) */ +#define HWTRIM_HSI_TRIM_HSI_TC_Pos (16UL) /*!< HSI_TC (Bit 16) */ +#define HWTRIM_HSI_TRIM_HSI_TC_Msk (0x30000UL) /*!< HSI_TC (Bitfield-Mask: 0x03) */ +/* ======================================================= LSI_TRIM ======================================================== */ +#define HWTRIM_LSI_TRIM_LSI_TRIM_Pos (0UL) /*!< LSI_TRIM (Bit 0) */ +#define HWTRIM_LSI_TRIM_LSI_TRIM_Msk (0xffUL) /*!< LSI_TRIM (Bitfield-Mask: 0xff) */ +/* ======================================================= MISC_CFG ======================================================== */ +#define HWTRIM_MISC_CFG_EXT_nRST_EN_Pos (0UL) /*!< EXT_nRST_EN (Bit 0) */ +#define HWTRIM_MISC_CFG_EXT_nRST_EN_Msk (0x1UL) /*!< EXT_nRST_EN (Bitfield-Mask: 0x01) */ + + +/* =========================================================================================================================== */ +/* ================ CRC ================ */ +/* =========================================================================================================================== */ + +/* ========================================================== CR =========================================================== */ +#define CRC_CR_POLYSEL_Pos (0UL) /*!< POLYSEL (Bit 0) */ +#define CRC_CR_POLYSEL_Msk (0x1UL) /*!< POLYSEL (Bitfield-Mask: 0x01) */ +#define CRC_CR_VERF_Pos (1UL) /*!< VERF (Bit 1) */ +#define CRC_CR_VERF_Msk (0x2UL) /*!< VERF (Bitfield-Mask: 0x01) */ +/* ========================================================== DIN ========================================================== */ +#define CRC_DIN_DIN_Pos (0UL) /*!< DIN (Bit 0) */ +#define CRC_DIN_DIN_Msk (0xffffffffUL) /*!< DIN (Bitfield-Mask: 0xffffffff) */ +/* ========================================================= DOUT ========================================================== */ +#define CRC_DOUT_DOUT_Pos (0UL) /*!< DOUT (Bit 0) */ +#define CRC_DOUT_DOUT_Msk (0xffffffffUL) /*!< DOUT (Bitfield-Mask: 0xffffffff) */ + + +/* =========================================================================================================================== */ +/* ================ DSP ================ */ +/* =========================================================================================================================== */ + +/* ========================================================== CR =========================================================== */ +#define DSP_CR_MODE_Pos (0UL) /*!< MODE (Bit 0) */ +#define DSP_CR_MODE_Msk (0x7UL) /*!< MODE (Bitfield-Mask: 0x07) */ +/* ========================================================== SR =========================================================== */ +#define DSP_SR_DONE_Pos (0UL) /*!< DONE (Bit 0) */ +#define DSP_SR_DONE_Msk (0x1UL) /*!< DONE (Bitfield-Mask: 0x01) */ +/* ========================================================= SDAT1 ========================================================= */ +/* ========================================================= SDAT2 ========================================================= */ +/* ========================================================= RSLT1 ========================================================= */ +/* ========================================================= RSLT2 ========================================================= */ + + +/* =========================================================================================================================== */ +/* ================ OPAMP ================ */ +/* =========================================================================================================================== */ + +/* ======================================================== PGA_CR ========================================================= */ +#define OPAMP_PGA_CR_PGA_EN_Pos (0UL) /*!< PGA_EN (Bit 0) */ +#define OPAMP_PGA_CR_PGA_EN_Msk (0x1UL) /*!< PGA_EN (Bitfield-Mask: 0x01) */ +#define OPAMP_PGA_CR_PGA_IO_EN_Pos (1UL) /*!< PGA_IO_EN (Bit 1) */ +#define OPAMP_PGA_CR_PGA_IO_EN_Msk (0x2UL) /*!< PGA_IO_EN (Bitfield-Mask: 0x01) */ +#define OPAMP_PGA_CR_PGA_GAIN_Pos (2UL) /*!< PGA_GAIN (Bit 2) */ +#define OPAMP_PGA_CR_PGA_GAIN_Msk (0xfcUL) /*!< PGA_GAIN (Bitfield-Mask: 0x3f) */ +#define OPAMP_PGA_CR_PGA_VIN_SEL_Pos (10UL) /*!< PGA_VIN_SEL (Bit 10) */ +#define OPAMP_PGA_CR_PGA_VIN_SEL_Msk (0x400UL) /*!< PGA_VIN_SEL (Bitfield-Mask: 0x01) */ +#define OPAMP_PGA_CR_PGA_VIP_SEL_Pos (11UL) /*!< PGA_VIP_SEL (Bit 11) */ +#define OPAMP_PGA_CR_PGA_VIP_SEL_Msk (0x800UL) /*!< PGA_VIP_SEL (Bitfield-Mask: 0x01) */ + + +/* =========================================================================================================================== */ +/* ================ COMP ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= CTRL ========================================================== */ +#define COMP_CTRL_EN_Pos (0UL) /*!< EN (Bit 0) */ +#define COMP_CTRL_EN_Msk (0x1UL) /*!< EN (Bitfield-Mask: 0x01) */ +#define COMP_CTRL_COUT_Pos (1UL) /*!< COUT (Bit 1) */ +#define COMP_CTRL_COUT_Msk (0x2UL) /*!< COUT (Bitfield-Mask: 0x01) */ +#define COMP_CTRL_VIN_SEL_Pos (2UL) /*!< VIN_SEL (Bit 2) */ +#define COMP_CTRL_VIN_SEL_Msk (0xcUL) /*!< VIN_SEL (Bitfield-Mask: 0x03) */ +#define COMP_CTRL_FIL_CTRL_Pos (4UL) /*!< FIL_CTRL (Bit 4) */ +#define COMP_CTRL_FIL_CTRL_Msk (0xf0UL) /*!< FIL_CTRL (Bitfield-Mask: 0x0f) */ +#define COMP_CTRL_HYS_EN_Pos (8UL) /*!< HYS_EN (Bit 8) */ +#define COMP_CTRL_HYS_EN_Msk (0x100UL) /*!< HYS_EN (Bitfield-Mask: 0x01) */ +#define COMP_CTRL_OUT_EN_Pos (11UL) /*!< OUT_EN (Bit 11) */ +#define COMP_CTRL_OUT_EN_Msk (0x800UL) /*!< OUT_EN (Bitfield-Mask: 0x01) */ +#define COMP_CTRL_POL_SEL_Pos (12UL) /*!< POL_SEL (Bit 12) */ +#define COMP_CTRL_POL_SEL_Msk (0x1000UL) /*!< POL_SEL (Bitfield-Mask: 0x01) */ +/* ======================================================== VIPSEL ========================================================= */ +#define COMP_VIPSEL_VIP_SEL_Pos (0UL) /*!< VIP_SEL (Bit 0) */ +#define COMP_VIPSEL_VIP_SEL_Msk (0x1fUL) /*!< VIP_SEL (Bitfield-Mask: 0x1f) */ +/* ========================================================== IR =========================================================== */ +#define COMP_IR_FIE_Pos (0UL) /*!< FIE (Bit 0) */ +#define COMP_IR_FIE_Msk (0x1UL) /*!< FIE (Bitfield-Mask: 0x01) */ +#define COMP_IR_RIE_Pos (1UL) /*!< RIE (Bit 1) */ +#define COMP_IR_RIE_Msk (0x2UL) /*!< RIE (Bitfield-Mask: 0x01) */ +/* ========================================================== IF =========================================================== */ +#define COMP_IF_FIF_Pos (0UL) /*!< FIF (Bit 0) */ +#define COMP_IF_FIF_Msk (0x1UL) /*!< FIF (Bitfield-Mask: 0x01) */ +#define COMP_IF_RIF_Pos (1UL) /*!< RIF (Bit 1) */ +#define COMP_IF_RIF_Msk (0x2UL) /*!< RIF (Bitfield-Mask: 0x01) */ +/* ======================================================== INITCNT ======================================================== */ +#define COMP_INITCNT_INIT_DELAY_Pos (0UL) /*!< INIT_DELAY (Bit 0) */ +#define COMP_INITCNT_INIT_DELAY_Msk (0x3ffUL) /*!< INIT_DELAY (Bitfield-Mask: 0x3ff) */ + + +/* =========================================================================================================================== */ +/* ================ TIM ================ */ +/* =========================================================================================================================== */ + +/* ========================================================== CR1 ========================================================== */ +#define TIM_CR1_CEN_Pos (0UL) /*!< CEN (Bit 0) */ +#define TIM_CR1_CEN_Msk (0x1UL) /*!< CEN (Bitfield-Mask: 0x01) */ +#define TIM_CR1_UDIS_Pos (1UL) /*!< UDIS (Bit 1) */ +#define TIM_CR1_UDIS_Msk (0x2UL) /*!< UDIS (Bitfield-Mask: 0x01) */ +#define TIM_CR1_URS_Pos (2UL) /*!< URS (Bit 2) */ +#define TIM_CR1_URS_Msk (0x4UL) /*!< URS (Bitfield-Mask: 0x01) */ +#define TIM_CR1_OPM_Pos (3UL) /*!< OPM (Bit 3) */ +#define TIM_CR1_OPM_Msk (0x8UL) /*!< OPM (Bitfield-Mask: 0x01) */ +#define TIM_CR1_DIR_Pos (4UL) /*!< DIR (Bit 4) */ +#define TIM_CR1_DIR_Msk (0x10UL) /*!< DIR (Bitfield-Mask: 0x01) */ +#define TIM_CR1_CMS_Pos (5UL) /*!< CMS (Bit 5) */ +#define TIM_CR1_CMS_Msk (0x60UL) /*!< CMS (Bitfield-Mask: 0x03) */ +#define TIM_CR1_ARPE_Pos (7UL) /*!< ARPE (Bit 7) */ +#define TIM_CR1_ARPE_Msk (0x80UL) /*!< ARPE (Bitfield-Mask: 0x01) */ +#define TIM_CR1_CKD_Pos (8UL) /*!< CKD (Bit 8) */ +#define TIM_CR1_CKD_Msk (0x300UL) /*!< CKD (Bitfield-Mask: 0x03) */ +#define TIM_CR1_ASYMEN_Pos (10UL) /*!< ASYMEN (Bit 10) */ +#define TIM_CR1_ASYMEN_Msk (0x400UL) /*!< ASYMEN (Bitfield-Mask: 0x01) */ +/* ========================================================== CR2 ========================================================== */ +#define TIM_CR2_CCPC_Pos (0UL) /*!< CCPC (Bit 0) */ +#define TIM_CR2_CCPC_Msk (0x1UL) /*!< CCPC (Bitfield-Mask: 0x01) */ +#define TIM_CR2_CCUS_Pos (2UL) /*!< CCUS (Bit 2) */ +#define TIM_CR2_CCUS_Msk (0x4UL) /*!< CCUS (Bitfield-Mask: 0x01) */ +#define TIM_CR2_MMS_Pos (4UL) /*!< MMS (Bit 4) */ +#define TIM_CR2_MMS_Msk (0x70UL) /*!< MMS (Bitfield-Mask: 0x07) */ +#define TIM_CR2_TI1S_Pos (7UL) /*!< TI1S (Bit 7) */ +#define TIM_CR2_TI1S_Msk (0x80UL) /*!< TI1S (Bitfield-Mask: 0x01) */ +#define TIM_CR2_OIS1_Pos (8UL) /*!< OIS1 (Bit 8) */ +#define TIM_CR2_OIS1_Msk (0x100UL) /*!< OIS1 (Bitfield-Mask: 0x01) */ +#define TIM_CR2_OIS1N_Pos (9UL) /*!< OIS1N (Bit 9) */ +#define TIM_CR2_OIS1N_Msk (0x200UL) /*!< OIS1N (Bitfield-Mask: 0x01) */ +#define TIM_CR2_OIS2_Pos (10UL) /*!< OIS2 (Bit 10) */ +#define TIM_CR2_OIS2_Msk (0x400UL) /*!< OIS2 (Bitfield-Mask: 0x01) */ +#define TIM_CR2_OIS2N_Pos (11UL) /*!< OIS2N (Bit 11) */ +#define TIM_CR2_OIS2N_Msk (0x800UL) /*!< OIS2N (Bitfield-Mask: 0x01) */ +#define TIM_CR2_OIS3_Pos (12UL) /*!< OIS3 (Bit 12) */ +#define TIM_CR2_OIS3_Msk (0x1000UL) /*!< OIS3 (Bitfield-Mask: 0x01) */ +#define TIM_CR2_OIS3N_Pos (13UL) /*!< OIS3N (Bit 13) */ +#define TIM_CR2_OIS3N_Msk (0x2000UL) /*!< OIS3N (Bitfield-Mask: 0x01) */ +#define TIM_CR2_OIS4_Pos (14UL) /*!< OIS4 (Bit 14) */ +#define TIM_CR2_OIS4_Msk (0x4000UL) /*!< OIS4 (Bitfield-Mask: 0x01) */ +/* ========================================================= SMCR ========================================================== */ +#define TIM_SMCR_SMS_Pos (0UL) /*!< SMS (Bit 0) */ +#define TIM_SMCR_SMS_Msk (0x7UL) /*!< SMS (Bitfield-Mask: 0x07) */ +#define TIM_SMCR_TS_Pos (4UL) /*!< TS (Bit 4) */ +#define TIM_SMCR_TS_Msk (0x70UL) /*!< TS (Bitfield-Mask: 0x07) */ +#define TIM_SMCR_MSM_Pos (7UL) /*!< MSM (Bit 7) */ +#define TIM_SMCR_MSM_Msk (0x80UL) /*!< MSM (Bitfield-Mask: 0x01) */ +#define TIM_SMCR_ETF_Pos (8UL) /*!< ETF (Bit 8) */ +#define TIM_SMCR_ETF_Msk (0xf00UL) /*!< ETF (Bitfield-Mask: 0x0f) */ +#define TIM_SMCR_ETPS_Pos (12UL) /*!< ETPS (Bit 12) */ +#define TIM_SMCR_ETPS_Msk (0x3000UL) /*!< ETPS (Bitfield-Mask: 0x03) */ +#define TIM_SMCR_ECE_Pos (14UL) /*!< ECE (Bit 14) */ +#define TIM_SMCR_ECE_Msk (0x4000UL) /*!< ECE (Bitfield-Mask: 0x01) */ +#define TIM_SMCR_ETP_Pos (15UL) /*!< ETP (Bit 15) */ +#define TIM_SMCR_ETP_Msk (0x8000UL) /*!< ETP (Bitfield-Mask: 0x01) */ +/* ========================================================= DIER ========================================================== */ +#define TIM_DIER_UIE_Pos (0UL) /*!< UIE (Bit 0) */ +#define TIM_DIER_UIE_Msk (0x1UL) /*!< UIE (Bitfield-Mask: 0x01) */ +#define TIM_DIER_CC1IE_Pos (1UL) /*!< CC1IE (Bit 1) */ +#define TIM_DIER_CC1IE_Msk (0x2UL) /*!< CC1IE (Bitfield-Mask: 0x01) */ +#define TIM_DIER_CC2IE_Pos (2UL) /*!< CC2IE (Bit 2) */ +#define TIM_DIER_CC2IE_Msk (0x4UL) /*!< CC2IE (Bitfield-Mask: 0x01) */ +#define TIM_DIER_CC3IE_Pos (3UL) /*!< CC3IE (Bit 3) */ +#define TIM_DIER_CC3IE_Msk (0x8UL) /*!< CC3IE (Bitfield-Mask: 0x01) */ +#define TIM_DIER_CC4IE_Pos (4UL) /*!< CC4IE (Bit 4) */ +#define TIM_DIER_CC4IE_Msk (0x10UL) /*!< CC4IE (Bitfield-Mask: 0x01) */ +#define TIM_DIER_COMIE_Pos (5UL) /*!< COMIE (Bit 5) */ +#define TIM_DIER_COMIE_Msk (0x20UL) /*!< COMIE (Bitfield-Mask: 0x01) */ +#define TIM_DIER_TIE_Pos (6UL) /*!< TIE (Bit 6) */ +#define TIM_DIER_TIE_Msk (0x40UL) /*!< TIE (Bitfield-Mask: 0x01) */ +#define TIM_DIER_BIE_Pos (7UL) /*!< BIE (Bit 7) */ +#define TIM_DIER_BIE_Msk (0x80UL) /*!< BIE (Bitfield-Mask: 0x01) */ +#define TIM_DIER_CCD1IE_Pos (8UL) /*!< CCD1IE (Bit 8) */ +#define TIM_DIER_CCD1IE_Msk (0x100UL) /*!< CCD1IE (Bitfield-Mask: 0x01) */ +#define TIM_DIER_CCD2IE_Pos (9UL) /*!< CCD2IE (Bit 9) */ +#define TIM_DIER_CCD2IE_Msk (0x200UL) /*!< CCD2IE (Bitfield-Mask: 0x01) */ +#define TIM_DIER_CCD3IE_Pos (10UL) /*!< CCD3IE (Bit 10) */ +#define TIM_DIER_CCD3IE_Msk (0x400UL) /*!< CCD3IE (Bitfield-Mask: 0x01) */ +#define TIM_DIER_OVIE_Pos (11UL) /*!< OVIE (Bit 11) */ +#define TIM_DIER_OVIE_Msk (0x800UL) /*!< OVIE (Bitfield-Mask: 0x01) */ +#define TIM_DIER_UDIE_Pos (12UL) /*!< UDIE (Bit 12) */ +#define TIM_DIER_UDIE_Msk (0x1000UL) /*!< UDIE (Bitfield-Mask: 0x01) */ +#define TIM_DIER_CCD4IE_Pos (13UL) /*!< CCD4IE (Bit 13) */ +#define TIM_DIER_CCD4IE_Msk (0x2000UL) /*!< CCD4IE (Bitfield-Mask: 0x01) */ +/* ========================================================== SR =========================================================== */ +#define TIM_SR_UIF_Pos (0UL) /*!< UIF (Bit 0) */ +#define TIM_SR_UIF_Msk (0x1UL) /*!< UIF (Bitfield-Mask: 0x01) */ +#define TIM_SR_CC1IF_Pos (1UL) /*!< CC1IF (Bit 1) */ +#define TIM_SR_CC1IF_Msk (0x2UL) /*!< CC1IF (Bitfield-Mask: 0x01) */ +#define TIM_SR_CC2IF_Pos (2UL) /*!< CC2IF (Bit 2) */ +#define TIM_SR_CC2IF_Msk (0x4UL) /*!< CC2IF (Bitfield-Mask: 0x01) */ +#define TIM_SR_CC3IF_Pos (3UL) /*!< CC3IF (Bit 3) */ +#define TIM_SR_CC3IF_Msk (0x8UL) /*!< CC3IF (Bitfield-Mask: 0x01) */ +#define TIM_SR_CC4IF_Pos (4UL) /*!< CC4IF (Bit 4) */ +#define TIM_SR_CC4IF_Msk (0x10UL) /*!< CC4IF (Bitfield-Mask: 0x01) */ +#define TIM_SR_COMIF_Pos (5UL) /*!< COMIF (Bit 5) */ +#define TIM_SR_COMIF_Msk (0x20UL) /*!< COMIF (Bitfield-Mask: 0x01) */ +#define TIM_SR_TIF_Pos (6UL) /*!< TIF (Bit 6) */ +#define TIM_SR_TIF_Msk (0x40UL) /*!< TIF (Bitfield-Mask: 0x01) */ +#define TIM_SR_BIF_Pos (7UL) /*!< BIF (Bit 7) */ +#define TIM_SR_BIF_Msk (0x80UL) /*!< BIF (Bitfield-Mask: 0x01) */ +#define TIM_SR_CC1OF_Pos (9UL) /*!< CC1OF (Bit 9) */ +#define TIM_SR_CC1OF_Msk (0x200UL) /*!< CC1OF (Bitfield-Mask: 0x01) */ +#define TIM_SR_CC2OF_Pos (10UL) /*!< CC2OF (Bit 10) */ +#define TIM_SR_CC2OF_Msk (0x400UL) /*!< CC2OF (Bitfield-Mask: 0x01) */ +#define TIM_SR_CC3OF_Pos (11UL) /*!< CC3OF (Bit 11) */ +#define TIM_SR_CC3OF_Msk (0x800UL) /*!< CC3OF (Bitfield-Mask: 0x01) */ +#define TIM_SR_CC4OF_Pos (12UL) /*!< CC4OF (Bit 12) */ +#define TIM_SR_CC4OF_Msk (0x1000UL) /*!< CC4OF (Bitfield-Mask: 0x01) */ +#define TIM_SR_CCD1IF_Pos (13UL) /*!< CCD1IF (Bit 13) */ +#define TIM_SR_CCD1IF_Msk (0x2000UL) /*!< CCD1IF (Bitfield-Mask: 0x01) */ +#define TIM_SR_CCD2IF_Pos (14UL) /*!< CCD2IF (Bit 14) */ +#define TIM_SR_CCD2IF_Msk (0x4000UL) /*!< CCD2IF (Bitfield-Mask: 0x01) */ +#define TIM_SR_CCD3IF_Pos (15UL) /*!< CCD3IF (Bit 15) */ +#define TIM_SR_CCD3IF_Msk (0x8000UL) /*!< CCD3IF (Bitfield-Mask: 0x01) */ +#define TIM_SR_OVIF_Pos (16UL) /*!< OVIF (Bit 16) */ +#define TIM_SR_OVIF_Msk (0x10000UL) /*!< OVIF (Bitfield-Mask: 0x01) */ +#define TIM_SR_UDIF_Pos (17UL) /*!< UDIF (Bit 17) */ +#define TIM_SR_UDIF_Msk (0x20000UL) /*!< UDIF (Bitfield-Mask: 0x01) */ +#define TIM_SR_CCD4IF_Pos (18UL) /*!< CCD4IF (Bit 18) */ +#define TIM_SR_CCD4IF_Msk (0x40000UL) /*!< CCD4IF (Bitfield-Mask: 0x01) */ +/* ========================================================== EGR ========================================================== */ +#define TIM_EGR_UG_Pos (0UL) /*!< UG (Bit 0) */ +#define TIM_EGR_UG_Msk (0x1UL) /*!< UG (Bitfield-Mask: 0x01) */ +#define TIM_EGR_CC1G_Pos (1UL) /*!< CC1G (Bit 1) */ +#define TIM_EGR_CC1G_Msk (0x2UL) /*!< CC1G (Bitfield-Mask: 0x01) */ +#define TIM_EGR_CC2G_Pos (2UL) /*!< CC2G (Bit 2) */ +#define TIM_EGR_CC2G_Msk (0x4UL) /*!< CC2G (Bitfield-Mask: 0x01) */ +#define TIM_EGR_CC3G_Pos (3UL) /*!< CC3G (Bit 3) */ +#define TIM_EGR_CC3G_Msk (0x8UL) /*!< CC3G (Bitfield-Mask: 0x01) */ +#define TIM_EGR_CC4G_Pos (4UL) /*!< CC4G (Bit 4) */ +#define TIM_EGR_CC4G_Msk (0x10UL) /*!< CC4G (Bitfield-Mask: 0x01) */ +#define TIM_EGR_COMG_Pos (5UL) /*!< COMG (Bit 5) */ +#define TIM_EGR_COMG_Msk (0x20UL) /*!< COMG (Bitfield-Mask: 0x01) */ +#define TIM_EGR_TG_Pos (6UL) /*!< TG (Bit 6) */ +#define TIM_EGR_TG_Msk (0x40UL) /*!< TG (Bitfield-Mask: 0x01) */ +#define TIM_EGR_BG_Pos (7UL) /*!< BG (Bit 7) */ +#define TIM_EGR_BG_Msk (0x80UL) /*!< BG (Bitfield-Mask: 0x01) */ +/* ===================================================== CCMR1_OUTPUT ====================================================== */ +#define TIM_CCMR1_OUTPUT_CC1S_Pos (0UL) /*!< CC1S (Bit 0) */ +#define TIM_CCMR1_OUTPUT_CC1S_Msk (0x3UL) /*!< CC1S (Bitfield-Mask: 0x03) */ +#define TIM_CCMR1_OUTPUT_OC1FE_Pos (2UL) /*!< OC1FE (Bit 2) */ +#define TIM_CCMR1_OUTPUT_OC1FE_Msk (0x4UL) /*!< OC1FE (Bitfield-Mask: 0x01) */ +#define TIM_CCMR1_OUTPUT_OC1PE_Pos (3UL) /*!< OC1PE (Bit 3) */ +#define TIM_CCMR1_OUTPUT_OC1PE_Msk (0x8UL) /*!< OC1PE (Bitfield-Mask: 0x01) */ +#define TIM_CCMR1_OUTPUT_OC1M_Pos (4UL) /*!< OC1M (Bit 4) */ +#define TIM_CCMR1_OUTPUT_OC1M_Msk (0x70UL) /*!< OC1M (Bitfield-Mask: 0x07) */ +#define TIM_CCMR1_OUTPUT_OC1CE_Pos (7UL) /*!< OC1CE (Bit 7) */ +#define TIM_CCMR1_OUTPUT_OC1CE_Msk (0x80UL) /*!< OC1CE (Bitfield-Mask: 0x01) */ +#define TIM_CCMR1_OUTPUT_CC2S_Pos (8UL) /*!< CC2S (Bit 8) */ +#define TIM_CCMR1_OUTPUT_CC2S_Msk (0x300UL) /*!< CC2S (Bitfield-Mask: 0x03) */ +#define TIM_CCMR1_OUTPUT_OC2FE_Pos (10UL) /*!< OC2FE (Bit 10) */ +#define TIM_CCMR1_OUTPUT_OC2FE_Msk (0x400UL) /*!< OC2FE (Bitfield-Mask: 0x01) */ +#define TIM_CCMR1_OUTPUT_OC2PE_Pos (11UL) /*!< OC2PE (Bit 11) */ +#define TIM_CCMR1_OUTPUT_OC2PE_Msk (0x800UL) /*!< OC2PE (Bitfield-Mask: 0x01) */ +#define TIM_CCMR1_OUTPUT_OC2M_Pos (12UL) /*!< OC2M (Bit 12) */ +#define TIM_CCMR1_OUTPUT_OC2M_Msk (0x7000UL) /*!< OC2M (Bitfield-Mask: 0x07) */ +#define TIM_CCMR1_OUTPUT_OC2CE_Pos (15UL) /*!< OC2CE (Bit 15) */ +#define TIM_CCMR1_OUTPUT_OC2CE_Msk (0x8000UL) /*!< OC2CE (Bitfield-Mask: 0x01) */ +/* ====================================================== CCMR1_INPUT ====================================================== */ +#define TIM_CCMR1_INPUT_CC1S_Pos (0UL) /*!< CC1S (Bit 0) */ +#define TIM_CCMR1_INPUT_CC1S_Msk (0x3UL) /*!< CC1S (Bitfield-Mask: 0x03) */ +#define TIM_CCMR1_INPUT_IC1PSC_Pos (2UL) /*!< IC1PSC (Bit 2) */ +#define TIM_CCMR1_INPUT_IC1PSC_Msk (0xcUL) /*!< IC1PSC (Bitfield-Mask: 0x03) */ +#define TIM_CCMR1_INPUT_IC1F_Pos (4UL) /*!< IC1F (Bit 4) */ +#define TIM_CCMR1_INPUT_IC1F_Msk (0xf0UL) /*!< IC1F (Bitfield-Mask: 0x0f) */ +#define TIM_CCMR1_INPUT_CC2S_Pos (8UL) /*!< CC2S (Bit 8) */ +#define TIM_CCMR1_INPUT_CC2S_Msk (0x300UL) /*!< CC2S (Bitfield-Mask: 0x03) */ +#define TIM_CCMR1_INPUT_IC2PSC_Pos (10UL) /*!< IC2PSC (Bit 10) */ +#define TIM_CCMR1_INPUT_IC2PSC_Msk (0xc00UL) /*!< IC2PSC (Bitfield-Mask: 0x03) */ +#define TIM_CCMR1_INPUT_IC2F_Pos (12UL) /*!< IC2F (Bit 12) */ +#define TIM_CCMR1_INPUT_IC2F_Msk (0xf000UL) /*!< IC2F (Bitfield-Mask: 0x0f) */ +/* ===================================================== CCMR2_OUTPUT ====================================================== */ +#define TIM_CCMR2_OUTPUT_CC3S_Pos (0UL) /*!< CC3S (Bit 0) */ +#define TIM_CCMR2_OUTPUT_CC3S_Msk (0x3UL) /*!< CC3S (Bitfield-Mask: 0x03) */ +#define TIM_CCMR2_OUTPUT_OC3FE_Pos (2UL) /*!< OC3FE (Bit 2) */ +#define TIM_CCMR2_OUTPUT_OC3FE_Msk (0x4UL) /*!< OC3FE (Bitfield-Mask: 0x01) */ +#define TIM_CCMR2_OUTPUT_OC3PE_Pos (3UL) /*!< OC3PE (Bit 3) */ +#define TIM_CCMR2_OUTPUT_OC3PE_Msk (0x8UL) /*!< OC3PE (Bitfield-Mask: 0x01) */ +#define TIM_CCMR2_OUTPUT_OC3M_Pos (4UL) /*!< OC3M (Bit 4) */ +#define TIM_CCMR2_OUTPUT_OC3M_Msk (0x70UL) /*!< OC3M (Bitfield-Mask: 0x07) */ +#define TIM_CCMR2_OUTPUT_OC3CE_Pos (7UL) /*!< OC3CE (Bit 7) */ +#define TIM_CCMR2_OUTPUT_OC3CE_Msk (0x80UL) /*!< OC3CE (Bitfield-Mask: 0x01) */ +#define TIM_CCMR2_OUTPUT_CC4S_Pos (8UL) /*!< CC4S (Bit 8) */ +#define TIM_CCMR2_OUTPUT_CC4S_Msk (0x300UL) /*!< CC4S (Bitfield-Mask: 0x03) */ +#define TIM_CCMR2_OUTPUT_OC4FE_Pos (10UL) /*!< OC4FE (Bit 10) */ +#define TIM_CCMR2_OUTPUT_OC4FE_Msk (0x400UL) /*!< OC4FE (Bitfield-Mask: 0x01) */ +#define TIM_CCMR2_OUTPUT_OC4PE_Pos (11UL) /*!< OC4PE (Bit 11) */ +#define TIM_CCMR2_OUTPUT_OC4PE_Msk (0x800UL) /*!< OC4PE (Bitfield-Mask: 0x01) */ +#define TIM_CCMR2_OUTPUT_OC4M_Pos (12UL) /*!< OC4M (Bit 12) */ +#define TIM_CCMR2_OUTPUT_OC4M_Msk (0x7000UL) /*!< OC4M (Bitfield-Mask: 0x07) */ +#define TIM_CCMR2_OUTPUT_OC4CE_Pos (15UL) /*!< OC4CE (Bit 15) */ +#define TIM_CCMR2_OUTPUT_OC4CE_Msk (0x8000UL) /*!< OC4CE (Bitfield-Mask: 0x01) */ +/* ====================================================== CCMR2_INPUT ====================================================== */ +#define TIM_CCMR2_INPUT_CC3S_Pos (0UL) /*!< CC3S (Bit 0) */ +#define TIM_CCMR2_INPUT_CC3S_Msk (0x3UL) /*!< CC3S (Bitfield-Mask: 0x03) */ +#define TIM_CCMR2_INPUT_IC3PSC_Pos (2UL) /*!< IC3PSC (Bit 2) */ +#define TIM_CCMR2_INPUT_IC3PSC_Msk (0xcUL) /*!< IC3PSC (Bitfield-Mask: 0x03) */ +#define TIM_CCMR2_INPUT_IC3F_Pos (4UL) /*!< IC3F (Bit 4) */ +#define TIM_CCMR2_INPUT_IC3F_Msk (0xf0UL) /*!< IC3F (Bitfield-Mask: 0x0f) */ +#define TIM_CCMR2_INPUT_CC4S_Pos (8UL) /*!< CC4S (Bit 8) */ +#define TIM_CCMR2_INPUT_CC4S_Msk (0x300UL) /*!< CC4S (Bitfield-Mask: 0x03) */ +#define TIM_CCMR2_INPUT_IC4PSC_Pos (10UL) /*!< IC4PSC (Bit 10) */ +#define TIM_CCMR2_INPUT_IC4PSC_Msk (0xc00UL) /*!< IC4PSC (Bitfield-Mask: 0x03) */ +#define TIM_CCMR2_INPUT_IC4F_Pos (12UL) /*!< IC4F (Bit 12) */ +#define TIM_CCMR2_INPUT_IC4F_Msk (0xf000UL) /*!< IC4F (Bitfield-Mask: 0x0f) */ +/* ========================================================= CCER ========================================================== */ +#define TIM_CCER_CC1E_Pos (0UL) /*!< CC1E (Bit 0) */ +#define TIM_CCER_CC1E_Msk (0x1UL) /*!< CC1E (Bitfield-Mask: 0x01) */ +#define TIM_CCER_CC1P_Pos (1UL) /*!< CC1P (Bit 1) */ +#define TIM_CCER_CC1P_Msk (0x2UL) /*!< CC1P (Bitfield-Mask: 0x01) */ +#define TIM_CCER_CC1NE_Pos (2UL) /*!< CC1NE (Bit 2) */ +#define TIM_CCER_CC1NE_Msk (0x4UL) /*!< CC1NE (Bitfield-Mask: 0x01) */ +#define TIM_CCER_CC1NP_Pos (3UL) /*!< CC1NP (Bit 3) */ +#define TIM_CCER_CC1NP_Msk (0x8UL) /*!< CC1NP (Bitfield-Mask: 0x01) */ +#define TIM_CCER_CC2E_Pos (4UL) /*!< CC2E (Bit 4) */ +#define TIM_CCER_CC2E_Msk (0x10UL) /*!< CC2E (Bitfield-Mask: 0x01) */ +#define TIM_CCER_CC2P_Pos (5UL) /*!< CC2P (Bit 5) */ +#define TIM_CCER_CC2P_Msk (0x20UL) /*!< CC2P (Bitfield-Mask: 0x01) */ +#define TIM_CCER_CC2NE_Pos (6UL) /*!< CC2NE (Bit 6) */ +#define TIM_CCER_CC2NE_Msk (0x40UL) /*!< CC2NE (Bitfield-Mask: 0x01) */ +#define TIM_CCER_CC2NP_Pos (7UL) /*!< CC2NP (Bit 7) */ +#define TIM_CCER_CC2NP_Msk (0x80UL) /*!< CC2NP (Bitfield-Mask: 0x01) */ +#define TIM_CCER_CC3E_Pos (8UL) /*!< CC3E (Bit 8) */ +#define TIM_CCER_CC3E_Msk (0x100UL) /*!< CC3E (Bitfield-Mask: 0x01) */ +#define TIM_CCER_CC3P_Pos (9UL) /*!< CC3P (Bit 9) */ +#define TIM_CCER_CC3P_Msk (0x200UL) /*!< CC3P (Bitfield-Mask: 0x01) */ +#define TIM_CCER_CC3NE_Pos (10UL) /*!< CC3NE (Bit 10) */ +#define TIM_CCER_CC3NE_Msk (0x400UL) /*!< CC3NE (Bitfield-Mask: 0x01) */ +#define TIM_CCER_CC3NP_Pos (11UL) /*!< CC3NP (Bit 11) */ +#define TIM_CCER_CC3NP_Msk (0x800UL) /*!< CC3NP (Bitfield-Mask: 0x01) */ +#define TIM_CCER_CC4E_Pos (12UL) /*!< CC4E (Bit 12) */ +#define TIM_CCER_CC4E_Msk (0x1000UL) /*!< CC4E (Bitfield-Mask: 0x01) */ +#define TIM_CCER_CC4P_Pos (13UL) /*!< CC4P (Bit 13) */ +#define TIM_CCER_CC4P_Msk (0x2000UL) /*!< CC4P (Bitfield-Mask: 0x01) */ +/* ========================================================== CNT ========================================================== */ +#define TIM_CNT_CNT_Pos (0UL) /*!< CNT (Bit 0) */ +#define TIM_CNT_CNT_Msk (0xffffUL) /*!< CNT (Bitfield-Mask: 0xffff) */ +/* ========================================================== PSC ========================================================== */ +#define TIM_PSC_PSC_Pos (0UL) /*!< PSC (Bit 0) */ +#define TIM_PSC_PSC_Msk (0xffffUL) /*!< PSC (Bitfield-Mask: 0xffff) */ +/* ========================================================== ARR ========================================================== */ +#define TIM_ARR_ARR_Pos (0UL) /*!< ARR (Bit 0) */ +#define TIM_ARR_ARR_Msk (0xffffUL) /*!< ARR (Bitfield-Mask: 0xffff) */ +/* ========================================================== RCR ========================================================== */ +#define TIM_RCR_REP_Pos (0UL) /*!< REP (Bit 0) */ +#define TIM_RCR_REP_Msk (0xffUL) /*!< REP (Bitfield-Mask: 0xff) */ +/* ========================================================= CCR1 ========================================================== */ +#define TIM_CCR1_CCR1_Pos (0UL) /*!< CCR1 (Bit 0) */ +#define TIM_CCR1_CCR1_Msk (0xfffffUL) /*!< CCR1 (Bitfield-Mask: 0xfffff) */ +/* ========================================================= CCR2 ========================================================== */ +#define TIM_CCR2_CCR2_Pos (0UL) /*!< CCR2 (Bit 0) */ +#define TIM_CCR2_CCR2_Msk (0xfffffUL) /*!< CCR2 (Bitfield-Mask: 0xfffff) */ +/* ========================================================= CCR3 ========================================================== */ +#define TIM_CCR3_CCR3_Pos (0UL) /*!< CCR3 (Bit 0) */ +#define TIM_CCR3_CCR3_Msk (0xfffffUL) /*!< CCR3 (Bitfield-Mask: 0xfffff) */ +/* ========================================================= CCR4 ========================================================== */ +#define TIM_CCR4_CCR4_Pos (0UL) /*!< CCR4 (Bit 0) */ +#define TIM_CCR4_CCR4_Msk (0xfffffUL) /*!< CCR4 (Bitfield-Mask: 0xfffff) */ +/* ========================================================= BDTR ========================================================== */ +#define TIM_BDTR_DTG_Pos (0UL) /*!< DTG (Bit 0) */ +#define TIM_BDTR_DTG_Msk (0xffUL) /*!< DTG (Bitfield-Mask: 0xff) */ +#define TIM_BDTR_LOCK_Pos (8UL) /*!< LOCK (Bit 8) */ +#define TIM_BDTR_LOCK_Msk (0x300UL) /*!< LOCK (Bitfield-Mask: 0x03) */ +#define TIM_BDTR_OSSI_Pos (10UL) /*!< OSSI (Bit 10) */ +#define TIM_BDTR_OSSI_Msk (0x400UL) /*!< OSSI (Bitfield-Mask: 0x01) */ +#define TIM_BDTR_OSSR_Pos (11UL) /*!< OSSR (Bit 11) */ +#define TIM_BDTR_OSSR_Msk (0x800UL) /*!< OSSR (Bitfield-Mask: 0x01) */ +#define TIM_BDTR_BKE_Pos (12UL) /*!< BKE (Bit 12) */ +#define TIM_BDTR_BKE_Msk (0x1000UL) /*!< BKE (Bitfield-Mask: 0x01) */ +#define TIM_BDTR_BKP_Pos (13UL) /*!< BKP (Bit 13) */ +#define TIM_BDTR_BKP_Msk (0x2000UL) /*!< BKP (Bitfield-Mask: 0x01) */ +#define TIM_BDTR_AOE_Pos (14UL) /*!< AOE (Bit 14) */ +#define TIM_BDTR_AOE_Msk (0x4000UL) /*!< AOE (Bitfield-Mask: 0x01) */ +#define TIM_BDTR_MOE_Pos (15UL) /*!< MOE (Bit 15) */ +#define TIM_BDTR_MOE_Msk (0x8000UL) /*!< MOE (Bitfield-Mask: 0x01) */ +#define TIM_BDTR_DTGF_Pos (16UL) /*!< DTGF (Bit 16) */ +#define TIM_BDTR_DTGF_Msk (0xff0000UL) /*!< DTGF (Bitfield-Mask: 0xff) */ +#define TIM_BDTR_DTAE_Pos (24UL) /*!< DTAE (Bit 24) */ +#define TIM_BDTR_DTAE_Msk (0x1000000UL) /*!< DTAE (Bitfield-Mask: 0x01) */ +/* ========================================================= CCDR1 ========================================================= */ +#define TIM_CCDR1_CCDR1_Pos (0UL) /*!< CCDR1 (Bit 0) */ +#define TIM_CCDR1_CCDR1_Msk (0xfffffUL) /*!< CCDR1 (Bitfield-Mask: 0xfffff) */ +/* ========================================================= CCDR2 ========================================================= */ +#define TIM_CCDR2_CCDR2_Pos (0UL) /*!< CCDR2 (Bit 0) */ +#define TIM_CCDR2_CCDR2_Msk (0xfffffUL) /*!< CCDR2 (Bitfield-Mask: 0xfffff) */ +/* ========================================================= CCDR3 ========================================================= */ +#define TIM_CCDR3_CCDR3_Pos (0UL) /*!< CCDR3 (Bit 0) */ +#define TIM_CCDR3_CCDR3_Msk (0xfffffUL) /*!< CCDR3 (Bitfield-Mask: 0xfffff) */ +/* ========================================================= CCDR4 ========================================================= */ +#define TIM_CCDR4_CCDR4_Pos (0UL) /*!< CCDR4 (Bit 0) */ +#define TIM_CCDR4_CCDR4_Msk (0xfffffUL) /*!< CCDR4 (Bitfield-Mask: 0xfffff) */ + + +/* =========================================================================================================================== */ +/* ================ LPTIM ================ */ +/* =========================================================================================================================== */ + +/* ========================================================== IR =========================================================== */ +#define LPTIM_IR_MR0_Pos (0UL) /*!< MR0 (Bit 0) */ +#define LPTIM_IR_MR0_Msk (0x1UL) /*!< MR0 (Bitfield-Mask: 0x01) */ +/* ========================================================== TCR ========================================================== */ +#define LPTIM_TCR_CEN_Pos (0UL) /*!< CEN (Bit 0) */ +#define LPTIM_TCR_CEN_Msk (0x1UL) /*!< CEN (Bitfield-Mask: 0x01) */ +#define LPTIM_TCR_CRST_Pos (1UL) /*!< CRST (Bit 1) */ +#define LPTIM_TCR_CRST_Msk (0x2UL) /*!< CRST (Bitfield-Mask: 0x01) */ +#define LPTIM_TCR_CLKS_Pos (2UL) /*!< CLKS (Bit 2) */ +#define LPTIM_TCR_CLKS_Msk (0xcUL) /*!< CLKS (Bitfield-Mask: 0x03) */ +#define LPTIM_TCR_TRIGSEL_Pos (4UL) /*!< TRIGSEL (Bit 4) */ +#define LPTIM_TCR_TRIGSEL_Msk (0x70UL) /*!< TRIGSEL (Bitfield-Mask: 0x07) */ +/* ========================================================== TC =========================================================== */ +#define LPTIM_TC_TC_Pos (0UL) /*!< TC (Bit 0) */ +#define LPTIM_TC_TC_Msk (0xffffUL) /*!< TC (Bitfield-Mask: 0xffff) */ +/* ========================================================== PR =========================================================== */ +#define LPTIM_PR_PR_Pos (0UL) /*!< PR (Bit 0) */ +#define LPTIM_PR_PR_Msk (0xffUL) /*!< PR (Bitfield-Mask: 0xff) */ +/* ========================================================== PC =========================================================== */ +#define LPTIM_PC_PC_Pos (0UL) /*!< PC (Bit 0) */ +#define LPTIM_PC_PC_Msk (0xffUL) /*!< PC (Bitfield-Mask: 0xff) */ +/* ========================================================== MCR ========================================================== */ +#define LPTIM_MCR_MR0INT_Pos (0UL) /*!< MR0INT (Bit 0) */ +#define LPTIM_MCR_MR0INT_Msk (0x1UL) /*!< MR0INT (Bitfield-Mask: 0x01) */ +#define LPTIM_MCR_MR0RST_Pos (1UL) /*!< MR0RST (Bit 1) */ +#define LPTIM_MCR_MR0RST_Msk (0x2UL) /*!< MR0RST (Bitfield-Mask: 0x01) */ +#define LPTIM_MCR_MR0STOP_Pos (2UL) /*!< MR0STOP (Bit 2) */ +#define LPTIM_MCR_MR0STOP_Msk (0x4UL) /*!< MR0STOP (Bitfield-Mask: 0x01) */ +/* ========================================================== MR0 ========================================================== */ +#define LPTIM_MR0_MR0_Pos (0UL) /*!< MR0 (Bit 0) */ +#define LPTIM_MR0_MR0_Msk (0xffffUL) /*!< MR0 (Bitfield-Mask: 0xffff) */ + +/** @} */ /* End of group PosMask_peripherals */ + + +/* =========================================================================================================================== */ +/* ================ Enumerated Values Peripheral Section ================ */ +/* =========================================================================================================================== */ + + +/** @addtogroup EnumValue_peripherals + * @{ + */ + + + +/* =========================================================================================================================== */ +/* ================ EFLASH_MEM ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= DATA0 ========================================================= */ +/* ======================================================= DATA_END ======================================================== */ + + +/* =========================================================================================================================== */ +/* ================ SRAM_MEM ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= DATA0 ========================================================= */ +/* ======================================================= DATA_END ======================================================== */ + + +/* =========================================================================================================================== */ +/* ================ NVR_MEM ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= DATA0 ========================================================= */ +/* ======================================================= DATA_END ======================================================== */ + + +/* =========================================================================================================================== */ +/* ================ CORET ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= revd ========================================================== */ + + +/* =========================================================================================================================== */ +/* ================ UID ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= UID1 ========================================================== */ +/* ========================================================= UID2 ========================================================== */ +/* ========================================================= UID3 ========================================================== */ + + +/* =========================================================================================================================== */ +/* ================ FLASH ================ */ +/* =========================================================================================================================== */ + +/* ========================================================== CMD ========================================================== */ +/* ================================================= FLASH CMD CMD [1..3] ================================================== */ +typedef enum { /*!< FLASH_CMD_CMD */ + FLASH_CMD_CMD_PROG = 0, /*!< PROG : Flash 32-bits program */ + FLASH_CMD_CMD_ERASE_SECTOR = 1, /*!< ERASE_SECTOR : Flash sector erase */ + FLASH_CMD_CMD_ERASE_CHIP = 2, /*!< ERASE_CHIP : Flash chip erase */ +} FLASH_CMD_CMD_Enum; + +/* ========================================================== SR =========================================================== */ +/* ========================================================== AR =========================================================== */ +/* ========================================================== DR =========================================================== */ +/* ========================================================== ACM ========================================================== */ +/* ========================================================== DIV ========================================================== */ + + +/* =========================================================================================================================== */ +/* ================ GPIO ================ */ +/* =========================================================================================================================== */ + +/* ========================================================== DAT ========================================================== */ +/* ========================================================== LAT ========================================================== */ +/* ========================================================= ITS1 ========================================================== */ +/* ========================================================= ITC1 ========================================================== */ +/* ========================================================== OES ========================================================== */ +/* ========================================================== OEC ========================================================== */ +/* ========================================================= INES ========================================================== */ +/* ========================================================= INEC ========================================================== */ +/* ========================================================== IES ========================================================== */ +/* ========================================================== IEC ========================================================== */ +/* ========================================================= ITS0 ========================================================== */ +/* ========================================================= ITC0 ========================================================== */ +/* ========================================================== PLS ========================================================== */ +/* ========================================================== PLC ========================================================== */ +/* ========================================================== IST ========================================================== */ +/* ========================================================== PUS ========================================================== */ +/* ========================================================== PUC ========================================================== */ +/* ========================================================== ODS ========================================================== */ +/* ========================================================== ODC ========================================================== */ +/* ========================================================== PDS ========================================================== */ +/* ========================================================== PDC ========================================================== */ +/* ========================================================= OSRS ========================================================== */ +/* ========================================================= OSRC ========================================================== */ +/* ========================================================== CTS ========================================================== */ +/* ========================================================== CTC ========================================================== */ + + +/* =========================================================================================================================== */ +/* ================ AFIO ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= PAAFR ========================================================= */ +/* ========================================================= PBAFR ========================================================= */ +/* ======================================================== FN1_AFR ======================================================== */ +/* ======================================================== FN2_AFR ======================================================== */ + + +/* =========================================================================================================================== */ +/* ================ SYSCFG ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= PMUCR ========================================================= */ +/* ========================================================= MCOCR ========================================================= */ +/* ============================================== SYSCFG MCOCR MCOSEL [0..2] =============================================== */ +typedef enum { /*!< SYSCFG_MCOCR_MCOSEL */ + SYSCFG_MCOCR_MCOSEL_HSI = 0, /*!< HSI : HSI RC clock */ + SYSCFG_MCOCR_MCOSEL_HSE = 1, /*!< HSE : HSE OSC clock */ + SYSCFG_MCOCR_MCOSEL_CLKDIV = 2, /*!< CLKDIV : HSI Clock Divider */ + SYSCFG_MCOCR_MCOSEL_LSI = 3, /*!< LSI : LSI RC clock */ + SYSCFG_MCOCR_MCOSEL_FCLK = 4, /*!< FCLK : F clock */ + SYSCFG_MCOCR_MCOSEL_GND = 7, /*!< GND : Peripheral clock */ +} SYSCFG_MCOCR_MCOSEL_Enum; + +/* ============================================= SYSCFG MCOCR SWRstEn [16..23] ============================================= */ +typedef enum { /*!< SYSCFG_MCOCR_SWRstEn */ + SYSCFG_MCOCR_SWRstEn_OFF = 0, /*!< OFF : Software reset off */ + SYSCFG_MCOCR_SWRstEn_ON = 90, /*!< ON : Software reset on */ +} SYSCFG_MCOCR_SWRstEn_Enum; + +/* ======================================================= SYSRSTSR ======================================================== */ +/* ===================================================== REBOOT_UNLOCK ===================================================== */ +/* ======================================================= SYSRSTCR ======================================================== */ +/* ======================================================= DEBUGENCR ======================================================= */ +/* ======================================================= SYSCLKCR ======================================================== */ +/* ============================================= SYSCFG SYSCLKCR CLKSW [0..2] ============================================== */ +typedef enum { /*!< SYSCFG_SYSCLKCR_CLKSW */ + SYSCFG_SYSCLKCR_CLKSW_HSI = 0, /*!< HSI : HSI RC clock source */ + SYSCFG_SYSCLKCR_CLKSW_HSE = 1, /*!< HSE : HSE OSC clock source */ + SYSCFG_SYSCLKCR_CLKSW_CLKDIV = 2, /*!< CLKDIV : Clock Divider source */ + SYSCFG_SYSCLKCR_CLKSW_LSI = 3, /*!< LSI : LSI RC clock source */ +} SYSCFG_SYSCLKCR_CLKSW_Enum; + +/* ========================================== SYSCFG SYSCLKCR SYSTICKCR [24..25] =========================================== */ +typedef enum { /*!< SYSCFG_SYSCLKCR_SYSTICKCR */ + SYSCFG_SYSCLKCR_SYSTICKCR_LSI = 0, /*!< LSI : Systick from LSI */ + SYSCFG_SYSCLKCR_SYSTICKCR_HSI_DIV2 = 1, /*!< HSI_DIV2 : Systick from HSI Divide 2 */ + SYSCFG_SYSCLKCR_SYSTICKCR_HSI_DIV4 = 2, /*!< HSI_DIV4 : Systick from HSI Divide 4 */ + SYSCFG_SYSCLKCR_SYSTICKCR_HSI_DIV8 = 3, /*!< HSI_DIV8 : Systick from HSI Divide 8 */ +} SYSCFG_SYSCLKCR_SYSTICKCR_Enum; + +/* ======================================================== PRSTEN ========================================================= */ +/* ======================================================== PCLKEN ========================================================= */ +/* ======================================================== ICEIOCR ======================================================== */ +/* ======================================================= RSTPINCR ======================================================== */ +/* =========================================== SYSCFG RSTPINCR RSTPINAF [0..15] ============================================ */ +typedef enum { /*!< SYSCFG_RSTPINCR_RSTPINAF */ + SYSCFG_RSTPINCR_RSTPINAF_ON = 42339, /*!< ON : Enable reset pin */ + SYSCFG_RSTPINCR_RSTPINAF_OFF = 0, /*!< OFF : Disable reset pin (Pin changes to I/O) */ +} SYSCFG_RSTPINCR_RSTPINAF_Enum; + +/* ===================================================== TIM2_CON_SEL ====================================================== */ +/* ============================================ SYSCFG TIM2_CON_SEL CH1 [0..2] ============================================= */ +typedef enum { /*!< SYSCFG_TIM2_CON_SEL_CH1 */ + SYSCFG_TIM2_CON_SEL_CH1_PAD = 0, /*!< PAD : From PAD */ + SYSCFG_TIM2_CON_SEL_CH1_UART = 1, /*!< UART : From UART0_RXD */ + SYSCFG_TIM2_CON_SEL_CH1_IIC = 2, /*!< IIC : From IIC_SDA */ + SYSCFG_TIM2_CON_SEL_CH1_OSC32K = 4, /*!< OSC32K : From OSC_32K */ +} SYSCFG_TIM2_CON_SEL_CH1_Enum; + +/* ============================================ SYSCFG TIM2_CON_SEL CH2 [4..6] ============================================= */ +typedef enum { /*!< SYSCFG_TIM2_CON_SEL_CH2 */ + SYSCFG_TIM2_CON_SEL_CH2_PAD = 0, /*!< PAD : From PAD */ + SYSCFG_TIM2_CON_SEL_CH2_UART = 1, /*!< UART : From UART0_RXD */ + SYSCFG_TIM2_CON_SEL_CH2_IIC = 2, /*!< IIC : From IIC_SDA */ + SYSCFG_TIM2_CON_SEL_CH2_OSC32K = 4, /*!< OSC32K : From OSC_32K */ +} SYSCFG_TIM2_CON_SEL_CH2_Enum; + +/* ============================================ SYSCFG TIM2_CON_SEL CH3 [8..10] ============================================ */ +typedef enum { /*!< SYSCFG_TIM2_CON_SEL_CH3 */ + SYSCFG_TIM2_CON_SEL_CH3_PAD = 0, /*!< PAD : From PAD */ + SYSCFG_TIM2_CON_SEL_CH3_UART = 1, /*!< UART : From UART0_RXD */ + SYSCFG_TIM2_CON_SEL_CH3_IIC = 2, /*!< IIC : From IIC_SDA */ + SYSCFG_TIM2_CON_SEL_CH3_OSC32K = 4, /*!< OSC32K : From OSC_32K */ +} SYSCFG_TIM2_CON_SEL_CH3_Enum; + +/* =========================================== SYSCFG TIM2_CON_SEL CH4 [12..14] ============================================ */ +typedef enum { /*!< SYSCFG_TIM2_CON_SEL_CH4 */ + SYSCFG_TIM2_CON_SEL_CH4_PAD = 0, /*!< PAD : From PAD */ + SYSCFG_TIM2_CON_SEL_CH4_UART = 1, /*!< UART : From UART0_RXD */ + SYSCFG_TIM2_CON_SEL_CH4_IIC = 2, /*!< IIC : From IIC_SDA */ + SYSCFG_TIM2_CON_SEL_CH4_OSC32K = 4, /*!< OSC32K : From OSC_32K */ +} SYSCFG_TIM2_CON_SEL_CH4_Enum; + +/* ======================================== SYSCFG TIM2_CON_SEL VC_CH1_INV [20..20] ======================================== */ +typedef enum { /*!< SYSCFG_TIM2_CON_SEL_VC_CH1_INV */ + SYSCFG_TIM2_CON_SEL_VC_CH1_INV_0 = 0, /*!< 0 : COMP */ + SYSCFG_TIM2_CON_SEL_VC_CH1_INV_1 = 1, /*!< 1 : COMP Inverse */ +} SYSCFG_TIM2_CON_SEL_VC_CH1_INV_Enum; + +/* ========================================== SYSCFG TIM2_CON_SEL VC_CH1 [21..21] ========================================== */ +typedef enum { /*!< SYSCFG_TIM2_CON_SEL_VC_CH1 */ + SYSCFG_TIM2_CON_SEL_VC_CH1_0 = 0, /*!< 0 : COMP(Used in conjunction with Vc_ch1_inv)) */ + SYSCFG_TIM2_CON_SEL_VC_CH1_1 = 1, /*!< 1 : CH1_CON[2:0] */ +} SYSCFG_TIM2_CON_SEL_VC_CH1_Enum; + +/* ======================================== SYSCFG TIM2_CON_SEL VC_CH2_INV [22..22] ======================================== */ +typedef enum { /*!< SYSCFG_TIM2_CON_SEL_VC_CH2_INV */ + SYSCFG_TIM2_CON_SEL_VC_CH2_INV_0 = 0, /*!< 0 : COMP */ + SYSCFG_TIM2_CON_SEL_VC_CH2_INV_1 = 1, /*!< 1 : COMP Inverse */ +} SYSCFG_TIM2_CON_SEL_VC_CH2_INV_Enum; + +/* ========================================== SYSCFG TIM2_CON_SEL VC_CH2 [23..23] ========================================== */ +typedef enum { /*!< SYSCFG_TIM2_CON_SEL_VC_CH2 */ + SYSCFG_TIM2_CON_SEL_VC_CH2_0 = 0, /*!< 0 : COMP(Used in conjunction with Vc_CH2_inv)) */ + SYSCFG_TIM2_CON_SEL_VC_CH2_1 = 1, /*!< 1 : CH2_CON[6:4] */ +} SYSCFG_TIM2_CON_SEL_VC_CH2_Enum; + +/* ======================================== SYSCFG TIM2_CON_SEL VC_CH3_INV [24..24] ======================================== */ +typedef enum { /*!< SYSCFG_TIM2_CON_SEL_VC_CH3_INV */ + SYSCFG_TIM2_CON_SEL_VC_CH3_INV_0 = 0, /*!< 0 : COMP */ + SYSCFG_TIM2_CON_SEL_VC_CH3_INV_1 = 1, /*!< 1 : COMP Inverse */ +} SYSCFG_TIM2_CON_SEL_VC_CH3_INV_Enum; + +/* ========================================== SYSCFG TIM2_CON_SEL VC_CH3 [25..25] ========================================== */ +typedef enum { /*!< SYSCFG_TIM2_CON_SEL_VC_CH3 */ + SYSCFG_TIM2_CON_SEL_VC_CH3_0 = 0, /*!< 0 : COMP(Used in conjunction with Vc_CH3_inv)) */ + SYSCFG_TIM2_CON_SEL_VC_CH3_1 = 1, /*!< 1 : CH3_CON[[10:8] */ +} SYSCFG_TIM2_CON_SEL_VC_CH3_Enum; + +/* ======================================== SYSCFG TIM2_CON_SEL VC_CH4_INV [26..26] ======================================== */ +typedef enum { /*!< SYSCFG_TIM2_CON_SEL_VC_CH4_INV */ + SYSCFG_TIM2_CON_SEL_VC_CH4_INV_0 = 0, /*!< 0 : COMP */ + SYSCFG_TIM2_CON_SEL_VC_CH4_INV_1 = 1, /*!< 1 : COMP Inverse */ +} SYSCFG_TIM2_CON_SEL_VC_CH4_INV_Enum; + +/* ========================================== SYSCFG TIM2_CON_SEL VC_CH4 [27..27] ========================================== */ +typedef enum { /*!< SYSCFG_TIM2_CON_SEL_VC_CH4 */ + SYSCFG_TIM2_CON_SEL_VC_CH4_0 = 0, /*!< 0 : COMP(Used in conjunction with Vc_CH4_inv)) */ + SYSCFG_TIM2_CON_SEL_VC_CH4_1 = 1, /*!< 1 : CH4_CON[14:12] */ +} SYSCFG_TIM2_CON_SEL_VC_CH4_Enum; + +/* ===================================================== EPWM_CON_SEL ====================================================== */ +/* ============================================ SYSCFG EPWM_CON_SEL CH1 [0..2] ============================================= */ +typedef enum { /*!< SYSCFG_EPWM_CON_SEL_CH1 */ + SYSCFG_EPWM_CON_SEL_CH1_PAD = 0, /*!< PAD : From PAD */ + SYSCFG_EPWM_CON_SEL_CH1_UART = 1, /*!< UART : From UART0_RXD */ + SYSCFG_EPWM_CON_SEL_CH1_IIC = 2, /*!< IIC : From IIC_SDA */ + SYSCFG_EPWM_CON_SEL_CH1_OSC32K = 4, /*!< OSC32K : From OSC_32K */ +} SYSCFG_EPWM_CON_SEL_CH1_Enum; + +/* ============================================ SYSCFG EPWM_CON_SEL CH2 [4..6] ============================================= */ +typedef enum { /*!< SYSCFG_EPWM_CON_SEL_CH2 */ + SYSCFG_EPWM_CON_SEL_CH2_PAD = 0, /*!< PAD : From PAD */ + SYSCFG_EPWM_CON_SEL_CH2_UART = 1, /*!< UART : From UART0_RXD */ + SYSCFG_EPWM_CON_SEL_CH2_IIC = 2, /*!< IIC : From IIC_SDA */ + SYSCFG_EPWM_CON_SEL_CH2_OSC32K = 4, /*!< OSC32K : From OSC_32K */ +} SYSCFG_EPWM_CON_SEL_CH2_Enum; + +/* ============================================ SYSCFG EPWM_CON_SEL CH3 [8..10] ============================================ */ +typedef enum { /*!< SYSCFG_EPWM_CON_SEL_CH3 */ + SYSCFG_EPWM_CON_SEL_CH3_PAD = 0, /*!< PAD : From PAD */ + SYSCFG_EPWM_CON_SEL_CH3_UART = 1, /*!< UART : From UART0_RXD */ + SYSCFG_EPWM_CON_SEL_CH3_IIC = 2, /*!< IIC : From IIC_SDA */ + SYSCFG_EPWM_CON_SEL_CH3_OSC32K = 4, /*!< OSC32K : From OSC_32K */ +} SYSCFG_EPWM_CON_SEL_CH3_Enum; + +/* =========================================== SYSCFG EPWM_CON_SEL CH4 [12..14] ============================================ */ +typedef enum { /*!< SYSCFG_EPWM_CON_SEL_CH4 */ + SYSCFG_EPWM_CON_SEL_CH4_PAD = 0, /*!< PAD : From PAD */ + SYSCFG_EPWM_CON_SEL_CH4_UART = 1, /*!< UART : From UART0_RXD */ + SYSCFG_EPWM_CON_SEL_CH4_IIC = 2, /*!< IIC : From IIC_SDA */ + SYSCFG_EPWM_CON_SEL_CH4_OSC32K = 4, /*!< OSC32K : From OSC_32K */ +} SYSCFG_EPWM_CON_SEL_CH4_Enum; + +/* ======================================== SYSCFG EPWM_CON_SEL VC_CH1_INV [20..20] ======================================== */ +typedef enum { /*!< SYSCFG_EPWM_CON_SEL_VC_CH1_INV */ + SYSCFG_EPWM_CON_SEL_VC_CH1_INV_0 = 0, /*!< 0 : COMP */ + SYSCFG_EPWM_CON_SEL_VC_CH1_INV_1 = 1, /*!< 1 : COMP Inverse */ +} SYSCFG_EPWM_CON_SEL_VC_CH1_INV_Enum; + +/* ========================================== SYSCFG EPWM_CON_SEL VC_CH1 [21..21] ========================================== */ +typedef enum { /*!< SYSCFG_EPWM_CON_SEL_VC_CH1 */ + SYSCFG_EPWM_CON_SEL_VC_CH1_0 = 0, /*!< 0 : COMP(Used in conjunction with Vc_ch1_inv)) */ + SYSCFG_EPWM_CON_SEL_VC_CH1_1 = 1, /*!< 1 : CH1_CON[2:0] */ +} SYSCFG_EPWM_CON_SEL_VC_CH1_Enum; + +/* ======================================== SYSCFG EPWM_CON_SEL VC_CH2_INV [22..22] ======================================== */ +typedef enum { /*!< SYSCFG_EPWM_CON_SEL_VC_CH2_INV */ + SYSCFG_EPWM_CON_SEL_VC_CH2_INV_0 = 0, /*!< 0 : COMP */ + SYSCFG_EPWM_CON_SEL_VC_CH2_INV_1 = 1, /*!< 1 : COMP Inverse */ +} SYSCFG_EPWM_CON_SEL_VC_CH2_INV_Enum; + +/* ========================================== SYSCFG EPWM_CON_SEL VC_CH2 [23..23] ========================================== */ +typedef enum { /*!< SYSCFG_EPWM_CON_SEL_VC_CH2 */ + SYSCFG_EPWM_CON_SEL_VC_CH2_0 = 0, /*!< 0 : COMP(Used in conjunction with Vc_CH2_inv)) */ + SYSCFG_EPWM_CON_SEL_VC_CH2_1 = 1, /*!< 1 : CH2_CON[6:4] */ +} SYSCFG_EPWM_CON_SEL_VC_CH2_Enum; + +/* ======================================== SYSCFG EPWM_CON_SEL VC_CH3_INV [24..24] ======================================== */ +typedef enum { /*!< SYSCFG_EPWM_CON_SEL_VC_CH3_INV */ + SYSCFG_EPWM_CON_SEL_VC_CH3_INV_0 = 0, /*!< 0 : COMP */ + SYSCFG_EPWM_CON_SEL_VC_CH3_INV_1 = 1, /*!< 1 : COMP Inverse */ +} SYSCFG_EPWM_CON_SEL_VC_CH3_INV_Enum; + +/* ========================================== SYSCFG EPWM_CON_SEL VC_CH3 [25..25] ========================================== */ +typedef enum { /*!< SYSCFG_EPWM_CON_SEL_VC_CH3 */ + SYSCFG_EPWM_CON_SEL_VC_CH3_0 = 0, /*!< 0 : COMP(Used in conjunction with Vc_CH3_inv)) */ + SYSCFG_EPWM_CON_SEL_VC_CH3_1 = 1, /*!< 1 : CH3_CON[[10:8] */ +} SYSCFG_EPWM_CON_SEL_VC_CH3_Enum; + +/* ======================================== SYSCFG EPWM_CON_SEL VC_CH4_INV [26..26] ======================================== */ +typedef enum { /*!< SYSCFG_EPWM_CON_SEL_VC_CH4_INV */ + SYSCFG_EPWM_CON_SEL_VC_CH4_INV_0 = 0, /*!< 0 : COMP */ + SYSCFG_EPWM_CON_SEL_VC_CH4_INV_1 = 1, /*!< 1 : COMP Inverse */ +} SYSCFG_EPWM_CON_SEL_VC_CH4_INV_Enum; + +/* ========================================== SYSCFG EPWM_CON_SEL VC_CH4 [27..27] ========================================== */ +typedef enum { /*!< SYSCFG_EPWM_CON_SEL_VC_CH4 */ + SYSCFG_EPWM_CON_SEL_VC_CH4_0 = 0, /*!< 0 : COMP(Used in conjunction with Vc_CH4_inv)) */ + SYSCFG_EPWM_CON_SEL_VC_CH4_1 = 1, /*!< 1 : CH4_CON[14:12] */ +} SYSCFG_EPWM_CON_SEL_VC_CH4_Enum; + +/* ======================================================== PRSTEN1 ======================================================== */ +/* ======================================================== HCLKEN ========================================================= */ +/* ======================================================== EVT_SEL ======================================================== */ +/* ========================================================= NMICR ========================================================= */ +/* ================================================ SYSCFG NMICR EN [5..7] ================================================= */ +typedef enum { /*!< SYSCFG_NMICR_EN */ + SYSCFG_NMICR_EN_ON = 5, /*!< ON : Enable interrupt link to NMI */ + SYSCFG_NMICR_EN_OFF = 0, /*!< OFF : Disable interrupt link to NMI */ +} SYSCFG_NMICR_EN_Enum; + +/* ======================================================== CHIPID ========================================================= */ + + +/* =========================================================================================================================== */ +/* ================ UART ================ */ +/* =========================================================================================================================== */ + +/* ========================================================== DAT ========================================================== */ +/* ========================================================== CR =========================================================== */ +/* ================================================== UART CR MODE [0..2] ================================================== */ +typedef enum { /*!< UART_CR_MODE */ + UART_CR_MODE_8D = 1, /*!< 8D : 8-bits data */ + UART_CR_MODE_7D1P = 3, /*!< 7D1P : 7-bits data + 1-bit parity */ + UART_CR_MODE_9D = 4, /*!< 9D : 9-bits data */ + UART_CR_MODE_8D1W = 5, /*!< 8D1W : 8-bits data + 1-bit wake-up */ + UART_CR_MODE_8D1P = 7, /*!< 8D1P : 8-bits data + 1-bit parity */ +} UART_CR_MODE_Enum; + +/* ================================================= UART CR STOPB [3..4] ================================================== */ +typedef enum { /*!< UART_CR_STOPB */ + UART_CR_STOPB_0_5B = 0, /*!< 0_5B : 0.5 bit stop */ + UART_CR_STOPB_1B = 1, /*!< 1B : 1 bit stop */ + UART_CR_STOPB_1_5B = 2, /*!< 1_5B : 1.5 bits stop */ + UART_CR_STOPB_2B = 3, /*!< 2B : 2 bits stop */ +} UART_CR_STOPB_Enum; + +/* ================================================== UART CR PAR [5..5] =================================================== */ +typedef enum { /*!< UART_CR_PAR */ + UART_CR_PAR_EVEN = 0, /*!< EVEN : Even parity check */ + UART_CR_PAR_ODD = 1, /*!< ODD : Odd parity check */ +} UART_CR_PAR_Enum; + +/* ========================================================== BR =========================================================== */ +/* ========================================================== IE =========================================================== */ +/* ========================================================== SR =========================================================== */ +/* ========================================================== GTR ========================================================== */ +/* ========================================================== TOR ========================================================== */ +/* ========================================================= TXFR ========================================================== */ +/* ========================================================= RXFR ========================================================== */ + + +/* =========================================================================================================================== */ +/* ================ I2C ================ */ +/* =========================================================================================================================== */ + +/* ======================================================== CTLSET ========================================================= */ +/* ========================================================= STAT ========================================================== */ +/* ========================================================= DATA ========================================================== */ +/* ========================================================= ADDR ========================================================== */ +/* ======================================================== CTLCLR ========================================================= */ + + +/* =========================================================================================================================== */ +/* ================ SPI ================ */ +/* =========================================================================================================================== */ + +/* ========================================================== CFG ========================================================== */ +/* ========================================================== STA ========================================================== */ +/* ========================================================= INTEN ========================================================= */ +/* ======================================================== INTDIS ========================================================= */ +/* ======================================================== INTMASK ======================================================== */ +/* ========================================================== EN =========================================================== */ +/* ========================================================= DELAY ========================================================= */ +/* ========================================================== TX =========================================================== */ +/* ========================================================== RX =========================================================== */ +/* ======================================================== IDLECNT ======================================================== */ +/* ========================================================= TXTH ========================================================== */ +/* ========================================================= RXTH ========================================================== */ + + +/* =========================================================================================================================== */ +/* ================ WDG ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= LOAD ========================================================== */ +/* ========================================================= VALUE ========================================================= */ +/* ========================================================== CR =========================================================== */ +/* ================================================== WDG CR INTE [0..0] =================================================== */ +typedef enum { /*!< WDG_CR_INTE */ + WDG_CR_INTE_IRQ_OFF = 0, /*!< IRQ_OFF : WDT disable interrupt */ + WDG_CR_INTE_IRQ_ON = 1, /*!< IRQ_ON : WDT enable interrupt */ +} WDG_CR_INTE_Enum; + +/* ======================================================== INTCLR ========================================================= */ +/* ========================================================== RIS ========================================================== */ +/* ========================================================== MIS ========================================================== */ +/* ========================================================= LOCK ========================================================== */ + + +/* =========================================================================================================================== */ +/* ================ ADC ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= CON0 ========================================================== */ +/* =================================================== ADC CON0 M [0..3] =================================================== */ +typedef enum { /*!< ADC_CON0_M */ + ADC_CON0_M_AIN0 = 0, /*!< AIN0 : Input channel */ + ADC_CON0_M_AIN1 = 1, /*!< AIN1 : Input channel */ + ADC_CON0_M_AIN2 = 2, /*!< AIN2 : Input channel */ + ADC_CON0_M_AIN3 = 3, /*!< AIN3 : Input channel */ + ADC_CON0_M_AIN4 = 4, /*!< AIN4 : Input channel */ + ADC_CON0_M_AIN5 = 5, /*!< AIN5 : Input channel */ + ADC_CON0_M_AIN6 = 6, /*!< AIN6 : Input channel */ + ADC_CON0_M_AIN7 = 7, /*!< AIN7 : Input channel */ + ADC_CON0_M_AIN8 = 8, /*!< AIN8 : Input channel */ + ADC_CON0_M_AIN9 = 9, /*!< AIN9 : Input channel */ + ADC_CON0_M_AIN10 = 10, /*!< AIN10 : Input channel */ + ADC_CON0_M_AIN11 = 11, /*!< AIN11 : Input channel */ + ADC_CON0_M_AIN12 = 12, /*!< AIN12 : Input channel */ + ADC_CON0_M_AIN13 = 13, /*!< AIN13 : Input channel */ + ADC_CON0_M_AIN14 = 14, /*!< AIN14 : Input channel */ + ADC_CON0_M_AIN15 = 15, /*!< AIN15 : Input channel */ +} ADC_CON0_M_Enum; + +/* ================================================= ADC CON0 CLK [8..10] ================================================== */ +typedef enum { /*!< ADC_CON0_CLK */ + ADC_CON0_CLK_Div2 = 0, /*!< Div2 : PCLK/2 */ + ADC_CON0_CLK_Div4 = 1, /*!< Div4 : PCLK/4 */ + ADC_CON0_CLK_Div8 = 2, /*!< Div8 : PCLK/8 */ + ADC_CON0_CLK_Div16 = 3, /*!< Div16 : PCLK/16 */ + ADC_CON0_CLK_Div32 = 4, /*!< Div32 : PCLK/32 */ + ADC_CON0_CLK_Div64 = 5, /*!< Div64 : PCLK/64 */ + ADC_CON0_CLK_Div3_75 = 6, /*!< Div3_75 : PCLK/3.75 */ + ADC_CON0_CLK_Div3_5 = 7, /*!< Div3_5 : PCLK/3.5 */ +} ADC_CON0_CLK_Enum; + +/* ================================================ ADC CON0 ALIGN [13..13] ================================================ */ +typedef enum { /*!< ADC_CON0_ALIGN */ + ADC_CON0_ALIGN_RIGHT = 0, /*!< RIGHT : right align */ + ADC_CON0_ALIGN_LEFT = 1, /*!< LEFT : left align */ +} ADC_CON0_ALIGN_Enum; + +/* =============================================== ADC CON0 INT_EN [16..19] ================================================ */ +typedef enum { /*!< ADC_CON0_INT_EN */ + ADC_CON0_INT_EN_DISABLE = 0, /*!< DISABLE : Disable interrupt */ + ADC_CON0_INT_EN_DONE = 1, /*!< DONE : Interrupt when conversion done */ + ADC_CON0_INT_EN_GT_THR = 2, /*!< GT_THR : Result is greater then threshold */ + ADC_CON0_INT_EN_LT_THR = 4, /*!< LT_THR : Result is littler then threshold */ + ADC_CON0_INT_EN_EQ_THR = 8, /*!< EQ_THR : Result is equal to threshold */ +} ADC_CON0_INT_EN_Enum; + +/* ================================================= ADC CON0 TZO [20..22] ================================================= */ +typedef enum { /*!< ADC_CON0_TZO */ + ADC_CON0_TZO_LSB_MINUS_4 = 0, /*!< LSB_MINUS_4 : -4 LSB */ + ADC_CON0_TZO_LSB_MINUS_3 = 1, /*!< LSB_MINUS_3 : -3 LSB */ + ADC_CON0_TZO_LSB_MINUS_2 = 2, /*!< LSB_MINUS_2 : -2 LSB */ + ADC_CON0_TZO_LSB_MINUS_1 = 3, /*!< LSB_MINUS_1 : -1 LSB */ + ADC_CON0_TZO_LSB = 4, /*!< LSB : keep LSB value */ + ADC_CON0_TZO_LSB_PLUS_1 = 5, /*!< LSB_PLUS_1 : +1 LSB */ + ADC_CON0_TZO_LSB_PLUS_2 = 6, /*!< LSB_PLUS_2 : +2 LSB */ + ADC_CON0_TZO_LSB_PLUS_3 = 7, /*!< LSB_PLUS_3 : +3 LSB */ +} ADC_CON0_TZO_Enum; + +/* ========================================================= STAT ========================================================== */ +/* ============================================== ADC STAT COMP_RESULT [4..5] ============================================== */ +typedef enum { /*!< ADC_STAT_COMP_RESULT */ + ADC_STAT_COMP_RESULT_NONE = 0, /*!< NONE : Auto-clear after read reg DATx */ + ADC_STAT_COMP_RESULT_GT_THR = 1, /*!< GT_THR : Result is greater then threshold */ + ADC_STAT_COMP_RESULT_LT_THR = 2, /*!< LT_THR : Result is littler then threshold */ + ADC_STAT_COMP_RESULT_EQ_THR = 3, /*!< EQ_THR : Result is equal to threshold */ +} ADC_STAT_COMP_RESULT_Enum; + +/* =============================================== ADC STAT DLY_SET [21..23] =============================================== */ +typedef enum { /*!< ADC_STAT_DLY_SET */ + ADC_STAT_DLY_SET_DLY_12 = 0, /*!< DLY_12 : Deley 12 cycles */ + ADC_STAT_DLY_SET_DLY_14 = 1, /*!< DLY_14 : Deley 14 cycles */ + ADC_STAT_DLY_SET_DLY_18 = 2, /*!< DLY_18 : Deley 18 cycles */ + ADC_STAT_DLY_SET_DLY_24 = 3, /*!< DLY_24 : Deley 24 cycles */ + ADC_STAT_DLY_SET_DLY_26 = 4, /*!< DLY_26 : Deley 26 cycles */ +} ADC_STAT_DLY_SET_Enum; + +/* ========================================================= DAT0 ========================================================== */ +/* ========================================================= DAT1 ========================================================== */ +/* ========================================================= DAT2 ========================================================== */ +/* ========================================================= DAT3 ========================================================== */ +/* ========================================================= DAT4 ========================================================== */ +/* ========================================================= DAT5 ========================================================== */ +/* ========================================================= DAT6 ========================================================== */ +/* ========================================================= DAT7 ========================================================== */ +/* ========================================================= DAT8 ========================================================== */ +/* ========================================================= DAT9 ========================================================== */ +/* ========================================================= DAT10 ========================================================= */ +/* ========================================================= DAT11 ========================================================= */ +/* ========================================================= DAT12 ========================================================= */ +/* ========================================================= DAT13 ========================================================= */ +/* ========================================================= DAT14 ========================================================= */ +/* ========================================================= DAT15 ========================================================= */ +/* ========================================================= CHSEL ========================================================= */ +/* ============================================= ADC CHSEL TRIG_SEL16 [26..27] ============================================= */ +typedef enum { /*!< ADC_CHSEL_TRIG_SEL16 */ + ADC_CHSEL_TRIG_SEL16_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_CHSEL_TRIG_SEL16_TIM0_OVERFLOW = 1, /*!< TIM0_OVERFLOW : TIM0 overflow trigger */ +} ADC_CHSEL_TRIG_SEL16_Enum; + +/* ============================================= ADC CHSEL TRIG_SEL17 [28..29] ============================================= */ +typedef enum { /*!< ADC_CHSEL_TRIG_SEL17 */ + ADC_CHSEL_TRIG_SEL17_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_CHSEL_TRIG_SEL17_PIN = 1, /*!< PIN : PB1/PB2 trigger */ +} ADC_CHSEL_TRIG_SEL17_Enum; + +/* ============================================= ADC CHSEL EXTRIG_SEL [30..31] ============================================= */ +typedef enum { /*!< ADC_CHSEL_EXTRIG_SEL */ + ADC_CHSEL_EXTRIG_SEL_PB1_RISING = 0, /*!< PB1_RISING : PB1 rising trigger */ + ADC_CHSEL_EXTRIG_SEL_PB1_FALLING = 1, /*!< PB1_FALLING : PB1 falling trigger */ + ADC_CHSEL_EXTRIG_SEL_PB2_RISING = 2, /*!< PB2_RISING : PB2 rising trigger */ + ADC_CHSEL_EXTRIG_SEL_PB2_FALLING = 3, /*!< PB2_FALLING : PB2 falling trigger */ +} ADC_CHSEL_EXTRIG_SEL_Enum; + +/* ======================================================== TRGSEL ========================================================= */ +/* ============================================== ADC TRGSEL TRIG_SEL0 [0..1] ============================================== */ +typedef enum { /*!< ADC_TRGSEL_TRIG_SEL0 */ + ADC_TRGSEL_TRIG_SEL0_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_TRGSEL_TRIG_SEL0_EPWM_CH1_RISING = 1, /*!< EPWM_CH1_RISING : EPWM0P(CH1) Rising */ +} ADC_TRGSEL_TRIG_SEL0_Enum; + +/* ============================================== ADC TRGSEL TRIG_SEL1 [2..3] ============================================== */ +typedef enum { /*!< ADC_TRGSEL_TRIG_SEL1 */ + ADC_TRGSEL_TRIG_SEL1_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_TRGSEL_TRIG_SEL1_EPWM_CH2_RISING = 1, /*!< EPWM_CH2_RISING : EPWM0P(CH2) Rising */ +} ADC_TRGSEL_TRIG_SEL1_Enum; + +/* ============================================== ADC TRGSEL TRIG_SEL2 [4..5] ============================================== */ +typedef enum { /*!< ADC_TRGSEL_TRIG_SEL2 */ + ADC_TRGSEL_TRIG_SEL2_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_TRGSEL_TRIG_SEL2_EPWM_CH3_RISING = 1, /*!< EPWM_CH3_RISING : EPWM0P(CH3) Rising */ +} ADC_TRGSEL_TRIG_SEL2_Enum; + +/* ============================================== ADC TRGSEL TRIG_SEL3 [6..7] ============================================== */ +typedef enum { /*!< ADC_TRGSEL_TRIG_SEL3 */ + ADC_TRGSEL_TRIG_SEL3_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_TRGSEL_TRIG_SEL3_EPWM_CH1_FALLING = 1, /*!< EPWM_CH1_FALLING : EPWM0P(CH1) Falling */ +} ADC_TRGSEL_TRIG_SEL3_Enum; + +/* ============================================== ADC TRGSEL TRIG_SEL4 [8..9] ============================================== */ +typedef enum { /*!< ADC_TRGSEL_TRIG_SEL4 */ + ADC_TRGSEL_TRIG_SEL4_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_TRGSEL_TRIG_SEL4_EPWM_CH2_FALLING = 1, /*!< EPWM_CH2_FALLING : EPWM0P(CH2) Falling */ +} ADC_TRGSEL_TRIG_SEL4_Enum; + +/* ============================================= ADC TRGSEL TRIG_SEL5 [10..11] ============================================= */ +typedef enum { /*!< ADC_TRGSEL_TRIG_SEL5 */ + ADC_TRGSEL_TRIG_SEL5_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_TRGSEL_TRIG_SEL5_EPWM_CH3_FALLING = 1, /*!< EPWM_CH3_FALLING : EPWM0P(CH3) Falling */ +} ADC_TRGSEL_TRIG_SEL5_Enum; + +/* ============================================= ADC TRGSEL TRIG_SEL6 [12..13] ============================================= */ +typedef enum { /*!< ADC_TRGSEL_TRIG_SEL6 */ + ADC_TRGSEL_TRIG_SEL6_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_TRGSEL_TRIG_SEL6_COMP0_RISING = 1, /*!< COMP0_RISING : COMP0 Rising */ +} ADC_TRGSEL_TRIG_SEL6_Enum; + +/* ============================================= ADC TRGSEL TRIG_SEL7 [14..15] ============================================= */ +typedef enum { /*!< ADC_TRGSEL_TRIG_SEL7 */ + ADC_TRGSEL_TRIG_SEL7_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_TRGSEL_TRIG_SEL7_COMP0_FALLING = 1, /*!< COMP0_FALLING : COMP0 Falling */ +} ADC_TRGSEL_TRIG_SEL7_Enum; + +/* ============================================= ADC TRGSEL TRIG_SEL8 [16..17] ============================================= */ +typedef enum { /*!< ADC_TRGSEL_TRIG_SEL8 */ + ADC_TRGSEL_TRIG_SEL8_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_TRGSEL_TRIG_SEL8_COMP1_RISING = 1, /*!< COMP1_RISING : COMP1 Rising */ +} ADC_TRGSEL_TRIG_SEL8_Enum; + +/* ============================================= ADC TRGSEL TRIG_SEL9 [18..19] ============================================= */ +typedef enum { /*!< ADC_TRGSEL_TRIG_SEL9 */ + ADC_TRGSEL_TRIG_SEL9_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_TRGSEL_TRIG_SEL9_COMP1_FALLING = 1, /*!< COMP1_FALLING : COMP1 Falling */ +} ADC_TRGSEL_TRIG_SEL9_Enum; + +/* ============================================ ADC TRGSEL TRIG_SEL10 [20..21] ============================================= */ +typedef enum { /*!< ADC_TRGSEL_TRIG_SEL10 */ + ADC_TRGSEL_TRIG_SEL10_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_TRGSEL_TRIG_SEL10_EPWM_UDF = 1, /*!< EPWM_UDF : EPWM Counter Underflow */ +} ADC_TRGSEL_TRIG_SEL10_Enum; + +/* ============================================ ADC TRGSEL TRIG_SEL11 [22..23] ============================================= */ +typedef enum { /*!< ADC_TRGSEL_TRIG_SEL11 */ + ADC_TRGSEL_TRIG_SEL11_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_TRGSEL_TRIG_SEL11_EPWM_OVF = 1, /*!< EPWM_OVF : EPWM Counter Overflow */ +} ADC_TRGSEL_TRIG_SEL11_Enum; + +/* ============================================ ADC TRGSEL TRIG_SEL12 [24..25] ============================================= */ +typedef enum { /*!< ADC_TRGSEL_TRIG_SEL12 */ + ADC_TRGSEL_TRIG_SEL12_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_TRGSEL_TRIG_SEL12_EPWM_CCR4_UP = 1, /*!< EPWM_CCR4_UP : EPWM CCR4 up-count */ +} ADC_TRGSEL_TRIG_SEL12_Enum; + +/* ============================================ ADC TRGSEL TRIG_SEL13 [26..27] ============================================= */ +typedef enum { /*!< ADC_TRGSEL_TRIG_SEL13 */ + ADC_TRGSEL_TRIG_SEL13_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_TRGSEL_TRIG_SEL13_EPWM_CCDR4_UP = 1, /*!< EPWM_CCDR4_UP : EPWM CCDR4 up-count */ +} ADC_TRGSEL_TRIG_SEL13_Enum; + +/* ============================================ ADC TRGSEL TRIG_SEL14 [28..29] ============================================= */ +typedef enum { /*!< ADC_TRGSEL_TRIG_SEL14 */ + ADC_TRGSEL_TRIG_SEL14_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_TRGSEL_TRIG_SEL14_EPWM_CCR4_DN = 1, /*!< EPWM_CCR4_DN : EPWM CCR4 down-count */ +} ADC_TRGSEL_TRIG_SEL14_Enum; + +/* ============================================ ADC TRGSEL TRIG_SEL15 [30..31] ============================================= */ +typedef enum { /*!< ADC_TRGSEL_TRIG_SEL15 */ + ADC_TRGSEL_TRIG_SEL15_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_TRGSEL_TRIG_SEL15_EPWM_CCDR4_DN = 1, /*!< EPWM_CCDR4_DN : EPWM CCDR4 down-count */ +} ADC_TRGSEL_TRIG_SEL15_Enum; + +/* ========================================================= BKSEL ========================================================= */ +/* =============================================== ADC BKSEL BK1_FLT [4..5] ================================================ */ +typedef enum { /*!< ADC_BKSEL_BK1_FLT */ + ADC_BKSEL_BK1_FLT_OFF = 0, /*!< OFF : Disable filter the brake from ADC source 1 */ + ADC_BKSEL_BK1_FLT_MATCH_2 = 1, /*!< MATCH_2 : Brake if result matches 2-times */ + ADC_BKSEL_BK1_FLT_MATCH_4 = 2, /*!< MATCH_4 : Brake if result matches 4-times */ + ADC_BKSEL_BK1_FLT_MATCH_7 = 3, /*!< MATCH_7 : Brake if result matches 7-times */ +} ADC_BKSEL_BK1_FLT_Enum; + +/* ================================================ ADC BKSEL BK1_EN [6..7] ================================================ */ +typedef enum { /*!< ADC_BKSEL_BK1_EN */ + ADC_BKSEL_BK1_EN_OFF = 0, /*!< OFF : Disable brake from ADC source 1 */ + ADC_BKSEL_BK1_EN_GT_THR = 1, /*!< GT_THR : Result is greater then threshold */ + ADC_BKSEL_BK1_EN_LT_THR = 2, /*!< LT_THR : Result is littler then threshold */ + ADC_BKSEL_BK1_EN_EQ_THR = 3, /*!< EQ_THR : Result is equal to threshold */ +} ADC_BKSEL_BK1_EN_Enum; + +/* ============================================== ADC BKSEL BK2_FLT [12..13] =============================================== */ +typedef enum { /*!< ADC_BKSEL_BK2_FLT */ + ADC_BKSEL_BK2_FLT_OFF = 0, /*!< OFF : Disable filter the brake from ADC source 2 */ + ADC_BKSEL_BK2_FLT_MATCH_2 = 1, /*!< MATCH_2 : Brake if result matches 2-times */ + ADC_BKSEL_BK2_FLT_MATCH_4 = 2, /*!< MATCH_4 : Brake if result matches 4-times */ + ADC_BKSEL_BK2_FLT_MATCH_7 = 3, /*!< MATCH_7 : Brake if result matches 7-times */ +} ADC_BKSEL_BK2_FLT_Enum; + +/* =============================================== ADC BKSEL BK2_EN [14..15] =============================================== */ +typedef enum { /*!< ADC_BKSEL_BK2_EN */ + ADC_BKSEL_BK2_EN_OFF = 0, /*!< OFF : Disable brake from ADC source 1 */ + ADC_BKSEL_BK2_EN_GT_THR = 1, /*!< GT_THR : Result is greater then threshold */ + ADC_BKSEL_BK2_EN_LT_THR = 2, /*!< LT_THR : Result is littler then threshold */ + ADC_BKSEL_BK2_EN_EQ_THR = 3, /*!< EQ_THR : Result is equal to threshold */ +} ADC_BKSEL_BK2_EN_Enum; + +/* ======================================================== BAKDAT ========================================================= */ + + +/* =========================================================================================================================== */ +/* ================ AMISC ================ */ +/* =========================================================================================================================== */ + +/* ====================================================== LVD_LVR_CR ======================================================= */ +/* ============================================ AMISC LVD_LVR_CR LVD_SEL [5..7] ============================================ */ +typedef enum { /*!< AMISC_LVD_LVR_CR_LVD_SEL */ + AMISC_LVD_LVR_CR_LVD_SEL_2V = 0, /*!< 2V : 2.0V */ + AMISC_LVD_LVR_CR_LVD_SEL_2_2V = 1, /*!< 2_2V : 2.2V */ + AMISC_LVD_LVR_CR_LVD_SEL_2_4V = 2, /*!< 2_4V : 2.4V */ + AMISC_LVD_LVR_CR_LVD_SEL_2_7V = 3, /*!< 2_7V : 2.7V */ + AMISC_LVD_LVR_CR_LVD_SEL_3V = 4, /*!< 3V : 3.0V */ + AMISC_LVD_LVR_CR_LVD_SEL_3_7V = 5, /*!< 3_7V : 3.7V */ + AMISC_LVD_LVR_CR_LVD_SEL_4V = 6, /*!< 4V : 4.0V */ + AMISC_LVD_LVR_CR_LVD_SEL_4_3V = 7, /*!< 4_3V : 4.3V */ +} AMISC_LVD_LVR_CR_LVD_SEL_Enum; + +/* =========================================== AMISC LVD_LVR_CR LVR_SEL [13..15] =========================================== */ +typedef enum { /*!< AMISC_LVD_LVR_CR_LVR_SEL */ + AMISC_LVD_LVR_CR_LVR_SEL_2V = 0, /*!< 2V : 2.0V */ + AMISC_LVD_LVR_CR_LVR_SEL_2_4V = 1, /*!< 2_4V : 2.4V */ + AMISC_LVD_LVR_CR_LVR_SEL_2_7V = 2, /*!< 2_7V : 2.7V */ + AMISC_LVD_LVR_CR_LVR_SEL_3V = 3, /*!< 3V : 3V */ + AMISC_LVD_LVR_CR_LVR_SEL_3_7V = 4, /*!< 3_7V : 3.7V */ +} AMISC_LVD_LVR_CR_LVR_SEL_Enum; + +/* ======================================================== VBUF_CR ======================================================== */ +/* ============================================= AMISC VBUF_CR ANA_SEL [6..12] ============================================= */ +typedef enum { /*!< AMISC_VBUF_CR_ANA_SEL */ + AMISC_VBUF_CR_ANA_SEL_NONE = 0, /*!< NONE : None */ + AMISC_VBUF_CR_ANA_SEL_TEMP = 1, /*!< TEMP : temp out */ + AMISC_VBUF_CR_ANA_SEL_DAC0 = 2, /*!< DAC0 : DAC 0 */ + AMISC_VBUF_CR_ANA_SEL_DAC1 = 4, /*!< DAC1 : DAC 1 */ + AMISC_VBUF_CR_ANA_SEL_VBuf_1p5v = 8, /*!< VBuf_1p5v : vbuf 1p5v out */ + AMISC_VBUF_CR_ANA_SEL_VDDL = 16, /*!< VDDL : vddl */ + AMISC_VBUF_CR_ANA_SEL_VSS = 32, /*!< VSS : vss */ + AMISC_VBUF_CR_ANA_SEL_VDD = 64, /*!< VDD : vdd */ +} AMISC_VBUF_CR_ANA_SEL_Enum; + +/* ======================================================== DAC_CR ========================================================= */ +/* ======================================================== HSI_CR ========================================================= */ +/* ============================================= AMISC HSI_CR LDO_SEL [0..15] ============================================== */ +typedef enum { /*!< AMISC_HSI_CR_LDO_SEL */ + AMISC_HSI_CR_LDO_SEL_LDO = 32896, /*!< LDO : ldo_oschf Disable abd vddl_oschf from ldo */ + AMISC_HSI_CR_LDO_SEL_Normal = 257, /*!< Normal : do_oschf Enable and vddl_oschf from ldo_oschf */ +} AMISC_HSI_CR_LDO_SEL_Enum; + +/* ======================================================== LSI_CR ========================================================= */ +/* ====================================================== ADC_AIN_CR ======================================================= */ + + +/* =========================================================================================================================== */ +/* ================ HWTRIM ================ */ +/* =========================================================================================================================== */ + +/* ======================================================= LDO_TRIM ======================================================== */ +/* =========================================== HWTRIM LDO_TRIM LDO_TUNE [10..11] =========================================== */ +typedef enum { /*!< HWTRIM_LDO_TRIM_LDO_TUNE */ + HWTRIM_LDO_TRIM_LDO_TUNE_STRENGTH = 0, /*!< STRENGTH : strength */ + HWTRIM_LDO_TRIM_LDO_TUNE_WEAK = 1, /*!< WEAK : weak */ + HWTRIM_LDO_TRIM_LDO_TUNE_MIDDLEddle = 2, /*!< MIDDLEddle : middle */ + HWTRIM_LDO_TRIM_LDO_TUNE_OFF = 3, /*!< OFF : off */ +} HWTRIM_LDO_TRIM_LDO_TUNE_Enum; + +/* ======================================================= VBUF_TRIM ======================================================= */ +/* ======================================================= HSI_TRIM ======================================================== */ +/* ======================================================= LSI_TRIM ======================================================== */ +/* ======================================================= MISC_CFG ======================================================== */ + + +/* =========================================================================================================================== */ +/* ================ CRC ================ */ +/* =========================================================================================================================== */ + +/* ========================================================== CR =========================================================== */ +/* ================================================= CRC CR POLYSEL [0..0] ================================================= */ +typedef enum { /*!< CRC_CR_POLYSEL */ + CRC_CR_POLYSEL_CRC16 = 1, /*!< CRC16 : x16 + x12 + x5 + 1 */ + CRC_CR_POLYSEL_CRC32 = 0, /*!< CRC32 : x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + + x7 + x5 + x4 + x2 + x + 1 */ +} CRC_CR_POLYSEL_Enum; + +/* ========================================================== DIN ========================================================== */ +/* ========================================================= DOUT ========================================================== */ + + +/* =========================================================================================================================== */ +/* ================ DSP ================ */ +/* =========================================================================================================================== */ + +/* ========================================================== CR =========================================================== */ +/* ================================================== DSP CR MODE [0..2] =================================================== */ +typedef enum { /*!< DSP_CR_MODE */ + DSP_CR_MODE_DIV = 1, /*!< DIV : 32-bits Divide Mode */ + DSP_CR_MODE_SQRT = 4, /*!< SQRT : square root mode */ +} DSP_CR_MODE_Enum; + +/* ========================================================== SR =========================================================== */ +/* ========================================================= SDAT1 ========================================================= */ +/* ========================================================= SDAT2 ========================================================= */ +/* ========================================================= RSLT1 ========================================================= */ +/* ========================================================= RSLT2 ========================================================= */ + + +/* =========================================================================================================================== */ +/* ================ OPAMP ================ */ +/* =========================================================================================================================== */ + +/* ======================================================== PGA_CR ========================================================= */ +/* ============================================= OPAMP PGA_CR PGA_GAIN [2..7] ============================================== */ +typedef enum { /*!< OPAMP_PGA_CR_PGA_GAIN */ + OPAMP_PGA_CR_PGA_GAIN_x1 = 1, /*!< x1 : Multiple of gain */ + OPAMP_PGA_CR_PGA_GAIN_x2 = 6, /*!< x2 : Multiple of gain */ + OPAMP_PGA_CR_PGA_GAIN_x3 = 10, /*!< x3 : Multiple of gain */ + OPAMP_PGA_CR_PGA_GAIN_x4 = 14, /*!< x4 : Multiple of gain */ + OPAMP_PGA_CR_PGA_GAIN_x5 = 18, /*!< x5 : Multiple of gain */ + OPAMP_PGA_CR_PGA_GAIN_x6 = 22, /*!< x6 : Multiple of gain */ + OPAMP_PGA_CR_PGA_GAIN_x7 = 26, /*!< x7 : Multiple of gain */ + OPAMP_PGA_CR_PGA_GAIN_x8 = 30, /*!< x8 : Multiple of gain */ + OPAMP_PGA_CR_PGA_GAIN_x9 = 34, /*!< x9 : Multiple of gain */ + OPAMP_PGA_CR_PGA_GAIN_x10 = 38, /*!< x10 : Multiple of gain */ + OPAMP_PGA_CR_PGA_GAIN_x11 = 42, /*!< x11 : Multiple of gain */ + OPAMP_PGA_CR_PGA_GAIN_x12 = 46, /*!< x12 : Multiple of gain */ + OPAMP_PGA_CR_PGA_GAIN_x13 = 50, /*!< x13 : Multiple of gain */ + OPAMP_PGA_CR_PGA_GAIN_x14 = 54, /*!< x14 : Multiple of gain */ + OPAMP_PGA_CR_PGA_GAIN_x15 = 58, /*!< x15 : Multiple of gain */ + OPAMP_PGA_CR_PGA_GAIN_x16 = 62, /*!< x16 : Multiple of gain */ +} OPAMP_PGA_CR_PGA_GAIN_Enum; + + + +/* =========================================================================================================================== */ +/* ================ COMP ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= CTRL ========================================================== */ +/* =============================================== COMP CTRL VIN_SEL [2..3] ================================================ */ +typedef enum { /*!< COMP_CTRL_VIN_SEL */ + COMP_CTRL_VIN_SEL_IO = 1, /*!< IO : selction IO Pin */ + COMP_CTRL_VIN_SEL_DAC = 2, /*!< DAC : selction DAC */ +} COMP_CTRL_VIN_SEL_Enum; + +/* =============================================== COMP CTRL FIL_CTRL [4..7] =============================================== */ +typedef enum { /*!< COMP_CTRL_FIL_CTRL */ + COMP_CTRL_FIL_CTRL_BYPASS = 0, /*!< BYPASS : No filter */ + COMP_CTRL_FIL_CTRL_SAMPLE_2 = 1, /*!< SAMPLE_2 : sample 2 times */ + COMP_CTRL_FIL_CTRL_SAMPLE_4 = 2, /*!< SAMPLE_4 : sample 4 times */ + COMP_CTRL_FIL_CTRL_SAMPLE_8 = 3, /*!< SAMPLE_8 : sample 8 times */ + COMP_CTRL_FIL_CTRL_SAMPLE_16 = 4, /*!< SAMPLE_16 : sample 16 times */ + COMP_CTRL_FIL_CTRL_SAMPLE_32 = 5, /*!< SAMPLE_32 : sample 32 times */ + COMP_CTRL_FIL_CTRL_SAMPLE_64 = 6, /*!< SAMPLE_64 : sample 64 times */ + COMP_CTRL_FIL_CTRL_SAMPLE_128 = 7, /*!< SAMPLE_128 : sample 128 times */ + COMP_CTRL_FIL_CTRL_SAMPLE_256 = 8, /*!< SAMPLE_256 : sample 256 times */ +} COMP_CTRL_FIL_CTRL_Enum; + +/* =============================================== COMP CTRL OUT_EN [11..11] =============================================== */ +typedef enum { /*!< COMP_CTRL_OUT_EN */ + COMP_CTRL_OUT_EN_NONE = 0, /*!< NONE : No signal output */ + COMP_CTRL_OUT_EN_IO = 1, /*!< IO : select IO output */ +} COMP_CTRL_OUT_EN_Enum; + +/* ============================================== COMP CTRL POL_SEL [12..12] =============================================== */ +typedef enum { /*!< COMP_CTRL_POL_SEL */ + COMP_CTRL_POL_SEL_NORMAL = 0, /*!< NORMAL : Normal polarity output */ + COMP_CTRL_POL_SEL_INVERT = 1, /*!< INVERT : Inverted */ +} COMP_CTRL_POL_SEL_Enum; + +/* ======================================================== VIPSEL ========================================================= */ +/* ============================================== COMP VIPSEL VIP_SEL [0..4] =============================================== */ +typedef enum { /*!< COMP_VIPSEL_VIP_SEL */ + COMP_VIPSEL_VIP_SEL_IO3 = 16, /*!< IO3 : I/O PA15 */ + COMP_VIPSEL_VIP_SEL_IO2 = 8, /*!< IO2 : I/O PA14 */ + COMP_VIPSEL_VIP_SEL_IO1 = 4, /*!< IO1 : I/O PA11 */ + COMP_VIPSEL_VIP_SEL_IO0 = 2, /*!< IO0 : I/O PA8 */ + COMP_VIPSEL_VIP_SEL_PGA = 1, /*!< PGA : Select PGA */ +} COMP_VIPSEL_VIP_SEL_Enum; + +/* ========================================================== IR =========================================================== */ +/* ========================================================== IF =========================================================== */ +/* ======================================================== INITCNT ======================================================== */ + + +/* =========================================================================================================================== */ +/* ================ TIM ================ */ +/* =========================================================================================================================== */ + +/* ========================================================== CR1 ========================================================== */ +/* ================================================== TIM CR1 CMS [5..6] =================================================== */ +typedef enum { /*!< TIM_CR1_CMS */ + TIM_CR1_CMS_EDGE = 0, /*!< EDGE : edge mode */ + TIM_CR1_CMS_CENTER1 = 1, /*!< CENTER1 : center mode 1: count-up will trigger interrupt */ + TIM_CR1_CMS_CENTER2 = 2, /*!< CENTER2 : center mode 2: count-down will trigger interrupt */ + TIM_CR1_CMS_CENTER3 = 3, /*!< CENTER3 : center mode 3: count-up and count-down will trigger + interrupt */ +} TIM_CR1_CMS_Enum; + +/* ================================================== TIM CR1 CKD [8..9] =================================================== */ +typedef enum { /*!< TIM_CR1_CKD */ + TIM_CR1_CKD_0 = 0, /*!< 0 : Tdts = tck_in */ + TIM_CR1_CKD_1 = 1, /*!< 1 : Tdts = tck_in*2 */ + TIM_CR1_CKD_2 = 2, /*!< 2 : Tdts = tck_in*4 */ + TIM_CR1_CKD_3 = 3, /*!< 3 : reserve */ +} TIM_CR1_CKD_Enum; + +/* ========================================================== CR2 ========================================================== */ +/* ================================================== TIM CR2 MMS [4..6] =================================================== */ +typedef enum { /*!< TIM_CR2_MMS */ + TIM_CR2_MMS_RESET = 0, /*!< RESET : UG Trigger TRGO */ + TIM_CR2_MMS_ENABLE = 1, /*!< ENABLE : CEN Trigger TRGO */ + TIM_CR2_MMS_UPDATE = 2, /*!< UPDATE : UPDATE Trigger TRGO */ + TIM_CR2_MMS_COMPARE = 3, /*!< COMPARE : COMPARE/CAPTURE Trigger TRGO */ + TIM_CR2_MMS_OC1REF = 4, /*!< OC1REF : OC1REF Trigger TRGO */ + TIM_CR2_MMS_OC2REF = 5, /*!< OC2REF : OC2REF Trigger TRGO */ + TIM_CR2_MMS_OC3REF = 6, /*!< OC3REF : OC3REF Trigger TRGO */ + TIM_CR2_MMS_OC4REF = 7, /*!< OC4REF : OC4REF Trigger TRGO */ +} TIM_CR2_MMS_Enum; + +/* ========================================================= SMCR ========================================================== */ +/* ================================================== TIM SMCR SMS [0..2] ================================================== */ +typedef enum { /*!< TIM_SMCR_SMS */ + TIM_SMCR_SMS_DISABLE = 0, /*!< DISABLE : close Slave mode */ + TIM_SMCR_SMS_Encode1 = 1, /*!< Encode1 : Encode mode 1: */ + TIM_SMCR_SMS_Encode2 = 2, /*!< Encode2 : Encode mode 2 */ + TIM_SMCR_SMS_Encode3 = 3, /*!< Encode3 : Encode mode 3 */ + TIM_SMCR_SMS_RESET = 4, /*!< RESET : Reset mode */ + TIM_SMCR_SMS_WINDOW = 5, /*!< WINDOW : Window mode */ + TIM_SMCR_SMS_TRIGGER = 6, /*!< TRIGGER : trigger mode */ + TIM_SMCR_SMS_EXTCLK = 7, /*!< EXTCLK : External clock mode 1 */ +} TIM_SMCR_SMS_Enum; + +/* ================================================== TIM SMCR TS [4..6] =================================================== */ +typedef enum { /*!< TIM_SMCR_TS */ + TIM_SMCR_TS_ITR0 = 0, /*!< ITR0 : ITR0 */ + TIM_SMCR_TS_ITR1 = 1, /*!< ITR1 : ITR1: */ + TIM_SMCR_TS_ITR2 = 2, /*!< ITR2 : ITR2 */ + TIM_SMCR_TS_ITR3 = 3, /*!< ITR3 : ITR3 */ + TIM_SMCR_TS_TI1F_ED = 4, /*!< TI1F_ED : TI1F_ED */ + TIM_SMCR_TS_T1FP1 = 5, /*!< T1FP1 : T1FP1 */ + TIM_SMCR_TS_T1FP2 = 6, /*!< T1FP2 : T1FP2 */ + TIM_SMCR_TS_ETRF = 7, /*!< ETRF : ETRF */ +} TIM_SMCR_TS_Enum; + +/* ================================================= TIM SMCR ETF [8..11] ================================================== */ +typedef enum { /*!< TIM_SMCR_ETF */ + TIM_SMCR_ETF_0 = 0, /*!< 0 : No filter */ + TIM_SMCR_ETF_1 = 1, /*!< 1 : fsampling = fclk_int,N=2 */ + TIM_SMCR_ETF_2 = 2, /*!< 2 : fsampling = fclk_int,N=4 */ + TIM_SMCR_ETF_3 = 3, /*!< 3 : fsampling = fclk_int,N=8 */ + TIM_SMCR_ETF_4 = 4, /*!< 4 : fsampling = Fdts/2,N=6 */ + TIM_SMCR_ETF_5 = 5, /*!< 5 : fsampling = Fdts/2,N=8 */ + TIM_SMCR_ETF_6 = 6, /*!< 6 : fsampling = Fdts/4,N=6 */ + TIM_SMCR_ETF_7 = 7, /*!< 7 : fsampling = Fdts/4,N=8 */ + TIM_SMCR_ETF_8 = 8, /*!< 8 : fsampling = Fdts/8,N=6 */ + TIM_SMCR_ETF_9 = 9, /*!< 9 : fsampling = Fdts/8,N=8 */ + TIM_SMCR_ETF_10 = 10, /*!< 10 : fsampling = Fdts/16,N=5 */ + TIM_SMCR_ETF_11 = 11, /*!< 11 : fsampling = Fdts/16,N=6 */ + TIM_SMCR_ETF_12 = 12, /*!< 12 : fsampling = Fdts/16,N=8 */ + TIM_SMCR_ETF_13 = 13, /*!< 13 : fsampling = Fdts/32,N=5 */ + TIM_SMCR_ETF_14 = 14, /*!< 14 : fsampling = Fdts/32,N=6 */ + TIM_SMCR_ETF_15 = 15, /*!< 15 : fsampling = Fdts/32,N=8 */ +} TIM_SMCR_ETF_Enum; + +/* ========================================================= DIER ========================================================== */ +/* ========================================================== SR =========================================================== */ +/* ========================================================== EGR ========================================================== */ +/* ===================================================== CCMR1_OUTPUT ====================================================== */ +/* ====================================================== CCMR1_INPUT ====================================================== */ +/* ===================================================== CCMR2_OUTPUT ====================================================== */ +/* ====================================================== CCMR2_INPUT ====================================================== */ +/* ========================================================= CCER ========================================================== */ +/* ========================================================== CNT ========================================================== */ +/* ========================================================== PSC ========================================================== */ +/* ========================================================== ARR ========================================================== */ +/* ========================================================== RCR ========================================================== */ +/* ========================================================= CCR1 ========================================================== */ +/* ========================================================= CCR2 ========================================================== */ +/* ========================================================= CCR3 ========================================================== */ +/* ========================================================= CCR4 ========================================================== */ +/* ========================================================= BDTR ========================================================== */ +/* ========================================================= CCDR1 ========================================================= */ +/* ========================================================= CCDR2 ========================================================= */ +/* ========================================================= CCDR3 ========================================================= */ +/* ========================================================= CCDR4 ========================================================= */ + + +/* =========================================================================================================================== */ +/* ================ LPTIM ================ */ +/* =========================================================================================================================== */ + +/* ========================================================== IR =========================================================== */ +/* ========================================================== TCR ========================================================== */ +/* ================================================= LPTIM TCR CLKS [2..3] ================================================= */ +typedef enum { /*!< LPTIM_TCR_CLKS */ + LPTIM_TCR_CLKS_SysClk = 0, /*!< SysClk : System Clock */ + LPTIM_TCR_CLKS_LSI = 1, /*!< LSI : LIRC 32KHz */ +} LPTIM_TCR_CLKS_Enum; + +/* =============================================== LPTIM TCR TRIGSEL [4..6] ================================================ */ +typedef enum { /*!< LPTIM_TCR_TRIGSEL */ + LPTIM_TCR_TRIGSEL_Normal = 0, /*!< Normal : Normal trigger */ + LPTIM_TCR_TRIGSEL_EPWMCh0P = 1, /*!< EPWMCh0P : EPWM CH0 (ouput) rising trigger */ + LPTIM_TCR_TRIGSEL_EPWMCh1P = 2, /*!< EPWMCh1P : EPWM CH1 (ouput) rising trigger */ + LPTIM_TCR_TRIGSEL_EPWMCh2P = 3, /*!< EPWMCh2P : EPWM CH2 (ouput) rising trigger */ + LPTIM_TCR_TRIGSEL_EPWMCh0N = 4, /*!< EPWMCh0N : EPWM CH0 (ouput) falling trigger */ + LPTIM_TCR_TRIGSEL_EPWMCh1N = 5, /*!< EPWMCh1N : EPWM CH1 (ouput) falling trigger */ + LPTIM_TCR_TRIGSEL_EPWMCh2N = 6, /*!< EPWMCh2N : EPWM CH2 (ouput) falling trigger */ +} LPTIM_TCR_TRIGSEL_Enum; + +/* ========================================================== TC =========================================================== */ +/* ========================================================== PR =========================================================== */ +/* ========================================================== PC =========================================================== */ +/* ========================================================== MCR ========================================================== */ +/* ========================================================== MR0 ========================================================== */ + +/** @} */ /* End of group EnumValue_peripherals */ + + +#ifdef __cplusplus +} +#endif + +#endif /* PEC930_H */ + + +/** @} */ /* End of group PEC930 */ + +/** @} */ /* End of group Padauk-tech */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/system_dev.h b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/system_dev.h new file mode 100644 index 0000000..98d0fa4 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/system_dev.h @@ -0,0 +1,383 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file system_dev.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __system_dev_H_wjaCXWfu_lqsX_H0XR_svyC_uj3MxJR5UZzV__ +#define __system_dev_H_wjaCXWfu_lqsX_H0XR_svyC_uj3MxJR5UZzV__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +//============================================================================= +// Constant Definition +//============================================================================= + +#ifndef SYS_TIMER_FREQ +#define SYS_TIMER_FREQ 32768ul +#endif + +#ifndef SYS_MAX_DELAY +#define SYS_MAX_DELAY 0x7FFFFFFFul +#endif + +#define SYS_IGNORE_TAG (~0) + +/** + * Exception Code + */ +typedef enum EXCPn +{ + /* =============== Nuclei N/NX Specific Exception Code =============== */ + EXCPn_InsUnalign = 0, /*!< Instruction address misaligned */ + EXCPn_InsAccFault = 1, /*!< Instruction access fault */ + EXCPn_IlleIns = 2, /*!< Illegal instruction */ + EXCPn_Break = 3, /*!< Beakpoint */ + EXCPn_LdAddrUnalign = 4, /*!< Load address misaligned */ + EXCPn_LdFault = 5, /*!< Load access fault */ + EXCPn_StAddrUnalign = 6, /*!< Store or AMO address misaligned */ + EXCPn_StAccessFault = 7, /*!< Store or AMO access fault */ + EXCPn_UmodeEcall = 8, /*!< Environment call from User mode */ + EXCPn_SmodeEcall = 9, /*!< Environment call from S-mode */ + EXCPn_MmodeEcall = 11, /*!< Environment call from Machine mode */ + +#if 1 + EXCPn_Total, +#else + EXCPn_InsPageFault = 12, /*!< Instruction page fault */ + EXCPn_LdPageFault = 13, /*!< Load page fault */ + EXCPn_StPageFault = 15, /*!< Store or AMO page fault */ + EXCPn_StackOverflow = 24, /*!< Stack overflow fault */ + EXCPn_StackUnderflow = 25, /*!< Stack underflow fault */ + EXCPn_Total, +#endif + EXCPn_NMI = 0xfff, /*!< NMI interrupt */ +} EXCPn_Type; + +/** + * SYS_TIMER_PERIOD with 1ms, 10ms, 100ms + */ +typedef enum sys_tick +{ + SYS_TICK_1_MS = 0, + SYS_TICK_10_MS, + SYS_TICK_100_MS, + SYS_TICK_1_SEC, +} sys_tick_t; + + +#if defined(__ECLIC_PRESENT) && (__ECLIC_PRESENT == 1) +typedef enum sys_irq_trigger +{ + SYS_IRQ_TRIGGER_LEVEL = ECLIC_LEVEL_TRIGGER, /*!< Level Triggerred */ + SYS_IRQ_TRIGGER_POSTIVE_EDGE = ECLIC_POSTIVE_EDGE_TRIGGER, /*!< Postive/Rising Edge Triggered */ + SYS_IRQ_TRIGGER_NEGTIVE_EDGE = ECLIC_NEGTIVE_EDGE_TRIGGER, /*!< Negtive/Falling Edge Triggered */ + SYS_IRQ_TRIGGER_MAX = ECLIC_MAX_TRIGGER, /*!< MAX Supported Trigger Mode */ +} sys_irq_trigger_t; + +typedef enum sys_irq_level +{ + SYS_IRQ_LEVEL_LL = 0, /*!< Interrupt Level lowest */ + SYS_IRQ_LEVEL_L = 1, /*!< Interrupt Level low */ + SYS_IRQ_LEVEL_M = 2, /*!< Interrupt Level midden */ + SYS_IRQ_LEVEL_H = 3, /*!< Interrupt Level high */ + SYS_IRQ_LEVEL_HH = 4, /*!< Interrupt Level highest */ +} sys_irq_level_t; + +typedef enum sys_irq_priority +{ + SYS_IRQ_PRIORITY_LOW = 0, /*!< Interrupt Priority Low */ + SYS_IRQ_PRIORITY_MIDDEN = 1, /*!< Interrupt Priority Midden */ + SYS_IRQ_PRIORITY_HIGH = 2, /*!< Interrupt Priority High */ +} sys_irq_priority_t; + +#endif /* __ECLIC_PRESENT */ + + +typedef void (*fp_isr_t)(void); + +/** + * Exception Handler Function Typedef + */ +typedef void (*cb_excp_handler_t)(uint32_t cause, uint32_t sp); +//============================================================================= +// Macro Definition +//============================================================================= +/** + * Locate function to specific section + * e.g. + * uint32_t __FASTCODE foo(void) { return 123; } + */ +#define __FASTCODE __attribute__((__section__(".fastcode"))) + + +__STATIC_FORCEINLINE uint32_t* __get_pc(void) +{ + uint32_t *pc; + __asm__("auipc %0, 0" : "=r"(pc)); + return pc; +} + +__STATIC_FORCEINLINE uint32_t* __get_sp(void) +{ + uint32_t *sp; + __asm__("move %0, sp" : "=r"(sp)); + return sp; +} + +//============================================================================= +// Structure Definition +//============================================================================= +typedef struct excp_frame +{ + uint32_t ra; /* ra: x1, return address for jump */ + uint32_t tp; /* tp: x4, thread pointer */ + uint32_t t0; /* t0: x5, temporary register 0 */ + uint32_t t1; /* t1: x6, temporary register 1 */ + uint32_t t2; /* t2: x7, temporary register 2 */ + uint32_t a0; /* a0: x10, return value or function argument 0 */ + uint32_t a1; /* a1: x11, return value or function argument 1 */ + uint32_t a2; /* a2: x12, function argument 2 */ + uint32_t a3; /* a3: x13, function argument 3 */ + uint32_t a4; /* a4: x14, function argument 4 */ + uint32_t a5; /* a5: x15, function argument 5 */ + uint32_t cause; /* cause: machine cause csr register */ + uint32_t epc; /* epc: machine exception program counter csr register */ + uint32_t msubm; /* msubm: machine sub-mode csr register, nuclei customized */ +} excp_frame_t; + +typedef struct sys_irq_attr +{ + uint8_t trig_mode; /*!< the interrupt trigger mode, @ref sys_irq_trigger_t */ + uint8_t disable_vector; /*!< use vector table or not */ + uint8_t level; /*!< interupt nested level, + high-level (bigger value) will interrupt low-level, @ref sys_irq_level_t */ + uint8_t priority; /*!< interrupt priority, + the priority of the pended interrupts (when the same IRQ level), @ref sys_irq_priority_t + ps. This priority has NOTHING about nested interrup */ +} sys_irq_attr_t; +//============================================================================= +// Global Data Definition +//============================================================================= +extern volatile uint32_t g_SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ +extern volatile uint32_t g_SysTicks; +extern volatile uint32_t g_SysTickPeriod; +extern volatile uint32_t g_SysTickUnit_MS; +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +/** + * \brief Enable system tick + */ +__STATIC_FORCEINLINE void sys_enable_systick(void) +{ + SysTick_Reload(g_SysTickPeriod); + ECLIC_EnableIRQ(SysTimer_IRQn); + SysTimer_Start(); + return; +} + +/** + * \brief Disable system tick + */ +__STATIC_FORCEINLINE void sys_disable_systick(void) +{ + ECLIC_DisableIRQ(SysTimer_IRQn); + SysTimer_Stop(); + return; +} + +/** + * \brief Trigger software interrupt through system timer + * + * \return None + */ +__STATIC_FORCEINLINE void sys_launch_swi(void) +{ + SysTimer_SetSWIRQ(); + return; +} + +/** + * \brief Clear software interrupt + * + * \return None + */ +__STATIC_FORCEINLINE void sys_clear_swi(void) +{ + SysTimer_ClearSWIRQ(); + return; +} + +/** + * \brief Clear interrupt flags of interrupt controller + * + * \param [in] irq_id the target IRQ Id, @ref IRQn_Type + * \return None + */ +__STATIC_FORCEINLINE void sys_clear_IRQFlag(IRQn_Type irq_id) +{ + ECLIC_ClearPendingIRQ(irq_id); + return; +} + +/** + * \brief Get the pending specific interrupt of interrupt controller + * + * \param [in] irq_id the target IRQ Id, @ref IRQn_Type + * \return + * IRQ is pending or not + * + */ +__STATIC_FORCEINLINE int sys_get_IRQPending(IRQn_Type irq_id) +{ + return ECLIC_GetPendingIRQ(irq_id); +} + +/** + * \brief Get system ticks + * + * \return + * System Ticks + */ +__STATIC_FORCEINLINE uint32_t sys_get_tick(void) +{ + return g_SysTicks; +} + +/** + * \brief Open interrupt source of interrupt controller + * + * \param [in] irq_id the target IRQ Id, @ref IRQn_Type + * \return None + */ +__STATIC_FORCEINLINE void sys_open_IRQ(IRQn_Type irq_id) +{ + ECLIC_EnableIRQ(irq_id); + ECLIC_ClearPendingIRQ(irq_id); + return; +} + +/** + * \brief Close interrupt source of interrupt controller + * + * \param [in] irq_id the target IRQ Id, @ref IRQn_Type + * \return None + */ +__STATIC_FORCEINLINE void sys_close_IRQ(IRQn_Type irq_id) +{ + ECLIC_DisableIRQ(irq_id); + return; +} + +/** + * \brief Enable global interrupt + * + * \return None + */ +__STATIC_FORCEINLINE void sys_enable_girq(void) +{ + __enable_irq(); + return; +} + +/** + * \brief Disable global interrupt + * + * \return None + */ +__STATIC_FORCEINLINE void sys_disable_girq(void) +{ + __disable_irq(); + return; +} + +/** + * \brief system high accuracy delay with systick + * + * \param [in] msec milli-seconds + * \return None + */ +void sys_delay(uint32_t msec); + +/** + * \brief system low accuracy delay with the CPU tick + * + * \param [in] ticks the CPU ticks + * \return None + */ +void sys_busy_wait(uint32_t ticks); + +/** + * \brief get system frequency + * + * \return the cpu frequency value + */ +uint32_t sys_get_cpu_freq(void); + +#if defined(__EXCP_PRESENT) && (__EXCP_PRESENT == 1) +/** + * \brief Register handler to Exception table + * + * \param [in] excp_id exception ID, @ref EXCPn_Type + * \param [in] excp_handler the handler function + * \return + * 0 : ok + * others: fail + */ +int sys_excp_register_handler(EXCPn_Type excp_id, uint32_t excp_handler); +#endif + +#if defined(__ECLIC_PRESENT) && (__ECLIC_PRESENT == 1) +/** + * \brief Set the attribute of the target interrupt + * + * \param [in] irq_id the terget IRQ ID, @ref IRQn_Type + * \param [in] pAttr pointer to a attribute of interrupt if necessary, @ref sys_irq_attr_t + * \return + * 0 : ok + * others: fail + */ +int sys_set_IRQAttr(IRQn_Type irq_id, sys_irq_attr_t *pAttr); + +/** + * \brief Register ISR to Interrupt + * + * \param [in] irq_id the terget IRQ ID, @ref IRQn_Type + * \param [in] cb_handler the ISR funciotn + * \param [in] pAttr pointer to a attribute of interrupt if necessary, @ref sys_irq_attr_t + * \return + * 0 : ok + * others: fail + */ +int sys_register_IRQ(IRQn_Type irq_id, void *cb_handler, sys_irq_attr_t *pAttr); + +#endif /* __ECLIC_PRESENT == 1 */ + +/** + * \brief Configure system tick + * + * \param [in] ticks period of ticks + * SYS_TICK_1_MS/ SYS_TICK_10_MS/ SYS_TICK_100_MS + */ +void sys_config_systick(uint32_t ticks); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/.DS_Store b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/.DS_Store new file mode 100644 index 0000000..65a9795 Binary files /dev/null and b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/.DS_Store differ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/Startup/startup.S b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/Startup/startup.S new file mode 100644 index 0000000..dcb3c91 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/Startup/startup.S @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2024 Padauk Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/****************************************************************************** + * \file startup.S + * \brief Modified NMSIS RISC-V Core based Core Device Startup File for + * RISC-V evaluation SoC which support RISC-V cores + * \version V1.00 + * \date 10/24/2024 + * + ******************************************************************************/ + +#include "riscv_encoding.h" + + .section .init + + .globl _start + .type _start,@function + +_start: + nop + /* ===== Startup Stage 1 ===== */ + csrc CSR_MSTATUS, MSTATUS_MIE + csrw CSR_MIE, 0x0 + + .option push + .option norelax + la gp, __global_pointer$ + la tp, __tls_base +#if defined(__riscv_zcmt) + la t0, __jvt_base$ + csrw CSR_JVT, t0 +#endif + .option pop + + la sp, _sp + +#if 0 + /* Disable/Enable ICE I/O */ + li a0, 0x00001C28 + li a1, 0x4000F804 + li a2, 0x80000000 + lw t0, (a1) + and t1, t0, a2 + beq t1, a2, 1f + li a0, 0x00201C28 +1: + li a1, 0xFFFFFFFF + li a2, 0x31454349 + lw t0, (a0) + beq t0, a1, 2f + beq t0, a2, 2f + li a0, 0x4001F02C + li a1, 0xE6530000 + sw a1, (a0) +2: +#endif + + li t0, MMISC_CTL_NMI_CAUSE_FFF + csrs CSR_MMISC_CTL, t0 + + li t0, MMISC_CTL_ZC + #if defined(__riscv_zcmp) || defined(__riscv_zcmt) + csrs CSR_MMISC_CTL, t0 + #else + csrc CSR_MMISC_CTL, t0 + #endif + + la t0, early_excp_entry + csrw CSR_MTVEC, t0 + + li t0, 0x3f + csrc CSR_MTVEC, t0 + csrs CSR_MTVEC, 0x3 + + csrci CSR_MCOUNTINHIBIT, 0x5 + + la a0, __fastcode_lma_start + la a1, __fastcode_vma_start + beq a0, a1, 2f + la a2, __fastcode_vma_end + bgeu a1, a2, 2f +1: + lw t0, (a0) + sw t0, (a1) + addi a0, a0, 4 + addi a1, a1, 4 + bltu a1, a2, 1b +2: + + la a0, _data_lma + la a1, _data + beq a0, a1, 2f + la a2, _edata + bgeu a1, a2, 2f +1: + lw t0, (a0) + sw t0, (a1) + addi a0, a0, 4 + addi a1, a1, 4 + bltu a1, a2, 1b +2: + + + la a0, __bss_start + la a1, _end + bgeu a0, a1, 2f +1: + sw zero, (a0) + addi a0, a0, 4 + bltu a0, a1, 1b +2: + + call sys_init + + call sys_premain_init + +#if defined(CONFIG_HAS_BPU) + li t0, MMISC_CTL_BPU + csrs CSR_MMISC_CTL, t0 +#endif + + /* ===== Call Main Function ===== */ + li a0, 0 + li a1, 0 + + call main + + call sys_postmain_fini + +1: + j 1b + + + .align 6 + .global early_excp_entry + .type early_excp_entry, @function +early_excp_entry: + wfi + j early_excp_entry diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/Startup/trap.S b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/Startup/trap.S new file mode 100644 index 0000000..eb049fe --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/Startup/trap.S @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2024 Padauk Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/****************************************************************************** + * \file trap.S + * \brief Modified NMSIS Interrupt and Exception Handling Template File + * for RISC-V evaluation SoC which support RISC-V cores + * \version V1.00 + * \date 10/24/2024 + * + ******************************************************************************/ + +#include "riscv_encoding.h" + +/****************************************************************************** + * \brief Global interrupt disabled + * \details + * This function disable global interrupt. + * \remarks + * - All the interrupt requests will be ignored by CPU. + */ +.macro DISABLE_MIE + csrc CSR_MSTATUS, MSTATUS_MIE +.endm + +/****************************************************************************** + * \brief Macro for context save + * \details + * This macro save ABI defined caller saved registers in the stack. + * \remarks + * - This Macro could use to save context when you enter to interrupt + * or exception + */ +/* Save caller registers */ +.macro SAVE_CONTEXT + + #ifndef __riscv_32e + /* rv32i */ + addi sp, sp, -20*REGBYTES + #else + /* rv32e */ + addi sp, sp, -14*REGBYTES + #endif /* __riscv_32e */ + + STORE x1, 0*REGBYTES(sp) + STORE x4, 1*REGBYTES(sp) + STORE x5, 2*REGBYTES(sp) + STORE x6, 3*REGBYTES(sp) + STORE x7, 4*REGBYTES(sp) + STORE x10, 5*REGBYTES(sp) + STORE x11, 6*REGBYTES(sp) + STORE x12, 7*REGBYTES(sp) + STORE x13, 8*REGBYTES(sp) + STORE x14, 9*REGBYTES(sp) + STORE x15, 10*REGBYTES(sp) + + #ifndef __riscv_32e + /* rv32i */ + STORE x16, 14*REGBYTES(sp) + STORE x17, 15*REGBYTES(sp) + STORE x28, 16*REGBYTES(sp) + STORE x29, 17*REGBYTES(sp) + STORE x30, 18*REGBYTES(sp) + STORE x31, 19*REGBYTES(sp) + #endif /* __riscv_32e */ +.endm + +/****************************************************************************** + * \brief Macro for restore caller registers + * \details + * This macro restore ABI defined caller saved registers from stack. + * \remarks + * - You could use this macro to restore context before you want return + * from interrupt or exeception + */ +/* Restore caller registers */ +.macro RESTORE_CONTEXT + LOAD x1, 0*REGBYTES(sp) + LOAD x4, 1*REGBYTES(sp) + LOAD x5, 2*REGBYTES(sp) + LOAD x6, 3*REGBYTES(sp) + LOAD x7, 4*REGBYTES(sp) + LOAD x10, 5*REGBYTES(sp) + LOAD x11, 6*REGBYTES(sp) + LOAD x12, 7*REGBYTES(sp) + LOAD x13, 8*REGBYTES(sp) + LOAD x14, 9*REGBYTES(sp) + LOAD x15, 10*REGBYTES(sp) + + #ifndef __riscv_32e + /* rv32i */ + LOAD x16, 14*REGBYTES(sp) + LOAD x17, 15*REGBYTES(sp) + LOAD x28, 16*REGBYTES(sp) + LOAD x29, 17*REGBYTES(sp) + LOAD x30, 18*REGBYTES(sp) + LOAD x31, 19*REGBYTES(sp) + + addi sp, sp, 20*REGBYTES + #else + /* rv32e */ + addi sp, sp, 14*REGBYTES + #endif /* __riscv_32e */ + +.endm + +/****************************************************************************** + * \brief Macro for save necessary CSRs to stack + * \details + * This macro store MCAUSE, MEPC, MSUBM to stack. + */ +.macro SAVE_CSR_CONTEXT + csrrwi x0, CSR_PUSHMCAUSE, 11 + csrrwi x0, CSR_PUSHMEPC, 12 + csrrwi x0, CSR_PUSHMSUBM, 13 +.endm + +/****************************************************************************** + * \brief Macro for restore necessary CSRs from stack + * \details + * This macro restore MSUBM, MEPC, MCAUSE from stack. + */ +.macro RESTORE_CSR_CONTEXT + LOAD x5, 13*REGBYTES(sp) + csrw CSR_MSUBM, x5 + LOAD x5, 12*REGBYTES(sp) + csrw CSR_MEPC, x5 + LOAD x5, 11*REGBYTES(sp) + csrw CSR_MCAUSE, x5 +.endm + +/****************************************************************************** + * \brief Exception/NMI Entry + * \details + * This function provide common entry functions for exception/nmi. + * \remarks + * This function provide a default exception/nmi entry. + * ABI defined caller save register and some CSR registers + * to be saved before enter interrupt handler and be restored before return. + */ + + .section .text.trap + .align 6 + .global excp_entry + .type excp_entry, @function +excp_entry: + + SAVE_CONTEXT + SAVE_CSR_CONTEXT + + csrr a0, mcause + mv a1, sp + + /** + * Call the exception handler function + * By default, the function template is provided in + * system_Device.c, you can adjust it as you want + */ + call sys_core_excp_handler + + RESTORE_CSR_CONTEXT + RESTORE_CONTEXT + + mret + + .size excp_entry, . - excp_entry + +/** + * \brief Non-Vector Interrupt Entry + * \details + * This function provide common entry functions for handling + * non-vector interrupts + * \remarks + * This function provide a default non-vector interrupt entry. + * ABI defined caller save register and some CSR registers need + * to be saved before enter interrupt handler and be restored before return. + */ + .section .text.irq + .align 2 + .weak irq_entry + .type irq_entry, @function +irq_entry: + + SAVE_CONTEXT + SAVE_CSR_CONTEXT + + csrrw ra, CSR_JALMNXTI, ra + + DISABLE_MIE + + RESTORE_CSR_CONTEXT + RESTORE_CONTEXT + + mret + + .size irq_entry, . - irq_entry + + + .section .text + .align 7 + .weak default_handler + .type default_handler, @function +Undef_Handler: +default_handler: +1: + j 1b + + .size default_handler, . - default_handler diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/interrupt.c b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/interrupt.c new file mode 100644 index 0000000..754ddcf --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/interrupt.c @@ -0,0 +1,119 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file interrupt.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "device.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +extern void default_handler(void); + +//============================================================================= +// Private Function Definition +//============================================================================= +/** + * \brief System Timer ISR + * + * \return None + */ +void eclic_mtim_handler(void) +{ + g_SysTicks++; + + // Reload Timer Interrupt + SysTick_Reload(g_SysTickPeriod); + return; +} + +/** + * \brief System Software ISR + * + * \return None + */ +__INTERRUPT void eclic_mswi_handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); + + sys_clear_swi(); + sys_clear_IRQFlag(SysSW_IRQn); + + RESTORE_IRQ_CSR_CONTEXT(); + return; +} + +__INTERRUPT void eclic_bwei_handler(void) +{ + return; +} + +__INTERRUPT void eclic_pmovi_handler(void) +{ + return; +} +//============================================================================= +// Public Function Definition +//============================================================================= + +/** + * irq vector table + */ +const fp_isr_t __Vectors[__ECLIC_INTNUM] __USED __attribute__((section (".mintvec"))) = +{ + (fp_isr_t)0, /* 0: Reserved */ + default_handler, /* 1: Reserved */ + default_handler, /* 2: Reserved */ + eclic_mswi_handler, /* 3: Machine software interrupt */ + default_handler, /* 4: Reserved */ + default_handler, /* 5: Reserved */ + default_handler, /* 6: Reserved */ + eclic_mtim_handler, /* 7: Machine timer interrupt */ + default_handler, /* 8: Reserved */ + default_handler, /* 9: Reserved */ + default_handler, /* 10: Reserved */ + default_handler, /* 11: Reserved */ + default_handler, /* 12: Reserved */ + default_handler, /* 13: Reserved */ + default_handler, /* 14: Reserved */ + default_handler, /* 15: Reserved */ + default_handler, /* 16: Reserved */ + eclic_bwei_handler, /* 17: Bus Error interrupt */ + eclic_pmovi_handler, /* 18: Performance Monitor */ + + /*========= external interrupt ================*/ + default_handler, /* 19: ext_irq Reserved */ + default_handler, /* 20: ext_irq Reserved */ + default_handler, /* 21: ext_irq Reserved */ + default_handler, /* 22: ext_irq Reserved */ + default_handler, /* 23: ext_irq Reserved */ + default_handler, /* 24: ext_irq Reserved */ + default_handler, /* 25: ext_irq Reserved */ + default_handler, /* 26: ext_irq Reserved */ + default_handler, /* 27: ext_irq Reserved */ + default_handler, /* 28: ext_irq Reserved */ + default_handler, /* 29: ext_irq Reserved */ + default_handler, /* 30: ext_irq Reserved */ + default_handler, /* 31: ext_irq Reserved */ + default_handler, /* 32: ext_irq Reserved */ + default_handler, /* 33: ext_irq Reserved */ +}; diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/syscalls.c b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/syscalls.c new file mode 100644 index 0000000..366b5ff --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/syscalls.c @@ -0,0 +1,201 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file syscalls.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/02 + * @license + * @description + */ + +#include +#include +#include +#include +#include +#include "nmsis_core.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= +#ifndef TIMEVAL_TO_TIMESPEC +#define TIMEVAL_TO_TIMESPEC(tv, ts) \ + do { \ + (ts)->tv_sec = (tv)->tv_sec; \ + (ts)->tv_nsec = (tv)->tv_usec * 1000; \ + } while (0) +#endif +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +__WEAK int _open(const char *name, int flags, int mode) +{ + return -1; +} + +__WEAK int _close(int fd) +{ + return -1; +} + +__WEAK ssize_t _read(int fd, void *ptr, size_t len) +{ + return 0; +} + +__WEAK ssize_t _write(int fd, const void *ptr, size_t len) +{ + return 0; +} + +__WEAK int _lseek(int file, int offset, int whence) +{ + return 0; +} + +__WEAK int _isatty(int fd) +{ + return 1; +} + +__WEAK int _stat(char *file, struct stat *st) +{ + st->st_mode = S_IFCHR; + return 0; +} + +__WEAK int _fstat(int file, struct stat *st) +{ + st->st_mode = S_IFCHR; + return 0; +} + + +__WEAK void _exit(int fd) +{ + while(1) + { + __WFI(); + } +} + +__WEAK int _wait(int *status) +{ + return -1; +} + +int _link(char *old, char *new) +{ + return -1; +} + +__WEAK int _unlink(const char *name) +{ + return -1; +} + + +__WEAK int _fork(void) +{ + return -1; +} + +__WEAK int _getpid(void) +{ + return 1; +} + +__WEAK int _kill(int pid, int sig) +{ + return -1; +} + +__WEAK int _execve(char *name, char **argv, char **env) +{ + return -1; +} + +__WEAK int _gettimeofday(struct timeval *tp, void *tzp) +{ + extern uint32_t SystemCoreClock; + uint64_t cycles; + + cycles = __get_rv_cycle(); + + tp->tv_sec = cycles / SystemCoreClock; + tp->tv_usec = (cycles % SystemCoreClock) * 1000000 / SystemCoreClock; + return 0; +} + +__WEAK int clock_gettime(clockid_t clock_id, struct timespec *tp) +{ + struct timeval tv; + int retval = -1; + + retval = _gettimeofday(&tv, NULL); + if (retval == 0) + { + TIMEVAL_TO_TIMESPEC(&tv, tp); + } + + return retval; +} + +__WEAK int clock_settime(clockid_t clock_id, const struct timespec *tp) +{ + return -1; +} + +__WEAK int clock_getres(clockid_t clock_id, struct timespec *res) +{ + extern uint32_t SystemCoreClock; + + res->tv_sec = 0; + res->tv_nsec = 1000000000l / SystemCoreClock; + + return 0; +} + +__WEAK clock_t _times(struct tms *buf) +{ + static struct timeval t0; + struct timeval t; + long long utime; + + /* When called for the first time, initialize t0. */ + if( t0.tv_sec == 0 && t0.tv_usec == 0 ) + { + _gettimeofday(&t0, 0); + } + + _gettimeofday(&t, 0); + + utime = (t.tv_sec - t0.tv_sec) * 1000000 + (t.tv_usec - t0.tv_usec); + buf->tms_utime = utime * CLOCKS_PER_SEC / 1000000; + buf->tms_stime = buf->tms_cstime = buf->tms_cutime = 0; + + return buf->tms_utime; +} + +__WEAK void *_sbrk(ptrdiff_t incr) +{ + return 0; +} diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/system_dev.c b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/system_dev.c new file mode 100644 index 0000000..0f1c46f --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/system_dev.c @@ -0,0 +1,424 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file system_dev.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#include "device.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_ENABLE_STACK_DEBUG 0 + +#if (CONFIG_ENABLE_STACK_DEBUG) + extern int sys_printf(const char* format, ...); + #define DEBUG(str, ...) sys_printf(str, ##__VA_ARGS__) +#else + #define DEBUG(str, ...) +#endif + +#if !defined(SYS_HIRC_VALUE) +#define SYS_HIRC_MHZ (60ul) +#define SYS_HIRC_VALUE (SYS_HIRC_MHZ * 1000ul * 1000ul) +#endif + +#if !defined(SYS_OSC_VALUE) +#define SYS_OSC_VALUE (8 * 1000ul * 1000ul) +#endif + +#if !defined(SYS_LIRC_VALUE) +#define SYS_LIRC_VALUE 32768ul +#endif + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +volatile uint32_t g_SystemCoreClock = SYS_HIRC_VALUE; +volatile uint32_t g_SysTicks = 0; +volatile uint32_t g_SysTickPeriod = 0; +volatile uint32_t g_SysTickUnit_MS = 0; + +//============================================================================= +// Private Function Definition +//============================================================================= + +#if defined(__EXCP_PRESENT) && (__EXCP_PRESENT == 1) + +/** + * Max exception handler number + */ +#define CONFIG_SYS_EXCP_MAX_NUM ((int)EXCPn_Total) + +/** + * \brief Store the exception handlers for each exception ID + * \note + * - This g_SysExcpHandlers are used to store all the handlers for all + * the exception codes Nuclei N100 core provided. + * - Exception code 0 - 11, totally 12 exceptions are mapped to g_SysExcpHandlers[0:11] + */ +static uint32_t g_SysExcpHandlers[CONFIG_SYS_EXCP_MAX_NUM] = {0}; +static uint32_t g_cb_nmi_handler = 0; + +/** + * @brief System Default Exception Handler + * This function provides a default exception handler for all exception IDs. + * By default, It will just print some information for debug, + * Vendor can customize it according to its requirements. + * + * @param [in] mcause code indicating the reason that caused the trap in machine mode + * @param [in] sp stack pointer + * @return + * None + */ +static void _sys_def_excp_handler(uint32_t mcause, uint32_t sp) +{ + DEBUG("MCAUSE : 0x%08X\n", mcause); + DEBUG("MEPC : 0x%08X\n", __RV_CSR_READ(CSR_MEPC)); + DEBUG("MTVAL : 0x%08X\n", __RV_CSR_READ(CSR_MTVAL)); + DEBUG("HARTID : %u\n", (unsigned int)__get_hart_id()); + + do{ /* Dump the frame of stack */ + DEBUG("ra: 0x%08X, tp: 0x%08X,\n" + "t0: 0x%08X, t1: 0x%08X, t2: 0x%08X,\n" + "a0: 0x%08X, a1: 0x%08X, a2: 0x%08X, a3: 0x%08X,\n" + "a4: 0x%08X, a5: 0x%08X,\n" + "cause: 0x%08X, epc: 0x%08X\n", + ((excp_frame_t*)sp)->ra, ((excp_frame_t*)sp)->tp, + ((excp_frame_t*)sp)->t0, ((excp_frame_t*)sp)->t1, ((excp_frame_t*)sp)->t2, + ((excp_frame_t*)sp)->a0, ((excp_frame_t*)sp)->a1, ((excp_frame_t*)sp)->a2, ((excp_frame_t*)sp)->a3, + ((excp_frame_t*)sp)->a4, ((excp_frame_t*)sp)->a5, + ((excp_frame_t*)sp)->cause, ((excp_frame_t*)sp)->epc); + DEBUG("sp: 0x%08X\n", (int)__get_sp()); + + #ifndef __riscv_32e + /* rv32i */ + DEBUG("t3: 0x%08X, t4: 0x%08X, t5: 0x%08X, t6: 0x%08X,\n" + "a6: 0x%08X, a7: 0x%08X\n", + ((excp_frame_t*)sp)->t3, ((excp_frame_t*)sp)->t4, ((excp_frame_t*)sp)->t5, ((excp_frame_t*)sp)->t6, + ((excp_frame_t*)sp)->a6, ((excp_frame_t*)sp)->a7); + #endif /* __riscv_32e */ + }while(0); + + while (1) + { + __WFI(); + } +} + + +/** + * @brief Common Exception handler entry + * This function provided a command entry for exception. + * Silicon Vendor could modify this template implementation according to requirement. + * @param [in] mcause code indicating the reason that caused the trap in machine mode + * @param [in] sp stack pointer + * @return + * 0 + * \remarks + * - RISCV provided common entry for all types of exception. This is proposed code template + * for exception entry function, Silicon Vendor could modify the implementation. + * - For the sys_core_excp_handler template, we provided exception register function \ref Exception_Register_EXC + * which can help developer to register your exception handler for specific exception number. + */ +__WEAK uint32_t sys_core_excp_handler(uint32_t mcause, uint32_t sp) +{ + uint32_t excp_code = (uint32_t)(mcause & 0x00000FFF); + cb_excp_handler_t cb_excp_handler = 0; + + cb_excp_handler = (excp_code == EXCPn_NMI) ? (cb_excp_handler_t)g_cb_nmi_handler + : (excp_code < CONFIG_SYS_EXCP_MAX_NUM) ? (cb_excp_handler_t)g_SysExcpHandlers[excp_code] + : (cb_excp_handler_t)_sys_def_excp_handler; + + if( cb_excp_handler ) + { + cb_excp_handler(mcause, sp); + } + return 0; +} + + +/** + * @brief Initialize all the default exception handlers + * The core exception handler for each exception ID + * will be initialized to @ref _sys_def_excp_handler. + * ps. Called in @ref sys_premain_init function, + * used to initialize default exception handlers for all exception IDs + * @return + * None + */ +__WEAK void sys_excp_init(void) +{ + extern void excp_entry(void); + + g_cb_nmi_handler = (uint32_t)_sys_def_excp_handler; + for(int i = 0; i < CONFIG_SYS_EXCP_MAX_NUM; i++) + { + g_SysExcpHandlers[i] = (uint32_t)_sys_def_excp_handler; + } + + __RV_CSR_WRITE(CSR_MTVEC, (uint32_t)excp_entry | 0x3ul); + + return; +} + +__WEAK int sys_excp_register_handler(EXCPn_Type excp_id, uint32_t excp_handler) +{ + if( (int)excp_id == EXCPn_NMI ) + { + g_cb_nmi_handler = excp_handler; + } + else if( (int)excp_id < CONFIG_SYS_EXCP_MAX_NUM ) + { + g_SysExcpHandlers[excp_id] = (uint32_t)excp_handler; + } + else + return -1; + + return 0; +} + +#else /* __EXCP_PRESENT == 1 */ + #define sys_excp_init() + #define sys_excp_register_handler() +#endif /* __EXCP_PRESENT == 1 */ + + +#if defined(__ECLIC_PRESENT) && (__ECLIC_PRESENT == 1) +/** + * @brief Initialize interrupt config + * Interrupt needs be initialized after boot up + * + * @return None + */ +static void sys_interrupt_init(void) +{ + extern const fp_isr_t __Vectors[__ECLIC_INTNUM]; + extern void irq_entry(void); + + __RV_CSR_WRITE(CSR_MTVT, (uint32_t)__Vectors); + __RV_CSR_WRITE(CSR_MTVT2, (uint32_t)irq_entry | 0x1ul); + + ECLIC_SetMth(0); + ECLIC_SetCfgNlbits(__ECLIC_INTCTLBITS); + + return; +} + +int sys_set_IRQAttr(IRQn_Type irq_id, sys_irq_attr_t *pAttr) +{ + if( irq_id >= __ECLIC_INTNUM || !pAttr ) + return -1; + + /* set interrupt vector mode */ + ECLIC_SetShvIRQ(irq_id, + (pAttr->disable_vector) ? ECLIC_NON_VECTOR_INTERRUPT : ECLIC_VECTOR_INTERRUPT); + + ECLIC_SetTrigIRQ(irq_id, pAttr->trig_mode); /* set interrupt vector mode */ + ECLIC_SetLevelIRQ(irq_id, pAttr->level); /* set interrupt level */ + ECLIC_SetPriorityIRQ(irq_id, pAttr->priority); /* set interrupt priority */ + + /* enable interrupt */ + ECLIC_EnableIRQ(irq_id); + + return 0; +} + +int sys_register_IRQ(IRQn_Type irq_id, void *cb_handler, sys_irq_attr_t *pAttr) +{ + if( irq_id >= __ECLIC_INTNUM || !cb_handler || !pAttr ) + return -1; + + ECLIC_DisableIRQ(irq_id); + + if( cb_handler ) + { + /* set interrupt handler entry to vector table */ + ECLIC_SetVector(irq_id, (rv_csr_t)cb_handler); + } + + sys_set_IRQAttr(irq_id, pAttr); + + return 0; +} + +#else /* __ECLIC_PRESENT == 1 */ + #define sys_interrupt_init() +#endif /* __ECLIC_PRESENT == 1 */ + + +/** + * \brief early init function before main + * + * \return + * none + * \details + * This function is executed right before main function. + * For RISC-V gnu toolchain, _init function might not be called + * by __libc_init_array function, so we defined a new function + * to do initialization + */ +void sys_premain_init(void) +{ + SysTimer_Stop(); + + g_SysTickPeriod = SYS_TICK_1_MS; + g_SysTicks = 0; + g_SystemCoreClock = sys_get_cpu_freq(); + + sys_excp_init(); + + sys_interrupt_init(); + + return; +} + +/** + * \brief finish function after main + * + * \param [in] status + * \return + * + * \details + * This function is executed right after main function. + * For RISC-V gnu toolchain, _fini function might not be called + * by __libc_fini_array function, so we defined a new function + * to do initialization + */ +void sys_postmain_fini(int status) +{ + return; +} + + +//============================================================================= +// Public Function Definition +//============================================================================= +void sys_init(void) +{ + /** + * Configure eFlash + * + Set eFlash latency + * + Disable and clear interrup + */ + FLASH->CMD = 0xA5A50020ul; + FLASH->SR = 0xFFFFFFFFul; + FLASH->DIV = (FLASH->DIV & ~FLASH_DIV_DIV_Msk) | \ + (SYS_HIRC_MHZ << FLASH_DIV_DIV_Pos) | \ + (0x1ul << 8); + +#if 1 + SYSCFG->PCLKEN |= SYSCFG_PCLKEN_AMISC_Msk; + AMISC->HSI_CR = (AMISC->HSI_CR & ~AMISC_HSI_CR_LDO_SEL_Msk) | \ + (AMISC_HSI_CR_LDO_SEL_LDO << AMISC_HSI_CR_LDO_SEL_Pos); +#endif + + return; +} + +/** + * \brief delay a time in milliseconds + * + * \param [in] msec count in milliseconds + * \return + * none + */ +void sys_delay(uint32_t msec) +{ +#if defined(__SYSTIMER_PRESENT) && (__SYSTIMER_PRESENT == 1) + /** + * Only for 1ms system tick + */ + uint32_t tick_start = 0; + + tick_start = g_SysTicks; + while( (g_SysTicks - tick_start) < msec ) + { + } + +#else + #warning "sys_delay_1ms function require system timer present, if you are using this, it will not work" +#endif +} + +void sys_busy_wait(uint32_t ticks) +{ + while( ticks-- ); + return; +} + +uint32_t sys_get_cpu_freq(void) +{ + if( (SYSCFG->SYSCLKCR & SYSCFG_SYSCLKCR_CLKSW_Msk) + == (SYSCFG_SYSCLKCR_CLKSW_HSI << SYSCFG_SYSCLKCR_CLKSW_Pos) ) + { + g_SystemCoreClock = SYS_HIRC_VALUE; + } + else if( (SYSCFG->SYSCLKCR & SYSCFG_SYSCLKCR_CLKSW_Msk) + == SYSCFG_SYSCLKCR_CLKSW_LSI << SYSCFG_SYSCLKCR_CLKSW_Pos ) + { + g_SystemCoreClock = SYS_LIRC_VALUE; + } + else if( (SYSCFG->SYSCLKCR & SYSCFG_SYSCLKCR_CLKSW_Msk) + == (SYSCFG_SYSCLKCR_CLKSW_HSE << SYSCFG_SYSCLKCR_CLKSW_Pos) ) + { + g_SystemCoreClock = SYS_OSC_VALUE; + } + else + { + uint32_t div = (SYSCFG->SYSCLKCR & SYSCFG_SYSCLKCR_CLKDIV_Msk) >> SYSCFG_SYSCLKCR_CLKDIV_Pos; + div = (div) ? (div + 1) : 2; + g_SystemCoreClock = SYS_HIRC_VALUE / div; + } + + return g_SystemCoreClock; +} + +void sys_config_systick(uint32_t ticks) +{ + volatile register uint32_t value = 0; + uint32_t sys_clock = SYS_HIRC_VALUE; + + if( (SYSCFG->SYSCLKCR & SYSCFG_SYSCLKCR_CLKSW_Msk) + == (SYSCFG_SYSCLKCR_CLKSW_CLKDIV << SYSCFG_SYSCLKCR_CLKSW_Pos) ) + { + uint32_t div = (SYSCFG->SYSCLKCR & SYSCFG_SYSCLKCR_CLKDIV_Msk) >> SYSCFG_SYSCLKCR_CLKDIV_Pos; + div = (div) ? (div + 1) : 2; + sys_clock = SYS_HIRC_VALUE / div; + } + + + value = (SYSCFG->SYSCLKCR & SYSCFG_SYSCLKCR_SYSTICKCR_Msk) >> SYSCFG_SYSCLKCR_SYSTICKCR_Pos; + + g_SysTickUnit_MS = (value == SYSCFG_SYSCLKCR_SYSTICKCR_HSI_DIV2) ? (sys_clock / 2000ul) : + (value == SYSCFG_SYSCLKCR_SYSTICKCR_HSI_DIV4) ? (sys_clock / 4000ul) : + (value == SYSCFG_SYSCLKCR_SYSTICKCR_HSI_DIV8) ? (sys_clock / 8000ul) : + (SYS_TIMER_FREQ / 1000ul); + + g_SysTickPeriod = (ticks == SYS_TICK_10_MS) ? (10ul * g_SysTickUnit_MS) : + (ticks == SYS_TICK_100_MS) ? (100ul * g_SysTickUnit_MS) : + (ticks == SYS_TICK_1_SEC) ? (1000ul * g_SysTickUnit_MS) : + g_SysTickUnit_MS; + + __disable_irq(); + + SysTimer_Stop(); + SysTick_Config(g_SysTickPeriod); + SysTimer_Start(); + + __enable_irq(); + return; +} diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/.DS_Store b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/.DS_Store new file mode 100644 index 0000000..62e3561 Binary files /dev/null and b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/.DS_Store differ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_adc.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_adc.h new file mode 100644 index 0000000..5f438fa --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_adc.h @@ -0,0 +1,527 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_adc.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/10 + * @license + * @description + */ + +#ifndef __hal_adc_H_wiD001de_llts_HbDE_s9jK_uDX2acTbwqSx__ +#define __hal_adc_H_wiD001de_llts_HbDE_s9jK_uDX2acTbwqSx__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_def.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define ADC_AIN_CHANNEL_NUM 16 + +/** + * ADC AIN channels + * ps. Channel-0 conversion priority is the highest and + * Channel-15 conversion priority is the lowest + */ +typedef enum ADC_Channels +{ + ADC_Channel_00 = (0x1ul << 0 ), + ADC_Channel_01 = (0x1ul << 1 ), + ADC_Channel_02 = (0x1ul << 2 ), + ADC_Channel_03 = (0x1ul << 3 ), + ADC_Channel_04 = (0x1ul << 4 ), + ADC_Channel_05 = (0x1ul << 5 ), + ADC_Channel_06 = (0x1ul << 6 ), + ADC_Channel_07 = (0x1ul << 7 ), + ADC_Channel_08 = (0x1ul << 8 ), + ADC_Channel_09 = (0x1ul << 9 ), + ADC_Channel_10 = (0x1ul << 10), + ADC_Channel_11 = (0x1ul << 11), + ADC_Channel_12 = (0x1ul << 12), + ADC_Channel_13 = (0x1ul << 13), + ADC_Channel_14 = (0x1ul << 14), + ADC_Channel_15 = (0x1ul << 15), + + ADC_Channel_OPA0_O = ADC_Channel_00, + ADC_Channel_OPA1_O = ADC_Channel_01, + ADC_Channel_AVSS = ADC_Channel_14, + ADC_Channel_AMISC = ADC_Channel_15, // It should configure AMISC->VBUF_CR_b.ANA_SEL +} ADC_ChannelsTypeDef; + +/** + * Sub-Channels of Channel-AMISC (channel-15) of ADC + * ref. AMISC->VBUF_CR_b.ANA_SEL + */ +typedef enum ADC_SubChannel +{ + ADC_SubChannel_NONE = (AMISC_VBUF_CR_ANA_SEL_NONE << AMISC_VBUF_CR_ANA_SEL_Pos), + ADC_SubChannel_TEMP = (AMISC_VBUF_CR_ANA_SEL_TEMP << AMISC_VBUF_CR_ANA_SEL_Pos), + ADC_SubChannel_DAC0 = (AMISC_VBUF_CR_ANA_SEL_DAC0 << AMISC_VBUF_CR_ANA_SEL_Pos), + ADC_SubChannel_DAC1 = (AMISC_VBUF_CR_ANA_SEL_DAC1 << AMISC_VBUF_CR_ANA_SEL_Pos), + ADC_SubChannel_VBuf_1_5 = (AMISC_VBUF_CR_ANA_SEL_VBuf_1p5v << AMISC_VBUF_CR_ANA_SEL_Pos), + ADC_SubChannel_VDDL = (AMISC_VBUF_CR_ANA_SEL_VDDL << AMISC_VBUF_CR_ANA_SEL_Pos), + ADC_SubChannel_VSS = (AMISC_VBUF_CR_ANA_SEL_VSS << AMISC_VBUF_CR_ANA_SEL_Pos), + ADC_SubChannel_VDD = (AMISC_VBUF_CR_ANA_SEL_VDD << AMISC_VBUF_CR_ANA_SEL_Pos), +} ADC_SubChannelTypeDef; + +/** + * ADC working clock divides + * Note 1: The Working-Clock of ADC MUST be 800KHz ~ 16MHz + * Note 2: It MUST wait 20-cycles after change ADC working-clock + */ +typedef enum ADC_ClkDiv +{ + ADC_ClkDiv_Auto = 0, + ADC_ClkDiv_2 = (ADC_CON0_CLK_Div2 << ADC_CON0_CLK_Pos), + ADC_ClkDiv_4 = (ADC_CON0_CLK_Div4 << ADC_CON0_CLK_Pos), + ADC_ClkDiv_8 = (ADC_CON0_CLK_Div8 << ADC_CON0_CLK_Pos), + ADC_ClkDiv_16 = (ADC_CON0_CLK_Div16 << ADC_CON0_CLK_Pos), + ADC_ClkDiv_32 = (ADC_CON0_CLK_Div32 << ADC_CON0_CLK_Pos), + ADC_ClkDiv_3_75 = (ADC_CON0_CLK_Div3_75 << ADC_CON0_CLK_Pos), + ADC_ClkDiv_3_5 = (ADC_CON0_CLK_Div3_5 << ADC_CON0_CLK_Pos), +} ADC_ClkDivTypeDef; + +/** + * ADC mode + */ +typedef enum ADC_Mode +{ + ADC_Mode_SingleConv = 0, + ADC_Mode_Continuous, /*!< ADC Continuous mode will be Never-Stop-Conversion. + This mode NOT support interrupt. */ + ADC_Mode_Scan, + ADC_Mode_Discontinuous, +} ADC_ModeTypeDef; + +/** + * ADC external trigger source for conversion + */ +typedef enum ADC_ExtTrigSource +{ + ADC_ExtTrigSource_00 = 0x0, + ADC_ExtTrigSource_01 = 0x1, + ADC_ExtTrigSource_02 = 0x2, + ADC_ExtTrigSource_03 = 0x3, + ADC_ExtTrigSource_04 = 0x4, + ADC_ExtTrigSource_05 = 0x5, + ADC_ExtTrigSource_06 = 0x6, + ADC_ExtTrigSource_07 = 0x7, + ADC_ExtTrigSource_08 = 0x8, + ADC_ExtTrigSource_09 = 0x9, + ADC_ExtTrigSource_10 = 0xA, + ADC_ExtTrigSource_11 = 0xB, + ADC_ExtTrigSource_12 = 0xC, + ADC_ExtTrigSource_13 = 0xD, + ADC_ExtTrigSource_14 = 0xE, + ADC_ExtTrigSource_15 = 0xF, + ADC_ExtTrigSource_16 = 0x1D, + ADC_ExtTrigSource_17 = 0x1E, + ADC_ExtTrigSource_Soft = 0xFF, /*!< ADC Software trigger */ + + ADC_ExtTrigSource_EPWM_CH1R = ADC_ExtTrigSource_00, /*!< ADC external source trigger from EPWM CH1 Rising */ + ADC_ExtTrigSource_EPWM_CH2R = ADC_ExtTrigSource_01, /*!< ADC external source trigger from EPWM CH2 Rising */ + ADC_ExtTrigSource_EPWM_CH3R = ADC_ExtTrigSource_02, /*!< ADC external source trigger from EPWM CH3 Rising */ + ADC_ExtTrigSource_EPWM_CH1F = ADC_ExtTrigSource_03, /*!< ADC external source trigger from EPWM CH1 Falling */ + ADC_ExtTrigSource_EPWM_CH2F = ADC_ExtTrigSource_04, /*!< ADC external source trigger from EPWM CH2 Falling */ + ADC_ExtTrigSource_EPWM_CH3F = ADC_ExtTrigSource_05, /*!< ADC external source trigger from EPWM CH3 Falling */ + ADC_ExtTrigSource_COMP0_Rise = ADC_ExtTrigSource_06, /*!< ADC external source trigger from COMP0 Rising */ + ADC_ExtTrigSource_COMP1_Rise = ADC_ExtTrigSource_08, /*!< ADC external source trigger from COMP1 Rising */ + ADC_ExtTrigSource_COMP0_Fall = ADC_ExtTrigSource_07, /*!< ADC external source trigger from COMP0 Falling */ + ADC_ExtTrigSource_COMP1_Fall = ADC_ExtTrigSource_09, /*!< ADC external source trigger from COMP1 Falling */ + ADC_ExtTrigSource_EPWM_UDF = ADC_ExtTrigSource_10, /*!< ADC external source trigger from EPWM Counter UDF */ + ADC_ExtTrigSource_EPWM_OVF = ADC_ExtTrigSource_11, /*!< ADC external source trigger from EPWM Counter OVF */ + ADC_ExtTrigSource_EPWM_CCR4_UP = ADC_ExtTrigSource_12, /*!< ADC external source trigger from EPWM_CNTUP == CCR4 */ + ADC_ExtTrigSource_EPWM_CCDR4_UP = ADC_ExtTrigSource_13, /*!< ADC external source trigger from EPWM_CNTUP == CCDR4 */ + ADC_ExtTrigSource_EPWM_CCR4_DN = ADC_ExtTrigSource_14, /*!< ADC external source trigger from EPWM_CNTDN == CCR4 */ + ADC_ExtTrigSource_EPWM_CCDR4_DN = ADC_ExtTrigSource_15, /*!< ADC external source trigger from EPWM_CNTDN == CCDR4 */ + ADC_ExtTrigSource_TIM0 = ADC_ExtTrigSource_16, /*!< ADC external source trigger from Tim0 */ + ADC_ExtTrigSource_PB1 = (ADC_ExtTrigSource_17), /*!< ADC external source trigger from Pin (PB1) */ + ADC_ExtTrigSource_PB2 = (ADC_ExtTrigSource_17 | 0x20ul), /*!< ADC external source trigger from Pin (PB2) */ +} ADC_ExtTrigSourceTypeDef; + +typedef enum ADC_ExtTrigMode +{ + ADC_ExtTrigMode_Disable = 0ul, + ADC_ExtTrigMode_Enable = 0x1ul, + ADC_ExtTrigMode_PinRising = ADC_ExtTrigMode_Enable, // Be used when external source is ADC_ExtTrigSource_17 + ADC_ExtTrigMode_PinFaling = (ADC_ExtTrigMode_Enable | 0x2ul), // Be used when external source is ADC_ExtTrigSource_17 +} ADC_ExtTrigModeTypeDef; + +/** + * ADC Data Align + */ +typedef enum ADC_DataAlign +{ + ADC_DataAlign_Right = (ADC_CON0_ALIGN_RIGHT << ADC_CON0_ALIGN_Pos), + ADC_DataAlign_Left = (ADC_CON0_ALIGN_LEFT << ADC_CON0_ALIGN_Pos), +} ADC_DataAlignTypeDef; + +/** + * The ADC interrupt type + */ +typedef enum ADC_IT +{ + ADC_IT_DISABLE = (ADC_CON0_INT_EN_DISABLE << ADC_CON0_INT_EN_Pos), + ADC_IT_CONV_DONE = (ADC_CON0_INT_EN_DONE << ADC_CON0_INT_EN_Pos), /*!< ADC conversion is done */ + ADC_IT_LOWER_THRESHOLD = (ADC_CON0_INT_EN_LT_THR << ADC_CON0_INT_EN_Pos), /*!< ADC conversion value is below threshold */ + ADC_IT_HIGHER_THRESHOLD = (ADC_CON0_INT_EN_GT_THR << ADC_CON0_INT_EN_Pos), /*!< ADC conversion value is above threshold */ + ADC_IT_EQUAL_THRESHOLD = (ADC_CON0_INT_EN_EQ_THR << ADC_CON0_INT_EN_Pos), /*!< ADC conversion value is equal to threshold */ + ADC_IT_CONV_GROUP_SUBSET = (0x80000000ul | ADC_CHSEL_DISC_INTSEL_Msk), + ADC_IT_CONV_GROUP_DONE = 0x80000000ul, +} ADC_ITTypeDef; + +/** + * The ADC interrupt status + */ +typedef enum ADC_ITStatus +{ + ADC_ITStatus_None = (ADC_STAT_COMP_RESULT_NONE << ADC_STAT_COMP_RESULT_Pos), + ADC_ITStatus_LowerThreshold = (ADC_STAT_COMP_RESULT_LT_THR << ADC_STAT_COMP_RESULT_Pos), + ADC_ITStatus_HigherThreshold = (ADC_STAT_COMP_RESULT_GT_THR << ADC_STAT_COMP_RESULT_Pos), + ADC_ITStatus_EqualThreshold = (ADC_STAT_COMP_RESULT_EQ_THR << ADC_STAT_COMP_RESULT_Pos), +} ADC_ITStatusTypeDef; + +/** + * The brake source type from an ADC channel + */ +typedef enum ADC_BKSrc +{ + ADC_BKSrc_Src1 = 0, + ADC_BKSrc_Src2 = 8, +} ADC_BKSrcTypeDef; + +/** + * The ADC brake filter type + */ +typedef enum ADC_BKFilter +{ + ADC_BKFilter_MATCH_1 = (ADC_BKSEL_BK1_FLT_OFF << ADC_BKSEL_BK1_FLT_Pos), + ADC_BKFilter_MATCH_2 = (ADC_BKSEL_BK1_FLT_MATCH_2 << ADC_BKSEL_BK1_FLT_Pos), + ADC_BKFilter_MATCH_4 = (ADC_BKSEL_BK1_FLT_MATCH_4 << ADC_BKSEL_BK1_FLT_Pos), + ADC_BKFilter_MATCH_7 = (ADC_BKSEL_BK1_FLT_MATCH_7 << ADC_BKSEL_BK1_FLT_Pos), +} ADC_BKFilterTypeDef; + +/** + * The Brake condition with the ADC brake source + */ +typedef enum ADC_BKCond +{ + ADC_BKCond_Disabe = (ADC_BKSEL_BK1_EN_OFF << ADC_BKSEL_BK1_EN_Pos), + ADC_BKCond_LOWER_THRESHOLD = (ADC_BKSEL_BK1_EN_GT_THR << ADC_BKSEL_BK1_EN_Pos), + ADC_BKCond_HIGHER_THRESHOLD = (ADC_BKSEL_BK1_EN_LT_THR << ADC_BKSEL_BK1_EN_Pos), + ADC_BKCond_EQUAL_THRESHOLD = (ADC_BKSEL_BK1_EN_EQ_THR << ADC_BKSEL_BK1_EN_Pos), +} ADC_BKCondTypeDef; + +//============================================================================= +// Macro Definition +//============================================================================= +/** + * \brief ADC Start + * ps. This API MUST be called after ADC_Init() + * + * \param [in] pHADC Pointer to an ADC handler + * \return + * None + */ +__STATIC_FORCEINLINE void ADC_Start(ADC_Type *pHADC) +{ + REG_SET_BITS(pHADC->STAT, ADC_STAT_INT_CLR_Msk); // clear flag + REG_SET_BITS(pHADC->CON0, ADC_CON0_START_Msk); + + sys_busy_wait(32); + return; +} + +/** + * \brief ADC conversion is idle or not + * + * \param [in] pHADC Pointer to an ADC handler + * \return + * 0: busy, others: idle + */ +__STATIC_FORCEINLINE uint32_t ADC_IsIdle(ADC_Type *pHADC) +{ + return REG_READ_MASK(pHADC->STAT, ADC_STAT_DONE_Msk); +} + +/** + * \brief Get the status of interrupt of ADC + * + * \param [in] pHADC Pointer to an ADC handler + * \return + * Interrupt flags, @ref ADC_ITStatusTypeDef + */ +__STATIC_FORCEINLINE ADC_ITStatusTypeDef ADC_GetITStatus(ADC_Type *pHADC) +{ + return REG_READ_MASK(pHADC->STAT, ADC_STAT_COMP_RESULT_Msk); +} + +/** + * \brief ADC Clear interrupt flag + * + * \param [in] pHADC + * \return + * None + */ +__STATIC_FORCEINLINE void ADC_ClearITFlag(ADC_Type *pHADC) +{ + REG_SET_BITS(pHADC->STAT, ADC_STAT_INT_CLR_Msk); + return; +} + +/** + * \brief Set the subset number of grouped-channels in ADC Discontinuous mode + * + * \param [in] pHADC Pointer to an ADC handler + * \param [in] subset_ch_num the subset channel number of a group + * ps. the group_ch_num ONLY be 1 ~ 8 + * \return + * None + */ +__STATIC_FORCEINLINE void ADC_DiscMode_SetGroupSubsetNum(ADC_Type *pHADC, uint8_t subset_ch_num) +{ + REG_WRITE_MASK(pHADC->CHSEL, ADC_CHSEL_DISCNUM_Msk, (subset_ch_num - 1) << ADC_CHSEL_DISCNUM_Pos); + return; +} + +/** + * \brief Get the EOC count of ADC + * + * \param [in] pHADC Pointer to an ADC handler + * \return + * The EOC count of ADC + */ +__STATIC_FORCEINLINE uint8_t ADC_GetEOCCnt(ADC_Type *pHADC) +{ + return (uint8_t)pHADC->STAT_b.EOC_CNT; +} + +/** + * \brief Enable/Disable backup ADC conversion value + * + * \param [in] pHADC Pointer to an ADC handler + * \return + * None + */ +__STATIC_FORCEINLINE void ADC_EnableBackup(ADC_Type *pHADC) +{ + REG_SET_BITS(pHADC->CON0, ADC_CON0_BAKEN_Msk); + return; +} + +__STATIC_FORCEINLINE void ADC_DisableBackup(ADC_Type *pHADC) +{ + REG_CLR_BITS(pHADC->CON0, ADC_CON0_BAKEN_Msk); + return; +} + +/** + * \brief Get the backup of ADC conversion value + * + * \param [in] pHADC Pointer to an ADC handler + * \return + * The backup value + */ +__STATIC_FORCEINLINE uint16_t ADC_GetBakcupValue(ADC_Type *pHADC) +{ + return (uint16_t)pHADC->BAKDAT_b.BAKDAT; +} + + +/** + * \brief Set the sample-period of an ADC + * + * \param [in] pHADC Pointer to an ADC handler + * \param [in] cycles extern cycles (range: 0 ~ 31, default: 3) + * \return + * None + */ +__STATIC_FORCEINLINE void ADC_SetSampleCycles(ADC_Type *pHADC, uint8_t cycles) +{ + pHADC->STAT_b.TS_SET = cycles; + return; +} + + +/** + * \brief Get the conversion value of the ADC in ISR + * + * \param [in] pHADC Pointer to an ADC handler + * \param [in] channel The target channel, @ref ADC_ChannelsTypeDef + * \return + * The ADC conversion value + */ +__STATIC_FORCEINLINE uint16_t ADC_ITGetConvValue(ADC_Type *pHADC, ADC_ChannelsTypeDef channel) +{ +#define __ADC_CLZ(x) __builtin_clz(x) + volatile uint32_t *pData = (volatile uint32_t*)&pHADC->DAT0; + uint32_t chnnl_id = (31ul - __ADC_CLZ(channel)); + + pData += (chnnl_id & 0xFul); + return (uint16_t)((*pData) & 0xFFFFul); +} + +/** + * \brief Disable interrupt of ADC + * + * \param [in] pHADC Pointer to an ADC handler + * \return + * None + */ +__STATIC_FORCEINLINE void ADC_ITDisable(ADC_Type *pHADC) +{ + REG_WRITE_MASK(pHADC->CON0, ADC_CON0_INT_EN_Msk, ADC_IT_DISABLE); + return; +} + +//============================================================================= +// Structure Definition +//============================================================================= +/** + * ADC initialization info + */ +typedef struct ADC_Init +{ + ADC_ChannelsTypeDef SelChannels; + ADC_ClkDivTypeDef ClkPrescaler; /*!< ADC the max working clock is 16-MHz */ + ADC_DataAlignTypeDef DataAlign; + ADC_ModeTypeDef Mode; + bool IsSoftTrig; +} ADC_InitTypeDef; + +/** + * The initialization info of brake source from the ADC Channel + */ +typedef struct ADC_BKSrcInit +{ + uint8_t SelBKChannel; // The target channel ID (0~15) as brake source + ADC_BKFilterTypeDef BkFilter; + ADC_BKCondTypeDef BKCond; +} ADC_BKSrcInitTypeDef; +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +/** + * \brief Deinitializes ADC module + * + * \param [in] pHADC Pointer to an ADC handler + * \return + * None + */ +void ADC_DeInit(ADC_Type *pHADC); + +/** + * \brief Initializes ADC module + * + * \param [in] pHADC Pointer to an ADC handler + * \param [in] pInit Pointer to an ADC_InitTypeDef structure, @ref ADC_InitTypeDef + * \return + * None + */ +void ADC_Init(ADC_Type *pHADC, ADC_InitTypeDef *pInit); + +/** + * \brief Fills each ADC_InitStruct member with its default value. + * + * \param [in] pInit Pointer to an ADC_InitTypeDef structure, @ref ADC_InitTypeDef + * \return + * None + */ +void ADC_StructInit(ADC_InitTypeDef *pInit); + +/** + * \brief ADC external trigger configuration + * Note. It should one by one to configure external sources + * + * \param [in] pHADC Pointer to an ADC handler + * \param [in] ext_src The target external source, @ref ADC_ExtTrigSourceTypeDef + * Note. if ext_src == ADC_ExtTrigSource_Soft, + * it will ignore trig_mode and DISABLE external trigger function + * \param [in] trig_mode The target ADC trigger mode, @ref ADC_ExtTrigModeTypeDef + * \return + * None + */ +void ADC_ExtTrigConfig(ADC_Type *pHADC, ADC_ExtTrigSourceTypeDef ext_src, ADC_ExtTrigModeTypeDef trig_mode); + +/** + * \brief Select the sub-channel of the ADC Channel-15 + * + * \param [in] subchannel The selected sub-channel of ADC channel-15, @ref ADC_SubChannelTypeDef + * \return + * None + */ +void ADC_SelSubChannel(ADC_SubChannelTypeDef subchannel); + +/** + * \brief Get the conversion value of an ADC channel + * + * \param [in] pHADC Pointer to an ADC handler + * \param [in] channel The target channel, @ref ADC_ChannelsTypeDef + * \return + * The ADC conversion value + */ +uint16_t ADC_GetChannelConvValue(ADC_Type *pHADC, ADC_ChannelsTypeDef channel); + +/** + * \brief Configures the comparison thresholds of an ADC channel + * + * \param [in] pHADC Pointer to an ADC handler + * \param [in] channel The target channel, @ref ADC_ChannelsTypeDef + * \param [in] threshold The target thershold value + * \return + * None + */ +void ADC_ChannelThresholdConfig(ADC_Type *pHADC, ADC_ChannelsTypeDef channel, uint16_t threshold); + +/** + * \brief Enables or disables the specified ADC interrupts + * + * \param [in] pHADC Pointer to an ADC handler + * \param [in] it_types The target interrupt types + * ps. It supports multi-interrupts selection, + * but 'ADC_IT_DISABLE' is standalone + * \return + * None + */ +void ADC_ITConfig(ADC_Type *pHADC, ADC_ITTypeDef it_types); + + +/** + * \brief Configures the brake source from an ADC channel + * + * \param [in] pHADC Pointer to an ADC handler + * \param [in] bk_src the brake source type, @ref ADC_BKSrcTypeDef + * \param [in] pBKInit Pointer to an instance of the ADC brake initialization info, @ref ADC_BKSrcInitTypeDef + * \return + * None + */ +__STATIC_FORCEINLINE void ADC_BrakeSrcConfig(ADC_Type *pHADC, ADC_BKSrcTypeDef bk_src, ADC_BKSrcInitTypeDef *pBKInit) +{ + REG_WRITE_MASK(pHADC->BKSEL, + (ADC_BKSEL_BK1_CH_Msk | ADC_BKSEL_BK1_FLT_Msk | ADC_BKSEL_BK1_EN_Msk) << bk_src, + ((pBKInit->SelBKChannel & 0xFul) | pBKInit->BkFilter | pBKInit->BKCond) << bk_src); + return; +} + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_amisc.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_amisc.h new file mode 100644 index 0000000..be9686c --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_amisc.h @@ -0,0 +1,402 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_amisc.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/10 + * @license + * @description + */ + +#ifndef __hal_amisc_H_wiD001de_alts_HbDE_s9jK_uDb2acTbwQSx__ +#define __hal_amisc_H_wiD001de_alts_HbDE_s9jK_uDb2acTbwQSx__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_def.h" +//============================================================================= +// Constant Definition +//============================================================================= +typedef enum +{ + AMISC_Status_OK = 0, + AMISC_Status_Error, + AMISC_Status_Bypass, +} AMISC_StatusTypeDef; + +/** + * The threshold of LVD voltage + */ +typedef enum +{ + AMISC_LVDVoltage_2V = (AMISC_LVD_LVR_CR_LVD_SEL_2V << AMISC_LVD_LVR_CR_LVD_SEL_Pos), + AMISC_LVDVoltage_2_2V = (AMISC_LVD_LVR_CR_LVD_SEL_2_2V << AMISC_LVD_LVR_CR_LVD_SEL_Pos), + AMISC_LVDVoltage_2_4V = (AMISC_LVD_LVR_CR_LVD_SEL_2_4V << AMISC_LVD_LVR_CR_LVD_SEL_Pos), + AMISC_LVDVoltage_2_7V = (AMISC_LVD_LVR_CR_LVD_SEL_2_7V << AMISC_LVD_LVR_CR_LVD_SEL_Pos), + AMISC_LVDVoltage_3V = (AMISC_LVD_LVR_CR_LVD_SEL_3V << AMISC_LVD_LVR_CR_LVD_SEL_Pos), + AMISC_LVDVoltage_3_7V = (AMISC_LVD_LVR_CR_LVD_SEL_3_7V << AMISC_LVD_LVR_CR_LVD_SEL_Pos), + AMISC_LVDVoltage_4V = (AMISC_LVD_LVR_CR_LVD_SEL_4V << AMISC_LVD_LVR_CR_LVD_SEL_Pos), + AMISC_LVDVoltage_4_3V = (AMISC_LVD_LVR_CR_LVD_SEL_4_3V << AMISC_LVD_LVR_CR_LVD_SEL_Pos), +} AMISC_LVDVoltageTypeDef; + +/** + * The threshold of LVR voltage + */ +typedef enum +{ + AMISC_LVRVoltage_2V = (AMISC_LVD_LVR_CR_LVR_SEL_2V << AMISC_LVD_LVR_CR_LVR_SEL_Pos), + AMISC_LVRVoltage_2_4V = (AMISC_LVD_LVR_CR_LVR_SEL_2_4V << AMISC_LVD_LVR_CR_LVR_SEL_Pos), + AMISC_LVRVoltage_2_7V = (AMISC_LVD_LVR_CR_LVR_SEL_2_7V << AMISC_LVD_LVR_CR_LVR_SEL_Pos), + AMISC_LVRVoltage_3V = (AMISC_LVD_LVR_CR_LVR_SEL_3V << AMISC_LVD_LVR_CR_LVR_SEL_Pos), + AMISC_LVRVoltage_3_7V = (AMISC_LVD_LVR_CR_LVR_SEL_3_7V << AMISC_LVD_LVR_CR_LVR_SEL_Pos), +} AMISC_LVRVoltageTypeDef; + +typedef enum +{ + AMISC_LVDFunc_LP = AMISC_LVD_LVR_CR_LDO_LP_EN_Msk, // LDO low power mode + AMISC_LVDFunc_TEMP = AMISC_LVD_LVR_CR_TEMP_EN_Msk, // Temperature detection + +} AMISC_LVDFuncTypeDef; + +typedef enum +{ + AMISC_InternalSrc_NONE = (AMISC_VBUF_CR_ANA_SEL_NONE << AMISC_VBUF_CR_ANA_SEL_Pos), + AMISC_InternalSrc_TEMP = (AMISC_VBUF_CR_ANA_SEL_TEMP << AMISC_VBUF_CR_ANA_SEL_Pos), + AMISC_InternalSrc_DAC0 = (AMISC_VBUF_CR_ANA_SEL_DAC0 << AMISC_VBUF_CR_ANA_SEL_Pos), + AMISC_InternalSrc_DAC1 = (AMISC_VBUF_CR_ANA_SEL_DAC1 << AMISC_VBUF_CR_ANA_SEL_Pos), + AMISC_InternalSrc_VBuf_1P5V = (AMISC_VBUF_CR_ANA_SEL_VBuf_1p5v << AMISC_VBUF_CR_ANA_SEL_Pos), + AMISC_InternalSrc_VDDL = (AMISC_VBUF_CR_ANA_SEL_VDDL << AMISC_VBUF_CR_ANA_SEL_Pos), + AMISC_InternalSrc_VSS = (AMISC_VBUF_CR_ANA_SEL_VSS << AMISC_VBUF_CR_ANA_SEL_Pos), + AMISC_InternalSrc_VDD = (AMISC_VBUF_CR_ANA_SEL_VDD << AMISC_VBUF_CR_ANA_SEL_Pos), +} AMISC_InternalSrcTypeDef; + +typedef enum +{ + AMISC_HSIPwrSrc_Normal = (AMISC_HSI_CR_LDO_SEL_Normal << AMISC_HSI_CR_LDO_SEL_Pos), + AMISC_HSIPwrSrc_LowPower = (AMISC_HSI_CR_LDO_SEL_LDO << AMISC_HSI_CR_LDO_SEL_Pos), + +} AMISC_HSIPwrSrcTypeDef; +//============================================================================= +// Macro Definition +//============================================================================= +/** + * \brief Configure DAC0 of Analog Misc. + * + * \param [in] step the voltage step (10-bits) of DAC + * \return + * None + */ +__STATIC_FORCEINLINE void AMISC_DAC0_Config(uint16_t step) +{ + REG_WRITE_MASK(AMISC->DAC_CR, + AMISC_DAC_CR_DAC0Step_Msk, + ((uint32_t)step << AMISC_DAC_CR_DAC0Step_Pos)); + return; +} + +/** + * \brief Configure DAC1 of Analog Misc. + * + * \param [in] step the voltage step (10-bits) of DAC + * \return + * None + */ +__STATIC_FORCEINLINE void AMISC_DAC1_Config(uint16_t step) +{ + REG_WRITE_MASK(AMISC->DAC_CR, + AMISC_DAC_CR_DAC1Step_Msk, + ((uint32_t)step << AMISC_DAC_CR_DAC1Step_Pos)); + return; +} + +/** + * \brief Enable DAC0 of Analog Misc. + * + * \return + * None + */ +__STATIC_FORCEINLINE void AMISC_DAC0_Enable(void) +{ + REG_SET_BITS(AMISC->DAC_CR, AMISC_DAC_CR_DAC0_EN_Msk); + return; +} + +/** + * \brief Enable DAC1 of Analog Misc. + * + * \return + * None + */ +__STATIC_FORCEINLINE void AMISC_DAC1_Enable(void) +{ + REG_SET_BITS(AMISC->DAC_CR, AMISC_DAC_CR_DAC1_EN_Msk); + return; +} + +/** + * \brief Disable DAC0 of Analog Misc. + * + * \return + * None + */ +__STATIC_FORCEINLINE void AMISC_DAC0_Disable(void) +{ + REG_CLR_BITS(AMISC->DAC_CR, AMISC_DAC_CR_DAC0_EN_Msk); + return; +} + +/** + * \brief Disable DAC1 of Analog Misc. + * + * \return + * None + */ +__STATIC_FORCEINLINE void AMISC_DAC1_Disable(void) +{ + REG_CLR_BITS(AMISC->DAC_CR, AMISC_DAC_CR_DAC1_EN_Msk); + return; +} + + +/** + * \brief Enable LVD module + * + * \return + * None + */ +__STATIC_FORCEINLINE void AMISC_LVD_Enable(void) +{ + REG_SET_BITS(AMISC->LVD_LVR_CR, AMISC_LVD_LVR_CR_LVD_EN_Msk); + return; +} + +/** + * \brief Disable LVD module + * + * \return + * None + */ +__STATIC_FORCEINLINE void AMISC_LVD_Disable(void) +{ + REG_CLR_BITS(AMISC->LVD_LVR_CR, AMISC_LVD_LVR_CR_LVD_EN_Msk); + return; +} + +/** + * \brief Enable LVR interrupt + * + * \return + * None + */ +__STATIC_FORCEINLINE void AMISC_LVR_Enable(void) +{ + REG_SET_BITS(AMISC->LVD_LVR_CR, AMISC_LVD_LVR_CR_LVR_EN_Msk); + return; +} + +/** + * \brief Disable LVR interrupt + * + * \return + * None + */ +__STATIC_FORCEINLINE void AMISC_LVR_Disable(void) +{ + REG_CLR_BITS(AMISC->LVD_LVR_CR, AMISC_LVD_LVR_CR_LVR_EN_Msk); + return; +} + +/** + * \brief Enable LVD interrupt + * + * \return + * None + */ +__STATIC_FORCEINLINE void AMISC_LVD_ITEnable(void) +{ + REG_SET_BITS(AMISC->LVD_LVR_CR, AMISC_LVD_LVR_CR_LVD_INT_EN_Msk); + return; +} + +/** + * \brief Disable LVD interrupt + * + * \return + * None + */ +__STATIC_FORCEINLINE void AMISC_LVD_ITDisable(void) +{ + REG_CLR_BITS(AMISC->LVD_LVR_CR, AMISC_LVD_LVR_CR_LVD_INT_EN_Msk); + return; +} + +/** + * \brief Get the status of LVD + * + * \return + * The new state of flags (SET or RESET) + */ +__STATIC_FORCEINLINE FlagStatus AMISC_LVD_GetFlagStatus(void) +{ + return REG_READ_MASK(AMISC->LVD_LVR_CR, AMISC_LVD_LVR_CR_LVD_STATE_Msk) ? SET : RESET; +} + +/** + * \brief Enable VBUF + * + * \return + * None + */ +__STATIC_FORCEINLINE void AMISC_Vbuf_Enable(void) +{ + REG_SET_BITS(AMISC->VBUF_CR, AMISC_VBUF_CR_VBUF_EN_Msk); + return; +} + +/** + * \brief Disable VBUF + * + * \param [in] pHAMisc Pointer to a Analog Misc. handler + * \return + * None + */ +__STATIC_FORCEINLINE void AMISC_Vbuf_Disable(void) +{ + REG_CLR_BITS(AMISC->VBUF_CR, AMISC_VBUF_CR_VBUF_EN_Msk); + return; +} + + +/** + * \brief Set the power source of HSI + * + * \param [in] pwr_src The target power source, @ref AMISC_HSIPwrSrcTypeDef + * \return + * None + */ +__STATIC_FORCEINLINE void AMISC_SetHSIPwrSrc(AMISC_HSIPwrSrcTypeDef pwr_src) +{ + REG_WRITE_MASK(AMISC->HSI_CR, AMISC_HSI_CR_LDO_SEL_Msk, pwr_src); + return; +} + +//============================================================================= +// Structure Definition +//============================================================================= +typedef struct +{ + AMISC_LVDVoltageTypeDef LVD_Voltage; + AMISC_LVRVoltageTypeDef LVR_Voltage; + AMISC_LVDFuncTypeDef LVD_FuncModes; + +} AMISC_LVDRInitTypeDef; +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +/** + * \brief Initialize Analog misc. module + * + * \return + * result status, @ref AMISC_StatusTypeDef + */ +AMISC_StatusTypeDef AMISC_Init(void); + +/** + * \brief De-Initialize Analog misc. module + * + * \param [in] is_force Force to de-initialize or not + * 0: Conditionally de-initialize + * others: Force to de-initialize + * \return + * result status, @ref AMISC_StatusTypeDef + */ +AMISC_StatusTypeDef AMISC_DeInit(uint32_t is_force); + +/** + * \brief Reset Analog misc. module + * NOTE: It will reset OPAMP, DAC, LDO functions at the same time + * + * \return + * result status, @ref AMISC_StatusTypeDef + */ +AMISC_StatusTypeDef AMISC_Reset(void); + +/** + * \brief Configure LVD/LVR module + * + * \param [in] pInit Pointer to a AMISC_LVDRInitTypeDef structure, @ref AMISC_LVDRInitTypeDef + * \return + * result status, @ref AMISC_StatusTypeDef + */ +AMISC_StatusTypeDef AMISC_LVD_LVR_Config(AMISC_LVDRInitTypeDef *pInit); + +/** + * \brief Disable HSI clock source + * + * \return + * None + */ +void AMISC_HSI_Disable(void); + +/** + * \brief Enable HSI clock source + * + * \return + * None + */ +void AMISC_HSI_Enable(void); + +/** + * \brief Disable LSI clock source + * + * \return + * None + */ +void AMISC_LSI_Disable(void); + +/** + * \brief Enable LSI clock source + * + * \return + * None + */ +void AMISC_LSI_Enable(void); + +/** + * \brief Select the VinP internal source of PGA + * + * \param [in] src_type the target VinP internal source + * \return + * None + */ +void AMISC_Sel_PGA_VinP_Src(AMISC_InternalSrcTypeDef src_type); + + +/** + * \brief Output the internal signals to I/O Pin + * + * \param [in] src_type The target internal signal, @ref AMISC_InternalSrcTypeDef + * \param [in] has_output Enable output or not + * \return + * None + */ +void AMISC_OutInternalSignalToIO(AMISC_InternalSrcTypeDef src_type, int has_output); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_comp.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_comp.h new file mode 100644 index 0000000..677f07b --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_comp.h @@ -0,0 +1,261 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_comp.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + +#ifndef __hal_comp_H_wqqzibVO_lvKI_HWdK_sROD_uhjcZz7SHMtL__ +#define __hal_comp_H_wqqzibVO_lvKI_HWdK_sROD_uhjcZz7SHMtL__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_def.h" +//============================================================================= +// Constant Definition +//============================================================================= +/** + * Input-minus type of the Comparator + */ +typedef enum COMP_VinM +{ + COMP_VinM_IO = (COMP_CTRL_VIN_SEL_IO << COMP_CTRL_VIN_SEL_Pos), + COMP_VinM_DAC = (COMP_CTRL_VIN_SEL_DAC << COMP_CTRL_VIN_SEL_Pos), +} COMP_VinMTypeDef; + + +/** + * Input-plus type of the Comparator + */ +typedef enum COMP_VinP +{ + COMP_VinP_PGA = (COMP_VIPSEL_VIP_SEL_PGA << COMP_VIPSEL_VIP_SEL_Pos), + COMP_VinP_IO0 = (COMP_VIPSEL_VIP_SEL_IO0 << COMP_VIPSEL_VIP_SEL_Pos), + COMP_VinP_IO1 = (COMP_VIPSEL_VIP_SEL_IO1 << COMP_VIPSEL_VIP_SEL_Pos), + COMP_VinP_IO2 = (COMP_VIPSEL_VIP_SEL_IO2 << COMP_VIPSEL_VIP_SEL_Pos), + COMP_VinP_IO3 = (COMP_VIPSEL_VIP_SEL_IO3 << COMP_VIPSEL_VIP_SEL_Pos), +} COMP_VinPTypeDef; + +/** + * Filter frequency of the Comparator + */ +typedef enum COMP_Filter +{ + COMP_Filter_Bypass = (COMP_CTRL_FIL_CTRL_BYPASS << COMP_CTRL_FIL_CTRL_Pos), + COMP_Filter_Sample_2 = (COMP_CTRL_FIL_CTRL_SAMPLE_2 << COMP_CTRL_FIL_CTRL_Pos), + COMP_Filter_Sample_4 = (COMP_CTRL_FIL_CTRL_SAMPLE_4 << COMP_CTRL_FIL_CTRL_Pos), + COMP_Filter_Sample_8 = (COMP_CTRL_FIL_CTRL_SAMPLE_8 << COMP_CTRL_FIL_CTRL_Pos), + COMP_Filter_Sample_16 = (COMP_CTRL_FIL_CTRL_SAMPLE_16 << COMP_CTRL_FIL_CTRL_Pos), + COMP_Filter_Sample_32 = (COMP_CTRL_FIL_CTRL_SAMPLE_32 << COMP_CTRL_FIL_CTRL_Pos), + COMP_Filter_Sample_64 = (COMP_CTRL_FIL_CTRL_SAMPLE_64 << COMP_CTRL_FIL_CTRL_Pos), + COMP_Filter_Sample_128 = (COMP_CTRL_FIL_CTRL_SAMPLE_128 << COMP_CTRL_FIL_CTRL_Pos), + COMP_Filter_Sample_256 = (COMP_CTRL_FIL_CTRL_SAMPLE_256 << COMP_CTRL_FIL_CTRL_Pos), +} COMP_FilterTypeDef; + +/** + * Output polarity of the Comparator + */ +typedef enum COMP_OutPolarity +{ + COMP_OutPolarity_Normal = (COMP_CTRL_POL_SEL_NORMAL << COMP_CTRL_POL_SEL_Pos), + COMP_OutPolarity_Invert = (COMP_CTRL_POL_SEL_INVERT << COMP_CTRL_POL_SEL_Pos), +} COMP_OutPolarityTypeDef; + +/** + * Interrupt type of the Comparator + */ +typedef enum COMP_IE +{ + COMP_IE_None = 0x0ul, + COMP_IE_Rising = COMP_IR_RIE_Msk, + COMP_IE_Falling = COMP_IR_FIE_Msk, + COMP_IE_ALL = (COMP_IR_RIE_Msk | COMP_IR_FIE_Msk), +} COMP_IETypeDef; + +/** + * Output type of the Comparator + */ +typedef enum COMP_Vout +{ + COMP_Vout_None = 0x0, + COMP_Vout_IO = COMP_CTRL_OUT_EN_Msk, +} COMP_VoutTypeDef; + +/** + * Input hysteresis type of the Comparator + */ +typedef enum COMP_Hysteresis +{ + COMP_Hysteresis_Disable = 0x0, + COMP_Hysteresis_Enable = COMP_CTRL_HYS_EN_Msk, +} COMP_HysteresisTypeDef; + + +//============================================================================= +// Macro Definition +//============================================================================= + +/** + * \brief COMP enable/disable + * + * \param [in] pHComp pointer to a COMP instance + * \return + * None + */ +__STATIC_INLINE void COMP_Enable(COMP_Type *pHComp) +{ + REG_SET_BITS(pHComp->CTRL, COMP_CTRL_EN_Msk); + return; +} + +__STATIC_INLINE void COMP_Disable(COMP_Type *pHComp) +{ + + REG_CLR_BITS(pHComp->CTRL, COMP_CTRL_EN_Msk); + return; +} + +/** + * \brief COMP get output level + * + * \param [in] pHComp pointer to a COMP instance + * \return + * 0 : COMP OUT Low + * others: COMP OUT High + */ +__STATIC_INLINE uint32_t COMP_GetOutputLevel(COMP_Type *pHComp) +{ + return REG_READ_MASK(pHComp->CTRL, COMP_CTRL_COUT_Msk); +} + +/** + * \brief COMP configure interrupt + * + * \param [in] pHComp pointer to a COMP instance + * \param [in] it_types the target interrupt type, @ref COMP_IETypeDef + * \return + * None + */ +__STATIC_INLINE void COMP_ITConfig(COMP_Type *pHComp, COMP_IETypeDef it_types) +{ + REG_WRITE_MASK(pHComp->IR, COMP_IR_RIE_Msk | COMP_IR_FIE_Msk, it_types); + return; +} + +/** + * \brief Get the status flags of the COMP + * + * \param [in] pHComp pointer to a COMP instance + * \param [in] flags the target flag type, @ref COMP_IETypeDef + * \return + * 0 : No target status + * other: Get the target status + */ +__STATIC_INLINE uint32_t COMP_GetFlagStatus(COMP_Type *pHComp, COMP_IETypeDef flags) +{ + return REG_READ_MASK(pHComp->IF, flags); +} + +/** + * \brief Clear the status flags of the COMP + * + * \param [in] pHComp pointer to a COMP instance + * \param [in] it_types the target interrupt type, @ref COMP_IETypeDef + * \return + * None + */ +__STATIC_INLINE void COMP_ClearFlag(COMP_Type *pHComp, COMP_IETypeDef it_types) +{ + REG_WRITE_MASK(pHComp->IF, COMP_IR_RIE_Msk | COMP_IR_FIE_Msk, it_types); + return; +} + +/** + * \brief Get the interrupt setting flags of the COMP + * + * \param [in] pHComp pointer to a COMP instance + * \return + * it_types, @ref COMP_IETypeDef + */ +__STATIC_INLINE COMP_IETypeDef COMP_GetITFlags(COMP_Type *pHComp) +{ + return REG_READ_MASK(pHComp->IR, COMP_IR_RIE_Msk | COMP_IR_FIE_Msk); +} +//============================================================================= +// Structure Definition +//============================================================================= + +typedef struct +{ + COMP_VinPTypeDef InputPlus; /*!< Set comparator Vin+. @ref COMP_VinPTypeDef */ + + COMP_VinMTypeDef InputMinus; /*!< Set comparator Vin-. @ref COMP_VinMTypeDef */ + + COMP_HysteresisTypeDef InputHysteresis; /*!< Set comparator hysteresis mode of the input minus. @ref COMP_HysteresisTypeDef */ + + COMP_FilterTypeDef FilterFreq; /*!< Set comparator filter frequency. @ref COMP_FilterTypeDef */ + + COMP_OutPolarityTypeDef OutputPolarity; /*!< Set comparator output polarity. @ref COMP_OutPolarityTypeDef */ + + COMP_VoutTypeDef OutputSel; /*!< Set comparator output selection. @ref COMP_VoutTypeDef */ + + uint16_t InitDelay; /*!< Set comparator initial delay ticks */ + +} COMP_InitTypeDef; + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +/** + * @brief Initializes the COMP module according to + * the specified parameters in the init_struct. + * + * @param pHComp: pointer to a COMP instance + * @param pInit: pointer to a COMP_InitTypeDef structure + * that contains the configuration information for the specified COMP module. + * @retval None. + */ +void COMP_Init(COMP_Type *pHComp, COMP_InitTypeDef *pInit); + + +/** + * \brief De-initializes the COMP module + * + * \param [in] pHComp pointer to a COMP instance + * \return + * None + */ +void COMP_DeInit(COMP_Type *pHComp); + +/** + * \brief Set each initial field to default value. + * + * \param [in] pInit pointer to a COMP_InitTypeDef structure. @ref COMP_InitTypeDef + * \return + * None + */ +void COMP_StructInit(COMP_InitTypeDef *pInit); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_crc.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_crc.h new file mode 100644 index 0000000..7b87b81 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_crc.h @@ -0,0 +1,110 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_crc.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + +#ifndef __hal_crc_H_w0Q7P8ed_lHTg_HFk4_sJpZ_ukncYhoixtqA__ +#define __hal_crc_H_w0Q7P8ed_lHTg_HFk4_sJpZ_ukncYhoixtqA__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "hal_def.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define CRC_START_CODE (~0u) + +typedef enum +{ + CRC_Status_OK, + CRC_Status_Error, +} CRC_Status; + +typedef enum +{ + CRC_Width_CRC32 = (CRC_CR_POLYSEL_CRC32 << CRC_CR_POLYSEL_Pos), + CRC_Width_CRC16 = (CRC_CR_POLYSEL_CRC16 << CRC_CR_POLYSEL_Pos), + +} CRC_WidthTypeDef; +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +/** + * \brief Initialize CRC module + * + * \return + * None + */ +void CRC_Init(void); + +/** + * \brief Calculate the crc value with singal value + * + * \param [in] pValue pointer to an instance of value + * \param [in] crc_width the type of crc width, @ref CRC_WidthTypeDef + * \return + * CRC value + */ +uint32_t CRC_CalcCRC(uint8_t *pValue, CRC_WidthTypeDef crc_width); + +/** + * \brief Calculate the CRC value of data stream + * + * \param [in] pData Pointer to the buffer containing the data to be computed + * \param [in] length Length of the buffer to be computed + * \param [in] crc_width the type of crc width, @ref CRC_WidthTypeDef + * \return + * CRC value + */ +uint32_t CRC_CalcBlockCRC(uint8_t *pData, int length, CRC_WidthTypeDef crc_width); + + +/** + * \brief Get the current CRC value + * + * \return + * CRC value + */ +uint32_t CRC_GetCRC(void); + +/** + * \brief Verify the completeness of data + * + * \param [in] Valid_CRC The expected CRC value + * \return + * 0: data does not match + * others: verify success + */ +uint32_t CRC_VerifyFlag(uint32_t Valid_CRC); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_def.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_def.h new file mode 100644 index 0000000..f011f42 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_def.h @@ -0,0 +1,193 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_def.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/10 + * @license + * @description + */ + +#ifndef __hal_def_H_wrmPni7q_lbcH_Hmna_sBkY_uUTtDspcvhdh__ +#define __hal_def_H_wrmPni7q_lbcH_Hmna_sBkY_uUTtDspcvhdh__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "device.h" +//============================================================================= +// Constant Definition +//============================================================================= +#if defined(__GNUC__) + +#else + #warning Not supported compiler type +#endif + +typedef enum +{ + DISABLE = 0, + ENABLE = !DISABLE +} FuncStatus, FunctionalState; + +typedef enum +{ + RESET = 0, + SET = !RESET +} FlagStatus, ITStatus; + +typedef enum +{ + ERROR = 0, + SUCCESS = !ERROR +} ErrorStatus; +//============================================================================= +// Macro Definition +//============================================================================= +#define REG_SET_BITS(__reg32__, __bit_msk__) ((__reg32__) |= (__bit_msk__)) +#define REG_CLR_BITS(__reg32__, __bit_msk__) ((__reg32__) &= ~(__bit_msk__)) + +#define REG_READ(__reg32__) (__reg32__) +#define REG_READ_MASK(__reg32__, __msk__) ((__reg32__) & (__msk__)) + +#define REG_WRITE(__reg32__, __val__) ((__reg32__) = (__val__)) +#define REG_WRITE_MASK(__reg32__, __msk__, __val__) ((__reg32__) = ((__reg32__) & ~(__msk__)) | ((__val__) & (__msk__))) + +#define ALIGN_4(x) (((x) + 0x3ul) & ~0x3ul) + +#define UNUSED(X) (void)(X) +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= +/** + * register 32-bits operators + */ +__STATIC_INLINE void reg32_set_bits(uint32_t *addr, uint32_t bit_msk) +{ + *((uint32_t*)addr) |= bit_msk; + return; +} + +__STATIC_INLINE void reg32_clr_bits(uint32_t *addr, uint32_t bit_msk) +{ + *((uint32_t*)addr) &= ~bit_msk; + return; +} + +__STATIC_INLINE uint32_t reg32_read(uint32_t *addr) +{ + return *((uint32_t*)addr); +} + +__STATIC_INLINE uint32_t reg32_read_mask(uint32_t *addr, uint32_t mask) +{ + return (*((uint32_t*)addr) & mask); +} + +__STATIC_INLINE void reg32_write(uint32_t *addr, uint32_t value) +{ + *(uint32_t*)addr = value; + return; +} + +__STATIC_INLINE void reg32_write_mask(uint32_t *addr, uint32_t mask, uint32_t value) +{ + *(uint32_t*)addr = ((*(uint32_t*)addr) & ~mask) | (value & mask); + return; +} + +/** + * register 16-bits operators + */ +__STATIC_INLINE void reg16_set_bits(uint16_t *addr, uint16_t bit_msk) +{ + *((uint16_t*)addr) |= bit_msk; + return; +} + +__STATIC_INLINE void reg16_clr_bits(uint16_t *addr, uint16_t bit_msk) +{ + *((uint16_t*)addr) &= ~bit_msk; + return; +} + +__STATIC_INLINE uint16_t reg16_read(uint16_t *addr) +{ + return *((uint16_t*)addr); +} + +__STATIC_INLINE uint16_t reg16_read_mask(uint16_t *addr, uint16_t mask) +{ + return (*((uint16_t*)addr) & mask); +} + +__STATIC_INLINE void reg16_write(uint16_t *addr, uint16_t value) +{ + *(uint16_t*)addr = value; + return; +} + +__STATIC_INLINE void reg16_write_mask(uint16_t *addr, uint16_t mask, uint16_t value) +{ + *(uint16_t*)addr = ((*(uint16_t*)addr) & ~mask) | (value & mask); + return; +} + +/** + * register 8-bits operators + */ +__STATIC_INLINE void reg8_set_bits(uint8_t *addr, uint8_t bit_msk) +{ + *((uint8_t*)addr) |= bit_msk; + return; +} + +__STATIC_INLINE void reg8_clr_bits(uint8_t *addr, uint8_t bit_msk) +{ + *((uint8_t*)addr) &= ~bit_msk; + return; +} + +__STATIC_INLINE uint8_t reg8_read(uint8_t *addr) +{ + return *((uint8_t*)addr); +} + +__STATIC_INLINE uint8_t reg8_read_mask(uint8_t *addr, uint8_t mask) +{ + return (*((uint8_t*)addr) & mask); +} + +__STATIC_INLINE void reg8_write(uint8_t *addr, uint8_t value) +{ + *(uint8_t*)addr = value; + return; +} + +__STATIC_INLINE void reg8_write_mask(uint8_t *addr, uint8_t mask, uint8_t value) +{ + *(uint8_t*)addr = ((*(uint8_t*)addr) & ~mask) | (value & mask); + return; +} + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_device.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_device.h new file mode 100644 index 0000000..d569167 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_device.h @@ -0,0 +1,138 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_device.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/10 + * @license + * @description + */ + +#ifndef __hal_device_H_wh21It4q_lc5o_HN4v_sYN9_uMvM6ZVOvOoN__ +#define __hal_device_H_wh21It4q_lc5o_HN4v_sYN9_uMvM6ZVOvOoN__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "hal_conf.h" +//============================================================================= +// Constant Definition +//============================================================================= +#if defined(USE_FULL_ASSERT) + #define assert_param(expr) ((expr) ? (void)0 : assert_failed((char*)__func__, __LINE__)) + void assert_failed(char *func, uint32_t line); +#else + #define assert_param(expr) +#endif +//============================================================================= +// Macro Definition +//============================================================================= +/** + * \brief Count leading zeros + * + * \param [in] x Value to count the leading zeros + * \return + * Number of leading zeros in value + */ +__STATIC_FORCEINLINE int HAL_CLZ(uint32_t x) +{ + return __builtin_clz(x); +} + +/** + * \brief Count the amount of bit-1 + * + * \param [in] x Value to count the amount of bit-1 + * \return + * The amount of bit-1 + */ +__STATIC_FORCEINLINE int HAL_PopCount(uint32_t x) +{ + return __builtin_popcount(x); +} + +/** + * \brief Get UID-1 value + * \return UID-1 + */ +__STATIC_FORCEINLINE uint32_t HAL_GetUID1(void) +{ + return REG_READ(UID->UID1); +} + +/** + * \brief Get UID-2 value + * \return UID-2 + */ +__STATIC_FORCEINLINE uint32_t HAL_GetUID2(void) +{ + return REG_READ(UID->UID2); +} + +/** + * \brief Get UID-3 value + * \return UID-3 + */ +__STATIC_FORCEINLINE uint32_t HAL_GetUID3(void) +{ + return REG_READ(UID->UID3); +} + +/** + * \brief Initialize the peripherals of this device + * + * \return + * None + */ +__STATIC_FORCEINLINE void HAL_DeviceInit(void) +{ + REG_WRITE(SYSCFG->PRSTEN1, 0xFFFFFFFFul); + REG_WRITE(SYSCFG->PRSTEN, 0xFFFFFFFFul); + REG_WRITE(SYSCFG->PRSTEN1, 0x0ul); + REG_WRITE(SYSCFG->PRSTEN, 0x0ul); + return; +} + +#define HAL_SetBits(_val_, _bit_mak_) REG_SET_BITS(_val_, _bit_mak_) +#define HAL_ClearBits(_val_, _bit_mak_) REG_CLR_BITS(_val_, _bit_mak_) +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +/** + * \brief Set the seed to initialize pseudo-random number generator + * + * \param [in] seed The seed value + * \return + * None + */ +void HAL_SRand(uint32_t seed); + +/** + * \brief Generate pseudo-random number + * + * \return + * The pseudo-random value + */ +uint32_t HAL_Rand(void); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_dsp.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_dsp.h new file mode 100644 index 0000000..2572b70 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_dsp.h @@ -0,0 +1,107 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_dsp.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + +#ifndef __hal_dsp_H_we15xl18_lz2k_Hix7_sTLr_uIRwmlwU5wH6__ +#define __hal_dsp_H_we15xl18_lz2k_Hix7_sTLr_uIRwmlwU5wH6__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "hal_def.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= +/** + * \brief H/W DSP Divide operation + * + * \param [in] numerator The numerator of Fraction + * \param [in] denominator The denominator of Fraction + * \param [in] pQuotient Pointer to a 32-bits signed value (Quotient) + * \param [in] pRemainder Pointer to a 32-bits signed value (Remainder) + * \return + * 0: ok + * others: fail + */ +__STATIC_FORCEINLINE int DSP_Div32(int numerator, int denominator, int *pQuotient, int *pRemainder) +{ + DSP->CR_b.MODE = DSP_CR_MODE_DIV; + + REG_WRITE(DSP->SDAT1, numerator); + REG_WRITE(DSP->SDAT2, denominator); + + while( !REG_READ(DSP->SR) ) {} + + if( pQuotient ) *pQuotient = REG_READ(DSP->RSLT1); + if( pRemainder ) *pRemainder = REG_READ(DSP->RSLT2); + + return 0; +} +//============================================================================= +// Structure Definition +//============================================================================= +/** + * the paraments of dsp square root calculate + */ +typedef struct +{ + union { + uint64_t value64; + uint32_t value32[2]; + }; +} DSP_SqrtParamTypeDef; + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +#if 0 +/** + * \brief H/W DSP Divide operation + * + * \param [in] numerator The numerator of Fraction + * \param [in] denominator The denominator of Fraction + * \param [in] pQuotient Pointer to a 32-bits signed value (Quotient) + * \param [in] pRemainder Pointer to a 32-bits signed value (Remainder) + * \return + * 0: ok + * others: fail + */ +int DSP_Div32(int numerator, int denominator, int *pQuotient, int *pRemainder); +#endif + +/** + * \brief H/w DSP Square root operation (unsigned 64-bits) + * + * \param [in] pParam The input paraments of Square root operation + * \return + * the calculated value + */ +uint32_t DSP_Sqrt32(DSP_SqrtParamTypeDef *pParam); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_flash.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_flash.h new file mode 100644 index 0000000..676d17c --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_flash.h @@ -0,0 +1,203 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_flash.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/10 + * @license + * @description + */ + +#ifndef __hal_flash_H_wm4SBnn4_laN2_HBZw_sxWM_uBboLm9QaVsk__ +#define __hal_flash_H_wm4SBnn4_laN2_HBZw_sxWM_uBboLm9QaVsk__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_def.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define FLASH_1_SECTOR_SIZE 512 +#define FLASH_1_PAGE_SIZE FLASH_1_SECTOR_SIZE + +#define FLASH_AUTH_KEY 0xA5A50000ul + +/** + * eFlash status + */ +typedef enum flash_state +{ + FLASH_STATE_OK = 0, + FLASH_STATE_BUSY, + FLASH_STATE_FAIL_PROG, + FLASH_STATE_FAIL_ERASE, + FLASH_STATE_FAIL_ADDR, + FLASH_STATE_NOT_4_ALIGN, + FLASH_STATE_FAIL_PARAM, + FLASH_STATE_TIMEOUT +} flash_state_t; + +/** + * eFlash latency type + */ +typedef enum flash_latency +{ + FLASH_LATENCY_1 = (0x1ul << FLASH_CMD_NWS_Pos), + FLASH_LATENCY_2 = (0x2ul << FLASH_CMD_NWS_Pos), + FLASH_LATENCY_3 = (0x3ul << FLASH_CMD_NWS_Pos), + +} flash_latency_t; + +/** + * eFlash H/w error type + */ +typedef enum flash_err_type +{ + FLASH_ERR_TYPE_OK = 0, + FLASH_ERR_TYPE_KEY = FLASH_SR_KEY_ERR_Msk, + FLASH_ERR_TYPE_ACCESS = FLASH_SR_ACC_ERR_Msk, + FLASH_ERR_TYPE_ADDRESS = FLASH_SR_ADDR_ERR_Msk, + + FLASH_ERR_TYPE_SYSINFO_FAIL = (FLASH_SR_HSI_TC_ERR_Msk | FLASH_SR_RSTIO_AF_ERR_Msk | \ + FLASH_SR_LDO_TRIM_ERR_Msk | FLASH_SR_VBUF_TRIM_ERR_Msk | \ + FLASH_SR_LSI_TRIM_ERR_Msk | FLASH_SR_HSI_TRIM_ERR_Msk), + + FLASH_ERR_TYPE_INVALID_TRIM_HSI = FLASH_SR_HSI_TRIM_ERR_Msk, + FLASH_ERR_TYPE_INVALID_TRIM_HSI_TC = FLASH_SR_HSI_TC_ERR_Msk, + FLASH_ERR_TYPE_INVALID_TRIM_LSI = FLASH_SR_LSI_TRIM_ERR_Msk, + FLASH_ERR_TYPE_INVALID_TRIM_VBUF = FLASH_SR_VBUF_TRIM_ERR_Msk, + FLASH_ERR_TYPE_INVALID_TRIM_LDO = FLASH_SR_LDO_TRIM_ERR_Msk, + FLASH_ERR_TYPE_INVALID_RSTIO_CFG = FLASH_SR_RSTIO_AF_ERR_Msk, +} flash_err_type_t; +//============================================================================= +// Macro Definition +//============================================================================= +/** + * \brief Check eFlash is idle or not. + * + * \return + * 0 : busy + * others: idle + */ +__STATIC_FORCEINLINE uint32_t FLASH_IsIdle(void) +{ + return !REG_READ_MASK(FLASH->CMD, FLASH_CMD_START_Msk); +} + + +/** + * \brief Get the latency type of eFlash + * + * \return + * Latency value, @ref flash_latency_t + */ +__STATIC_FORCEINLINE uint32_t FLASH_GetLatency(void) +{ + return REG_READ_MASK(FLASH->CMD, FLASH_CMD_NWS_Msk); +} + +/** + * \brief Get eFlash H/w error type + * + * \return + * eFlash H/w error type, @ref flash_err_type_t + */ +__STATIC_FORCEINLINE flash_err_type_t FLASH_GetHwErr(void) +{ + return (flash_err_type_t)REG_READ(FLASH->SR); +} +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +/** + * \brief Set Flash latency + * When CPU frequency is over eFlash, + * CPU MUST wait eFlash response + * + * \param [in] latency CPU wait latency (cycles) for eFlash, @ref flash_latency_t + * \return + * state, @ref flash_state_t + */ +flash_state_t +FLASH_SetLatency(flash_latency_t latency); + + +/** + * \brief Erase a page of eFlash + * + * \param [in] page_addr the target address (FLASH_1_PAGE_SIZE align) of the eFlash + * \return + * state, @ref flash_state_t + */ +flash_state_t +FLASH_ErasePage(uint32_t page_addr); + + +/** + * \brief Program a word (32-bits) value to eFlash + * + * \param [in] addr the target address of the eFlash + * \param [in] value the target value (32-bits) + * \return + * state, @ref flash_state_t + */ +flash_state_t +FLASH_ProgWord(uint32_t addr, uint32_t value); + +/** + * \brief Program a half-word (16-bits) value to eFlash + * + * \param [in] addr the target address of the eFlash + * \param [in] value the target value (16-bits) + * \return + * state, @ref flash_state_t + */ +flash_state_t +FLASH_ProgHWord(uint32_t addr, uint16_t value); + +/** + * \brief Program a byte (8-bits) value to eFlash + * + * \param [in] addr the target address of the eFlash + * \param [in] value the target value (8-bits) + * \return + * state, @ref flash_state_t + */ +flash_state_t +FLASH_ProgByte(uint32_t addr, uint8_t value); + +/** + * \brief Program data set to eFlash + * + * \param [in] addr the target address of the eFlash + * \param [in] pData pointer to a 32-bits buffer of data set + * \param [in] length the 4-align length of data + * \return + * state, @ref flash_state_t + */ +flash_state_t +FLASH_ProgData(uint32_t addr, uint32_t *pData, int length); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_gpio.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_gpio.h new file mode 100644 index 0000000..cca4b6f --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_gpio.h @@ -0,0 +1,420 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_gpio.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + +#ifndef __hal_gpio_H_wPOJofWz_lXUp_H0cZ_sE46_uv8ZKHIsTlMH__ +#define __hal_gpio_H_wPOJofWz_lXUp_H0cZ_sE46_uv8ZKHIsTlMH__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_def.h" +//============================================================================= +// Constant Definition +//============================================================================= + +typedef enum +{ + GPIO_PIN_RESET = 0u, + GPIO_PIN_SET, + GPIO_PIN_LOW = GPIO_PIN_RESET, + GPIO_PIN_HIGH = GPIO_PIN_SET, +} GPIO_PinStateTypeDef; + +typedef enum +{ + GPIO_Mode_IN = 0x00, /*!< GPIO Input Mode */ + GPIO_Mode_OUT, /*!< GPIO Output Mode */ + GPIO_Mode_ANAL, /*!< GPIO Analog In/Out Mode */ + GPIO_Mode_AF, /*!< GPIO Alternate function Mode */ + GPIO_Mode_PWR_Saving, /*!< GPIO Power-Saving Mode */ + +} GPIO_ModeTypeDef; + +typedef enum +{ + GPIO_PuPd_NOPULL = 0x00, + GPIO_PuPd_UP = 0x01, + GPIO_PuPd_DOWN = 0x02 +}GPIO_PuPdTypeDef; + +typedef enum +{ + GPIO_OType_PP = 0x0, + GPIO_OType_OD +}GPIO_OTypeTypeDef; + +typedef enum +{ + GPIO_Pin_00 = (0x1ul << 0), + GPIO_Pin_01 = (0x1ul << 1), + GPIO_Pin_02 = (0x1ul << 2), + GPIO_Pin_03 = (0x1ul << 3), + GPIO_Pin_04 = (0x1ul << 4), + GPIO_Pin_05 = (0x1ul << 5), + GPIO_Pin_06 = (0x1ul << 6), + GPIO_Pin_07 = (0x1ul << 7), + GPIO_Pin_08 = (0x1ul << 8), + GPIO_Pin_09 = (0x1ul << 9), + GPIO_Pin_10 = (0x1ul << 10), + GPIO_Pin_11 = (0x1ul << 11), + GPIO_Pin_12 = (0x1ul << 12), + GPIO_Pin_13 = (0x1ul << 13), + GPIO_Pin_14 = (0x1ul << 14), + GPIO_Pin_15 = (0x1ul << 15), + GPIO_PIN_All = 0xFFFFul + +} GPIO_PinTypeDef; + +/** + * GPIO Pin Alternate Function + */ +typedef enum +{ + GPIO_AF_0 = 0, + GPIO_AF_1, + GPIO_AF_2, + GPIO_AF_3, + GPIO_AF_4, + GPIO_AF_5, + GPIO_AF_6, + GPIO_AF_7, +} GPIO_AFTypeDef; + +typedef enum +{ + GPIO_Peri_Fn1, + GPIO_Peri_BKIN, + GPIO_Peri_ECAP0, + GPIO_Peri_ECAP1, + GPIO_Peri_ECAP2, + GPIO_Peri_EPETR, + GPIO_Peri_Fn2, + GPIO_Peri_TCAP0, + GPIO_Peri_TCAP1, + GPIO_Peri_TCAP2, + GPIO_Peri_T2ETR, + GPIO_Peri_I2C_PULL0, + GPIO_Peri_I2C_PULL1, + GPIO_Peri_I2C_PULL2, + GPIO_Peri_I2C_PULL3, + GPIO_Peri_I2C_PULL4, + GPIO_Peri_I2C_PULL5, + GPIO_Peri_I2C_PULL6, + GPIO_Peri_I2C_PULL7, +} GPIO_PeriTypeDef; + +/** + * Peripheral Alternate Function + * ps. GPIO FNx_AFR + */ +typedef enum +{ + GPIO_PeriAF_0 = 0, + GPIO_PeriAF_1, + GPIO_PeriAF_2, + GPIO_PeriAF_3, + GPIO_PeriAF_4, + GPIO_PeriAF_5, + GPIO_PeriAF_6, + GPIO_PeriAF_7, + GPIO_PeriAF_8, + GPIO_PeriAF_9, + GPIO_PeriAF_10, + GPIO_PeriAF_11, +} GPIO_PeriAFTypeDef; + +typedef enum +{ + GPIO_Polarity_Low_Fall = 0, // Low level or falling edge + GPIO_Polarity_High_Rise = 1, // High level or rising edge +} GPIO_PolarityTypeDef; + +typedef enum +{ + GPIO_Trigger_Level = 0, // Level trigger + GPIO_Trigger_Edge = 1, // Edge trigger + GPIO_Trigger_Any_Edge = 2, +} GPIO_TriggerTypeDef; + + +//============================================================================= +// Macro Definition +//============================================================================= +/** + * \brief Reads the input data of specified GPIO port pin. + * + * \param [in] pHGpio Pointer to a GPIO handler + * \param [in] pin the target pin, @ref GPIO_PinTypeDef + * \return + * 0 : pin low state + * others: pin high state + */ +__STATIC_FORCEINLINE uint8_t GPIO_ReadInputDataBit(GPIO_Type *pHGpio, GPIO_PinTypeDef pin) +{ + return REG_READ_MASK(pHGpio->DAT, pin) ? GPIO_PIN_HIGH : GPIO_PIN_LOW; +} + + +/** + * \brief Read all input data of a GPIO port. + * + * \param [in] pHGpio Pointer to a GPIO handler + * \return + * the gpio pins data + */ +__STATIC_FORCEINLINE uint16_t GPIO_ReadInputData(GPIO_Type *pHGpio) +{ + return REG_READ(pHGpio->DAT); +} + + +/** + * \brief Reads the output data of specified GPIO port pin. + * + * \param [in] pHGpio Pointer to a GPIO handler + * \param [in] pin the target pin, @ref GPIO_PinTypeDef + * \return + * 0 : pin low state + * others: pin high state + */ +__STATIC_FORCEINLINE uint8_t GPIO_ReadOutputDataBit(GPIO_Type *pHGpio, uint16_t pin) +{ + return REG_READ_MASK(pHGpio->DAT, pin) ? GPIO_PIN_HIGH : GPIO_PIN_LOW; +} + +/** + * \brief Reads all GPIO port pins output data. + * + * \param [in] pHGpio Pointer to a GPIO handler + * \return + * the gpio pins data + */ +__STATIC_FORCEINLINE uint16_t GPIO_ReadOutputData(GPIO_Type *pHGpio) +{ + return REG_READ(pHGpio->DAT); +} + + +/** + * \brief Sets the selected data port bits. + * + * \param [in] pHGpio Pointer to a GPIO handler + * \param [in] pins the target pin, @ref GPIO_PinTypeDef + * \return + * none + */ +__STATIC_FORCEINLINE void GPIO_SetBits(GPIO_Type *pHGpio, uint16_t pins) +{ + REG_SET_BITS(pHGpio->LAT, pins); + return; +} + +/** + * \brief Clears the selected data port bits. + * + * \param [in] pHGpio Pointer to a GPIO handler + * \param [in] pins the target pin, @ref GPIO_PinTypeDef + * \return + * none + */ +__STATIC_FORCEINLINE void GPIO_ResetBits(GPIO_Type *pHGpio, uint16_t pins) +{ + REG_CLR_BITS(pHGpio->LAT, pins); + return; +} + + +/** + * \brief Sets or clears the selected data port bit. + * + * \param [in] pHGpio Pointer to a GPIO handler + * \param [in] pins the target pin, @ref GPIO_PinTypeDef + * \param [in] state the target pin state, @ref GPIO_PinStateTypeDef + * \return + * None + */ +__STATIC_FORCEINLINE void GPIO_WriteBit(GPIO_Type *pHGpio, uint16_t pins, GPIO_PinStateTypeDef state) +{ + (state == GPIO_PIN_HIGH) ? + REG_SET_BITS(pHGpio->LAT, pins) : + REG_CLR_BITS(pHGpio->LAT, pins); + return; +} + +/** + * \brief Writes data to the specified GPIO data port. + * + * \param [in] pHGpio Pointer to a GPIO handler + * \param [in] value Specifies the value to be written to the port output data register + * \return + * None + */ +__STATIC_FORCEINLINE void GPIO_Write(GPIO_Type *pHGpio, uint16_t value) +{ + REG_WRITE(pHGpio->LAT, value); + return; +} + +/** + * \brief Toggle the specified pin of GPIO port. + * + * \param [in] pHGpio Pointer to a GPIO handler + * \param [in] pin The target pin, @ref GPIO_PinTypeDef + * \return + * None + */ +__STATIC_FORCEINLINE void GPIO_TogglePin(GPIO_Type *pHGpio, GPIO_PinTypeDef pin) +{ + pHGpio->LAT ^= pin; + return; +} + +/** + * \brief Enable/Disable the pin interrupt of GPIO + * + * \param [in] pHGpio Pointer to a GPIO handler + * \param [in] pin The target pin, @ref GPIO_PinTypeDef + * \return + * None + */ +__STATIC_FORCEINLINE void GPIO_ITEnable(GPIO_Type *pHGpio, GPIO_PinTypeDef pin) +{ + REG_SET_BITS(pHGpio->IES, pin); + return; +} + +__STATIC_FORCEINLINE void GPIO_ITDisable(GPIO_Type *pHGpio, GPIO_PinTypeDef pin) +{ + REG_SET_BITS(pHGpio->IEC, pin); + return; +} + +/** + * \brief Get the interrupt flag of a GPIO pin + * + * \param [in] pHGpio Pointer to a GPIO handler + * \param [in] pin The target pin, @ref GPIO_PinTypeDef + * \return + * the flag of status + */ +__STATIC_FORCEINLINE uint32_t GPIO_GetITFlag(GPIO_Type *pHGpio, GPIO_PinTypeDef pin) +{ + return REG_READ_MASK(pHGpio->IST, pin); +} +/** + * \brief Clear GPIO interrupt flag + * + * \param [in] pHGpio Pointer to a GPIO handler + * \param [in] pin The target pin, @ref GPIO_PinTypeDef + * \return + * None + */ +__STATIC_FORCEINLINE void GPIO_ClearITFlag(GPIO_Type *pHGpio, GPIO_PinTypeDef pin) +{ + REG_SET_BITS(pHGpio->IST, pin); + return; +} +//============================================================================= +// Structure Definition +//============================================================================= +typedef struct GPIO_ITInit +{ + GPIO_PolarityTypeDef GPIO_Polarity; /*!< Interrupt polarity. + This parameter can be a value of @ref GPIO_PolarityTypeDef */ + + GPIO_TriggerTypeDef GPIO_Trigger; /*!< Interrupt trigger type. + This parameter can be a value of @ref GPIO_TriggerTypeDef */ +} GPIO_ITInitTypeDef; + +typedef struct GPIO_Init +{ + uint16_t GPIO_Pin; /*!< GPIO_Pin */ + + GPIO_ModeTypeDef GPIO_Mode; /*!< GPIO_Mode */ + + GPIO_PuPdTypeDef GPIO_PuPd; /*!< Specifies the operating Pull-up/Pull down for the selected pins. + This parameter can be a value of @ref GPIO_PuPdTypeDef */ + + GPIO_OTypeTypeDef GPIO_OType; /*!< Specifies the operating output type for the selected pins. + This parameter can be a value of @ref GPIO_OTypeTypeDef */ + + GPIO_AFTypeDef GPIO_AF_Mode; /*!< Peripheral to be connected to the selected pins. + This parameter can be a value of @ref GPIO_AFTypeDef */ + + GPIO_ITInitTypeDef GPIO_ITInit; /*!< Specifies the interrupt initial parameters, @ref GPIO_ITInitTypeDef */ + + +} GPIO_InitTypeDef; +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +/** + * \brief Initializes the gpio peripheral according to the specified parameters. + * + * \param [in] pHGpio Pointer to a GPIO handler + * \param [in] pInit Pointer to a instance of GPIO_InitTypeDef + * \return + * 0 : success + * other: fail + */ +int GPIO_Init(GPIO_Type *pHGpio, GPIO_InitTypeDef *pInit); + +/** + * \brief De-initializes the gpio peripheral according to the specified parameters. + * + * \param [in] pHGpio Pointer to a GPIO handler + * \param [in] pins The target pin, @ref GPIO_PinTypeDef + * \return + * None + */ +void GPIO_DeInit(GPIO_Type *pHGpio, uint32_t pins); + + +/** + * \brief Set Pin configuration of Peripheral IP with the specific Alternate Function + * + * \param [in] pHGpio Pointer to a GPIO handler + * \param [in] peri_type the specific peripheral IP, @ref GPIO_PeriTypeDef + * \param [in] af_mode the af mode, @ref GPIO_PeriAFTypeDef + * \return + * None + */ +void GPIO_PeriAFConfig(GPIO_Type *pHGpio, GPIO_PeriTypeDef peri_type, GPIO_PeriAFTypeDef af_mode); + + +/** + * \brief Configure GPIO interrrupt + * + * \param [in] pHGpio Pointer to a GPIO handler + * \param [in] pins The target pin, @ref GPIO_PinTypeDef + * \param [in] pInit Pointer to an instance of GPIO_ITInitTypeDef, @ref GPIO_ITInitTypeDef + * \return + * Nore + */ +void GPIO_ITConfig(GPIO_Type *pHGpio, GPIO_PinTypeDef pins, GPIO_ITInitTypeDef *pInit); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_i2c.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_i2c.h new file mode 100644 index 0000000..8172fd4 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_i2c.h @@ -0,0 +1,325 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_i2c.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/10 + * @license + * @description + */ + +#ifndef __hal_i2c_H_wiTQLukR_lyWI_H9X1_s634_uL7YYZQ9qyOX__ +#define __hal_i2c_H_wiTQLukR_lyWI_H9X1_s634_uL7YYZQ9qyOX__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_def.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define I2C_BLOCKING 0xFFFF + +typedef enum +{ + I2C_Err_OK = 0, + I2C_Err_Fail, + I2C_Err_WrongParams, + I2C_Err_TimeOut, + +} I2C_ErrTypeDef; + +typedef enum +{ + /* Misc */ + I2C_State_ERROR = 0x00u, + I2C_State_BUS_IDLE = 0xF8u, + I2C_State_SLAVE_STOP_RESTART = 0xA0u, + + /* Master Transmit */ + I2C_State_MASTER_TX_START = 0x08u, + I2C_State_MASTER_TX_RESTART = 0x10u, + I2C_State_MASTER_TX_SLAW_ACK = 0x18u, // Master sent (SlaveAddress + W-bit) and received ACK + I2C_State_MASTER_TX_SLAW_NOACK = 0x20u, + I2C_State_MASTER_TX_DATA_ACK = 0x28u, // Master sent data and received ACK + I2C_State_MASTER_TX_DATA_NOACK = 0x30u, + I2C_State_MASTER_TX_LOST_BUS = 0x38u, + + /* Master Receive */ + I2C_State_MASTER_RX_START = I2C_State_MASTER_TX_START, + I2C_State_MASTER_RX_RESTART = I2C_State_MASTER_TX_RESTART, + I2C_State_MASTER_RX_SLAR_ACK = 0x40u, // Master sent (SlaveAddress + R-bit) and received ACK + I2C_State_MASTER_RX_SLAR_NOACK = 0x48u, + I2C_State_MASTER_RX_DATA_ACK = 0x50u, // Master received data and received ACK + I2C_State_MASTER_RX_DATA_NOACK = 0x58u, + I2C_State_MASTER_RX_LOST_BUS = I2C_State_MASTER_TX_LOST_BUS, + + /* Slave Receive */ + I2C_State_SLAVE_RX_SLAW_ACK = 0x60u, + I2C_State_SLAVE_RX_SLAW_LOST_BUS = 0x68u, + I2C_State_SLAVE_RX_BROAD_ACK = 0x70u, // received broad address and sent ACK + I2C_State_SLAVE_RX_BADDR_LOST_BUS = 0x78u, + I2C_State_SLAVE_RX_DATA_ACK = 0x80u, // received data and sent ACK + I2C_State_SLAVE_RX_DATA_NOACK = 0x88u, + I2C_State_SLAVE_RX_BDATA_ACK = 0x90u, // received data (with broad address) and sent ACK + I2C_State_SLAVE_RX_BDATA_NOACK = 0x98u, + + /* Slave Transmit */ + I2C_State_SLAVE_RX_SLAR_ACK = 0xA8u, + I2C_State_SLAVE_TX_LOST_BUS = 0xB0u, + I2C_State_SLAVE_TX_DATA_ACK = 0xB8u, + I2C_State_SLAVE_TX_DATA_NOACK = 0xC0u, + I2C_State_SLAVE_TX_LAST_DATA = 0xC8u, + +} I2C_StateTypeDef; + +/** + * I2C role mode + */ +typedef enum +{ + I2C_Mode_NONE = 0x00U, /*!< No I2C communication on going */ + I2C_Mode_MASTER = 0x10U, /*!< I2C communication is in Master Mode */ + I2C_Mode_SLAVE = 0x20U, /*!< I2C communication is in Slave Mode */ +} I2C_ModeTypeDef; + +/** + * The divide of I2C Clock + */ +typedef enum +{ + I2C_CLK_Div60 = 60, + I2C_CLK_Div120 = 120, + I2C_CLK_Div160 = 160, + I2C_CLK_Div192 = 192, + I2C_CLK_Div244 = 244, + I2C_CLK_Div256 = 256, + I2C_CLK_Div960 = 960, + +} I2C_Clk_DivTypeDef; + +typedef enum +{ + I2C_BroadAck_Disable = 0x0ul, + I2C_BroadAck_Enable = I2C_ADDR_GC_Msk, +} I2C_BroadAckTypeDef; + +typedef enum +{ + I2C_XferMode_Idle = 0, + I2C_XferMode_Transmite, + I2C_XferMode_Recevie, +} I2C_XferModeTypeDef; +//============================================================================= +// Macro Definition +//============================================================================= +/** + * \brief Get the Hardware state of an I2C + * + * \param [in] pHI2C The handle of I2C + * \return + * Hardware state + */ +__STATIC_FORCEINLINE uint32_t I2C_GetHwState(I2C_Type *pHI2C) +{ + return pHI2C->STAT_b.STAT; +} +//============================================================================= +// Structure Definition +//============================================================================= +/** + * I2C Initial Configuration + */ +typedef struct I2C_Init +{ + I2C_Clk_DivTypeDef ClockDiv; + I2C_ModeTypeDef Mode; /*!< Specifies the I2C mode. This parameter can be a value of I2C_mode. */ + uint8_t OwnAddress; /*!< Specifies the first device own address. This parameter can be a 7-bit address. */ + I2C_BroadAckTypeDef BroadAck; /*!< ACK enable or disable when as slave. + This parameter can be a value of @ref I2C_BroadAckTypeDef */ +} I2C_InitTypeDef; + +typedef struct I2C_IT_Handle +{ + I2C_Type *pHI2C; + + uint8_t *pTxBuffPtr; /*!< Pointer to I2C Tx transfer Buffer */ + __IO uint16_t TxXferCount; /*!< I2C Tx Transfer Counter */ + + uint8_t *pRxBuffPtr; /*!< Pointer to I2C Rx transfer Buffer */ + __IO uint16_t RxXferCount; /*!< I2C Rx Transfer Counter */ + + I2C_XferModeTypeDef XferMode; + __IO uint16_t DevAddress; /*!< I2C Target device address */ + +} I2C_IT_HandleTypeDef; +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +/** + * \brief Fills each init_struct member with its default value. + * + * \param [in] pInit Pointer to an I2C_InitTypeDef structure + * which will be initialized. + * \return + * None + */ +void I2C_StructInit(I2C_InitTypeDef *pInit); + +/** + * \brief Initializes the I2C module + * + * \param [in] pHI2C Pointer to an I2C handler + * \param [in] pInit Pointer to an I2C_InitTypeDef structure that + * contains the configuration information for the specified + * I2C peripheral + * \return + * error code, @ref I2C_ErrTypeDef + */ +I2C_ErrTypeDef I2C_Init(I2C_Type *pHI2C, I2C_InitTypeDef *pInit); + +/** + * \brief De-Initializes the I2C peripheral registers to their default values. + * + * \param [in] pHI2C Pointer to an I2C handler + * \return + * None + */ +void I2C_DeInit(I2C_Type *pHI2C); + +/** + * \brief I2C-Master transmits an amount of data in blocking mode. + * + * \param [in] pHI2C Pointer to an I2C handler + * \param [in] DevAddr Target device address: The device 7 bits address value + * in datasheet must be shift at right before call interface + * \param [in] pData Pointer to data buffer + * \param [in] Size Amount of data to be sent + * \return + * error code, @ref I2C_ErrTypeDef + */ +I2C_ErrTypeDef I2C_Master_Transmit(I2C_Type *pHI2C, uint16_t DevAddr, uint8_t *pData, uint16_t Size); + +/** + * \brief I2C-Master receives an amount of data in blocking mode. + * + * \param [in] pHI2C Pointer to an I2C handler + * \param [in] DevAddr Target device address: The device 7 bits address value + * in datasheet must be shift at right before call interface + * \param [in] pData Pointer to data buffer + * \param [in] pSize Amount of data to be received + * \param [in] Timeout_ms Timeout with mseconds. If Timeout_ms == I2C_BLOCKING, slave transmit with blocking mode + * \return + * error code, @ref I2C_ErrTypeDef + */ +I2C_ErrTypeDef I2C_Master_Receive(I2C_Type *pHI2C, uint8_t DevAddr, uint8_t *pData, uint16_t *pSize, uint16_t Timeout_ms); + + +/** + * \brief I2C-Slave Transmit data in blocking mode + * + * \param [in] pHI2C Pointer to an I2C handler + * \param [in] pData Pointer to data buffer + * \param [in] Size Amount of data to be sent + * \param [in] Timeout_ms Timeout with mseconds. If Timeout_ms == I2C_BLOCKING, slave transmit with blocking mode + * \return + * error code, @ref I2C_ErrTypeDef + */ +I2C_ErrTypeDef I2C_Slave_Transmit(I2C_Type *pHI2C, uint8_t *pData, uint16_t Size, uint16_t Timeout_ms); + +/** + * \brief I2C-Slave Receive data in blocking mode + * + * \param [in] pHI2C Pointer to an I2C handler + * \param [in] pData Pointer to data buffer + * \param [in] pSize Amount of data to be received + * \param [in] Timeout_ms Timeout with mseconds. If Timeout_ms == I2C_BLOCKING, slave transmit with blocking mode + * \return + * error code, @ref I2C_ErrTypeDef + */ +I2C_ErrTypeDef I2C_Slave_Receive(I2C_Type *pHI2C, uint8_t *pData, uint16_t *pSize, uint16_t Timeout_ms); + +/** + * \brief I2C-Master transmits an amount of data in interrupt mode. + * + * \param [in] pHITI2C Pointer to an I2C IT handler, @ref I2C_IT_HandleTypeDef + * \param [in] DevAddr Target device address: The device 7 bits address value + * in datasheet must be shift at right before call interface + * \param [in] pData Pointer to data buffer + * \param [in] Size Amount of data to be sent + * \return + * error code, @ref I2C_ErrTypeDef + */ +I2C_ErrTypeDef I2C_Master_Transmit_IT(I2C_IT_HandleTypeDef *pHITI2C, uint16_t DevAddr, uint8_t *pData, uint16_t Size); + +/** + * \brief I2C-Master receives an amount of data in interrupt mode. + * + * \param [in] pHITI2C Pointer to an I2C IT handler, @ref I2C_IT_HandleTypeDef + * \param [in] DevAddr Target device address: The device 7 bits address value + * in datasheet must be shift at right before call interface + * \param [in] pData Pointer to data buffer + * \param [in] Size Amount of data to be received + * \return + * error code, @ref I2C_ErrTypeDef + */ +I2C_ErrTypeDef I2C_Master_Receive_IT(I2C_IT_HandleTypeDef *pHITI2C, uint8_t DevAddr, uint8_t *pData, uint16_t Size); + +/** + * \brief I2C-Slave Transmit data in interrupt mode + * + * \param [in] pHITI2C Pointer to an I2C IT handler, @ref I2C_IT_HandleTypeDef + * \param [in] pData Pointer to data buffer + * \param [in] Size Amount of data to be sent + * \return + * error code, @ref I2C_ErrTypeDef + */ +I2C_ErrTypeDef I2C_Slave_Transmit_IT(I2C_IT_HandleTypeDef *pHITI2C, uint8_t *pData, uint16_t Size); + +/** + * \brief I2C-Slave Receive data in interrupt mode + * + * \param [in] pHITI2C Pointer to an I2C IT handler, @ref I2C_IT_HandleTypeDef + * \param [in] pData Pointer to data buffer + * \param [in] Size Amount of data to be received + * \return + * error code, @ref I2C_ErrTypeDef + */ +I2C_ErrTypeDef I2C_Slave_Receive_IT(I2C_IT_HandleTypeDef *pHITI2C, uint8_t *pData, uint16_t Size); + +/** + * \brief This function handles I2C-Master interrupt request. + * + * \param [in] pHITI2C Pointer to an I2C IT Handler, @ref I2C_IT_HandleTypeDef + * \return + * None + */ +void I2C_Master_IRQHandler(I2C_IT_HandleTypeDef *pHITI2C); + +/** + * \brief This function handles I2C-Slave interrupt request. + * + * \param [in] pHITI2C Pointer to an I2C IT Handler, @ref I2C_IT_HandleTypeDef + * \return + * None + */ +void I2C_Slave_IRQHandler(I2C_IT_HandleTypeDef *pHITI2C); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_lptim.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_lptim.h new file mode 100644 index 0000000..2baa23a --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_lptim.h @@ -0,0 +1,244 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file lptim.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + +#ifndef __hal_lptim_H_wP2Tfucu_lfcA_HOTx_s6ox_udtG8lP5WVqK__ +#define __hal_lptim_H_wP2Tfucu_lfcA_HOTx_s6ox_udtG8lP5WVqK__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_def.h" +//============================================================================= +// Constant Definition +//============================================================================= +typedef enum +{ + LPTIM_CLK_Src_SysClk = (LPTIM_TCR_CLKS_SysClk << LPTIM_TCR_CLKS_Pos), + LPTIM_CLK_Src_LSI = (LPTIM_TCR_CLKS_LSI << LPTIM_TCR_CLKS_Pos), + +} LPTIM_CLK_SrcTypeDef; + +typedef enum +{ + LPTIM_MatchMode_Normal = 0, + LPTIM_MatchMode_IRQ = LPTIM_MCR_MR0INT_Msk, + LPTIM_MatchMode_Reset = LPTIM_MCR_MR0RST_Msk, + LPTIM_MatchMode_Stop = LPTIM_MCR_MR0STOP_Msk, +} LPTIM_MatchModeTypeDef; + +typedef enum +{ + LPTIM_Flag_Match0 = LPTIM_IR_MR0_Msk, +} LPTIM_FlagTypeDef; + +typedef enum +{ + LPTIM_TrigSrc_Normal = (LPTIM_TCR_TRIGSEL_Normal << LPTIM_TCR_TRIGSEL_Pos), + LPTIM_TrigSrc_PWMCh0_Rising = (LPTIM_TCR_TRIGSEL_EPWMCh0P << LPTIM_TCR_TRIGSEL_Pos), + LPTIM_TrigSrc_PWMCh1_Rising = (LPTIM_TCR_TRIGSEL_EPWMCh1P << LPTIM_TCR_TRIGSEL_Pos), + LPTIM_TrigSrc_PWMCh2_Rising = (LPTIM_TCR_TRIGSEL_EPWMCh2P << LPTIM_TCR_TRIGSEL_Pos), + LPTIM_TrigSrc_PWMCh0_Falling = (LPTIM_TCR_TRIGSEL_EPWMCh0N << LPTIM_TCR_TRIGSEL_Pos), + LPTIM_TrigSrc_PWMCh1_Falling = (LPTIM_TCR_TRIGSEL_EPWMCh1N << LPTIM_TCR_TRIGSEL_Pos), + LPTIM_TrigSrc_PWMCh2_Falling = (LPTIM_TCR_TRIGSEL_EPWMCh2N << LPTIM_TCR_TRIGSEL_Pos), +} LPTIM_TrigSrcTypeDef; + +//============================================================================= +// Macro Definition +//============================================================================= +/** + * \brief LpTim enable/disable + * + * \param [in] pHLpTim the LpTim/TIm0/TIM1 instance + * \return + * None + */ +__STATIC_INLINE void LPTIM_Enable(LPTIM_Type *pHLpTim) +{ + REG_SET_BITS(pHLpTim->TCR, LPTIM_TCR_CEN_Msk); + return; +} + +__STATIC_INLINE void LPTIM_Disable(LPTIM_Type *pHLpTim) +{ + REG_CLR_BITS(pHLpTim->TCR, LPTIM_TCR_CEN_Msk); + return; +} + +/** + * \brief Check whether the specified LpTIM flag is set or not. + * + * \param [in] pHLpTim the LpTim/TIm0/TIM1 instance + * \param [in] flag specifies the flag to check, @ref LPTIM_FlagTypeDef. + * \return + * 0: no status + * others: get the status + */ +__STATIC_INLINE uint32_t LPTIM_GetFlagStatus(LPTIM_Type *pHLpTim, LPTIM_FlagTypeDef flag) +{ + return REG_READ_MASK(pHLpTim->IR, flag); +} + +/** + * \brief Clear the LpTim's pending flags. + * + * \param [in] pHLpTim the LpTim/TIm0/TIM1 instance + * \param [in] flag specifies the flag to clear, @ref LPTIM_FlagTypeDef. + * \return + * None + */ +__STATIC_INLINE void LPTIM_ClearFlag(LPTIM_Type *pHLpTim, LPTIM_FlagTypeDef flag) +{ + REG_SET_BITS(pHLpTim->IR, flag); + return; +} + +/** + * \brief Reset LpTim + * + * \param [in] pHLpTim the LpTim/TIm0/TIM1 instance + * \return + * None + */ +__STATIC_INLINE void LPTIM_Reset(LPTIM_Type *pHLpTim) +{ + REG_SET_BITS(pHLpTim->TCR, LPTIM_TCR_CRST_Msk); + return; +} + +/** + * \brief Set the compare mode + * + * \param [in] pHLpTim the LpTim/TIm0/TIM1 instance + * \param [in] mode the specific match mode, @ref LPTIM_MatchModeTypeDef + * \param [in] MatchValue the target match value + * \return + * None + */ +__STATIC_INLINE void LPTIM_SetMatch(LPTIM_Type *pHLpTim, LPTIM_MatchModeTypeDef mode, uint16_t MatchValue) +{ + REG_SET_BITS(pHLpTim->MCR, mode); + REG_WRITE_MASK(pHLpTim->MR0, LPTIM_MR0_MR0_Msk, (MatchValue << LPTIM_MR0_MR0_Pos)); + return; +} + +/** + * \brief Set LpTim prescaler + * + * \param [in] pHLpTim the LpTim/TIm0/TIM1 instance + * \param [in] pr_value prescaler value + * \return + * None + */ +__STATIC_INLINE void LPTIM_SetPrescaler(LPTIM_Type *pHLpTim, uint8_t pr_value) +{ + REG_WRITE_MASK(pHLpTim->PR, LPTIM_PR_PR_Msk, (pr_value << LPTIM_PR_PR_Pos)); + return; +} + +/** + * \brief Get actual counter value + * + * \param [in] pHLpTim the LpTim/TIm0/TIM1 instance + * \return + * Counter value + */ +__STATIC_INLINE uint16_t LPTIM_GetCounter(LPTIM_Type *pHLpTim) +{ + return REG_READ_MASK(pHLpTim->TC, LPTIM_TC_TC_Msk); +} + + +/** + * \brief Configure the external trigger used as a trigger event for the LPTIM. + * + * \param [in] pHLpTim the LpTim/TIm0/TIM1 instance + * \param [in] trig_src specific the tirgger source of LpTim, @ref LPTIM_TrigSrcTypeDef + * \return + * None + */ +__STATIC_INLINE void LPTIM_ConfigTrigger(LPTIM_Type *pHLpTim, LPTIM_TrigSrcTypeDef trig_src) +{ + REG_WRITE_MASK(pHLpTim->TCR, LPTIM_TCR_TRIGSEL_Msk, trig_src); + return; +} +//============================================================================= +// Structure Definition +//============================================================================= + +/** + * LpTIM Init structure definition + */ +typedef struct +{ + LPTIM_CLK_SrcTypeDef LPTIM_ClockSource; /*!< Specifies the source of the clock. */ + LPTIM_MatchModeTypeDef LPTIM_MatchMode; /*!< Specifies the mode when LPTIM matches the target counter value. */ + uint16_t LPTIM_MatchValue; /*!< Specifies the repetition counter value. */ + uint8_t LPTIM_Prescaler; /*!< Specifies the prescaler value used to divide the LPTIM clock. */ +} LPTIM_InitTypeDef; +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +/** + * @brief Fills each LPTIM_InitTypeDef member with its default value. + * @param pInit: pointer to a LPTIM_TimeBaseInitTypeDef + * structure which will be initialized. + * @retval None. + */ +void LPTIM_StructInit(LPTIM_InitTypeDef *pInit); + + +/** + * @brief Initializes the lptim module according to + * the specified parameters in the init_struct. + * + * @param pHLpTim: the LpTim/TIm0/TIM1 instance + * @param pInit: pointer to a LPTIM_InitTypeDef structure + that contains the configuration information for the + * specified LpTIM module. + * @retval None. + */ +void LPTIM_Init(LPTIM_Type *pHLpTim, LPTIM_InitTypeDef *pInit); + +/** + * \brief De-initialize LpTim + * + * \param [in] pHLpTim the LpTim/TIm0/TIM1 instance + * \return + * None + */ +void LPTIM_DeInit(LPTIM_Type *pHLpTim); + +/** + * \brief Enables or disables the specified LpTim interrupts + * + * \param [in] pHLpTim the LpTim/TIm0/TIM1 instance + * \param [in] has_enable enable or not + * \return + * None + */ +void LPTIM_ITConfig(LPTIM_Type *pHLpTim, int has_enable); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_opamp.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_opamp.h new file mode 100644 index 0000000..7993a53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_opamp.h @@ -0,0 +1,185 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_opamp.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/12/05 + * @license + * @description + */ + +#ifndef __hal_opamp_H_wWPO7hlc_lEYx_HN8q_ssua_u8WscF53B3q1__ +#define __hal_opamp_H_wWPO7hlc_lEYx_HN8q_ssua_u8WscF53B3q1__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_def.h" +//============================================================================= +// Constant Definition +//============================================================================= +/** + * The gain type of PGA of OPAMP + */ +typedef enum +{ + OPAMP_PGAGain_Ext = (0x00 << OPAMP_PGA_CR_PGA_GAIN_Pos), + OPAMP_PGAGain_1 = (OPAMP_PGA_CR_PGA_GAIN_x1 << OPAMP_PGA_CR_PGA_GAIN_Pos), + OPAMP_PGAGain_2 = (OPAMP_PGA_CR_PGA_GAIN_x2 << OPAMP_PGA_CR_PGA_GAIN_Pos), + OPAMP_PGAGain_3 = (OPAMP_PGA_CR_PGA_GAIN_x3 << OPAMP_PGA_CR_PGA_GAIN_Pos), + OPAMP_PGAGain_4 = (OPAMP_PGA_CR_PGA_GAIN_x4 << OPAMP_PGA_CR_PGA_GAIN_Pos), + OPAMP_PGAGain_5 = (OPAMP_PGA_CR_PGA_GAIN_x5 << OPAMP_PGA_CR_PGA_GAIN_Pos), + OPAMP_PGAGain_6 = (OPAMP_PGA_CR_PGA_GAIN_x6 << OPAMP_PGA_CR_PGA_GAIN_Pos), + OPAMP_PGAGain_7 = (OPAMP_PGA_CR_PGA_GAIN_x7 << OPAMP_PGA_CR_PGA_GAIN_Pos), + OPAMP_PGAGain_8 = (OPAMP_PGA_CR_PGA_GAIN_x8 << OPAMP_PGA_CR_PGA_GAIN_Pos), + OPAMP_PGAGain_9 = (OPAMP_PGA_CR_PGA_GAIN_x9 << OPAMP_PGA_CR_PGA_GAIN_Pos), + OPAMP_PGAGain_10 = (OPAMP_PGA_CR_PGA_GAIN_x10 << OPAMP_PGA_CR_PGA_GAIN_Pos), + OPAMP_PGAGain_11 = (OPAMP_PGA_CR_PGA_GAIN_x11 << OPAMP_PGA_CR_PGA_GAIN_Pos), + OPAMP_PGAGain_12 = (OPAMP_PGA_CR_PGA_GAIN_x12 << OPAMP_PGA_CR_PGA_GAIN_Pos), + OPAMP_PGAGain_13 = (OPAMP_PGA_CR_PGA_GAIN_x13 << OPAMP_PGA_CR_PGA_GAIN_Pos), + OPAMP_PGAGain_14 = (OPAMP_PGA_CR_PGA_GAIN_x14 << OPAMP_PGA_CR_PGA_GAIN_Pos), + OPAMP_PGAGain_15 = (OPAMP_PGA_CR_PGA_GAIN_x15 << OPAMP_PGA_CR_PGA_GAIN_Pos), + OPAMP_PGAGain_16 = (OPAMP_PGA_CR_PGA_GAIN_x16 << OPAMP_PGA_CR_PGA_GAIN_Pos), + +} OPAMP_PGAGainTypeDef; + + +/** + * The Vinput Plus signal source + */ +typedef enum +{ + OPAMP_VinP_Internal = (0x0ul << OPAMP_PGA_CR_PGA_VIP_SEL_Pos), + OPAMP_VinP_IO = (0x1ul << OPAMP_PGA_CR_PGA_VIP_SEL_Pos), +} OPAMP_VinPTypeDef; + +/** + * The Vinput Minus signal source + */ +typedef enum +{ + OPAMP_VinM_GND = (0x0ul << OPAMP_PGA_CR_PGA_VIN_SEL_Pos), + OPAMP_VinM_IO = (0x1ul << OPAMP_PGA_CR_PGA_VIN_SEL_Pos), +} OPAMP_VinMTypeDef; + +/** + * The Voutput destination + */ +typedef enum +{ + OPAMP_Vout_None = (0x0ul << OPAMP_PGA_CR_PGA_IO_EN_Pos), + OPAMP_Vout_IO = (0x1ul << OPAMP_PGA_CR_PGA_IO_EN_Pos), +} OPAMP_VoutTypeDef; +//============================================================================= +// Macro Definition +//============================================================================= +/** + * \brief Enable OPAMP + * + * \param [in] pHOPAmp The OPAMP instance + * \return + * None + */ +__STATIC_FORCEINLINE void OPAMP_Enable(OPAMP_Type *pHOPAmp) +{ + REG_SET_BITS(pHOPAmp->PGA_CR, OPAMP_PGA_CR_PGA_EN_Msk); + return; +} + +/** + * \brief Disable OPAMP + * + * \param [in] pHOPAmp The OPAMP instance + * \return + * None + */ +__STATIC_FORCEINLINE void OPAMP_Disable(OPAMP_Type *pHOPAmp) +{ + REG_CLR_BITS(pHOPAmp->PGA_CR, OPAMP_PGA_CR_PGA_EN_Msk); + return; +} + +/** + * \brief Set OPAMP PGA gain + * + * \param [in] pHOPAmp The OPAMP instance + * \param [in] gain The PGA gain, @ref OPAMP_PGAGainTypeDef + * \return + * None + */ +__STATIC_FORCEINLINE void OPAMP_SetPGAGain(OPAMP_Type *pHOPAmp, OPAMP_PGAGainTypeDef gain) +{ + REG_WRITE_MASK(pHOPAmp->PGA_CR, OPAMP_PGA_CR_PGA_GAIN_Msk, gain); + return; +} + +/** + * \brief Get OPAMP PGA gain + * + * \param [in] pHOPAmp The OPAMP instance + * \return + * the gain value, @ref OPAMP_PGAGainTypeDef + */ +__STATIC_FORCEINLINE OPAMP_PGAGainTypeDef OPAMP_GetPGAGain(OPAMP_Type *pHOPAmp) +{ + return REG_READ_MASK(pHOPAmp->PGA_CR, OPAMP_PGA_CR_PGA_GAIN_Msk); +} + +//============================================================================= +// Structure Definition +//============================================================================= +typedef struct +{ + OPAMP_VinPTypeDef OPAMP_VinP; + OPAMP_VinMTypeDef OPAMP_VinM; + OPAMP_VoutTypeDef OPAMP_Vout; + OPAMP_PGAGainTypeDef OPAMP_Gain; /*!< Specifies the PGA Gain of OPAMP, @ref OPAMP_PGAGainTypeDef */ +} OPAMP_InitTypeDef; +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +/** + * \brief Initialize OPAMP + * + * \param [in] pHOPAmp The OPAMP instance + * \param [in] pInit pointer to a OPAMP_InitTypeDef structure + * \return + * 0: ok, others: fail + */ +int OPAMP_Init(OPAMP_Type *pHOPAmp, OPAMP_InitTypeDef *pInit); + +/** + * \brief De-Initialize OPAMP + * + * \param [in] pHOPAmp The OPAMP instance + * \return + * None + */ +void OPAMP_DeInit(OPAMP_Type *pHOPAmp); + +/** + * \brief Set each field to default value + * + * \param [in] pInit pointer to a OPAMP_InitTypeDef structure + * \return + * None + */ +void OPAMP_StructInit(OPAMP_InitTypeDef *pInit); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_pwr.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_pwr.h new file mode 100644 index 0000000..0f377fb --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_pwr.h @@ -0,0 +1,112 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_pwr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + +#ifndef __hal_pmu_H_w8beFgJ5_lJKl_Ha3F_skkM_ujsx8CpdddI2__ +#define __hal_pmu_H_w8beFgJ5_lJKl_Ha3F_skkM_ujsx8CpdddI2__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_def.h" +//============================================================================= +// Constant Definition +//============================================================================= +/** + * Power mode type + */ +typedef enum PWR_Mode +{ + PWR_Mode_Sleep = 0, + PWR_Mode_DeepSleep, + +} PWR_ModeTypeDef; + +/** + * The wake-up type of power mode + */ +typedef enum PWR_Wakeup +{ + PWR_Wakeup_IO_PORT_A = (0x1ul << 0), + PWR_Wakeup_IO_PORT_B = (0x1ul << 1), + PWR_Wakeup_LpTIM = (0x1ul << 2), + PWR_Wakeup_WDG = (0x1ul << 3), + +} PWR_WakeupTypeDef; + +/** + * \brief Set the peripheral before entering power mode + * + * \param [in] pwr_mode the target power mode, @ref PWR_ModeTypeDef + * \param [in] pWakeup_type provide the target wake-up module from App level + * \return + * None + */ +typedef void (*CallbaskPreSleepTypeDef)(PWR_ModeTypeDef pwr_mode, PWR_WakeupTypeDef *pWakeup_type); + +/** + * \brief Set the peripheral after power mode wake-up + * + * \param [in] pwr_mode the target power mode, @ref PWR_ModeTypeDef + * \return + * None + */ +typedef void (*CallbaskPostSleepTypeDef)(PWR_ModeTypeDef pwr_mode); + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +/** + * \brief Enters Sleep mode + * + * @param [in] cb_pre_set_clk Set peripheral BEFORE entering sleep + * @param [in] cb_post_set_clk Set peripheral AFTER wake-up from sleep + * \return + * None + */ +void PWR_EnterSleepMode(CallbaskPreSleepTypeDef cb_pre_set, + CallbaskPostSleepTypeDef cb_post_set); + + +/** + * @brief Enters Deep Sleep mode. + * + * @param [in] cb_pre_set_clk Set peripheral BEFORE entering deepsleep + * @param [in] cb_post_set_clk Set peripheral AFTER wake-up from deepsleep + * @return + * None + */ +void PWR_EnterDeepSleepMode(CallbaskPreSleepTypeDef cb_pre_set, + CallbaskPostSleepTypeDef cb_post_set); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_spi.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_spi.h new file mode 100644 index 0000000..3bddd67 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_spi.h @@ -0,0 +1,145 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_spi.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + +#ifndef __hal_spi_H_wPLkKnnQ_le5I_Hr02_sscR_uSVsVXDq15tf__ +#define __hal_spi_H_wPLkKnnQ_le5I_Hr02_sscR_uSVsVXDq15tf__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_def.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define SPI_Mode_Slave (0x00U) /*!< SPI slave mode */ +#define SPI_Mode_Master (0x01U) /*!< SPI master mode */ + +#define SPI_CPOL_Low (0x00U) /*!< The clock is low in idle state. */ +#define SPI_CPOL_High (0x01U) /*!< The clock is high in idle state. */ + +#define SPI_CPHA_Effective (0x00U) /*!< Data sampling starts from the second clock edge. */ +#define SPI_CPHA_Ineffective (0x01U) /*!< Data sampling starts from the first clock edge. */ + + +#define SPI_FirstBit_MSB (0x00U) /*!< Data transfers start from MSB */ +#define SPI_FirstBit_LSB (0x01U) /*!< Data transfers start from LSB */ + +#define SPI_SSOUT_Selected (0x00U) +#define SPI_SSOUT_NoSelected (0x01U) + +#define SPI_ManualMode_Disable (0x00U) +#define SPI_ManualMode_Enable (0x01U) + +#define SPI_RECVOV_Flag (0x01 << SPI_STA_RECVOV_Pos) +#define SPI_MDF_Flag (0x01 << SPI_STA_MDF_Pos) +#define SPI_TXNFUL_Flag (0x01 << SPI_STA_TXNFUL_Pos) +#define SPI_TXFUL_Flag (0x01 << SPI_STA_TXFUL_Pos) +#define SPI_RXNEP_Flag (0x01 << SPI_STA_RXNEP_Pos) +#define SPI_RXFUL_Flag (0x01 << SPI_STA_RXFUL_Pos) +#define SPI_TXUFL_Flag (0x01 << SPI_STA_TXUFL_Pos) +#define SPI_BUSY_Flag (0x01 << SPI_STA_BUSY_Pos) + +typedef enum +{ + SPI_TxDataSize_8b = 0, /*!< 8 bits valid data */ + SPI_TxDataSize_16b , /*!< 16 bits valid data */ + SPI_TxDataSize_24b , /*!< 24 bits valid data */ + SPI_TxDataSize_32b , /*!< 32 bits valid data */ +} SPI_TXDataSizeTypedef; + +typedef enum +{ + SPI_BaudratePrescaler_2 = 0, /*!< SCK clock devide by 2 */ + SPI_BaudratePrescaler_4 , /*!< SCK clock devide by 4 */ + SPI_BaudratePrescaler_8 , /*!< SCK clock devide by 7 */ + SPI_BaudratePrescaler_16 , /*!< SCK clock devide by 16 */ + SPI_BaudratePrescaler_32 , /*!< SCK clock devide by 32 */ + SPI_BaudratePrescaler_64 , /*!< SCK clock devide by 64 */ + SPI_BaudratePrescaler_128 , /*!< SCK clock devide by 128 */ + SPI_BaudratePrescaler_256 , /*!< SCK clock devide by 256 */ +} SPI_DBTypedef; +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= +/** + * @brief SPI Init structure definition + */ +typedef struct +{ + uint32_t SPI_Mode; /*!< Specifies the SPI operating mode */ + uint32_t SPI_CPOL; /*!< Specifies the serial clock steady state */ + uint32_t SPI_CPHA; /*!< Specifies the clock active edge for the bit capture */ + uint32_t SPI_TxDataSize; /*!< Specifies the SPI available data size */ + uint32_t SPI_BaudRatePrescaler; /*!< Specifies the Baud Rate prescaler value which will be */ + uint32_t SPI_FirstBit; /*!< Specifies whether data transfers start from MSB or LSB bit */ +} SPI_InitTypeDef; + +typedef struct +{ + uint8_t d_int; /*!< Specifies the SPI operating mode */ + uint8_t d_after; /*!< Specifies the serial clock steady state */ + uint8_t d_btwn; /*!< Specifies the clock active edge for the bit capture */ + uint8_t d_nss; /*!< Specifies the SPI available data size */ + +} SPI_DelayTypeDef; + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +void SPI_DeInit(SPI_Type *spi); +void SPI_StructInit(SPI_InitTypeDef *init_struct); +void SPI_Init(SPI_Type *spi, SPI_InitTypeDef *init_struct); +void SPI_Enable(SPI_Type *spi); +void SPI_Disable(SPI_Type *spi); +void SPI_MasterEnable(SPI_Type *spi); +void SPI_SlaveEnable(SPI_Type *spi); +void SPI_SendData(SPI_Type *spi, uint32_t data); +uint32_t SPI_ReceiveData(SPI_Type *spi); +void SPI_SetBaudRatePrescaler(SPI_Type *spi, SPI_DBTypedef spi_baudrateprescaler); +void SPI_SetSSOUT(SPI_Type *spi, uint32_t ss_out_value); +void SPI_SetManualChipSelect(SPI_Type *spi, uint32_t mcs_value); +void SPI_SetManualMode(SPI_Type *spi, uint32_t mce_en); +void SPI_ManualModeStart(SPI_Type *spi); +void SPI_SetTxDataSize(SPI_Type *spi, SPI_TXDataSizeTypedef datasize_value); +uint32_t SPI_GetInterruptStatus(SPI_Type *spi, uint32_t flag); +uint32_t SPI_GetFlagStatus(SPI_Type *spi, uint32_t flag); +void SPI_ClearFlagStatus(SPI_Type *spi, uint32_t flag); +void SPI_SetInterrupt(SPI_Type *spi, uint32_t flag); +void SPI_SetInterruptDisable(SPI_Type *spi, uint32_t flag); +void SPI_SetDelay(SPI_Type *spi, SPI_DelayTypeDef * delay_set); +void SPI_SetIdleCnt(SPI_Type *spi, uint32_t idle_cnt); +void SPI_SetTXTH(SPI_Type *spi, uint32_t txth); +void SPI_SetRXTH(SPI_Type *spi, uint32_t rxth); + +void SPI_ManualSendData(SPI_Type *spi, uint32_t data); + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_syscfg.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_syscfg.h new file mode 100644 index 0000000..019682d --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_syscfg.h @@ -0,0 +1,522 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_rcc.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + +#ifndef __hal_rcc_H_wdMtMHdK_l9Vy_HKdj_sp8x_uwqQm6IIBDo5__ +#define __hal_rcc_H_wdMtMHdK_l9Vy_HKdj_sp8x_uwqQm6IIBDo5__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_def.h" +//============================================================================= +// Constant Definition +//============================================================================= + +#define SYSCFG_SIGN_RST_PIN_EN 0xA563 + +/** + * Clock source + */ +typedef enum +{ + SYSCFG_ClkSrc_HSI = SYSCFG_SYSCLKCR_CLKSW_HSI << SYSCFG_SYSCLKCR_CLKSW_Pos, /*!< Internal High Speed Clock. */ + SYSCFG_ClkSrc_HSE = SYSCFG_SYSCLKCR_CLKSW_HSE << SYSCFG_SYSCLKCR_CLKSW_Pos, /*!< External High Speed Clock. */ + SYSCFG_ClkSrc_LSI = SYSCFG_SYSCLKCR_CLKSW_LSI << SYSCFG_SYSCLKCR_CLKSW_Pos, /*!< Internal Low Speed Clock. */ + SYSCFG_ClkSrc_FreqDiv = SYSCFG_SYSCLKCR_CLKSW_CLKDIV << SYSCFG_SYSCLKCR_CLKSW_Pos, /*!< Prescaler Clock. */ +} SYSCFG_ClkSrcTypeDef; + +typedef enum +{ + SYSCFG_SysClkDiv2 = (1ul << SYSCFG_SYSCLKCR_CLKDIV_Pos), + SYSCFG_SysClkDiv4 = (3ul << SYSCFG_SYSCLKCR_CLKDIV_Pos), + SYSCFG_SysClkDiv8 = (7ul << SYSCFG_SYSCLKCR_CLKDIV_Pos), +} SYSCFG_SysClkDivTypeDef; + +typedef enum +{ + SYSCFG_SysTickSrc_LSI = (SYSCFG_SYSCLKCR_SYSTICKCR_LSI << SYSCFG_SYSCLKCR_SYSTICKCR_Pos), + SYSCFG_SysTickSrc_HSI_Div2 = (SYSCFG_SYSCLKCR_SYSTICKCR_HSI_DIV2 << SYSCFG_SYSCLKCR_SYSTICKCR_Pos), + SYSCFG_SysTickSrc_HSI_Div4 = (SYSCFG_SYSCLKCR_SYSTICKCR_HSI_DIV4 << SYSCFG_SYSCLKCR_SYSTICKCR_Pos), + SYSCFG_SysTickSrc_HSI_Div8 = (SYSCFG_SYSCLKCR_SYSTICKCR_HSI_DIV8 << SYSCFG_SYSCLKCR_SYSTICKCR_Pos), +} SYSCFG_SysTickSrcTypeDef; + +typedef enum +{ +#define SYSCFG_FLAGS_TYPE_Msk 0x3F + SYSCFG_FLAG_PINRST = (uint8_t)((1 << 6U) | SYSCFG_SYSRSTSR_PADRST_Pos), /*!< PIN reset flag */ + SYSCFG_FLAG_PORRST = (uint8_t)((1 << 6U) | SYSCFG_SYSRSTSR_PORRST_Pos), /*!< POR/PDR reset flag */ + SYSCFG_FLAG_SFTRST = (uint8_t)((1 << 6U) | SYSCFG_SYSRSTSR_SWRST_Pos), /*!< Software Reset flag */ + SYSCFG_FLAG_WDGRST = (uint8_t)((1 << 6U) | SYSCFG_SYSRSTSR_WDGRST_Pos), /*!< Watchdog reset flag */ + SYSCFG_FLAG_LOCKUPRST = (uint8_t)((1 << 6U) | SYSCFG_SYSRSTSR_LOCKUPRST_Pos), /*!< LOCKUP reset flag */ + SYSCFG_FLAG_LVDRST = (uint8_t)((1 << 6U) | SYSCFG_SYSRSTSR_LVDRST_Pos), /*!< LVD reset flag */ + SYSCFG_FLAG_REBOOTRST = (uint8_t)((1 << 6U) | SYSCFG_SYSRSTSR_REBOOTRST_Pos), /*!< Re-boot latch reset flag */ + + SYSCFG_FLAG_ALL = (uint8_t)((1 << 6U) | SYSCFG_FLAGS_TYPE_Msk) /*!< Only for clearing flags */ +} SYSCFG_FlagTypeDef; +//============================================================================= +// Macro Definition +//============================================================================= + +/*** PCLK Module Enable ***/ + +/* UART0 */ +#define __HAL_SYSCFG_UART0_CLK_ENABLE() REG_SET_BITS(SYSCFG->PCLKEN, SYSCFG_PCLKEN_UART0_Msk) +#define __HAL_SYSCFG_UART0_CLK_DISABLE() REG_CLR_BITS(SYSCFG->PCLKEN, (SYSCFG_PCLKEN_UART0_Msk)) + +#define __HAL_SYSCFG_UART0_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->PCLKEN, SYSCFG_PCLKEN_UART0_Msk) + +/* TIM0 */ +#define __HAL_SYSCFG_TIM0_CLK_ENABLE() REG_SET_BITS(SYSCFG->PCLKEN, SYSCFG_PCLKEN_TIM0_Msk) +#define __HAL_SYSCFG_TIM0_CLK_DISABLE() REG_CLR_BITS(SYSCFG->PCLKEN, (SYSCFG_PCLKEN_TIM0_Msk)) + +#define __HAL_SYSCFG_TIM0_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->PCLKEN, SYSCFG_PCLKEN_TIM0_Msk) + +/* TIM1 */ +#define __HAL_SYSCFG_TIM1_CLK_ENABLE() REG_SET_BITS(SYSCFG->PCLKEN, SYSCFG_PCLKEN_TIM1_Msk) +#define __HAL_SYSCFG_TIM1_CLK_DISABLE() REG_CLR_BITS(SYSCFG->PCLKEN, (SYSCFG_PCLKEN_TIM1_Msk)) + +#define __HAL_SYSCFG_TIM1_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->PCLKEN, SYSCFG_PCLKEN_TIM1_Msk) + +/* LPTIM */ +#define __HAL_SYSCFG_LPTIM_CLK_ENABLE() REG_SET_BITS(SYSCFG->PCLKEN, SYSCFG_PCLKEN_LPTIM_Msk) +#define __HAL_SYSCFG_LPTIM_CLK_DISABLE() REG_CLR_BITS(SYSCFG->PCLKEN, (SYSCFG_PCLKEN_LPTIM_Msk)) + +#define __HAL_SYSCFG_LPTIM_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->PCLKEN, SYSCFG_PCLKEN_LPTIM_Msk) + +/* ADC */ +#define __HAL_SYSCFG_ADC_CLK_ENABLE() REG_SET_BITS(SYSCFG->PCLKEN, SYSCFG_PCLKEN_ADC_Msk) +#define __HAL_SYSCFG_ADC_CLK_DISABLE() REG_CLR_BITS(SYSCFG->PCLKEN, (SYSCFG_PCLKEN_ADC_Msk)) + +#define __HAL_SYSCFG_ADC_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->PCLKEN, SYSCFG_PCLKEN_ADC_Msk) + +/* EPWM */ +#define __HAL_SYSCFG_EPWM_CLK_ENABLE() REG_SET_BITS(SYSCFG->PCLKEN, SYSCFG_PCLKEN_EPWM_Msk) +#define __HAL_SYSCFG_EPWM_CLK_DISABLE() REG_CLR_BITS(SYSCFG->PCLKEN, (SYSCFG_PCLKEN_EPWM_Msk)) + +#define __HAL_SYSCFG_EPWM_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->PCLKEN, SYSCFG_PCLKEN_EPWM_Msk) + +/* DSP */ +#define __HAL_SYSCFG_DSP_CLK_ENABLE() REG_SET_BITS(SYSCFG->PCLKEN, SYSCFG_PCLKEN_DSP_Msk) +#define __HAL_SYSCFG_DSP_CLK_DISABLE() REG_CLR_BITS(SYSCFG->PCLKEN, (SYSCFG_PCLKEN_DSP_Msk)) + +#define __HAL_SYSCFG_DSP_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->PCLKEN, SYSCFG_PCLKEN_DSP_Msk) + +/* COMP0 */ +#define __HAL_SYSCFG_COMP0_CLK_ENABLE() REG_SET_BITS(SYSCFG->PCLKEN, SYSCFG_PCLKEN_COMP0_Msk) +#define __HAL_SYSCFG_COMP0_CLK_DISABLE() REG_CLR_BITS(SYSCFG->PCLKEN, (SYSCFG_PCLKEN_COMP0_Msk)) + +#define __HAL_SYSCFG_COMP0_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->PCLKEN, SYSCFG_PCLKEN_COMP0_Msk) + +/* SPI */ +#define __HAL_SYSCFG_SPI_CLK_ENABLE() REG_SET_BITS(SYSCFG->PCLKEN, SYSCFG_PCLKEN_SPI_Msk) +#define __HAL_SYSCFG_SPI_CLK_DISABLE() REG_CLR_BITS(SYSCFG->PCLKEN, (SYSCFG_PCLKEN_SPI_Msk)) + +#define __HAL_SYSCFG_SPI_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->PCLKEN, SYSCFG_PCLKEN_SPI_Msk) + +/* TIM2 */ +#define __HAL_SYSCFG_TIM2_CLK_ENABLE() REG_SET_BITS(SYSCFG->PCLKEN, SYSCFG_PCLKEN_TIM2_Msk) +#define __HAL_SYSCFG_TIM2_CLK_DISABLE() REG_CLR_BITS(SYSCFG->PCLKEN, (SYSCFG_PCLKEN_TIM2_Msk)) + +#define __HAL_SYSCFG_TIM2_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->PCLKEN, SYSCFG_PCLKEN_TIM2_Msk) + +/* I2C */ +#define __HAL_SYSCFG_I2C_CLK_ENABLE() REG_SET_BITS(SYSCFG->PCLKEN, SYSCFG_PCLKEN_I2C_Msk) +#define __HAL_SYSCFG_I2C_CLK_DISABLE() REG_CLR_BITS(SYSCFG->PCLKEN, (SYSCFG_PCLKEN_I2C_Msk)) + +#define __HAL_SYSCFG_I2C_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->PCLKEN, SYSCFG_PCLKEN_I2C_Msk) + +/* COMP1 */ +#define __HAL_SYSCFG_COMP1_CLK_ENABLE() REG_SET_BITS(SYSCFG->PCLKEN, SYSCFG_PCLKEN_COMP1_Msk) +#define __HAL_SYSCFG_COMP1_CLK_DISABLE() REG_CLR_BITS(SYSCFG->PCLKEN, (SYSCFG_PCLKEN_COMP1_Msk)) + +#define __HAL_SYSCFG_COMP1_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->PCLKEN, SYSCFG_PCLKEN_COMP1_Msk) + +/* WDG */ +#define __HAL_SYSCFG_WDG_CLK_ENABLE() REG_SET_BITS(SYSCFG->PCLKEN, SYSCFG_PCLKEN_WDG_Msk) +#define __HAL_SYSCFG_WDG_CLK_DISABLE() REG_CLR_BITS(SYSCFG->PCLKEN, (SYSCFG_PCLKEN_WDG_Msk)) + +#define __HAL_SYSCFG_WDG_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->PCLKEN, SYSCFG_PCLKEN_WDG_Msk) + +/* AMISC */ +#define __HAL_SYSCFG_AMISC_CLK_ENABLE() REG_SET_BITS(SYSCFG->PCLKEN, SYSCFG_PCLKEN_AMISC_Msk) +#define __HAL_SYSCFG_AMISC_CLK_DISABLE() REG_CLR_BITS(SYSCFG->PCLKEN, (SYSCFG_PCLKEN_AMISC_Msk)) + +#define __HAL_SYSCFG_AMISC_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->PCLKEN, SYSCFG_PCLKEN_AMISC_Msk) + + +/*** HCLK Module Enable ***/ + +/* GPIOA */ +#define __HAL_SYSCFG_GPIOA_CLK_ENABLE() REG_SET_BITS(SYSCFG->HCLKEN, SYSCFG_HCLKEN_GPIOA_Msk) +#define __HAL_SYSCFG_GPIOA_CLK_DISABLE() REG_CLR_BITS(SYSCFG->HCLKEN, (SYSCFG_HCLKEN_GPIOA_Msk)) + +#define __HAL_SYSCFG_GPIOA_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->HCLKEN, SYSCFG_HCLKEN_GPIOA_Msk) + +/* GPIOB */ +#define __HAL_SYSCFG_GPIOB_CLK_ENABLE() REG_SET_BITS(SYSCFG->HCLKEN, SYSCFG_HCLKEN_GPIOB_Msk) +#define __HAL_SYSCFG_GPIOB_CLK_DISABLE() REG_CLR_BITS(SYSCFG->HCLKEN, (SYSCFG_HCLKEN_GPIOB_Msk)) + +#define __HAL_SYSCFG_GPIOB_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->HCLKEN, SYSCFG_HCLKEN_GPIOB_Msk) + +/* CRC */ +#define __HAL_SYSCFG_CRC_CLK_ENABLE() REG_SET_BITS(SYSCFG->HCLKEN, SYSCFG_HCLKEN_CRC_Msk) +#define __HAL_SYSCFG_CRC_CLK_DISABLE() REG_CLR_BITS(SYSCFG->HCLKEN, (SYSCFG_HCLKEN_CRC_Msk)) + +#define __HAL_SYSCFG_CRC_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->HCLKEN, SYSCFG_HCLKEN_CRC_Msk) + + +/*** peripherals reset ***/ + +/* UART0 */ +#define __HAL_SYSCFG_UART0_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_UART0_Msk) +#define __HAL_SYSCFG_UART0_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_UART0_Msk) + +#define __HAL_SYSCFG_RESET_UART0() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_UART0_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_UART0_Msk); \ + }while(0) + + +/* TIM0 */ +#define __HAL_SYSCFG_TIM0_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_TIM0_Msk) +#define __HAL_SYSCFG_TIM0_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_TIM0_Msk) + +#define __HAL_SYSCFG_RESET_TIM0() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_TIM0_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_TIM0_Msk); \ + }while(0) + + +/* TIM1 */ +#define __HAL_SYSCFG_TIM1_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_TIM1_Msk) +#define __HAL_SYSCFG_TIM1_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_TIM1_Msk) + +#define __HAL_SYSCFG_RESET_TIM1() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_TIM1_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_TIM1_Msk); \ + }while(0) + + +/* LPTIM */ +#define __HAL_SYSCFG_LPTIM_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_LPTIM_Msk) +#define __HAL_SYSCFG_LPTIM_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_LPTIM_Msk) + +#define __HAL_SYSCFG_RESET_LPTIM() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_LPTIM_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_LPTIM_Msk); \ + }while(0) + + +/* ADC */ +#define __HAL_SYSCFG_ADC_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_ADC_Msk) +#define __HAL_SYSCFG_ADC_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_ADC_Msk) + +#define __HAL_SYSCFG_RESET_ADC() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_ADC_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_ADC_Msk); \ + }while(0) + + +/* EPWM */ +#define __HAL_SYSCFG_EPWM_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_EPWM_Msk) +#define __HAL_SYSCFG_EPWM_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_EPWM_Msk) + +#define __HAL_SYSCFG_RESET_EPWM() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_EPWM_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_EPWM_Msk); \ + }while(0) + + +/* DSP */ +#define __HAL_SYSCFG_DSP_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_DSP_Msk) +#define __HAL_SYSCFG_DSP_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_DSP_Msk) + +#define __HAL_SYSCFG_RESET_DSP() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_DSP_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_DSP_Msk); \ + }while(0) + + +/* COMP0 */ +#define __HAL_SYSCFG_COMP0_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_COMP0_Msk) +#define __HAL_SYSCFG_COMP0_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_COMP0_Msk) + +#define __HAL_SYSCFG_RESET_COMP0() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_COMP0_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_COMP0_Msk); \ + }while(0) + + +/* SPI */ +#define __HAL_SYSCFG_SPI_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_SPI_Msk) +#define __HAL_SYSCFG_SPI_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_SPI_Msk) + +#define __HAL_SYSCFG_RESET_SPI() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_SPI_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_SPI_Msk); \ + }while(0) + + +/* TIM2 */ +#define __HAL_SYSCFG_TIM2_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_TIM2_Msk) +#define __HAL_SYSCFG_TIM2_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_TIM2_Msk) + +#define __HAL_SYSCFG_RESET_TIM2() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_TIM2_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_TIM2_Msk); \ + }while(0) + + +/* I2C */ +#define __HAL_SYSCFG_I2C_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_I2C_Msk) +#define __HAL_SYSCFG_I2C_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_I2C_Msk) + +#define __HAL_SYSCFG_RESET_I2C() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_I2C_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_I2C_Msk); \ + }while(0) + + +/* COMP1 */ +#define __HAL_SYSCFG_COMP1_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_COMP1_Msk) +#define __HAL_SYSCFG_COMP1_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_COMP1_Msk) + +#define __HAL_SYSCFG_RESET_COMP1() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_COMP1_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_COMP1_Msk); \ + }while(0) + + +/* WDG */ +#define __HAL_SYSCFG_WDG_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_WDG_Msk) +#define __HAL_SYSCFG_WDG_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_WDG_Msk) + +#define __HAL_SYSCFG_RESET_WDG() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_WDG_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_WDG_Msk); \ + }while(0) + + +/* AMISC */ +#define __HAL_SYSCFG_AMISC_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_AMISC_Msk) +#define __HAL_SYSCFG_AMISC_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_AMISC_Msk) + +#define __HAL_SYSCFG_RESET_AMISC() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_AMISC_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_AMISC_Msk); \ + }while(0) + + + +/*** peripherals reset ***/ + +/* GPIOA */ +#define __HAL_SYSCFG_GPIOA_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN1, SYSCFG_PRSTEN1_GPIOA_Msk) +#define __HAL_SYSCFG_GPIOA_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN1, SYSCFG_PRSTEN1_GPIOA_Msk) + +#define __HAL_SYSCFG_RESET_GPIOA() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN1, SYSCFG_PRSTEN1_GPIOA_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN1, SYSCFG_PRSTEN1_GPIOA_Msk); \ + }while(0) + + +/* GPIOB */ +#define __HAL_SYSCFG_GPIOB_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN1, SYSCFG_PRSTEN1_GPIOB_Msk) +#define __HAL_SYSCFG_GPIOB_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN1, SYSCFG_PRSTEN1_GPIOB_Msk) + +#define __HAL_SYSCFG_RESET_GPIOB() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN1, SYSCFG_PRSTEN1_GPIOB_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN1, SYSCFG_PRSTEN1_GPIOB_Msk); \ + }while(0) + + +/* CRC */ +#define __HAL_SYSCFG_CRC_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN1, SYSCFG_PRSTEN1_CRC_Msk) +#define __HAL_SYSCFG_CRC_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN1, SYSCFG_PRSTEN1_CRC_Msk) + +#define __HAL_SYSCFG_RESET_CRC() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN1, SYSCFG_PRSTEN1_CRC_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN1, SYSCFG_PRSTEN1_CRC_Msk); \ + }while(0) + + + +/** + * \brief Get chip ID of DUT + * + * \return + * Chip ID + */ +__STATIC_FORCEINLINE uint32_t SYSCFG_GetChipID(void) +{ + return REG_READ(SYSCFG->CHIPID); +} + +/** + * \brief Configure Reset-Pin to normal I/O or not + * + * \param [in] is_enable Set Reset-Pin to normal I/O or not + * \return + * None + */ +__STATIC_FORCEINLINE void SYSCFG_SetRstPin2NormalIO(int is_enable) +{ + (is_enable) + ? REG_WRITE_MASK(SYSCFG->RSTPINCR, SYSCFG_RSTPINCR_RSTPINAF_Msk, SYSCFG_RSTPINCR_RSTPINAF_OFF << SYSCFG_RSTPINCR_RSTPINAF_Pos) + : REG_WRITE_MASK(SYSCFG->RSTPINCR, SYSCFG_RSTPINCR_RSTPINAF_Msk, SYSCFG_RSTPINCR_RSTPINAF_ON << SYSCFG_RSTPINCR_RSTPINAF_Pos); + return; +} + +/** + * \brief Enable low-power feature or not + * + * \param [in] is_enable 0: disable, others: enable + * \return + * None + */ +__STATIC_FORCEINLINE void SYSCFG_SetLowPower(int is_enable) +{ + (is_enable) + ? REG_SET_BITS(SYSCFG->PMUCR, SYSCFG_PMUCR_PMUEN_Msk) + : REG_CLR_BITS(SYSCFG->PMUCR, SYSCFG_PMUCR_PMUEN_Msk); + return; +} + +/** + * \brief Get the system clock source type + * + * \return + * The system clock source type, @ref SYSCFG_ClkSrcTypeDef + */ +__STATIC_FORCEINLINE SYSCFG_ClkSrcTypeDef SYSCFG_GetSysClkType(void) +{ + return REG_READ_MASK(SYSCFG->SYSCLKCR, SYSCFG_SYSCLKCR_CLKSW_Msk); +} + +/** + * \brief Set System-Tick source + * + * \param [in] ClkSrc the target clock source of System-Tick, @ref SYSCFG_SysTickSrcTypeDef + * \return + * None + */ +__STATIC_FORCEINLINE void SYSCFG_SetSysTickSrc(SYSCFG_SysTickSrcTypeDef ClkSrc) +{ + REG_WRITE_MASK(SYSCFG->SYSCLKCR, SYSCFG_SYSCLKCR_SYSTICKCR_Msk, ClkSrc); + return; +} + +/** + * \brief Get System-Tick source + * + * \return + * the current clock source of System-Tick, @ref SYSCFG_SysTickSrcTypeDef + */ +__STATIC_FORCEINLINE SYSCFG_SysTickSrcTypeDef SYSCFG_GetSysTickSrc(void) +{ + return REG_READ_MASK(SYSCFG->SYSCLKCR, SYSCFG_SYSCLKCR_SYSTICKCR_Msk); +} + +/** + * \brief Set LSI Always On + * + * \param [in] is_enable 0: disable, others: enable + * \return + * None + */ +__STATIC_FORCEINLINE void SYSCFG_SetLSIAlwaysOn(int is_enable) +{ + (is_enable) + ? REG_SET_BITS(SYSCFG->SYSCLKCR, SYSCFG_SYSCLKCR_LSIAON_Msk) + : REG_CLR_BITS(SYSCFG->SYSCLKCR, SYSCFG_SYSCLKCR_LSIAON_Msk); + return; +} +//============================================================================= +// Structure Definition +//============================================================================= +typedef struct +{ + SYSCFG_ClkSrcTypeDef ClkSource; /*!< The target clock source, @ref SYSCFG_ClkSrcTypeDef. + If ClkSource == SYSCFG_ClkSrc_FreqDiv, + SysClk_Div will be effective. */ + + SYSCFG_SysClkDivTypeDef SysClk_Div; /*!< SYSCLK clock prescaler, @ref SYSCFG_SysClkDivTypeDef (default: Div2). */ + + SYSCFG_SysTickSrcTypeDef SysTickSrc; /*!< Select the clock source of system-tick, @ref SYSCFG_SysTickSrcTypeDef (default: LSI) */ + +} SYSCFG_ClkInitTypeDef; +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +/** + * \brief Configure system clock + * + * \param [in] pInit Pointer to a SYSCFG_ClkInitTypeDef structure, @ref SYSCFG_ClkInitTypeDef + * \return + * None + */ +void SYSCFG_SysClkConfig(SYSCFG_ClkInitTypeDef *pInit); + +/** + * \brief Checks whether the specified SYSCFG flag is set or not. + * + * \param [in] flag Specifies the flag to check, @ref SYSCFG_FlagTypeDef + * \return + * 0 : Nothing + * others: Get the specific status + */ +int SYSCFG_GetFlagStatus(SYSCFG_FlagTypeDef flag); + +/** + * \brief Clear the SYSCFG flags. + * + * \param [in] flag Specifies the flag to check, @ref SYSCFG_FlagTypeDef + * \return + * None + */ +void SYSCFG_ClearFlags(SYSCFG_FlagTypeDef flag); + + +/** + * \brief Trigger DUT to reboot and letch system parameters + * ps. This API will block program and force to reboot DUT + * + * \return + * No return + */ +void SYSCFG_RebootLetch(void); + +/** + * \brief Configure Alternate Function mode of I/O Pins of ICE (jTag) + * + * \param [in] is_enable Enable ICE I/O pins or not + * \return + * None + */ +void SYSCFG_SetICEPin2NormalIO(int is_enable); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_tim.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_tim.h new file mode 100644 index 0000000..dd588d9 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_tim.h @@ -0,0 +1,564 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_timer.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + +#ifndef __hal_timer_H_wP2TyFFu_lfcA_HOTx_s6ox_udtPYlP5WVqK__ +#define __hal_timer_H_wP2TyFFu_lfcA_HOTx_s6ox_udtPYlP5WVqK__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_def.h" +//============================================================================= +// Constant Definition +//============================================================================= +/** + * @brief TIM Time Base Init structure definition + */ +typedef struct +{ + uint16_t TIM_Prescaler; /*!< Specifies the prescaler value used to divide the TIM clock. */ + uint32_t TIM_CounterMode; /*!< Specifies the counter mode. */ + uint32_t TIM_Period; /*!< Specifies the period value to be loaded into the active */ + uint32_t TIM_ClockDivision; /*!< Specifies the clock division. */ + uint8_t TIM_RepetitionCounter; /*!< Specifies the repetition counter value. Each time the RCR downcounter */ +} TIM_TimeBaseInitTypeDef; + +/** + * @brief TIM Output Compare Init structure definition + */ +typedef struct +{ + uint32_t TIM_OCMode; /*!< Specifies the TIM mode. */ + uint32_t TIM_OutputState; /*!< Specifies the TIM Output Compare state. */ + uint32_t TIM_OutputNState; /*!< Specifies the TIM complementary Output Compare state. */ + uint32_t TIM_Pulse; /*!< Specifies the pulse value to be loaded into the Capture Compare Register. */ + uint32_t TIM_OCPolarity; /*!< Specifies the output polarity. */ + uint32_t TIM_OCNPolarity; /*!< Specifies the complementary output polarity. */ + uint32_t TIM_OCIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. */ + uint32_t TIM_OCNIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. */ +} TIM_OCInitTypeDef; + +/** + * @brief TIM Input Capture Init structure definition + */ +typedef struct +{ + uint16_t TIM_Channel; /*!< Specifies the TIM channel. */ + uint16_t TIM_ICPolarity; /*!< Specifies the active edge of the input signal. */ + uint16_t TIM_ICSelection; /*!< Specifies the input. */ + uint16_t TIM_ICPrescaler; /*!< Specifies the Input Capture Prescaler. */ + uint16_t TIM_ICFilter; /*!< Specifies the input capture filter. */ +} TIM_ICInitTypeDef; + +/** + * @brief BDTR structure definition + */ +typedef struct +{ + uint16_t TIM_OSSRState; /*!< Specifies the Off-State selection used in Run mode. */ + uint16_t TIM_OSSIState; /*!< Specifies the Off-State used in Idle state. */ + uint16_t TIM_LOCKLevel; /*!< Specifies the LOCK level parameters. */ + uint16_t TIM_DeadTime; /*!< Specifies the delay time between the switching-off and */ + uint16_t TIM_Break; /*!< Specifies whether the TIM Break input is enabled or not. */ + uint16_t TIM_BreakPolarity; /*!< Specifies the TIM Break Input pin polarity. */ + uint16_t TIM_AutomaticOutput; /*!< Specifies whether the TIM Automatic Output feature is enabled or not. */ + uint16_t TIM_DTGFTime; /*!< Specifies the delay time between the switching-off and */ + uint32_t TIM_DTAEState; /*!< Specifies the delay time between the switching-off and */ +} TIM_BDTRInitTypeDef; +/** + * @} + */ + +/** @defgroup TIM_Exported_Constants + * @{ + */ + +/** + * @brief TIM_Clock_Division_CKD + */ +#define TIM_CKD_Div1 (0x00U << TIM_CR1_CKD_Pos) /*!< TDTS = Tck_tim */ +#define TIM_CKD_Div2 (0x01U << TIM_CR1_CKD_Pos) /*!< TDTS = 2 * Tck_tim */ +#define TIM_CKD_Div4 (0x02U << TIM_CR1_CKD_Pos) /*!< TDTS = 4 * Tck_tim */ + +/** + * @brief TIM_Counter_Mode + */ +#define TIM_CounterMode_Up (0x00U << TIM_CR1_DIR_Pos) /*!< TIM Up Counting Mode */ +#define TIM_CounterMode_Down (0x01U << TIM_CR1_DIR_Pos) /*!< TIM Down Counting Mode */ +#define TIM_CounterMode_CenterAligned1 (0x01U << TIM_CR1_CMS_Pos) /*!< TIM Center Aligned Mode1 */ +#define TIM_CounterMode_CenterAligned2 (0x02U << TIM_CR1_CMS_Pos) /*!< TIM Center Aligned Mode2 */ +#define TIM_CounterMode_CenterAligned3 (0x03U << TIM_CR1_CMS_Pos) /*!< TIM Center Aligned Mode3 */ + +/** + * @brief TIM_Prescaler_Reload_Mode + */ +#define TIM_PSCReloadMode_Update (0x00U << TIM_EGR_UG_Pos) /*!< The Prescaler is loaded at the update event */ +#define TIM_PSCReloadMode_Immediate (0x01U << TIM_EGR_UG_Pos) /*!< The Prescaler is loaded immediately */ + +/** + * @brief TIM_Output_Compare_and_PWM_modes_and_Forced_Action + */ +#define TIM_OCMode_Timing 0x00U /*!< Output compare mode: Timing */ +#define TIM_OCMode_Active 0x01U /*!< Output compare mode: Active */ +#define TIM_OCMode_Inactive 0x02U /*!< Output compare mode: Inactive */ +#define TIM_OCMode_Toggle 0x03U /*!< Output compare mode: Toggle */ +#define TIM_ForcedAction_Inactive 0x04U /*!< Force inactive level on OCnREF */ +#define TIM_ForcedAction_Active 0x05U /*!< Force active level on OCnREF */ +#define TIM_OCMode_PWM1 0x06U /*!< Output compare mode: PWM1 */ +#define TIM_OCMode_PWM2 0x07U /*!< Output compare mode: PWM2 */ + +/** + * @brief TIM_Output_Compare_Polarity + */ +#define TIM_OCPolarity_High 0x00U /*!< Output Compare active high */ +#define TIM_OCPolarity_Low 0x01U /*!< Output Compare active low */ + +/** + * @brief TIM_Output_Compare_N_Polarity + */ +#define TIM_OCNPolarity_High 0x00U /*!< Output Compare active high */ +#define TIM_OCNPolarity_Low 0x01U /*!< Output Compare active low */ + +/** + * @brief TIM_Output_Compare_state + */ +#define TIM_OutputState_Disable 0x00U /*!< Output Compare Disable */ +#define TIM_OutputState_Enable 0x01U /*!< Output Compare Enable */ + +/** + * @brief TIM_Output_Compare_N_state + */ +#define TIM_OutputNState_Disable 0x00U /*!< Output Compare N Disable */ +#define TIM_OutputNState_Enable 0x01U /*!< Output Compare N Enable */ + +/** + * @brief TIM_Output_Compare_Idle_State + */ +#define TIM_OCIdleState_Reset 0x00U /*!< OCn=0 (after a dead-time if OCnN is implemented) when MOE=0.(n= 0 : 4) */ +#define TIM_OCIdleState_Set 0x01U /*!< OCn=1 (after a dead-time if OCnN is implemented) when MOE=0.(n= 0 : 4) */ + +/** + * @brief TIM_Output_Compare_N_Idle_State + */ +#define TIM_OCNIdleState_Reset 0x00U /*!< OCnN=0 after a dead-time when MOE=0.(n= 0 : 4) */ +#define TIM_OCNIdleState_Set 0x01U /*!< OCnN=1 after a dead-time when MOE=0.(n= 0 : 4) */ + +/** + * @brief TIM_Channel + */ +#define TIM_Channel_1 0x0000 /*!< TIM Channel 1 */ +#define TIM_Channel_2 0x0004 /*!< TIM Channel 2 */ +#define TIM_Channel_3 0x0008 /*!< TIM Channel 3 */ +#define TIM_Channel_4 0x000C /*!< TIM Channel 4 */ + + +/** + * @brief TIM_Input_Capture_Polarity + */ +#define TIM_ICPolarity_Rising (0x00 << TIM_CCER_CC1P_Pos) /*!< IC Rising edge */ +#define TIM_ICPolarity_Falling (0x01 << TIM_CCER_CC1P_Pos) /*!< IC Falling edge */ +//#define TIM_ICPolarity_BothEdge ((0x01 << TIM_CCER_CC1P_Pos) | (0x01 << TIM_CCER_CC1NP_Pos)) + +/** + * @brief TIM_Input_Capture_Selection + */ +#define TIM_ICSelection_DirectTI 0x01U +#define TIM_ICSelection_IndirectTI 0x02U +#define TIM_ICSelection_TRC 0x03U + +/** + * @brief TIM_Input_Capture_Prescaler + */ +#define TIM_ICPSC_Div1 0x0000 /*!< no prescaler */ +#define TIM_ICPSC_Div2 0x0004 /*!< capture is done once every 2 events */ +#define TIM_ICPSC_Div4 0x0008 /*!< capture is done once every 4 events */ +#define TIM_ICPSC_Div8 0x000C /*!< capture is done once every 8 events */ + +/** + * @brief OSSR_Off_State_Selection_for_Run_mode_state + */ +#define TIM_OSSRState_Disable (0x00U << TIM_BDTR_OSSR_Pos) +#define TIM_OSSRState_Enable (0x01U << TIM_BDTR_OSSR_Pos) + +/** + * @brief OSSI_Off_State_Selection_for_Idle_mode_state + */ +#define TIM_OSSIState_Disable (0x00U << TIM_BDTR_OSSI_Pos) +#define TIM_OSSIState_Enable (0x01U << TIM_BDTR_OSSI_Pos) + +/** + * @brief Lock_level + */ +#define TIM_LockLevel_OFF (0x00U << TIM_BDTR_LOCK_Pos)//svd should LOOK -> LOCK +#define TIM_LockLevel_1 (0x01U << TIM_BDTR_LOCK_Pos) +#define TIM_LockLevel_2 (0x02U << TIM_BDTR_LOCK_Pos) +#define TIM_LockLevel_3 (0x03U << TIM_BDTR_LOCK_Pos) + +/** + * @brief Break_Input_enable_disable + */ +#define TIM_Break_Disable (0x00U << TIM_BDTR_BKE_Pos) /*!< Break inputs (BRK and CSS clock failure event) disabled */ +#define TIM_Break_Enable (0x01U << TIM_BDTR_BKE_Pos) /*!< Break inputs (BRK and CSS clock failure event) enabled */ + +/** + * @brief Break_Polarity + */ +#define TIM_BreakPolarity_Low (0x00U << TIM_BDTR_BKP_Pos) /*!< Break input BRK is active low */ +#define TIM_BreakPolarity_High (0x01U << TIM_BDTR_BKP_Pos) /*!< Break input BRK is active high */ + +/** + * @brief TIM_AOE_Bit_Set_Reset + */ +#define TIM_AutomaticOutput_Disable (0x00U << TIM_BDTR_AOE_Pos) /*!< MOE can be set only by software. */ +#define TIM_AutomaticOutput_Enable (0x01U << TIM_BDTR_AOE_Pos) /*!< MOE can be set by software or automatically at the next + update event (if the break input is not be active). */ +/** + * @brief TIM_DOE_Bit_Set_Reset + */ +#define TIM_DirectOutput_Disable (0x00U << TIM_BDTR_DOE_Pos) /*!< Direct output disable, output waiting for dead time */ +#define TIM_DirectOutput_Enable (0x01U << TIM_BDTR_DOE_Pos) /*!< Direct output enable, no longer waiting for output after dead time */ + +/** + * @brief DATE_State_Selection_for_Idle_mode_state + */ +#define TIM_DTAEState_Disable (0x00U << TIM_BDTR_DTAE_Pos) +#define TIM_DTAEState_Enable (0x01U << TIM_BDTR_DTAE_Pos) +/** + * @brief TIM_interrupt_sources + */ +#define TIM_IT_Update (0x01U << TIM_DIER_UIE_Pos) /*!< TIM update Interrupt source */ +#define TIM_IT_CC1 (0x01U << TIM_DIER_CC1IE_Pos) /*!< TIM Capture Compare 1 Interrupt source */ +#define TIM_IT_CC2 (0x01U << TIM_DIER_CC2IE_Pos) /*!< TIM Capture Compare 2 Interrupt source */ +#define TIM_IT_CC3 (0x01U << TIM_DIER_CC3IE_Pos) /*!< TIM Capture Compare 3 Interrupt source */ +#define TIM_IT_CC4 (0x01U << TIM_DIER_CC4IE_Pos) /*!< TIM Capture Compare 4 Interrupt source */ +#define TIM_IT_COM (0x01U << TIM_DIER_COMIE_Pos) /*!< TIM Commutation Interrupt source */ +#define TIM_IT_Trigger (0x01U << TIM_DIER_TIE_Pos) /*!< TIM Trigger Interrupt source */ +#define TIM_IT_Break (0x01U << TIM_DIER_BIE_Pos) /*!< TIM Break Interrupt source */ +#define TIM_IT_CCD1 (0x01U << TIM_DIER_CCD1IE_Pos) /*!< TIM Capture Compare 1 Interrupt source */ +#define TIM_IT_CCD2 (0x01U << TIM_DIER_CCD2IE_Pos) /*!< TIM Capture Compare 2 Interrupt source */ +#define TIM_IT_CCD3 (0x01U << TIM_DIER_CCD3IE_Pos) /*!< TIM Capture Compare 3 Interrupt source */ +#define TIM_IT_OV (0x01U << TIM_DIER_OVIE_Pos) /*!< TIM Trigger Interrupt source */ +#define TIM_IT_UD (0x01U << TIM_DIER_UDIE_Pos) /*!< TIM Break Interrupt source */ +#define TIM_IT_CCD4 (0x01U << TIM_DIER_CCD4IE_Pos) /*!< TIM Capture Compare 4 Interrupt source */ + + +/** + * @brief TIM_Event_Source + */ +#define TIM_EventSource_Update (0x01U << TIM_EGR_UG_Pos) /*!< Timer update Event source */ +#define TIM_EventSource_CC1 (0x01U << TIM_EGR_CC1G_Pos) /*!< Timer Capture Compare 1 Event source */ +#define TIM_EventSource_CC2 (0x01U << TIM_EGR_CC2G_Pos) /*!< Timer Capture Compare 2 Event source */ +#define TIM_EventSource_CC3 (0x01U << TIM_EGR_CC3G_Pos) /*!< Timer Capture Compare 3 Event source */ +#define TIM_EventSource_CC4 (0x01U << TIM_EGR_CC4G_Pos) /*!< Timer Capture Compare 4 Event source */ +#define TIM_EventSource_COM (0x01U << TIM_EGR_COMG_Pos) /*!< Timer COM event source */ +#define TIM_EventSource_Trigger (0x01U << TIM_EGR_TG_Pos) /*!< Timer Trigger Event source */ +#define TIM_EventSource_Break (0x01U << TIM_EGR_BG_Pos) /*!< Timer Break event source */ + + +/** + * @brief TIM_Internal_Trigger_Selection + */ +#define TIM_TS_ITR0 (0x00U << TIM_SMCR_TS_Pos) /*!< Internal Trigger 0 */ +#define TIM_TS_ITR1 (0x01U << TIM_SMCR_TS_Pos) /*!< Internal Trigger 1 */ +#define TIM_TS_ITR2 (0x02U << TIM_SMCR_TS_Pos) /*!< Internal Trigger 2 */ +#define TIM_TS_ITR3 (0x03U << TIM_SMCR_TS_Pos) /*!< Internal Trigger 3 */ +#define TIM_TS_TI1F_ED (0x04U << TIM_SMCR_TS_Pos) /*!< TI1 Edge Detector */ +#define TIM_TS_TI1FP1 (0x05U << TIM_SMCR_TS_Pos) /*!< Filtered Timer Input 1 */ +#define TIM_TS_TI2FP2 (0x06U << TIM_SMCR_TS_Pos) /*!< Filtered Timer Input 2 */ +#define TIM_TS_ETRF (0x07U << TIM_SMCR_TS_Pos) /*!< TI1 Edge Detector */ + +/** + * @brief TIM_Encoder_Mode + */ +#define TIM_EncoderMode_TI1 (0x01U << TIM_SMCR_SMS_Pos) /*!< Counter counts on TI1FP1 edge depending on TI2FP2 level. */ +#define TIM_EncoderMode_TI2 (0x02U << TIM_SMCR_SMS_Pos) /*!< Counter counts on TI2FP2 edge depending on TI1FP1 level. */ +#define TIM_EncoderMode_TI12 (0x03U << TIM_SMCR_SMS_Pos) /*!< Counter counts on both TI1FP1 and TI2FP2 edges depending on the level of the other input. */ + +#define TIM_CCMR1_CC1S_OC (0x00U << TIM_CCMR1_OUTPUT_CC1S_Pos) +#define TIM_CCMR1_CC1S_DirectTI (0x01U << TIM_CCMR1_OUTPUT_CC1S_Pos) +#define TIM_CCMR1_CC1S_IndirectTI (0x02U << TIM_CCMR1_OUTPUT_CC1S_Pos) +#define TIM_CCMR1_CC1S_TRC (0x03U << TIM_CCMR1_OUTPUT_CC1S_Pos) + +#define TIM_CCMR1_CC2S_OC (0x00U << TIM_CCMR1_OUTPUT_CC2S_Pos) +#define TIM_CCMR1_CC2S_DirectTI (0x01U << TIM_CCMR1_OUTPUT_CC2S_Pos) +#define TIM_CCMR1_CC2S_IndirectTI (0x02U << TIM_CCMR1_OUTPUT_CC2S_Pos) +#define TIM_CCMR1_CC2S_TRC (0x03U << TIM_CCMR1_OUTPUT_CC2S_Pos) + +/** + * @brief TIM_Output_Compare_Preload_State + */ +#define TIM_OCPreload_Disable (0x00U << TIM_CCMR1_OUTPUT_OC1PE_Pos) /*!< TIM output compare preload disable */ +#define TIM_OCPreload_Enable (0x01U << TIM_CCMR1_OUTPUT_OC1PE_Pos) /*!< TIM output compare preload enable */ + +/** + * @brief TIM_Output_Compare_Clear_State + */ +#define TIM_OCClear_Disable (0x00U << TIM_CCMR1_OUTPUT_OC1CE_Pos) /*!< TIM Output clear disable */ +#define TIM_OCClear_Enable (0x01U << TIM_CCMR1_OUTPUT_OC1CE_Pos) /*!< TIM Output clear enable */ + +/** + * @brief TIM_Output_Compare_Fast_State + */ +#define TIM_OCFast_Disable (0x00U << TIM_CCMR1_OUTPUT_OC1FE_Pos) /*!< TIM output compare fast disable */ +#define TIM_OCFast_Enable (0x01U << TIM_CCMR1_OUTPUT_OC1FE_Pos) /*!< TIM output compare fast enable */ + +/** + * @brief TIM_Capture_Compare_state + */ +#define TIM_CCx_Disable (0x00U << TIM_CCER_CC1E_Pos) /*!< Capture/Compare Enable */ +#define TIM_CCx_Enable (0x01U << TIM_CCER_CC1E_Pos) /*!< Capture/Compare Enable */ + +/** + * @brief TIM_Capture_Compare_N_state + */ +#define TIM_CCxN_Disable (0x00U << TIM_CCER_CC1NE_Pos) /*!< Capture/Compare N Enable */ +#define TIM_CCxN_Enable (0x01U << TIM_CCER_CC1NE_Pos) /*!< Capture/Compare N Enable */ + +/** + * @brief TIM_Update_Source + */ +#define TIM_UpdateSource_Global (0x00U << TIM_CR1_URS_Pos) /*!< Source of update is counter overflow/underflow. */ +#define TIM_UpdateSource_Regular (0x01U << TIM_CR1_URS_Pos) /*!< Source of update is the counter overflow/underflow + or the setting of UG bit, or an update generation + through the slave mode controller. */ + +/** + * @brief TIM_One_Pulse_Mode + */ +#define TIM_OPMode_Repetitive (0x00U << TIM_CR1_OPM_Pos) /*!< Counter is not stopped at update event */ +#define TIM_OPMode_Single (0x01U << TIM_CR1_OPM_Pos) /*!< Counter stops counting at the next update event (clearing the bit CEN) */ + +/** + * @brief TIM_Trigger_Output_Source + */ +#define TIM_TRIGSource_Reset (0x00U << TIM_CR2_MMS_Pos) /*!< The UG bit in the TIM_EGR register is used as the trigger output (TRIG). */ +#define TIM_TRIGSource_Enable (0x01U << TIM_CR2_MMS_Pos) /*!< The Counter Enable CEN is used as the trigger output (TRIG). */ +#define TIM_TRIGSource_Update (0x02U << TIM_CR2_MMS_Pos) /*!< The update event is used as the trigger output (TRIG). */ +#define TIM_TRIGSource_OC1 (0x03U << TIM_CR2_MMS_Pos) /*!< The trigger output sends a positive pulse when the CC1IF flag */ +#define TIM_TRIGSource_OC1REF (0x04U << TIM_CR2_MMS_Pos) /*!< OC1REF signal is used as the trigger output (TRIG). */ +#define TIM_TRIGSource_OC2REF (0x05U << TIM_CR2_MMS_Pos) /*!< OC2REF signal is used as the trigger output (TRIG). */ +#define TIM_TRIGSource_OC3REF (0x06U << TIM_CR2_MMS_Pos) /*!< OC3REF signal is used as the trigger output (TRIG). */ +#define TIM_TRIGSource_OC4REF (0x07U << TIM_CR2_MMS_Pos) /*!< OC4REF signal is used as the trigger output (TRIG). */ + +/** + * @brief TIM_Slave_Mode + */ +#define TIM_SlaveMode_Reset (0x04U << TIM_SMCR_SMS_Pos) /*!< Rising edge of the selected trigger signal (TRGI) re-initializes */ +#define TIM_SlaveMode_Gated (0x05U << TIM_SMCR_SMS_Pos) /*!< The counter clock is enabled when the trigger signal (TRGI) is high. */ +#define TIM_SlaveMode_Trigger (0x06U << TIM_SMCR_SMS_Pos) /*!< The counter starts at a rising edge of the trigger TRGI. */ +#define TIM_SlaveMode_External1 (0x07U << TIM_SMCR_SMS_Pos) /*!< Rising edges of the selected trigger (TRGI) clock the counter. */ + +/** + * @brief TIM_Master_Slave_Mode + */ +#define TIM_MasterSlaveMode_Disable (0x00U << TIM_SMCR_MSM_Pos) /*!< No action */ +#define TIM_MasterSlaveMode_Enable (0x01U << TIM_SMCR_MSM_Pos) /*!< synchronization between the current timer and its slaves (through TRIG) */ + +/** + * @brief TIM_Flags + */ +#define TIM_FLAG_Update (0x01U << TIM_SR_UIF_Pos) /*!< TIM update Flag */ +#define TIM_FLAG_CC1 (0x01U << TIM_SR_CC1IF_Pos) /*!< TIM Capture Compare 1 Flag */ +#define TIM_FLAG_CC2 (0x01U << TIM_SR_CC2IF_Pos) /*!< TIM Capture Compare 2 Flag */ +#define TIM_FLAG_CC3 (0x01U << TIM_SR_CC3IF_Pos) /*!< TIM Capture Compare 3 Flag */ +#define TIM_FLAG_CC4 (0x01U << TIM_SR_CC4IF_Pos) /*!< TIM Capture Compare 4 Flag */ +#define TIM_FLAG_COM (0x01U << TIM_SR_COMIF_Pos) /*!< TIM Commutation Flag */ +#define TIM_FLAG_Trigger (0x01U << TIM_SR_TIF_Pos) /*!< TIM Trigger Flag */ +#define TIM_FLAG_Break (0x01U << TIM_SR_BIF_Pos) /*!< TIM Break Flag */ +#define TIM_FLAG_CC1OF (0x01U << TIM_SR_CC1OF_Pos) /*!< TIM Capture Compare 1 overcapture Flag */ +#define TIM_FLAG_CC2OF (0x01U << TIM_SR_CC2OF_Pos) /*!< TIM Capture Compare 2 overcapture Flag */ +#define TIM_FLAG_CC3OF (0x01U << TIM_SR_CC3OF_Pos) /*!< TIM Capture Compare 3 overcapture Flag */ +#define TIM_FLAG_CC4OF (0x01U << TIM_SR_CC4OF_Pos) /*!< TIM Capture Compare 4 overcapture Flag */ + +/** + * @brief PWM phase shift and DMA repeat update + */ +#define TIM_PDER_CCR1SHIFTEN (0x01U << TIM_PDER_CCR1_SHIFT_EN_Pos) /*!< TIM Channel 1 output PWM phase shift enable bit */ +#define TIM_PDER_CCR2SHIFTEN (0x01U << TIM_PDER_CCR2_SHIFT_EN_Pos) /*!< TIM Channel 2 output PWM phase shift enable bit */ +#define TIM_PDER_CCR3SHIFTEN (0x01U << TIM_PDER_CCR3_SHIFT_EN_Pos) /*!< TIM Channel 3 output PWM phase shift enable bit */ +#define TIM_PDER_CCR4SHIFTEN (0x01U << TIM_PDER_CCR4_SHIFT_EN_Pos) /*!< TIM Channel 4 output PWM phase shift enable bit */ +#define TIM_PDER_CCR5SHIFTEN (0x01U << TIM_PDER_CCR5_SHIFT_EN_Pos) /*!< TIM Channel 5 output PWM phase shift enable bit */ + +/** @defgroup TIM_TIx_External_Clock_Source + * @{ + */ +#define TIM_TIxExternalCLK1Source_TI1 ((uint16_t)0x0050) +#define TIM_TIxExternalCLK1Source_TI2 ((uint16_t)0x0060) +#define TIM_TIxExternalCLK1Source_TI1ED ((uint16_t)0x0040) + +/** @defgroup TIM_External_Trigger_Prescaler + * @{ + */ + +#define TIM_ExtTRGPSC_OFF (0x00U << TIM_SMCR_ETPS_Pos) +#define TIM_ExtTRGPSC_DIV2 (0x01U << TIM_SMCR_ETPS_Pos) +#define TIM_ExtTRGPSC_DIV4 (0x02U << TIM_SMCR_ETPS_Pos) +#define TIM_ExtTRGPSC_DIV8 (0x03U << TIM_SMCR_ETPS_Pos) + +/** @defgroup TIM_External_Trigger_Polarity + * @{ + */ +#define TIM_ExtTRGPolarity_Inverted (0x01U << TIM_SMCR_ETP_Pos) +#define TIM_ExtTRGPolarity_NonInverted (0x00U << TIM_SMCR_ETP_Pos) + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +void TIM_DeInit(TIM_Type *tim); + +void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef *init_struct); +void TIM_TimeBaseInit(TIM_Type *tim, TIM_TimeBaseInitTypeDef *init_struct); + +void TIM_OCStructInit(TIM_OCInitTypeDef *init_struct); +void TIM_OC1Init(TIM_Type *tim, TIM_OCInitTypeDef *init_struct); +void TIM_OC2Init(TIM_Type *tim, TIM_OCInitTypeDef *init_struct); +void TIM_OC3Init(TIM_Type *tim, TIM_OCInitTypeDef *init_struct); +void TIM_OC4Init(TIM_Type *tim, TIM_OCInitTypeDef *init_struct); + +void TIM_SetIC1Prescaler(TIM_Type *tim, uint32_t psc); +void TIM_SetIC2Prescaler(TIM_Type *tim, uint32_t psc); +void TIM_SetIC3Prescaler(TIM_Type *tim, uint32_t psc); +void TIM_SetIC4Prescaler(TIM_Type *tim, uint32_t psc); +void TIM_ICStructInit(TIM_ICInitTypeDef *init_struct); +void TIM_ICInit(TIM_Type *tim, TIM_ICInitTypeDef *init_struct); +void TIM_PWMIConfig(TIM_Type *tim, TIM_ICInitTypeDef *init_struct); +void TIM_BDTRStructInit(TIM_BDTRInitTypeDef *init_struct); +void TIM_BDTRConfig(TIM_Type *tim, TIM_BDTRInitTypeDef *init_struct); +void TIM_CtrlPWMOutputs(TIM_Type *tim, FunctionalState state); + +void TIM_Cmd(TIM_Type *tim, FunctionalState state); + +void TIM_ITConfig(TIM_Type *tim, uint32_t it, FunctionalState state); +void TIM_GenerateEvent(TIM_Type *tim, uint32_t source); + +void TIM_InternalClockConfig(TIM_Type *tim); +void TIM_ITRxExternalClockConfig(TIM_Type *tim, uint32_t source); + +void TIM_SelectInputTrigger(TIM_Type *tim, uint16_t source); + +void TIM_PrescalerConfig(TIM_Type *tim, uint16_t prescaler, uint16_t reloadMode); +void TIM_CounterModeConfig(TIM_Type *tim, uint32_t counter_mode); + +void TIM_EncoderInterfaceConfig(TIM_Type *tim, uint32_t encoder_mode, uint32_t ic1_polarity, uint32_t ic2_polarity); +void TIM_ForcedOC1Config(TIM_Type *tim, uint32_t forced_action); +void TIM_ForcedOC2Config(TIM_Type *tim, uint32_t forced_action); +void TIM_ForcedOC3Config(TIM_Type *tim, uint32_t forced_action); +void TIM_ForcedOC4Config(TIM_Type *tim, uint32_t forced_action); + +void TIM_ClearOC1Ref(TIM_Type *tim, uint16_t TIM_OCClear); +void TIM_ClearOC2Ref(TIM_Type *tim, uint16_t TIM_OCClear); +void TIM_ClearOC3Ref(TIM_Type *tim, uint16_t TIM_OCClear); +void TIM_ClearOC4Ref(TIM_Type *tim, uint16_t TIM_OCClear); + +void TIM_ARRPreloadConfig(TIM_Type *tim, FunctionalState state); +void TIM_SelectCOM(TIM_Type *tim, FunctionalState state); +void TIM_SelectCCDMA(TIM_Type *tim, FunctionalState state); +void TIM_CCPreloadControl(TIM_Type *tim, FunctionalState state); + +void TIM_OC1PreloadConfig(TIM_Type *tim, uint32_t preload); +void TIM_OC2PreloadConfig(TIM_Type *tim, uint32_t preload); +void TIM_OC3PreloadConfig(TIM_Type *tim, uint32_t preload); +void TIM_OC4PreloadConfig(TIM_Type *tim, uint32_t preload); + +void TIM_OC1FastConfig(TIM_Type *tim, uint32_t fast); +void TIM_OC2FastConfig(TIM_Type *tim, uint32_t fast); +void TIM_OC3FastConfig(TIM_Type *tim, uint32_t fast); +void TIM_OC4FastConfig(TIM_Type *tim, uint32_t fast); + +void TIM_OC1PolarityConfig(TIM_Type *tim, uint32_t polarity); +void TIM_OC1NPolarityConfig(TIM_Type *tim, uint32_t polarity); +void TIM_OC2PolarityConfig(TIM_Type *tim, uint32_t polarity); +void TIM_OC2NPolarityConfig(TIM_Type *tim, uint32_t polarity); +void TIM_OC3PolarityConfig(TIM_Type *tim, uint32_t polarity); +void TIM_OC3NPolarityConfig(TIM_Type *tim, uint32_t polarity); +void TIM_OC4PolarityConfig(TIM_Type *tim, uint32_t polarity); +void TIM_OC4NPolarityConfig(TIM_Type *tim, uint32_t polarity); + +void TIM_CCxCmd(TIM_Type *tim, uint16_t channel, uint32_t ccx_en); +void TIM_CCxNCmd(TIM_Type *tim, uint16_t channel, uint32_t ccxn_en); + +void TIM_SelectOCxM(TIM_Type *tim, uint16_t channel, uint32_t mode); +void TIM_SetCompare1(TIM_Type *tim, uint32_t compare); +void TIM_SetCompare2(TIM_Type *tim, uint32_t compare); +void TIM_SetCompare3(TIM_Type *tim, uint32_t compare); +void TIM_SetCompare4(TIM_Type *tim, uint32_t compare); + +void TIM_ASYMEN_Cmd(TIM_Type *tim, FunctionalState state); +void TIM_SetDownCompare1(TIM_Type *tim, uint32_t compare); +void TIM_SetDownCompare2(TIM_Type *tim, uint32_t compare); +void TIM_SetDownCompare3(TIM_Type *tim, uint32_t compare); +void TIM_SetDownCompare4(TIM_Type *tim, uint32_t compare); + +void TIM_UpdateDisableConfig(TIM_Type *tim, FunctionalState state); +void TIM_UpdateRequestConfig(TIM_Type *tim, uint32_t source); +void TIM_SelectHallSensor(TIM_Type *tim, FunctionalState state); +void TIM_SelectOnePulseMode(TIM_Type *tim, uint32_t mode); +void TIM_SelectOutputTrigger(TIM_Type *tim, uint32_t source); + +void TIM_SelectSlaveMode(TIM_Type *tim, uint32_t mode); +void TIM_SelectMasterSlaveMode(TIM_Type *tim, uint32_t mode); + +void TIM_SetAutoreload(TIM_Type *tim, uint16_t auto_reload); +void TIM_SetCounter(TIM_Type *tim, uint32_t counter); + +void TIM_SetClockDivision(TIM_Type *tim, uint32_t clock_div); + +uint32_t TIM_GetCapture1(TIM_Type *tim); +uint32_t TIM_GetCapture2(TIM_Type *tim); +uint32_t TIM_GetCapture3(TIM_Type *tim); +uint32_t TIM_GetCapture4(TIM_Type *tim); + +uint32_t TIM_GetCounter(TIM_Type *tim); +uint16_t TIM_GetPrescaler(TIM_Type *tim); + +FlagStatus TIM_GetFlagStatus(TIM_Type *tim, uint32_t flag); +void TIM_ClearFlag(TIM_Type *tim, uint32_t flag); +ITStatus TIM_GetITStatus(TIM_Type *tim, uint32_t it); +void TIM_ClearITPendingBit(TIM_Type *tim, uint32_t it); + +void TIM_PWMShiftConfig(TIM_Type *tim, uint32_t it, FunctionalState state); +void TIM_SetCCR1FALL(TIM_Type *tim, uint32_t shift); +void TIM_SetCCR2FALL(TIM_Type *tim, uint32_t shift); +void TIM_SetCCR3FALL(TIM_Type *tim, uint32_t shift); +void TIM_SetCCR4FALL(TIM_Type *tim, uint32_t shift); + +FlagStatus TIM_GetCountDirection(TIM_Type *tim); +uint32_t TIM_GetTIMxClock(TIM_Type *tim); + +void TIM_ETRClockMode1Config(TIM_Type *tim, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter); +void TIM_ETRClockMode2Config(TIM_Type* TIMx, uint16_t TIM_ExtTRGPrescaler,uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter); +void TIM_TIxExternalClockConfig(TIM_Type *TIMx, uint16_t TIM_TIxExternalCLKSource, uint16_t TIM_ICPolarity, uint16_t ICFilter); +void TIM_ETRConfig(TIM_Type *tim, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,uint16_t ExtTRGFilter); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_uart.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_uart.h new file mode 100644 index 0000000..d3ef924 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_uart.h @@ -0,0 +1,286 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_uart.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/10 + * @license + * @description + */ + +#ifndef __hal_uart_H_wrM7moXg_lQUd_HTJv_sOBv_uu2tvbtzutNR__ +#define __hal_uart_H_wrM7moXg_lQUd_HTJv_sOBv_uu2tvbtzutNR__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_def.h" +//============================================================================= +// Constant Definition +//============================================================================= +typedef enum +{ + UART_ERR_OK = 0, + UART_ERR_NULL_POINTER, + +} UART_ErrTypeDef; + +/** + * UART Word Length + */ +typedef enum +{ + UART_WordLength_8b = (UART_CR_MODE_8D << UART_CR_MODE_Pos), + UART_WordLength_8b1P = (UART_CR_MODE_8D1P << UART_CR_MODE_Pos), + UART_WordLength_9b = (UART_CR_MODE_9D << UART_CR_MODE_Pos), + +} UART_WordLengthTypeDef; + + +/** + * UART Stop Bits + */ +typedef enum +{ + UART_StopBits_1 = (UART_CR_STOPB_1B << UART_CR_STOPB_Pos), + UART_StopBits_2 = (UART_CR_STOPB_2B << UART_CR_STOPB_Pos), +} UART_StopBitsTypeDef; + + +/** + * UART Parity + */ +typedef enum +{ + UART_Parity_No = (UART_CR_PAR_EVEN << UART_CR_PAR_Pos), + UART_Parity_Even = (UART_CR_PAR_EVEN << UART_CR_PAR_Pos), + UART_Parity_Odd = (UART_CR_PAR_ODD << UART_CR_PAR_Pos), +} UART_ParityTypeDef; + + +/** + * UART Mode + */ +typedef enum +{ + UART_Mode_Tx = 0, + UART_Mode_TxRx = UART_CR_RXEN_Msk, + +} UART_ModeTypeDef; + +typedef enum +{ + /* tx type */ + UART_IT_TX_FIFO_EMPTY = UART_IE_TXEE_Msk, + UART_IT_TX_FIFO_FULL = UART_IE_TXFE_Msk, + UART_IT_TX_FIFO_HEMPTY = UART_IE_TXHEE_Msk, // Half-Empty + UART_IT_TX_DONE = UART_IE_TXENDE_Msk, + + /* rx type */ + UART_IT_RX_FIFO_NO_EMPTY = UART_IE_RXNEE_Msk, + UART_IT_RX_FIFO_FULL = UART_IE_RXFE_Msk, + UART_IT_RX_FIFO_HFULL = UART_IE_RXHFE_Msk, // Half-Full + + /* error type */ + #if 1 + UART_IT_ERR = (UART_IE_PERRE_Msk | UART_IE_FERRE_Msk | UART_IE_OVERRE_Msk | \ + UART_IE_TONEE_Msk | UART_IE_TOIDLEE_Msk) + #else + UART_IT_ERR_PARITY = UART_IE_PERRE_Msk, + UART_IT_ERR_FRAME = UART_IE_FERRE_Msk, + UART_IT_ERR_OVERFLOW = UART_IE_OVERRE_Msk, + UART_IT_ERR_CLR_FIFO_TIMEOUT = UART_IE_TONEE_Msk, + UART_IT_ERR_IDLE_TIMEOUT = UART_IE_TOIDLEE_Msk, + #endif + +} UART_ITTypeDef; + + +/** + * UART_Flags + */ +typedef enum +{ + UART_FLAG_RXNE = UART_SR_RXNE_Msk, /*!< Read data register not empty */ + UART_FLAG_TXE = UART_SR_TXE_Msk, /*!< Transmit data register Empty */ + UART_FLAG_TXHE = UART_SR_TXHE_Msk, /*!< Transmit data register half Empty */ + UART_FLAG_PERR = UART_SR_PERR_Msk, /*!< Parity error */ + UART_FLAG_FERR = UART_SR_FERR_Msk, /*!< Framing error */ + UART_FLAG_OVERR = UART_SR_OVERR_Msk, /*!< Overrun error */ + UART_FLAG_TONE = UART_SR_TONE_Msk, /*!< TONE Interrupt enable */ + UART_FLAG_TOIDLE = UART_SR_TOIDLE_Msk, /*!< TOIDLE interrupt enable */ + UART_FLAG_RXHF = UART_SR_RXHF_Msk, /*!< Read data register half empty */ + UART_FLAG_RXF = UART_SR_RXF_Msk, /*!< Read data register empty */ + UART_FLAG_TXEND = UART_SR_TXEND_Msk, /*!< TXEND interrupt enable */ + UART_FLAG_TXF = UART_SR_TXF_Msk, /*!< TXF interrupt enable */ +} UART_FlagTypeDef; + +//============================================================================= +// Macro Definition +//============================================================================= +/** + * \brief Uart reset/clear reception FIFO + * + * \param [in] pHUart Pointer to a UART handle + * \return + * None + */ +__STATIC_FORCEINLINE void UART_ResetRxFIFO(UART_Type *pHUart) +{ + REG_WRITE(pHUart->RXFR, 0xe930); + return; +} + +/** + * \brief Uart reset/clear transmission FIFO + * + * \param [in] pHUart Pointer to a UART handle + * \return + * None + */ +__STATIC_FORCEINLINE void UART_ResetTxFIFO(UART_Type *pHUart) +{ + REG_WRITE(pHUart->TXFR, 0xe930); + return; +} + +/** + * \brief Start UART module + * + * \param [in] pHUart Pointer to a UART handle + * \return + * None + */ +__STATIC_FORCEINLINE void UART_Start(UART_Type *pHUart) +{ + REG_SET_BITS(pHUart->CR, UART_CR_RUN_Msk); + return; +} + +/** + * \brief Stop UART module + * + * \param [in] pHUart Pointer to a UART handle + * \return + * + */ +__STATIC_FORCEINLINE void UART_Stop(UART_Type *pHUart) +{ + REG_CLR_BITS(pHUart->CR, UART_CR_RUN_Msk); + return; +} + +/** + * \brief Wait UART module Tx FIFO empty + * + * \param [in] pHUart Pointer to a UART handle + * \return + * None + */ +__STATIC_FORCEINLINE void UART_WaitTxFifoEmpty(UART_Type *pHUart) +{ + while( !REG_READ_MASK(pHUart->SR, UART_SR_TXE_Msk) ); + + return; +} + +/** + * \brief Get the interrupt status + * + * \param [in] pHUart Pointer to a UART handle + * \param [in] flags The target interrupt types, @ref UART_ITTypeDef + * \return + * status, @ref UART_ITTypeDef + */ +__STATIC_FORCEINLINE uint32_t UART_GetITStatus(UART_Type *pHUart, uint32_t flags) +{ + return REG_READ_MASK(pHUart->SR, flags); +} + +/** + * \brief Get the status of UART + * + * \param [in] pHUart Pointer to a UART handle + * \param [in] flags The specifies flags to check, @ref UART_FlagTypeDef + * \return + * The new state of flags (SET or RESET) + */ +__STATIC_FORCEINLINE FlagStatus UART_GetFlagStatus(UART_Type *pHUart, UART_FlagTypeDef flags) +{ + return (pHUart->SR & flags) ? SET : RESET; +} +//============================================================================= +// Structure Definition +//============================================================================= +typedef struct +{ + uint32_t BaudRate; + UART_WordLengthTypeDef WordLength; + UART_StopBitsTypeDef StopBits; + UART_ParityTypeDef Parity; + UART_ModeTypeDef Mode; + +} UART_InitTypeDef; +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +/** + * \brief Initialize UART module + * + * \param [in] pHUart Pointer to a UART handle + * \param [in] pInit Pointer to a init structure, @ref UART_InitTypeDef + * \return + * Error number, @ref UART_ErrTypeDef + */ +UART_ErrTypeDef UART_Init(UART_Type *pHUart, UART_InitTypeDef *pInit); + +/** + * \brief Send data througn UART module + * + * \param [in] pHUart Pointer to a UART handle + * \param [in] value the sent data + * \return + * None + */ +void UART_SendData(UART_Type *pHUart, uint16_t value); + +/** + * \brief Receive data through UART module + * + * \param [in] pHUart Pointer to a UART handle + * \return + * received data + */ +uint16_t UART_ReceiveData(UART_Type *pHUart); + +/** + * \brief Configure the interrupts of UART module + * + * \param [in] pHUart Pointer to a UART handle + * \param [in] flags The target interrupt types, @ref UART_ITTypeDef + * \param [in] is_enable enable or disable interrupts (0: disable, others: enable) + * \return + * Error number, @ref UART_ErrTypeDef + */ +UART_ErrTypeDef UART_ITConfig(UART_Type *pHUart, uint32_t flags, uint32_t is_enable); + + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_wdg.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_wdg.h new file mode 100644 index 0000000..99e4ae9 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_wdg.h @@ -0,0 +1,249 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_wdg.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + +#ifndef __hal_wdg_H_wI4mp2FJ_l3m6_H3ua_sohm_ufSbFzwpuIAH__ +#define __hal_wdg_H_wI4mp2FJ_l3m6_H3ua_sohm_ufSbFzwpuIAH__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_def.h" +//============================================================================= +// Constant Definition +//============================================================================= +/** + * The reset mode of the WatchDog + */ +typedef enum WDG_Reset +{ + WDG_Reset_Disable = 0x0ul, + WDG_Reset_Enable = WDG_CR_RSTE_Msk, /*!< WatchDog trigger system reset if timeout */ +} WDG_ResetTypeDef; +//============================================================================= +// Macro Definition +//============================================================================= +/** + * \brief Lock/Unlonk the WatchDog accessing + * + * \return + * None + */ +__STATIC_FORCEINLINE void WDG_Lock(void) +{ + REG_WRITE(WDG->LOCK, 0x930ul); + return; +} + +__STATIC_FORCEINLINE void WDG_Unlock(void) +{ + REG_WRITE(WDG->LOCK, 0x1ACCE551ul); + return; +} + +/** + * \brief Enable/Disable the WatchDog + * + * \return + * None + */ +__STATIC_FORCEINLINE void WDG_Enable(void) +{ + WDG_Unlock(); + REG_SET_BITS(WDG->CR, WDG_CR_INTE_Msk); + WDG_Lock(); + return; +} + +__STATIC_FORCEINLINE void WDG_Disable(void) +{ + WDG_Unlock(); + REG_CLR_BITS(WDG->CR, WDG_CR_INTE_Msk); + WDG_Lock(); + return; +} + +/** + * \brief Set the counter value of the WatchDog + * + * \param [in] Counter the specific counter value (32-bits) of the WDG + * \return + * None + */ +__STATIC_FORCEINLINE void WDG_SetCounter(uint32_t Counter) +{ + REG_WRITE(WDG->LOAD, Counter); + REG_WRITE(WDG->INTCLR, 0x1ul); + return; +} + +/** + * \brief Get the counter value of the WatchDog + * + * \return + * the counter value of the WatchDog + */ +__STATIC_FORCEINLINE uint32_t WDG_GetCounter(void) +{ + return REG_READ(WDG->VALUE); +} + +/** + * \brief Enable interrupt function of the WatchDog + * + * \return + * None + */ +__STATIC_FORCEINLINE void WDG_ITEnable(void) +{ + sys_open_IRQ(WDG_IRQn); + sys_enable_girq(); + return; +} + +/** + * \brief Disable interrupt function of the WatchDog + * + * \return + * None + */ +__STATIC_FORCEINLINE void WDG_ITDisable(void) +{ + sys_close_IRQ(WDG_IRQn); + return; +} + +/** + * \brief Get the timeout status of the WatchDog + * + * \return + * 0: No timeout + * other: timeout happened + */ +__STATIC_FORCEINLINE uint32_t WDG_GetStatusFlag(void) +{ + return REG_READ_MASK(WDG->RIS, WDG_RIS_RIF_Msk); +} + +/** + * \brief Clear the flag of interrupt of the WatchDog + * + * \return + * None + */ +__STATIC_FORCEINLINE void WDG_ClearITFlag(void) +{ + if( !REG_READ_MASK(WDG->CR, WDG_CR_RSTE_Msk) ) + { + WDG_Unlock(); + REG_WRITE(WDG->INTCLR, 0x1ul); + WDG_Lock(); + } + return; +} + +/** + * \brief Extend timeout of the WatchDog + * + * \return + * None + */ +__STATIC_FORCEINLINE void WDG_Kick(void) +{ + WDG_Unlock(); + REG_WRITE(WDG->INTCLR, 0x1ul); + WDG_Lock(); + return; +} + +/** + * \brief Enable/Disable debug mode of the WatchDog + * ps. WatchDog stop to conunt when enable debug mode + * + * \param [in] is_debug_mode enable debug mode or not + * \return + * None + */ +__STATIC_FORCEINLINE void WDG_DebugMode(int is_debug_mode) +{ + (is_debug_mode) + ? REG_SET_BITS(WDG->CR, WDG_CR_DBGE_Msk) + : REG_CLR_BITS(WDG->CR, WDG_CR_DBGE_Msk); + return; +} + +/** + * \brief Convert the mille-seconds to counter value + * + * \param [in] msec Mille-second (max: 134217727) + * \return + * the counter value + */ +__STATIC_INLINE uint32_t WDG_MSec2Counter(uint32_t msec) +{ + return (((uint32_t)msec * 32ul) - 1ul); +} +//============================================================================= +// Structure Definition +//============================================================================= +typedef struct WDG_Init +{ + uint32_t Counter; /*!< Specifies the WatchDog counter value */ + WDG_ResetTypeDef ResetMode; /*!< Reset system or not when timeout, @ref WDG_ResetTypeDef */ +} WDG_InitTypeDef; + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +/** + * \brief Fills each WDG_InitTypeDef member with its default value. + * + * \param [in] pInit Pointer to a WatchDog initial structure, @ref WDG_InitTypeDef + * \return + * None + */ +void WDG_StructInit(WDG_InitTypeDef *pInit); + +/** + * \brief Initialize the WatchDog + * ps. Register-ISR MUST be after WDG_Init() + * + * \param [in] pInit Pointer to a WatchDog initial structure, @ref WDG_InitTypeDef + * \return + * None + */ +void WDG_Init(WDG_InitTypeDef *pInit); + +/** + * \brief De-initialize the WatchDog + * + * \return + * None + */ +void WDG_DeInit(void); + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_adc.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_adc.c new file mode 100644 index 0000000..9f7e668 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_adc.c @@ -0,0 +1,302 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_adc.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/10 + * @license + * @description + */ + + +#include "hal_device.h" + +#if defined(CONFIG_ENABLE_HAL_ADC) +//============================================================================= +// Constant Definition +//============================================================================= +#define ADC_TIMEOUT_CNT (60*1000*10) + +#define ADC_ALL_CHANNELS_Msk (0xFFFF) + +#define ADC_MAX_WORK_CLK (16*1000*1000) +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +void ADC_DeInit(ADC_Type *pHADC) +{ + __HAL_SYSCFG_RESET_ADC(); + __HAL_SYSCFG_ADC_CLK_DISABLE(); + + return; +} + +void ADC_Init(ADC_Type *pHADC, ADC_InitTypeDef *pInit) +{ + /* Enable ADC Controller */ + __HAL_SYSCFG_ADC_CLK_ENABLE(); + __HAL_SYSCFG_RESET_ADC(); + + if( pInit->ClkPrescaler == ADC_ClkDiv_Auto ) + { + /** + * The max working clock of ADC is 16-MHz (min 800KHz). + * Auto-Calculate the fastest ADC working clock at the current system clock + */ + uint32_t divider = 0; + + divider = (g_SystemCoreClock + (ADC_MAX_WORK_CLK - 1)) / ADC_MAX_WORK_CLK; + pInit->ClkPrescaler = (divider <= 2) ? ADC_ClkDiv_2 : + (divider <= 4) ? ADC_ClkDiv_4 : + ADC_ClkDiv_8; + } + + /** + * + When change ADC working clock, it should wait 20-cycles + * + Enable Analog Physical Module + * Clear_Bits(ADC_CON0_PWD_Msk | ADC_CON0_RST_Msk) + * + Enable ADC (ADC_START MUST wait 32-cycles after enable) + */ + REG_WRITE_MASK(pHADC->CON0, + ADC_CON0_CLK_Msk | ADC_CON0_PWD_Msk | ADC_CON0_RST_Msk | ADC_CON0_EN_Msk, + pInit->ClkPrescaler | ADC_CON0_EN_Msk); + sys_busy_wait(100); + + REG_CLR_BITS(pHADC->CHSEL, ADC_CHSEL_DISCEN_Msk); + REG_CLR_BITS(pHADC->STAT, ADC_STAT_EOC_CHECK_DIS_Msk); + + if( pInit->Mode == ADC_Mode_SingleConv ) + { + /** + * CONTINUE | ENCONT | DISCEN + * 0 | 0 | 0 + */ + uint32_t channel_id = (31ul - HAL_CLZ(pInit->SelChannels)); + + REG_WRITE_MASK(pHADC->CON0, + ADC_CON0_M_Msk | \ + (ADC_CON0_CONTINUE_Msk | ADC_CON0_ENCONT_Msk) | \ + ADC_CON0_ALIGN_Msk, + (channel_id << ADC_CON0_M_Pos) | + 0x0ul | 0x0ul | + pInit->DataAlign); + } + else + { + int chnnl_cnt = 0; + uint32_t target_chnnls = (uint32_t)pInit->SelChannels; + + while( target_chnnls ) + { + int index = 31ul - HAL_CLZ(target_chnnls); + + target_chnnls &= ~(0x1ul << index); + chnnl_cnt++; + } + + switch( pInit->Mode ) + { + default: + return; + break; + + case ADC_Mode_Continuous: + /** + * Never Stop Conversion and + * NOT support interrupt (Done-Flag will always be 0) + * + * CONTINUE | ENCONT | DISCEN + * 1 | 1 | 0 + */ + REG_WRITE_MASK(pHADC->CON0, + (ADC_CON0_CONTINUE_Msk | ADC_CON0_ENCONT_Msk) | \ + ADC_CON0_ALIGN_Msk, + ADC_CON0_CONTINUE_Msk | ADC_CON0_ENCONT_Msk | + pInit->DataAlign); + + REG_SET_BITS(pHADC->STAT, ADC_STAT_EOC_CHECK_DIS_Msk); + REG_WRITE_MASK(pHADC->CHSEL, ADC_CHSEL_CH_SEL_Msk, pInit->SelChannels); + break; + + case ADC_Mode_Scan: + /** + * CONTINUE | ENCONT | DISCEN + * 1 | 0 | 0 + */ + REG_WRITE_MASK(pHADC->CON0, + (ADC_CON0_CONTINUE_Msk | ADC_CON0_ENCONT_Msk) | \ + ADC_CON0_ALIGN_Msk, + ADC_CON0_CONTINUE_Msk | 0x0ul | + pInit->DataAlign); + + REG_WRITE_MASK(pHADC->CHSEL, + ADC_CHSEL_CH_SEL_Msk | ADC_CHSEL_DISCEN_Msk | ADC_CHSEL_CH_CNT_Msk, + pInit->SelChannels | 0x0ul | (chnnl_cnt - 1) << ADC_CHSEL_CH_CNT_Pos); + break; + + case ADC_Mode_Discontinuous: + /** + * CONTINUE | ENCONT | DISCEN + * 1 | 0 | 1 + */ + REG_WRITE_MASK(pHADC->CON0, + (ADC_CON0_CONTINUE_Msk | ADC_CON0_ENCONT_Msk) | \ + ADC_CON0_ALIGN_Msk, + ADC_CON0_CONTINUE_Msk | 0x0ul | + pInit->DataAlign); + + REG_WRITE_MASK(pHADC->CHSEL, + ADC_CHSEL_CH_SEL_Msk | ADC_CHSEL_DISCEN_Msk | \ + ADC_CHSEL_CH_CNT_Msk | ADC_CHSEL_DISCNUM_Msk, + pInit->SelChannels | ADC_CHSEL_DISCEN_Msk | + (chnnl_cnt - 1) << ADC_CHSEL_CH_CNT_Pos); + break; + } + } + + + (pInit->IsSoftTrig == true) ? + REG_CLR_BITS(pHADC->CON0, ADC_CON0_TRIG_EN_Msk) : + REG_SET_BITS(pHADC->CON0, ADC_CON0_TRIG_EN_Msk); + + return; +} + +void ADC_StructInit(ADC_InitTypeDef *pInit) +{ + pInit->SelChannels = ADC_Channel_AVSS; + pInit->ClkPrescaler = ADC_ClkDiv_Auto; + pInit->DataAlign = ADC_DataAlign_Right; + pInit->Mode = ADC_Mode_SingleConv; + pInit->IsSoftTrig = true; + return; +} + + +void ADC_ExtTrigConfig(ADC_Type *pHADC, ADC_ExtTrigSourceTypeDef ext_src, ADC_ExtTrigModeTypeDef trig_mode) +{ + if( ext_src == ADC_ExtTrigSource_Soft ) + { + REG_CLR_BITS(pHADC->CON0, ADC_CON0_TRIG_EN_Msk); + } + else + { + int shift = (ext_src & 0xF) << 1; + + REG_SET_BITS(pHADC->CON0, ADC_CON0_TRIG_EN_Msk); + + if( ext_src & 0x10 ) + { + uint32_t pin_sel = 0; + + /* TRIG_SEL17 rising/falling configuraion */ + pin_sel = (((ext_src & 0x20ul) >> 4) | ((trig_mode >> 1) & 0x1ul)) << ADC_CHSEL_EXTRIG_SEL_Pos; + + REG_WRITE_MASK(pHADC->CHSEL, + (0x3ul << shift) | ADC_CHSEL_EXTRIG_SEL_Msk, + ((trig_mode & 0x1ul) << shift) | pin_sel); + } + else + { + REG_WRITE_MASK(pHADC->TRGSEL, ADC_TRGSEL_TRIG_SEL0_Msk << shift, (trig_mode & 0x1ul) << shift); + } + } + return; +} + +/** + * \brief Select the sub-channel of the ADC Channel-15 + * + * \param [in] subchannel The selected sub-channel of ADC channel-15, @ref ADC_SubChannelTypeDef + * \return + * None + */ +void ADC_SelSubChannel(ADC_SubChannelTypeDef subchannel) +{ + AMISC_InternalSrcTypeDef src_type = AMISC_InternalSrc_NONE; + + src_type = (subchannel == ADC_SubChannel_TEMP) ? AMISC_InternalSrc_TEMP : + (subchannel == ADC_SubChannel_DAC0) ? AMISC_InternalSrc_DAC0 : + (subchannel == ADC_SubChannel_DAC1) ? AMISC_InternalSrc_DAC1 : + (subchannel == ADC_SubChannel_VBuf_1_5) ? AMISC_InternalSrc_VBuf_1P5V : + (subchannel == ADC_SubChannel_VDDL) ? AMISC_InternalSrc_VDDL : + (subchannel == ADC_SubChannel_VSS) ? AMISC_InternalSrc_VSS : + (subchannel == ADC_SubChannel_VDD) ? AMISC_InternalSrc_VDD : + AMISC_InternalSrc_NONE; + + AMISC_OutInternalSignalToIO(src_type, false); + + REG_SET_BITS(AMISC->ADC_AIN_CR, AMISC_ADC_AIN_CR_ANA2ADC_EN_Msk); + return; +} + +uint16_t ADC_GetChannelConvValue(ADC_Type *pHADC, ADC_ChannelsTypeDef channel) +{ + volatile uint32_t *pData = (volatile uint32_t*)&pHADC->DAT0; + int timeout = 0; + uint32_t chnnl_id = (31ul - HAL_CLZ(channel)); + + while( REG_READ_MASK(pHADC->CON0, ADC_CON0_ENCONT_Msk) == 0 && + REG_READ_MASK(pHADC->STAT, ADC_STAT_DONE_Msk) == 0 ) + { + if( timeout++ > ADC_TIMEOUT_CNT ) + return 0; + } + + pData += (chnnl_id & 0xFul); + return (uint16_t)((*pData) & 0xFFFFul); +} + +void ADC_ChannelThresholdConfig(ADC_Type *pHADC, ADC_ChannelsTypeDef channel, uint16_t threshold) +{ + volatile uint32_t *pReg = (volatile uint32_t*)&pHADC->DAT0; + uint32_t chnnl_id = (31ul - HAL_CLZ(channel)); + + pReg += (chnnl_id & 0xFul); + + REG_WRITE_MASK(*pReg, ADC_DAT0_CMPTH_Msk, (threshold << ADC_DAT0_CMPTH_Pos)); + return; +} + +void ADC_ITConfig(ADC_Type *pHADC, ADC_ITTypeDef it_types) +{ + REG_CLR_BITS(pHADC->CHSEL, ADC_CHSEL_DISC_INTSEL_Msk); + + if( it_types == ADC_IT_DISABLE ) + { + sys_close_IRQ(ADC0_IRQn); + REG_CLR_BITS(pHADC->CON0, ADC_CON0_INT_EN_Msk); + } + else + { + if( it_types == ADC_IT_CONV_GROUP_SUBSET ) + REG_SET_BITS(pHADC->CHSEL, ADC_CHSEL_DISC_INTSEL_Msk); + + REG_WRITE_MASK(pHADC->CON0, ADC_CON0_INT_EN_Msk, it_types); + sys_open_IRQ(ADC0_IRQn); + } + + return; +} + + + +#endif /* CONFIG_ENABLE_HAL_ADC */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_amisc.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_amisc.c new file mode 100644 index 0000000..048aab0 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_amisc.c @@ -0,0 +1,201 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_amisc.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/10 + * @license + * @description + */ + + +#include "hal_device.h" + +#if defined(CONFIG_ENABLE_HAL_AMISC) +//============================================================================= +// Constant Definition +//============================================================================= +#define AMISC_LVD_LVR_ENABLE_FLAGS (AMISC_LVD_LVR_CR_LVD_EN_Msk | AMISC_LVD_LVR_CR_LVR_EN_Msk | \ + AMISC_LVD_LVR_CR_LDO_LP_EN_Msk | AMISC_LVD_LVR_CR_TEMP_EN_Msk) +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +AMISC_StatusTypeDef AMISC_Init(void) +{ + /* AMISC clock enable */ + __HAL_SYSCFG_AMISC_CLK_ENABLE(); + AMISC_SetHSIPwrSrc(AMISC_HSIPwrSrc_LowPower); + return AMISC_Status_OK; +} + +AMISC_StatusTypeDef AMISC_DeInit(uint32_t is_force) +{ + if( is_force || + (REG_READ_MASK(AMISC->DAC_CR, AMISC_DAC_CR_DAC0_EN_Msk | AMISC_DAC_CR_DAC1_EN_Msk) == 0 && + REG_READ_MASK(AMISC->LVD_LVR_CR, AMISC_LVD_LVR_ENABLE_FLAGS) == 0 && + REG_READ_MASK(OPAMP0->PGA_CR, OPAMP_PGA_CR_PGA_EN_Msk) == 0 && + REG_READ_MASK(OPAMP1->PGA_CR, OPAMP_PGA_CR_PGA_EN_Msk) == 0) ) + { + /* AMISC clock disable */ + __HAL_SYSCFG_AMISC_CLK_DISABLE(); + return AMISC_Status_OK; + } + return AMISC_Status_Bypass; +} + +AMISC_StatusTypeDef AMISC_Reset(void) +{ + if( REG_READ_MASK(AMISC->DAC_CR, AMISC_DAC_CR_DAC0_EN_Msk | AMISC_DAC_CR_DAC1_EN_Msk) == 0 && + REG_READ_MASK(AMISC->LVD_LVR_CR, AMISC_LVD_LVR_ENABLE_FLAGS) == 0 && + REG_READ_MASK(OPAMP0->PGA_CR, OPAMP_PGA_CR_PGA_EN_Msk) == 0 && + REG_READ_MASK(OPAMP1->PGA_CR, OPAMP_PGA_CR_PGA_EN_Msk) == 0 ) + { + /* AMISC reset */ + __HAL_SYSCFG_RESET_AMISC(); + AMISC_SetHSIPwrSrc(AMISC_HSIPwrSrc_LowPower); + return AMISC_Status_OK; + } + + return AMISC_Status_Error; +} + +AMISC_StatusTypeDef AMISC_LVD_LVR_Config(AMISC_LVDRInitTypeDef *pInit) +{ + REG_WRITE_MASK(AMISC->LVD_LVR_CR, + AMISC_LVD_LVR_CR_LVD_SEL_Msk | AMISC_LVD_LVR_CR_LVR_SEL_Msk | \ + AMISC_LVD_LVR_CR_LDO_LP_EN_Msk | AMISC_LVD_LVR_CR_TEMP_EN_Msk, + pInit->LVD_Voltage | pInit->LVR_Voltage | pInit->LVD_FuncModes); + + return AMISC_Status_OK; +} + +void AMISC_HSI_Disable(void) +{ + if( SYSCFG_GetSysClkType() == SYSCFG_ClkSrc_LSI ) + { + REG_WRITE(AMISC->HSI_CR, 0x80000000); + } + return; +} + +void AMISC_HSI_Enable(void) +{ + REG_WRITE(AMISC->HSI_CR, 0x01000000); + return; +} + +void AMISC_LSI_Disable(void) +{ + if( SYSCFG_GetSysClkType() != SYSCFG_ClkSrc_LSI ) + { + REG_WRITE(AMISC->LSI_CR, 0x80000000); + } + return; +} + +void AMISC_LSI_Enable(void) +{ + REG_WRITE(AMISC->LSI_CR, 0x01000000); + return; +} + +void AMISC_Sel_PGA_VinP_Src(AMISC_InternalSrcTypeDef src_type) +{ + AMISC_InternalSrcTypeDef VinP_Src = AMISC_InternalSrc_NONE; + + /* AMISC clock enable */ + __HAL_SYSCFG_AMISC_CLK_ENABLE(); + + VinP_Src = (src_type == AMISC_InternalSrc_NONE) + ? src_type : (AMISC_VBUF_CR_ANA2PGA_EN_Msk | src_type); + + switch( src_type ) + { + default: + break; + + case AMISC_InternalSrc_NONE: + break; + + case AMISC_InternalSrc_TEMP: + REG_SET_BITS(AMISC->LVD_LVR_CR, AMISC_LVD_LVR_CR_TEMP_EN_Msk); + break; + + case AMISC_InternalSrc_DAC0: + AMISC_DAC0_Enable(); + break; + case AMISC_InternalSrc_DAC1: + AMISC_DAC1_Enable(); + break; + case AMISC_InternalSrc_VBuf_1P5V: + REG_SET_BITS(AMISC->VBUF_CR, AMISC_VBUF_CR_VBUF_EN_Msk); + break; + } + + REG_WRITE_MASK(AMISC->VBUF_CR, + AMISC_VBUF_CR_ANA_SEL_Msk | AMISC_VBUF_CR_ANA2PGA_EN_Msk, + VinP_Src); + + sys_busy_wait(60*1000); + return; +} + +void AMISC_OutInternalSignalToIO(AMISC_InternalSrcTypeDef src_type, int has_output) +{ + uint32_t value = (has_output) + ? (src_type | AMISC_VBUF_CR_ANA2IO_EN_Msk) : src_type; + + /* AMISC clock enable */ + __HAL_SYSCFG_AMISC_CLK_ENABLE(); + + switch( src_type ) + { + default: + break; + + case AMISC_InternalSrc_NONE: + break; + + case AMISC_InternalSrc_TEMP: + REG_SET_BITS(AMISC->LVD_LVR_CR, AMISC_LVD_LVR_CR_TEMP_EN_Msk); + break; + + case AMISC_InternalSrc_DAC0: + AMISC_DAC0_Enable(); + break; + case AMISC_InternalSrc_DAC1: + AMISC_DAC1_Enable(); + break; + case AMISC_InternalSrc_VBuf_1P5V: + REG_SET_BITS(value, AMISC_VBUF_CR_VBUF_EN_Msk); + break; + } + + REG_WRITE_MASK(AMISC->VBUF_CR, + AMISC_VBUF_CR_ANA_SEL_Msk | AMISC_VBUF_CR_ANA2IO_EN_Msk | AMISC_VBUF_CR_VBUF_EN_Msk, + value); + + sys_busy_wait(60*1000); + return; +} + + +#endif /* CONFIG_ENABLE_HAL_AMISC */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_comp.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_comp.c new file mode 100644 index 0000000..47ff3f6 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_comp.c @@ -0,0 +1,94 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_vcmp.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + + +#include "hal_device.h" + +#if defined(CONFIG_ENABLE_HAL_COMP) + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +void COMP_StructInit(COMP_InitTypeDef *pInit) +{ + pInit->InputPlus = COMP_VinP_IO3; + pInit->InputMinus = 0x0; + pInit->InputHysteresis = COMP_Hysteresis_Disable; + pInit->FilterFreq = COMP_Filter_Bypass; + pInit->OutputPolarity = COMP_OutPolarity_Normal; + pInit->OutputSel = COMP_Vout_None; + pInit->InitDelay = 0x3C; + return; +} + +void COMP_Init(COMP_Type *pHComp, COMP_InitTypeDef *pInit) +{ + if( pHComp == COMP0 ) + { + __HAL_SYSCFG_RESET_COMP0(); + __HAL_SYSCFG_COMP0_CLK_ENABLE(); + } + else if( pHComp == COMP1 ) + { + __HAL_SYSCFG_RESET_COMP1(); + __HAL_SYSCFG_COMP1_CLK_ENABLE(); + } + + REG_WRITE_MASK(pHComp->CTRL, + COMP_CTRL_VIN_SEL_Msk | COMP_CTRL_FIL_CTRL_Msk | COMP_CTRL_POL_SEL_Msk | + COMP_CTRL_OUT_EN_Msk | COMP_CTRL_HYS_EN_Msk , + pInit->InputMinus | pInit->FilterFreq | pInit->OutputPolarity | + pInit->OutputSel | pInit->InputHysteresis); + + REG_WRITE_MASK(pHComp->VIPSEL, COMP_VIPSEL_VIP_SEL_Msk, pInit->InputPlus); + + REG_WRITE_MASK(pHComp->INITCNT, COMP_INITCNT_INIT_DELAY_Msk, pInit->InitDelay); + + return; +} + +void COMP_DeInit(COMP_Type *pHComp) +{ + if( pHComp == COMP0 ) + { + __HAL_SYSCFG_RESET_COMP0(); + __HAL_SYSCFG_COMP0_CLK_DISABLE(); + } + else if( pHComp == COMP1 ) + { + __HAL_SYSCFG_RESET_COMP1(); + __HAL_SYSCFG_COMP1_CLK_DISABLE(); + } + return; +} + +#endif /* CONFIG_ENABLE_HAL_VCMP */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_crc.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_crc.c new file mode 100644 index 0000000..27f4831 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_crc.c @@ -0,0 +1,123 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_crc.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + + +#include "hal_device.h" + +#if defined(CONFIG_ENABLE_HAL_CRC) + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +void CRC_Init(void) +{ + /* reset CRC module */ + __HAL_SYSCFG_RESET_CRC(); + + /* enable clock */ + __HAL_SYSCFG_CRC_CLK_ENABLE(); + + return; +} + +uint32_t CRC_CalcCRC(uint8_t *pData, CRC_WidthTypeDef crc_width) +{ + REG_WRITE(CRC->CR, crc_width); + + *((uint8_t*)&CRC->DIN) = *pData; + + return REG_READ_MASK(CRC->DOUT, REG_READ_MASK(CRC->CR, CRC_CR_POLYSEL_Msk) ? 0xFFFFul : 0xFFFFFFFFul); +} + +uint32_t CRC_CalcBlockCRC(uint8_t *pData, int length, CRC_WidthTypeDef crc_width) +{ + REG_WRITE(CRC->CR, crc_width); + + if( ((uint32_t)pData & 0x3) == 0 && (length & 0x3) == 0 ) + { + uint32_t *pWord = (uint32_t*)pData; + + length = length >> 2; + while( length-- ) + { + // Write each word to the CRC_DATA register + *((uint32_t*)&CRC->DIN) = *pWord++; + } + } + else if( ((uint32_t)pData & 0x1) == 0 && (length & 0x1) == 0 ) + { + uint16_t *pHWord = (uint16_t*)pData; + volatile uint16_t *pDatIn = (volatile uint16_t*)&CRC->DIN; + + length = length >> 1; + while( length-- ) + { + // Write each half-word to the CRC_DATA register + *pDatIn = *pHWord++; + } + } + else + { + volatile uint8_t *pDatIn = (volatile uint8_t*)&CRC->DIN; + + while( length-- ) + { + // Write each byte to the CRC_DATA register + *pDatIn = *pData++; + } + } + + return REG_READ_MASK(CRC->DOUT, REG_READ_MASK(CRC->CR, CRC_CR_POLYSEL_Msk) ? 0xFFFFul : 0xFFFFFFFFul); +} + +uint32_t CRC_GetCRC(void) +{ + return REG_READ_MASK(CRC->DOUT, REG_READ_MASK(CRC->CR, CRC_CR_POLYSEL_Msk) ? 0xFFFFul : 0xFFFFFFFFul); +} + + +uint32_t CRC_VerifyFlag(uint32_t Valid_CRC) +{ + if( Valid_CRC & 0xFFFF0000 ) + { + *((uint32_t*)&CRC->DIN) = (uint32_t)(Valid_CRC & CRC_DIN_DIN_Msk); + } + else + { + volatile uint16_t *pDatIn = (volatile uint16_t*)&CRC->DIN; + *pDatIn = (uint16_t)(Valid_CRC & CRC_DIN_DIN_Msk); + } + + return REG_READ_MASK(CRC->CR, CRC_CR_VERF_Msk); +} + +#endif /* CONFIG_ENABLE_HAL_CRC */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_device.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_device.c new file mode 100644 index 0000000..3755582 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_device.c @@ -0,0 +1,73 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_device.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/10 + * @license + * @description + */ + + +#include "hal_device.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static uint32_t g_seed1 = 0, g_seed2 = 0, g_seed3 = 0, g_seed4 = 0; +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +__WEAK void assert_failed(char *func, uint32_t line) +{ + while (1); +} + +void HAL_SRand(uint32_t seed) +{ + g_seed1 = seed; + g_seed2 = seed << 2; + g_seed3 = seed << 3; + g_seed4 = seed << 4; + return; +} + +uint32_t HAL_Rand(void) +{ + if( g_seed1 == 0 && g_seed2 == 0 ) + { + g_seed1 = ((uint16_t*)&__TIME__)[0]; + g_seed2 = ((uint16_t*)&__TIME__)[1]; + g_seed3 = ((uint16_t*)&__TIME__)[2]; + g_seed4 = ((uint16_t*)&__TIME__)[3]; + } + + uint32_t b; + b = ((g_seed1 << 6) ^ g_seed1) >> 13; + g_seed1 = ((g_seed1 & 0xFFFFFFFEU) << 18) ^ b; + b = ((g_seed2 << 2) ^ g_seed2) >> 27; + g_seed2 = ((g_seed2 & 0xFFFFFFF8U) << 2) ^ b; + b = ((g_seed3 << 13) ^ g_seed3) >> 21; + g_seed3 = ((g_seed3 & 0xFFFFFFF0U) << 7) ^ b; + b = ((g_seed4 << 3) ^ g_seed4) >> 12; + g_seed4 = ((g_seed4 & 0xFFFFFF80U) << 13) ^ b; + return (g_seed1 ^ g_seed2 ^ g_seed3 ^ g_seed4); +} diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_dsp.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_dsp.c new file mode 100644 index 0000000..7794eb7 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_dsp.c @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_dsp.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + + +#include "hal_device.h" + +#if defined(CONFIG_ENABLE_HAL_DSP) + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +#if 0 +int DSP_Div32(int numerator, int denominator, int *pQuotient, int *pRemainder) +{ + #if 0 + /* ToDo: It need to check RSLT1/RSLT2 should be clear with CPU or not */ + REG_WRITE(DSP->RSLT1, 0x0ul); + REG_WRITE(DSP->RSLT2, 0x0ul); + #endif + + DSP->CR_b.MODE = DSP_CR_MODE_DIV; + + REG_WRITE(DSP->SDAT1, numerator); + REG_WRITE(DSP->SDAT2, denominator); + + while( !REG_READ(DSP->SR) ) {} + + if( pQuotient ) *pQuotient = REG_READ(DSP->RSLT1); + if( pRemainder ) *pRemainder = REG_READ(DSP->RSLT2); + + return 0; +} +#endif + +uint32_t DSP_Sqrt32(DSP_SqrtParamTypeDef *pParam) +{ + #if 0 + /* ToDo: It need to check RSLT1/RSLT2 should be clear with CPU or not */ + REG_WRITE(DSP->RSLT1, 0x0ul); + REG_WRITE(DSP->RSLT2, 0x0ul); + #endif + + DSP->CR_b.MODE = DSP_CR_MODE_SQRT; + + REG_WRITE(DSP->SDAT1, pParam->value32[0]); + REG_WRITE(DSP->SDAT2, pParam->value32[1]); + + while( !REG_READ(DSP->SR) ) {} + + return REG_READ(DSP->RSLT1); +} + + +#endif /* CONFIG_ENABLE_HAL_DSP */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_flash.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_flash.c new file mode 100644 index 0000000..e9f4a79 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_flash.c @@ -0,0 +1,280 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_flash.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/10 + * @license + * @description + */ + + +#include "hal_device.h" + +#if defined(CONFIG_ENABLE_HAL_FLASH) +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_FLASH_TIMEOUT 0xFFFFFFFFul +#define FLASH_PE_CLK_MAX (1ul*1000*1000) +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= +static void +_FLASH_SetDivider(void) +{ + uint32_t div = 0; + div = sys_get_cpu_freq() / FLASH_PE_CLK_MAX; + + REG_WRITE(FLASH->DIV, div | (0x1ul << 8)); + return; +} +//============================================================================= +// Public Function Definition +//============================================================================= +flash_state_t FLASH_SetLatency(flash_latency_t latency) +{ + uint32_t pclk = 0; + + /* ToDo: verify system clock and latency relation */ + + pclk = sys_get_cpu_freq(); + + if( pclk > 80*1000*1000 && + latency == FLASH_LATENCY_1 ) + { + return FLASH_STATE_FAIL_PARAM; + } + + REG_WRITE_MASK(FLASH->CMD, + (FLASH_CMD_KEY_Msk | FLASH_CMD_NWS_Msk), + (FLASH_AUTH_KEY | latency)); + + return FLASH_STATE_OK; +} + +flash_state_t +FLASH_ErasePage(uint32_t page_addr) +{ + flash_state_t rval = FLASH_STATE_OK; + + _FLASH_SetDivider(); + + do { + REG_WRITE(FLASH->SR, 0xFFFFFFFFul); // clean interrutp flags + + // FLASH->FLIER = FLASH_FLIER_CMD_ENDE_Msk | FLASH_FLIER_CMD_ERRE_Msk; + // FLASH->FLIER = FLASH_FLIER_ADDR_ERRE_Msk; + + FLASH->AR = page_addr & ~(FLASH_1_PAGE_SIZE - 1); + + REG_WRITE_MASK(FLASH->CMD, + (FLASH_CMD_KEY_Msk | FLASH_CMD_START_Msk | + FLASH_CMD_UNLOCK_Msk | + FLASH_CMD_CMD_Msk), + (FLASH_AUTH_KEY | FLASH_CMD_START_Msk | \ + (0x1ul << FLASH_CMD_UNLOCK_Pos) | \ + (FLASH_CMD_CMD_ERASE_SECTOR << FLASH_CMD_CMD_Pos))); + + while( !FLASH_IsIdle() ); + } while(0); + + /* lock P/E operations */ + REG_WRITE_MASK(FLASH->CMD, + (FLASH_CMD_KEY_Msk | FLASH_CMD_UNLOCK_Msk), + FLASH_AUTH_KEY); + + return rval; +} + +flash_state_t +FLASH_ProgWord(uint32_t addr, uint32_t value) +{ + flash_state_t rval = FLASH_STATE_OK; + + do { + if( addr & 0x3 ) + { + rval = FLASH_STATE_FAIL_ADDR; + break; + } + + _FLASH_SetDivider(); + + REG_WRITE(FLASH->SR, 0xFFFFFFFFul); // clean interrutp flags + + FLASH->AR = addr; + FLASH->DR = value; + + REG_WRITE_MASK(FLASH->CMD, + (FLASH_CMD_KEY_Msk | FLASH_CMD_START_Msk | + FLASH_CMD_UNLOCK_Msk | + FLASH_CMD_CMD_Msk), + (FLASH_AUTH_KEY | FLASH_CMD_START_Msk | \ + (0x1ul << FLASH_CMD_UNLOCK_Pos) | \ + (FLASH_CMD_CMD_PROG << FLASH_CMD_CMD_Pos))); + + while( !FLASH_IsIdle() ); + } while(0); + + /* lock P/E operations */ + REG_WRITE_MASK(FLASH->CMD, + (FLASH_CMD_KEY_Msk | FLASH_CMD_UNLOCK_Msk), + FLASH_AUTH_KEY); + + return rval; +} + +flash_state_t +FLASH_ProgHWord(uint32_t addr, uint16_t value) +{ + flash_state_t rval = FLASH_STATE_OK; + + do { + union { + uint16_t hword[2]; + uint32_t word; + } u; + + if( addr & 0x1 ) + { + rval = FLASH_STATE_FAIL_ADDR; + break; + } + + _FLASH_SetDivider(); + REG_WRITE(FLASH->SR, 0xFFFFFFFFul); // clean interrutp flags + + #if 0 + u.word = 0xFFFFFFFFul; + #else + u.word = *(uint32_t*)(addr & ~0x3); + #endif + + u.hword[(addr & 0x2) ? 1 : 0] = value; + + FLASH->AR = (addr & ~0x3); + FLASH->DR = u.word; + + REG_WRITE_MASK(FLASH->CMD, + (FLASH_CMD_KEY_Msk | FLASH_CMD_START_Msk | + FLASH_CMD_UNLOCK_Msk | + FLASH_CMD_CMD_Msk), + (FLASH_AUTH_KEY | FLASH_CMD_START_Msk | \ + (0x1ul << FLASH_CMD_UNLOCK_Pos) | \ + (FLASH_CMD_CMD_PROG << FLASH_CMD_CMD_Pos))); + + while( !FLASH_IsIdle() ); + } while(0); + + /* lock P/E operations */ + REG_WRITE_MASK(FLASH->CMD, + (FLASH_CMD_KEY_Msk | FLASH_CMD_UNLOCK_Msk), + FLASH_AUTH_KEY); + + return rval; +} + +flash_state_t +FLASH_ProgByte(uint32_t addr, uint8_t value) +{ + flash_state_t rval = FLASH_STATE_OK; + + do { + union { + uint8_t byte[4]; + uint32_t word; + } u; + + _FLASH_SetDivider(); + REG_WRITE(FLASH->SR, 0xFFFFFFFFul); // clean interrutp flags + + #if 0 + u.word = 0xFFFFFFFFul; + #else + u.word = *(uint32_t*)(addr & ~0x3); + #endif + + u.byte[(addr & 0x3)] = value; + + FLASH->AR = (addr & ~0x3); + FLASH->DR = u.word; + + REG_WRITE_MASK(FLASH->CMD, + (FLASH_CMD_KEY_Msk | FLASH_CMD_START_Msk | + FLASH_CMD_UNLOCK_Msk | + FLASH_CMD_CMD_Msk), + (FLASH_AUTH_KEY | FLASH_CMD_START_Msk | \ + (0x1ul << FLASH_CMD_UNLOCK_Pos) | \ + (FLASH_CMD_CMD_PROG << FLASH_CMD_CMD_Pos))); + + while( !FLASH_IsIdle() ); + } while(0); + + /* lock P/E operations */ + REG_WRITE_MASK(FLASH->CMD, + (FLASH_CMD_KEY_Msk | FLASH_CMD_UNLOCK_Msk), + FLASH_AUTH_KEY); + + return rval; +} + +flash_state_t +FLASH_ProgData(uint32_t addr, uint32_t *pData, int length) +{ + flash_state_t rval = FLASH_STATE_OK; + + do { + if( addr & 0x3 || length & 0x3 ) + { + rval = FLASH_STATE_NOT_4_ALIGN; + break; + } + + _FLASH_SetDivider(); + REG_WRITE(FLASH->SR, 0xFFFFFFFFul); // clean interrutp flags + + FLASH->AR = addr; + + do { + FLASH->DR = *pData++; + FLASH->AR = addr; + + REG_WRITE_MASK(FLASH->CMD, + (FLASH_CMD_KEY_Msk | + FLASH_CMD_UNLOCK_Msk | + FLASH_CMD_CMD_Msk | FLASH_CMD_START_Msk), + (FLASH_AUTH_KEY | \ + (0x1ul << FLASH_CMD_UNLOCK_Pos) | \ + (FLASH_CMD_CMD_PROG << FLASH_CMD_CMD_Pos) | FLASH_CMD_START_Msk)); + + while( !FLASH_IsIdle() ); + + length -= 4; + addr += 4; + } while( length > 0 ); + + /* lock P/E operations */ + REG_WRITE_MASK(FLASH->CMD, + (FLASH_CMD_KEY_Msk | FLASH_CMD_UNLOCK_Msk), + FLASH_AUTH_KEY); + } while(0); + + return rval; +} + +#endif /* CONFIG_ENABLE_HAL_FLASH */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_gpio.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_gpio.c new file mode 100644 index 0000000..702bd42 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_gpio.c @@ -0,0 +1,249 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_gpio.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + + +#include "hal_device.h" + +#if defined(CONFIG_ENABLE_HAL_GPIO) + +//============================================================================= +// Constant Definition +//============================================================================= +#define GPIO_PORTA_AF_PINS (GPIO_Pin_00 | GPIO_Pin_01 | GPIO_Pin_02 | GPIO_Pin_03 | \ + GPIO_Pin_04 | GPIO_Pin_05 | GPIO_Pin_14 | GPIO_Pin_15) + +#define GPIO_PORTB_AF_PINS (GPIO_Pin_00 | GPIO_Pin_01 | GPIO_Pin_02 | GPIO_Pin_03 | \ + GPIO_Pin_04 | GPIO_Pin_05) +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int GPIO_Init(GPIO_Type *pHGpio, GPIO_InitTypeDef *pInit) +{ + int rval = 0; + + if( pHGpio == GPIOA ) + { + __HAL_SYSCFG_GPIOA_CLK_ENABLE(); + } + else if( pHGpio == GPIOB ) + { + __HAL_SYSCFG_GPIOB_CLK_ENABLE(); + } + + for(int i = 0; i < 16; i++) + { + uint32_t pin_cur = (0x1ul << i); + + if( REG_READ_MASK(pInit->GPIO_Pin, pin_cur) == 0 ) + continue; + + // enable Schmitt-Trigger + REG_SET_BITS(pHGpio->CTS, pin_cur); + + (pInit->GPIO_OType == GPIO_OType_OD) + ? REG_SET_BITS(pHGpio->ODS, pin_cur) + : REG_SET_BITS(pHGpio->ODC, pin_cur); + + switch( pInit->GPIO_Mode ) + { + default: + case GPIO_Mode_IN: /* Input mode */ + REG_SET_BITS(pHGpio->OEC, pin_cur); + REG_SET_BITS(pHGpio->INES, pin_cur); + + if( pInit->GPIO_PuPd == GPIO_PuPd_UP ) + { + REG_SET_BITS(pHGpio->PUS, pin_cur); + REG_SET_BITS(pHGpio->PDC, pin_cur); + } + else if( pInit->GPIO_PuPd == GPIO_PuPd_DOWN ) + { + REG_SET_BITS(pHGpio->PDS, pin_cur); + REG_SET_BITS(pHGpio->PUC, pin_cur); + } + else + { /* NOPULL */ + REG_SET_BITS(pHGpio->PDC, pin_cur); + REG_SET_BITS(pHGpio->PUC, pin_cur); + } + + GPIO_ITConfig(pHGpio, (GPIO_PinTypeDef)pin_cur, &pInit->GPIO_ITInit); + break; + + case GPIO_Mode_OUT: /* Output mode */ + REG_SET_BITS(pHGpio->INEC, pin_cur); + REG_SET_BITS(pHGpio->OES, pin_cur); + + if( pInit->GPIO_PuPd == GPIO_PuPd_UP ) + { + REG_SET_BITS(pHGpio->LAT, pin_cur); + } + else if( pInit->GPIO_PuPd == GPIO_PuPd_DOWN ) + { + REG_CLR_BITS(pHGpio->LAT, pin_cur); + } + else + { + /* NOPULL, H/w not support */ + } + break; + + case GPIO_Mode_ANAL: /* Analog mode */ + REG_SET_BITS(pHGpio->INEC, pin_cur); + + // disable Schmitt-Trigger + REG_SET_BITS(pHGpio->CTC, pin_cur); + break; + + case GPIO_Mode_PWR_Saving: + REG_SET_BITS(pHGpio->INEC, pin_cur); + REG_SET_BITS(pHGpio->OEC, pin_cur); + break; + + case GPIO_Mode_AF: /* Alternate mode */ + if( pHGpio == GPIOA && (pin_cur & GPIO_PORTA_AF_PINS) ) + { + int shift = 31 - HAL_CLZ(pin_cur); + + shift = (shift > 5) ? (shift - 8) : shift; + REG_WRITE_MASK(AFIO->PAAFR, (AFIO_PAAFR_PA0_Msk << 3*shift), pInit->GPIO_AF_Mode << 3*shift); + } + else if( pHGpio == GPIOB && (pin_cur & GPIO_PORTB_AF_PINS) ) + { + int shift = 31 - HAL_CLZ(pin_cur); + + REG_WRITE_MASK(AFIO->PBAFR, (AFIO_PBAFR_PB0_Msk << 3*shift), pInit->GPIO_AF_Mode << 3*shift); + } + else + { + // The target pin is not supported AF mode + return -1; + } + break; + } + } + + return rval; +} + +void GPIO_DeInit(GPIO_Type *pHGpio, uint32_t pins) +{ + while( pins ) + { + int shift = 31 - HAL_CLZ(pins); + uint32_t pin_cur = 0x0; + + pin_cur = 0x1ul << shift; + REG_CLR_BITS(pins, pin_cur); + + REG_SET_BITS(pHGpio->IEC, pin_cur); // disable interrupt + + REG_SET_BITS(pHGpio->INEC, pin_cur); + REG_SET_BITS(pHGpio->OEC, pin_cur); + + REG_SET_BITS(pHGpio->ODC, pin_cur); + + REG_SET_BITS(pHGpio->ITC0, pin_cur); + REG_SET_BITS(pHGpio->ITC1, pin_cur); + REG_SET_BITS(pHGpio->PLC, pin_cur); + REG_SET_BITS(pHGpio->IST, pin_cur); + + REG_SET_BITS(pHGpio->CTS, pin_cur); + + if( pHGpio == GPIOA && (pin_cur & GPIO_PORTA_AF_PINS) ) + { + shift = (shift > 5) ? (shift - 8) : shift; + REG_WRITE_MASK(AFIO->PAAFR, (AFIO_PAAFR_PA0_Msk << 3*shift), GPIO_AF_0 << 3*shift); + } + else if( pHGpio == GPIOB && (pin_cur & GPIO_PORTB_AF_PINS) ) + { + REG_WRITE_MASK(AFIO->PBAFR, (AFIO_PBAFR_PB0_Msk << 3*shift), GPIO_AF_0 << 3*shift); + } + } + + return; +} + +void GPIO_PeriAFConfig(GPIO_Type *pHGpio, GPIO_PeriTypeDef peri_type, GPIO_PeriAFTypeDef af_mode) +{ + if( peri_type < GPIO_Peri_Fn2 ) + { + // Fn1_AFR case + (peri_type == GPIO_Peri_BKIN) ? REG_WRITE_MASK(AFIO->FN1_AFR, AFIO_FN1_AFR_BKIN_Msk, af_mode << AFIO_FN1_AFR_BKIN_Pos) : + (peri_type == GPIO_Peri_ECAP0) ? REG_WRITE_MASK(AFIO->FN1_AFR, AFIO_FN1_AFR_ECAP0_Msk, af_mode << AFIO_FN1_AFR_ECAP0_Pos) : + (peri_type == GPIO_Peri_ECAP1) ? REG_WRITE_MASK(AFIO->FN1_AFR, AFIO_FN1_AFR_ECAP1_Msk, af_mode << AFIO_FN1_AFR_ECAP1_Pos) : + (peri_type == GPIO_Peri_ECAP2) ? REG_WRITE_MASK(AFIO->FN1_AFR, AFIO_FN1_AFR_ECAP2_Msk, af_mode << AFIO_FN1_AFR_ECAP2_Pos) : + REG_WRITE_MASK(AFIO->FN1_AFR, AFIO_FN1_AFR_EPETR_Msk, af_mode << AFIO_FN1_AFR_EPETR_Pos); + } + else + { + // Fn2_AFR case + (peri_type == GPIO_Peri_TCAP0) ? REG_WRITE_MASK(AFIO->FN2_AFR, AFIO_FN2_AFR_TCAP0_Msk, af_mode << AFIO_FN2_AFR_TCAP0_Pos) : + (peri_type == GPIO_Peri_TCAP1) ? REG_WRITE_MASK(AFIO->FN2_AFR, AFIO_FN2_AFR_TCAP1_Msk, af_mode << AFIO_FN2_AFR_TCAP1_Pos) : + (peri_type == GPIO_Peri_TCAP2) ? REG_WRITE_MASK(AFIO->FN2_AFR, AFIO_FN2_AFR_TCAP2_Msk, af_mode << AFIO_FN2_AFR_TCAP2_Pos) : + (peri_type == GPIO_Peri_I2C_PULL0) ? REG_WRITE_MASK(AFIO->FN2_AFR, AFIO_FN2_AFR_I2C_PULL0_Msk, af_mode << AFIO_FN2_AFR_I2C_PULL0_Pos) : + (peri_type == GPIO_Peri_I2C_PULL1) ? REG_WRITE_MASK(AFIO->FN2_AFR, AFIO_FN2_AFR_I2C_PULL1_Msk, af_mode << AFIO_FN2_AFR_I2C_PULL1_Pos) : + (peri_type == GPIO_Peri_I2C_PULL2) ? REG_WRITE_MASK(AFIO->FN2_AFR, AFIO_FN2_AFR_I2C_PULL2_Msk, af_mode << AFIO_FN2_AFR_I2C_PULL2_Pos) : + (peri_type == GPIO_Peri_I2C_PULL3) ? REG_WRITE_MASK(AFIO->FN2_AFR, AFIO_FN2_AFR_I2C_PULL3_Msk, af_mode << AFIO_FN2_AFR_I2C_PULL3_Pos) : + (peri_type == GPIO_Peri_I2C_PULL4) ? REG_WRITE_MASK(AFIO->FN2_AFR, AFIO_FN2_AFR_I2C_PULL4_Msk, af_mode << AFIO_FN2_AFR_I2C_PULL4_Pos) : + (peri_type == GPIO_Peri_I2C_PULL5) ? REG_WRITE_MASK(AFIO->FN2_AFR, AFIO_FN2_AFR_I2C_PULL5_Msk, af_mode << AFIO_FN2_AFR_I2C_PULL5_Pos) : + (peri_type == GPIO_Peri_I2C_PULL6) ? REG_WRITE_MASK(AFIO->FN2_AFR, AFIO_FN2_AFR_I2C_PULL6_Msk, af_mode << AFIO_FN2_AFR_I2C_PULL6_Pos) : + (peri_type == GPIO_Peri_I2C_PULL7) ? REG_WRITE_MASK(AFIO->FN2_AFR, AFIO_FN2_AFR_I2C_PULL7_Msk, af_mode << AFIO_FN2_AFR_I2C_PULL7_Pos) : + REG_WRITE_MASK(AFIO->FN2_AFR, AFIO_FN2_AFR_T2ETR_Msk, af_mode << AFIO_FN2_AFR_T2ETR_Pos); + } + return; +} + + + +void GPIO_ITConfig(GPIO_Type *pHGpio, GPIO_PinTypeDef pins, GPIO_ITInitTypeDef *pInit) +{ + // set Interrupt trigger type & polarity + if( pInit->GPIO_Trigger == GPIO_Trigger_Any_Edge ) + { + REG_SET_BITS(pHGpio->ITS1, pins); // both edge + } + else if( pInit->GPIO_Trigger == GPIO_Trigger_Edge ) + { + REG_SET_BITS(pHGpio->ITC1, pins); + REG_SET_BITS(pHGpio->ITS0, pins); // Edge trigger + } + else + { + REG_SET_BITS(pHGpio->ITC1, pins); + REG_SET_BITS(pHGpio->ITC0, pins); // Level trigger + } + + (pInit->GPIO_Polarity == GPIO_Polarity_High_Rise) ? + REG_SET_BITS(pHGpio->PLS, pins) : // High level or rising edge + REG_SET_BITS(pHGpio->PLC, pins); // Low level or falling edge + + return; +} + +#endif /* CONFIG_ENABLE_HAL_GPIO */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_i2c.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_i2c.c new file mode 100644 index 0000000..d55ce9e --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_i2c.c @@ -0,0 +1,868 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_i2c.c +* +* @author Wei-Lun Hsu +* @version 0.1 +* @date 2024/09/10 +* @license +* @description +*/ + + +#include "hal_device.h" + +#if defined(CONFIG_ENABLE_HAL_I2C) +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_I2C_TIMEOUT 20U /*!< Timeout 20 ms */ +#define I2C_CLOCK_FREQ_MAX (400ul*1000) + +typedef enum +{ + I2C_SwState_SUCCESS = 0, /*!< Waited i2c status flag */ + I2C_SwState_ERROR = 1, /*!< No i2c status flag */ + I2C_SwState_WAITING = 2, /*!< Waiting i2c status flag */ + I2C_SwState_HOLD_DATA = 3, /*!< I2C hold data flag */ + I2C_SwState_FORCE_STOP = 4, /*!< I2C force stop flag */ + I2C_SwState_RESTART = 5, /*!< I2C restart flag */ +} I2C_SwState; + +typedef enum +{ + I2C_TxStage_START_BIT = 0, + I2C_TxStage_ADDRESS, + I2C_TxStage_DATA, + +} I2C_TxStage; + +#define I2C_START_BIT_H I2C_CTLSET_STA_Msk +#define I2C_START_BIT_L 0x0u + +#define I2C_STOP_BIT_H I2C_CTLSET_STO_Msk +#define I2C_STOP_BIT_L 0x0u + +#define I2C_ACK_BIT_H I2C_CTLSET_AA_Msk +#define I2C_ACK_BIT_L 0x0u + + +#define I2C_CLK_DIVIDER_60 (I2C_CTLSET_CR1_Msk | I2C_CTLSET_CR2_Msk) +#define I2C_CLK_DIVIDER_120 (I2C_CTLSET_CR0_Msk | I2C_CTLSET_CR2_Msk) +#define I2C_CLK_DIVIDER_160 (I2C_CTLSET_CR0_Msk | I2C_CTLSET_CR1_Msk) +#define I2C_CLK_DIVIDER_192 I2C_CTLSET_CR1_Msk +#define I2C_CLK_DIVIDER_244 I2C_CTLSET_CR0_Msk +#define I2C_CLK_DIVIDER_256 0x0ul +#define I2C_CLK_DIVIDER_960 I2C_CTLSET_CR2_Msk +#define I2C_CLK_DIVIDER_Msk (I2C_CTLSET_CR0_Msk | I2C_CTLSET_CR1_Msk | I2C_CTLSET_CR2_Msk) +//============================================================================= +// Macro Definition +//============================================================================= +/** + * \brief Set/Clear Ack bit + * + * \param [in] pHI2C The handle of I2C + * \return None + */ +__STATIC_FORCEINLINE void _I2C_SET_ACK_FLAG(I2C_Type *pHI2C) +{ + REG_SET_BITS(pHI2C->CTLSET, I2C_CTLSET_AA_Msk); + return; +} + +__STATIC_FORCEINLINE void _I2C_CLR_ACK_FLAG(I2C_Type *pHI2C) +{ + REG_SET_BITS(pHI2C->CTLCLR, I2C_CTLCLR_AA_Msk); + return; +} + +/** + * \brief Set/Clear Start bit + * + * \param [in] pHI2C The handle of I2C + * \return None + */ +__STATIC_FORCEINLINE void _I2C_SET_START_FLAG(I2C_Type *pHI2C) +{ + REG_SET_BITS(pHI2C->CTLSET, I2C_CTLSET_STA_Msk); + return; +} + +__STATIC_FORCEINLINE void _I2C_CLR_START_FLAG(I2C_Type *pHI2C) +{ + REG_SET_BITS(pHI2C->CTLCLR, I2C_CTLCLR_STA_Msk); + return; +} + +/** + * \brief Check Interrupt flag of an I2C + * + * \param [in] __HANDLE__ The handle of I2C + * \return + * 0 : no interrupt + * others: get interrupt + */ +#define __I2C_GET_SI_FLAG(__HANDLE__) REG_READ_MASK((__HANDLE__)->CTLSET, I2C_CTLSET_SI_Msk) + + +/** + * \brief Set/Clear the I2C interrupt set-flag + * + * \param [in] pHI2C The handle of I2C + * \return + * None + */ +__STATIC_FORCEINLINE void _I2C_SET_SI_FLAG(I2C_Type *pHI2C) +{ + REG_SET_BITS(pHI2C->CTLSET, I2C_CTLSET_SI_Msk); + return; +} + +__STATIC_FORCEINLINE void _I2C_CLR_SI_FLAG(I2C_Type *pHI2C) +{ + REG_SET_BITS(pHI2C->CTLCLR, I2C_CTLCLR_SI_Msk); + return; +} + +/** + * \brief Enable/Disable General Call + * + * \param [in] pHI2C The handle of I2C + * \return None + */ +__STATIC_FORCEINLINE void _I2C_GC_ENABLE(I2C_Type *pHI2C) +{ + REG_SET_BITS(pHI2C->ADDR, I2C_ADDR_GC_Msk); + return; +} + +__STATIC_FORCEINLINE void _I2C_GC_DISABLE(I2C_Type *pHI2C) +{ + REG_CLR_BITS(pHI2C->ADDR, I2C_ADDR_GC_Msk); + return; +} + +/** + * \brief Enable/Disable I2C module + * + * \param [in] pHI2C The handle of I2C + * \return + * None + */ +__STATIC_FORCEINLINE void _I2C_ENABLE(I2C_Type *pHI2C) +{ + REG_SET_BITS(pHI2C->CTLSET, I2C_CTLSET_EN_Msk); + return; +} + +__STATIC_FORCEINLINE void _I2C_DISABLE(I2C_Type *pHI2C) +{ + REG_SET_BITS(pHI2C->CTLCLR, I2C_CTLSET_EN_Msk); + return; +} + + + /** + * \brief Configure the Start/Stop/ACK flag + * + * \param [in] pHI2C The handle of I2C + * \param [in] start_bit The target state of start_bit + * \param [in] stop_bit The target state of stop_bit + * \param [in] ack_bit The target state of ack_bit + * \return + * None + */ + __STATIC_FORCEINLINE void _I2C_Config(I2C_Type *pHI2C, uint32_t start_bit, uint32_t stop_bit, uint32_t ack_bit) +{ + REG_WRITE_MASK(pHI2C->CTLCLR, + I2C_CTLCLR_STA_Msk | I2C_CTLCLR_STO_Msk | I2C_CTLCLR_AA_Msk, + I2C_CTLCLR_STA_Msk | I2C_CTLCLR_STO_Msk | I2C_CTLCLR_AA_Msk); + + REG_WRITE_MASK(pHI2C->CTLSET, + I2C_CTLSET_STA_Msk | I2C_CTLSET_STO_Msk | I2C_CTLSET_AA_Msk, + (start_bit) | (stop_bit) | (ack_bit)); + return; +} + + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= +static I2C_ErrTypeDef +_I2C_Wait_SI_Flag(I2C_Type *pHI2C, uint32_t timeout_ms) +{ + uint32_t start_ticks = 0; + + start_ticks = sys_get_tick(); + + while( !REG_READ_MASK(pHI2C->CTLSET, I2C_CTLSET_SI_Msk) ) + { + if( (sys_get_tick() - start_ticks) > timeout_ms ) + { + return I2C_Err_TimeOut; + } + } + + return I2C_Err_OK; +} + +static I2C_SwState +_I2C_Master_Send_Byte(I2C_Type *pHI2C, uint8_t **ppData, bool is_end) +{ + __IO uint32_t *pData_reg = &pHI2C->DATA; + I2C_SwState rval = I2C_SwState_SUCCESS; + + switch( REG_READ(pHI2C->STAT) ) + { + default: + _I2C_Config(pHI2C, I2C_START_BIT_L, I2C_STOP_BIT_H, I2C_ACK_BIT_L); + rval = I2C_SwState_ERROR; + break; + + case I2C_State_MASTER_TX_START: + case I2C_State_MASTER_TX_RESTART: + case I2C_State_MASTER_TX_SLAW_ACK: + *((__IO uint8_t*)pData_reg) = *((__IO uint8_t*)(*ppData)); + *ppData = *ppData + 1; + _I2C_Config(pHI2C, I2C_START_BIT_L, I2C_STOP_BIT_L, I2C_ACK_BIT_L); + break; + + case I2C_State_MASTER_TX_SLAW_NOACK: + case I2C_State_MASTER_TX_DATA_NOACK: + _I2C_Config(pHI2C, I2C_START_BIT_L, I2C_STOP_BIT_H, I2C_ACK_BIT_L); + break; + + case I2C_State_MASTER_TX_DATA_ACK: + if( is_end ) + { + _I2C_Config(pHI2C, I2C_START_BIT_L, I2C_STOP_BIT_H, I2C_ACK_BIT_L); + break; + } + + *((__IO uint8_t*)pData_reg) = *((__IO uint8_t*)(*ppData)); + *ppData = *ppData + 1; + break; + + case I2C_State_MASTER_TX_LOST_BUS: + _I2C_Config(pHI2C, I2C_START_BIT_H, I2C_STOP_BIT_L, I2C_ACK_BIT_L); + break; + } + + _I2C_CLR_SI_FLAG(pHI2C); + + return rval; +} + +static I2C_SwState +_I2C_Master_Recv_Byte(I2C_Type *pHI2C, uint8_t **ppData, uint32_t is_end) +{ + __IO uint32_t *pData_reg = &pHI2C->DATA; + I2C_SwState rval = I2C_SwState_SUCCESS; + + switch( REG_READ(pHI2C->STAT) ) + { + default: + _I2C_Config(pHI2C, I2C_START_BIT_L, I2C_STOP_BIT_H, I2C_ACK_BIT_L); + rval = I2C_SwState_ERROR; + break; + + case I2C_State_MASTER_TX_DATA_ACK: + _I2C_Config(pHI2C, I2C_START_BIT_H, I2C_STOP_BIT_L, I2C_ACK_BIT_L); + break; + + case I2C_State_MASTER_RX_START: + case I2C_State_MASTER_RX_RESTART: + *((__IO uint8_t*)pData_reg) = *((__IO uint8_t*)(*ppData)); + *ppData = *ppData + 1; + _I2C_Config(pHI2C, I2C_START_BIT_L, I2C_STOP_BIT_L, I2C_ACK_BIT_L); + break; + + case I2C_State_MASTER_RX_SLAR_ACK: + _I2C_Config(pHI2C, I2C_START_BIT_L, + I2C_STOP_BIT_L, + (is_end)? I2C_ACK_BIT_L : I2C_ACK_BIT_H); + break; + + case I2C_State_MASTER_RX_DATA_ACK: + _I2C_Config(pHI2C, I2C_START_BIT_L, + I2C_STOP_BIT_L, + (is_end) ? I2C_ACK_BIT_L : I2C_ACK_BIT_H); + + *(__IO uint8_t*)(*ppData) = *((__IO uint8_t*)pData_reg); + *ppData = *ppData + 1; + + break; + + case I2C_State_MASTER_RX_DATA_NOACK: + *(__IO uint8_t*)(*ppData) = *((__IO uint8_t*)pData_reg); + *ppData = *ppData + 1; + + case I2C_State_MASTER_RX_SLAR_NOACK: + _I2C_Config(pHI2C, I2C_START_BIT_L, I2C_STOP_BIT_H, I2C_ACK_BIT_H); + break; + + case I2C_State_MASTER_RX_LOST_BUS: + _I2C_Config(pHI2C, I2C_START_BIT_H, I2C_STOP_BIT_L, I2C_ACK_BIT_H); + break; + } + + _I2C_CLR_SI_FLAG(pHI2C); + + return rval; +} + +static I2C_SwState +_I2C_Slave_Send_Byte(I2C_Type *pHI2C, uint8_t **ppData, bool *pHasRxAddr, bool is_end) +{ + __IO uint32_t *pData_reg = &pHI2C->DATA; + I2C_SwState rval = I2C_SwState_SUCCESS; + + switch( REG_READ(pHI2C->STAT) ) + { + default: + _I2C_Config(pHI2C, I2C_START_BIT_L, I2C_STOP_BIT_H, I2C_ACK_BIT_H); + rval = I2C_SwState_ERROR; + break; + + case I2C_State_SLAVE_RX_SLAR_ACK: + *pHasRxAddr = true; + case I2C_State_SLAVE_TX_DATA_ACK: + if( is_end ) + { + _I2C_Config(pHI2C, I2C_START_BIT_L, I2C_STOP_BIT_H, I2C_ACK_BIT_H); + break; + } + + *((__IO uint8_t*)pData_reg) = *((__IO uint8_t*)(*ppData)); + *ppData = *ppData + 1; + _I2C_Config(pHI2C, I2C_START_BIT_L, I2C_STOP_BIT_L, I2C_ACK_BIT_H); + break; + + case I2C_State_SLAVE_TX_LOST_BUS: + *((__IO uint8_t*)pData_reg) = *((__IO uint8_t*)(*ppData)); + *ppData = *ppData + 1; + _I2C_Config(pHI2C, I2C_START_BIT_H, I2C_STOP_BIT_L, I2C_ACK_BIT_H); + break; + + case I2C_State_SLAVE_TX_DATA_NOACK: + case I2C_State_SLAVE_TX_LAST_DATA: + _I2C_Config(pHI2C, I2C_START_BIT_L, I2C_STOP_BIT_L, I2C_ACK_BIT_H); + rval = I2C_SwState_SUCCESS; + break; + + case I2C_State_SLAVE_STOP_RESTART: // master force stop + _I2C_Config(pHI2C, I2C_START_BIT_L, I2C_STOP_BIT_L, I2C_ACK_BIT_H); + rval = (*pHasRxAddr) ? I2C_SwState_FORCE_STOP : I2C_SwState_RESTART; + break; + } + + _I2C_CLR_SI_FLAG(pHI2C); + + return rval; +} + +static I2C_SwState +_I2C_Slave_Recv_Byte(I2C_Type *pHI2C, uint8_t **ppData, uint32_t is_end) +{ + __IO uint32_t *pData_reg = &pHI2C->DATA; + I2C_SwState rval = I2C_SwState_SUCCESS; + + switch( REG_READ(pHI2C->STAT) ) + { + default: + _I2C_Config(pHI2C, I2C_START_BIT_L, I2C_STOP_BIT_H, I2C_ACK_BIT_H); + rval = I2C_SwState_ERROR; + break; + + case I2C_State_SLAVE_RX_SLAW_LOST_BUS: + case I2C_State_SLAVE_RX_BADDR_LOST_BUS: + _I2C_Config(pHI2C, I2C_START_BIT_H, I2C_STOP_BIT_L, I2C_ACK_BIT_H); + break; + + case I2C_State_SLAVE_RX_SLAW_ACK: + case I2C_State_SLAVE_RX_BDATA_NOACK: + case I2C_State_SLAVE_RX_BROAD_ACK: + _I2C_Config(pHI2C, I2C_START_BIT_L, + I2C_STOP_BIT_L, + (is_end) ? I2C_ACK_BIT_L : I2C_ACK_BIT_H); + + rval = I2C_SwState_HOLD_DATA; + break; + + case I2C_State_SLAVE_RX_DATA_ACK: + *(__IO uint8_t*)(*ppData) = *((__IO uint8_t*)pData_reg); + *ppData = *ppData + 1; + + _I2C_Config(pHI2C, I2C_START_BIT_L, + I2C_STOP_BIT_L, + (is_end) ? I2C_ACK_BIT_L : I2C_ACK_BIT_H); + break; + + case I2C_State_SLAVE_RX_DATA_NOACK: + *(__IO uint8_t*)(*ppData) = *((__IO uint8_t*)pData_reg); + *ppData = *ppData + 1; + + _I2C_Config(pHI2C, I2C_START_BIT_L, + (is_end) ? I2C_STOP_BIT_H : I2C_STOP_BIT_L, + I2C_ACK_BIT_H); + break; + + case I2C_State_SLAVE_RX_BDATA_ACK: + *(__IO uint8_t*)(*ppData) = *((__IO uint8_t*)pData_reg); + *ppData = *ppData + 1; + + _I2C_Config(pHI2C, I2C_START_BIT_L, I2C_STOP_BIT_L, I2C_ACK_BIT_H); + break; + + case I2C_State_SLAVE_STOP_RESTART: // master force stop + _I2C_Config(pHI2C, I2C_START_BIT_L, I2C_STOP_BIT_L, I2C_ACK_BIT_H); + rval = I2C_SwState_FORCE_STOP; + break; + } + + _I2C_CLR_SI_FLAG(pHI2C); + + return rval; +} +//============================================================================= +// Public Function Definition +//============================================================================= +void I2C_StructInit(I2C_InitTypeDef *pInit) +{ + int divider = 0; + + pInit->Mode = I2C_Mode_MASTER; + pInit->OwnAddress = 0x0; + pInit->BroadAck = I2C_BroadAck_Disable; + + divider = (g_SystemCoreClock / I2C_CLOCK_FREQ_MAX); + pInit->ClockDiv = (divider <= I2C_CLK_Div60) ? I2C_CLK_Div60 : + (divider <= I2C_CLK_Div120) ? I2C_CLK_Div120 : + (divider <= I2C_CLK_Div160) ? I2C_CLK_Div160 : + (divider <= I2C_CLK_Div192) ? I2C_CLK_Div192 : + (divider <= I2C_CLK_Div244) ? I2C_CLK_Div244 : + (divider <= I2C_CLK_Div256) ? I2C_CLK_Div256 : + I2C_CLK_Div960; + + return; +} + +void I2C_DeInit(I2C_Type *pHI2C) +{ + if( (int)pHI2C == (int)I2C0 ) + sys_close_IRQ(I2C0_IRQn); + + _I2C_DISABLE(pHI2C); + + __HAL_SYSCFG_RESET_I2C(); + __HAL_SYSCFG_I2C_CLK_DISABLE(); + return; +} + + +I2C_ErrTypeDef I2C_Init(I2C_Type *pHI2C, I2C_InitTypeDef *pInit) +{ + __HAL_SYSCFG_I2C_CLK_ENABLE(); + __HAL_SYSCFG_RESET_I2C(); + + if( pInit->Mode == I2C_Mode_MASTER ) + { + uint32_t divider = 0ul; + + #if 0 + /** + * I2C clock freq should less than I2C_CLOCK_FREQ_MAX + */ + if( (g_SystemCoreClock / pInit->ClockDiv) > I2C_CLOCK_FREQ_MAX ) + return I2C_Err_WrongParams; + #endif + + divider = (pInit->ClockDiv == I2C_CLK_Div960) ? I2C_CLK_DIVIDER_960 : + (pInit->ClockDiv == I2C_CLK_Div256) ? I2C_CLK_DIVIDER_256 : + (pInit->ClockDiv == I2C_CLK_Div244) ? I2C_CLK_DIVIDER_244 : + (pInit->ClockDiv == I2C_CLK_Div192) ? I2C_CLK_DIVIDER_192 : + (pInit->ClockDiv == I2C_CLK_Div160) ? I2C_CLK_DIVIDER_160 : + (pInit->ClockDiv == I2C_CLK_Div120) ? I2C_CLK_DIVIDER_120 : + I2C_CLK_DIVIDER_60; + + /* Set divider */ + REG_WRITE_MASK(pHI2C->CTLSET, I2C_CLK_DIVIDER_Msk, divider); + + /* clear ack flag */ + _I2C_CLR_ACK_FLAG(pHI2C); + } + else if( pInit->Mode == I2C_Mode_SLAVE ) + { + /* Configure Slave Address */ + REG_WRITE_MASK(pHI2C->ADDR, + I2C_ADDR_ADDR_Msk | I2C_ADDR_GC_Msk, + (pInit->OwnAddress << I2C_ADDR_ADDR_Pos) | pInit->BroadAck); + + REG_WRITE_MASK(pHI2C->CTLSET, I2C_CLK_DIVIDER_Msk, pInit->ClockDiv); + + _I2C_SET_ACK_FLAG(pHI2C); + } + else + return I2C_Err_WrongParams; + + + _I2C_ENABLE(pHI2C); + _I2C_CLR_SI_FLAG(pHI2C); + + return I2C_Err_OK; +} + +I2C_ErrTypeDef I2C_Master_Transmit(I2C_Type *pHI2C, uint16_t DevAddr, uint8_t *pData, uint16_t Size) +{ + I2C_SwState rval = I2C_SwState_SUCCESS; + I2C_TxStage stage = I2C_TxStage_START_BIT; + uint16_t tx_nbytes = 0; + + if( (int)pHI2C == (int)I2C0 ) + sys_close_IRQ(I2C0_IRQn); + + _I2C_SET_START_FLAG(pHI2C); + stage = I2C_TxStage_ADDRESS; + + while( tx_nbytes < Size ) + { + if( _I2C_Wait_SI_Flag(pHI2C, CONFIG_I2C_TIMEOUT) != I2C_Err_OK ) + break; + + if( stage == I2C_TxStage_ADDRESS ) + { + uint8_t addr = (uint8_t)DevAddr & ~0x1u; // write mode + uint8_t *pAddr = 0; + + pAddr = &addr; + rval = _I2C_Master_Send_Byte(pHI2C, &pAddr, false); + if( rval == I2C_SwState_ERROR ) + break; + + stage = I2C_TxStage_DATA; + continue; + } + else + { + rval = _I2C_Master_Send_Byte(pHI2C, &pData, false); + if( rval == I2C_SwState_ERROR ) + break; + } + + tx_nbytes = (rval == I2C_SwState_SUCCESS) ? tx_nbytes + 1 : tx_nbytes; + } + + if( rval == I2C_SwState_SUCCESS ) + { + // send STOP-bit + _I2C_Wait_SI_Flag(pHI2C, CONFIG_I2C_TIMEOUT); + _I2C_Master_Send_Byte(pHI2C, &pData, true); + } + + return (rval == I2C_SwState_SUCCESS) ? I2C_Err_OK : I2C_Err_Fail; +} + +I2C_ErrTypeDef I2C_Master_Receive(I2C_Type *pHI2C, uint8_t DevAddr, uint8_t *pData, uint16_t *pSize, uint16_t Timeout_ms) +{ + I2C_SwState rval = I2C_SwState_SUCCESS; + I2C_TxStage stage = I2C_TxStage_START_BIT; + uint16_t buf_size = *pSize; + int rx_nbytes = 0; + + if( (int)pHI2C == (int)I2C0 ) + sys_close_IRQ(I2C0_IRQn); + + _I2C_SET_START_FLAG(pHI2C); + stage = I2C_TxStage_ADDRESS; + + if( pSize ) *pSize = 0; + + while( rx_nbytes < buf_size ) + { + if( _I2C_Wait_SI_Flag(pHI2C, Timeout_ms) != I2C_Err_OK ) + { + if( Timeout_ms == I2C_BLOCKING ) + continue; + + return I2C_Err_TimeOut; + } + + if( stage == I2C_TxStage_ADDRESS ) + { + uint8_t addr = (uint8_t)DevAddr | 0x1u; // read mode + uint8_t *pAddr = 0; + + pAddr = &addr; + rval = _I2C_Master_Recv_Byte(pHI2C, &pAddr, (buf_size == 1)); + if( rval == I2C_SwState_ERROR ) + break; + + /** + * send DevAddr+R and then receive data + * ps. Decrease the DevAddr+R byte + */ + rx_nbytes = -1; + stage = I2C_TxStage_DATA; + continue; + } + else + { + rval = _I2C_Master_Recv_Byte(pHI2C, &pData, ((rx_nbytes + 1) == (buf_size-1))); + if( rval == I2C_SwState_ERROR ) + break; + } + + rx_nbytes = (rval == I2C_SwState_SUCCESS) ? rx_nbytes + 1 : rx_nbytes; + } + + if( pSize ) *pSize = rx_nbytes; + + return (rval == I2C_SwState_SUCCESS) ? I2C_Err_OK : I2C_Err_Fail; +} + +I2C_ErrTypeDef I2C_Slave_Transmit(I2C_Type *pHI2C, uint8_t *pData, uint16_t Size, uint16_t Timeout_ms) +{ + __IO uint16_t tx_nbytes = 0; + I2C_SwState rval = I2C_SwState_SUCCESS; + bool HasRecvAddr = false; + + if( (int)pHI2C == (int)I2C0 ) + sys_close_IRQ(I2C0_IRQn); + + while( tx_nbytes < Size ) + { + if( _I2C_Wait_SI_Flag(pHI2C, Timeout_ms) != I2C_Err_OK ) + { + if( Timeout_ms == I2C_BLOCKING ) + continue; + + return I2C_Err_TimeOut; + } + + rval = _I2C_Slave_Send_Byte(pHI2C, &pData, &HasRecvAddr, false); + if( rval == I2C_SwState_ERROR || rval == I2C_SwState_FORCE_STOP ) + { + break; + } + + tx_nbytes = (rval == I2C_SwState_SUCCESS) ? tx_nbytes + 1 : tx_nbytes; + } + + if( rval == I2C_SwState_SUCCESS ) + { + // send STOP-bit + _I2C_Wait_SI_Flag(pHI2C, CONFIG_I2C_TIMEOUT); + _I2C_Slave_Send_Byte(pHI2C, &pData, &HasRecvAddr, true); + } + + return (rval == I2C_SwState_SUCCESS) ? I2C_Err_OK : I2C_Err_Fail; +} + +I2C_ErrTypeDef I2C_Slave_Receive(I2C_Type *pHI2C, uint8_t *pData, uint16_t *pSize, uint16_t Timeout_ms) +{ + uint16_t rx_nbytes = 0; + uint16_t buf_size = *pSize; + I2C_SwState rval = I2C_SwState_SUCCESS; + + if( (int)pHI2C == (int)I2C0 ) + sys_close_IRQ(I2C0_IRQn); + + if( pSize ) *pSize = 0; + + while( rx_nbytes < buf_size ) + { + if( _I2C_Wait_SI_Flag(pHI2C, Timeout_ms) != I2C_Err_OK ) + { + if( Timeout_ms == I2C_BLOCKING ) + continue; + + return I2C_Err_TimeOut; + } + + rval = _I2C_Slave_Recv_Byte(pHI2C, &pData, ((rx_nbytes + 1) == buf_size)); + if( rval == I2C_SwState_ERROR || rval == I2C_SwState_FORCE_STOP ) + { + break; + } + + rx_nbytes = (rval == I2C_SwState_SUCCESS) ? rx_nbytes + 1 : rx_nbytes; + } + + if( pSize ) *pSize = rx_nbytes; + + return (rval == I2C_SwState_SUCCESS) ? I2C_Err_OK : I2C_Err_Fail; +} + +I2C_ErrTypeDef I2C_Master_Transmit_IT(I2C_IT_HandleTypeDef *pHITI2C, uint16_t DevAddr, uint8_t *pData, uint16_t Size) +{ + pHITI2C->XferMode = I2C_XferMode_Transmite; + pHITI2C->DevAddress = (uint8_t)DevAddr; + pHITI2C->pTxBuffPtr = pData; + pHITI2C->TxXferCount = Size; + + if( (int)pHITI2C->pHI2C == (int)I2C0 ) + sys_open_IRQ(I2C0_IRQn); + + REG_WRITE_MASK(pHITI2C->pHI2C->CTLSET, + I2C_CTLSET_STA_Msk | I2C_CTLSET_SI_Msk, + I2C_CTLSET_STA_Msk | I2C_CTLSET_SI_Msk); + + return I2C_Err_OK; +} + +I2C_ErrTypeDef I2C_Master_Receive_IT(I2C_IT_HandleTypeDef *pHITI2C, uint8_t DevAddr, uint8_t *pData, uint16_t Size) +{ + pHITI2C->XferMode = I2C_XferMode_Recevie; + pHITI2C->DevAddress = (uint8_t)DevAddr; + pHITI2C->pRxBuffPtr = pData; + pHITI2C->RxXferCount = Size; + + if( (int)pHITI2C->pHI2C == (int)I2C0 ) + sys_open_IRQ(I2C0_IRQn); + + REG_WRITE_MASK(pHITI2C->pHI2C->CTLSET, + I2C_CTLSET_STA_Msk | I2C_CTLSET_SI_Msk, + I2C_CTLSET_STA_Msk | I2C_CTLSET_SI_Msk); + + return I2C_Err_OK; +} + +I2C_ErrTypeDef I2C_Slave_Transmit_IT(I2C_IT_HandleTypeDef *pHITI2C, uint8_t *pData, uint16_t Size) +{ + pHITI2C->XferMode = I2C_XferMode_Transmite; + pHITI2C->pTxBuffPtr = pData; + pHITI2C->TxXferCount = Size; + + _I2C_SET_SI_FLAG(pHITI2C->pHI2C); + if( (int)pHITI2C->pHI2C == (int)I2C0 ) + sys_open_IRQ(I2C0_IRQn); + + return I2C_Err_OK; +} + +I2C_ErrTypeDef I2C_Slave_Receive_IT(I2C_IT_HandleTypeDef *pHITI2C, uint8_t *pData, uint16_t Size) +{ + pHITI2C->XferMode = I2C_XferMode_Recevie; + pHITI2C->pRxBuffPtr = pData; + pHITI2C->RxXferCount = Size; + + _I2C_SET_SI_FLAG(pHITI2C->pHI2C); + if( (int)pHITI2C->pHI2C == (int)I2C0 ) + sys_open_IRQ(I2C0_IRQn); + + return I2C_Err_OK; +} + +void I2C_Master_IRQHandler(I2C_IT_HandleTypeDef *pHITI2C) +{ + I2C_SwState rval = I2C_SwState_SUCCESS; + + if( pHITI2C->XferMode == I2C_XferMode_Transmite ) + { + if( pHITI2C->DevAddress & 0x8000 ) + { + // xfer data stage, if pHITI2C->TxXferCount == 0, I2C should send STOP-bit + rval = _I2C_Master_Send_Byte(pHITI2C->pHI2C, &pHITI2C->pTxBuffPtr, (pHITI2C->TxXferCount) ? false : true); + if( rval == I2C_SwState_SUCCESS ) + pHITI2C->TxXferCount--; + + if( pHITI2C->TxXferCount == 0xFFFF ) + { + pHITI2C->XferMode = I2C_XferMode_Idle; + } + } + else + { + uint8_t *pAddr = 0; + + pHITI2C->DevAddress &= ~0x1u; // write mode + + pAddr = (uint8_t*)&pHITI2C->DevAddress; + rval = _I2C_Master_Send_Byte(pHITI2C->pHI2C, &pAddr, false); + if( rval == I2C_SwState_SUCCESS ) + pHITI2C->DevAddress |= 0x8000; + } + } + else if( pHITI2C->XferMode == I2C_XferMode_Recevie ) + { + if( pHITI2C->DevAddress & 0x8000 ) + { + rval = _I2C_Master_Recv_Byte(pHITI2C->pHI2C, &pHITI2C->pRxBuffPtr, (pHITI2C->RxXferCount - 2) ? false : true); + if( rval == I2C_SwState_SUCCESS ) + pHITI2C->RxXferCount--; + + if( pHITI2C->RxXferCount == 0 ) + { + pHITI2C->XferMode = I2C_XferMode_Idle; + } + } + else + { + uint8_t *pAddr = 0; + + pHITI2C->DevAddress |= 0x1u; // read mode + + pAddr = (uint8_t*)&pHITI2C->DevAddress; + rval = _I2C_Master_Recv_Byte(pHITI2C->pHI2C, &pAddr, false); + if( rval == I2C_SwState_SUCCESS ) + { + pHITI2C->DevAddress |= 0x8000; + + /** + * send DevAddr+R and then receive data + * ps. Decrease the DevAddr+R byte + */ + pHITI2C->RxXferCount++; + } + } + } + + return; +} + +void I2C_Slave_IRQHandler(I2C_IT_HandleTypeDef *pHITI2C) +{ + I2C_SwState rval = I2C_SwState_SUCCESS; + + if( pHITI2C->XferMode == I2C_XferMode_Transmite ) + { + bool HasRecvAddr = false; + + // xfer data stage, if pHITI2C->TxXferCount == 0, I2C should send STOP-bit + rval = _I2C_Slave_Send_Byte(pHITI2C->pHI2C, &pHITI2C->pTxBuffPtr, &HasRecvAddr, (pHITI2C->TxXferCount) ? false : true); + pHITI2C->TxXferCount = (rval == I2C_SwState_SUCCESS) ? pHITI2C->TxXferCount - 1 : + (rval == I2C_SwState_FORCE_STOP) ? 0xFFFF : + pHITI2C->TxXferCount; + + if( pHITI2C->TxXferCount == 0xFFFF ) + { + pHITI2C->XferMode = I2C_XferMode_Idle; + } + } + else if( pHITI2C->XferMode == I2C_XferMode_Recevie ) + { + rval = _I2C_Slave_Recv_Byte(pHITI2C->pHI2C, &pHITI2C->pRxBuffPtr, (pHITI2C->RxXferCount == 2)); + + pHITI2C->RxXferCount = (rval == I2C_SwState_SUCCESS) ? pHITI2C->RxXferCount - 1 : + (rval == I2C_SwState_FORCE_STOP) ? 0 : + pHITI2C->RxXferCount; + + if( pHITI2C->RxXferCount == 0 ) + { + pHITI2C->XferMode = I2C_XferMode_Idle; + } + } + + return; +} + +#endif /* CONFIG_ENABLE_HAL_I2C */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_lptim.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_lptim.c new file mode 100644 index 0000000..4024828 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_lptim.c @@ -0,0 +1,145 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_lptim.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + + +#include "hal_device.h" + +#if defined(CONFIG_ENABLE_HAL_LPTIM) || defined(CONFIG_ENABLE_HAL_TIM0) || defined(CONFIG_ENABLE_HAL_TIM1) + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +void LPTIM_StructInit(LPTIM_InitTypeDef *pInit) +{ + pInit->LPTIM_Prescaler = 0; + pInit->LPTIM_ClockSource = LPTIM_CLK_Src_SysClk; + pInit->LPTIM_MatchMode = LPTIM_MatchMode_Normal; + pInit->LPTIM_MatchValue = 0; + + return; +} + + +void LPTIM_Init(LPTIM_Type *pHLpTim, LPTIM_InitTypeDef *pInit) +{ + if( pHLpTim == LPTIM ) + { + sys_close_IRQ(LPTIM_IRQn); + + __HAL_SYSCFG_RESET_LPTIM(); + __HAL_SYSCFG_LPTIM_CLK_ENABLE(); + + REG_WRITE_MASK(pHLpTim->TCR, LPTIM_TCR_CLKS_Msk, pInit->LPTIM_ClockSource); + } + else if( pHLpTim == TIM0 ) + { + sys_close_IRQ(TIM0_IRQn); + + __HAL_SYSCFG_RESET_TIM0(); + __HAL_SYSCFG_TIM0_CLK_ENABLE(); + } + else if( pHLpTim == TIM1 ) + { + sys_close_IRQ(TIM1_IRQn); + + __HAL_SYSCFG_RESET_TIM1(); + __HAL_SYSCFG_TIM1_CLK_ENABLE(); + } + + REG_SET_BITS(pHLpTim->IR, LPTIM_IR_MR0_Msk); + REG_SET_BITS(pHLpTim->TCR, LPTIM_TCR_CRST_Msk); + + pHLpTim->PR = pInit->LPTIM_Prescaler; + pHLpTim->MCR = pInit->LPTIM_MatchMode; + pHLpTim->MR0 = pInit->LPTIM_MatchValue; + + return; +} + + +void LPTIM_DeInit(LPTIM_Type *pHLpTim) +{ + REG_SET_BITS(pHLpTim->TCR, LPTIM_TCR_CRST_Msk); + + if( pHLpTim == LPTIM ) + { + __HAL_SYSCFG_LPTIM_CLK_DISABLE(); + __HAL_SYSCFG_RESET_LPTIM(); + + sys_close_IRQ(LPTIM_IRQn); + } + else if( pHLpTim == TIM0 ) + { + __HAL_SYSCFG_TIM1_CLK_DISABLE(); + __HAL_SYSCFG_RESET_TIM0(); + + sys_close_IRQ(TIM0_IRQn); + } + else if( pHLpTim == TIM1 ) + { + __HAL_SYSCFG_TIM1_CLK_DISABLE(); + __HAL_SYSCFG_RESET_TIM1(); + + sys_close_IRQ(TIM1_IRQn); + } + + return; +} + + +void LPTIM_ITConfig(LPTIM_Type *pHLpTim, int has_enable) +{ + if( pHLpTim == LPTIM ) + { + (has_enable) + ? sys_open_IRQ(LPTIM_IRQn) + : sys_close_IRQ(LPTIM_IRQn); + } + else if( pHLpTim == TIM0 ) + { + (has_enable) + ? sys_open_IRQ(TIM0_IRQn) + : sys_close_IRQ(TIM0_IRQn); + } + else if( pHLpTim == TIM1 ) + { + (has_enable) + ? sys_open_IRQ(TIM1_IRQn) + : sys_close_IRQ(TIM1_IRQn); + } + + return; +} + + + +#endif /* CONFIG_ENABLE_HAL_LPTIM || CONFIG_ENABLE_HAL_TIM0 || CONFIG_ENABLE_HAL_TIM1 */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_opamp.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_opamp.c new file mode 100644 index 0000000..482e971 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_opamp.c @@ -0,0 +1,74 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_opamp.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/12/05 + * @license + * @description + */ + + +#include "hal_device.h" + +#if defined(CONFIG_ENABLE_HAL_OPAMP) + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int OPAMP_Init(OPAMP_Type *pHOPAmp, OPAMP_InitTypeDef *pInit) +{ + AMISC_Init(); + + REG_WRITE_MASK(pHOPAmp->PGA_CR, + OPAMP_PGA_CR_PGA_VIP_SEL_Msk | OPAMP_PGA_CR_PGA_VIN_SEL_Msk | \ + OPAMP_PGA_CR_PGA_IO_EN_Msk | OPAMP_PGA_CR_PGA_GAIN_Msk, + pInit->OPAMP_VinP | pInit->OPAMP_VinM | pInit->OPAMP_Vout | pInit->OPAMP_Gain); + return 0; +} + +void OPAMP_DeInit(OPAMP_Type *pHOPAmp) +{ + OPAMP_Disable(pHOPAmp); + + REG_WRITE_MASK(pHOPAmp->PGA_CR, + OPAMP_PGA_CR_PGA_VIP_SEL_Msk | OPAMP_PGA_CR_PGA_VIN_SEL_Msk | \ + OPAMP_PGA_CR_PGA_IO_EN_Msk | OPAMP_PGA_CR_PGA_GAIN_Msk, + OPAMP_VinP_Internal | OPAMP_VinM_GND | OPAMP_Vout_None | OPAMP_PGAGain_1); + + AMISC_DeInit(false); + return; +} + +void OPAMP_StructInit(OPAMP_InitTypeDef *pInit) +{ + pInit->OPAMP_VinP = OPAMP_VinP_Internal; + pInit->OPAMP_VinM = OPAMP_VinM_GND; + pInit->OPAMP_Vout = OPAMP_Vout_None; + pInit->OPAMP_Gain = OPAMP_PGAGain_1; + return; +} + +#endif /* CONFIG_ENABLE_HAL_OPAMP */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_pwr.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_pwr.c new file mode 100644 index 0000000..ef9d377 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_pwr.c @@ -0,0 +1,115 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_pwr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + + +#include "hal_device.h" + +#if defined(CONFIG_ENABLE_HAL_PWR) + +//============================================================================= +// Constant Definition +//============================================================================= +#if 1 + #define __PWR_WAIT_RECHARGE() do{ __NOP(); __NOP(); __NOP(); __NOP(); \ + }while(0) +#else + #define __PWR_WAIT_RECHARGE() +#endif +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +void PWR_EnterSleepMode(CallbaskPreSleepTypeDef cb_pre_set, + CallbaskPostSleepTypeDef cb_post_set) +{ + int wakeup_type = 0; + + sys_disable_girq(); + + if( cb_pre_set ) + cb_pre_set(PWR_Mode_Sleep, (PWR_WakeupTypeDef*)&wakeup_type); + + __HAL_SYSCFG_AMISC_CLK_ENABLE(); + + AMISC_SetHSIPwrSrc(AMISC_HSIPwrSrc_LowPower); + + REG_WRITE(AMISC->DAC_CR, 0x0ul); // Off DAC leakage + + __set_wfi_sleepmode(WFI_SHALLOW_SLEEP); + + __WFI(); + /* __PWR_WAIT_RECHARGE(); */ + + if( cb_post_set ) + cb_post_set(PWR_Mode_Sleep); + + sys_enable_girq(); + + return; +} + + +void PWR_EnterDeepSleepMode(CallbaskPreSleepTypeDef cb_pre_set, + CallbaskPostSleepTypeDef cb_post_set) +{ + int wakeup_type = 0; + + sys_disable_girq(); + + if( cb_pre_set ) + cb_pre_set(PWR_Mode_DeepSleep, (PWR_WakeupTypeDef*)&wakeup_type); + + __HAL_SYSCFG_AMISC_CLK_ENABLE(); + + AMISC_SetHSIPwrSrc(AMISC_HSIPwrSrc_LowPower); + + REG_WRITE(AMISC->DAC_CR, 0x0ul); // Off DAC leakage + + SYSCFG_SetLowPower(true); + + /* Judge wakeup trigger */ + (wakeup_type & PWR_Wakeup_LpTIM) ? sys_open_IRQ(LPTIM_IRQn) : sys_close_IRQ(LPTIM_IRQn); + (wakeup_type & PWR_Wakeup_WDG) ? sys_open_IRQ(WDG_IRQn) : sys_close_IRQ(WDG_IRQn); + (wakeup_type & PWR_Wakeup_IO_PORT_A) ? sys_open_IRQ(GPIOA_IRQn) : sys_close_IRQ(GPIOA_IRQn); + (wakeup_type & PWR_Wakeup_IO_PORT_B) ? sys_open_IRQ(GPIOB_IRQn) : sys_close_IRQ(GPIOB_IRQn); + + __set_wfi_sleepmode(WFI_DEEP_SLEEP); + + __WFI(); + __PWR_WAIT_RECHARGE(); + + SYSCFG_SetLowPower(false); + + if( cb_post_set ) + cb_post_set(PWR_Mode_DeepSleep); + + sys_enable_girq(); + + return; +} + +#endif /* CONFIG_ENABLE_HAL_PMU */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_spi.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_spi.c new file mode 100644 index 0000000..9e593d5 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_spi.c @@ -0,0 +1,381 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_spi.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + + +#include "hal_device.h" + +#if defined(CONFIG_ENABLE_HAL_SPI) + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +/** + * @brief Deinitializes the spi peripheral registers to their + * default reset values. + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @retval None. + */ +void SPI_DeInit(SPI_Type *spi) +{ + if (spi == SPI0) + { + __HAL_SYSCFG_RESET_SPI(); + } +} + +/** + * @brief Fills each init_struct member with its default value. + * @param init_struct: pointer to a SPI_InitTypeDef structure + * which will be initialized. + * @retval None. + */ +void SPI_StructInit(SPI_InitTypeDef *init_struct) +{ + init_struct->SPI_Mode = SPI_Mode_Master; + init_struct->SPI_CPOL = SPI_CPOL_Low; + init_struct->SPI_CPHA = SPI_CPHA_Effective; + init_struct->SPI_TxDataSize = SPI_TxDataSize_8b; + init_struct->SPI_BaudRatePrescaler = SPI_BaudratePrescaler_256; + init_struct->SPI_FirstBit = SPI_FirstBit_MSB; +} + +/** + * @brief Initializes the spi peripheral according to the specified + * parameters in the init_struct . + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param init_struct: pointer to a SPI_InitTypeDef structure + * that contains the configuration information for the + * specified SPI peripheral. + * @retval None. + */ +void SPI_Init(SPI_Type *spi, SPI_InitTypeDef *init_struct) +{ + + __HAL_SYSCFG_SPI_CLK_ENABLE(); + + REG_WRITE_MASK(spi->CFG, SPI_CFG_MODE_Msk, (init_struct->SPI_Mode << SPI_CFG_MODE_Pos)); + REG_WRITE_MASK(spi->CFG, SPI_CFG_CPOL_Msk, (init_struct->SPI_CPOL << SPI_CFG_CPOL_Pos)); + REG_WRITE_MASK(spi->CFG, SPI_CFG_CPHA_Msk, (init_struct->SPI_CPHA << SPI_CFG_CPHA_Pos)); + REG_WRITE_MASK(spi->CFG, SPI_CFG_TXWDSZ_Msk, (init_struct->SPI_TxDataSize << SPI_CFG_TXWDSZ_Pos)); + REG_WRITE_MASK(spi->CFG, SPI_CFG_DB_Msk, (init_struct->SPI_BaudRatePrescaler << SPI_CFG_DB_Pos)); + REG_WRITE_MASK(spi->CFG, SPI_CFG_LSB_Msk, (init_struct->SPI_FirstBit << SPI_CFG_LSB_Pos)); +} + +/** + * @brief Enables or disables the specified SPI peripheral. + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param state: new state of the spi peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void SPI_Enable(SPI_Type *spi) +{ + REG_SET_BITS(spi->EN, SPI_EN_EN_Msk); +} + +void SPI_Disable(SPI_Type *spi) +{ + REG_CLR_BITS(spi->EN, SPI_EN_EN_Msk); +} + + +void SPI_MasterEnable(SPI_Type *spi) +{ + REG_SET_BITS(spi->CFG, SPI_CFG_MODE_Msk); +} + +void SPI_SlaveEnable(SPI_Type *spi) +{ + REG_CLR_BITS(spi->CFG, SPI_CFG_MODE_Msk); +} + +/** + * @brief Transmits a Data through the spi peripheral. + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param data : Data to be transmitted. + * @retval None. + */ +void SPI_SendData(SPI_Type *spi, uint32_t data) +{ + spi->TX = data; +} + +/** + * @brief Returns the most recent received data by the spi peripheral. + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @retval The value of the received data. + */ +uint32_t SPI_ReceiveData(SPI_Type *spi) +{ + return (spi->RX); +} + +/** + * @brief Set the clock divide + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param baudrate: the clcok divide value + * @retval None. + */ +void SPI_SetBaudRatePrescaler(SPI_Type *spi, SPI_DBTypedef spi_baudrateprescaler) +{ + REG_WRITE_MASK(spi->CFG, SPI_CFG_DB_Msk, (spi_baudrateprescaler << SPI_CFG_DB_Pos)); +} + +/** + * @brief Configures the CS pin control select for the selected SPI. + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param nss: specifies the SPI NSS internal state. + * This parameter can be one of the following values: + * @arg SPI_SSOUT_Selected: CS pin is low + * @arg SPI_SSOUT_NoSelected: CS pin is high + * @retval None. + */ +void SPI_SetSSOUT(SPI_Type *spi, uint32_t ss_out_value) +{ + REG_WRITE_MASK(spi->CFG, SPI_CFG_SS_OUT_Msk, (ss_out_value << SPI_CFG_SS_OUT_Pos)); +} + +/** + * @brief Configures the CS pin manual select enable for the selected SPI. + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param mcs_value: CS manual select enable + * @retval None. + */ +void SPI_SetManualChipSelect(SPI_Type *spi, uint32_t mcs_value) +{ + REG_WRITE_MASK(spi->CFG, SPI_CFG_MCS_Msk, (mcs_value << SPI_CFG_MCS_Pos)); +} + +/** + * @brief Configures the manual mode for the selected SPI. + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param mce_en: Manual mode enable or disable + * @retval None. + */ +void SPI_SetManualMode(SPI_Type *spi, uint32_t mce_en) +{ + REG_WRITE_MASK(spi->CFG, SPI_CFG_MSE_Msk, (mce_en << SPI_CFG_MSE_Pos)); +} + +/** + * @brief Configures the manual send data for the selected SPI. + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @retval None. + */ +void SPI_ManualModeStart(SPI_Type *spi) +{ + REG_SET_BITS(spi->CFG, SPI_CFG_MSTC_Msk); +} +/** + * @brief Configures the data size for the selected SPI. + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param datasize_value: specifies the SPI data size. + * @retval None. + * @retval None. + */ +void SPI_SetTxDataSize(SPI_Type *spi, SPI_TXDataSizeTypedef datasize_value) +{ + REG_WRITE_MASK(spi->CFG, SPI_CFG_TXWDSZ_Msk, (datasize_value << SPI_CFG_TXWDSZ_Pos)); +} + +/** + * @brief Get interrupt status + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param flag: selects the position of the interrupt flag + * @arg SPI_RECVOV_Flag + * @arg SPI_MDF_Flag + * @arg SPI_TXNFUL_Flag + * @arg SPI_TXFUL_Flag + * @arg SPI_RXNEP_Flag + * @arg SPI_RXFUL_Flag + * @arg SPI_TXUFL_Flag + * @arg SPI_BUSY_Flag + * @retval indicate the interrupt flag is set or reset + */ +uint32_t SPI_GetInterruptStatus(SPI_Type *spi, uint32_t flag) +{ + return ((spi->STA & flag) ? 1 : 0); +} + +/** + * @brief Get interrupt flag status + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param flag: selects the position of the interrupt flag + * @retval indicate the interrupt flag is set or reset + */ +uint32_t SPI_GetFlagStatus(SPI_Type *spi, uint32_t flag) +{ + return ((spi->STA & flag) ? 1 : 0); +} + +/** + * @brief Clear interrupt flag + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param flag: selects the position of the interrupt flag + * only for RECVOV,MDF,TXUFL + * @retval write 1 to clear the interrupt flag + */ +void SPI_ClearFlagStatus(SPI_Type *spi, uint32_t flag) +{ + REG_SET_BITS(spi->STA, flag); +} + +/** + * @brief Set interrupt bit enable + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param interrupt: specifies the SPI interrupt source to enable. + * @retval None + */ +void SPI_SetInterrupt(SPI_Type *spi, uint32_t flag) +{ + REG_SET_BITS(spi->INTEN, flag); +} + +/** + * @brief Set interrupt bit disable + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param interrupt: specifies the SPI interrupt source to disable. + * @retval None + */ +void SPI_SetInterruptDisable(SPI_Type *spi, uint32_t flag) +{ + REG_SET_BITS(spi->INTDIS, flag); +} +/** + * @brief Config the delay of spi transmit. + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param delay_set: the delay value to set + * @retval None. + */ +void SPI_SetDelay(SPI_Type *spi, SPI_DelayTypeDef * delay_set) +{ + REG_WRITE_MASK(spi->DELAY, SPI_DELAY_d_int_Msk, (delay_set->d_int << SPI_DELAY_d_int_Pos)); + REG_WRITE_MASK(spi->DELAY, SPI_DELAY_d_affter_Msk, (delay_set->d_after << SPI_DELAY_d_affter_Pos)); + REG_WRITE_MASK(spi->DELAY, SPI_DELAY_d_btwn_Msk, (delay_set->d_btwn << SPI_DELAY_d_btwn_Pos)); + REG_WRITE_MASK(spi->DELAY, SPI_DELAY_d_nss_Msk, (delay_set->d_nss << SPI_DELAY_d_nss_Pos)); + +} + +/** + * @brief Set the idle time of the slaver device + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param idle_cnt: the idle time in slave mode + * @retval None. + */ +void SPI_SetIdleCnt(SPI_Type *spi, uint32_t idle_cnt) +{ + spi->IDLECNT = idle_cnt; +} + +/** + * @brief Transmits a Data through the spi peripheral. + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param data : Data to be transmitted by manual mode. + * @retval None. + */ +void SPI_ManualSendData(SPI_Type *spi, uint32_t data) +{ + spi->TX = data; + + SPI_ManualModeStart(spi); +} + + + +/** + * @brief Set the send fifo threshold + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param txth: the value of send fifo threshold + * @retval None. + */ +void SPI_SetTXTH(SPI_Type *spi, uint32_t txth) +{ + spi->TXTH = txth; +} + +/** + * @brief Set the receive fifo threshold + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param txth: the value of receive fifo threshold + * @retval None. + */ +void SPI_SetRXTH(SPI_Type *spi, uint32_t rxth) +{ + spi->RXTH = rxth; +} + + + +#endif /* CONFIG_ENABLE_HAL_SPI */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_syscfg.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_syscfg.c new file mode 100644 index 0000000..6d877d8 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_syscfg.c @@ -0,0 +1,103 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_rcc.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + + +#include "hal_device.h" + +#if defined(CONFIG_ENABLE_HAL_SYSCFG) + +//============================================================================= +// Constant Definition +//============================================================================= +#define SYSCFG_RST_FLAGS_ALL (SYSCFG_SYSRSTSR_SWRST_Msk | SYSCFG_SYSRSTSR_WDGRST_Msk | \ + SYSCFG_SYSRSTSR_LOCKUPRST_Msk | SYSCFG_SYSRSTSR_PORRST_Msk | \ + SYSCFG_SYSRSTSR_PADRST_Msk | SYSCFG_SYSRSTSR_LVDRST_Msk | \ + SYSCFG_SYSRSTSR_REBOOTRST_Msk) + +#define SYSCFG_AUTHKEY_REBOOT_UNLOCK 0xAB56 + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +void SYSCFG_SysClkConfig(SYSCFG_ClkInitTypeDef *pInit) +{ + REG_WRITE_MASK(SYSCFG->SYSCLKCR, + (SYSCFG_SYSCLKCR_CLKSW_Msk | SYSCFG_SYSCLKCR_CLKDIV_Msk), + (pInit->ClkSource | pInit->SysClk_Div)); + + SYSCFG_SetSysTickSrc(pInit->SysTickSrc); + + g_SystemCoreClock = sys_get_cpu_freq(); + return; +} + +int SYSCFG_GetFlagStatus(SYSCFG_FlagTypeDef flag) +{ + uint32_t status = 0; + uint32_t mask = (flag == SYSCFG_FLAG_ALL) + ? SYSCFG_FLAGS_TYPE_Msk + : (uint32_t)1ul << (flag & SYSCFG_FLAGS_TYPE_Msk); + + status = REG_READ(SYSCFG->SYSRSTSR); + + return (status & mask); +} + + +void SYSCFG_ClearFlags(SYSCFG_FlagTypeDef flag) +{ + uint32_t shift = flag & SYSCFG_FLAGS_TYPE_Msk; + + (shift == SYSCFG_FLAGS_TYPE_Msk) + ? REG_SET_BITS(SYSCFG->SYSRSTSR, SYSCFG_RST_FLAGS_ALL) + : REG_SET_BITS(SYSCFG->SYSRSTSR, ((uint32_t)1ul << shift)); + + return; +} + +void SYSCFG_RebootLetch(void) +{ + REG_WRITE(SYSCFG->REBOOT_UNLOCK, SYSCFG_AUTHKEY_REBOOT_UNLOCK); + REG_SET_BITS(SYSCFG->SYSRSTCR, SYSCFG_SYSRSTCR_REBOOTEN_Msk); + + while(1); + return; +} + +void SYSCFG_SetICEPin2NormalIO(int is_enable) +{ + (is_enable) + ? REG_WRITE(SYSCFG->ICEIOCR, 0xE653ul << SYSCFG_ICEIOCR_AUTHKEY_Pos) + : REG_WRITE(SYSCFG->ICEIOCR, + (0xE653ul << SYSCFG_ICEIOCR_AUTHKEY_Pos) | \ + SYSCFG_ICEIOCR_JTAGIOEN_Msk | SYSCFG_ICEIOCR_DBG_CTRL_EN_Msk | SYSCFG_ICEIOCR_DBG_EN_Msk); + return; +} + + +#endif /* CONFIG_ENABLE_HAL_RCC */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_tim.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_tim.c new file mode 100644 index 0000000..f278fb6 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_tim.c @@ -0,0 +1,1647 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_timer.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + + +#include "hal_device.h" + +#if defined(CONFIG_ENABLE_HAL_TIM2) || defined(CONFIG_ENABLE_HAL_EPWM) + +//============================================================================= +// Constant Definition +//============================================================================= +#define SMCR_ETR_Mask ((uint16_t)0x00FF) +#define CCMR_Offset ((uint16_t)0x0018) +#define CCER_CCE_Set ((uint16_t)0x0001) +#define CCER_CCNE_Set ((uint16_t)0x0004) +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +/** + * @brief Deinitializes the tim peripheral registers to their default reset values. + * @param tim: select the TIM peripheral. + * @retval None. + */ +void TIM_DeInit(TIM_Type *tim) +{ + if (tim == TIM2) + { + __HAL_SYSCFG_RESET_TIM2(); + } + else if (tim == EPWM) + { + __HAL_SYSCFG_RESET_EPWM(); + } + return; +} + +/** + * @brief Fills each init_struct member with its default value. + * @param init_struct : pointer to a TIM_TimeBaseInitTypeDef + * structure which will be initialized. + * @retval None. + */ +void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef *init_struct) +{ + init_struct->TIM_Period = 0xFFFFFFFF; + init_struct->TIM_Prescaler = 0x0000; + init_struct->TIM_ClockDivision = TIM_CKD_Div1; + init_struct->TIM_CounterMode = TIM_CounterMode_Up; + init_struct->TIM_RepetitionCounter = 0x00; +} + +/** + * @brief Initializes the tim Time Base Unit peripheral according to + * the specified parameters in the init_struct. + * @param tim: select the TIM peripheral. + * @param init_struct: pointer to a TIM_TimeBaseInitTypeDef + * structure that contains the configuration information for the + * specified TIM peripheral. + * @retval None. + */ +void TIM_TimeBaseInit(TIM_Type *tim, TIM_TimeBaseInitTypeDef *init_struct) +{ + if (tim == TIM2) + { + __HAL_SYSCFG_TIM2_CLK_ENABLE(); + } + else if (tim == EPWM) + { + __HAL_SYSCFG_EPWM_CLK_ENABLE(); + } + REG_WRITE_MASK(tim->CR1, TIM_CR1_CKD_Msk, init_struct->TIM_ClockDivision); + REG_WRITE_MASK(tim->CR1, TIM_CR1_CMS_Msk | TIM_CR1_DIR_Msk, init_struct->TIM_CounterMode); + REG_WRITE_MASK(tim->RCR, TIM_RCR_REP_Msk, init_struct->TIM_RepetitionCounter); + + tim->ARR = init_struct->TIM_Period; + tim->PSC = init_struct->TIM_Prescaler; + + tim->EGR = TIM_PSCReloadMode_Immediate; +} + +/** + * @brief Fills each init_struct member with its default value. + * @param init_struct : pointer to a TIM_OCInitTypeDef structure which will be initialized. + * @retval None. + */ +void TIM_OCStructInit(TIM_OCInitTypeDef *init_struct) +{ + init_struct->TIM_OCMode = TIM_OCMode_Timing; + init_struct->TIM_OutputState = TIM_OutputState_Disable; + init_struct->TIM_OutputNState = TIM_OutputNState_Disable; + init_struct->TIM_Pulse = 0x00000000; + init_struct->TIM_OCPolarity = TIM_OCPolarity_High; + init_struct->TIM_OCNPolarity = TIM_OCNPolarity_High; + init_struct->TIM_OCIdleState = TIM_OCIdleState_Reset; + init_struct->TIM_OCNIdleState = TIM_OCNIdleState_Reset; +} + +/** + * @brief Initializes the tim Channel1 according to the specified + * parameters in the init_struct. + * @param tim: select the TIM peripheral. + * @param init_struct: pointer to a TIM_OCInitTypeDef structure that + * contains the configuration information for the specified TIM peripheral. + * @retval None. + */ +void TIM_OC1Init(TIM_Type *tim, TIM_OCInitTypeDef *init_struct) +{ + REG_WRITE_MASK(tim->CCMR1_OUTPUT, TIM_CCMR1_OUTPUT_OC1M_Msk, init_struct->TIM_OCMode << TIM_CCMR1_OUTPUT_OC1M_Pos); + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC1E_Msk, init_struct->TIM_OutputState << TIM_CCER_CC1E_Pos); + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC1P_Msk, init_struct->TIM_OCPolarity << TIM_CCER_CC1P_Pos); + + tim->CCR1 = init_struct->TIM_Pulse; + + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC1NE_Msk, init_struct->TIM_OutputNState << TIM_CCER_CC1NE_Pos); + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC1NP_Msk, init_struct->TIM_OCNPolarity << TIM_CCER_CC1NP_Pos); + + REG_WRITE_MASK(tim->CR2, TIM_CR2_OIS1_Msk, init_struct->TIM_OCIdleState << TIM_CR2_OIS1_Pos); + REG_WRITE_MASK(tim->CR2, TIM_CR2_OIS1N_Msk, init_struct->TIM_OCNIdleState << TIM_CR2_OIS1N_Pos); + +} + +/** + * @brief Initializes the tim Channel2 according to the specified + * parameters in the init_struct. + * @param tim: select the TIM peripheral. + * @param init_struct: pointer to a TIM_OCInitTypeDef structure that + * contains the configuration information for the specified TIM peripheral. + * @retval None. + */ +void TIM_OC2Init(TIM_Type *tim, TIM_OCInitTypeDef *init_struct) +{ + REG_WRITE_MASK(tim->CCMR1_OUTPUT, TIM_CCMR1_OUTPUT_OC2M_Msk, init_struct->TIM_OCMode << TIM_CCMR1_OUTPUT_OC2M_Pos); + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC2E_Msk, init_struct->TIM_OutputState << TIM_CCER_CC2E_Pos); + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC2P_Msk, init_struct->TIM_OCPolarity << TIM_CCER_CC2P_Pos); + + tim->CCR2 = init_struct->TIM_Pulse; + + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC2NE_Msk, init_struct->TIM_OutputNState << TIM_CCER_CC2NE_Pos); + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC2NP_Msk, init_struct->TIM_OCNPolarity << TIM_CCER_CC2NP_Pos); + + REG_WRITE_MASK(tim->CR2, TIM_CR2_OIS2_Msk, init_struct->TIM_OCIdleState << TIM_CR2_OIS2_Pos); + REG_WRITE_MASK(tim->CR2, TIM_CR2_OIS2N_Msk, init_struct->TIM_OCNIdleState << TIM_CR2_OIS2N_Pos); + +} + +/** + * @brief Initializes the tim Channel3 according to the specified + * parameters in the init_struct. + * @param tim: select the TIM peripheral. + * @param init_struct: pointer to a TIM_OCInitTypeDef structure that + * contains the configuration information for the specified TIM peripheral. + * @retval None. + */ +void TIM_OC3Init(TIM_Type *tim, TIM_OCInitTypeDef *init_struct) +{ + REG_WRITE_MASK(tim->CCMR2_OUTPUT, TIM_CCMR2_OUTPUT_OC3M_Msk, init_struct->TIM_OCMode << TIM_CCMR2_OUTPUT_OC3M_Pos); + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC3E_Msk, init_struct->TIM_OutputState << TIM_CCER_CC3E_Pos); + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC3P_Msk, init_struct->TIM_OCPolarity << TIM_CCER_CC3P_Pos); + + tim->CCR3 = init_struct->TIM_Pulse; + + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC3NE_Msk, init_struct->TIM_OutputNState << TIM_CCER_CC3NE_Pos); + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC3NP_Msk, init_struct->TIM_OCNPolarity << TIM_CCER_CC3NP_Pos); + + REG_WRITE_MASK(tim->CR2, TIM_CR2_OIS3_Msk, init_struct->TIM_OCIdleState << TIM_CR2_OIS3_Pos); + REG_WRITE_MASK(tim->CR2, TIM_CR2_OIS3N_Msk, init_struct->TIM_OCNIdleState << TIM_CR2_OIS3N_Pos); + +} + +/** + * @brief Initializes the tim Channel4 according to the specified + * parameters in the init_struct. + * @param tim:select the TIM peripheral. + * @param init_struct: pointer to a TIM_OCInitTypeDef structure that + * contains the configuration information for the specified TIM peripheral. + * @retval None. + */ +void TIM_OC4Init(TIM_Type *tim, TIM_OCInitTypeDef *init_struct) +{ + REG_WRITE_MASK(tim->CCMR2_OUTPUT, TIM_CCMR2_OUTPUT_OC4M_Msk, init_struct->TIM_OCMode << TIM_CCMR2_OUTPUT_OC4M_Pos); + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC4E_Msk, init_struct->TIM_OutputState << TIM_CCER_CC4E_Pos); + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC4P_Msk, init_struct->TIM_OCPolarity << TIM_CCER_CC4P_Pos); + + tim->CCR4 = init_struct->TIM_Pulse; + + REG_WRITE_MASK(tim->CR2, TIM_CR2_OIS4_Msk, init_struct->TIM_OCIdleState << TIM_CR2_OIS4_Pos); + +} + +/** + * @brief Configure the TI1 as Input. + * @param tim: select the TIM peripheral. + * @param polarity : The Input Polarity. + * @arg TIM_ICPolarity_Rising + * @arg TIM_ICPolarity_Falling + * @arg TIM_ICPolarity_BothEdge + * @param selection: specifies the input to be used. + * @arg TIM_ICSelection_DirectTI: TIM Input 1 is selected to be connected to IC1. + * @arg TIM_ICSelection_IndirectTI: TIM Input 1 is selected to be connected to IC2. + * @arg TIM_ICSelection_TRC: TIM Input 1 is selected to be connected to TRC. + * @param filter: Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None. + */ +static void TI1_Configure(TIM_Type *tim, uint16_t polarity, uint16_t selection, uint16_t filter) +{ + REG_WRITE_MASK(tim->CCMR1_INPUT, TIM_CCMR1_INPUT_CC1S_Msk, selection << TIM_CCMR1_INPUT_CC1S_Pos); + REG_WRITE_MASK(tim->CCMR1_INPUT, TIM_CCMR1_INPUT_IC1F_Msk, filter << TIM_CCMR1_INPUT_IC1F_Pos); + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC1E_Msk | TIM_CCER_CC1P_Msk | TIM_CCER_CC1NP_Msk, polarity | TIM_CCER_CC1E_Msk); +} + +/** + * @brief Configure the TI2 as Input. + * @param tim: select the TIM peripheral. + * @param polarity : The Input Polarity. + * @arg TIM_ICPolarity_Rising + * @arg TIM_ICPolarity_Falling + * @arg TIM_ICPolarity_BothEdge + * @param selection: specifies the input to be used. + * @arg TIM_ICSelection_DirectTI: TIM Input 2 is selected to be connected to IC2. + * @arg TIM_ICSelection_IndirectTI: TIM Input 2 is selected to be connected to IC1. + * @arg TIM_ICSelection_TRC: TIM Input 2 is selected to be connected to TRC. + * @param filter: Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None. + */ +static void TI2_Configure(TIM_Type *tim, uint16_t polarity, uint16_t selection, uint16_t filter) +{ + REG_WRITE_MASK(tim->CCMR1_INPUT, TIM_CCMR1_INPUT_CC2S_Msk, selection << TIM_CCMR1_INPUT_CC2S_Pos); + REG_WRITE_MASK(tim->CCMR1_INPUT, TIM_CCMR1_INPUT_IC2F_Msk, filter << TIM_CCMR1_INPUT_IC2F_Pos); + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC2E_Msk | TIM_CCER_CC2P_Msk | TIM_CCER_CC2NP_Msk, (polarity << 4) | TIM_CCER_CC2E_Msk); +} + +/** + * @brief Configure the TI3 as Input. + * @param tim: select the TIM peripheral. + * @param polarity : The Input Polarity. + * @arg TIM_ICPolarity_Rising + * @arg TIM_ICPolarity_Falling + * @arg TIM_ICPolarity_BothEdge + * @param selection: specifies the input to be used. + * @arg TIM_ICSelection_DirectTI: TIM Input 3 is selected to be connected to IC3. + * @arg TIM_ICSelection_IndirectTI: TIM Input 3 is selected to be connected to IC4. + * @arg TIM_ICSelection_TRC: TIM Input 3 is selected to be connected to TRC. + * @param filter: Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None. + */ +static void TI3_Configure(TIM_Type *tim, uint16_t polarity, uint16_t selection, uint16_t filter) +{ + REG_WRITE_MASK(tim->CCMR2_INPUT, TIM_CCMR2_INPUT_CC3S_Msk, selection << TIM_CCMR2_INPUT_CC3S_Pos); + REG_WRITE_MASK(tim->CCMR2_INPUT, TIM_CCMR2_INPUT_IC3F_Msk, filter << TIM_CCMR2_INPUT_IC3F_Pos); + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC3E_Msk | TIM_CCER_CC3P_Msk | TIM_CCER_CC3NP_Msk, (polarity << 8) | TIM_CCER_CC3E_Msk); +} + +/** + * @brief Configure the TI4 as Input. + * @param tim: select the TIM peripheral. + * @param polarity : The Input Polarity. + * @arg TIM_ICPolarity_Rising + * @arg TIM_ICPolarity_Falling + * @arg TIM_ICPolarity_BothEdge + * @param selection: specifies the input to be used. + * @arg TIM_ICSelection_DirectTI: TIM Input 4 is selected to be connected to IC4. + * @arg TIM_ICSelection_IndirectTI: TIM Input 4 is selected to be connected to IC3. + * @arg TIM_ICSelection_TRC: TIM Input 4 is selected to be connected to TRC. + * @param filter: Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None. + */ +static void TI4_Configure(TIM_Type *tim, uint16_t polarity, uint16_t selection, uint16_t filter) +{ + REG_WRITE_MASK(tim->CCMR2_INPUT, TIM_CCMR2_INPUT_CC4S_Msk, selection << TIM_CCMR2_INPUT_CC4S_Pos); + REG_WRITE_MASK(tim->CCMR2_INPUT, TIM_CCMR2_INPUT_IC4F_Msk, filter << TIM_CCMR2_INPUT_IC4F_Pos); + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC4E_Msk | TIM_CCER_CC4P_Msk, (polarity << 12) | TIM_CCER_CC4E_Msk);// | TIM_CCER_CC4NP_Msk +} + +/** + * @brief Sets the tim Input Capture 1 prescaler. + * @param tim: select the TIM peripheral. + * @param psc: specifies the Input Capture1 prescaler new value. + * This parameter can be one of the following values: + * @arg TIM_ICPSC_Div1: no prescaler + * @arg TIM_ICPSC_Div2: capture is done once every 2 events + * @arg TIM_ICPSC_Div4: capture is done once every 4 events + * @arg TIM_ICPSC_Div8: capture is done once every 8 events + * @retval None. + */ +void TIM_SetIC1Prescaler(TIM_Type *tim, uint32_t psc) +{ + REG_WRITE_MASK(tim->CCMR1_INPUT, TIM_CCMR1_INPUT_IC1PSC_Msk, psc); +} + +/** + * @brief Sets the tim Input Capture 2 prescaler. + * @param tim: select the TIM peripheral. + * @param psc: specifies the Input Capture2 prescaler new value. + * This parameter can be one of the following values: + * @arg TIM_ICPSC_Div1: no prescaler + * @arg TIM_ICPSC_Div2: capture is done once every 2 events + * @arg TIM_ICPSC_Div4: capture is done once every 4 events + * @arg TIM_ICPSC_Div8: capture is done once every 8 events + * @retval None. + */ +void TIM_SetIC2Prescaler(TIM_Type *tim, uint32_t psc) +{ + REG_WRITE_MASK(tim->CCMR1_INPUT, TIM_CCMR1_INPUT_IC2PSC_Msk, psc << 8); +} + +/** + * @brief Sets the tim Input Capture 3 prescaler. + * @param tim: select the TIM peripheral. + * @param psc: specifies the Input Capture3 prescaler new value. + * This parameter can be one of the following values: + * @arg TIM_ICPSC_Div1: no prescaler + * @arg TIM_ICPSC_Div2: capture is done once every 2 events + * @arg TIM_ICPSC_Div4: capture is done once every 4 events + * @arg TIM_ICPSC_Div8: capture is done once every 8 events + * @retval None. + */ +void TIM_SetIC3Prescaler(TIM_Type *tim, uint32_t psc) +{ + REG_WRITE_MASK(tim->CCMR2_INPUT, TIM_CCMR2_INPUT_IC3PSC_Msk, psc); +} + +/** + * @brief Sets the tim Input Capture 4 prescaler. + * @param tim: select the TIM peripheral. + * @param psc: specifies the Input Capture4 prescaler new value. + * This parameter can be one of the following values: + * @arg TIM_ICPSC_Div1: no prescaler + * @arg TIM_ICPSC_Div2: capture is done once every 2 events + * @arg TIM_ICPSC_Div4: capture is done once every 4 events + * @arg TIM_ICPSC_Div8: capture is done once every 8 events + * @retval None. + */ +void TIM_SetIC4Prescaler(TIM_Type *tim, uint32_t psc) +{ + REG_WRITE_MASK(tim->CCMR2_INPUT, TIM_CCMR2_INPUT_IC4PSC_Msk, psc << 8); +} + +/** + * @brief Fills each init_struct member with its default value. + * @param init_struct: pointer to a TIM_ICInitTypeDef structure which will + * be initialized. + * @retval None. + */ +void TIM_ICStructInit(TIM_ICInitTypeDef *init_struct) +{ + init_struct->TIM_Channel = TIM_Channel_1; + init_struct->TIM_ICPolarity = TIM_ICPolarity_Rising; + init_struct->TIM_ICSelection = TIM_ICSelection_DirectTI; + init_struct->TIM_ICPrescaler = TIM_ICPSC_Div1; + init_struct->TIM_ICFilter = 0x00; +} + +/** + * @brief Initializes the TIM peripheral according to the specified + * parameters in the init_struct. + * @param tim: select the TIM peripheral. + * @param init_struct: pointer to a TIM_ICInitTypeDef structure that + * contains the configuration information for the specified TIM peripheral. + * @retval None. + */ +void TIM_ICInit(TIM_Type *tim, TIM_ICInitTypeDef *init_struct) +{ + switch (init_struct->TIM_Channel) + { + case TIM_Channel_1: + TI1_Configure(tim, init_struct->TIM_ICPolarity, init_struct->TIM_ICSelection, init_struct->TIM_ICFilter); + TIM_SetIC1Prescaler(tim, init_struct->TIM_ICPrescaler); + break; + + case TIM_Channel_2: + TI2_Configure(tim, init_struct->TIM_ICPolarity, init_struct->TIM_ICSelection, init_struct->TIM_ICFilter); + TIM_SetIC2Prescaler(tim, init_struct->TIM_ICPrescaler); + break; + + case TIM_Channel_3: + TI3_Configure(tim, init_struct->TIM_ICPolarity, init_struct->TIM_ICSelection, init_struct->TIM_ICFilter); + TIM_SetIC3Prescaler(tim, init_struct->TIM_ICPrescaler); + break; + + case TIM_Channel_4: + TI4_Configure(tim, init_struct->TIM_ICPolarity, init_struct->TIM_ICSelection, init_struct->TIM_ICFilter); + TIM_SetIC4Prescaler(tim, init_struct->TIM_ICPrescaler); + break; + + default: + break; + } +} + +/** + * @brief Configures the TIM peripheral according to the specified + * parameters in the init_struct to measure an external PWM signal. + * @param tim: select the TIM peripheral. + * @param init_struct: pointer to a TIM_ICInitTypeDef structure that + * contains the configuration information for the specified TIM peripheral. + * @retval None. + */ +void TIM_PWMIConfig(TIM_Type *tim, TIM_ICInitTypeDef *init_struct) +{ + uint16_t icoppositepolarity = TIM_ICPolarity_Rising; + uint16_t icoppositeselection = TIM_ICSelection_DirectTI; + + icoppositepolarity = (init_struct->TIM_ICPolarity == TIM_ICPolarity_Rising) ? TIM_ICPolarity_Falling : TIM_ICPolarity_Rising; + icoppositeselection = (init_struct->TIM_ICSelection == TIM_ICSelection_DirectTI) ? TIM_ICSelection_IndirectTI : TIM_ICSelection_DirectTI; + + if (init_struct->TIM_Channel == TIM_Channel_1) + { + TI1_Configure(tim, init_struct->TIM_ICPolarity, init_struct->TIM_ICSelection, init_struct->TIM_ICFilter); + TIM_SetIC1Prescaler(tim, init_struct->TIM_ICPrescaler); + TI2_Configure(tim, icoppositepolarity, icoppositeselection, init_struct->TIM_ICFilter); + TIM_SetIC2Prescaler(tim, init_struct->TIM_ICPrescaler); + } + else + { + TI2_Configure(tim, init_struct->TIM_ICPolarity, init_struct->TIM_ICSelection, init_struct->TIM_ICFilter); + TIM_SetIC2Prescaler(tim, init_struct->TIM_ICPrescaler); + TI1_Configure(tim, icoppositepolarity, icoppositeselection, init_struct->TIM_ICFilter); + TIM_SetIC1Prescaler(tim, init_struct->TIM_ICPrescaler); + } +} + +/** + * @brief Fills each init_struct member with its default value. + * @param init_struct: pointer to a TIM_BDTRInitTypeDef structure which will be initialized. + * @retval None. + */ +void TIM_BDTRStructInit(TIM_BDTRInitTypeDef *init_struct) +{ + init_struct->TIM_OSSRState = TIM_OSSRState_Disable; + init_struct->TIM_OSSIState = TIM_OSSIState_Disable; + init_struct->TIM_LOCKLevel = TIM_LockLevel_OFF; + init_struct->TIM_DeadTime = 0x00; + init_struct->TIM_Break = TIM_Break_Disable; + init_struct->TIM_BreakPolarity = TIM_BreakPolarity_Low; + init_struct->TIM_AutomaticOutput = TIM_AutomaticOutput_Disable; +} + +/** + * @brief Configures the: Break feature, dead time, Lock level, the OSSI, + * the OSSR State and the AOE(automatic output enable). + * @param tim: select the TIM + * @param init_struct: pointer to a TIM_BDTRInitTypeDef structure that + * contains the BDTR Register configuration information for the TIM peripheral. + * @retval None. + */ +void TIM_BDTRConfig(TIM_Type *tim, TIM_BDTRInitTypeDef *init_struct) +{ + tim->BDTR = (uint32_t)init_struct->TIM_OSSRState | init_struct->TIM_OSSIState | init_struct->TIM_LOCKLevel | + init_struct->TIM_DeadTime | init_struct->TIM_Break | init_struct->TIM_BreakPolarity | + init_struct->TIM_AutomaticOutput; +} + +/** + * @brief Enables or disables the specified TIM peripheral. + * @param tim: select the TIM peripheral. + * @param state: new state of the tim peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void TIM_Cmd(TIM_Type *tim, FunctionalState state) +{ + (state) ? \ + (tim->CR1 |= (0x01U << TIM_CR1_CEN_Pos)) : \ + (tim->CR1 &= ~(0x01U << TIM_CR1_CEN_Pos)); +} + +/** + * @brief Enables or disables the Asymmetric Mode. + * @param tim: select the TIM peripheral. + * @param state: new state of the tim peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void TIM_ASYMEN_Cmd(TIM_Type *tim, FunctionalState state) +{ + (state) ? \ + (tim->CR1 |= (0x01U << TIM_CR1_ASYMEN_Pos)) : \ + (tim->CR1 &= ~(0x01U << TIM_CR1_ASYMEN_Pos)); +} + +/** + * @brief Enables or disables the TIM peripheral Main Outputs. + * @param tim: select the TIM peripheral. + * @param state: new state of the TIM peripheral Main Outputs. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void TIM_CtrlPWMOutputs(TIM_Type *tim, FunctionalState state) +{ + (state) ? \ + (tim->BDTR |= (0x01U << TIM_BDTR_MOE_Pos)) : \ + (tim->BDTR &= ~(0x01U << TIM_BDTR_MOE_Pos)); +} + +/** + * @brief Enables or disables the specified TIM interrupts. + * @param tim: select the tim peripheral. + * @param it: specifies the TIM interrupts sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg TIM_IT_Update: TIM update Interrupt source + * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source + * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source + * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source + * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source + * @arg TIM_IT_COM: TIM Commutation Interrupt source + * @arg TIM_IT_Trigger: TIM Trigger Interrupt source + * @arg TIM_IT_Break: TIM Break Interrupt source + * @arg TIM_IT_CC5 + * @param state: new state of the TIM interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void TIM_ITConfig(TIM_Type *tim, uint32_t it, FunctionalState state) // TIMIT_TypeDef +{ + (state) ? \ + (tim->DIER |= it) : \ + (tim->DIER &= ~it); +} + +/** + * @brief Configures the tim event to be generate by software. + * @param tim: select the TIM peripheral. + * @param source: specifies the event source. + * This parameter can be one or more of the following values: + * @arg TIM_EventSource_Update :Timer update Event source + * @arg TIM_EventSource_CC1 :Timer Capture Compare 1 Event source + * @arg TIM_EventSource_CC2 :Timer Capture Compare 2 Event source + * @arg TIM_EventSource_CC3 :Timer Capture Compare 3 Event source + * @arg TIM_EventSource_CC4 :Timer Capture Compare 4 Event source + * @arg TIM_EventSource_COM :Timer COM event source + * @arg TIM_EventSource_Trigger:Timer Trigger Event source + * @arg TIM_EventSource_Break :Timer Break event source + * @arg TIM_EventSource_CC5 :Timer Capture Compare 5 Event source + * @note + * - TIM_EventSource_COM and TIM_EventSource_Break are used only with partial timer. + * @retval None. + */ +void TIM_GenerateEvent(TIM_Type *tim, uint32_t source) +{ + tim->EGR = source; +} + +/** + * @brief Configures the tim internal Clock + * @param tim: select the TIM peripheral. + * @retval None. + */ +void TIM_InternalClockConfig(TIM_Type *tim) +{ + tim->SMCR &= (uint16_t)(~(uint16_t)TIM_SMCR_SMS_Msk); +} + +/** + * @brief Configures the tim Internal Trigger as External Clock + * @param tim: select the TIM peripheral. + * @param source: Trigger source. + * This parameter can be one of the following values: + * @arg TIM_TS_ITR0: Internal Trigger 0 + * @arg TIM_TS_ITR1: Internal Trigger 1 + * @arg TIM_TS_ITR2: Internal Trigger 2 + * @arg TIM_TS_ITR3: Internal Trigger 3 + * @arg TIM_TS_TI1F_ED : TI1 Edge Detector + * @arg TIM_TS_TI1FP1 : Filtered Timer Input + * @arg TIM_TS_TI2FP2 : Filtered Timer Input + * @arg TIM_TS_ETRF : TI1 Edge Detector + * @retval None. + */ +void TIM_ITRxExternalClockConfig(TIM_Type *tim, uint32_t source) +{ + TIM_SelectInputTrigger(tim, source); + tim->SMCR |= TIM_SlaveMode_External1; +} + +/** + * @brief Selects the Input Trigger source + * @param tim: select the TIM peripheral. + * @param source: The Input Trigger source. + * This parameter can be one of the following values: + * @arg TIM_TS_ITR0: Internal Trigger 0 + * @arg TIM_TS_ITR1: Internal Trigger 1 + * @arg TIM_TS_ITR2: Internal Trigger 2 + * @arg TIM_TS_ITR3: Internal Trigger 3 + * @arg TIM_TS_TI1F_ED: TI1 Edge Detector + * @arg TIM_TS_TI1FP1: Filtered Timer Input 1 + * @arg TIM_TS_TI2FP2: Filtered Timer Input 2 + * @arg TIM_TS_ETRF: External Trigger input + * @retval None. + */ +void TIM_SelectInputTrigger(TIM_Type *tim, uint16_t source) +{ + REG_WRITE_MASK(tim->SMCR, TIM_SMCR_TS_Msk, source); +} + +/** + * @brief Configures the tim Prescaler. + * @param tim: select the TIM peripheral. + * @param prescaler: specifies the Prescaler Register value + * @param reloadMode: specifies the TIM Prescaler Reload mode + * @arg TIM_PSCReloadMode_Update :The Prescaler is loaded at the update event. + * @arg TIM_PSCReloadMode_Immediate :The Prescaler is loaded immediately. + * @retval None. + */ +void TIM_PrescalerConfig(TIM_Type *tim, uint16_t prescaler, uint16_t reloadMode) +{ + tim->PSC = prescaler; + tim->EGR = reloadMode; +} + + +/** + * @brief Configures the External clock Mode1 + * @param TIMx: where x can be 2, EPWM to select the TIM peripheral. + * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF. + * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2. + * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4. + * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8. + * @param TIM_ExtTRGPolarity: The external Trigger Polarity. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active. + * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active. + * @param ExtTRGFilter: External Trigger Filter. + * This parameter must be a value between 0x00 and 0x0F + * @retval None + */ +void TIM_ETRClockMode1Config(TIM_Type *tim, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter) +{ + /* Configure the ETR Clock source */ + TIM_ETRConfig(tim, TIM_ExtTRGPrescaler, TIM_ExtTRGPolarity, ExtTRGFilter); + + /* Select the External clock mode1 . Select the Trigger selection : ETRF */ + REG_WRITE_MASK(tim->SMCR, TIM_SMCR_SMS_Msk | TIM_SMCR_TS_Msk , TIM_SlaveMode_External1 | TIM_TS_ETRF ); +} + + + +/** + * @brief Configures the TIMx Trigger as External Clock + * @param TIMx: where x can be 2, EPWM to select the TIM peripheral. + * @param TIM_TIxExternalCLKSource: Trigger source. + * This parameter can be one of the following values: + * @arg TIM_TIxExternalCLK1Source_TI1ED: TI1 Edge Detector + * @arg TIM_TIxExternalCLK1Source_TI1: Filtered Timer Input 1 + * @arg TIM_TIxExternalCLK1Source_TI2: Filtered Timer Input 2 + * @param TIM_ICPolarity: specifies the TIx Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Rising + * @arg TIM_ICPolarity_Falling + * @param ICFilter : specifies the filter value. + * This parameter must be a value between 0x0 and 0xF. + * @retval None + */ +void TIM_TIxExternalClockConfig(TIM_Type *TIMx, uint16_t TIM_TIxExternalCLKSource, uint16_t TIM_ICPolarity, uint16_t ICFilter) +{ + /* Configure the Timer Input Clock Source */ + + /* Select the Trigger source */ + TIM_SelectInputTrigger(TIMx, TIM_TIxExternalCLKSource); + /* Select the External clock mode1 */ + TIMx->SMCR |= TIM_SlaveMode_External1; +} + +/** + * @brief Configures the External clock Mode2 + * @param TIMx: where x can be 2, EPWM to select the TIM peripheral. + * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF. + * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2. + * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4. + * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8. + * @param TIM_ExtTRGPolarity: The external Trigger Polarity. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active. + * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active. + * @param ExtTRGFilter: External Trigger Filter. + * This parameter must be a value between 0x00 and 0x0F + * @retval None + */ +void TIM_ETRClockMode2Config(TIM_Type *tim, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter) +{ + /* Configure the ETR Clock source */ + TIM_ETRConfig(tim, TIM_ExtTRGPrescaler, TIM_ExtTRGPolarity, ExtTRGFilter); + /* Enable the External clock mode2 */ + tim->SMCR |= TIM_SMCR_ECE_Msk; +} + +/** + * @brief Configures the TIMx External Trigger (ETR). + * @param TIMx: where x can be 2, EPWM to select the TIM peripheral. + * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF. + * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2. + * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4. + * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8. + * @param TIM_ExtTRGPolarity: The external Trigger Polarity. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active. + * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active. + * @param ExtTRGFilter: External Trigger Filter. + * This parameter must be a value between 0x00 and 0x0F + * @retval None + */ +void TIM_ETRConfig(TIM_Type *tim, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,uint16_t ExtTRGFilter) +{ + REG_WRITE_MASK(tim->SMCR, TIM_SMCR_ETPS_Msk | TIM_SMCR_ETP_Msk | TIM_SMCR_ETF_Msk,TIM_ExtTRGPrescaler | TIM_ExtTRGPolarity | ExtTRGFilter << TIM_SMCR_ETF_Pos); +} + +/** + * @brief Specifies the tim Counter Mode to be used. + * @param tim:select the TIM peripheral. + * @param counter_mode: specifies the Counter Mode to be used + * This parameter can be one of the following values: + * @arg TIM_CounterMode_Up : TIM Up Counting Mode + * @arg TIM_CounterMode_Down : TIM Down Counting Mode + * @arg TIM_CounterMode_CenterAligned1: TIM Center Aligned Mode1 + * @arg TIM_CounterMode_CenterAligned2: TIM Center Aligned Mode2 + * @arg TIM_CounterMode_CenterAligned3: TIM Center Aligned Mode3 + * @retval None. + */ +void TIM_CounterModeConfig(TIM_Type *tim, uint32_t counter_mode) +{ + REG_WRITE_MASK(tim->CR1, TIM_CR1_CMS_Msk | TIM_CR1_DIR_Msk, counter_mode); +} + +/** + * @brief Configures the tim Encoder Interface. + * @param tim: select the TIM peripheral. + * @param encoder_mode: specifies the tim Encoder Mode. + * This parameter can be one of the following values: + * @arg TIM_EncoderMode_TI1: Counter counts on TI1FP1 edge depending on TI2FP2 level. + * @arg TIM_EncoderMode_TI2: Counter counts on TI2FP2 edge depending on TI1FP1 level. + * @arg TIM_EncoderMode_TI12: Counter counts on both TI1FP1 and TI2FP2 edges depending + * on the level of the other input. + * @param ic1_polarity: specifies the IC1 Polarity + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Falling: IC Falling edge. + * @arg TIM_ICPolarity_Rising: IC Rising edge. + * @param ic2_polarity: specifies the IC2 Polarity + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Falling: IC Falling edge. + * @arg TIM_ICPolarity_Rising: IC Rising edge. + * @retval None. + */ +void TIM_EncoderInterfaceConfig(TIM_Type *tim, uint32_t encoder_mode, uint32_t ic1_polarity, uint32_t ic2_polarity) +{ + REG_WRITE_MASK(tim->SMCR, TIM_SMCR_SMS_Msk, encoder_mode); + REG_WRITE_MASK(tim->CCMR1_OUTPUT, TIM_CCMR1_OUTPUT_CC1S_Msk | TIM_CCMR1_OUTPUT_CC2S_Msk, TIM_CCMR1_CC1S_DirectTI | TIM_CCMR1_CC2S_DirectTI); + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC1P_Msk | TIM_CCER_CC2P_Msk, ic1_polarity | (ic2_polarity << 4)); +} + +/** + * @brief Forces the tim output 1 waveform to active or inactive level. + * @param tim: select the TIM peripheral. + * @param forced_action: specifies the forced Action to be set to the output waveform. + * This parameter can be one of the following values: + * @arg TIM_ForcedAction_Active: Force active level on OC1REF + * @arg TIM_ForcedAction_Inactive: Force inactive level on OC1REF. + * @retval None. + */ +void TIM_ForcedOC1Config(TIM_Type *tim, uint32_t forced_action) +{ + REG_WRITE_MASK(tim->CCMR1_OUTPUT, TIM_CCMR1_OUTPUT_OC1M_Msk, forced_action << TIM_CCMR1_OUTPUT_OC1M_Pos); +} + +/** + * @brief Forces the tim output 2 waveform to active or inactive level. + * @param tim: select the TIM peripheral. + * @param forced_action: specifies the forced Action to be set to the output waveform. + * This parameter can be one of the following values: + * @arg TIM_ForcedAction_Active: Force active level on OC2REF + * @arg TIM_ForcedAction_Inactive: Force inactive level on OC2REF. + * @retval None. + */ +void TIM_ForcedOC2Config(TIM_Type *tim, uint32_t forced_action) +{ + REG_WRITE_MASK(tim->CCMR1_OUTPUT, TIM_CCMR1_OUTPUT_OC2M_Msk, forced_action << TIM_CCMR1_OUTPUT_OC2M_Pos); +} + +/** + * @brief Forces the tim output 3 waveform to active or inactive level. + * @param tim: select the TIM peripheral. + * @param forced_action: specifies the forced Action to be set to the output waveform. + * This parameter can be one of the following values: + * @arg TIM_ForcedAction_Active: Force active level on OC3REF + * @arg TIM_ForcedAction_Inactive: Force inactive level on OC3REF. + * @retval None. + */ +void TIM_ForcedOC3Config(TIM_Type *tim, uint32_t forced_action) +{ + REG_WRITE_MASK(tim->CCMR2_OUTPUT, TIM_CCMR2_OUTPUT_OC3M_Msk, forced_action << TIM_CCMR2_OUTPUT_OC3M_Pos); +} + +/** + * @brief Forces the tim output 4 waveform to active or inactive level. + * @param tim: select the TIM peripheral. + * @param forced_action: specifies the forced Action to be set to the output waveform. + * This parameter can be one of the following values: + * @arg TIM_ForcedAction_Active: Force active level on OC4REF + * @arg TIM_ForcedAction_Inactive: Force inactive level on OC4REF. + * @retval None. + */ +void TIM_ForcedOC4Config(TIM_Type *tim, uint32_t forced_action) +{ + REG_WRITE_MASK(tim->CCMR2_OUTPUT, TIM_CCMR2_OUTPUT_OC4M_Msk, forced_action << TIM_CCMR2_OUTPUT_OC4M_Pos); +} + +/** + * @brief Enables or disables tim peripheral Preload register on ARR. + * @param tim: select the TIM peripheral. + * @param state: new state of the tim peripheral Preload register + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void TIM_ARRPreloadConfig(TIM_Type *tim, FunctionalState state) +{ + (state) ? \ + (tim->CR1 |= (0x01U << TIM_CR1_ARPE_Pos)) : \ + (tim->CR1 &= ~(0x01U << TIM_CR1_ARPE_Pos)); +} + +/** + * @brief Selects the TIM peripheral Commutation event. + * @param tim: select the tim peripheral. + * @param state: new state of the Commutation event. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void TIM_SelectCOM(TIM_Type *tim, FunctionalState state) +{ + (state) ? \ + (tim->CR2 |= (0x01U << TIM_CR2_CCUS_Pos)) : \ + (tim->CR2 &= ~(0x01U << TIM_CR2_CCUS_Pos)); +} + +/** + * @brief Sets or Resets the TIM peripheral Capture Compare Preload Control bit. + * @param tim: select the tim peripheral. + * @param state: new state of the Capture Compare Preload Control bit + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void TIM_CCPreloadControl(TIM_Type *tim, FunctionalState state) +{ + (state) ? \ + (tim->CR2 |= (0x01U << TIM_CR2_CCPC_Pos)) : \ + (tim->CR2 &= ~(0x01U << TIM_CR2_CCPC_Pos)); +} + +/** + * @brief Enables or disables the tim peripheral Preload register on CCR1. + * @param tim: select the TIM peripheral. + * @param preload: new state of the tim peripheral Preload register + * This parameter can be one of the following values: + * @arg TIM_OCPreload_Disable + * @arg TIM_OCPreload_Enable + * @retval None. + */ +void TIM_OC1PreloadConfig(TIM_Type *tim, uint32_t preload) +{ + REG_WRITE_MASK(tim->CCMR1_OUTPUT, TIM_CCMR1_OUTPUT_OC1PE_Msk, preload); +} + +/** + * @brief Enables or disables the tim peripheral Preload register on CCR2. + * @param tim: select the TIM peripheral. + * @param preload: new state of the tim peripheral Preload register + * This parameter can be one of the following values: + * @arg TIM_OCPreload_Disable + * @arg TIM_OCPreload_Enable + * @retval None. + */ +void TIM_OC2PreloadConfig(TIM_Type *tim, uint32_t preload) +{ + REG_WRITE_MASK(tim->CCMR1_OUTPUT, TIM_CCMR1_OUTPUT_OC2PE_Msk, preload << 8); +} + +/** + * @brief Enables or disables the tim peripheral Preload register on CCR3. + * @param tim: select the TIM peripheral. + * @param preload: new state of the tim peripheral Preload register + * This parameter can be one of the following values: + * @arg TIM_OCPreload_Disable + * @arg TIM_OCPreload_Enable + * @retval None. + */ +void TIM_OC3PreloadConfig(TIM_Type *tim, uint32_t preload) +{ + REG_WRITE_MASK(tim->CCMR2_OUTPUT, TIM_CCMR2_OUTPUT_OC3PE_Msk, preload); +} + +/** + * @brief Enables or disables the tim peripheral Preload register on CCR4. + * @param tim: select the TIM peripheral. + * @param preload: new state of the tim peripheral Preload register + * This parameter can be one of the following values: + * @arg TIM_OCPreload_Disable + * @arg TIM_OCPreload_Enable + * @retval None. + */ +void TIM_OC4PreloadConfig(TIM_Type *tim, uint32_t preload) +{ + REG_WRITE_MASK(tim->CCMR2_OUTPUT, TIM_CCMR2_OUTPUT_OC4PE_Msk, preload << 8); +} + + + +/** + * @brief Configures the tim Output Compare 1 Fast feature. + * @param tim: select the TIM peripheral. + * @param fast: new state of the Output Compare Fast Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCFast_Enable: TIM output compare fast enable + * @arg TIM_OCFast_Disable: TIM output compare fast disable + * @retval None. + */ +void TIM_OC1FastConfig(TIM_Type *tim, uint32_t fast) +{ + REG_WRITE_MASK(tim->CCMR1_OUTPUT, TIM_CCMR1_OUTPUT_OC1FE_Msk, fast); +} + +/** + * @brief Configures the tim Output Compare 2 Fast feature. + * @param tim: select the TIM peripheral. + * @param fast: new state of the Output Compare Fast Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCFast_Enable: TIM output compare fast enable + * @arg TIM_OCFast_Disable: TIM output compare fast disable + * @retval None. + */ +void TIM_OC2FastConfig(TIM_Type *tim, uint32_t fast) +{ + REG_WRITE_MASK(tim->CCMR1_OUTPUT, TIM_CCMR1_OUTPUT_OC2FE_Msk, fast << 8); +} + +/** + * @brief Configures the tim Output Compare 3 Fast feature. + * @param tim: select the TIM peripheral. + * @param fast: new state of the Output Compare Fast Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCFast_Enable: TIM output compare fast enable + * @arg TIM_OCFast_Disable: TIM output compare fast disable + * @retval None. + */ +void TIM_OC3FastConfig(TIM_Type *tim, uint32_t fast) +{ + REG_WRITE_MASK(tim->CCMR2_OUTPUT, TIM_CCMR2_OUTPUT_OC3FE_Msk, fast); +} + +/** + * @brief Configures the tim Output Compare 4 Fast feature. + * @param tim: select the TIM peripheral. + * @param fast: new state of the Output Compare Fast Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCFast_Enable: TIM output compare fast enable + * @arg TIM_OCFast_Disable: TIM output compare fast disable + * @retval None. + */ +void TIM_OC4FastConfig(TIM_Type *tim, uint32_t fast) +{ + REG_WRITE_MASK(tim->CCMR2_OUTPUT, TIM_CCMR2_OUTPUT_OC4FE_Msk, fast << 8); +} + +/** + * @brief Configures the tim channel 1 polarity. + * @param tim: select the TIM peripheral. + * @param polarity: specifies the OC1 Polarity + * This parameter can be one of the following values: + * @arg TIM_OCPolarity_High: Output Compare active high + * @arg TIM_OCPolarity_Low: Output Compare active low + * @retval None. + */ +void TIM_OC1PolarityConfig(TIM_Type *tim, uint32_t polarity) +{ + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC1P_Msk, polarity << TIM_CCER_CC1P_Pos); +} + +/** + * @brief Configures the tim Channel 1N polarity. + * @param tim: select the TIM peripheral. + * @param polarity: specifies the OC1N Polarity + * This parameter can be one of the following values: + * @arg TIM_OCNPolarity_High: Output Compare active high + * @arg TIM_OCNPolarity_Low: Output Compare active low + * @retval None. + */ +void TIM_OC1NPolarityConfig(TIM_Type *tim, uint32_t polarity) +{ + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC1NP_Msk, polarity << TIM_CCER_CC1NP_Pos); +} + +/** + * @brief Configures the tim channel 2 polarity. + * @param tim: select the TIM peripheral. + * @param polarity: specifies the OC2 Polarity + * This parameter can be one of the following values: + * @arg TIM_OCPolarity_High: Output Compare active high + * @arg TIM_OCPolarity_Low: Output Compare active low + * @retval None. + */ +void TIM_OC2PolarityConfig(TIM_Type *tim, uint32_t polarity) +{ + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC2P_Msk, polarity << TIM_CCER_CC2P_Pos); +} + +/** + * @brief Configures the tim Channel 2N polarity. + * @param tim: select the TIM peripheral. + * @param polarity: specifies the OC2N Polarity + * This parameter can be one of the following values: + * @arg TIM_OCNPolarity_High: Output Compare active high + * @arg TIM_OCNPolarity_Low: Output Compare active low + * @retval None. + */ +void TIM_OC2NPolarityConfig(TIM_Type *tim, uint32_t polarity) +{ + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC2NP_Msk, polarity << TIM_CCER_CC2NP_Pos); +} + +/** + * @brief Configures the tim channel 3 polarity. + * @param tim: select the TIM peripheral. + * @param polarity: specifies the OC3 Polarity + * This parameter can be one of the following values: + * @arg TIM_OCPolarity_High: Output Compare active high + * @arg TIM_OCPolarity_Low: Output Compare active low + * @retval None. + */ +void TIM_OC3PolarityConfig(TIM_Type *tim, uint32_t polarity) +{ + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC3P_Msk, polarity << TIM_CCER_CC3P_Pos); +} + +/** + * @brief Configures the tim Channel 3N polarity. + * @param tim: select the TIM peripheral. + * @param polarity: specifies the OC3N Polarity + * This parameter can be one of the following values: + * @arg TIM_OCNPolarity_High: Output Compare active high + * @arg TIM_OCNPolarity_Low: Output Compare active low + * @retval None. + */ +void TIM_OC3NPolarityConfig(TIM_Type *tim, uint32_t polarity) +{ + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC3NP_Msk, polarity << TIM_CCER_CC3NP_Pos); +} + +/** + * @brief Configures the tim channel 4 polarity. + * @param tim: select the TIM peripheral. + * @param polarity: specifies the OC4 Polarity + * This parameter can be one of the following values: + * @arg TIM_OCPolarity_High: Output Compare active high + * @arg TIM_OCPolarity_Low: Output Compare active low + * @retval None. + */ +void TIM_OC4PolarityConfig(TIM_Type *tim, uint32_t polarity) +{ + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC4P_Msk, polarity << TIM_CCER_CC4P_Pos); +} + +///** +// * @brief Configures the tim channel 4N polarity. +// * @param tim: select the TIM peripheral. +// * @param polarity: specifies the OC4N Polarity +// * This parameter can be one of the following values: +// * @arg TIM_OCNPolarity_High: Output Compare active high +// * @arg TIM_OCNPolarity_Low: Output Compare active low +// * @retval None. +// */ +//void TIM_OC4NPolarityConfig(TIM_Type *tim, uint32_t polarity) +//{ +// REG_WRITE_MASK(tim->CCER, TIM_CCER_CC4NP_Msk, polarity << TIM_CCER_CC4NP_Pos); +//} + +/** + * @brief Enables or disables the TIM Capture Compare Channel x. + * @param tim: select the TIM peripheral. + * @param channel: specifies the TIM Channel + * This parameter can be one of the following values: + * @arg TIM_Channel_1: TIM Channel 1 + * @arg TIM_Channel_2: TIM Channel 2 + * @arg TIM_Channel_3: TIM Channel 3 + * @arg TIM_Channel_4: TIM Channel 4 + * @arg TIM_Channel_5: TIM Channel 5(Only for some MM32 TIM1/8) + * @param TIM_CCx: specifies the TIM Channel CCxE bit new state. + * This parameter can be: TIM_CCx_Enable or TIM_CCx_Disable. + * @retval None. + */ +void TIM_CCxCmd(TIM_Type *tim, uint16_t channel, uint32_t ccx_en) +{ + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC1E_Msk << channel, ccx_en << channel); +} + +/** + * @brief Enables or disables the TIM Capture Compare Channel xN. + * @param tim: select the TIM peripheral. + * @param channel: specifies the TIM Channel + * This parameter can be one of the following values: + * @arg TIM_Channel_1: TIM Channel 1 + * @arg TIM_Channel_2: TIM Channel 2 + * @arg TIM_Channel_3: TIM Channel 3 + * @arg TIM_Channel_4: TIM Channel 4 + * @param TTIM_CHANNEL_5IM_CCxN: specifies the TIM Channel CCxNE bit new state. + * This parameter can be: TIM_CCXN_ENABLE or TIM_CCXN_Disable. + * @retval None. + */ +void TIM_CCxNCmd(TIM_Type *tim, uint16_t channel, uint32_t ccxn_en) +{ + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC1NE_Msk << channel, ccxn_en << channel); +} + +/** + * @brief Selects the TIM Output Compare Mode. + * @note This function disables the selected channel before changing the Output Compare Mode. + * User has to enable this channel using TIM_CCxCmd and TIM_CCxNCmd functions. + * @param tim: select the TIM peripheral. + * @param channel: specifies the TIM Channel + * @arg TIM_Channel_1: TIM Channel 1 + * @arg TIM_Channel_2: TIM Channel 2 + * @arg TIM_Channel_3: TIM Channel 3 + * @arg TIM_Channel_4: TIM Channel 4 + * @param mode: specifies the TIM Output Compare Mode. + * @arg TIM_OCMode_Timing + * @arg TIM_OCMode_Active + * @arg TIM_OCMode_Inactive + * @arg TIM_OCMode_Toggle + * @arg TIM_ForcedAction_Inactive + * @arg TIM_ForcedAction_Active + * @arg TIM_OCMode_PWM1 + * @arg TIM_OCMode_PWM2 + * @retval None. + */ +void TIM_SelectOCxM(TIM_Type *tim, uint16_t channel, uint32_t mode) +{ + tim->CCER &= ~(TIM_CCER_CC1E_Msk << channel); + + switch (channel) + { + case TIM_Channel_1: + REG_WRITE_MASK(tim->CCMR1_OUTPUT, TIM_CCMR1_OUTPUT_OC1M_Msk, mode << TIM_CCMR1_OUTPUT_OC1M_Pos); + break; + + case TIM_Channel_2: + REG_WRITE_MASK(tim->CCMR1_OUTPUT, TIM_CCMR1_OUTPUT_OC2M_Msk, mode << TIM_CCMR1_OUTPUT_OC2M_Pos); + break; + + case TIM_Channel_3: + REG_WRITE_MASK(tim->CCMR2_OUTPUT, TIM_CCMR2_OUTPUT_OC3M_Msk, mode << TIM_CCMR2_OUTPUT_OC3M_Pos); + break; + + case TIM_Channel_4: + REG_WRITE_MASK(tim->CCMR2_OUTPUT, TIM_CCMR2_OUTPUT_OC4M_Msk, mode << TIM_CCMR2_OUTPUT_OC4M_Pos); + break; + + default: + break; + } +} + +/** + * @brief Enables or Disables the tim Update event. + * @param tim: select the TIM peripheral. + * @param state: new state of the tim UDIS bit + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void TIM_UpdateDisableConfig(TIM_Type *tim, FunctionalState state) +{ + (state) ? \ + (tim->CR1 |= (0x01U << TIM_CR1_UDIS_Pos)) : \ + (tim->CR1 &= ~(0x01U << TIM_CR1_UDIS_Pos)); +} + +/** + * @brief Configures the tim Update Request Interrupt source. + * @param tim: select the TIM peripheral. + * @param source: specifies the Update source. + * This parameter can be one of the following values: + * @arg TIM_UPDATESOURCE_REGULAR: Source of update is the counter overflow/underflow + * or the setting of UG bit, or an update generation + * through the slave mode controller. + * @arg TIM_UPDATESOURCE_GLOBAL: Source of update is counter overflow/underflow. + * @retval None. + */ +void TIM_UpdateRequestConfig(TIM_Type *tim, uint32_t source) +{ + REG_WRITE_MASK(tim->CR1, TIM_CR1_URS_Msk, source); +} + +/** + * @brief Enables or disables the tim's Hall sensor interface. + * @param tim: select the TIM peripheral. + * @param state: new state of the tim Hall sensor interface. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void TIM_SelectHallSensor(TIM_Type *tim, FunctionalState state) +{ + (state) ? \ + (tim->CR2 |= (0x01U << TIM_CR2_TI1S_Pos)) : \ + (tim->CR2 &= ~(0x01U << TIM_CR2_TI1S_Pos)); +} + +/** + * @brief Selects the tim's One Pulse Mode. + * @param tim: select the TIM peripheral. + * @param mode: specifies the OPM Mode to be used. + * This parameter can be one of the following values: + * @arg TIM_OPMode_Repetitive + * @arg TIM_OPMode_Single + * @retval None. + */ +void TIM_SelectOnePulseMode(TIM_Type *tim, uint32_t mode) +{ + REG_WRITE_MASK(tim->CR1, TIM_CR1_OPM_Msk, mode); +} + +/** + * @brief Selects the tim Trigger Output Mode. + * @param tim:select the TIM peripheral. + * @param source: specifies the Trigger Output source. + * This paramter can be one of the following values: + * - For all tim + * @arg TIM_TRIGSource_Reset : The UG bit in the TIM_EGR register is used as the trigger output (TRIG). + * @arg TIM_TRIGSource_Enable: The Counter Enable CEN is used as the trigger output (TRIG). + * @arg TIM_TRIGSource_Update: The update event is selected as the trigger output (TRIG). + * @arg TIM_TRIGSource_OC1 : The trigger output sends a positive pulse when the CC1IF flag is to be set, as soon as a capture or compare match occurs (TRIG). + * @arg TIM_TRIGSource_OC1REF: OC1REF signal is used as the trigger output (TRIG). + * @arg TIM_TRIGSource_OC2REF: OC2REF signal is used as the trigger output (TRIG). + * @arg TIM_TRIGSource_OC3REF: OC3REF signal is used as the trigger output (TRIG). + * @arg TIM_TRIGSource_OC4REF: OC4REF signal is used as the trigger output (TRIG). + * + * @retval None. + */ +void TIM_SelectOutputTrigger(TIM_Type *tim, uint32_t source) +{ + REG_WRITE_MASK(tim->CR2, TIM_CR2_MMS_Msk, source); +} + +/** + * @brief Selects the tim Slave Mode. + * @param tim: select the TIM peripheral. + * @param mode: specifies the Timer Slave Mode. + * @arg TIM_SlaveMode_Reset : Rising edge of the selected trigger signal (TRGI) re-initialize the counter and triggers an update of the registers. + * @arg TIM_SlaveMode_Gated : The counter clock is enabled when the trigger signal (TRGI) is high. + * @arg TIM_SlaveMode_Trigger : The counter starts at a rising edge of the trigger TRGI. + * @arg TIM_SlaveMode_External1: Rising edges of the selected trigger (TRGI) clock the counter. + * @retval None. + */ +void TIM_SelectSlaveMode(TIM_Type *tim, uint32_t mode) +{ + REG_WRITE_MASK(tim->SMCR, TIM_SMCR_SMS_Msk, mode); +} + +/** + * @brief Sets or Resets the tim Master/Slave Mode. + * @param tim: select the TIM peripheral. + * @param mode: specifies the Timer Master Slave Mode. + * @arg TIM_MasterSlaveMode_Enable: synchronization between the current timer and its slaves (through TRIG). + * @arg TIM_MasterSlaveMode_Disable: No action + * @retval None. + */ +void TIM_SelectMasterSlaveMode(TIM_Type *tim, uint32_t mode) +{ + REG_WRITE_MASK(tim->SMCR, TIM_SMCR_MSM_Msk, mode); +} + +/** + * @brief Sets the tim Counter Register value + * @param tim: select the TIM peripheral. + * @param auto_reload: specifies the Counter register new value. + * @retval None. + */ +void TIM_SetAutoreload(TIM_Type *tim, uint16_t auto_reload) +{ + tim->ARR = auto_reload; +} + +/** + * @brief Sets the tim Counter Register value + * @param tim: select the TIM peripheral. + * @param counter: specifies the Counter register new value. + * @retval None. + */ +void TIM_SetCounter(TIM_Type *tim, uint32_t counter) +{ + tim->CNT = counter; +} + +/** + * @brief Sets the tim Clock Division value. + * @param tim: select + * the TIM peripheral. + * @param clock_div: specifies the clock division value. + * This parameter can be one of the following value: + * @arg TIM_CKD_DIV_1: TDTS = Tck_tim + * @arg TIM_CKD_DIV_2: TDTS = 2 * Tck_tim + * @arg TIM_CKD_DIV_4: TDTS = 4 * Tck_tim + * @retval None. + */ +void TIM_SetClockDivision(TIM_Type *tim, uint32_t clock_div) +{ + REG_WRITE_MASK(tim->CR1, TIM_CR1_CKD_Msk, clock_div); +} + +/** + * @brief Sets the tim Capture Compare1 Register value + * @param tim: select the TIM peripheral. + * @param compare: specifies the Capture Compare1 register new value. + * @retval None. + */ +void TIM_SetCompare1(TIM_Type *tim, uint32_t compare) +{ + tim->CCR1 = (uint16_t)compare; +} + +/** + * @brief Sets the tim Capture Compare2 Register value + * @param tim: select the TIM peripheral. + * @param compare: specifies the Capture Compare2 register new value. + * @retval None. + */ +void TIM_SetCompare2(TIM_Type *tim, uint32_t compare) +{ + tim->CCR2 = (uint16_t)compare; +} + +/** + * @brief Sets the tim Capture Compare3 Register value + * @param tim: select the TIM peripheral. + * @param compare: specifies the Capture Compare3 register new value. + * @retval None. + */ +void TIM_SetCompare3(TIM_Type *tim, uint32_t compare) +{ + tim->CCR3 = (uint16_t)compare; +} + +/** + * @brief Sets the tim Capture Compare4 Register value + * @param tim: select the TIM peripheral. + * @param compare: specifies the Capture Compare4 register new value. + * @retval None. + */ +void TIM_SetCompare4(TIM_Type *tim, uint32_t compare) +{ + tim->CCR4 = (uint16_t)compare; +} + +/** + * @brief Sets the tim Downwards Compare1 Register value + * @param tim: select the TIM peripheral. + * @param compare: specifies the Capture Compare1 register new value. + * @retval None. + */ +void TIM_SetDownCompare1(TIM_Type *tim, uint32_t compare) +{ + tim->CCDR1 = (uint16_t)compare; +} + +/** + * @brief Sets the tim Downwards Compare2 Register value + * @param tim: select the TIM peripheral. + * @param compare: specifies the Capture Compare2 register new value. + * @retval None. + */ +void TIM_SetDownCompare2(TIM_Type *tim, uint32_t compare) +{ + tim->CCDR2 = (uint16_t)compare; +} + +/** + * @brief Sets the tim Downwards Compare3 Register value + * @param tim: select the TIM peripheral. + * @param compare: specifies the Capture Compare3 register new value. + * @retval None. + */ +void TIM_SetDownCompare3(TIM_Type *tim, uint32_t compare) +{ + tim->CCDR3 = (uint16_t)compare; +} + +/** + * @brief Sets the tim Downwards Compare4 Register value + * @param tim: select the TIM peripheral. + * @param compare: specifies the Capture Compare4 register new value. + * @retval None. + */ +void TIM_SetDownCompare4(TIM_Type *tim, uint32_t compare) +{ + tim->CCDR4 = (uint16_t)compare; +} + +/** + * @brief Gets the tim Input Capture 1 value. + * @param tim: select the TIM peripheral. + * @retval Value: Capture Compare 1 Register value. + */ +uint32_t TIM_GetCapture1(TIM_Type *tim) +{ + return (tim->CCR1); +} + +/** + * @brief Gets the tim Input Capture 2 value. + * @param tim: select the TIM peripheral. + * @retval Value: Capture Compare 2 Register value. + */ +uint32_t TIM_GetCapture2(TIM_Type *tim) +{ + return (tim->CCR2); +} + +/** + * @brief Gets the tim Input Capture 3 value. + * @param tim: select the TIM peripheral. + * @retval Value: Capture Compare 3 Register value. + */ +uint32_t TIM_GetCapture3(TIM_Type *tim) +{ + return (tim->CCR3); +} + +/** + * @brief Gets the tim Input Capture 4 value. + * @param tim: select the TIM peripheral. + * @retval Value: Capture Compare 4 Register value. + */ +uint32_t TIM_GetCapture4(TIM_Type *tim) +{ + return (tim->CCR4); +} + + + +/** + * @brief Gets the tim Counter value. + * @param tim: select the TIM peripheral. + * @retval Value: Counter Register value. + */ +uint32_t TIM_GetCounter(TIM_Type *tim) +{ + return (tim->CNT); +} + +/** + * @brief Gets the tim Prescaler value. + * @param tim: select the TIM peripheral. + * @retval Value: Prescaler Register value. + */ +uint16_t TIM_GetPrescaler(TIM_Type *tim) +{ + return (tim->PSC); +} + +/** + * @brief Checks whether the specified TIM flag is set or not. + * @param tim: select the TIM peripheral. + * @param flag: specifies the flag to check. + * This parameter can be one of the following values: + * @arg TIM_FLAG_Update: TIM update Flag + * @arg TIM_FLAG_CC1: TIM Capture Compare 1 Flag + * @arg TIM_FLAG_CC2: TIM Capture Compare 2 Flag + * @arg TIM_FLAG_CC3: TIM Capture Compare 3 Flag + * @arg TIM_FLAG_CC4: TIM Capture Compare 4 Flag + * @arg TIM_FLAG_COM: TIM Commutation Flag + * @arg TIM_FLAG_Trigger: TIM Trigger Flag + * @arg TIM_FLAG_Break: TIM Break Flag + * @arg TIM_FLAG_CC1OF: TIM Capture Compare 1 overcapture Flag + * @arg TIM_FLAG_CC2OF: TIM Capture Compare 2 overcapture Flag + * @arg TIM_FLAG_CC3OF: TIM Capture Compare 3 overcapture Flag + * @arg TIM_FLAG_CC4OF: TIM Capture Compare 4 overcapture Flag + * @retval State: The new state of TIM_FLAG (SET or RESET). + */ +FlagStatus TIM_GetFlagStatus(TIM_Type *tim, uint32_t flag) +{ + return ((tim->SR &flag) ? SET : RESET); +} + +/** + * @brief Clears the tim's pending flags. + * @param tim: select the TIM peripheral. + * @param flag: specifies the flag bit to clear. + * This parameter can be any combination of the following values: + * @arg TIM_FLAG_Update: TIM update Flag + * @arg TIM_FLAG_CC1: TIM Capture Compare 1 Flag + * @arg TIM_FLAG_CC2: TIM Capture Compare 2 Flag + * @arg TIM_FLAG_CC3: TIM Capture Compare 3 Flag + * @arg TIM_FLAG_CC4: TIM Capture Compare 4 Flag + * @arg TIM_FLAG_COM: TIM Commutation Flag + * @arg TIM_FLAG_Trigger: TIM Trigger Flag + * @arg TIM_FLAG_Break: TIM Break Flag + * @arg TIM_FLAG_CC1OF: TIM Capture Compare 1 overcapture Flag + * @arg TIM_FLAG_CC2OF: TIM Capture Compare 2 overcapture Flag + * @arg TIM_FLAG_CC3OF: TIM Capture Compare 3 overcapture Flag + * @arg TIM_FLAG_CC4OF: TIM Capture Compare 4 overcapture Flag + * @retval None. + */ +void TIM_ClearFlag(TIM_Type *tim, uint32_t flag) +{ + tim->SR &= ~flag; +} + +/** + * @brief Checks whether the TIM interrupt has occurred or not. + * @param tim: select the TIM peripheral. + * @param it: specifies the TIM interrupt source to check. + * This parameter can be one of the following values: + * @arg TIM_IT_Update: TIM update Interrupt source + * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source + * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source + * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source + * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source + * @arg TIM_IT_COM: TIM Commutation Interrupt source + * @arg TIM_IT_Trigger: TIM Trigger Interrupt source + * @arg TIM_IT_Break: TIM Break Interrupt source + * @retval State: The new state of the TIM_IT(SET or RESET). + */ +ITStatus TIM_GetITStatus(TIM_Type *tim, uint32_t it) +{ + return (((tim->SR &it) && (tim->DIER &it)) ? SET : RESET); +} + +/** + * @brief Clears the tim's interrupt pending bits. + * @param tim: select the TIM peripheral. + * @param it: specifies the pending bit to clear. + * This parameter can be any combination of the following values: + * @arg TIM_IT_Update: TIM update Interrupt source + * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source + * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source + * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source + * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source + * @arg TIM_IT_COM: TIM Commutation Interrupt source + * @arg TIM_IT_Trigger: TIM Trigger Interrupt source + * @arg TIM_IT_Break: TIM Break Interrupt source + * @note + * - TIM14, TIM16 and TIM17 can have TIM_IT_Update or TIM_IT_CC1. + * - TIM_IT_Break is used only with TIM1 and TIM8. + * - TIM_IT_COM is used only with TIM1, TIM8, TIM16 and TIM17. + * @retval None. + */ +void TIM_ClearITPendingBit(TIM_Type *tim, uint32_t it) +{ + tim->SR &= ~it; +} + +/** + * @brief Checks whether the specified TIM flag is set or not. + * @param tim: select the TIM peripheral. + * @retval None. + */ +FlagStatus TIM_GetCountDirection(TIM_Type *tim) +{ + return ((tim->CR1 &TIM_CR1_DIR_Msk) ? SET : RESET); +} + +/** + * @brief Clears or safeguards the OCREF1 signal on an external event + * @param tim: where tim can be 2,EPWM to select the TIM peripheral. + * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCClear_Enable: TIM Output clear enable + * @arg TIM_OCClear_Disable: TIM Output clear disable + * @retval None + */ +void TIM_ClearOC1Ref(TIM_Type *tim, uint16_t TIM_OCClear) +{ + REG_WRITE_MASK(TIM->CCMR1_OUTPUT, TIM_CCMR1_OUTPUT_OC1CE_Msk, TIM_OCClear); +} + +/** + * @brief Clears or safeguards the OCREF2 signal on an external event + * @param tim: where tim can be 2,EPWM to select the TIM peripheral. + * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCClear_Enable: TIM Output clear enable + * @arg TIM_OCClear_Disable: TIM Output clear disable + * @retval None + */ +void TIM_ClearOC2Ref(TIM_Type *tim, uint16_t TIM_OCClear) +{ + REG_WRITE_MASK(TIM->CCMR1_OUTPUT, TIM_CCMR1_OUTPUT_OC2CE_Msk, TIM_OCClear << 8); +} + +/** + * @brief Clears or safeguards the OCREF3 signal on an external event + * @param tim: where tim can be 2,EPWM to select the TIM peripheral. + * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCClear_Enable: TIM Output clear enable + * @arg TIM_OCClear_Disable: TIM Output clear disable + * @retval None + */ +void TIM_ClearOC3Ref(TIM_Type *tim, uint16_t TIM_OCClear) +{ + REG_WRITE_MASK(TIM->CCMR2_OUTPUT, TIM_CCMR2_OUTPUT_OC3CE_Msk, TIM_OCClear); +} + +/** + * @brief Clears or safeguards the OCREF4 signal on an external event + * @param tim: where tim can be 2,EPWM to select the TIM peripheral. + * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCClear_Enable: TIM Output clear enable + * @arg TIM_OCClear_Disable: TIM Output clear disable + * @retval None + */ +void TIM_ClearOC4Ref(TIM_Type *tim, uint16_t TIM_OCClear) +{ + REG_WRITE_MASK(TIM->CCMR2_OUTPUT, TIM_CCMR2_OUTPUT_OC4CE_Msk, TIM_OCClear << 8); +} + +#endif /* CONFIG_ENABLE_HAL_TIM2 || CONFIG_ENABLE_HAL_EPWM */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_uart.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_uart.c new file mode 100644 index 0000000..f51ccaa --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_uart.c @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_uart.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/10 + * @license + * @description + */ + + +#include "hal_device.h" + +#if defined(CONFIG_ENABLE_HAL_UART) +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +UART_ErrTypeDef UART_Init(UART_Type *pHUart, UART_InitTypeDef *pInit) +{ + uint32_t pclk = g_SystemCoreClock; + uint32_t baudrate = 0; + + if( pHUart == 0 || pInit == 0 ) + { + return UART_ERR_NULL_POINTER; + } + + if( pHUart == UART0 ) + { + __HAL_SYSCFG_UART0_CLK_ENABLE(); + __HAL_SYSCFG_RESET_UART0(); + } + + REG_WRITE(pHUart->CR, 0x0); + REG_WRITE(pHUart->IE, 0x0); + + UART_ResetRxFIFO(pHUart); + UART_ResetTxFIFO(pHUart); + + /** + * Uart->BR_b.BR should use algorithm to approach target baudrate + */ + baudrate = (pclk + (pInit->BaudRate * 8)) / (pInit->BaudRate * 16); + pHUart->BR = baudrate; + + REG_WRITE_MASK(pHUart->CR, + (UART_CR_MODE_Msk | UART_CR_STOPB_Msk | UART_CR_PAR_Msk | UART_CR_RXEN_Msk), + (pInit->WordLength | pInit->StopBits | pInit->Parity | pInit->Mode)); + + return UART_ERR_OK; +} + +void UART_SendData(UART_Type *pHUart, uint16_t value) +{ + pHUart->DAT_b.DAT = value; + return; +} + +uint16_t UART_ReceiveData(UART_Type *pHUart) +{ + return pHUart->DAT_b.DAT; +} + +UART_ErrTypeDef UART_ITConfig(UART_Type *pHUart, uint32_t flags, uint32_t is_enable) +{ + if( pHUart == 0 ) + return UART_ERR_NULL_POINTER; + + (is_enable) ? + REG_SET_BITS(pHUart->IE, flags) : + REG_CLR_BITS(pHUart->IE, flags); + + return UART_ERR_OK; +} + + + +#endif /* CONFIG_ENABLE_HAL_UART */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_wdg.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_wdg.c new file mode 100644 index 0000000..b1176a5 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_wdg.c @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_wdg.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + + +#include "hal_device.h" + +#if defined(CONFIG_ENABLE_HAL_WDG) + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +void WDG_StructInit(WDG_InitTypeDef *pInit) +{ + pInit->Counter = 0xFFFFFFFFul; + pInit->ResetMode = WDG_Reset_Disable; + return; +} + +void WDG_Init(WDG_InitTypeDef *pInit) +{ + __HAL_SYSCFG_RESET_WDG(); + __HAL_SYSCFG_WDG_CLK_ENABLE(); + + sys_close_IRQ(WDG_IRQn); + + WDG_Unlock(); + + REG_WRITE(WDG->LOAD, pInit->Counter); + REG_WRITE_MASK(WDG->CR, WDG_CR_RSTE_Msk, pInit->ResetMode); + REG_WRITE(WDG->INTCLR, 0x1ul); + + WDG_Lock(); + + return; +} + +void WDG_DeInit(void) +{ + __HAL_SYSCFG_WDG_CLK_DISABLE(); + __HAL_SYSCFG_RESET_WDG(); + + sys_close_IRQ(WDG_IRQn); + return; +} + +#endif /* CONFIG_ENABLE_HAL_WDG */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/.DS_Store b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/.DS_Store new file mode 100644 index 0000000..ab7b4bc Binary files /dev/null and b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/.DS_Store differ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/.DS_Store b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/.DS_Store new file mode 100644 index 0000000..6b4deef Binary files /dev/null and b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/.DS_Store differ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_compatiable.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_compatiable.h new file mode 100644 index 0000000..0b49812 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_compatiable.h @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __CORE_COMPATIABLE_H__ +#define __CORE_COMPATIABLE_H__ +/*! + * @file core_compatiable.h + * @brief ARM compatiable function definitions header file + */ +#ifdef __cplusplus + extern "C" { +#endif + +#include "core_feature_base.h" + +/* ===== ARM Compatiable Functions ===== */ +/** + * \defgroup NMSIS_Core_ARMCompatiable_Functions ARM Compatiable Functions + * \ingroup NMSIS_Core + * \brief A few functions that compatiable with ARM CMSIS-Core. + * \details + * + * Here we provided a few functions that compatiable with ARM CMSIS-Core, + * mostly used in the DSP and NN library. + * @{ + */ +/** \brief Instruction Synchronization Barrier, compatiable with ARM */ +#define __ISB() __RWMB() + +/** \brief Data Synchronization Barrier, compatiable with ARM */ +#define __DSB() __RWMB() + +/** \brief Data Memory Barrier, compatiable with ARM */ +#define __DMB() __RWMB() + +/** \brief LDRT Unprivileged (8 bit), ARM Compatiable */ +#define __LDRBT(ptr) __LB((ptr)) +/** \brief LDRT Unprivileged (16 bit), ARM Compatiable */ +#define __LDRHT(ptr) __LH((ptr)) +/** \brief LDRT Unprivileged (32 bit), ARM Compatiable */ +#define __LDRT(ptr) __LW((ptr)) + +/** \brief STRT Unprivileged (8 bit), ARM Compatiable */ +#define __STRBT(val, ptr) __SB((ptr), (val)) +/** \brief STRT Unprivileged (16 bit), ARM Compatiable */ +#define __STRHT(val, ptr) __SH((ptr), (val)) +/** \brief STRT Unprivileged (32 bit), ARM Compatiable */ +#define __STRT(val, ptr) __SW((ptr), (val)) + +/* ===== Saturation Operations ===== */ +/** + * \brief Signed Saturate + * \details Saturates a signed value. + * \param [in] value Value to be saturated + * \param [in] sat Bit position to saturate to (1..32) + * \return Saturated value + */ +#if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1) +#define __SSAT(val, sat) __RV_SCLIP32((val), (sat-1)) +#else +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) { + return max; + } else if (val < min) { + return min; + } + } + return val; +} +#endif + +/** + * \brief Unsigned Saturate + * \details Saturates an unsigned value. + * \param [in] value Value to be saturated + * \param [in] sat Bit position to saturate to (0..31) + * \return Saturated value + */ +#if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1) +#define __USAT(val, sat) __RV_UCLIP32((val), (sat)) +#else +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) { + return max; + } else if (val < 0) { + return 0U; + } + } + return (uint32_t)val; +} +#endif + +/* ===== Data Processing Operations ===== */ +/** + * \brief Reverse byte order (32 bit) + * \details Reverses the byte order in unsigned integer value. + * For example, 0x12345678 becomes 0x78563412. + * \param [in] value Value to reverse + * \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV(uint32_t value) +{ + uint32_t result; + + result = ((value & 0xff000000) >> 24) + | ((value & 0x00ff0000) >> 8 ) + | ((value & 0x0000ff00) << 8 ) + | ((value & 0x000000ff) << 24); + return result; +} + +/** + * \brief Reverse byte order (16 bit) + * \details Reverses the byte order within each halfword of a word. + * For example, 0x12345678 becomes 0x34127856. + * \param [in] value Value to reverse + * \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + result = ((value & 0xff000000) >> 8) + | ((value & 0x00ff0000) << 8 ) + | ((value & 0x0000ff00) >> 8 ) + | ((value & 0x000000ff) << 8) ; + + return result; +} + +/** + * \brief Reverse byte order (16 bit) + * \details Reverses the byte order in a 16-bit value + * and returns the signed 16-bit result. + * For example, 0x0080 becomes 0x8000. + * \param [in] value Value to reverse + * \return Reversed value + */ +__STATIC_FORCEINLINE int16_t __REVSH(int16_t value) +{ + int16_t result; + result = ((value & 0xff00) >> 8) | ((value & 0x00ff) << 8); + return result; +} + +/** + * \brief Rotate Right in unsigned value (32 bit) + * \details Rotate Right (immediate) provides the value of + * the contents of a register rotated by a variable number of bits. + * \param [in] op1 Value to rotate + * \param [in] op2 Number of Bits to rotate(0-31) + * \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 = op2 & 0x1F; + if (op2 == 0U) { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + +/** + * \brief Rotate Right in uint32x2 value (64 bit) + * \details Rotate Right (immediate) provides the value of + * the contents of a register rotated by a variable number of bits. + * \param [in] op1 Value to rotate([63:32] and [31:0] rotate separately) + * \param [in] op2 Number of Bits to rotate + * \return Rotated value([63:32] | [31:0]) + */ +__STATIC_FORCEINLINE uint64_t __ROR64(uint64_t op1, uint32_t op2) +{ + op2 = op2 & 0x1F; + if (op2 == 0U) { + return op1; + } + uint32_t tmp1 = (uint32_t)op1; + uint32_t tmp2 = (uint32_t)(op1 >> 32); + return (uint64_t)((tmp1 >> op2) | (tmp1 << (32U - op2))) + | ((uint64_t)((tmp2 >> op2) | (tmp2 << (32U - op2))) << 32); +} + +/** + * \brief Reverse bit order of value + * \details Reverses the bit order of the given value. + * \param [in] value Value to reverse + * \return Reversed value + */ +#if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1) +#define __RBIT(value) __RV_BITREVI((value), 31) +#else +__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ + return result; +} +#endif /* defined(__DSP_PRESENT) && (__DSP_PRESENT == 1) */ + +/** + * \brief Count leading zeros + * \details Counts the number of leading zeros of a data value. + * \param [in] data Value to count the leading zeros + * \return number of leading zeros in value + */ +#if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1) +#define __CLZ(data) __RV_CLZ32(data) +#else +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t data) +{ + uint8_t ret = 0; + uint32_t temp = ~data; + while (temp & 0x80000000) { + temp <<= 1; + ret++; + } + return ret; +} +#endif /* defined(__DSP_PRESENT) && (__DSP_PRESENT == 1) */ + +/** + * \brief Count tailing zero + * \details Return the count of least-significant bit zero.for example, return 3 if x=0bxxx1000 + * \param [in] data Value to count the tailing zeros + * \return number of tailing zeros in value + */ +__STATIC_FORCEINLINE unsigned long __CTZ(unsigned long data) +{ + unsigned long ret = 0; + + while (!(data & 1UL)) { + ret++; + data = data >> 1; + } + + return ret; +} + +/** + * \brief Expand byte to unsigned long value + * \details Expand byte value x to unsigned long value's each byte. + * \param [in] x the byte value to be expand, the input must be uint8_t type + * \return Expanded value in unsigned long + */ +#if __RISCV_XLEN == 32 +#define __EXPD_BYTE(x) ((unsigned long)(((unsigned long)(x) << 0) | \ + ((unsigned long)(x) << 8) | \ + ((unsigned long)(x) << 16) | \ + ((unsigned long)(x) << 24))) +#elif __RISCV_XLEN == 64 +#define __EXPD_BYTE(x) ((unsigned long)(((unsigned long)(x) << 0) | \ + ((unsigned long)(x) << 8) | \ + ((unsigned long)(x) << 16) | \ + ((unsigned long)(x) << 24) | \ + ((unsigned long)(x) << 32) | \ + ((unsigned long)(x) << 40) | \ + ((unsigned long)(x) << 48) | \ + ((unsigned long)(x) << 56))) +#endif + +/** @} */ /* End of Doxygen Group NMSIS_Core_ARMCompatiable_Functions */ + +#ifdef __cplusplus +} +#endif +#endif /* __CORE_COMPATIABLE_H__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_base.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_base.h new file mode 100644 index 0000000..0e6d24f --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_base.h @@ -0,0 +1,2245 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CORE_FEATURE_BASE__ +#define __CORE_FEATURE_BASE__ +/*! + * @file core_feature_base.h + * @brief Base core feature API for Nuclei N/NX Core + */ +/* + * Core Base Feature Configuration Macro: + * 1. __HARTID_OFFSET: Optional, define this macro when your cpu system first hart hartid and hart index is different. + * eg. If your cpu system, first hart hartid is 2, hart index is 0, then set this macro to 2 + * + */ +#include + +#ifdef __cplusplus + extern "C" { +#endif + +#include "nmsis_compiler.h" + +/** + * \defgroup NMSIS_Core_Registers Register Define and Type Definitions + * \brief Type definitions and defines for core registers. + * + * @{ + */ +#ifndef __RISCV_XLEN + /** \brief Refer to the width of an integer register in bits(either 32 or 64) */ + #ifndef __riscv_xlen + #define __RISCV_XLEN 32 + #else + #define __RISCV_XLEN __riscv_xlen + #endif +#endif /* __RISCV_XLEN */ + +/** \brief Type of Control and Status Register(CSR), depends on the XLEN defined in RISC-V */ +typedef unsigned long rv_csr_t; + +/** @} */ /* End of Doxygen Group NMSIS_Core_Registers */ +/** + * \defgroup NMSIS_Core_Base_Registers Base Register Define and Type Definitions + * \ingroup NMSIS_Core_Registers + * \brief Type definitions and defines for base core registers. + * + * @{ + */ +/** + * \brief Union type to access MISA CSR register. + */ +typedef union { + struct { + rv_csr_t a:1; /*!< bit: 0 Atomic extension */ + rv_csr_t b:1; /*!< bit: 1 Tentatively reserved for Bit-Manipulation extension */ + rv_csr_t c:1; /*!< bit: 2 Compressed extension */ + rv_csr_t d:1; /*!< bit: 3 Double-precision floating-point extension */ + rv_csr_t e:1; /*!< bit: 4 RV32E base ISA */ + rv_csr_t f:1; /*!< bit: 5 Single-precision floating-point extension */ + rv_csr_t g:1; /*!< bit: 6 Additional standard extensions present */ + rv_csr_t h:1; /*!< bit: 7 Hypervisor extension */ + rv_csr_t i:1; /*!< bit: 8 RV32I/64I/128I base ISA */ + rv_csr_t j:1; /*!< bit: 9 Tentatively reserved for Dynamically Translated Languages extension */ + rv_csr_t _reserved1:1; /*!< bit: 10 Reserved */ + rv_csr_t l:1; /*!< bit: 11 Tentatively reserved for Decimal Floating-Point extension */ + rv_csr_t m:1; /*!< bit: 12 Integer Multiply/Divide extension */ + rv_csr_t n:1; /*!< bit: 13 User-level interrupts supported */ + rv_csr_t _reserved2:1; /*!< bit: 14 Reserved */ + rv_csr_t p:1; /*!< bit: 15 Tentatively reserved for Packed-SIMD extension */ + rv_csr_t q:1; /*!< bit: 16 Quad-precision floating-point extension */ + rv_csr_t _resreved3:1; /*!< bit: 17 Reserved */ + rv_csr_t s:1; /*!< bit: 18 Supervisor mode implemented */ + rv_csr_t t:1; /*!< bit: 19 Tentatively reserved for Transactional Memory extension */ + rv_csr_t u:1; /*!< bit: 20 User mode implemented */ + rv_csr_t v:1; /*!< bit: 21 Tentatively reserved for Vector extension */ + rv_csr_t _reserved4:1; /*!< bit: 22 Reserved */ + rv_csr_t x:1; /*!< bit: 23 Non-standard extensions present */ +#if defined(__RISCV_XLEN) && __RISCV_XLEN == 64 + rv_csr_t _reserved5:38; /*!< bit: 24..61 Reserved */ + rv_csr_t mxl:2; /*!< bit: 62..63 Machine XLEN */ +#else + rv_csr_t _reserved5:6; /*!< bit: 24..29 Reserved */ + rv_csr_t mxl:2; /*!< bit: 30..31 Machine XLEN */ +#endif + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MISA_Type; + +/** + * \brief Union type to access MSTATUS CSR register. + */ +typedef union { + struct { +#if defined(__RISCV_XLEN) && __RISCV_XLEN == 64 + rv_csr_t _reserved0:3; /*!< bit: 0..2 Reserved */ + rv_csr_t mie:1; /*!< bit: 3 Machine mode interrupt enable flag */ + rv_csr_t _reserved1:3; /*!< bit: 4..6 Reserved */ + rv_csr_t mpie:1; /*!< bit: 7 mirror of MIE flag */ + rv_csr_t _reserved2:3; /*!< bit: 8..10 Reserved */ + rv_csr_t mpp:2; /*!< bit: 11..12 mirror of Privilege Mode */ + rv_csr_t fs:2; /*!< bit: 13..14 FS status flag */ + rv_csr_t xs:2; /*!< bit: 15..16 XS status flag */ + rv_csr_t mprv:1; /*!< bit: Machine mode PMP */ + rv_csr_t _reserved3:14; /*!< bit: 18..31 Reserved */ + rv_csr_t uxl:2; /*!< bit: 32..33 user mode xlen */ + rv_csr_t _reserved6:29; /*!< bit: 34..62 Reserved */ + rv_csr_t sd:1; /*!< bit: Dirty status for XS or FS */ +#else + rv_csr_t _reserved0:1; /*!< bit: 0 Reserved */ + rv_csr_t sie:1; /*!< bit: 1 supervisor interrupt enable flag */ + rv_csr_t _reserved1:1; /*!< bit: 2 Reserved */ + rv_csr_t mie:1; /*!< bit: 3 Machine mode interrupt enable flag */ + rv_csr_t _reserved2:1; /*!< bit: 4 Reserved */ + rv_csr_t spie:1; /*!< bit: 3 Supervisor Privilede mode interrupt enable flag */ + rv_csr_t _reserved3:1; /*!< bit: Reserved */ + rv_csr_t mpie:1; /*!< bit: mirror of MIE flag */ + rv_csr_t _reserved4:3; /*!< bit: Reserved */ + rv_csr_t mpp:2; /*!< bit: mirror of Privilege Mode */ + rv_csr_t fs:2; /*!< bit: FS status flag */ + rv_csr_t xs:2; /*!< bit: XS status flag */ + rv_csr_t mprv:1; /*!< bit: Machine mode PMP */ + rv_csr_t sum:1; /*!< bit: Supervisor Mode load and store protection */ + rv_csr_t _reserved6:12; /*!< bit: 19..30 Reserved */ + rv_csr_t sd:1; /*!< bit: Dirty status for XS or FS */ +#endif + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MSTATUS_Type; + +/** + * \brief Union type to access MTVEC CSR register. + */ +typedef union { + struct { + rv_csr_t mode:6; /*!< bit: 0..5 interrupt mode control */ +#if defined(__RISCV_XLEN) && __RISCV_XLEN == 64 + rv_csr_t addr:58; /*!< bit: 6..63 mtvec address */ +#else + rv_csr_t addr:26; /*!< bit: 6..31 mtvec address */ +#endif + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MTVEC_Type; + +/** + * \brief Union type to access MCAUSE CSR register. + */ +typedef union { + struct { + rv_csr_t exccode:12; /*!< bit: 11..0 exception or interrupt code */ + rv_csr_t _reserved0:4; /*!< bit: 15..12 Reserved */ + rv_csr_t mpil:8; /*!< bit: 23..16 Previous interrupt level */ + rv_csr_t _reserved1:3; /*!< bit: 26..24 Reserved */ + rv_csr_t mpie:1; /*!< bit: 27 Interrupt enable flag before enter interrupt */ + rv_csr_t mpp:2; /*!< bit: 29..28 Privilede mode flag before enter interrupt */ + rv_csr_t minhv:1; /*!< bit: 30 Machine interrupt vector table */ +#if defined(__RISCV_XLEN) && __RISCV_XLEN == 64 + rv_csr_t _reserved2:32; /*!< bit: 31..62 Reserved */ + rv_csr_t interrupt:1; /*!< bit: 63 trap type. 0 means exception and 1 means interrupt */ +#else + rv_csr_t interrupt:1; /*!< bit: 31 trap type. 0 means exception and 1 means interrupt */ +#endif + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MCAUSE_Type; + +/** + * \brief Union type to access MCOUNTINHIBIT CSR register. + */ +typedef union { + struct { + rv_csr_t cy:1; /*!< bit: 0 1 means disable mcycle counter */ + rv_csr_t _reserved0:1; /*!< bit: 1 Reserved */ + rv_csr_t ir:1; /*!< bit: 2 1 means disable minstret counter */ +#if defined(__RISCV_XLEN) && __RISCV_XLEN == 64 + rv_csr_t _reserved1:61; /*!< bit: 3..63 Reserved */ +#else + rv_csr_t _reserved1:29; /*!< bit: 3..31 Reserved */ +#endif + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MCOUNTINHIBIT_Type; + +/** + * \brief Union type to access MSUBM CSR register. + */ +typedef union { + struct { + rv_csr_t _reserved0:6; /*!< bit: 0..5 Reserved */ + rv_csr_t typ:2; /*!< bit: 6..7 current trap type */ + rv_csr_t ptyp:2; /*!< bit: 8..9 previous trap type */ +#if defined(__RISCV_XLEN) && __RISCV_XLEN == 64 + rv_csr_t _reserved1:54; /*!< bit: 10..63 Reserved */ +#else + rv_csr_t _reserved1:22; /*!< bit: 10..31 Reserved */ +#endif + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MSUBM_Type; + +/** + * \brief Union type to access MDCAUSE CSR register. + */ +typedef union { + struct { + rv_csr_t mdcause:3; /*!< bit: 0..2 More detailed exception information as MCAUSE supplement */ + rv_csr_t _reserved0:__RISCV_XLEN-3; /*!< bit: 3..XLEN-1 Reserved */ + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MDCAUSE_Type; + +/** + * \brief Union type to access MMISC_CTRL CSR register. + */ +typedef union { + struct { + rv_csr_t _reserved0:3; /*!< bit: 0..2 Reserved */ + rv_csr_t bpu:1; /*!< bit: 3 dynamic prediction enable flag */ + rv_csr_t _reserved1:2; /*!< bit: 4..5 Reserved */ + rv_csr_t misalign:1; /*!< bit: 6 misaligned access support flag */ + rv_csr_t zcmt_zcmp:1; /*!< bit: 7 Zc Ext uses the cfdsp of D Ext’s encoding or not */ + rv_csr_t core_buserr:1; /*!< bit: 8 core bus error exception or interrupt */ + rv_csr_t nmi_cause:1; /*!< bit: 9 mnvec control and nmi mcase exccode */ + rv_csr_t imreturn_en:1; /*!< bit: 10 IMRETURN mode of trace */ + rv_csr_t sijump_en:1; /*!< bit: 11 SIJUMP mode of trace */ + rv_csr_t ldspec_en:1; /*!< bit: 12 enable load speculative goes to mem interface */ + rv_csr_t _reserved2:1; /*!< bit: 13 Reserved */ + rv_csr_t dbg_sec:1; /*!< bit: 14 debug access mode */ + rv_csr_t _reserved3:__RISCV_XLEN-15; /*!< bit: 15..XLEN-1 Reserved */ + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MMISCCTRL_Type; + +typedef CSR_MMISCCTRL_Type CSR_MMISCCTL_Type; + +/** + * \brief Union type to access MCACHE_CTL CSR register. + */ +typedef union { + struct { + rv_csr_t ic_en:1; /*!< I-Cache enable */ + rv_csr_t ic_scpd_mod:1; /*!< Scratchpad mode, 0: Scratchpad as ICache Data RAM, 1: Scratchpad as ILM SRAM */ + rv_csr_t ic_ecc_en:1; /*!< I-Cache ECC enable */ + rv_csr_t ic_ecc_excp_en:1; /*!< I-Cache 2bit ECC error exception enable */ + rv_csr_t ic_rwtecc:1; /*!< Control I-Cache Tag Ram ECC code injection */ + rv_csr_t ic_rwdecc:1; /*!< Control I-Cache Data Ram ECC code injection */ + rv_csr_t ic_pf_en:1; /*!< I-Cache prefetch enable */ + rv_csr_t ic_cancel_en:1; /*!< I-Cache change flow canceling enable control */ + rv_csr_t ic_ecc_chk_en:1; /*!< I-Cache check ECC codes enable */ + rv_csr_t _reserved0:7; + rv_csr_t dc_en:1; /*!< DCache enable */ + rv_csr_t dc_ecc_en:1; /*!< D-Cache ECC enable */ + rv_csr_t dc_ecc_excp_en:1; /*!< D-Cache 2bit ECC error exception enable */ + rv_csr_t dc_rwtecc:1; /*!< Control D-Cache Tag Ram ECC code injection */ + rv_csr_t dc_rwdecc:1; /*!< Control D-Cache Data Ram ECC code injection */ + rv_csr_t dc_ecc_chk_en:1; /*!< D-Cache check ECC codes enable */ + rv_csr_t _reserved1:__RISCV_XLEN-22; + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MCACHECTL_Type; + +/** + * \brief Union type to access MSAVESTATUS CSR register. + */ +typedef union { + struct { + rv_csr_t mpie1:1; /*!< bit: 0 interrupt enable flag of fisrt level NMI/exception nestting */ + rv_csr_t mpp1:2; /*!< bit: 1..2 privilede mode of fisrt level NMI/exception nestting */ + rv_csr_t _reserved0:3; /*!< bit: 3..5 Reserved */ + rv_csr_t ptyp1:2; /*!< bit: 6..7 NMI/exception type of before first nestting */ + rv_csr_t mpie2:1; /*!< bit: 8 interrupt enable flag of second level NMI/exception nestting */ + rv_csr_t mpp2:2; /*!< bit: 9..10 privilede mode of second level NMI/exception nestting */ + rv_csr_t _reserved1:3; /*!< bit: 11..13 Reserved */ + rv_csr_t ptyp2:2; /*!< bit: 14..15 NMI/exception type of before second nestting */ +#if defined(__RISCV_XLEN) && __RISCV_XLEN == 64 + rv_csr_t _reserved2:48; /*!< bit: 16..63 Reserved*/ +#else + rv_csr_t _reserved2:16; /*!< bit: 16..31 Reserved*/ +#endif + } b; /*!< Structure used for bit access */ + rv_csr_t w; /*!< Type used for csr data access */ +} CSR_MSAVESTATUS_Type; + +/** + * \brief Union type to access MILM_CTL CSR register. + */ +typedef union { + struct { + rv_csr_t ilm_en:1; /*!< ILM enable */ + rv_csr_t ilm_ecc_en:1; /*!< ILM ECC eanble */ + rv_csr_t ilm_ecc_excp_en:1; /*!< ILM ECC exception enable */ + rv_csr_t ilm_rwecc:1; /*!< Control mecc_code write to ilm, simulate error injection */ + rv_csr_t ilm_ecc_chk_en:1; /*!< ILM check ECC codes enable */ + rv_csr_t _reserved0:5; /*!< Reserved */ + rv_csr_t ilm_bpa:__RISCV_XLEN-10; /*!< ILM base address */ + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MILMCTL_Type; + +/** + * \brief Union type to access MDLM_CTL CSR register. + */ +typedef union { + struct { + rv_csr_t dlm_en:1; /*!< DLM enable */ + rv_csr_t dlm_ecc_en:1; /*!< DLM ECC eanble */ + rv_csr_t dlm_ecc_excp_en:1; /*!< DLM ECC exception enable */ + rv_csr_t dlm_rwecc:1; /*!< Control mecc_code write to dlm, simulate error injection */ + rv_csr_t dlm_ecc_chk_en:1; /*!< DLM check ECC codes enable */ + rv_csr_t _reserved0:5; /*!< Reserved */ + rv_csr_t dlm_bpa:__RISCV_XLEN-10; /*!< DLM base address */ + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MDLMCTL_Type; + +/** + * \brief Union type to access MCFG_INFO CSR register. + */ +typedef union { + struct { + rv_csr_t tee:1; /*!< TEE present */ + rv_csr_t ecc:1; /*!< ECC present */ + rv_csr_t clic:1; /*!< CLIC present */ + rv_csr_t plic:1; /*!< PLIC present */ + rv_csr_t fio:1; /*!< FIO present */ + rv_csr_t ppi:1; /*!< PPI present */ + rv_csr_t nice:1; /*!< NICE present */ + rv_csr_t ilm:1; /*!< ILM present */ + rv_csr_t dlm:1; /*!< DLM present */ + rv_csr_t icache:1; /*!< ICache present */ + rv_csr_t dcache:1; /*!< DCache present */ + rv_csr_t smp:1; /*!< SMP present */ + rv_csr_t dsp_n1:1; /*!< DSP N1 present */ + rv_csr_t dsp_n2:1; /*!< DSP N2 present */ + rv_csr_t dsp_n3:1; /*!< DSP N3 present */ + rv_csr_t zc_xlcz:1; /*!< Zc and xlcz extension present */ + rv_csr_t iregion:1; /*!< IREGION present */ + rv_csr_t vpu_degree:2; /*!< Indicate the VPU degree of parallel */ + rv_csr_t sec_mode:1; /*!< Smwg extension present */ + rv_csr_t etrace:1; /*!< Etrace present */ + rv_csr_t safety_mecha:2; /*!< Indicate Core's safety mechanism */ + rv_csr_t vnice:1; /*!< VNICE present */ + rv_csr_t _reserved1:__RISCV_XLEN-24; + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MCFGINFO_Type; + +/** + * \brief Union type to access MICFG_INFO CSR register. + */ +typedef union { + struct { + rv_csr_t set:4; /*!< I-Cache sets per way */ + rv_csr_t way:3; /*!< I-Cache way */ + rv_csr_t lsize:3; /*!< I-Cache line size */ + rv_csr_t _reserved0:6; + rv_csr_t lm_size:5; /*!< ILM size, need to be 2^n size */ + rv_csr_t lm_xonly:1; /*!< ILM Execute only permission */ + rv_csr_t lm_ecc:1; /*!< ILM ECC present */ + rv_csr_t _reserved1:__RISCV_XLEN-23; + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MICFGINFO_Type; + +/** + * \brief Union type to access MDCFG_INFO CSR register. + */ +typedef union { + struct { + rv_csr_t set:4; /*!< D-Cache sets per way */ + rv_csr_t way:3; /*!< D-Cache way */ + rv_csr_t lsize:3; /*!< D-Cache line size */ + rv_csr_t _reserved0:6; + rv_csr_t lm_size:5; /*!< DLM size, need to be 2^n size */ + rv_csr_t lm_ecc:1; /*!< DLM ECC present */ + rv_csr_t _reserved1:__RISCV_XLEN-22; + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MDCFGINFO_Type; + +/** + * \brief Union type to access MTLBCFG_INFO CSR register. + */ +typedef union { + struct { + rv_csr_t set:4; /*!< Main TLB sets per way */ + rv_csr_t way:3; /*!< Main TLB ways */ + rv_csr_t lsize:3; /*!< Main TLB line size */ + rv_csr_t ecc:1; /*!< Main TLB supports ECC or not */ + rv_csr_t _reserved0:5; /*!< Reserved 0 */ + rv_csr_t i_size:3; /*!< ITLB size */ + rv_csr_t d_size:3; /*!< DTLB size */ + rv_csr_t _reserved1:__RISCV_XLEN-22; /*!< Reserved 0 */ + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MTLBCFGINFO_Type; + +/** + * \brief Union type to access MPPICFG_INFO CSR register. + */ +typedef union { + struct { + rv_csr_t _reserved0:1; /*!< Reserved 1 */ + rv_csr_t ppi_size:5; /*!< PPI size, need to be 2^n size */ + rv_csr_t _reserved1:4; /*!< Reserved 0 */ + rv_csr_t ppi_bpa:__RISCV_XLEN-10; /*!< PPI base address */ + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MPPICFGINFO_Type; + +/** + * \brief Union type to access MFIOCFG_INFO CSR register. + */ +typedef union { + struct { + rv_csr_t _reserved0:1; /*!< Reserved */ + rv_csr_t fio_size:5; /*!< FIO size, need to be 2^n size */ + rv_csr_t _reserved1:4; /*!< Reserved */ + rv_csr_t fio_bpa:__RISCV_XLEN-10; /*!< FIO base address */ + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MFIOCFGINFO_Type; + +/** + * \brief Union type to access MECC_LOCK CSR register. + */ +typedef union { + struct { + rv_csr_t ecc_lock:1; /*!< RW permission, ECC Lock configure */ + rv_csr_t _reserved0:__RISCV_XLEN-1; /*!< Reserved */ + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MECCLOCK_Type; + +/** + * \brief Union type to access MECC_CODE CSR register. + */ +typedef union { + struct { + rv_csr_t code:9; /*!< Used to inject ECC check code */ + rv_csr_t _reserved0:7; /*!< Reserved 0 */ + rv_csr_t ramid:5; /*!< The ID of RAM that has 2bit ECC error, software can clear these bits */ + rv_csr_t _reserved1:3; /*!< Reserved 0 */ + rv_csr_t sramid:5; /*!< The ID of RAM that has 1bit ECC error, software can clear these bits */ + rv_csr_t _reserved2:__RISCV_XLEN-29; /*!< Reserved 0 */ + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MECCCODE_Type; + +/** @} */ /* End of Doxygen Group NMSIS_Core_Base_Registers */ + +/* ########################### Core Function Access ########################### */ +/** + * \defgroup NMSIS_Core_CSR_Register_Access Core CSR Register Access + * \ingroup NMSIS_Core + * \brief Functions to access the Core CSR Registers + * \details + * + * The following functions or macros provide access to Core CSR registers. + * - \ref NMSIS_Core_CSR_Encoding + * - \ref NMSIS_Core_CSR_Registers + * @{ + */ + + +#ifndef __ASSEMBLY__ + +#ifndef __ICCRISCV__ + +/** + * \brief CSR operation Macro for csrrw instruction. + * \details + * Read the content of csr register to __v, + * then write content of val into csr register, then return __v + * \param csr CSR macro definition defined in + * \ref NMSIS_Core_CSR_Registers, eg. \ref CSR_MSTATUS + * \param val value to store into the CSR register + * \return the CSR register value before written + */ +#define __RV_CSR_SWAP(csr, val) \ + ({ \ + rv_csr_t __v = (unsigned long)(val); \ + __ASM volatile("csrrw %0, " STRINGIFY(csr) ", %1" \ + : "=r"(__v) \ + : "rK"(__v) \ + : "memory"); \ + __v; \ + }) + +/** + * \brief CSR operation Macro for csrr instruction. + * \details + * Read the content of csr register to __v and return it + * \param csr CSR macro definition defined in + * \ref NMSIS_Core_CSR_Registers, eg. \ref CSR_MSTATUS + * \return the CSR register value + */ +#define __RV_CSR_READ(csr) \ + ({ \ + rv_csr_t __v; \ + __ASM volatile("csrr %0, " STRINGIFY(csr) \ + : "=r"(__v) \ + : \ + : "memory"); \ + __v; \ + }) + +/** + * \brief CSR operation Macro for csrw instruction. + * \details + * Write the content of val to csr register + * \param csr CSR macro definition defined in + * \ref NMSIS_Core_CSR_Registers, eg. \ref CSR_MSTATUS + * \param val value to store into the CSR register + */ +#define __RV_CSR_WRITE(csr, val) \ + ({ \ + rv_csr_t __v = (rv_csr_t)(val); \ + __ASM volatile("csrw " STRINGIFY(csr) ", %0" \ + : \ + : "rK"(__v) \ + : "memory"); \ + }) + +/** + * \brief CSR operation Macro for csrrs instruction. + * \details + * Read the content of csr register to __v, + * then set csr register to be __v | val, then return __v + * \param csr CSR macro definition defined in + * \ref NMSIS_Core_CSR_Registers, eg. \ref CSR_MSTATUS + * \param val Mask value to be used wih csrrs instruction + * \return the CSR register value before written + */ +#define __RV_CSR_READ_SET(csr, val) \ + ({ \ + rv_csr_t __v = (rv_csr_t)(val); \ + __ASM volatile("csrrs %0, " STRINGIFY(csr) ", %1" \ + : "=r"(__v) \ + : "rK"(__v) \ + : "memory"); \ + __v; \ + }) + +/** + * \brief CSR operation Macro for csrs instruction. + * \details + * Set csr register to be csr_content | val + * \param csr CSR macro definition defined in + * \ref NMSIS_Core_CSR_Registers, eg. \ref CSR_MSTATUS + * \param val Mask value to be used wih csrs instruction + */ +#define __RV_CSR_SET(csr, val) \ + ({ \ + rv_csr_t __v = (rv_csr_t)(val); \ + __ASM volatile("csrs " STRINGIFY(csr) ", %0" \ + : \ + : "rK"(__v) \ + : "memory"); \ + }) + +/** + * \brief CSR operation Macro for csrrc instruction. + * \details + * Read the content of csr register to __v, + * then set csr register to be __v & ~val, then return __v + * \param csr CSR macro definition defined in + * \ref NMSIS_Core_CSR_Registers, eg. \ref CSR_MSTATUS + * \param val Mask value to be used wih csrrc instruction + * \return the CSR register value before written + */ +#define __RV_CSR_READ_CLEAR(csr, val) \ + ({ \ + rv_csr_t __v = (rv_csr_t)(val); \ + __ASM volatile("csrrc %0, " STRINGIFY(csr) ", %1" \ + : "=r"(__v) \ + : "rK"(__v) \ + : "memory"); \ + __v; \ + }) + +/** + * \brief CSR operation Macro for csrc instruction. + * \details + * Set csr register to be csr_content & ~val + * \param csr CSR macro definition defined in + * \ref NMSIS_Core_CSR_Registers, eg. \ref CSR_MSTATUS + * \param val Mask value to be used wih csrc instruction + */ +#define __RV_CSR_CLEAR(csr, val) \ + ({ \ + rv_csr_t __v = (rv_csr_t)(val); \ + __ASM volatile("csrc " STRINGIFY(csr) ", %0" \ + : \ + : "rK"(__v) \ + : "memory"); \ + }) +#else + +#include + +#define __RV_CSR_SWAP __write_csr +#define __RV_CSR_READ __read_csr +#define __RV_CSR_WRITE __write_csr +#define __RV_CSR_READ_SET __set_bits_csr +#define __RV_CSR_SET __set_bits_csr +#define __RV_CSR_READ_CLEAR __clear_bits_csr +#define __RV_CSR_CLEAR __clear_bits_csr + +#endif /* __ICCRISCV__ */ + +#endif /* __ASSEMBLY__ */ + +/** + * \brief switch privilege from machine mode to others. + * \details + * Execute into \ref entry_point in \ref mode(supervisor or user) with given stack + * \param mode privilege mode + * \param stack predefined stack, size should set enough + * \param entry_point a function pointer to execute + */ +__STATIC_FORCEINLINE void __switch_mode(uint8_t mode, uintptr_t stack, void(*entry_point)(void)) +{ + unsigned long val = 0; + + /* Set MPP to the requested privilege mode */ + val = __RV_CSR_READ(CSR_MSTATUS); + val = __RV_INSERT_FIELD(val, MSTATUS_MPP, mode); + + /* Set previous MIE disabled */ + val = __RV_INSERT_FIELD(val, MSTATUS_MPIE, 0); + + __RV_CSR_WRITE(CSR_MSTATUS, val); + + /* Set the entry point in MEPC */ + __RV_CSR_WRITE(CSR_MEPC, (unsigned long)entry_point); + + /* Set the register file */ + __ASM volatile("mv sp, %0" ::"r"(stack)); + + __ASM volatile("mret"); +} + +/** + * \brief Enable IRQ Interrupts + * \details Enables IRQ interrupts by setting the MIE-bit in the MSTATUS Register. + * \remarks + * Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __RV_CSR_SET(CSR_MSTATUS, MSTATUS_MIE); +} + +/** + * \brief Disable IRQ Interrupts + * \details Disables IRQ interrupts by clearing the MIE-bit in the MSTATUS Register. + * \remarks + * Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __RV_CSR_CLEAR(CSR_MSTATUS, MSTATUS_MIE); +} + +/** + * \brief Enable External IRQ Interrupts + * \details Enables External IRQ interrupts by setting the MEIE-bit in the MIE Register. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __enable_ext_irq(void) +{ + __RV_CSR_SET(CSR_MIE, MIE_MEIE); +} + +/** + * \brief Disable External IRQ Interrupts + * \details Disables External IRQ interrupts by clearing the MEIE-bit in the MIE Register. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __disable_ext_irq(void) +{ + __RV_CSR_CLEAR(CSR_MIE, MIE_MEIE); +} + +/** + * \brief Enable Timer IRQ Interrupts + * \details Enables Timer IRQ interrupts by setting the MTIE-bit in the MIE Register. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __enable_timer_irq(void) +{ + __RV_CSR_SET(CSR_MIE, MIE_MTIE); +} + +/** + * \brief Disable Timer IRQ Interrupts + * \details Disables Timer IRQ interrupts by clearing the MTIE-bit in the MIE Register. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __disable_timer_irq(void) +{ + __RV_CSR_CLEAR(CSR_MIE, MIE_MTIE); +} + +/** + * \brief Enable software IRQ Interrupts + * \details Enables software IRQ interrupts by setting the MSIE-bit in the MIE Register. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __enable_sw_irq(void) +{ + __RV_CSR_SET(CSR_MIE, MIE_MSIE); +} + +/** + * \brief Disable software IRQ Interrupts + * \details Disables software IRQ interrupts by clearing the MSIE-bit in the MIE Register. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __disable_sw_irq(void) +{ + __RV_CSR_CLEAR(CSR_MIE, MIE_MSIE); +} + +/** + * \brief Disable Core IRQ Interrupt + * \details Disable Core IRQ interrupt by clearing the irq bit in the MIE Register. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __disable_core_irq(uint32_t irq) +{ + __RV_CSR_CLEAR(CSR_MIE, 1 << irq); +} + +/** + * \brief Enable Core IRQ Interrupt + * \details Enable Core IRQ interrupt by setting the irq bit in the MIE Register. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __enable_core_irq(uint32_t irq) +{ + __RV_CSR_SET(CSR_MIE, 1 << irq); +} + +/** + * \brief Get Core IRQ Interrupt Pending status + * \details Get Core IRQ interrupt pending status of irq bit. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE uint32_t __get_core_irq_pending(uint32_t irq) +{ + return ((__RV_CSR_READ(CSR_MIP) >> irq) & 0x1); +} + +/** + * \brief Clear Core IRQ Interrupt Pending status + * \details Clear Core IRQ interrupt pending status of irq bit. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __clear_core_irq_pending(uint32_t irq) +{ + __RV_CSR_SET(CSR_MIP, 1 << irq); +} + +/** + * \brief Enable IRQ Interrupts in supervisor mode + * \details Enables IRQ interrupts by setting the SIE-bit in the SSTATUS Register. + * \remarks + * Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_irq_s(void) +{ + __RV_CSR_SET(CSR_SSTATUS, SSTATUS_SIE); +} + +/** + * \brief Disable IRQ Interrupts in supervisor mode + * \details Disables IRQ interrupts by clearing the SIE-bit in the SSTATUS Register. + * \remarks + * Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_irq_s(void) +{ + __RV_CSR_CLEAR(CSR_SSTATUS, SSTATUS_SIE); +} + +/** + * \brief Enable External IRQ Interrupts in supervisor mode + * \details Enables External IRQ interrupts by setting the SEIE-bit in the SIE Register. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __enable_ext_irq_s(void) +{ + __RV_CSR_SET(CSR_SIE, MIE_SEIE); +} + +/** + * \brief Disable External IRQ Interrupts in supervisor mode + * \details Disables External IRQ interrupts by clearing the SEIE-bit in the SIE Register. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __disable_ext_irq_s(void) +{ + __RV_CSR_CLEAR(CSR_SIE, MIE_SEIE); +} + +/** + * \brief Enable Timer IRQ Interrupts in supervisor mode + * \details Enables Timer IRQ interrupts by setting the STIE-bit in the SIE Register. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __enable_timer_irq_s(void) +{ + __RV_CSR_SET(CSR_SIE, MIE_STIE); +} + +/** + * \brief Disable Timer IRQ Interrupts in supervisor mode + * \details Disables Timer IRQ interrupts by clearing the STIE-bit in the SIE Register. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __disable_timer_irq_s(void) +{ + __RV_CSR_CLEAR(CSR_SIE, MIE_STIE); +} + +/** + * \brief Enable software IRQ Interrupts in supervisor mode + * \details Enables software IRQ interrupts by setting the SSIE-bit in the SIE Register. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __enable_sw_irq_s(void) +{ + __RV_CSR_SET(CSR_MIE, MIE_SSIE); +} + +/** + * \brief Disable software IRQ Interrupts in supervisor mode + * \details Disables software IRQ interrupts by clearing the SSIE-bit in the SIE Register. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __disable_sw_irq_s(void) +{ + __RV_CSR_CLEAR(CSR_SIE, MIE_SSIE); +} + +/** + * \brief Disable Core IRQ Interrupt in supervisor mode + * \details Disable Core IRQ interrupt by clearing the irq bit in the SIE Register. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __disable_core_irq_s(uint32_t irq) +{ + __RV_CSR_CLEAR(CSR_SIE, 1 << irq); +} + +/** + * \brief Enable Core IRQ Interrupt in supervisor mode + * \details Enable Core IRQ interrupt by setting the irq bit in the MIE Register. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __enable_core_irq_s(uint32_t irq) +{ + __RV_CSR_SET(CSR_SIE, 1 << irq); +} + +/** + * \brief Get Core IRQ Interrupt Pending status in supervisor mode + * \details Get Core IRQ interrupt pending status of irq bit. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE uint32_t __get_core_irq_pending_s(uint32_t irq) +{ + return ((__RV_CSR_READ(CSR_SIP) >> irq) & 0x1); +} + +/** + * \brief Clear Core IRQ Interrupt Pending status in supervisor mode + * \details Clear Core IRQ interrupt pending status of irq bit. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __clear_core_irq_pending_s(uint32_t irq) +{ + __RV_CSR_SET(CSR_SIP, 1 << irq); +} + +/** + * \brief Read whole 64 bits value of mcycle counter + * \details This function will read the whole 64 bits of MCYCLE register + * \return The whole 64 bits value of MCYCLE + * \remarks It will work for both RV32 and RV64 to get full 64bits value of MCYCLE + */ +__STATIC_FORCEINLINE uint64_t __get_rv_cycle(void) +{ +#if __RISCV_XLEN == 32 + volatile uint32_t high0, low, high; + uint64_t full; + + high0 = __RV_CSR_READ(CSR_MCYCLEH); + low = __RV_CSR_READ(CSR_MCYCLE); + high = __RV_CSR_READ(CSR_MCYCLEH); + if (high0 != high) { + low = __RV_CSR_READ(CSR_MCYCLE); + } + full = (((uint64_t)high) << 32) | low; + return full; +#elif __RISCV_XLEN == 64 + return (uint64_t)__RV_CSR_READ(CSR_MCYCLE); +#else // TODO Need cover for XLEN=128 case in future + return (uint64_t)__RV_CSR_READ(CSR_MCYCLE); +#endif +} + +/** + * \brief Set whole 64 bits value of mcycle counter + * \details This function will set the whole 64 bits of MCYCLE register + * \remarks It will work for both RV32 and RV64 to set full 64bits value of MCYCLE + */ +__STATIC_FORCEINLINE void __set_rv_cycle(uint64_t cycle) +{ +#if __RISCV_XLEN == 32 + __RV_CSR_WRITE(CSR_MCYCLE, 0); // prevent carry + __RV_CSR_WRITE(CSR_MCYCLEH, (uint32_t)(cycle >> 32)); + __RV_CSR_WRITE(CSR_MCYCLE, (uint32_t)(cycle)); +#elif __RISCV_XLEN == 64 + __RV_CSR_WRITE(CSR_MCYCLE, cycle); +#else // TODO Need cover for XLEN=128 case in future +#endif +} + +/** + * \brief Read whole 64 bits value of machine instruction-retired counter + * \details This function will read the whole 64 bits of MINSTRET register + * \return The whole 64 bits value of MINSTRET + * \remarks It will work for both RV32 and RV64 to get full 64bits value of MINSTRET + */ +__STATIC_FORCEINLINE uint64_t __get_rv_instret(void) +{ +#if __RISCV_XLEN == 32 + volatile uint32_t high0, low, high; + uint64_t full; + + high0 = __RV_CSR_READ(CSR_MINSTRETH); + low = __RV_CSR_READ(CSR_MINSTRET); + high = __RV_CSR_READ(CSR_MINSTRETH); + if (high0 != high) { + low = __RV_CSR_READ(CSR_MINSTRET); + } + full = (((uint64_t)high) << 32) | low; + return full; +#elif __RISCV_XLEN == 64 + return (uint64_t)__RV_CSR_READ(CSR_MINSTRET); +#else // TODO Need cover for XLEN=128 case in future + return (uint64_t)__RV_CSR_READ(CSR_MINSTRET); +#endif +} + +/** + * \brief Set whole 64 bits value of machine instruction-retired counter + * \details This function will set the whole 64 bits of MINSTRET register + * \remarks It will work for both RV32 and RV64 to set full 64bits value of MINSTRET + */ +__STATIC_FORCEINLINE void __set_rv_instret(uint64_t instret) +{ +#if __RISCV_XLEN == 32 + __RV_CSR_WRITE(CSR_MINSTRET, 0); // prevent carry + __RV_CSR_WRITE(CSR_MINSTRETH, (uint32_t)(instret >> 32)); + __RV_CSR_WRITE(CSR_MINSTRET, (uint32_t)(instret)); +#elif __RISCV_XLEN == 64 + __RV_CSR_WRITE(CSR_MINSTRET, instret); +#else // TODO Need cover for XLEN=128 case in future +#endif +} + +/** + * \brief Read whole 64 bits value of real-time clock + * \details This function will read the whole 64 bits of TIME register + * \return The whole 64 bits value of TIME CSR + * \remarks It will work for both RV32 and RV64 to get full 64bits value of TIME + * \attention only available when user mode available + */ +__STATIC_FORCEINLINE uint64_t __get_rv_time(void) +{ +#if __RISCV_XLEN == 32 + volatile uint32_t high0, low, high; + uint64_t full; + + high0 = __RV_CSR_READ(CSR_TIMEH); + low = __RV_CSR_READ(CSR_TIME); + high = __RV_CSR_READ(CSR_TIMEH); + if (high0 != high) { + low = __RV_CSR_READ(CSR_TIME); + } + full = (((uint64_t)high) << 32) | low; + return full; +#elif __RISCV_XLEN == 64 + return (uint64_t)__RV_CSR_READ(CSR_TIME); +#else // TODO Need cover for XLEN=128 case in future + return (uint64_t)__RV_CSR_READ(CSR_TIME); +#endif +} + +/** + * \brief Get cluster id of current cluster + * \details This function will get cluster id of current cluster in a multiple cluster system + * \return The cluster id of current cluster + * \remarks mhartid bit 15-8 is designed for cluster id in nuclei subsystem reference design + * \attention function is allowed in machine mode only + */ +__STATIC_FORCEINLINE unsigned long __get_cluster_id(void) +{ + unsigned long id; + + id = (__RV_CSR_READ(CSR_MHARTID) >> 8) & 0xFF; + return id; +} + +/** + * \brief Get hart index of current cluster + * \details This function will get hart index of current cluster in a multiple cluster system, + * hart index is hartid - hartid offset, for example if your hartid is 1, and offset is 1, then + * hart index is 0 + * \return The hart index of current cluster + * \attention function is allowed in machine mode only + */ +__STATIC_FORCEINLINE unsigned long __get_hart_index(void) +{ + unsigned long id; +#ifdef __HARTID_OFFSET + id = __RV_CSR_READ(CSR_MHARTID) - __HARTID_OFFSET; +#else + id = __RV_CSR_READ(CSR_MHARTID); +#endif + return id; +} + +/** + * \brief Get hart id of current cluster + * \details This function will get hart id of current cluster in a multiple cluster system + * \return The hart id of current cluster + * \remarks it will return full hartid not part of it for reference subsystem design, + * if your reference subsystem design has hartid offset, please define __HARTID_OFFSET in + * .h + * \attention function is allowed in machine mode only + */ +__STATIC_FORCEINLINE unsigned long __get_hart_id(void) +{ + unsigned long id; + id = __RV_CSR_READ(CSR_MHARTID); + return id; +} + +/** @} */ /* End of Doxygen Group NMSIS_Core_CSR_Register_Access */ + +/* ########################### CPU Intrinsic Functions ########################### */ +/** + * \defgroup NMSIS_Core_CPU_Intrinsic Intrinsic Functions for CPU Intructions + * \ingroup NMSIS_Core + * \brief Functions that generate RISC-V CPU instructions. + * \details + * + * The following functions generate specified RISC-V instructions that cannot be directly accessed by compiler. + * @{ + */ + +/** + * \brief NOP Instruction + * \details + * No Operation does nothing. + * This instruction can be used for code alignment purposes. + */ +__STATIC_FORCEINLINE void __NOP(void) +{ + __ASM volatile("nop"); +} + +/** + * \brief Wait For Interrupt + * \details + * Wait For Interrupt is is executed using CSR_WFE.WFE=0 and WFI instruction. + * It will suspends execution until interrupt, NMI or Debug happened. + * When Core is waked up by interrupt, if + * 1. mstatus.MIE == 1(interrupt enabled), Core will enter ISR code + * 2. mstatus.MIE == 0(interrupt disabled), Core will resume previous execution + */ +__STATIC_FORCEINLINE void __WFI(void) +{ + __RV_CSR_CLEAR(CSR_WFE, WFE_WFE); + __ASM volatile("wfi"); +} + +/** + * \brief Wait For Event + * \details + * Wait For Event is executed using CSR_WFE.WFE=1 and WFI instruction. + * It will suspends execution until event, NMI or Debug happened. + * When Core is waked up, Core will resume previous execution + */ +__STATIC_FORCEINLINE void __WFE(void) +{ + __RV_CSR_SET(CSR_WFE, WFE_WFE); + __ASM volatile("wfi"); + __RV_CSR_CLEAR(CSR_WFE, WFE_WFE); +} + +/** + * \brief Breakpoint Instruction + * \details + * Causes the processor to enter Debug state. + * Debug tools can use this to investigate system state + * when the instruction at a particular address is reached. + */ +__STATIC_FORCEINLINE void __EBREAK(void) +{ + __ASM volatile("ebreak"); +} + +/** + * \brief Environment Call Instruction + * \details + * The ECALL instruction is used to make a service request to + * the execution environment. + */ +__STATIC_FORCEINLINE void __ECALL(void) +{ + __ASM volatile("ecall"); +} + +/** + * \brief WFI Sleep Mode enumeration + */ +typedef enum WFI_SleepMode { + WFI_SHALLOW_SLEEP = 0, /*!< Shallow sleep mode, the core_clk will poweroff */ + WFI_DEEP_SLEEP = 1 /*!< Deep sleep mode, the core_clk and core_ano_clk will poweroff */ +} WFI_SleepMode_Type; + +/** + * \brief Set Sleep mode of WFI + * \details + * Set the SLEEPVALUE CSR register to control the + * WFI Sleep mode. + * \param[in] mode The sleep mode to be set + */ +__STATIC_FORCEINLINE void __set_wfi_sleepmode(WFI_SleepMode_Type mode) +{ + __RV_CSR_WRITE(CSR_SLEEPVALUE, mode); +} + +/** + * \brief Send TX Event + * \details + * Set the CSR TXEVT to control send a TX Event. + * The Core will output signal tx_evt as output event signal. + */ +__STATIC_FORCEINLINE void __TXEVT(void) +{ + __RV_CSR_SET(CSR_TXEVT, 0x1); +} + +/** + * \brief Enable MCYCLE counter + * \details + * Clear the CY bit of MCOUNTINHIBIT to 0 to enable MCYCLE Counter + */ +__STATIC_FORCEINLINE void __enable_mcycle_counter(void) +{ + __RV_CSR_CLEAR(CSR_MCOUNTINHIBIT, MCOUNTINHIBIT_CY); +} + +/** + * \brief Disable MCYCLE counter + * \details + * Set the CY bit of MCOUNTINHIBIT to 1 to disable MCYCLE Counter + */ +__STATIC_FORCEINLINE void __disable_mcycle_counter(void) +{ + __RV_CSR_SET(CSR_MCOUNTINHIBIT, MCOUNTINHIBIT_CY); +} + +/** + * \brief Enable MINSTRET counter + * \details + * Clear the IR bit of MCOUNTINHIBIT to 0 to enable MINSTRET Counter + */ +__STATIC_FORCEINLINE void __enable_minstret_counter(void) +{ + __RV_CSR_CLEAR(CSR_MCOUNTINHIBIT, MCOUNTINHIBIT_IR); +} + +/** + * \brief Disable MINSTRET counter + * \details + * Set the IR bit of MCOUNTINHIBIT to 1 to disable MINSTRET Counter + */ +__STATIC_FORCEINLINE void __disable_minstret_counter(void) +{ + __RV_CSR_SET(CSR_MCOUNTINHIBIT, MCOUNTINHIBIT_IR); +} + +/** + * \brief Enable selected hardware performance monitor counter + * \param [in] idx the index of the hardware performance monitor counter + * \details + * enable selected hardware performance monitor counter mhpmcounterx. + */ +__STATIC_FORCEINLINE void __enable_mhpm_counter(unsigned long idx) +{ + __RV_CSR_CLEAR(CSR_MCOUNTINHIBIT, (1 << idx)); +} + +/** + * \brief Disable selected hardware performance monitor counter + * \param [in] idx the index of the hardware performance monitor counter + * \details + * Disable selected hardware performance monitor counter mhpmcounterx. + */ +__STATIC_FORCEINLINE void __disable_mhpm_counter(unsigned long idx) +{ + __RV_CSR_SET(CSR_MCOUNTINHIBIT, (1 << idx)); +} + +/** + * \brief Enable hardware performance counters with mask + * \param [in] mask mask of selected hardware performance monitor counters + * \details + * enable mhpmcounterx with mask, only the masked ones will be enabled. + * mhpmcounter3-mhpmcount31 are for high performance monitor counters. + */ +__STATIC_FORCEINLINE void __enable_mhpm_counters(unsigned long mask) +{ + __RV_CSR_CLEAR(CSR_MCOUNTINHIBIT, mask); +} + +/** + * \brief Disable hardware performance counters with mask + * \param [in] mask mask of selected hardware performance monitor counters + * \details + * Disable mhpmcounterx with mask, only the masked ones will be disabled. + * mhpmcounter3-mhpmcount31 are for high performance monitor counters. + */ +__STATIC_FORCEINLINE void __disable_mhpm_counters(unsigned long mask) +{ + __RV_CSR_SET(CSR_MCOUNTINHIBIT, mask); +} + +/** + * \brief Enable all MCYCLE & MINSTRET & MHPMCOUNTER counter + * \details + * Clear all to zero to enable all counters, + * such as cycle, instret, high performance monitor counters + */ +__STATIC_FORCEINLINE void __enable_all_counter(void) +{ + __RV_CSR_CLEAR(CSR_MCOUNTINHIBIT, 0xFFFFFFFF); +} + +/** + * \brief Disable all MCYCLE & MINSTRET & MHPMCOUNTER counter + * \details + * Set all to one to disable all counters, + * such as cycle, instret, high performance monitor counters + */ +__STATIC_FORCEINLINE void __disable_all_counter(void) +{ + __RV_CSR_SET(CSR_MCOUNTINHIBIT, 0xFFFFFFFF); +} + +/** + * \brief Set event for selected high performance monitor event + * \param [in] idx HPMEVENTx CSR index(3-31) + * \param [in] event HPMEVENTx Register value to set + * \details + * Set event for high performance monitor event register + */ +__STATIC_FORCEINLINE void __set_hpm_event(unsigned long idx, unsigned long event) +{ + switch (idx) { + case 3: __RV_CSR_WRITE(CSR_MHPMEVENT3, event); break; + case 4: __RV_CSR_WRITE(CSR_MHPMEVENT4, event); break; + case 5: __RV_CSR_WRITE(CSR_MHPMEVENT5, event); break; + case 6: __RV_CSR_WRITE(CSR_MHPMEVENT6, event); break; + case 7: __RV_CSR_WRITE(CSR_MHPMEVENT7, event); break; + case 8: __RV_CSR_WRITE(CSR_MHPMEVENT8, event); break; + case 9: __RV_CSR_WRITE(CSR_MHPMEVENT9, event); break; + case 10: __RV_CSR_WRITE(CSR_MHPMEVENT10, event); break; + case 11: __RV_CSR_WRITE(CSR_MHPMEVENT11, event); break; + case 12: __RV_CSR_WRITE(CSR_MHPMEVENT12, event); break; + case 13: __RV_CSR_WRITE(CSR_MHPMEVENT13, event); break; + case 14: __RV_CSR_WRITE(CSR_MHPMEVENT14, event); break; + case 15: __RV_CSR_WRITE(CSR_MHPMEVENT15, event); break; + case 16: __RV_CSR_WRITE(CSR_MHPMEVENT16, event); break; + case 17: __RV_CSR_WRITE(CSR_MHPMEVENT17, event); break; + case 18: __RV_CSR_WRITE(CSR_MHPMEVENT18, event); break; + case 19: __RV_CSR_WRITE(CSR_MHPMEVENT19, event); break; + case 20: __RV_CSR_WRITE(CSR_MHPMEVENT20, event); break; + case 21: __RV_CSR_WRITE(CSR_MHPMEVENT21, event); break; + case 22: __RV_CSR_WRITE(CSR_MHPMEVENT22, event); break; + case 23: __RV_CSR_WRITE(CSR_MHPMEVENT23, event); break; + case 24: __RV_CSR_WRITE(CSR_MHPMEVENT24, event); break; + case 25: __RV_CSR_WRITE(CSR_MHPMEVENT25, event); break; + case 26: __RV_CSR_WRITE(CSR_MHPMEVENT26, event); break; + case 27: __RV_CSR_WRITE(CSR_MHPMEVENT27, event); break; + case 28: __RV_CSR_WRITE(CSR_MHPMEVENT28, event); break; + case 29: __RV_CSR_WRITE(CSR_MHPMEVENT29, event); break; + case 30: __RV_CSR_WRITE(CSR_MHPMEVENT30, event); break; + case 31: __RV_CSR_WRITE(CSR_MHPMEVENT31, event); break; + default: break; + } +} + +/** + * \brief Get event for selected high performance monitor event + * \param [in] idx HPMEVENTx CSR index(3-31) + * \param [in] event HPMEVENTx Register value to set + * \details + * Get high performance monitor event register value + * \return HPMEVENTx Register value + */ +__STATIC_FORCEINLINE unsigned long __get_hpm_event(unsigned long idx) +{ + switch (idx) { + case 3: return __RV_CSR_READ(CSR_MHPMEVENT3); + case 4: return __RV_CSR_READ(CSR_MHPMEVENT4); + case 5: return __RV_CSR_READ(CSR_MHPMEVENT5); + case 6: return __RV_CSR_READ(CSR_MHPMEVENT6); + case 7: return __RV_CSR_READ(CSR_MHPMEVENT7); + case 8: return __RV_CSR_READ(CSR_MHPMEVENT8); + case 9: return __RV_CSR_READ(CSR_MHPMEVENT9); + case 10: return __RV_CSR_READ(CSR_MHPMEVENT10); + case 11: return __RV_CSR_READ(CSR_MHPMEVENT11); + case 12: return __RV_CSR_READ(CSR_MHPMEVENT12); + case 13: return __RV_CSR_READ(CSR_MHPMEVENT13); + case 14: return __RV_CSR_READ(CSR_MHPMEVENT14); + case 15: return __RV_CSR_READ(CSR_MHPMEVENT15); + case 16: return __RV_CSR_READ(CSR_MHPMEVENT16); + case 17: return __RV_CSR_READ(CSR_MHPMEVENT17); + case 18: return __RV_CSR_READ(CSR_MHPMEVENT18); + case 19: return __RV_CSR_READ(CSR_MHPMEVENT19); + case 20: return __RV_CSR_READ(CSR_MHPMEVENT20); + case 21: return __RV_CSR_READ(CSR_MHPMEVENT21); + case 22: return __RV_CSR_READ(CSR_MHPMEVENT22); + case 23: return __RV_CSR_READ(CSR_MHPMEVENT23); + case 24: return __RV_CSR_READ(CSR_MHPMEVENT24); + case 25: return __RV_CSR_READ(CSR_MHPMEVENT25); + case 26: return __RV_CSR_READ(CSR_MHPMEVENT26); + case 27: return __RV_CSR_READ(CSR_MHPMEVENT27); + case 28: return __RV_CSR_READ(CSR_MHPMEVENT28); + case 29: return __RV_CSR_READ(CSR_MHPMEVENT29); + case 30: return __RV_CSR_READ(CSR_MHPMEVENT30); + case 31: return __RV_CSR_READ(CSR_MHPMEVENT31); + default: return 0; + } +} + +/** + * \brief Set value for selected high performance monitor counter + * \param [in] idx HPMCOUNTERx CSR index(3-31) + * \param [in] value HPMCOUNTERx Register value to set + * \details + * Set value for high performance monitor couner register + */ +__STATIC_FORCEINLINE void __set_hpm_counter(unsigned long idx, uint64_t value) +{ + switch (idx) { +#if __RISCV_XLEN == 32 + case 3: __RV_CSR_WRITE(CSR_MHPMCOUNTER3, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER3H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER3, (uint32_t)(value)); break; + case 4: __RV_CSR_WRITE(CSR_MHPMCOUNTER4, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER4H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER4, (uint32_t)(value)); break; + case 5: __RV_CSR_WRITE(CSR_MHPMCOUNTER5, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER5H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER5, (uint32_t)(value)); break; + case 6: __RV_CSR_WRITE(CSR_MHPMCOUNTER6, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER6H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER6, (uint32_t)(value)); break; + case 7: __RV_CSR_WRITE(CSR_MHPMCOUNTER7, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER7H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER7, (uint32_t)(value)); break; + case 8: __RV_CSR_WRITE(CSR_MHPMCOUNTER8, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER8H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER8, (uint32_t)(value)); break; + case 9: __RV_CSR_WRITE(CSR_MHPMCOUNTER9, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER9H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER9, (uint32_t)(value)); break; + case 10: __RV_CSR_WRITE(CSR_MHPMCOUNTER10, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER10H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER10, (uint32_t)(value)); break; + case 11: __RV_CSR_WRITE(CSR_MHPMCOUNTER11, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER11H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER11, (uint32_t)(value)); break; + case 12: __RV_CSR_WRITE(CSR_MHPMCOUNTER12, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER12H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER12, (uint32_t)(value)); break; + case 13: __RV_CSR_WRITE(CSR_MHPMCOUNTER13, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER13H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER13, (uint32_t)(value)); break; + case 14: __RV_CSR_WRITE(CSR_MHPMCOUNTER14, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER14H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER14, (uint32_t)(value)); break; + case 15: __RV_CSR_WRITE(CSR_MHPMCOUNTER15, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER15H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER15, (uint32_t)(value)); break; + case 16: __RV_CSR_WRITE(CSR_MHPMCOUNTER16, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER16H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER16, (uint32_t)(value)); break; + case 17: __RV_CSR_WRITE(CSR_MHPMCOUNTER17, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER17H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER17, (uint32_t)(value)); break; + case 18: __RV_CSR_WRITE(CSR_MHPMCOUNTER18, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER18H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER18, (uint32_t)(value)); break; + case 19: __RV_CSR_WRITE(CSR_MHPMCOUNTER19, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER19H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER19, (uint32_t)(value)); break; + case 20: __RV_CSR_WRITE(CSR_MHPMCOUNTER20, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER20H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER20, (uint32_t)(value)); break; + case 21: __RV_CSR_WRITE(CSR_MHPMCOUNTER21, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER21H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER21, (uint32_t)(value)); break; + case 22: __RV_CSR_WRITE(CSR_MHPMCOUNTER22, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER22H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER22, (uint32_t)(value)); break; + case 23: __RV_CSR_WRITE(CSR_MHPMCOUNTER23, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER23H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER23, (uint32_t)(value)); break; + case 24: __RV_CSR_WRITE(CSR_MHPMCOUNTER24, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER24H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER24, (uint32_t)(value)); break; + case 25: __RV_CSR_WRITE(CSR_MHPMCOUNTER25, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER25H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER25, (uint32_t)(value)); break; + case 26: __RV_CSR_WRITE(CSR_MHPMCOUNTER26, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER26H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER26, (uint32_t)(value)); break; + case 27: __RV_CSR_WRITE(CSR_MHPMCOUNTER27, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER27H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER27, (uint32_t)(value)); break; + case 28: __RV_CSR_WRITE(CSR_MHPMCOUNTER28, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER28H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER28, (uint32_t)(value)); break; + case 29: __RV_CSR_WRITE(CSR_MHPMCOUNTER29, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER29H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER29, (uint32_t)(value)); break; + case 30: __RV_CSR_WRITE(CSR_MHPMCOUNTER30, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER30H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER30, (uint32_t)(value)); break; + case 31: __RV_CSR_WRITE(CSR_MHPMCOUNTER31, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER31H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER31, (uint32_t)(value)); break; + +#elif __RISCV_XLEN == 64 + case 3: __RV_CSR_WRITE(CSR_MHPMCOUNTER3, (value)); break; + case 4: __RV_CSR_WRITE(CSR_MHPMCOUNTER4, (value)); break; + case 5: __RV_CSR_WRITE(CSR_MHPMCOUNTER5, (value)); break; + case 6: __RV_CSR_WRITE(CSR_MHPMCOUNTER6, (value)); break; + case 7: __RV_CSR_WRITE(CSR_MHPMCOUNTER7, (value)); break; + case 8: __RV_CSR_WRITE(CSR_MHPMCOUNTER8, (value)); break; + case 9: __RV_CSR_WRITE(CSR_MHPMCOUNTER9, (value)); break; + case 10: __RV_CSR_WRITE(CSR_MHPMCOUNTER10, (value)); break; + case 11: __RV_CSR_WRITE(CSR_MHPMCOUNTER11, (value)); break; + case 12: __RV_CSR_WRITE(CSR_MHPMCOUNTER12, (value)); break; + case 13: __RV_CSR_WRITE(CSR_MHPMCOUNTER13, (value)); break; + case 14: __RV_CSR_WRITE(CSR_MHPMCOUNTER14, (value)); break; + case 15: __RV_CSR_WRITE(CSR_MHPMCOUNTER15, (value)); break; + case 16: __RV_CSR_WRITE(CSR_MHPMCOUNTER16, (value)); break; + case 17: __RV_CSR_WRITE(CSR_MHPMCOUNTER17, (value)); break; + case 18: __RV_CSR_WRITE(CSR_MHPMCOUNTER18, (value)); break; + case 19: __RV_CSR_WRITE(CSR_MHPMCOUNTER19, (value)); break; + case 20: __RV_CSR_WRITE(CSR_MHPMCOUNTER20, (value)); break; + case 21: __RV_CSR_WRITE(CSR_MHPMCOUNTER21, (value)); break; + case 22: __RV_CSR_WRITE(CSR_MHPMCOUNTER22, (value)); break; + case 23: __RV_CSR_WRITE(CSR_MHPMCOUNTER23, (value)); break; + case 24: __RV_CSR_WRITE(CSR_MHPMCOUNTER24, (value)); break; + case 25: __RV_CSR_WRITE(CSR_MHPMCOUNTER25, (value)); break; + case 26: __RV_CSR_WRITE(CSR_MHPMCOUNTER26, (value)); break; + case 27: __RV_CSR_WRITE(CSR_MHPMCOUNTER27, (value)); break; + case 28: __RV_CSR_WRITE(CSR_MHPMCOUNTER28, (value)); break; + case 29: __RV_CSR_WRITE(CSR_MHPMCOUNTER29, (value)); break; + case 30: __RV_CSR_WRITE(CSR_MHPMCOUNTER30, (value)); break; + case 31: __RV_CSR_WRITE(CSR_MHPMCOUNTER31, (value)); break; + +#else +#endif + default: break; + } +} + +/** + * \brief Get value of selected high performance monitor couner + * \param [in] idx HPMCOUNTERx CSR index(3-31) + * \param [in] event HPMCOUNTERx Register value to set + * \details + * Get high performance monitor counter register value + * \return HPMCOUNTERx Register value + */ +__STATIC_FORCEINLINE unsigned long __get_hpm_counter(unsigned long idx) +{ +#if __RISCV_XLEN == 32 + volatile uint32_t high0, low, high; + uint64_t full; + + switch (idx) { + case 0: return __get_rv_cycle(); + case 2: return __get_rv_instret(); + case 3: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER3H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER3); + high = __RV_CSR_READ(CSR_MHPMCOUNTER3H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER3); } + full = (((uint64_t)high) << 32) | low; return full; + case 4: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER4H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER4); + high = __RV_CSR_READ(CSR_MHPMCOUNTER4H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER4); } + full = (((uint64_t)high) << 32) | low; return full; + case 5: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER5H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER5); + high = __RV_CSR_READ(CSR_MHPMCOUNTER5H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER5); } + full = (((uint64_t)high) << 32) | low; return full; + case 6: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER6H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER6); + high = __RV_CSR_READ(CSR_MHPMCOUNTER6H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER6); } + full = (((uint64_t)high) << 32) | low; return full; + case 7: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER7H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER7); + high = __RV_CSR_READ(CSR_MHPMCOUNTER7H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER7); } + full = (((uint64_t)high) << 32) | low; return full; + case 8: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER8H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER8); + high = __RV_CSR_READ(CSR_MHPMCOUNTER8H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER8); } + full = (((uint64_t)high) << 32) | low; return full; + case 9: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER9H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER9); + high = __RV_CSR_READ(CSR_MHPMCOUNTER9H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER9); } + full = (((uint64_t)high) << 32) | low; return full; + case 10: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER10H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER10); + high = __RV_CSR_READ(CSR_MHPMCOUNTER10H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER10); } + full = (((uint64_t)high) << 32) | low; return full; + case 11: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER11H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER11); + high = __RV_CSR_READ(CSR_MHPMCOUNTER11H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER11); } + full = (((uint64_t)high) << 32) | low; return full; + case 12: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER12H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER12); + high = __RV_CSR_READ(CSR_MHPMCOUNTER12H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER12); } + full = (((uint64_t)high) << 32) | low; return full; + case 13: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER13H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER13); + high = __RV_CSR_READ(CSR_MHPMCOUNTER13H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER13); } + full = (((uint64_t)high) << 32) | low; return full; + case 14: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER14H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER14); + high = __RV_CSR_READ(CSR_MHPMCOUNTER14H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER14); } + full = (((uint64_t)high) << 32) | low; return full; + case 15: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER15H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER15); + high = __RV_CSR_READ(CSR_MHPMCOUNTER15H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER15); } + full = (((uint64_t)high) << 32) | low; return full; + case 16: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER16H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER16); + high = __RV_CSR_READ(CSR_MHPMCOUNTER16H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER16); } + full = (((uint64_t)high) << 32) | low; return full; + case 17: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER17H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER17); + high = __RV_CSR_READ(CSR_MHPMCOUNTER17H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER17); } + full = (((uint64_t)high) << 32) | low; return full; + case 18: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER18H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER18); + high = __RV_CSR_READ(CSR_MHPMCOUNTER18H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER18); } + full = (((uint64_t)high) << 32) | low; return full; + case 19: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER19H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER19); + high = __RV_CSR_READ(CSR_MHPMCOUNTER19H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER19); } + full = (((uint64_t)high) << 32) | low; return full; + case 20: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER20H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER20); + high = __RV_CSR_READ(CSR_MHPMCOUNTER20H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER20); } + full = (((uint64_t)high) << 32) | low; return full; + case 21: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER21H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER21); + high = __RV_CSR_READ(CSR_MHPMCOUNTER21H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER21); } + full = (((uint64_t)high) << 32) | low; return full; + case 22: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER22H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER22); + high = __RV_CSR_READ(CSR_MHPMCOUNTER22H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER22); } + full = (((uint64_t)high) << 32) | low; return full; + case 23: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER23H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER23); + high = __RV_CSR_READ(CSR_MHPMCOUNTER23H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER23); } + full = (((uint64_t)high) << 32) | low; return full; + case 24: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER24H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER24); + high = __RV_CSR_READ(CSR_MHPMCOUNTER24H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER24); } + full = (((uint64_t)high) << 32) | low; return full; + case 25: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER25H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER25); + high = __RV_CSR_READ(CSR_MHPMCOUNTER25H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER25); } + full = (((uint64_t)high) << 32) | low; return full; + case 26: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER26H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER26); + high = __RV_CSR_READ(CSR_MHPMCOUNTER26H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER26); } + full = (((uint64_t)high) << 32) | low; return full; + case 27: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER27H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER27); + high = __RV_CSR_READ(CSR_MHPMCOUNTER27H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER27); } + full = (((uint64_t)high) << 32) | low; return full; + case 28: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER28H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER28); + high = __RV_CSR_READ(CSR_MHPMCOUNTER28H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER28); } + full = (((uint64_t)high) << 32) | low; return full; + case 29: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER29H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER29); + high = __RV_CSR_READ(CSR_MHPMCOUNTER29H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER29); } + full = (((uint64_t)high) << 32) | low; return full; + case 30: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER30H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER30); + high = __RV_CSR_READ(CSR_MHPMCOUNTER30H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER30); } + full = (((uint64_t)high) << 32) | low; return full; + case 31: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER31H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER31); + high = __RV_CSR_READ(CSR_MHPMCOUNTER31H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER31); } + full = (((uint64_t)high) << 32) | low; return full; + +#elif __RISCV_XLEN == 64 + switch (idx) { + case 0: return __get_rv_cycle(); + case 2: return __get_rv_instret(); + case 3: return __RV_CSR_READ(CSR_MHPMCOUNTER3); + case 4: return __RV_CSR_READ(CSR_MHPMCOUNTER4); + case 5: return __RV_CSR_READ(CSR_MHPMCOUNTER5); + case 6: return __RV_CSR_READ(CSR_MHPMCOUNTER6); + case 7: return __RV_CSR_READ(CSR_MHPMCOUNTER7); + case 8: return __RV_CSR_READ(CSR_MHPMCOUNTER8); + case 9: return __RV_CSR_READ(CSR_MHPMCOUNTER9); + case 10: return __RV_CSR_READ(CSR_MHPMCOUNTER10); + case 11: return __RV_CSR_READ(CSR_MHPMCOUNTER11); + case 12: return __RV_CSR_READ(CSR_MHPMCOUNTER12); + case 13: return __RV_CSR_READ(CSR_MHPMCOUNTER13); + case 14: return __RV_CSR_READ(CSR_MHPMCOUNTER14); + case 15: return __RV_CSR_READ(CSR_MHPMCOUNTER15); + case 16: return __RV_CSR_READ(CSR_MHPMCOUNTER16); + case 17: return __RV_CSR_READ(CSR_MHPMCOUNTER17); + case 18: return __RV_CSR_READ(CSR_MHPMCOUNTER18); + case 19: return __RV_CSR_READ(CSR_MHPMCOUNTER19); + case 20: return __RV_CSR_READ(CSR_MHPMCOUNTER20); + case 21: return __RV_CSR_READ(CSR_MHPMCOUNTER21); + case 22: return __RV_CSR_READ(CSR_MHPMCOUNTER22); + case 23: return __RV_CSR_READ(CSR_MHPMCOUNTER23); + case 24: return __RV_CSR_READ(CSR_MHPMCOUNTER24); + case 25: return __RV_CSR_READ(CSR_MHPMCOUNTER25); + case 26: return __RV_CSR_READ(CSR_MHPMCOUNTER26); + case 27: return __RV_CSR_READ(CSR_MHPMCOUNTER27); + case 28: return __RV_CSR_READ(CSR_MHPMCOUNTER28); + case 29: return __RV_CSR_READ(CSR_MHPMCOUNTER29); + case 30: return __RV_CSR_READ(CSR_MHPMCOUNTER30); + case 31: return __RV_CSR_READ(CSR_MHPMCOUNTER31); + +#else + switch (idx) { +#endif + default: return 0; + } +} + +/** + * \brief Set exceptions delegation to S mode + * \details Set certain exceptions of supervisor mode or user mode + * delegated from machined mode to supervisor mode. + * \remarks + * Exception should trigger in supervisor mode or user mode. + */ +__STATIC_FORCEINLINE void __set_medeleg(unsigned long mask) +{ + __RV_CSR_WRITE(CSR_MEDELEG, mask); +} + +/** + * \brief Execute fence instruction, p -> pred, s -> succ + * \details + * the FENCE instruction ensures that all memory accesses from instructions preceding + * the fence in program order (the `predecessor set`) appear earlier in the global memory order than + * memory accesses from instructions appearing after the fence in program order (the `successor set`). + * For details, please refer to The RISC-V Instruction Set Manual + * \param p predecessor set, such as iorw, rw, r, w + * \param s successor set, such as iorw, rw, r, w + **/ +#define __FENCE(p, s) __ASM volatile ("fence " #p "," #s : : : "memory") + +/** + * \brief Fence.i Instruction + * \details + * The FENCE.I instruction is used to synchronize the instruction + * and data streams. + */ +__STATIC_FORCEINLINE void __FENCE_I(void) +{ + __ASM volatile("fence.i"); +} + +/** \brief Read & Write Memory barrier */ +#define __RWMB() __FENCE(iorw,iorw) + +/** \brief Read Memory barrier */ +#define __RMB() __FENCE(ir,ir) + +/** \brief Write Memory barrier */ +#define __WMB() __FENCE(ow,ow) + +/** \brief SMP Read & Write Memory barrier */ +#define __SMP_RWMB() __FENCE(rw,rw) + +/** \brief SMP Read Memory barrier */ +#define __SMP_RMB() __FENCE(r,r) + +/** \brief SMP Write Memory barrier */ +#define __SMP_WMB() __FENCE(w,w) + +/** \brief CPU relax for busy loop */ +#define __CPU_RELAX() __ASM volatile ("" : : : "memory") + + +/* ===== Load/Store Operations ===== */ +/** + * \brief Load 8bit value from address (8 bit) + * \details Load 8 bit value. + * \param [in] addr Address pointer to data + * \return value of type uint8_t at (*addr) + */ +__STATIC_FORCEINLINE uint8_t __LB(volatile void *addr) +{ + uint8_t result; + + __ASM volatile ("lb %0, 0(%1)" : "=r" (result) : "r" (addr)); + return result; +} + +/** + * \brief Load 16bit value from address (16 bit) + * \details Load 16 bit value. + * \param [in] addr Address pointer to data + * \return value of type uint16_t at (*addr) + */ +__STATIC_FORCEINLINE uint16_t __LH(volatile void *addr) +{ + uint16_t result; + + __ASM volatile ("lh %0, 0(%1)" : "=r" (result) : "r" (addr)); + return result; +} + +/** + * \brief Load 32bit value from address (32 bit) + * \details Load 32 bit value. + * \param [in] addr Address pointer to data + * \return value of type uint32_t at (*addr) + */ +__STATIC_FORCEINLINE uint32_t __LW(volatile void *addr) +{ + uint32_t result; + + __ASM volatile ("lw %0, 0(%1)" : "=r" (result) : "r" (addr)); + return result; +} + +#if __RISCV_XLEN != 32 +/** + * \brief Load 64bit value from address (64 bit) + * \details Load 64 bit value. + * \param [in] addr Address pointer to data + * \return value of type uint64_t at (*addr) + * \remarks RV64 only macro + */ +__STATIC_FORCEINLINE uint64_t __LD(volatile void *addr) +{ + uint64_t result; + __ASM volatile ("ld %0, 0(%1)" : "=r" (result) : "r" (addr)); + return result; +} +#endif + +/** + * \brief Write 8bit value to address (8 bit) + * \details Write 8 bit value. + * \param [in] addr Address pointer to data + * \param [in] val Value to set + */ +__STATIC_FORCEINLINE void __SB(volatile void *addr, uint8_t val) +{ + __ASM volatile ("sb %0, 0(%1)" : : "r" (val), "r" (addr)); +} + +/** + * \brief Write 16bit value to address (16 bit) + * \details Write 16 bit value. + * \param [in] addr Address pointer to data + * \param [in] val Value to set + */ +__STATIC_FORCEINLINE void __SH(volatile void *addr, uint16_t val) +{ + __ASM volatile ("sh %0, 0(%1)" : : "r" (val), "r" (addr)); +} + +/** + * \brief Write 32bit value to address (32 bit) + * \details Write 32 bit value. + * \param [in] addr Address pointer to data + * \param [in] val Value to set + */ +__STATIC_FORCEINLINE void __SW(volatile void *addr, uint32_t val) +{ + __ASM volatile ("sw %0, 0(%1)" : : "r" (val), "r" (addr)); +} + +#if __RISCV_XLEN != 32 +/** + * \brief Write 64bit value to address (64 bit) + * \details Write 64 bit value. + * \param [in] addr Address pointer to data + * \param [in] val Value to set + */ +__STATIC_FORCEINLINE void __SD(volatile void *addr, uint64_t val) +{ + __ASM volatile ("sd %0, 0(%1)" : : "r" (val), "r" (addr)); +} +#endif + +/** + * \brief Compare and Swap 32bit value using LR and SC + * \details Compare old value with memory, if identical, + * store new value in memory. Return the initial value in memory. + * Success is indicated by comparing return value with OLD. + * memory address, return 0 if successful, otherwise return !0 + * \param [in] addr Address pointer to data, address need to be 4byte aligned + * \param [in] oldval Old value of the data in address + * \param [in] newval New value to be stored into the address + * \return return the initial value in memory + */ +__STATIC_FORCEINLINE uint32_t __CAS_W(volatile uint32_t *addr, uint32_t oldval, uint32_t newval) +{ + uint32_t result; + uint32_t rc; + + __ASM volatile ( \ + "0: lr.w %0, %2 \n" \ + " bne %0, %z3, 1f \n" \ + " sc.w %1, %z4, %2 \n" \ + " bnez %1, 0b \n" \ + "1:\n" \ + : "=&r"(result), "=&r"(rc), "+A"(*addr) \ + : "r"(oldval), "r"(newval) \ + : "memory"); + return result; +} + +/** + * \brief Atomic Swap 32bit value into memory + * \details Atomically swap new 32bit value into memory using amoswap.d. + * \param [in] addr Address pointer to data, address need to be 4byte aligned + * \param [in] newval New value to be stored into the address + * \return return the original value in memory + */ +__STATIC_FORCEINLINE uint32_t __AMOSWAP_W(volatile uint32_t *addr, uint32_t newval) +{ + uint32_t result; + + __ASM volatile ("amoswap.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(newval) : "memory"); + return result; +} + +/** + * \brief Atomic Add with 32bit value + * \details Atomically ADD 32bit value with value in memory using amoadd.d. + * \param [in] addr Address pointer to data, address need to be 4byte aligned + * \param [in] value value to be ADDed + * \return return memory value + add value + */ +__STATIC_FORCEINLINE int32_t __AMOADD_W(volatile int32_t *addr, int32_t value) +{ + int32_t result; + + __ASM volatile ("amoadd.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/** + * \brief Atomic And with 32bit value + * \details Atomically AND 32bit value with value in memory using amoand.d. + * \param [in] addr Address pointer to data, address need to be 4byte aligned + * \param [in] value value to be ANDed + * \return return memory value & and value + */ +__STATIC_FORCEINLINE int32_t __AMOAND_W(volatile int32_t *addr, int32_t value) +{ + int32_t result; + + __ASM volatile ("amoand.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/** + * \brief Atomic OR with 32bit value + * \details Atomically OR 32bit value with value in memory using amoor.d. + * \param [in] addr Address pointer to data, address need to be 4byte aligned + * \param [in] value value to be ORed + * \return return memory value | and value + */ +__STATIC_FORCEINLINE int32_t __AMOOR_W(volatile int32_t *addr, int32_t value) +{ + int32_t result; + + __ASM volatile ("amoor.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/** + * \brief Atomic XOR with 32bit value + * \details Atomically XOR 32bit value with value in memory using amoxor.d. + * \param [in] addr Address pointer to data, address need to be 4byte aligned + * \param [in] value value to be XORed + * \return return memory value ^ and value + */ +__STATIC_FORCEINLINE int32_t __AMOXOR_W(volatile int32_t *addr, int32_t value) +{ + int32_t result; + + __ASM volatile ("amoxor.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/** + * \brief Atomic unsigned MAX with 32bit value + * \details Atomically unsigned max compare 32bit value with value in memory using amomaxu.d. + * \param [in] addr Address pointer to data, address need to be 4byte aligned + * \param [in] value value to be compared + * \return return the bigger value + */ +__STATIC_FORCEINLINE uint32_t __AMOMAXU_W(volatile uint32_t *addr, uint32_t value) +{ + uint32_t result; + + __ASM volatile ("amomaxu.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/** + * \brief Atomic signed MAX with 32bit value + * \details Atomically signed max compare 32bit value with value in memory using amomax.d. + * \param [in] addr Address pointer to data, address need to be 4byte aligned + * \param [in] value value to be compared + * \return the bigger value + */ +__STATIC_FORCEINLINE int32_t __AMOMAX_W(volatile int32_t *addr, int32_t value) +{ + int32_t result; + + __ASM volatile ("amomax.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/** + * \brief Atomic unsigned MIN with 32bit value + * \details Atomically unsigned min compare 32bit value with value in memory using amominu.d. + * \param [in] addr Address pointer to data, address need to be 4byte aligned + * \param [in] value value to be compared + * \return the smaller value + */ +__STATIC_FORCEINLINE uint32_t __AMOMINU_W(volatile uint32_t *addr, uint32_t value) +{ + uint32_t result; + + __ASM volatile ("amominu.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/** + * \brief Atomic signed MIN with 32bit value + * \details Atomically signed min compare 32bit value with value in memory using amomin.d. + * \param [in] addr Address pointer to data, address need to be 4byte aligned + * \param [in] value value to be compared + * \return the smaller value + */ +__STATIC_FORCEINLINE int32_t __AMOMIN_W(volatile int32_t *addr, int32_t value) +{ + int32_t result; + + __ASM volatile ("amomin.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +#if __RISCV_XLEN == 64 +/** + * \brief Compare and Swap 64bit value using LR and SC + * \details Compare old value with memory, if identical, + * store new value in memory. Return the initial value in memory. + * Success is indicated by comparing return value with OLD. + * memory address, return 0 if successful, otherwise return !0 + * \param [in] addr Address pointer to data, address need to be 8byte aligned + * \param [in] oldval Old value of the data in address + * \param [in] newval New value to be stored into the address + * \return return the initial value in memory + */ +__STATIC_FORCEINLINE uint64_t __CAS_D(volatile uint64_t *addr, uint64_t oldval, uint64_t newval) +{ + uint64_t result; + uint64_t rc; + + __ASM volatile ( \ + "0: lr.d %0, %2 \n" \ + " bne %0, %z3, 1f \n" \ + " sc.d %1, %z4, %2 \n" \ + " bnez %1, 0b \n" \ + "1:\n" \ + : "=&r"(result), "=&r"(rc), "+A"(*addr) \ + : "r"(oldval), "r"(newval) \ + : "memory"); + return result; +} + +/** + * \brief Atomic Swap 64bit value into memory + * \details Atomically swap new 64bit value into memory using amoswap.d. + * \param [in] addr Address pointer to data, address need to be 8byte aligned + * \param [in] newval New value to be stored into the address + * \return return the original value in memory + */ +__STATIC_FORCEINLINE uint64_t __AMOSWAP_D(volatile uint64_t *addr, uint64_t newval) +{ + uint64_t result; + + __ASM volatile ("amoswap.d %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(newval) : "memory"); + return result; +} + +/** + * \brief Atomic Add with 64bit value + * \details Atomically ADD 64bit value with value in memory using amoadd.d. + * \param [in] addr Address pointer to data, address need to be 8byte aligned + * \param [in] value value to be ADDed + * \return return memory value + add value + */ +__STATIC_FORCEINLINE int64_t __AMOADD_D(volatile int64_t *addr, int64_t value) +{ + int64_t result; + + __ASM volatile ("amoadd.d %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/** + * \brief Atomic And with 64bit value + * \details Atomically AND 64bit value with value in memory using amoand.d. + * \param [in] addr Address pointer to data, address need to be 8byte aligned + * \param [in] value value to be ANDed + * \return return memory value & and value + */ +__STATIC_FORCEINLINE int64_t __AMOAND_D(volatile int64_t *addr, int64_t value) +{ + int64_t result; + + __ASM volatile ("amoand.d %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/** + * \brief Atomic OR with 64bit value + * \details Atomically OR 64bit value with value in memory using amoor.d. + * \param [in] addr Address pointer to data, address need to be 8byte aligned + * \param [in] value value to be ORed + * \return return memory value | and value + */ +__STATIC_FORCEINLINE int64_t __AMOOR_D(volatile int64_t *addr, int64_t value) +{ + int64_t result; + + __ASM volatile ("amoor.d %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/** + * \brief Atomic XOR with 64bit value + * \details Atomically XOR 64bit value with value in memory using amoxor.d. + * \param [in] addr Address pointer to data, address need to be 8byte aligned + * \param [in] value value to be XORed + * \return return memory value ^ and value + */ +__STATIC_FORCEINLINE int64_t __AMOXOR_D(volatile int64_t *addr, int64_t value) +{ + int64_t result; + + __ASM volatile ("amoxor.d %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/** + * \brief Atomic unsigned MAX with 64bit value + * \details Atomically unsigned max compare 64bit value with value in memory using amomaxu.d. + * \param [in] addr Address pointer to data, address need to be 8byte aligned + * \param [in] value value to be compared + * \return return the bigger value + */ +__STATIC_FORCEINLINE uint64_t __AMOMAXU_D(volatile uint64_t *addr, uint64_t value) +{ + uint64_t result; + + __ASM volatile ("amomaxu.d %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/** + * \brief Atomic signed MAX with 64bit value + * \details Atomically signed max compare 64bit value with value in memory using amomax.d. + * \param [in] addr Address pointer to data, address need to be 8byte aligned + * \param [in] value value to be compared + * \return the bigger value + */ +__STATIC_FORCEINLINE int64_t __AMOMAX_D(volatile int64_t *addr, int64_t value) +{ + int64_t result; + + __ASM volatile ("amomax.d %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/** + * \brief Atomic unsigned MIN with 64bit value + * \details Atomically unsigned min compare 64bit value with value in memory using amominu.d. + * \param [in] addr Address pointer to data, address need to be 8byte aligned + * \param [in] value value to be compared + * \return the smaller value + */ +__STATIC_FORCEINLINE uint64_t __AMOMINU_D(volatile uint64_t *addr, uint64_t value) +{ + uint64_t result; + + __ASM volatile ("amominu.d %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/** + * \brief Atomic signed MIN with 64bit value + * \details Atomically signed min compare 64bit value with value in memory using amomin.d. + * \param [in] addr Address pointer to data, address need to be 8byte aligned + * \param [in] value value to be compared + * \return the smaller value + */ +__STATIC_FORCEINLINE int64_t __AMOMIN_D(volatile int64_t *addr, int64_t value) +{ + int64_t result; + + __ASM volatile ("amomin.d %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} +#endif /* __RISCV_XLEN == 64 */ + +/** @} */ /* End of Doxygen Group NMSIS_Core_CPU_Intrinsic */ + +#ifdef __cplusplus +} +#endif +#endif /* __CORE_FEATURE_BASE__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_bitmanip.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_bitmanip.h new file mode 100644 index 0000000..3922d12 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_bitmanip.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __CORE_FEATURE_BITMANIP__ +#define __CORE_FEATURE_BITMANIP__ + +/*! + * @file core_feature_bitmanip.h + * @brief Bitmanipulation feature API header file for Nuclei N/NX Core + */ +/* + * Bitmanipulation Feature Configuration Macro: + * 1. __BITMANIP_PRESENT: Define whether Bitmanipulation Unit is present or not + * * 0: Not present + * * 1: Present + */ +#ifdef __cplusplus + extern "C" { +#endif + +#include "core_feature_base.h" + +#if defined(__BITMANIP_PRESENT) && (__BITMANIP_PRESENT == 1) + +/* ########################### CPU Bitmanipulation Intrinsic Functions ########################### */ +/** + * \defgroup NMSIS_Core_Bitmanip_Intrinsic Intrinsic Functions for Bitmanipulation Instructions + * \ingroup NMSIS_Core + * \brief Functions that generate RISC-V Bitmanipulation instructions. + * \details + * + * RISC-V Bitmanipulation Intrinsic APIs are provided directly through compiler generated intrinsic function. + * + * This intrinsic function support in compiler is introduced in nuclei riscv gcc 10.2. + * + * API header file can be found in lib/gcc/riscv-nuclei-elf//include/rvintrin.h + * + * For Nuclei GCC 13/Clang 17, this intrinsic header no longer existed, please take care. + * + * @{ + */ +/** @} */ /* End of Doxygen Group NMSIS_Core_Bitmanip_Intrinsic */ + +#if defined(__INC_INTRINSIC_API) && (__INC_INTRINSIC_API == 1) +// deleted in gcc13, you can directly use b extension intrinisc api +//#include +#endif + +#endif /* defined(__BITMANIP_PRESENT) && (__BITMANIP_PRESENT == 1) */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_FEATURE_BITMANIP__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_cache.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_cache.h new file mode 100644 index 0000000..f16445f --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_cache.h @@ -0,0 +1,1517 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __CORE_FEATURE_CACHE_H__ +#define __CORE_FEATURE_CACHE_H__ +/*! + * @file core_feature_cache.h + * @brief Cache feature API header file for Nuclei N/NX Core + */ +/* + * Cache Feature Configuration Macro: + * 1. __ICACHE_PRESENT: Define whether I-Cache Unit is present or not. + * * 0: Not present + * * 1: Present + * 2. __DCACHE_PRESENT: Define whether D-Cache Unit is present or not. + * * 0: Not present + * * 1: Present + * 3. __CCM_PRESENT: Define whether Nuclei Cache Control and Maintainence(CCM) Unit is present or not. + * * 0: Not present + * * 1: Present + */ +#ifdef __cplusplus + extern "C" { +#endif + +#include "core_feature_base.h" + + +#if defined(__CCM_PRESENT) && (__CCM_PRESENT == 1) + +/* ########################## Cache functions #################################### */ +/** + * \defgroup NMSIS_Core_Cache Cache Functions + * \brief Functions that configure Instruction and Data Cache. + * @{ + * + * Nuclei provide Cache Control and Maintainence(CCM) for software to control and maintain + * the internal L1 I/D Cache of the RISC-V Core, software can manage the cache flexibly to + * meet the actual application scenarios. + * + * The CCM operations have 3 types: by single address, by all and flush pipeline. + * The CCM operations are done via CSR registers, M/S/U mode has its own CSR registers to + * do CCM operations. By default, CCM operations are not allowed in S/U mode, you can execute + * \ref EnableSUCCM in M-Mode to enable it. + * + * * API names started with M, such as \ref MInvalICacheLine must be called in M-Mode only. + * * API names started with S, such as \ref SInvalICacheLine should be called in S-Mode. + * * API names started with U, such as \ref UInvalICacheLine should be called in U-Mode. + * + */ + + +/** + * \brief Cache CCM Operation Fail Info + */ +typedef enum CCM_OP_FINFO { + CCM_OP_SUCCESS = 0x0, /*!< Lock Succeed */ + CCM_OP_EXCEED_ERR = 0x1, /*!< Exceed the the number of lockable ways(N-Way I/D-Cache, lockable is N-1) */ + CCM_OP_PERM_CHECK_ERR = 0x2, /*!< PMP/sPMP/Page-Table X(I-Cache)/R(D-Cache) permission check failed, or belong to Device/Non-Cacheable address range */ + CCM_OP_REFILL_BUS_ERR = 0x3, /*!< Refill has Bus Error */ + CCM_OP_ECC_ERR = 0x4 /*!< Deprecated, ECC Error, this error code is removed in later Nuclei CCM RTL design, please don't use it */ +} CCM_OP_FINFO_Type; + +/** + * \brief Cache CCM Command Types + */ +typedef enum CCM_CMD { + CCM_DC_INVAL = 0x0, /*!< Unlock and invalidate D-Cache line specified by CSR CCM_XBEGINADDR */ + CCM_DC_WB = 0x1, /*!< Flush the specific D-Cache line specified by CSR CCM_XBEGINADDR */ + CCM_DC_WBINVAL = 0x2, /*!< Unlock, flush and invalidate the specific D-Cache line specified by CSR CCM_XBEGINADDR */ + CCM_DC_LOCK = 0x3, /*!< Lock the specific D-Cache line specified by CSR CCM_XBEGINADDR */ + CCM_DC_UNLOCK = 0x4, /*!< Unlock the specific D-Cache line specified by CSR CCM_XBEGINADDR */ + CCM_DC_WBINVAL_ALL = 0x6, /*!< Unlock and flush and invalidate all the valid and dirty D-Cache lines */ + CCM_DC_WB_ALL = 0x7, /*!< Flush all the valid and dirty D-Cache lines */ + CCM_DC_INVAL_ALL = 0x17, /*!< Unlock and invalidate all the D-Cache lines */ + CCM_IC_INVAL = 0x8, /*!< Unlock and invalidate I-Cache line specified by CSR CCM_XBEGINADDR */ + CCM_IC_LOCK = 0xb, /*!< Lock the specific I-Cache line specified by CSR CCM_XBEGINADDR */ + CCM_IC_UNLOCK = 0xc, /*!< Unlock the specific I-Cache line specified by CSR CCM_XBEGINADDR */ + CCM_IC_INVAL_ALL = 0xd /*!< Unlock and invalidate all the I-Cache lines */ +} CCM_CMD_Type; + +/** + * \brief Cache Information Type + */ +typedef struct CacheInfo { + uint32_t linesize; /*!< Cache Line size in bytes */ + uint32_t ways; /*!< Cache ways */ + uint32_t setperway; /*!< Cache set per way */ + uint32_t size; /*!< Cache total size in bytes */ +} CacheInfo_Type; + +#if __riscv_xlen == 32 +#define CCM_SUEN_SUEN_Msk (0xFFFFFFFFUL) /*!< CSR CCM_SUEN: SUEN Mask */ +#else +#define CCM_SUEN_SUEN_Msk (0xFFFFFFFFFFFFFFFFUL) /*!< CSR CCM_SUEN: SUEN Mask */ +#endif + +/** + * \brief Enable CCM operation in Supervisor/User Mode + * \details + * This function enable CCM operation in Supervisor/User Mode. + * If enabled, CCM operations in supervisor/user mode will + * be allowed. + * \remarks + * - This function can be called in M-Mode only. + * \sa + * - \ref DisableSUCCM +*/ +__STATIC_FORCEINLINE void EnableSUCCM(void) +{ + __RV_CSR_SET(CSR_CCM_SUEN, CCM_SUEN_SUEN_Msk); +} + +/** + * \brief Disable CCM operation in Supervisor/User Mode + * \details + * This function disable CCM operation in Supervisor/User Mode. + * If not enabled, CCM operations in supervisor/user mode will + * trigger a *illegal intruction* exception. + * \remarks + * - This function can be called in M-Mode only. + * \sa + * - \ref EnableSUCCM +*/ +__STATIC_FORCEINLINE void DisableSUCCM(void) +{ + __RV_CSR_CLEAR(CSR_CCM_SUEN, CCM_SUEN_SUEN_Msk); +} + +/** + * \brief Flush pipeline after CCM operation + * \details + * This function is used to flush pipeline after CCM operations + * on Cache, it will ensure latest instructions or data can be + * seen by pipeline. + * \remarks + * - This function can be called in M/S/U-Mode only. +*/ +__STATIC_FORCEINLINE void FlushPipeCCM(void) +{ + __RV_CSR_WRITE(CSR_CCM_FPIPE, 0x1); +} +/** @} */ /* End of Doxygen Group NMSIS_Core_Cache */ +#endif + +#if defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1) + +/** + * \defgroup NMSIS_Core_ICache I-Cache Functions + * \ingroup NMSIS_Core_Cache + * \brief Functions that configure Instruction Cache. + * @{ + */ + +/** + * \brief Check ICache Unit Present or Not + * \details + * This function check icache unit present or not via mcfg_info csr + * \remarks + * - This function might not work for some old nuclei processors + * - Please make sure the version of your nuclei processor contain ICACHE bit in mcfg_info + * \return 1 if present otherwise 0 +*/ +__STATIC_FORCEINLINE int32_t ICachePresent(void) +{ + if (__RV_CSR_READ(CSR_MCFG_INFO) & MCFG_INFO_ICACHE) { + return 1; + } + return 0; +} + +/** + * \brief Enable ICache + * \details + * This function enable I-Cache + * \remarks + * - This function can be called in M-Mode only. + * - This \ref CSR_MCACHE_CTL register control I Cache enable. + * \sa + * - \ref DisableICache +*/ +__STATIC_FORCEINLINE void EnableICache(void) +{ + __RV_CSR_SET(CSR_MCACHE_CTL, MCACHE_CTL_IC_EN); +} + +/** + * \brief Disable ICache + * \details + * This function Disable I-Cache + * \remarks + * - This function can be called in M-Mode only. + * - This \ref CSR_MCACHE_CTL register control I Cache enable. + * \sa + * - \ref EnableICache + */ +__STATIC_FORCEINLINE void DisableICache(void) +{ + __RV_CSR_CLEAR(CSR_MCACHE_CTL, MCACHE_CTL_IC_EN); +} + +/** + * \brief Enable ICache ECC + * \details + * This function enable I-Cache ECC + * \remarks + * - This function can be called in M-Mode only. + * - This \ref CSR_MCACHE_CTL register control I Cache ECC enable. + * \sa + * - \ref DisableICacheECC +*/ +__STATIC_FORCEINLINE void EnableICacheECC(void) +{ + __RV_CSR_SET(CSR_MCACHE_CTL, MCACHE_CTL_IC_ECC_EN); +} + +/** + * \brief Disable ICache ECC + * \details + * This function disable I-Cache ECC + * \remarks + * - This function can be called in M-Mode only. + * - This \ref CSR_MCACHE_CTL register control I Cache ECC enable. + * \sa + * - \ref EnableICacheECC +*/ +__STATIC_FORCEINLINE void DisableICacheECC(void) +{ + __RV_CSR_CLEAR(CSR_MCACHE_CTL, MCACHE_CTL_IC_ECC_EN); +} + +#if defined(__CCM_PRESENT) && (__CCM_PRESENT == 1) +/** + * \brief Get I-Cache Information + * \details + * This function get I-Cache Information + * \remarks + * - This function can be called in M-Mode only. + * - You can use this function in combination with cache lines operations + * \sa + * - \ref GetDCacheInfo + */ +__STATIC_FORCEINLINE int32_t GetICacheInfo(CacheInfo_Type *info) +{ + if (info == NULL) { + return -1; + } + CSR_MICFGINFO_Type csr_ccfg; + csr_ccfg.d = __RV_CSR_READ(CSR_MICFG_INFO); + info->setperway = (1 << csr_ccfg.b.set) << 3; + info->ways = (1 + csr_ccfg.b.way); + if (csr_ccfg.b.lsize == 0) { + info->linesize = 0; + } else { + info->linesize = (1 << (csr_ccfg.b.lsize - 1)) << 3; + } + info->size = info->setperway * info->ways * info->linesize; + return 0; +} + +/** + * \brief Invalidate one I-Cache line specified by address in M-Mode + * \details + * This function unlock and invalidate one I-Cache line specified + * by the address. + * Command \ref CCM_IC_INVAL is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be invalidated + */ +__STATIC_FORCEINLINE void MInvalICacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_MBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_IC_INVAL); +} + +/** + * \brief Invalidate several I-Cache lines specified by address in M-Mode + * \details + * This function unlock and invalidate several I-Cache lines specified + * by the address and line count. + * Command \ref CCM_IC_INVAL is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be invalidated + * \param [in] cnt count of cache lines to be invalidated + */ +__STATIC_FORCEINLINE void MInvalICacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_MBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_IC_INVAL); + } + } +} + +/** + * \brief Invalidate one I-Cache line specified by address in S-Mode + * \details + * This function unlock and invalidate one I-Cache line specified + * by the address. + * Command \ref CCM_IC_INVAL is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be invalidated + */ +__STATIC_FORCEINLINE void SInvalICacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_SBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_IC_INVAL); +} + +/** + * \brief Invalidate several I-Cache lines specified by address in S-Mode + * \details + * This function unlock and invalidate several I-Cache lines specified + * by the address and line count. + * Command \ref CCM_IC_INVAL is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be invalidated + * \param [in] cnt count of cache lines to be invalidated + */ +__STATIC_FORCEINLINE void SInvalICacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_SBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_IC_INVAL); + } + } +} + +/** + * \brief Invalidate one I-Cache line specified by address in U-Mode + * \details + * This function unlock and invalidate one I-Cache line specified + * by the address. + * Command \ref CCM_IC_INVAL is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be invalidated + */ +__STATIC_FORCEINLINE void UInvalICacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_UBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_IC_INVAL); +} + +/** + * \brief Invalidate several I-Cache lines specified by address in U-Mode + * \details + * This function unlock and invalidate several I-Cache lines specified + * by the address and line count. + * Command \ref CCM_IC_INVAL is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be invalidated + * \param [in] cnt count of cache lines to be invalidated + */ +__STATIC_FORCEINLINE void UInvalICacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_UBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_IC_INVAL); + } + } +} + +/** + * \brief Lock one I-Cache line specified by address in M-Mode + * \details + * This function lock one I-Cache line specified by the address. + * Command \ref CCM_IC_LOCK is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be locked + * \return result of CCM lock operation, see enum \ref CCM_OP_FINFO + */ +__STATIC_FORCEINLINE unsigned long MLockICacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_MBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_IC_LOCK); + return __RV_CSR_READ(CSR_CCM_MDATA); +} + +/** + * \brief Lock several I-Cache lines specified by address in M-Mode + * \details + * This function lock several I-Cache lines specified by the address + * and line count. + * Command \ref CCM_IC_LOCK is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be locked + * \param [in] cnt count of cache lines to be locked + * \return result of CCM lock operation, see enum \ref CCM_OP_FINFO + */ +__STATIC_FORCEINLINE unsigned long MLockICacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + unsigned long fail_info = CCM_OP_SUCCESS; + __RV_CSR_WRITE(CSR_CCM_MBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_IC_LOCK); + fail_info = __RV_CSR_READ(CSR_CCM_MDATA); + if (CCM_OP_SUCCESS != fail_info) { + return fail_info; + } + } + } + return CCM_OP_SUCCESS; +} + +/** + * \brief Lock one I-Cache line specified by address in S-Mode + * \details + * This function lock one I-Cache line specified by the address. + * Command \ref CCM_IC_LOCK is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be locked + * \return result of CCM lock operation, see enum \ref CCM_OP_FINFO + */ +__STATIC_FORCEINLINE unsigned long SLockICacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_SBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_IC_LOCK); + return __RV_CSR_READ(CSR_CCM_SDATA); +} + +/** + * \brief Lock several I-Cache lines specified by address in S-Mode + * \details + * This function lock several I-Cache lines specified by the address + * and line count. + * Command \ref CCM_IC_LOCK is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be locked + * \param [in] cnt count of cache lines to be locked + * \return result of CCM lock operation, see enum \ref CCM_OP_FINFO + */ +__STATIC_FORCEINLINE unsigned long SLockICacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + unsigned long fail_info = CCM_OP_SUCCESS; + __RV_CSR_WRITE(CSR_CCM_SBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_IC_LOCK); + fail_info = __RV_CSR_READ(CSR_CCM_SDATA); + if (CCM_OP_SUCCESS != fail_info) { + return fail_info; + } + } + } + return CCM_OP_SUCCESS; +} + +/** + * \brief Lock one I-Cache line specified by address in U-Mode + * \details + * This function lock one I-Cache line specified by the address. + * Command \ref CCM_IC_LOCK is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be locked + * \return result of CCM lock operation, see enum \ref CCM_OP_FINFO + */ +__STATIC_FORCEINLINE unsigned long ULockICacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_UBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_IC_LOCK); + return __RV_CSR_READ(CSR_CCM_UDATA); +} + +/** + * \brief Lock several I-Cache lines specified by address in U-Mode + * \details + * This function lock several I-Cache lines specified by the address + * and line count. + * Command \ref CCM_IC_LOCK is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be locked + * \param [in] cnt count of cache lines to be locked + * \return result of CCM lock operation, see enum \ref CCM_OP_FINFO + */ +__STATIC_FORCEINLINE unsigned long ULockICacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + unsigned long fail_info = CCM_OP_SUCCESS; + __RV_CSR_WRITE(CSR_CCM_UBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_IC_LOCK); + fail_info = __RV_CSR_READ(CSR_CCM_UDATA); + if (CCM_OP_SUCCESS != fail_info) { + return fail_info; + } + } + } + return CCM_OP_SUCCESS; +} + +/** + * \brief Unlock one I-Cache line specified by address in M-Mode + * \details + * This function unlock one I-Cache line specified by the address. + * Command \ref CCM_IC_UNLOCK is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be unlocked + */ +__STATIC_FORCEINLINE void MUnlockICacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_MBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_IC_UNLOCK); +} + +/** + * \brief Unlock several I-Cache lines specified by address in M-Mode + * \details + * This function unlock several I-Cache lines specified + * by the address and line count. + * Command \ref CCM_IC_UNLOCK is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be unlocked + * \param [in] cnt count of cache lines to be unlocked + */ +__STATIC_FORCEINLINE void MUnlockICacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_MBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_IC_UNLOCK); + } + } +} + +/** + * \brief Unlock one I-Cache line specified by address in S-Mode + * \details + * This function unlock one I-Cache line specified by the address. + * Command \ref CCM_IC_UNLOCK is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be unlocked + */ +__STATIC_FORCEINLINE void SUnlockICacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_SBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_IC_UNLOCK); +} + +/** + * \brief Unlock several I-Cache lines specified by address in S-Mode + * \details + * This function unlock several I-Cache lines specified + * by the address and line count. + * Command \ref CCM_IC_UNLOCK is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be unlocked + * \param [in] cnt count of cache lines to be unlocked + */ +__STATIC_FORCEINLINE void SUnlockICacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_SBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_IC_UNLOCK); + } + } +} + +/** + * \brief Unlock one I-Cache line specified by address in U-Mode + * \details + * This function unlock one I-Cache line specified by the address. + * Command \ref CCM_IC_UNLOCK is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be unlocked + */ +__STATIC_FORCEINLINE void UUnlockICacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_UBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_IC_UNLOCK); +} + +/** + * \brief Unlock several I-Cache lines specified by address in U-Mode + * \details + * This function unlock several I-Cache lines specified + * by the address and line count. + * Command \ref CCM_IC_UNLOCK is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be unlocked + * \param [in] cnt count of cache lines to be unlocked + */ +__STATIC_FORCEINLINE void UUnlockICacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_UBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_IC_UNLOCK); + } + } +} + +/** + * \brief Invalidate all I-Cache lines in M-Mode + * \details + * This function invalidate all I-Cache lines. + * Command \ref CCM_IC_INVAL_ALL is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be invalidated + */ +__STATIC_FORCEINLINE void MInvalICache(void) +{ + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_IC_INVAL_ALL); +} + +/** + * \brief Invalidate all I-Cache lines in S-Mode + * \details + * This function invalidate all I-Cache lines. + * Command \ref CCM_IC_INVAL_ALL is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be invalidated + */ +__STATIC_FORCEINLINE void SInvalICache(void) +{ + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_IC_INVAL_ALL); +} + +/** + * \brief Invalidate all I-Cache lines in U-Mode + * \details + * This function invalidate all I-Cache lines. + * Command \ref CCM_IC_INVAL_ALL is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be invalidated + */ +__STATIC_FORCEINLINE void UInvalICache(void) +{ + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_IC_INVAL_ALL); +} +#endif /* defined(__CCM_PRESENT) && (__CCM_PRESENT == 1) */ +/** @} */ /* End of Doxygen Group NMSIS_Core_ICache */ +#endif /* defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1) */ + +#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1) +/** + * \defgroup NMSIS_Core_DCache D-Cache Functions + * \ingroup NMSIS_Core_Cache + * \brief Functions that configure Data Cache. + * @{ + */ + +/** + * \brief Check DCache Unit Present or Not + * \details + * This function check dcache unit present or not via mcfg_info csr + * \remarks + * - This function might not work for some old nuclei processors + * - Please make sure the version of your nuclei processor contain DCACHE bit in mcfg_info + * \return 1 if present otherwise 0 +*/ +__STATIC_FORCEINLINE int32_t DCachePresent(void) +{ + if (__RV_CSR_READ(CSR_MCFG_INFO) & MCFG_INFO_DCACHE) { + return 1; + } + return 0; +} + +/** + * \brief Enable DCache + * \details + * This function enable D-Cache + * \remarks + * - This function can be called in M-Mode only. + * - This \ref CSR_MCACHE_CTL register control D Cache enable. + * \sa + * - \ref DisableDCache +*/ +__STATIC_FORCEINLINE void EnableDCache(void) +{ + __RV_CSR_SET(CSR_MCACHE_CTL, MCACHE_CTL_DC_EN); +} + +/** + * \brief Disable DCache + * \details + * This function Disable D-Cache + * \remarks + * - This function can be called in M-Mode only. + * - This \ref CSR_MCACHE_CTL register control D Cache enable. + * \sa + * - \ref EnableDCache + */ +__STATIC_FORCEINLINE void DisableDCache(void) +{ + __RV_CSR_CLEAR(CSR_MCACHE_CTL, MCACHE_CTL_DC_EN); +} + +/** + * \brief Enable DCache ECC + * \details + * This function enable D-Cache ECC + * \remarks + * - This function can be called in M-Mode only. + * - This \ref CSR_MCACHE_CTL register control D Cache ECC enable. + * \sa + * - \ref DisableDCacheECC +*/ +__STATIC_FORCEINLINE void EnableDCacheECC(void) +{ + __RV_CSR_SET(CSR_MCACHE_CTL, MCACHE_CTL_DC_ECC_EN); +} + +/** + * \brief Disable DCache ECC + * \details + * This function disable D-Cache ECC + * \remarks + * - This function can be called in M-Mode only. + * - This \ref CSR_MCACHE_CTL register control D Cache ECC enable. + * \sa + * - \ref EnableDCacheECC +*/ +__STATIC_FORCEINLINE void DisableDCacheECC(void) +{ + __RV_CSR_CLEAR(CSR_MCACHE_CTL, MCACHE_CTL_DC_ECC_EN); +} + +#if defined(__CCM_PRESENT) && (__CCM_PRESENT == 1) +/** + * \brief Get D-Cache Information + * \details + * This function get D-Cache Information + * \remarks + * - This function can be called in M-Mode only. + * - You can use this function in combination with cache lines operations + * \sa + * - \ref GetICacheInfo + */ +__STATIC_FORCEINLINE int32_t GetDCacheInfo(CacheInfo_Type *info) +{ + if (info == NULL) { + return -1; + } + CSR_MDCFGINFO_Type csr_ccfg; + csr_ccfg.d = __RV_CSR_READ(CSR_MDCFG_INFO); + info->setperway = (1 << csr_ccfg.b.set) << 3; + info->ways = (1 + csr_ccfg.b.way); + if (csr_ccfg.b.lsize == 0) { + info->linesize = 0; + } else { + info->linesize = (1 << (csr_ccfg.b.lsize - 1)) << 3; + } + info->size = info->setperway * info->ways * info->linesize; + return 0; +} + +/** + * \brief Invalidate one D-Cache line specified by address in M-Mode + * \details + * This function unlock and invalidate one D-Cache line specified + * by the address. + * Command \ref CCM_DC_INVAL is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be invalidated + */ +__STATIC_FORCEINLINE void MInvalDCacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_MBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_DC_INVAL); +} + +/** + * \brief Invalidate several D-Cache lines specified by address in M-Mode + * \details + * This function unlock and invalidate several D-Cache lines specified + * by the address and line count. + * Command \ref CCM_DC_INVAL is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be invalidated + * \param [in] cnt count of cache lines to be invalidated + */ +__STATIC_FORCEINLINE void MInvalDCacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_MBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_DC_INVAL); + } + } +} + +/** + * \brief Invalidate one D-Cache line specified by address in S-Mode + * \details + * This function unlock and invalidate one D-Cache line specified + * by the address. + * Command \ref CCM_DC_INVAL is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be invalidated + */ +__STATIC_FORCEINLINE void SInvalDCacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_SBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_DC_INVAL); +} + +/** + * \brief Invalidate several D-Cache lines specified by address in S-Mode + * \details + * This function unlock and invalidate several D-Cache lines specified + * by the address and line count. + * Command \ref CCM_DC_INVAL is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be invalidated + * \param [in] cnt count of cache lines to be invalidated + */ +__STATIC_FORCEINLINE void SInvalDCacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_SBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_DC_INVAL); + } + } +} + +/** + * \brief Invalidate one D-Cache line specified by address in U-Mode + * \details + * This function unlock and invalidate one D-Cache line specified + * by the address. + * Command \ref CCM_DC_INVAL is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be invalidated + */ +__STATIC_FORCEINLINE void UInvalDCacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_UBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_DC_INVAL); +} + +/** + * \brief Invalidate several D-Cache lines specified by address in U-Mode + * \details + * This function unlock and invalidate several D-Cache lines specified + * by the address and line count. + * Command \ref CCM_DC_INVAL is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be invalidated + * \param [in] cnt count of cache lines to be invalidated + */ +__STATIC_FORCEINLINE void UInvalDCacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_UBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_DC_INVAL); + } + } +} + +/** + * \brief Flush one D-Cache line specified by address in M-Mode + * \details + * This function flush one D-Cache line specified by the address. + * Command \ref CCM_DC_WB is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be flushed + */ +__STATIC_FORCEINLINE void MFlushDCacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_MBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_DC_WB); +} + +/** + * \brief Flush several D-Cache lines specified by address in M-Mode + * \details + * This function flush several D-Cache lines specified + * by the address and line count. + * Command \ref CCM_DC_WB is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be flushed + * \param [in] cnt count of cache lines to be flushed + */ +__STATIC_FORCEINLINE void MFlushDCacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_MBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_DC_WB); + } + } +} + +/** + * \brief Flush one D-Cache line specified by address in S-Mode + * \details + * This function flush one D-Cache line specified by the address. + * Command \ref CCM_DC_WB is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be flushed + */ +__STATIC_FORCEINLINE void SFlushDCacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_SBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_DC_WB); +} + +/** + * \brief Flush several D-Cache lines specified by address in S-Mode + * \details + * This function flush several D-Cache lines specified + * by the address and line count. + * Command \ref CCM_DC_WB is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be flushed + * \param [in] cnt count of cache lines to be flushed + */ +__STATIC_FORCEINLINE void SFlushDCacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_SBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_DC_WB); + } + } +} + +/** + * \brief Flush one D-Cache line specified by address in U-Mode + * \details + * This function flush one D-Cache line specified by the address. + * Command \ref CCM_DC_WB is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be flushed + */ +__STATIC_FORCEINLINE void UFlushDCacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_UBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_DC_WB); +} + +/** + * \brief Flush several D-Cache lines specified by address in U-Mode + * \details + * This function flush several D-Cache lines specified + * by the address and line count. + * Command \ref CCM_DC_WB is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be flushed + * \param [in] cnt count of cache lines to be flushed + */ +__STATIC_FORCEINLINE void UFlushDCacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_UBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_DC_WB); + } + } +} + +/** + * \brief Flush and invalidate one D-Cache line specified by address in M-Mode + * \details + * This function flush and invalidate one D-Cache line specified by the address. + * Command \ref CCM_DC_WBINVAL is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be flushed and invalidated + */ +__STATIC_FORCEINLINE void MFlushInvalDCacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_MBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_DC_WBINVAL); +} + +/** + * \brief Flush and invalidate several D-Cache lines specified by address in M-Mode + * \details + * This function flush and invalidate several D-Cache lines specified + * by the address and line count. + * Command \ref CCM_DC_WBINVAL is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be flushed and invalidated + * \param [in] cnt count of cache lines to be flushed and invalidated + */ +__STATIC_FORCEINLINE void MFlushInvalDCacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_MBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_DC_WBINVAL); + } + } +} + +/** + * \brief Flush and invalidate one D-Cache line specified by address in S-Mode + * \details + * This function flush and invalidate one D-Cache line specified by the address. + * Command \ref CCM_DC_WBINVAL is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be flushed and invalidated + */ +__STATIC_FORCEINLINE void SFlushInvalDCacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_SBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_DC_WBINVAL); +} + +/** + * \brief Flush and invalidate several D-Cache lines specified by address in S-Mode + * \details + * This function flush and invalidate several D-Cache lines specified + * by the address and line count. + * Command \ref CCM_DC_WBINVAL is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be flushed and invalidated + * \param [in] cnt count of cache lines to be flushed and invalidated + */ +__STATIC_FORCEINLINE void SFlushInvalDCacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_SBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_DC_WBINVAL); + } + } +} + +/** + * \brief Flush and invalidate one D-Cache line specified by address in U-Mode + * \details + * This function flush and invalidate one D-Cache line specified by the address. + * Command \ref CCM_DC_WBINVAL is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be flushed and invalidated + */ +__STATIC_FORCEINLINE void UFlushInvalDCacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_UBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_DC_WBINVAL); +} + +/** + * \brief Flush and invalidate several D-Cache lines specified by address in U-Mode + * \details + * This function flush and invalidate several D-Cache lines specified + * by the address and line count. + * Command \ref CCM_DC_WBINVAL is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be flushed and invalidated + * \param [in] cnt count of cache lines to be flushed and invalidated + */ +__STATIC_FORCEINLINE void UFlushInvalDCacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_UBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_DC_WBINVAL); + } + } +} + +/** + * \brief Lock one D-Cache line specified by address in M-Mode + * \details + * This function lock one D-Cache line specified by the address. + * Command \ref CCM_DC_LOCK is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be locked + * \return result of CCM lock operation, see enum \ref CCM_OP_FINFO + */ +__STATIC_FORCEINLINE unsigned long MLockDCacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_MBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_DC_LOCK); + return __RV_CSR_READ(CSR_CCM_MDATA); +} + +/** + * \brief Lock several D-Cache lines specified by address in M-Mode + * \details + * This function lock several D-Cache lines specified by the address + * and line count. + * Command \ref CCM_DC_LOCK is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be locked + * \param [in] cnt count of cache lines to be locked + * \return result of CCM lock operation, see enum \ref CCM_OP_FINFO + */ +__STATIC_FORCEINLINE unsigned long MLockDCacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + unsigned long fail_info = CCM_OP_SUCCESS; + __RV_CSR_WRITE(CSR_CCM_MBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_DC_LOCK); + fail_info = __RV_CSR_READ(CSR_CCM_MDATA); + if (CCM_OP_SUCCESS != fail_info) { + return fail_info; + } + } + } + return CCM_OP_SUCCESS; +} + +/** + * \brief Lock one D-Cache line specified by address in S-Mode + * \details + * This function lock one D-Cache line specified by the address. + * Command \ref CCM_DC_LOCK is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be locked + * \return result of CCM lock operation, see enum \ref CCM_OP_FINFO + */ +__STATIC_FORCEINLINE unsigned long SLockDCacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_SBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_DC_LOCK); + return __RV_CSR_READ(CSR_CCM_SDATA); +} + +/** + * \brief Lock several D-Cache lines specified by address in S-Mode + * \details + * This function lock several D-Cache lines specified by the address + * and line count. + * Command \ref CCM_DC_LOCK is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be locked + * \param [in] cnt count of cache lines to be locked + * \return result of CCM lock operation, see enum \ref CCM_OP_FINFO + */ +__STATIC_FORCEINLINE unsigned long SLockDCacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + unsigned long fail_info = CCM_OP_SUCCESS; + __RV_CSR_WRITE(CSR_CCM_SBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_DC_LOCK); + fail_info = __RV_CSR_READ(CSR_CCM_SDATA); + if (CCM_OP_SUCCESS != fail_info) { + return fail_info; + } + } + } + return CCM_OP_SUCCESS; +} + +/** + * \brief Lock one D-Cache line specified by address in U-Mode + * \details + * This function lock one D-Cache line specified by the address. + * Command \ref CCM_DC_LOCK is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be locked + * \return result of CCM lock operation, see enum \ref CCM_OP_FINFO + */ +__STATIC_FORCEINLINE unsigned long ULockDCacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_UBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_DC_LOCK); + return __RV_CSR_READ(CSR_CCM_UDATA); +} + +/** + * \brief Lock several D-Cache lines specified by address in U-Mode + * \details + * This function lock several D-Cache lines specified by the address + * and line count. + * Command \ref CCM_DC_LOCK is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be locked + * \param [in] cnt count of cache lines to be locked + * \return result of CCM lock operation, see enum \ref CCM_OP_FINFO + */ +__STATIC_FORCEINLINE unsigned long ULockDCacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + unsigned long fail_info = CCM_OP_SUCCESS; + __RV_CSR_WRITE(CSR_CCM_UBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_DC_LOCK); + fail_info = __RV_CSR_READ(CSR_CCM_UDATA); + if (CCM_OP_SUCCESS != fail_info) { + return fail_info; + } + } + } + return CCM_OP_SUCCESS; +} + +/** + * \brief Unlock one D-Cache line specified by address in M-Mode + * \details + * This function unlock one D-Cache line specified by the address. + * Command \ref CCM_DC_UNLOCK is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be unlocked + */ +__STATIC_FORCEINLINE void MUnlockDCacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_MBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_DC_UNLOCK); +} + +/** + * \brief Unlock several D-Cache lines specified by address in M-Mode + * \details + * This function unlock several D-Cache lines specified + * by the address and line count. + * Command \ref CCM_DC_UNLOCK is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be unlocked + * \param [in] cnt count of cache lines to be unlocked + */ +__STATIC_FORCEINLINE void MUnlockDCacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_MBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_DC_UNLOCK); + } + } +} + +/** + * \brief Unlock one D-Cache line specified by address in S-Mode + * \details + * This function unlock one D-Cache line specified by the address. + * Command \ref CCM_DC_UNLOCK is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be unlocked + */ +__STATIC_FORCEINLINE void SUnlockDCacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_SBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_DC_UNLOCK); +} + +/** + * \brief Unlock several D-Cache lines specified by address in S-Mode + * \details + * This function unlock several D-Cache lines specified + * by the address and line count. + * Command \ref CCM_DC_UNLOCK is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be unlocked + * \param [in] cnt count of cache lines to be unlocked + */ +__STATIC_FORCEINLINE void SUnlockDCacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_SBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_DC_UNLOCK); + } + } +} + +/** + * \brief Unlock one D-Cache line specified by address in U-Mode + * \details + * This function unlock one D-Cache line specified by the address. + * Command \ref CCM_DC_UNLOCK is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be unlocked + */ +__STATIC_FORCEINLINE void UUnlockDCacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_UBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_DC_UNLOCK); +} + +/** + * \brief Unlock several D-Cache lines specified by address in U-Mode + * \details + * This function unlock several D-Cache lines specified + * by the address and line count. + * Command \ref CCM_DC_UNLOCK is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be unlocked + * \param [in] cnt count of cache lines to be unlocked + */ +__STATIC_FORCEINLINE void UUnlockDCacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_UBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_DC_UNLOCK); + } + } +} + +/** + * \brief Invalidate all D-Cache lines in M-Mode + * \details + * This function invalidate all D-Cache lines. + * Command \ref CCM_DC_INVAL_ALL is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be invalidated + */ +__STATIC_FORCEINLINE void MInvalDCache(void) +{ + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_DC_INVAL_ALL); +} + +/** + * \brief Invalidate all D-Cache lines in S-Mode + * \details + * This function invalidate all D-Cache lines. + * Command \ref CCM_DC_INVAL_ALL is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be invalidated + */ +__STATIC_FORCEINLINE void SInvalDCache(void) +{ + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_DC_INVAL_ALL); +} + +/** + * \brief Invalidate all D-Cache lines in U-Mode + * \details + * This function invalidate all D-Cache lines. + * In U-Mode, this operation will be automatically + * translated to flush and invalidate operations by hardware. + * Command \ref CCM_DC_INVAL_ALL is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be invalidated + */ +__STATIC_FORCEINLINE void UInvalDCache(void) +{ + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_DC_INVAL_ALL); +} + +/** + * \brief Flush all D-Cache lines in M-Mode + * \details + * This function flush all D-Cache lines. + * Command \ref CCM_DC_WB_ALL is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be flushed + */ +__STATIC_FORCEINLINE void MFlushDCache(void) +{ + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_DC_WB_ALL); +} + +/** + * \brief Flush all D-Cache lines in S-Mode + * \details + * This function flush all D-Cache lines. + * Command \ref CCM_DC_WB_ALL is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be flushed + */ +__STATIC_FORCEINLINE void SFlushDCache(void) +{ + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_DC_WB_ALL); +} + +/** + * \brief Flush all D-Cache lines in U-Mode + * \details + * This function flush all D-Cache lines. + * Command \ref CCM_DC_WB_ALL is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be flushed + */ +__STATIC_FORCEINLINE void UFlushDCache(void) +{ + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_DC_WB_ALL); +} + +/** + * \brief Flush and invalidate all D-Cache lines in M-Mode + * \details + * This function flush and invalidate all D-Cache lines. + * Command \ref CCM_DC_WBINVAL_ALL is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be flushed and locked + */ +__STATIC_FORCEINLINE void MFlushInvalDCache(void) +{ + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_DC_WBINVAL_ALL); +} + +/** + * \brief Flush and invalidate all D-Cache lines in S-Mode + * \details + * This function flush and invalidate all D-Cache lines. + * Command \ref CCM_DC_WBINVAL_ALL is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be flushed and locked + */ +__STATIC_FORCEINLINE void SFlushInvalDCache(void) +{ + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_DC_WBINVAL_ALL); +} + +/** + * \brief Flush and invalidate all D-Cache lines in U-Mode + * \details + * This function flush and invalidate all D-Cache lines. + * Command \ref CCM_DC_WBINVAL_ALL is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be flushed and locked + */ +__STATIC_FORCEINLINE void UFlushInvalDCache(void) +{ + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_DC_WBINVAL_ALL); +} +#endif /* defined(__CCM_PRESENT) && (__CCM_PRESENT == 1) */ + +/** @} */ /* End of Doxygen Group NMSIS_Core_DCache */ +#endif /* defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1) */ + +#ifdef __cplusplus +} +#endif +#endif /* __CORE_FEATURE_CACHE_H__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_cidu.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_cidu.h new file mode 100644 index 0000000..35c9a23 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_cidu.h @@ -0,0 +1,438 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __CORE_FEATURE_CIDU_H__ +#define __CORE_FEATURE_CIDU_H__ +/*! + * @file core_feature_cidu.h + * @brief Cluster Interrupt Distribution Unit feature API header file for Nuclei N/NX Core + */ +/* + * CIDU Feature Configuration Macro: + * 1. __CIDU_PRESENT: Define whether Cluster Interrupt Distribution Unit is present or not. + * * 0: Not present + * * 1: Present + * 2. __CIDU_BASEADDR: Define the base address of the CIDU. + */ +#ifdef __cplusplus +extern "C" { +#endif + +#include "core_feature_base.h" + +#if defined(__CIDU_PRESENT) && (__CIDU_PRESENT == 1) + +/* ########################## CIDU functions #################################### */ +/** + * \defgroup NMSIS_Core_CIDU CIDU Functions + * \brief Functions that manage external interrupts, inter core interrupts and semaphores. + * @{ + * + * Nuclei provide Cluster Interrupt Distribution Unit (CIDU) for scenarios that a SMP system is designed for real + * time application or both Linux and real time application, and Nuclei processor core can optionally support CIDU. + * The CIDU is used to distribute external interrupts to the core’s ECLIC, also it provides Inter Core Interrupt (ICI) + * and Semaphores Mechanism. Its features are as follows: + * + * * Support up to 16 Cores in one cluster + * * Support up to 4096 external interrupts sources + * * Support up to 16 Inter Core Interrupts + * * Support 32 Semaphores + * + */ + +#ifndef __CIDU_BASEADDR +/* Base address of CIDU(__CIDU_BASEADDR) should be defined in */ +#error "__CIDU_BASEADDR is not defined, please check!" +#endif + +#define CIDU_BASE __CIDU_BASEADDR +#define CIDU_RECEIVE_INTERRUPT_EN(core_id) (0x1U << core_id) /*!< Indicates the core can receive corresponding interrupt */ + +#define CIDU_CORE_INT_STATUS_OFS 0x0 /*!< Core n Inter Core Interrupt status register base offset */ +#define CIDU_SEMAPHORE_OFS 0x80 /*!< Semaphore n register base offset */ +#define CIDU_ICI_SHADOW_OFS 0x3FFC /*!< ICI Interrupt source core ID and target core ID register offset */ +#define CIDU_INT_INDICATOR_OFS 0x4000 /*!< External interrupt n indicator register base offset */ +#define CIDU_INT_MASK_OFS 0x8000 /*!< External interrupt n mask (mask interrupt n to cores or not when interrupt n indicator on)register base offset */ +#define CIDU_CORE_NUM_OFS 0xC084 /*!< Static configuration core num register offset */ +#define CIDU_INT_NUM_OFS 0xC090 /*!< Static configuration external interrupt number register offset */ + +#define CIDU_CORE_INT_STATUS_ADDR(n) (unsigned long)((CIDU_BASE) + (CIDU_CORE_INT_STATUS_OFS) + ((n) << 2)) /*!< Core n Inter Core Interrupt status register address */ +#define CIDU_SEMAPHORE_ADDR(n) (unsigned long)((CIDU_BASE) + (CIDU_SEMAPHORE_OFS) + ((n) << 2)) /*!< Semaphore n register address */ +#define CIDU_ICI_SHADOW_ADDR (unsigned long)((CIDU_BASE) + (CIDU_ICI_SHADOW_OFS)) /*!< ICI Interrupt source core ID and target core ID register address */ +#define CIDU_INT_INDICATOR_ADDR(n) (unsigned long)((CIDU_BASE) + (CIDU_INT_INDICATOR_OFS) + ((n) << 2)) /*!< External interrupt n indicator register address */ +#define CIDU_INT_MASK_ADDR(n) (unsigned long)((CIDU_BASE) + (CIDU_INT_MASK_OFS) + ((n) << 2)) /*!< External interrupt n mask (mask interrupt n to cores or not when interrupt n indicator on)register address */ +#define CIDU_CORE_NUM_ADDR (unsigned long)((CIDU_BASE) + (CIDU_CORE_NUM_OFS)) /*!< Static configuration core num register address */ +#define CIDU_INT_NUM_ADDR (unsigned long)((CIDU_BASE) + (CIDU_INT_NUM_OFS)) /*!< Static configuration external interrupt number register address */ + + +/* SEND_CORE_ID position in ICI_SHADOW_REG register */ +#define CIDU_ICI_SEND_CORE_ID_POS 16 + +/** + * \brief Get core number in the cluster + * \details + * Indicate the static configuration core num in the cluster. + * \return core number configured + * \remarks + * - In a Nulcei multi-core system, each core has an identifiable serial number, the serial number starts from 0 and is + * continuous, also the number is static. + * - CORE_NUM register is read only. +*/ +__STATIC_FORCEINLINE uint32_t CIDU_GetCoreNum(void) +{ + uint32_t val; + uint32_t* addr = (uint32_t*)CIDU_CORE_NUM_ADDR; + + val = __LW(addr); + return val; +} + +/** + * \brief Get external interrupt number + * \details + * Indicate the static configuration external interrupt number + * \return interrupt number configured + * \remarks + * - INT_NUM register is read only. +*/ +__STATIC_FORCEINLINE uint32_t CIDU_GetIntNum(void) +{ + uint32_t val; + uint32_t* addr = (uint32_t*)CIDU_INT_NUM_ADDR; + + val = __LW(addr); + return val; +} +/** @} */ /* End of Doxygen Group NMSIS_Core_CIDU */ + +/** + * \defgroup NMSIS_Core_Distribute_Interrupt External Interrupt Distribution Functions + * \ingroup NMSIS_Core_CIDU + * \brief Functions that distribute external interrupts to cores. + * @{ + */ + +/** + * \brief Broadcast external interrupt to cores + * \details + * This function broadcasts external interrupt which id is int_id to some/all target cores + * \param [in] int_id external interrupt id + * \param [in] to_cores target cores which can receive interrupt, use bitwise inclusive or + * of \ref CIDU_RECEIVE_INTERRUPT_EN(core_id) + * \remarks + * - External IRQn ID(int_id) is from the hard-wired persperctive, + * which has an offset mapped to the ECLIC IRQn, see Interrupt Number Definition in + * - By default on reset, only core 0 can receive interrupt which id is int_id +*/ +__STATIC_FORCEINLINE void CIDU_BroadcastExtInterrupt(uint32_t int_id, uint32_t to_cores) +{ + uint32_t* addr = (uint32_t*)CIDU_INT_INDICATOR_ADDR(int_id); + + __SW(addr, (uint32_t)to_cores); +} + +/** + * \brief get broadcast mode status + * \details + * Just query the INTn_INDICATOR register value + * \param [in] int_id external interrupt id + * \return INTn_INDICATOR register value + * \remarks + * - External IRQn ID(int_id) is from the hard-wired persperctive, + * which has an offset mapped to the ECLIC IRQn, see Interrupt Number Definition in + * - By default on reset, only core 0 can receive interrupt which id is int_id +*/ +__STATIC_FORCEINLINE uint32_t CIDU_GetBroadcastModeStatus(uint32_t int_id) +{ + uint32_t val = 0; + uint32_t* addr = (uint32_t*)CIDU_INT_INDICATOR_ADDR(int_id); + + val = __LW(addr); + return val; +} + +/** + * \brief Let the first coming core to first claim the interrupt + * \details + * In external interrupt broadcast mode, make the first coming core to claim this interrupt and then can handle it. + * \param [in] int_id external interrupt id + * \param [in] core_id core id that receive the interrupt + * \return -1 if it fails to claim the interrupt, else it can continue to handle the interrupt + * \remarks + * - External IRQn ID(int_id) is from the hard-wired persperctive, + * which has an offset mapped to the ECLIC IRQn, see Interrupt Number Definition in . + * - If it fails to claim the interrupt, it should quit the interrupt n's handler of all cores + * - When a core claims the interrupt successfully and has handled it, it must call \ref CIDU_ResetFirstClaimMode to reset the claim. + * \sa + * - \ref CIDU_BroadcastExtInterrupt + * - \ref CIDU_ResetFirstClaimMode +*/ +__STATIC_FORCEINLINE long CIDU_SetFirstClaimMode(uint32_t int_id, uint32_t core_id) +{ + uint32_t val = 0; + uint32_t* addr = (uint32_t*)CIDU_INT_MASK_ADDR(int_id); + uint32_t mask = 1 << core_id; + + __SW(addr, mask); + val = __LW(addr); + if (mask == val) { + return 0; + } + return -1; +} + +/** + * \brief Reset the claim mode mask + * \details + * Reset the claim mode mask by Writing the reset value (all 1) to it + * \param [in] int_id external interrupt id + * \remarks + * - External IRQn ID(int_id) is from the hard-wired persperctive, + * which has an offset mapped to the ECLIC IRQn, see Interrupt Number Definition in + * - When a core claims the interrupt successfully and handle it, it must call \ref CIDU_ResetFirstClaimMode to reset the claim + * \sa + * - \ref CIDU_SetFirstClaimMode +*/ +__STATIC_FORCEINLINE void CIDU_ResetFirstClaimMode(uint32_t int_id) +{ + uint32_t val = 0; + uint32_t* addr = (uint32_t*)CIDU_INT_MASK_ADDR(int_id); + + /* clear by writing all 1 */ + __SW(addr, 0xFFFFFFFF); +} + +/** + * \brief Get the claim mask status + * \details + * Get the claim mode staus, each bit[n] indicates whether core n has claimed interrupt successfully, + * 1 means yes, 0 means no. + * \param [in] int_id external interrupt id + * \return claim mode register INTn_MASK value + * \remarks + * - External IRQn ID(int_id) is from the hard-wired persperctive, + * which has an offset mapped to the ECLIC IRQn, see Interrupt Number Definition in + * \sa + * - \ref CIDU_ResetFirstClaimMode + * - \ref CIDU_SetFirstClaimMode +*/ +__STATIC_FORCEINLINE uint32_t CIDU_GetClaimStatus(uint32_t int_id) +{ + uint32_t val = 0; + uint32_t* addr = (uint32_t*)CIDU_INT_MASK_ADDR(int_id); + + val = __LW(addr); + return val; +} +/** @} */ /* End of Doxygen Group NMSIS_Core_Distribute_Interrupt */ + +/** + * \defgroup NMSIS_Core_ICI Inter Core Interrupt Functions + * \ingroup NMSIS_Core_CIDU + * \brief Functions that implement Inter Core Interrupt mechanism. + * @{ + * Inter Core Interrupt (ICI) means that one core can send interrupt to another core in a multi-core cluster. CIDU ICI belongs + * to Internal Interrupt. + * + * * CIDU ICI Interrupt ID is fixed to 16. + */ + +/** + * \brief Trigger interrupt to another core in a multi-core cluster + * \details + * When called by core send_core_id, CIDU will trigger ICI to core recv_core_id automatically. + * and core recv_core_id could query \ref CIDU_GetCoreIntSenderId to know the sender. + * \param [in] send_core_id the core id which want to send the inter core interrupt + * \param [in] recv_core_id the core id which will receive the inter core interrupt + * \remarks + * - The core recv_core_id need to call CIDU_ClearInterCoreIntReq to clear the corresponding bit/bits + * of its own COREn_INT_STATUS. + * - It supports that multiple cores call \ref CIDU_TriggerInterCoreInt simultaneously. + * \sa + * - \ref CIDU_GetCoreIntSenderId + * - \ref CIDU_ClearInterCoreIntReq +*/ +__STATIC_FORCEINLINE void CIDU_TriggerInterCoreInt(uint32_t send_core_id, uint32_t recv_core_id) +{ + uint32_t val = 0; + uint32_t* addr = (uint32_t*)CIDU_ICI_SHADOW_ADDR; + + val = (uint32_t)(send_core_id << CIDU_ICI_SEND_CORE_ID_POS) | (uint32_t)(recv_core_id); + __SW(addr, (uint32_t)val); +} + +/** + * \brief Core recv_core_id queries out who sends inter core interrupt to itself + * \details + * In the ISR of ICI, receive core can query if bit[n] of this return value is 1, core n sends the current ICI, + * if bit[m] is 1, then core m also sends, etc. + * \param [in] recv_core_id the core id which receives the inter core interrupt + * \return Value that shows sender core's ID n whose bit[n](bit[m] if core m send too, etc.) is 1 + * \remarks + * - If the ICI ISR has finished the job, should call \ref CIDU_ClearInterCoreIntReq to clear the IRQ +*/ +__STATIC_FORCEINLINE uint32_t CIDU_QueryCoreIntSenderMask(uint32_t recv_core_id) +{ + uint32_t val = 0; + uint32_t* addr = (uint32_t*)CIDU_CORE_INT_STATUS_ADDR(recv_core_id); + + val = __LW(addr); + return val; +} + +/** + * \brief Clear the corresponding bit/bits of ICI request triggered by sender core + * \details + * Core recv_core_id write 1 to clear the bit send_core_id of the core recv_core_id's COREn_INT_STATUS. + * \param [in] send_core_id the core id which wants to send the inter core interrupt + * \param [in] recv_core_id the core id which will receive the inter core interrupt + * \remarks + * - If the ICI ISR has finished the job of send_core_id_n's ICI, then clear bit send_core_id_n; + * if it has finished send_core_id_n and send_core_id_m's, then should clear both the bits, etc. +*/ +__STATIC_FORCEINLINE void CIDU_ClearInterCoreIntReq(uint32_t send_core_id, uint32_t recv_core_id) +{ + uint32_t val = 0; + uint32_t* addr = (uint32_t*)CIDU_CORE_INT_STATUS_ADDR(recv_core_id); + + val = (uint32_t)(1 << send_core_id); + __SW(addr, val); +} +/** @} */ /* End of Doxygen Group NMSIS_Core_ICI */ + +/** + * \defgroup NMSIS_Core_Semaphore Semaphore Functions + * \ingroup NMSIS_Core_CIDU + * \brief Functions that configure and use semaphores + * @{ + * Semaphore is very useful for multi-core cluster without SMP enable. + * + * * All Cores in the cluster agree on using SEMAPHORE_n register to protect a critical resource (an UART device for example). + * * If Core n wants to access the critical resource, it should try to own the SEMPAPHORE_n register, or else it can’t access the critical resource. + * * When the Core n owns the register SEMPAPHORE_n and finishes the job related the critical resource, then it should + * release the register by writing all 1 to it. + */ + +/** + * \brief Get SEMAPHOREn's value + * \details + * Just query the semaphore n's value + * \param [in] semph_n the semaphore id used to protect a critical resource + * \return register SEMAPHOREn_STATUS value +*/ +__STATIC_FORCEINLINE uint32_t CIDU_GetSemaphoreStatus(uint32_t semph_n) +{ + uint32_t val; + uint32_t* addr = (uint32_t*)CIDU_SEMAPHORE_ADDR(semph_n); + + val = __LW(addr); + return val; +} + +/** + * \brief check SEMAPHOREn's acquired status + * \details + * Query that whether SEMAPHOREn has been acquired by one core successfully. + * \param [in] semph_n the semaphore id used to protect a critical resource + * \param [in] core_id the core id that wants to access the critical resource + * \return 0 if core_id has acquired this semaphore successfully, or else -1 if failed + * \remarks + * - When the core n owns the register SEMPAPHORE_n and finishes the job related the critical resource, + * it should call \ref CIDU_ReleaseSemaphore to release it. + * \sa + * - \ref CIDU_GetSemaphoreStatus + * - \ref CIDU_ReleaseSemaphore +*/ +__STATIC_FORCEINLINE long CIDU_CheckSemaphoreAcquired(uint32_t semph_n, uint32_t core_id) +{ + uint32_t val; + val = CIDU_GetSemaphoreStatus(semph_n); + if (core_id != val) { + return -1; + } + return 0; +} + +/** + * \brief Acquire the SEMAPHOREn + * \details + * Acuqire the SEMAPHOREn, and check the acquired status + * \param [in] semph_n the semaphore id used to protect a critical resource + * \param [in] core_id the core id that wants to access the critical resource + * \return 0 if core_id has acquired this semaphore successfully, or else -1 if failed + * \remarks + * - When the core n owns the register SEMPAPHORE_n and finishes the job related the critical resource, + * it should call \ref CIDU_ReleaseSemaphore to release it. + * \sa + * - \ref CIDU_CheckSemaphoreAcquired + * - \ref CIDU_ReleaseSemaphore +*/ +__STATIC_FORCEINLINE long CIDU_AcquireSemaphore(uint32_t semph_n, uint32_t core_id) +{ + long semaphore_status = -1; + uint32_t* addr = (uint32_t*)CIDU_SEMAPHORE_ADDR(semph_n); + + __SW(addr, core_id); + semaphore_status = CIDU_CheckSemaphoreAcquired(semph_n, core_id); + return semaphore_status; +} + +/** + * \brief Keep acquiring the SEMAPHOREn until it has acquired this semaphore successfully + * \details + * Query that whether SEMAPHOREn has been owned by one core successfully, if not, keep trying. + * \param [in] semph_n the semaphore id used to protect a critical resource + * \param [in] core_id the core id that wants to access the critical resource + * \remarks + * - Core n will block here acquiring, so take care that core should release the semaphore when related job done. + * \sa + * - \ref CIDU_AcquireSemaphore + * - \ref CIDU_ReleaseSemaphore +*/ +__STATIC_FORCEINLINE void CIDU_AcquireSemaphore_Block(uint32_t semph_n, uint32_t core_id) +{ + int32_t semaphore_status = -1; + + while(0 != semaphore_status) { + semaphore_status = CIDU_AcquireSemaphore(semph_n, core_id); + } +} + +/** + * \brief Release the SEMAPHOREn + * \details + * Release the SEMAPHOREn by writing all 1 to SEMAPHOREn register. + * \param [in] semph_n the semaphore id used to protect a critical resource + * \remarks + * - When the core finishes the job related to the critical resource, it should release the corresponding semaphore. + * \sa + * - \ref CIDU_AcquireSemaphore_Block +*/ +__STATIC_FORCEINLINE void CIDU_ReleaseSemaphore(uint32_t semph_n) +{ + uint32_t* addr = (uint32_t*)CIDU_SEMAPHORE_ADDR(semph_n); + + /* Release by writing all 1 */ + __SW(addr, 0xFFFFFFFF); +} +/** @} */ /* End of Doxygen Group NMSIS_Core_Semaphore */ +#endif /* defined(__CIDU_PRESENT) && (__CIDU_PRESENT == 1) */ + +#ifdef __cplusplus +} +#endif +#endif /* __CORE_FEATURE_CIDU_H__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_dsp.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_dsp.h new file mode 100644 index 0000000..60c676c --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_dsp.h @@ -0,0 +1,24934 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __CORE_FEATURE_DSP__ +#define __CORE_FEATURE_DSP__ + +/*! + * @file core_feature_dsp.h + * @brief DSP feature API header file for Nuclei N/NX Core + */ +/* + * DSP Feature Configuration Macro: + * 1. __DSP_PRESENT: Define whether Digital Signal Processing Unit(DSP) is present or not + * * 0: Not present + * * 1: Present + */ +#ifdef __cplusplus + extern "C" { +#endif + +#include "core_feature_base.h" + +#if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1) + +#if defined(__INC_INTRINSIC_API) && (__INC_INTRINSIC_API == 1) +#ifndef __ICCRISCV__ +#include +#endif +#endif + +#ifndef __ICCRISCV__ +/* ########################### CPU SIMD DSP Intrinsic Functions ########################### */ +/** + * \defgroup NMSIS_Core_DSP_Intrinsic Intrinsic Functions for SIMD Instructions + * \ingroup NMSIS_Core + * \brief Functions that generate RISC-V DSP SIMD instructions. + * \details + * + * The following functions generate specified RISC-V SIMD instructions that cannot be directly accessed by compiler. + * * **DSP ISA Extension Instruction Summary** + * + **Shorthand Definitions** + * - r.H == rH1: r[31:16], r.L == r.H0: r[15:0] + * - r.B3: r[31:24], r.B2: r[23:16], r.B1: r[15:8], r.B0: r[7:0] + * - r.B[x]: r[(x*8+7):(x*8+0)] + * - r.H[x]: r[(x*16+7):(x*16+0)] + * - r.W[x]: r[(x*32+31):(x*32+0)] + * - r[xU]: the upper 32-bit of a 64-bit number; xU represents the GPR number that contains this upper part 32-bit value. + * - r[xL]: the lower 32-bit of a 64-bit number; xL represents the GPR number that contains this lower part 32-bit value. + * - r[xU].r[xL]: a 64-bit number that is formed from a pair of GPRs. + * - s>>: signed arithmetic right shift: + * - u>>: unsigned logical right shift + * - SAT.Qn(): Saturate to the range of [-2^n, 2^n-1], if saturation happens, set PSW.OV. + * - SAT.Um(): Saturate to the range of [0, 2^m-1], if saturation happens, set PSW.OV. + * - RUND(): Indicate `rounding`, i.e., add 1 to the most significant discarded bit for right shift or MSW-type multiplication instructions. + * - Sign or Zero Extending functions: + * - SEm(data): Sign-Extend data to m-bit.: + * - ZEm(data): Zero-Extend data to m-bit. + * - ABS(x): Calculate the absolute value of `x`. + * - CONCAT(x,y): Concatinate `x` and `y` to form a value. + * - u<: Unsinged less than comparison. + * - u<=: Unsinged less than & equal comparison. + * - u>: Unsinged greater than comparison. + * - s*: Signed multiplication. + * - u*: Unsigned multiplication. + * + * @{ + */ +/** @} */ /* End of Doxygen Group NMSIS_Core_DSP_Intrinsic */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIMD_DATA_PROCESS SIMD Data Processing Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic + * \brief SIMD Data Processing Instructions + * \details + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB SIMD 16-bit Add/Subtract Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_DATA_PROCESS + * \brief SIMD 16-bit Add/Subtract Instructions + * \details + * Based on the combination of the types of the two 16-bit arithmetic operations, the SIMD 16-bit + * add/subtract instructions can be classified into 6 main categories: Addition (two 16-bit addition), + * Subtraction (two 16-bit subtraction), Crossed Add & Sub (one addition and one subtraction), and + * Crossed Sub & Add (one subtraction and one addition), Straight Add & Sub (one addition and one + * subtraction), and Straight Sub & Add (one subtraction and one addition). + * Based on the way of how an overflow condition is handled, the SIMD 16-bit add/subtract + * instructions can be classified into 5 groups: Wrap-around (dropping overflow), Signed Halving + * (keeping overflow by dropping 1 LSB bit), Unsigned Halving, Signed Saturation (clipping overflow), + * and Unsigned Saturation. + * Together, there are 30 SIMD 16-bit add/subtract instructions. + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_ADDSUB SIMD 8-bit Addition & Subtraction Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_DATA_PROCESS + * \brief SIMD 8-bit Addition & Subtraction Instructions + * \details + * Based on the types of the four 8-bit arithmetic operations, the SIMD 8-bit add/subtract instructions + * can be classified into 2 main categories: Addition (four 8-bit addition), and Subtraction (four 8-bit + * subtraction). + * Based on the way of how an overflow condition is handled for singed or unsigned operation, the + * SIMD 8-bit add/subtract instructions can be classified into 5 groups: Wrap-around (dropping + * overflow), Signed Halving (keeping overflow by dropping 1 LSB bit), Unsigned Halving, Signed + * Saturation (clipping overflow), and Unsigned Saturation. + * Together, there are 10 SIMD 8-bit add/subtract instructions. + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_SHIFT SIMD 16-bit Shift Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_DATA_PROCESS + * \brief SIMD 16-bit Shift Instructions + * \details + * there are 14 SIMD 16-bit shift instructions. + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_SHIFT SIMD 8-bit Shift Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_DATA_PROCESS + * \brief SIMD 8-bit Shift Instructions + * \details + * there are 14 SIMD 8-bit shift instructions. + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_CMP SIMD 16-bit Compare Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_DATA_PROCESS + * \brief SIMD 16-bit Compare Instructions + * \details + * there are 5 SIMD 16-bit Compare instructions. + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_CMP SIMD 8-bit Compare Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_DATA_PROCESS + * \brief SIMD 8-bit Compare Instructions + * \details + * there are 5 SIMD 8-bit Compare instructions. + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_MULTIPLY SIMD 16-bit Multiply Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_DATA_PROCESS + * \brief SIMD 16-bit Multiply Instructions + * \details + * there are 6 SIMD 16-bit Multiply instructions. + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_MULTIPLY SIMD 8-bit Multiply Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_DATA_PROCESS + * \brief SIMD 8-bit Multiply Instructions + * \details + * there are 6 SIMD 8-bit Multiply instructions. + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_MISC SIMD 16-bit Miscellaneous Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_DATA_PROCESS + * \brief SIMD 16-bit Miscellaneous Instructions + * \details + * there are 10 SIMD 16-bit Misc instructions. + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_MISC SIMD 8-bit Miscellaneous Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_DATA_PROCESS + * \brief SIMD 8-bit Miscellaneous Instructions + * \details + * there are 10 SIMD 8-bit Miscellaneous instructions. + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_UNPACK SIMD 8-bit Unpacking Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_DATA_PROCESS + * \brief SIMD 8-bit Unpacking Instructions + * \details + * there are 8 SIMD 8-bit Unpacking instructions. + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_NON_SIMD Non-SIMD Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic + * \brief Non-SIMD Instructions + * \details + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q15_SAT_ALU Non-SIMD Q15 saturation ALU Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD + * \brief Non-SIMD Q15 saturation ALU Instructions + * \details + * there are 7 Non-SIMD Q15 saturation ALU Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q31_SAT_ALU Non-SIMD Q31 saturation ALU Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD + * \brief Non-SIMD Q31 saturation ALU Instructions + * \details + * there are Non-SIMD Q31 saturation ALU Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_32B_COMPUTATION 32-bit Computation Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD + * \brief 32-bit Computation Instructions + * \details + * there are 8 32-bit Computation Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_OV_FLAG_SC OV (Overflow) flag Set/Clear Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD + * \brief OV (Overflow) flag Set/Clear Instructions + * \details + * The following table lists the user instructions related to Overflow (OV) flag manipulation. there are 2 OV (Overflow) flag Set/Clear Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_MISC Non-SIMD Miscellaneous Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD + * \brief Non-SIMD Miscellaneous Instructions + * \details + * There are 13 Miscellaneous Instructions here. + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_PART_SIMD_DATA_PROCESS Partial-SIMD Data Processing Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic + * \brief Partial-SIMD Data Processing Instructions + * \details + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_PACK SIMD 16-bit Packing Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_PART_SIMD_DATA_PROCESS + * \brief SIMD 16-bit Packing Instructions + * \details + * there are 4 SIMD16-bit Packing Instructions. + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X32_MAC Signed MSW 32x32 Multiply and Add Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_PART_SIMD_DATA_PROCESS + * \brief Signed MSW 32x32 Multiply and Add Instructions + * \details + * there are 8 Signed MSW 32x32 Multiply and Add Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC Signed MSW 32x16 Multiply and Add Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_PART_SIMD_DATA_PROCESS + * \brief Signed MSW 32x16 Multiply and Add Instructions + * \details + * there are 15 Signed MSW 32x16 Multiply and Add Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB Signed 16-bit Multiply 32-bit Add/Subtract Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_PART_SIMD_DATA_PROCESS + * \brief Signed 16-bit Multiply 32-bit Add/Subtract Instructions + * \details + * there are 18 Signed 16-bit Multiply 32-bit Add/Subtract Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_64B_ADDSUB Signed 16-bit Multiply 64-bit Add/Subtract Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_PART_SIMD_DATA_PROCESS + * \brief Signed 16-bit Multiply 64-bit Add/Subtract Instructions + * \details + * there is Signed 16-bit Multiply 64-bit Add/Subtract Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_PART_SIMD_MISC Partial-SIMD Miscellaneous Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_PART_SIMD_DATA_PROCESS + * \brief Partial-SIMD Miscellaneous Instructions + * \details + * there are 7 Partial-SIMD Miscellaneous Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_8B_MULT_32B_ADD 8-bit Multiply with 32-bit Add Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_PART_SIMD_DATA_PROCESS + * \brief 8-bit Multiply with 32-bit Add Instructions + * \details + * there are 3 8-bit Multiply with 32-bit Add Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_64B_PROFILE 64-bit Profile Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic + * \brief 64-bit Profile Instructions + * \details + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_64B_ADDSUB 64-bit Addition & Subtraction Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_64B_PROFILE + * \brief 64-bit Addition & Subtraction Instructions + * \details + * there are 10 64-bit Addition & Subtraction Instructions. + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_32B_MULT_64B_ADDSUB 32-bit Multiply with 64-bit Add/Subtract Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_64B_PROFILE + * \brief 32-bit Multiply with 64-bit Add/Subtract Instructions + * \details + * there are 32-bit Multiply 64-bit Add/Subtract Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_64B_ADDSUB Signed 16-bit Multiply with 64-bit Add/Subtract Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_64B_PROFILE + * \brief Signed 16-bit Multiply with 64-bit Add/Subtract Instructions + * \details + * there are 10 Signed 16-bit Multiply with 64-bit Add/Subtract Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_RV64_ONLY RV64 Only Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic + * \brief RV64 Only Instructions + * \details + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB (RV64 Only) SIMD 32-bit Add/Subtract Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_ONLY + * \brief (RV64 Only) SIMD 32-bit Add/Subtract Instructions + * \details + * The following tables list instructions that are only present in RV64. + * There are 30 SIMD 32-bit addition or subtraction instructions.there are 4 SIMD16-bit Packing Instructions. + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_SHIFT (RV64 Only) SIMD 32-bit Shift Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_ONLY + * \brief (RV64 Only) SIMD 32-bit Shift Instructions + * \details + * there are 14 (RV64 Only) SIMD 32-bit Shift Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_MISC (RV64 Only) SIMD 32-bit Miscellaneous Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_ONLY + * \brief (RV64 Only) SIMD 32-bit Miscellaneous Instructions + * \details + * there are 5 (RV64 Only) SIMD 32-bit Miscellaneous Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_Q15_SAT_MULT (RV64 Only) SIMD Q15 Saturating Multiply Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_ONLY + * \brief (RV64 Only) SIMD Q15 Saturating Multiply Instructions + * \details + * there are 9 (RV64 Only) SIMD Q15 saturating Multiply Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_RV64_32B_MULT (RV64 Only) 32-bit Multiply Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_ONLY + * \brief (RV64 Only) 32-bit Multiply Instructions + * \details + * there is 3 RV64 Only) 32-bit Multiply Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_RV64_32B_MULT_ADD (RV64 Only) 32-bit Multiply & Add Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_ONLY + * \brief (RV64 Only) 32-bit Multiply & Add Instructions + * \details + * there are 3 (RV64 Only) 32-bit Multiply & Add Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PARALLEL_MAC (RV64 Only) 32-bit Parallel Multiply & Add Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_ONLY + * \brief (RV64 Only) 32-bit Parallel Multiply & Add Instructions + * \details + * there are 12 (RV64 Only) 32-bit Parallel Multiply & Add Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_RV64_NON_SIMD_32B_SHIFT (RV64 Only) Non-SIMD 32-bit Shift Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_ONLY + * \brief (RV64 Only) Non-SIMD 32-bit Shift Instructions + * \details + * there are 1 (RV64 Only) Non-SIMD 32-bit Shift Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PACK 32-bit Packing Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_ONLY + * \brief 32-bit Packing Instructions + * \details + * There are four 32-bit packing instructions here + */ + +/* ===== Inline Function Start for 3.1. ADD8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_ADDSUB + * \brief ADD8 (SIMD 8-bit Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * ADD8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit integer element additions simultaneously. + * + * **Description**:\n + * This instruction adds the 8-bit integer elements in Rs1 with the 8-bit integer elements + * in Rs2, and then writes the 8-bit element results to Rd. + * + * **Note**:\n + * This instruction can be used for either signed or unsigned addition. + * + * **Operations**:\n + * ~~~ + * Rd.B[x] = Rs1.B[x] + Rs2.B[x]; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_ADD8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("add8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.1. ADD8 ===== */ + +/* ===== Inline Function Start for 3.2. ADD16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief ADD16 (SIMD 16-bit Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * ADD16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit integer element additions simultaneously. + * + * **Description**:\n + * This instruction adds the 16-bit integer elements in Rs1 with the 16-bit integer + * elements in Rs2, and then writes the 16-bit element results to Rd. + * + * **Note**:\n + * This instruction can be used for either signed or unsigned addition. + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = Rs1.H[x] + Rs2.H[x]; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_ADD16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("add16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.2. ADD16 ===== */ + +/* ===== Inline Function Start for 3.3. ADD64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_64B_ADDSUB + * \brief ADD64 (64-bit Addition) + * \details + * **Type**: 64-bit Profile + * + * **Syntax**:\n + * ~~~ + * ADD64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Add two 64-bit signed or unsigned integers. + * + * **RV32 Description**:\n + * This instruction adds the 64-bit integer of an even/odd pair of registers specified + * by Rs1(4,1) with the 64-bit integer of an even/odd pair of registers specified by Rs2(4,1), and then + * writes the 64-bit result to an even/odd pair of registers specified by Rd(4,1). + * Rx(4,1), i.e., value d, determines the even/odd pair group of two registers. Specifically, the register + * pair includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * + * **RV64 Description**:\n + * This instruction has the same behavior as the ADD instruction in RV64I. + * + * **Note**:\n + * This instruction can be used for either signed or unsigned addition. + * + * **Operations**:\n + * ~~~ + * RV32: + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * a_L = CONCAT(Rs1(4,1),1'b0); a_H = CONCAT(Rs1(4,1),1'b1); + * b_L = CONCAT(Rs2(4,1),1'b0); b_H = CONCAT(Rs2(4,1),1'b1); + * R[t_H].R[t_L] = R[a_H].R[a_L] + R[b_H].R[b_L]; + * RV64: + * Rd = Rs1 + Rs2; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_ADD64(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("add64 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.3. ADD64 ===== */ + +/* ===== Inline Function Start for 3.4. AVE ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_MISC + * \brief AVE (Average with Rounding) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * AVE Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Calculate the average of the contents of two general registers. + * + * **Description**:\n + * This instruction calculates the average value of two signed integers stored in Rs1 and + * Rs2, rounds up a half-integer result to the nearest integer, and writes the result to Rd. + * + * **Operations**:\n + * ~~~ + * Sum = CONCAT(Rs1[MSB],Rs1[MSB:0]) + CONCAT(Rs2[MSB],Rs2[MSB:0]) + 1; + * Rd = Sum[(MSB+1):1]; + * for RV32: MSB=31, + * for RV64: MSB=63 + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_AVE(long a, long b) +{ + long result; + __ASM volatile("ave %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.4. AVE ===== */ + +/* ===== Inline Function Start for 3.5. BITREV ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_MISC + * \brief BITREV (Bit Reverse) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * BITREV Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Reverse the bit positions of the source operand within a specified width starting from bit + * 0. The reversed width is a variable from a GPR. + * + * **Description**:\n + * This instruction reverses the bit positions of the content of Rs1. The reversed bit width + * is calculated as Rs2[4:0]+1 (RV32) or Rs2[5:0]+1 (RV64). The upper bits beyond the reversed width + * are filled with zeros. After the bit reverse operation, the result is written to Rd. + * + * **Operations**:\n + * ~~~ + * msb = Rs2[4:0]; (for RV32) + * msb = Rs2[5:0]; (for RV64) + * rev[0:msb] = Rs1[msb:0]; + * Rd = ZE(rev[msb:0]); + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_BITREV(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("bitrev %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.5. BITREV ===== */ + +/* ===== Inline Function Start for 3.6. BITREVI ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_MISC + * \brief BITREVI (Bit Reverse Immediate) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * (RV32) BITREVI Rd, Rs1, imm[4:0] + * (RV64) BITREVI Rd, Rs1, imm[5:0] + * ~~~ + * + * **Purpose**:\n + * Reverse the bit positions of the source operand within a specified width starting from bit + * 0. The reversed width is an immediate value. + * + * **Description**:\n + * This instruction reverses the bit positions of the content of Rs1. The reversed bit width + * is calculated as imm[4:0]+1 (RV32) or imm[5:0]+1 (RV64). The upper bits beyond the reversed width + * are filled with zeros. After the bit reverse operation, the result is written to Rd. + * + * **Operations**:\n + * ~~~ + * msb = imm[4:0]; (RV32) + * msb = imm[5:0]; (RV64) + * rev[0:msb] = Rs1[msb:0]; + * Rd = ZE(rev[msb:0]); + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_BITREVI(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("bitrevi %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.6. BITREVI ===== */ + +/* ===== Inline Function Start for 3.7. BPICK ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_MISC + * \brief BPICK (Bit-wise Pick) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * BPICK Rd, Rs1, Rs2, Rc + * ~~~ + * + * **Purpose**:\n + * Select from two source operands based on a bit mask in the third operand. + * + * **Description**:\n + * This instruction selects individual bits from Rs1 or Rs2, based on the bit mask value in + * Rc. If a bit in Rc is 1, the corresponding bit is from Rs1; otherwise, the corresponding bit is from Rs2. + * The selection results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd[x] = Rc[x]? Rs1[x] : Rs2[x]; + * for RV32, x=31...0 + * for RV64, x=63...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \param [in] c unsigned long type of value stored in c + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_BPICK(unsigned long a, unsigned long b, unsigned long c) +{ + unsigned long result; + __ASM volatile("bpick %0, %1, %2, %3" : "=r"(result) : "r"(a), "r"(b), "r"(c)); + return result; +} +/* ===== Inline Function End for 3.7. BPICK ===== */ + +/* ===== Inline Function Start for 3.8. CLROV ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_OV_FLAG_SC + * \brief CLROV (Clear OV flag) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * CLROV # pseudo mnemonic + * ~~~ + * + * **Purpose**:\n + * This pseudo instruction is an alias to `CSRRCI x0, ucode, 1` instruction. + * + * + */ +__STATIC_FORCEINLINE void __RV_CLROV(void) +{ + __ASM volatile("clrov "); +} +/* ===== Inline Function End for 3.8. CLROV ===== */ + +/* ===== Inline Function Start for 3.9. CLRS8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_MISC + * \brief CLRS8 (SIMD 8-bit Count Leading Redundant Sign) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * CLRS8 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Count the number of redundant sign bits of the 8-bit elements of a general register. + * + * **Description**:\n + * Starting from the bits next to the sign bits of the 8-bit elements of Rs1, this instruction + * counts the number of redundant sign bits and writes the result to the corresponding 8-bit elements + * of Rd. + * + * **Operations**:\n + * ~~~ + * snum[x] = Rs1.B[x]; + * cnt[x] = 0; + * for (i = 6 to 0) { + * if (snum[x](i) == snum[x](7)) { + * cnt[x] = cnt[x] + 1; + * } else { + * break; + * } + * } + * Rd.B[x] = cnt[x]; + * for RV32: x=3...0 + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_CLRS8(unsigned long a) +{ + unsigned long result; + __ASM volatile("clrs8 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.9. CLRS8 ===== */ + +/* ===== Inline Function Start for 3.10. CLRS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_MISC + * \brief CLRS16 (SIMD 16-bit Count Leading Redundant Sign) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * CLRS16 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Count the number of redundant sign bits of the 16-bit elements of a general register. + * + * **Description**:\n + * Starting from the bits next to the sign bits of the 16-bit elements of Rs1, this + * instruction counts the number of redundant sign bits and writes the result to the corresponding 16- + * bit elements of Rd. + * + * **Operations**:\n + * ~~~ + * snum[x] = Rs1.H[x]; + * cnt[x] = 0; + * for (i = 14 to 0) { + * if (snum[x](i) == snum[x](15)) { + * cnt[x] = cnt[x] + 1; + * } else { + * break; + * } + * } + * Rd.H[x] = cnt[x]; + * for RV32: x=1...0 + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_CLRS16(unsigned long a) +{ + unsigned long result; + __ASM volatile("clrs16 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.10. CLRS16 ===== */ + +/* ===== Inline Function Start for 3.11. CLRS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_PART_SIMD_MISC + * \brief CLRS32 (SIMD 32-bit Count Leading Redundant Sign) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * CLRS32 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Count the number of redundant sign bits of the 32-bit elements of a general register. + * + * **Description**:\n + * Starting from the bits next to the sign bits of the 32-bit elements of Rs1, this + * instruction counts the number of redundant sign bits and writes the result to the corresponding 32- + * bit elements of Rd. + * + * **Operations**:\n + * ~~~ + * snum[x] = Rs1.W[x]; + * cnt[x] = 0; + * for (i = 30 to 0) { + * if (snum[x](i) == snum[x](31)) { + * cnt[x] = cnt[x] + 1; + * } else { + * break; + * } + * } + * Rd.W[x] = cnt[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_CLRS32(unsigned long a) +{ + unsigned long result; + __ASM volatile("clrs32 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.11. CLRS32 ===== */ + +/* ===== Inline Function Start for 3.12. CLO8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_MISC + * \brief CLO8 (SIMD 8-bit Count Leading One) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * CLO8 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Count the number of leading one bits of the 8-bit elements of a general register. + * + * **Description**:\n + * Starting from the most significant bits of the 8-bit elements of Rs1, this instruction + * counts the number of leading one bits and writes the results to the corresponding 8-bit elements of + * Rd. + * + * **Operations**:\n + * ~~~ + * snum[x] = Rs1.B[x]; + * cnt[x] = 0; + * for (i = 7 to 0) { + * if (snum[x](i) == 1) { + * cnt[x] = cnt[x] + 1; + * } else { + * break; + * } + * } + * Rd.B[x] = cnt[x]; + * for RV32: x=3...0 + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_CLO8(unsigned long a) +{ + unsigned long result; + __ASM volatile("clo8 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.12. CLO8 ===== */ + +/* ===== Inline Function Start for 3.13. CLO16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_MISC + * \brief CLO16 (SIMD 16-bit Count Leading One) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * CLO16 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Count the number of leading one bits of the 16-bit elements of a general register. + * + * **Description**:\n + * Starting from the most significant bits of the 16-bit elements of Rs1, this instruction + * counts the number of leading one bits and writes the results to the corresponding 16-bit elements + * of Rd. + * + * **Operations**:\n + * ~~~ + * snum[x] = Rs1.H[x]; + * cnt[x] = 0; + * for (i = 15 to 0) { + * if (snum[x](i) == 1) { + * cnt[x] = cnt[x] + 1; + * } else { + * break; + * } + * } + * Rd.H[x] = cnt[x]; + * for RV32: x=1...0 + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_CLO16(unsigned long a) +{ + unsigned long result; + __ASM volatile("clo16 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.13. CLO16 ===== */ + +/* ===== Inline Function Start for 3.14. CLO32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_PART_SIMD_MISC + * \brief CLO32 (SIMD 32-bit Count Leading One) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * CLO32 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Count the number of leading one bits of the 32-bit elements of a general register. + * + * **Description**:\n + * Starting from the most significant bits of the 32-bit elements of Rs1, this instruction + * counts the number of leading one bits and writes the results to the corresponding 32-bit elements + * of Rd. + * + * **Operations**:\n + * ~~~ + * snum[x] = Rs1.W[x]; + * cnt[x] = 0; + * for (i = 31 to 0) { + * if (snum[x](i) == 1) { + * cnt[x] = cnt[x] + 1; + * } else { + * break; + * } + * } + * Rd.W[x] = cnt[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_CLO32(unsigned long a) +{ + unsigned long result; + __ASM volatile("clo32 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.14. CLO32 ===== */ + +/* ===== Inline Function Start for 3.15. CLZ8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_MISC + * \brief CLZ8 (SIMD 8-bit Count Leading Zero) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * CLZ8 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Count the number of leading zero bits of the 8-bit elements of a general register. + * + * **Description**:\n + * Starting from the most significant bits of the 8-bit elements of Rs1, this instruction + * counts the number of leading zero bits and writes the results to the corresponding 8-bit elements of + * Rd. + * + * **Operations**:\n + * ~~~ + * snum[x] = Rs1.B[x]; + * cnt[x] = 0; + * for (i = 7 to 0) { + * if (snum[x](i) == 0) { + * cnt[x] = cnt[x] + 1; + * } else { + * break; + * } + * } + * Rd.B[x] = cnt[x]; + * for RV32: x=3...0 + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_CLZ8(unsigned long a) +{ + unsigned long result; + __ASM volatile("clz8 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.15. CLZ8 ===== */ + +/* ===== Inline Function Start for 3.16. CLZ16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_MISC + * \brief CLZ16 (SIMD 16-bit Count Leading Zero) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * CLZ16 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Count the number of leading zero bits of the 16-bit elements of a general register. + * + * **Description**:\n + * Starting from the most significant bits of the 16-bit elements of Rs1, this instruction + * counts the number of leading zero bits and writes the results to the corresponding 16-bit elements + * of Rd. + * + * **Operations**:\n + * ~~~ + * snum[x] = Rs1.H[x]; + * cnt[x] = 0; + * for (i = 15 to 0) { + * if (snum[x](i) == 0) { + * cnt[x] = cnt[x] + 1; + * } else { + * break; + * } + * } + * Rd.H[x] = cnt[x]; + * for RV32: x=1...0 + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_CLZ16(unsigned long a) +{ + unsigned long result; + __ASM volatile("clz16 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.16. CLZ16 ===== */ + +/* ===== Inline Function Start for 3.17. CLZ32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_PART_SIMD_MISC + * \brief CLZ32 (SIMD 32-bit Count Leading Zero) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * CLZ32 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Count the number of leading zero bits of the 32-bit elements of a general register. + * + * **Description**:\n + * Starting from the most significant bits of the 32-bit elements of Rs1, this instruction + * counts the number of leading zero bits and writes the results to the corresponding 32-bit elements + * of Rd. + * + * **Operations**:\n + * ~~~ + * snum[x] = Rs1.W[x]; + * cnt[x] = 0; + * for (i = 31 to 0) { + * if (snum[x](i) == 0) { + * cnt[x] = cnt[x] + 1; + * } else { + * break; + * } + * } + * Rd.W[x] = cnt[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_CLZ32(unsigned long a) +{ + unsigned long result; + __ASM volatile("clz32 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.17. CLZ32 ===== */ + +/* ===== Inline Function Start for 3.18. CMPEQ8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_CMP + * \brief CMPEQ8 (SIMD 8-bit Integer Compare Equal) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * CMPEQ8 Rs, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit integer elements equal comparisons simultaneously. + * + * **Description**:\n + * This instruction compares the 8-bit integer elements in Rs1 with the 8-bit integer + * elements in Rs2 to see if they are equal. If they are equal, the result is 0xFF; otherwise, the result is + * 0x0. The 8-bit element comparison results are written to Rd. + * + * **Note**:\n + * This instruction can be used for either signed or unsigned numbers. + * + * **Operations**:\n + * ~~~ + * Rd.B[x] = (Rs1.B[x] == Rs2.B[x])? 0xff : 0x0; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_CMPEQ8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("cmpeq8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.18. CMPEQ8 ===== */ + +/* ===== Inline Function Start for 3.19. CMPEQ16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_CMP + * \brief CMPEQ16 (SIMD 16-bit Integer Compare Equal) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * CMPEQ16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit integer elements equal comparisons simultaneously. + * + * **Description**:\n + * This instruction compares the 16-bit integer elements in Rs1 with the 16-bit integer + * elements in Rs2 to see if they are equal. If they are equal, the result is 0xFFFF; otherwise, the result + * is 0x0. The 16-bit element comparison results are written to Rt. + * + * **Note**:\n + * This instruction can be used for either signed or unsigned numbers. + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = (Rs1.H[x] == Rs2.H[x])? 0xffff : 0x0; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_CMPEQ16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("cmpeq16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.19. CMPEQ16 ===== */ + +/* ===== Inline Function Start for 3.20. CRAS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief CRAS16 (SIMD 16-bit Cross Addition & Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * CRAS16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit integer element addition and 16-bit integer element subtraction in a 32-bit + * chunk simultaneously. Operands are from crossed positions in 32-bit chunks. + * + * **Description**:\n + * This instruction adds the 16-bit integer element in [31:16] of 32-bit chunks in Rs1 with + * the 16-bit integer element in [15:0] of 32-bit chunks in Rs2, and writes the result to [31:16] of 32-bit + * chunks in Rd; at the same time, it subtracts the 16-bit integer element in [31:16] of 32-bit chunks in + * Rs2 from the 16-bit integer element in [15:0] of 32-bit chunks, and writes the result to [15:0] of 32- + * bit chunks in Rd. + * + * **Note**:\n + * This instruction can be used for either signed or unsigned operations. + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:16] = Rs1.W[x][31:16] + Rs2.W[x][15:0]; + * Rd.W[x][15:0] = Rs1.W[x][15:0] - Rs2.W[x][31:16]; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_CRAS16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("cras16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.20. CRAS16 ===== */ + +/* ===== Inline Function Start for 3.21. CRSA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief CRSA16 (SIMD 16-bit Cross Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * CRSA16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit integer element subtraction and 16-bit integer element addition in a 32-bit + * chunk simultaneously. Operands are from crossed positions in 32-bit chunks. + * + * **Description**:\n + * This instruction subtracts the 16-bit integer element in [15:0] of 32-bit chunks in Rs2 + * from the 16-bit integer element in [31:16] of 32-bit chunks in Rs1, and writes the result to [31:16] of + * 32-bit chunks in Rd; at the same time, it adds the 16-bit integer element in [31:16] of 32-bit chunks + * in Rs2 with the 16-bit integer element in [15:0] of 32-bit chunks in Rs1, and writes the result to + * [15:0] of 32-bit chunks in Rd. + * + * **Note**:\n + * This instruction can be used for either signed or unsigned operations. + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:16] = Rs1.W[x][31:16] - Rs2.W[x][15:0]; + * Rd.W[x][15:0] = Rs1.W[x][15:0] + Rs2.W[x][31:16]; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_CRSA16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("crsa16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.21. CRSA16 ===== */ + +/* ===== Inline Function Start for 3.22. INSB ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_MISC + * \brief INSB (Insert Byte) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * (RV32) INSB Rd, Rs1, imm[1:0] + * (RV64) INSB Rd, Rs1, imm[2:0] + * ~~~ + * + * **Purpose**:\n + * Insert byte 0 of a 32-bit or 64-bit register into one of the byte elements of another register. + * + * **Description**:\n + * This instruction inserts byte 0 of Rs1 into byte `imm[1:0]` (RV32) or `imm[2:0]` (RV64) + * of Rd. + * + * **Operations**:\n + * ~~~ + * bpos = imm[1:0]; (RV32) + * bpos = imm[2:0]; (RV64) + * Rd.B[bpos] = Rs1.B[0] + * ~~~ + * + * \param [in] t unsigned long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_INSB(t, a, b) \ + ({ \ + unsigned long __t = (unsigned long)(t); \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("insb %0, %1, %2" : "+r"(__t) : "r"(__a), "K"(b)); \ + __t; \ + }) +/* ===== Inline Function End for 3.22. INSB ===== */ + +/* ===== Inline Function Start for 3.23. KABS8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_MISC + * \brief KABS8 (SIMD 8-bit Saturating Absolute) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KABS8 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Get the absolute value of 8-bit signed integer elements simultaneously. + * + * **Description**:\n + * This instruction calculates the absolute value of 8-bit signed integer elements stored + * in Rs1 and writes the element results to Rd. If the input number is 0x80, this instruction generates + * 0x7f as the output and sets the OV bit to 1. + * + * **Operations**:\n + * ~~~ + * src = Rs1.B[x]; + * if (src == 0x80) { + * src = 0x7f; + * OV = 1; + * } else if (src[7] == 1) + * src = -src; + * } + * Rd.B[x] = src; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KABS8(unsigned long a) +{ + unsigned long result; + __ASM volatile("kabs8 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.23. KABS8 ===== */ + +/* ===== Inline Function Start for 3.24. KABS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_MISC + * \brief KABS16 (SIMD 16-bit Saturating Absolute) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KABS16 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Get the absolute value of 16-bit signed integer elements simultaneously. + * + * **Description**:\n + * This instruction calculates the absolute value of 16-bit signed integer elements stored + * in Rs1 and writes the element results to Rd. If the input number is 0x8000, this instruction + * generates 0x7fff as the output and sets the OV bit to 1. + * + * **Operations**:\n + * ~~~ + * src = Rs1.H[x]; + * if (src == 0x8000) { + * src = 0x7fff; + * OV = 1; + * } else if (src[15] == 1) + * src = -src; + * } + * Rd.H[x] = src; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KABS16(unsigned long a) +{ + unsigned long result; + __ASM volatile("kabs16 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.24. KABS16 ===== */ + +/* ===== Inline Function Start for 3.25. KABSW ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q31_SAT_ALU + * \brief KABSW (Scalar 32-bit Absolute Value with Saturation) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KABSW Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Get the absolute value of a signed 32-bit integer in a general register. + * + * **Description**:\n + * This instruction calculates the absolute value of a signed 32-bit integer stored in Rs1. + * The result is sign-extended (for RV64) and written to Rd. This instruction with the minimum + * negative integer input of 0x80000000 will produce a saturated output of maximum positive integer + * of 0x7fffffff and the OV flag will be set to 1. + * + * **Operations**:\n + * ~~~ + * if (Rs1.W[0] >= 0) { + * res = Rs1.W[0]; + * } else { + * If (Rs1.W[0] == 0x80000000) { + * res = 0x7fffffff; + * OV = 1; + * } else { + * res = -Rs1.W[0]; + * } + * } + * Rd = SE32(res); + * ~~~ + * + * \param [in] a signed long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KABSW(signed long a) +{ + unsigned long result; + __ASM volatile("kabsw %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.25. KABSW ===== */ + +/* ===== Inline Function Start for 3.26. KADD8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_ADDSUB + * \brief KADD8 (SIMD 8-bit Signed Saturating Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KADD8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit signed integer element saturating additions simultaneously. + * + * **Description**:\n + * This instruction adds the 8-bit signed integer elements in Rs1 with the 8-bit signed + * integer elements in Rs2. If any of the results are beyond the Q7 number range (-2^7 <= Q7 <= 2^7-1), they + * are saturated to the range and the OV bit is set to 1. The saturated results are written to Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.B[x] + Rs2.B[x]; + * if (res[x] > 127) { + * res[x] = 127; + * OV = 1; + * } else if (res[x] < -128) { + * res[x] = -128; + * OV = 1; + * } + * Rd.B[x] = res[x]; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KADD8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("kadd8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.26. KADD8 ===== */ + +/* ===== Inline Function Start for 3.27. KADD16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief KADD16 (SIMD 16-bit Signed Saturating Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KADD16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element saturating additions simultaneously. + * + * **Description**:\n + * This instruction adds the 16-bit signed integer elements in Rs1 with the 16-bit signed + * integer elements in Rs2. If any of the results are beyond the Q15 number range (-2^15 <= Q15 <= 2^15-1), + * they are saturated to the range and the OV bit is set to 1. The saturated results are written to Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.H[x] + Rs2.H[x]; + * if (res[x] > 32767) { + * res[x] = 32767; + * OV = 1; + * } else if (res[x] < -32768) { + * res[x] = -32768; + * OV = 1; + * } + * Rd.H[x] = res[x]; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KADD16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("kadd16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.27. KADD16 ===== */ + +/* ===== Inline Function Start for 3.28. KADD64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_64B_ADDSUB + * \brief KADD64 (64-bit Signed Saturating Addition) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * KADD64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Add two 64-bit signed integers. The result is saturated to the Q63 range. + * + * **RV32 Description**:\n + * This instruction adds the 64-bit signed integer of an even/odd pair of registers + * specified by Rs1(4,1) with the 64-bit signed integer of an even/odd pair of registers specified by + * Rs2(4,1). If the 64-bit result is beyond the Q63 number range (-2^63 <= Q63 <= 2^63-1), it is saturated to the + * range and the OV bit is set to 1. The saturated result is written to an even/odd pair of registers + * specified by Rd(4,1). + * Rx(4,1), i.e., value d, determines the even/odd pair group of two registers. Specifically, the register + * pair includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * + * **RV64 Description**:\n + * This instruction adds the 64-bit signed integer in Rs1 with the 64-bit signed + * integer in Rs2. If the result is beyond the Q63 number range (-2^63 <= Q63 <= 2^63-1), it is saturated to the + * range and the OV bit is set to 1. The saturated result is written to Rd. + * + * **Operations**:\n + * ~~~ + * RV32: + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * a_L = CONCAT(Rs1(4,1),1'b0); a_H = CONCAT(Rs1(4,1),1'b1); + * b_L = CONCAT(Rs2(4,1),1'b0); b_H = CONCAT(Rs2(4,1),1'b1); + * result = R[a_H].R[a_L] + R[b_H].R[b_L]; + * if (result > (2^63)-1) { + * result = (2^63)-1; OV = 1; + * } else if (result < -2^63) { + * result = -2^63; OV = 1; + * } + * R[t_H].R[t_L] = result; + * RV64: + * result = Rs1 + Rs2; + * if (result > (2^63)-1) { + * result = (2^63)-1; OV = 1; + * } else if (result < -2^63) { + * result = -2^63; OV = 1; + * } + * Rd = result; + * ~~~ + * + * \param [in] a long long type of value stored in a + * \param [in] b long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_KADD64(long long a, long long b) +{ + long long result; + __ASM volatile("kadd64 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.28. KADD64 ===== */ + +/* ===== Inline Function Start for 3.29. KADDH ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q15_SAT_ALU + * \brief KADDH (Signed Addition with Q15 Saturation) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KADDH Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Add the signed lower 32-bit content of two registers with Q15 saturation. + * + * **Description**:\n + * The signed lower 32-bit content of Rs1 is added with the signed lower 32-bit content of + * Rs2. And the result is saturated to the 16-bit signed integer range of [-2^15, 2^15-1] and then sign- + * extended and written to Rd. If saturation happens, this instruction sets the OV flag. + * + * **Operations**:\n + * ~~~ + * tmp = Rs1.W[0] + Rs2.W[0]; + * if (tmp > 32767) { + * res = 32767; + * OV = 1; + * } else if (tmp < -32768) { + * res = -32768; + * OV = 1 + * } else { + * res = tmp; + * } + * Rd = SE(tmp[15:0]); + * ~~~ + * + * \param [in] a int type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KADDH(int a, int b) +{ + long result; + __ASM volatile("kaddh %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.29. KADDH ===== */ + +/* ===== Inline Function Start for 3.30. KADDW ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q31_SAT_ALU + * \brief KADDW (Signed Addition with Q31 Saturation) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KADDW Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Add the lower 32-bit signed content of two registers with Q31 saturation. + * + * **Description**:\n + * The lower 32-bit signed content of Rs1 is added with the lower 32-bit signed content of + * Rs2. And the result is saturated to the 32-bit signed integer range of [-2^31, 2^31-1] and then sign- + * extended and written to Rd. If saturation happens, this instruction sets the OV flag. + * + * **Operations**:\n + * ~~~ + * tmp = Rs1.W[0] + Rs2.W[0]; + * if (tmp > (2^31)-1) { + * res = (2^31)-1; + * OV = 1; + * } else if (tmp < -2^31) { + * res = -2^31; + * OV = 1 + * } else { + * res = tmp; + * } + * Rd = res[31:0]; // RV32 + * Rd = SE(res[31:0]) // RV64 + * ~~~ + * + * \param [in] a int type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KADDW(int a, int b) +{ + long result; + __ASM volatile("kaddw %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.30. KADDW ===== */ + +/* ===== Inline Function Start for 3.31. KCRAS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief KCRAS16 (SIMD 16-bit Signed Saturating Cross Addition & Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KCRAS16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element saturating addition and 16-bit signed integer element + * saturating subtraction in a 32-bit chunk simultaneously. Operands are from crossed positions in 32- + * bit chunks. + * + * **Description**:\n + * This instruction adds the 16-bit signed integer element in [31:16] of 32-bit chunks in + * Rs1 with the 16-bit signed integer element in [15:0] of 32-bit chunks in Rs2; at the same time, it + * subtracts the 16-bit signed integer element in [31:16] of 32-bit chunks in Rs2 from the 16-bit signed + * integer element in [15:0] of 32-bit chunks in Rs1. If any of the results are beyond the Q15 number + * range (-2^15 <= Q15 <= 2^15-1), they are saturated to the range and the OV bit is set to 1. The saturated + * results are written to [31:16] of 32-bit chunks in Rd for addition and [15:0] of 32-bit chunks in Rd for + * subtraction. + * + * **Operations**:\n + * ~~~ + * res1 = Rs1.W[x][31:16] + Rs2.W[x][15:0]; + * res2 = Rs1.W[x][15:0] - Rs2.W[x][31:16]; + * for (res in [res1, res2]) { + * if (res > (2^15)-1) { + * res = (2^15)-1; + * OV = 1; + * } else if (res < -2^15) { + * res = -2^15; + * OV = 1; + * } + * } + * Rd.W[x][31:16] = res1; + * Rd.W[x][15:0] = res2; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KCRAS16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("kcras16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.31. KCRAS16 ===== */ + +/* ===== Inline Function Start for 3.32. KCRSA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief KCRSA16 (SIMD 16-bit Signed Saturating Cross Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KCRSA16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element saturating subtraction and 16-bit signed integer element + * saturating addition in a 32-bit chunk simultaneously. Operands are from crossed positions in 32-bit + * chunks. + * + * **Description**:\n + * This instruction subtracts the 16-bit signed integer element in [15:0] of 32-bit chunks + * in Rs2 from the 16-bit signed integer element in [31:16] of 32-bit chunks in Rs1; at the same time, it + * adds the 16-bit signed integer element in [31:16] of 32-bit chunks in Rs2 with the 16-bit signed + * integer element in [15:0] of 32-bit chunks in Rs1. If any of the results are beyond the Q15 number + * range (-2^15 <= Q15 <= 2^15-1), they are saturated to the range and the OV bit is set to 1. The saturated + * results are written to [31:16] of 32-bit chunks in Rd for subtraction and [15:0] of 32-bit chunks in Rd + * for addition. + * + * **Operations**:\n + * ~~~ + * res1 = Rs1.W[x][31:16] - Rs2.W[x][15:0]; + * res2 = Rs1.W[x][15:0] + Rs2.W[x][31:16]; + * for (res in [res1, res2]) { + * if (res > (2^15)-1) { + * res = (2^15)-1; + * OV = 1; + * } else if (res < -2^15) { + * res = -2^15; + * OV = 1; + * } + * } + * Rd.W[x][31:16] = res1; + * Rd.W[x][15:0] = res2; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KCRSA16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("kcrsa16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.32. KCRSA16 ===== */ + +/* ===== Inline Function Start for 3.33.1. KDMBB ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q31_SAT_ALU + * \brief KDMBB (Signed Saturating Double Multiply B16 x B16) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KDMxy Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion + * of the lower 32-bit chunk in registers and then double and saturate the Q31 result. The result is + * written into the destination register for RV32 or sign-extended to 64-bits and written into the + * destination register for RV64. If saturation happens, an overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs1 with + * the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs2. The Q30 result is then + * doubled and saturated into a Q31 value. The Q31 value is then written into Rd (sign-extended in + * RV64). When both the two Q15 inputs are 0x8000, saturation will happen. The result will be + * saturated to 0x7FFFFFFF and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * aop = Rs1.H[0]; bop = Rs2.H[0]; // KDMBB + * aop = Rs1.H[0]; bop = Rs2.H[1]; // KDMBT + * aop = Rs1.H[1]; bop = Rs2.H[1]; // KDMTT + * If (0x8000 != aop | 0x8000 != bop) { + * Mresult = aop * bop; + * resQ31 = Mresult << 1; + * Rd = resQ31; // RV32 + * Rd = SE(resQ31); // RV64 + * } else { + * resQ31 = 0x7FFFFFFF; + * Rd = resQ31; // RV32 + * Rd = SE(resQ31); // RV64 + * OV = 1; + * } + * ~~~ + * + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KDMBB(unsigned int a, unsigned int b) +{ + long result; + __ASM volatile("kdmbb %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.33.1. KDMBB ===== */ + +/* ===== Inline Function Start for 3.33.2. KDMBT ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q31_SAT_ALU + * \brief KDMBT (Signed Saturating Double Multiply B16 x T16) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KDMxy Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion + * of the lower 32-bit chunk in registers and then double and saturate the Q31 result. The result is + * written into the destination register for RV32 or sign-extended to 64-bits and written into the + * destination register for RV64. If saturation happens, an overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs1 with + * the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs2. The Q30 result is then + * doubled and saturated into a Q31 value. The Q31 value is then written into Rd (sign-extended in + * RV64). When both the two Q15 inputs are 0x8000, saturation will happen. The result will be + * saturated to 0x7FFFFFFF and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * aop = Rs1.H[0]; bop = Rs2.H[0]; // KDMBB + * aop = Rs1.H[0]; bop = Rs2.H[1]; // KDMBT + * aop = Rs1.H[1]; bop = Rs2.H[1]; // KDMTT + * If (0x8000 != aop | 0x8000 != bop) { + * Mresult = aop * bop; + * resQ31 = Mresult << 1; + * Rd = resQ31; // RV32 + * Rd = SE(resQ31); // RV64 + * } else { + * resQ31 = 0x7FFFFFFF; + * Rd = resQ31; // RV32 + * Rd = SE(resQ31); // RV64 + * OV = 1; + * } + * ~~~ + * + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KDMBT(unsigned int a, unsigned int b) +{ + long result; + __ASM volatile("kdmbt %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.33.2. KDMBT ===== */ + +/* ===== Inline Function Start for 3.33.3. KDMTT ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q31_SAT_ALU + * \brief KDMTT (Signed Saturating Double Multiply T16 x T16) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KDMxy Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion + * of the lower 32-bit chunk in registers and then double and saturate the Q31 result. The result is + * written into the destination register for RV32 or sign-extended to 64-bits and written into the + * destination register for RV64. If saturation happens, an overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs1 with + * the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs2. The Q30 result is then + * doubled and saturated into a Q31 value. The Q31 value is then written into Rd (sign-extended in + * RV64). When both the two Q15 inputs are 0x8000, saturation will happen. The result will be + * saturated to 0x7FFFFFFF and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * aop = Rs1.H[0]; bop = Rs2.H[0]; // KDMBB + * aop = Rs1.H[0]; bop = Rs2.H[1]; // KDMBT + * aop = Rs1.H[1]; bop = Rs2.H[1]; // KDMTT + * If (0x8000 != aop | 0x8000 != bop) { + * Mresult = aop * bop; + * resQ31 = Mresult << 1; + * Rd = resQ31; // RV32 + * Rd = SE(resQ31); // RV64 + * } else { + * resQ31 = 0x7FFFFFFF; + * Rd = resQ31; // RV32 + * Rd = SE(resQ31); // RV64 + * OV = 1; + * } + * ~~~ + * + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KDMTT(unsigned int a, unsigned int b) +{ + long result; + __ASM volatile("kdmtt %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.33.3. KDMTT ===== */ + +/* ===== Inline Function Start for 3.34.1. KDMABB ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q31_SAT_ALU + * \brief KDMABB (Signed Saturating Double Multiply Addition B16 x B16) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KDMAxy Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion + * of the lower 32-bit chunk in registers and then double and saturate the Q31 result, add the result + * with the sign-extended lower 32-bit chunk destination register and write the saturated addition + * result into the destination register. If saturation happens, an overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs1 with + * the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs2. The Q30 result is then + * doubled and saturated into a Q31 value. The Q31 value is then added with the content of Rd. If the + * addition result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and + * the OV flag is set to 1. The result after saturation is written to Rd. + * When both the two Q15 inputs are 0x8000, saturation will happen and the overflow flag OV will be + * set. + * + * **Operations**:\n + * ~~~ + * aop = Rs1.H[0]; bop = Rs2.H[0]; // KDMABB + * aop = Rs1.H[0]; bop = Rs2.H[1]; // KDMABT + * aop = Rs1.H[1]; bop = Rs2.H[1]; // KDMATT + * If (0x8000 != aop | 0x8000 != bop) { + * Mresult = aop * bop; + * resQ31 = Mresult << 1; + * } else { + * resQ31 = 0x7FFFFFFF; + * OV = 1; + * } + * resadd = Rd + resQ31; // RV32 + * resadd = Rd.W[0] + resQ31; // RV64 + * if (resadd > (2^31)-1) { + * resadd = (2^31)-1; + * OV = 1; + * } else if (resadd < -2^31) { + * resadd = -2^31; + * OV = 1; + * } + * Rd = resadd; // RV32 + * Rd = SE(resadd); // RV64 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KDMABB(long t, unsigned int a, unsigned int b) +{ + __ASM volatile("kdmabb %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.34.1. KDMABB ===== */ + +/* ===== Inline Function Start for 3.34.2. KDMABT ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q31_SAT_ALU + * \brief KDMABT (Signed Saturating Double Multiply Addition B16 x T16) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KDMAxy Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion + * of the lower 32-bit chunk in registers and then double and saturate the Q31 result, add the result + * with the sign-extended lower 32-bit chunk destination register and write the saturated addition + * result into the destination register. If saturation happens, an overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs1 with + * the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs2. The Q30 result is then + * doubled and saturated into a Q31 value. The Q31 value is then added with the content of Rd. If the + * addition result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and + * the OV flag is set to 1. The result after saturation is written to Rd. + * When both the two Q15 inputs are 0x8000, saturation will happen and the overflow flag OV will be + * set. + * + * **Operations**:\n + * ~~~ + * aop = Rs1.H[0]; bop = Rs2.H[0]; // KDMABB + * aop = Rs1.H[0]; bop = Rs2.H[1]; // KDMABT + * aop = Rs1.H[1]; bop = Rs2.H[1]; // KDMATT + * If (0x8000 != aop | 0x8000 != bop) { + * Mresult = aop * bop; + * resQ31 = Mresult << 1; + * } else { + * resQ31 = 0x7FFFFFFF; + * OV = 1; + * } + * resadd = Rd + resQ31; // RV32 + * resadd = Rd.W[0] + resQ31; // RV64 + * if (resadd > (2^31)-1) { + * resadd = (2^31)-1; + * OV = 1; + * } else if (resadd < -2^31) { + * resadd = -2^31; + * OV = 1; + * } + * Rd = resadd; // RV32 + * Rd = SE(resadd); // RV64 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KDMABT(long t, unsigned int a, unsigned int b) +{ + __ASM volatile("kdmabt %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.34.2. KDMABT ===== */ + +/* ===== Inline Function Start for 3.34.3. KDMATT ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q31_SAT_ALU + * \brief KDMATT (Signed Saturating Double Multiply Addition T16 x T16) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KDMAxy Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion + * of the lower 32-bit chunk in registers and then double and saturate the Q31 result, add the result + * with the sign-extended lower 32-bit chunk destination register and write the saturated addition + * result into the destination register. If saturation happens, an overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs1 with + * the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs2. The Q30 result is then + * doubled and saturated into a Q31 value. The Q31 value is then added with the content of Rd. If the + * addition result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and + * the OV flag is set to 1. The result after saturation is written to Rd. + * When both the two Q15 inputs are 0x8000, saturation will happen and the overflow flag OV will be + * set. + * + * **Operations**:\n + * ~~~ + * aop = Rs1.H[0]; bop = Rs2.H[0]; // KDMABB + * aop = Rs1.H[0]; bop = Rs2.H[1]; // KDMABT + * aop = Rs1.H[1]; bop = Rs2.H[1]; // KDMATT + * If (0x8000 != aop | 0x8000 != bop) { + * Mresult = aop * bop; + * resQ31 = Mresult << 1; + * } else { + * resQ31 = 0x7FFFFFFF; + * OV = 1; + * } + * resadd = Rd + resQ31; // RV32 + * resadd = Rd.W[0] + resQ31; // RV64 + * if (resadd > (2^31)-1) { + * resadd = (2^31)-1; + * OV = 1; + * } else if (resadd < -2^31) { + * resadd = -2^31; + * OV = 1; + * } + * Rd = resadd; // RV32 + * Rd = SE(resadd); // RV64 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KDMATT(long t, unsigned int a, unsigned int b) +{ + __ASM volatile("kdmatt %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.34.3. KDMATT ===== */ + +/* ===== Inline Function Start for 3.35.1. KHM8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_MULTIPLY + * \brief KHM8 (SIMD Signed Saturating Q7 Multiply) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KHM8 Rd, Rs1, Rs2 + * KHMX8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do Q7xQ7 element multiplications simultaneously. The Q14 results are then reduced to Q7 + * numbers again. + * + * **Description**:\n + * For the `KHM8` instruction, multiply the top 8-bit Q7 content of 16-bit chunks in Rs1 + * with the top 8-bit Q7 content of 16-bit chunks in Rs2. At the same time, multiply the bottom 8-bit Q7 + * content of 16-bit chunks in Rs1 with the bottom 8-bit Q7 content of 16-bit chunks in Rs2. + * For the `KHMX16` instruction, multiply the top 8-bit Q7 content of 16-bit chunks in Rs1 with the + * bottom 8-bit Q7 content of 16-bit chunks in Rs2. At the same time, multiply the bottom 8-bit Q7 + * content of 16-bit chunks in Rs1 with the top 8-bit Q7 content of 16-bit chunks in Rs2. + * The Q14 results are then right-shifted 7-bits and saturated into Q7 values. The Q7 results are then + * written into Rd. When both the two Q7 inputs of a multiplication are 0x80, saturation will happen. + * The result will be saturated to 0x7F and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * if (is `KHM8`) { + * op1t = Rs1.B[x+1]; op2t = Rs2.B[x+1]; // top + * op1b = Rs1.B[x]; op2b = Rs2.B[x]; // bottom + * } else if (is `KHMX8`) { + * op1t = Rs1.H[x+1]; op2t = Rs2.H[x]; // Rs1 top + * op1b = Rs1.H[x]; op2b = Rs2.H[x+1]; // Rs1 bottom + * } + * for ((aop,bop,res) in [(op1t,op2t,rest), (op1b,op2b,resb)]) { + * if (0x80 != aop | 0x80 != bop) { + * res = (aop s* bop) >> 7; + * } else { + * res= 0x7F; + * OV = 1; + * } + * } + * Rd.H[x/2] = concat(rest, resb); + * for RV32, x=0,2 + * for RV64, x=0,2,4,6 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KHM8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("khm8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.35.1. KHM8 ===== */ + +/* ===== Inline Function Start for 3.35.2. KHMX8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_MULTIPLY + * \brief KHMX8 (SIMD Signed Saturating Crossed Q7 Multiply) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KHM8 Rd, Rs1, Rs2 + * KHMX8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do Q7xQ7 element multiplications simultaneously. The Q14 results are then reduced to Q7 + * numbers again. + * + * **Description**:\n + * For the `KHM8` instruction, multiply the top 8-bit Q7 content of 16-bit chunks in Rs1 + * with the top 8-bit Q7 content of 16-bit chunks in Rs2. At the same time, multiply the bottom 8-bit Q7 + * content of 16-bit chunks in Rs1 with the bottom 8-bit Q7 content of 16-bit chunks in Rs2. + * For the `KHMX16` instruction, multiply the top 8-bit Q7 content of 16-bit chunks in Rs1 with the + * bottom 8-bit Q7 content of 16-bit chunks in Rs2. At the same time, multiply the bottom 8-bit Q7 + * content of 16-bit chunks in Rs1 with the top 8-bit Q7 content of 16-bit chunks in Rs2. + * The Q14 results are then right-shifted 7-bits and saturated into Q7 values. The Q7 results are then + * written into Rd. When both the two Q7 inputs of a multiplication are 0x80, saturation will happen. + * The result will be saturated to 0x7F and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * if (is `KHM8`) { + * op1t = Rs1.B[x+1]; op2t = Rs2.B[x+1]; // top + * op1b = Rs1.B[x]; op2b = Rs2.B[x]; // bottom + * } else if (is `KHMX8`) { + * op1t = Rs1.H[x+1]; op2t = Rs2.H[x]; // Rs1 top + * op1b = Rs1.H[x]; op2b = Rs2.H[x+1]; // Rs1 bottom + * } + * for ((aop,bop,res) in [(op1t,op2t,rest), (op1b,op2b,resb)]) { + * if (0x80 != aop | 0x80 != bop) { + * res = (aop s* bop) >> 7; + * } else { + * res= 0x7F; + * OV = 1; + * } + * } + * Rd.H[x/2] = concat(rest, resb); + * for RV32, x=0,2 + * for RV64, x=0,2,4,6 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KHMX8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("khmx8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.35.2. KHMX8 ===== */ + +/* ===== Inline Function Start for 3.36.1. KHM16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_MULTIPLY + * \brief KHM16 (SIMD Signed Saturating Q15 Multiply) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KHM16 Rd, Rs1, Rs2 + * KHMX16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do Q15xQ15 element multiplications simultaneously. The Q30 results are then reduced to + * Q15 numbers again. + * + * **Description**:\n + * For the `KHM16` instruction, multiply the top 16-bit Q15 content of 32-bit chunks in + * Rs1 with the top 16-bit Q15 content of 32-bit chunks in Rs2. At the same time, multiply the bottom + * 16-bit Q15 content of 32-bit chunks in Rs1 with the bottom 16-bit Q15 content of 32-bit chunks in + * Rs2. + * For the `KHMX16` instruction, multiply the top 16-bit Q15 content of 32-bit chunks in Rs1 with the + * bottom 16-bit Q15 content of 32-bit chunks in Rs2. At the same time, multiply the bottom 16-bit Q15 + * content of 32-bit chunks in Rs1 with the top 16-bit Q15 content of 32-bit chunks in Rs2. + * The Q30 results are then right-shifted 15-bits and saturated into Q15 values. The Q15 results are + * then written into Rd. When both the two Q15 inputs of a multiplication are 0x8000, saturation will + * happen. The result will be saturated to 0x7FFF and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * if (is `KHM16`) { + * op1t = Rs1.H[x+1]; op2t = Rs2.H[x+1]; // top + * op1b = Rs1.H[x]; op2b = Rs2.H[x]; // bottom + * } else if (is `KHMX16`) { + * op1t = Rs1.H[x+1]; op2t = Rs2.H[x]; // Rs1 top + * op1b = Rs1.H[x]; op2b = Rs2.H[x+1]; // Rs1 bottom + * } + * for ((aop,bop,res) in [(op1t,op2t,rest), (op1b,op2b,resb)]) { + * if (0x8000 != aop | 0x8000 != bop) { + * res = (aop s* bop) >> 15; + * } else { + * res= 0x7FFF; + * OV = 1; + * } + * } + * Rd.W[x/2] = concat(rest, resb); + * for RV32: x=0 + * for RV64: x=0,2 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KHM16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("khm16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.36.1. KHM16 ===== */ + +/* ===== Inline Function Start for 3.36.2. KHMX16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_MULTIPLY + * \brief KHMX16 (SIMD Signed Saturating Crossed Q15 Multiply) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KHM16 Rd, Rs1, Rs2 + * KHMX16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do Q15xQ15 element multiplications simultaneously. The Q30 results are then reduced to + * Q15 numbers again. + * + * **Description**:\n + * For the `KHM16` instruction, multiply the top 16-bit Q15 content of 32-bit chunks in + * Rs1 with the top 16-bit Q15 content of 32-bit chunks in Rs2. At the same time, multiply the bottom + * 16-bit Q15 content of 32-bit chunks in Rs1 with the bottom 16-bit Q15 content of 32-bit chunks in + * Rs2. + * For the `KHMX16` instruction, multiply the top 16-bit Q15 content of 32-bit chunks in Rs1 with the + * bottom 16-bit Q15 content of 32-bit chunks in Rs2. At the same time, multiply the bottom 16-bit Q15 + * content of 32-bit chunks in Rs1 with the top 16-bit Q15 content of 32-bit chunks in Rs2. + * The Q30 results are then right-shifted 15-bits and saturated into Q15 values. The Q15 results are + * then written into Rd. When both the two Q15 inputs of a multiplication are 0x8000, saturation will + * happen. The result will be saturated to 0x7FFF and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * if (is `KHM16`) { + * op1t = Rs1.H[x+1]; op2t = Rs2.H[x+1]; // top + * op1b = Rs1.H[x]; op2b = Rs2.H[x]; // bottom + * } else if (is `KHMX16`) { + * op1t = Rs1.H[x+1]; op2t = Rs2.H[x]; // Rs1 top + * op1b = Rs1.H[x]; op2b = Rs2.H[x+1]; // Rs1 bottom + * } + * for ((aop,bop,res) in [(op1t,op2t,rest), (op1b,op2b,resb)]) { + * if (0x8000 != aop | 0x8000 != bop) { + * res = (aop s* bop) >> 15; + * } else { + * res= 0x7FFF; + * OV = 1; + * } + * } + * Rd.W[x/2] = concat(rest, resb); + * for RV32: x=0 + * for RV64: x=0,2 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KHMX16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("khmx16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.36.2. KHMX16 ===== */ + +/* ===== Inline Function Start for 3.37.1. KHMBB ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q15_SAT_ALU + * \brief KHMBB (Signed Saturating Half Multiply B16 x B16) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KHMxy Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 number contents of two 16-bit data in the corresponding portion + * of the lower 32-bit chunk in registers and then right-shift 15 bits to turn the Q30 result into a Q15 + * number again and saturate the Q15 result into the destination register. If saturation happens, an + * overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs1 with + * the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs2. The Q30 result is then right- + * shifted 15-bits and saturated into a Q15 value. The Q15 value is then sing-extended and written into + * Rd. When both the two Q15 inputs are 0x8000, saturation will happen. The result will be saturated + * to 0x7FFF and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * aop = Rs1.H[0]; bop = Rs2.H[0]; // KHMBB + * aop = Rs1.H[0]; bop = Rs2.H[1]; // KHMBT + * aop = Rs1.H[1]; bop = Rs2.H[1]; // KHMTT + * If (0x8000 != aop | 0x8000 != bop) { + * Mresult[31:0] = aop * bop; + * res[15:0] = Mresult[30:15]; + * } else { + * res[15:0] = 0x7FFF; + * OV = 1; + * } + * Rd = SE32(res[15:0]); // Rv32 + * Rd = SE64(res[15:0]); // RV64 + * ~~~ + * + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KHMBB(unsigned int a, unsigned int b) +{ + long result; + __ASM volatile("khmbb %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.37.1. KHMBB ===== */ + +/* ===== Inline Function Start for 3.37.2. KHMBT ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q15_SAT_ALU + * \brief KHMBT (Signed Saturating Half Multiply B16 x T16) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KHMxy Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 number contents of two 16-bit data in the corresponding portion + * of the lower 32-bit chunk in registers and then right-shift 15 bits to turn the Q30 result into a Q15 + * number again and saturate the Q15 result into the destination register. If saturation happens, an + * overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs1 with + * the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs2. The Q30 result is then right- + * shifted 15-bits and saturated into a Q15 value. The Q15 value is then sing-extended and written into + * Rd. When both the two Q15 inputs are 0x8000, saturation will happen. The result will be saturated + * to 0x7FFF and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * aop = Rs1.H[0]; bop = Rs2.H[0]; // KHMBB + * aop = Rs1.H[0]; bop = Rs2.H[1]; // KHMBT + * aop = Rs1.H[1]; bop = Rs2.H[1]; // KHMTT + * If (0x8000 != aop | 0x8000 != bop) { + * Mresult[31:0] = aop * bop; + * res[15:0] = Mresult[30:15]; + * } else { + * res[15:0] = 0x7FFF; + * OV = 1; + * } + * Rd = SE32(res[15:0]); // Rv32 + * Rd = SE64(res[15:0]); // RV64 + * ~~~ + * + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KHMBT(unsigned int a, unsigned int b) +{ + long result; + __ASM volatile("khmbt %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.37.2. KHMBT ===== */ + +/* ===== Inline Function Start for 3.37.3. KHMTT ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q15_SAT_ALU + * \brief KHMTT (Signed Saturating Half Multiply T16 x T16) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KHMxy Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 number contents of two 16-bit data in the corresponding portion + * of the lower 32-bit chunk in registers and then right-shift 15 bits to turn the Q30 result into a Q15 + * number again and saturate the Q15 result into the destination register. If saturation happens, an + * overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs1 with + * the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs2. The Q30 result is then right- + * shifted 15-bits and saturated into a Q15 value. The Q15 value is then sing-extended and written into + * Rd. When both the two Q15 inputs are 0x8000, saturation will happen. The result will be saturated + * to 0x7FFF and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * aop = Rs1.H[0]; bop = Rs2.H[0]; // KHMBB + * aop = Rs1.H[0]; bop = Rs2.H[1]; // KHMBT + * aop = Rs1.H[1]; bop = Rs2.H[1]; // KHMTT + * If (0x8000 != aop | 0x8000 != bop) { + * Mresult[31:0] = aop * bop; + * res[15:0] = Mresult[30:15]; + * } else { + * res[15:0] = 0x7FFF; + * OV = 1; + * } + * Rd = SE32(res[15:0]); // Rv32 + * Rd = SE64(res[15:0]); // RV64 + * ~~~ + * + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KHMTT(unsigned int a, unsigned int b) +{ + long result; + __ASM volatile("khmtt %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.37.3. KHMTT ===== */ + +/* ===== Inline Function Start for 3.38.1. KMABB ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief KMABB (SIMD Saturating Signed Multiply Bottom Halfs & Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMABB Rd, Rs1, Rs2 + * KMABT Rd, Rs1, Rs2 + * KMATT Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 16-bit content of 32-bit elements in a register with the 16-bit content + * of 32-bit elements in another register and add the result to the content of 32-bit elements in the + * third register. The addition result may be saturated and is written to the third register. + * * KMABB: rd.W[x] + bottom*bottom (per 32-bit element) + * * KMABT rd.W[x] + bottom*top (per 32-bit element) + * * KMATT rd.W[x] + top*top (per 32-bit element) + * + * **Description**:\n + * For the `KMABB` instruction, it multiplies the bottom 16-bit content of 32-bit elements in Rs1 with + * the bottom 16-bit content of 32-bit elements in Rs2. + * For the `KMABT` instruction, it multiplies the bottom 16-bit content of 32-bit elements in Rs1 with + * the top 16-bit content of 32-bit elements in Rs2. + * For the `KMATT` instruction, it multiplies the top 16-bit content of 32-bit elements in Rs1 with the + * top 16-bit content of 32-bit elements in Rs2. + * The multiplication result is added to the content of 32-bit elements in Rd. If the addition result is + * beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and the OV bit is set to + * 1. The results after saturation are written to Rd. The 16-bit contents of Rs1 and Rs2 are treated as + * signed integers. + * + * **Operations**:\n + * ~~~ + * res[x] = Rd.W[x] + (Rs1.W[x].H[0] * Rs2.W[x].H[0]); // KMABB + * res[x] = Rd.W[x] + (Rs1.W[x].H[0] * Rs2.W[x].H[1]); // KMABT + * res[x] = Rd.W[x] + (Rs1.W[x].H[1] * Rs2.W[x].H[1]); // KMATT + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMABB(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmabb %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.38.1. KMABB ===== */ + +/* ===== Inline Function Start for 3.38.2. KMABT ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief KMABT (SIMD Saturating Signed Multiply Bottom & Top Halfs & Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMABB Rd, Rs1, Rs2 + * KMABT Rd, Rs1, Rs2 + * KMATT Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 16-bit content of 32-bit elements in a register with the 16-bit content + * of 32-bit elements in another register and add the result to the content of 32-bit elements in the + * third register. The addition result may be saturated and is written to the third register. + * * KMABB: rd.W[x] + bottom*bottom (per 32-bit element) + * * KMABT rd.W[x] + bottom*top (per 32-bit element) + * * KMATT rd.W[x] + top*top (per 32-bit element) + * + * **Description**:\n + * For the `KMABB` instruction, it multiplies the bottom 16-bit content of 32-bit elements in Rs1 with + * the bottom 16-bit content of 32-bit elements in Rs2. + * For the `KMABT` instruction, it multiplies the bottom 16-bit content of 32-bit elements in Rs1 with + * the top 16-bit content of 32-bit elements in Rs2. + * For the `KMATT` instruction, it multiplies the top 16-bit content of 32-bit elements in Rs1 with the + * top 16-bit content of 32-bit elements in Rs2. + * The multiplication result is added to the content of 32-bit elements in Rd. If the addition result is + * beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and the OV bit is set to + * 1. The results after saturation are written to Rd. The 16-bit contents of Rs1 and Rs2 are treated as + * signed integers. + * + * **Operations**:\n + * ~~~ + * res[x] = Rd.W[x] + (Rs1.W[x].H[0] * Rs2.W[x].H[0]); // KMABB + * res[x] = Rd.W[x] + (Rs1.W[x].H[0] * Rs2.W[x].H[1]); // KMABT + * res[x] = Rd.W[x] + (Rs1.W[x].H[1] * Rs2.W[x].H[1]); // KMATT + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMABT(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmabt %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.38.2. KMABT ===== */ + +/* ===== Inline Function Start for 3.38.3. KMATT ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief KMATT (SIMD Saturating Signed Multiply Top Halfs & Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMABB Rd, Rs1, Rs2 + * KMABT Rd, Rs1, Rs2 + * KMATT Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 16-bit content of 32-bit elements in a register with the 16-bit content + * of 32-bit elements in another register and add the result to the content of 32-bit elements in the + * third register. The addition result may be saturated and is written to the third register. + * * KMABB: rd.W[x] + bottom*bottom (per 32-bit element) + * * KMABT rd.W[x] + bottom*top (per 32-bit element) + * * KMATT rd.W[x] + top*top (per 32-bit element) + * + * **Description**:\n + * For the `KMABB` instruction, it multiplies the bottom 16-bit content of 32-bit elements in Rs1 with + * the bottom 16-bit content of 32-bit elements in Rs2. + * For the `KMABT` instruction, it multiplies the bottom 16-bit content of 32-bit elements in Rs1 with + * the top 16-bit content of 32-bit elements in Rs2. + * For the `KMATT` instruction, it multiplies the top 16-bit content of 32-bit elements in Rs1 with the + * top 16-bit content of 32-bit elements in Rs2. + * The multiplication result is added to the content of 32-bit elements in Rd. If the addition result is + * beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and the OV bit is set to + * 1. The results after saturation are written to Rd. The 16-bit contents of Rs1 and Rs2 are treated as + * signed integers. + * + * **Operations**:\n + * ~~~ + * res[x] = Rd.W[x] + (Rs1.W[x].H[0] * Rs2.W[x].H[0]); // KMABB + * res[x] = Rd.W[x] + (Rs1.W[x].H[0] * Rs2.W[x].H[1]); // KMABT + * res[x] = Rd.W[x] + (Rs1.W[x].H[1] * Rs2.W[x].H[1]); // KMATT + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMATT(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmatt %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.38.3. KMATT ===== */ + +/* ===== Inline Function Start for 3.39.1. KMADA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief KMADA (SIMD Saturating Signed Multiply Two Halfs and Two Adds) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMADA Rd, Rs1, Rs2 + * KMAXDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from 32-bit elements in two registers; and then adds + * the two 32-bit results and 32-bit elements in a third register together. The addition result may be + * saturated. + * * KMADA: rd.W[x] + top*top + bottom*bottom (per 32-bit element) + * * KMAXDA: rd.W[x] + top*bottom + bottom*top (per 32-bit element) + * + * **Description**:\n + * For the `KMADA instruction, it multiplies the bottom 16-bit content of 32-bit elements in Rs1 with + * the bottom 16-bit content of 32-bit elements in Rs2 and then adds the result to the result of + * multiplying the top 16-bit content of 32-bit elements in Rs1 with the top 16-bit content of 32-bit + * elements in Rs2. + * For the `KMAXDA` instruction, it multiplies the top 16-bit content of 32-bit elements in Rs1 with the + * bottom 16-bit content of 32-bit elements in Rs2 and then adds the result to the result of multiplying + * the bottom 16-bit content of 32-bit elements in Rs1 with the top 16-bit content of 32-bit elements in + * Rs2. + * The result is added to the content of 32-bit elements in Rd. If the addition result is beyond the Q31 + * number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and the OV bit is set to 1. The 32-bit + * results after saturation are written to Rd. The 16-bit contents of Rs1 and Rs2 are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * // KMADA + * res[x] = Rd.W[x] + (Rs1.W[x].H[1] * Rs2.W[x].H[1]) + (Rs1.W[x].H[0] * Rs2.W[x].H[0]); + * // KMAXDA + * res[x] = Rd.W[x] + (Rs1.W[x].H[1] * Rs2.W[x].H[0]) + (Rs1.W[x].H[0] * Rs2.W[x].H[1]); + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMADA(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmada %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.39.1. KMADA ===== */ + +/* ===== Inline Function Start for 3.39.2. KMAXDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief KMAXDA (SIMD Saturating Signed Crossed Multiply Two Halfs and Two Adds) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMADA Rd, Rs1, Rs2 + * KMAXDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from 32-bit elements in two registers; and then adds + * the two 32-bit results and 32-bit elements in a third register together. The addition result may be + * saturated. + * * KMADA: rd.W[x] + top*top + bottom*bottom (per 32-bit element) + * * KMAXDA: rd.W[x] + top*bottom + bottom*top (per 32-bit element) + * + * **Description**:\n + * For the `KMADA instruction, it multiplies the bottom 16-bit content of 32-bit elements in Rs1 with + * the bottom 16-bit content of 32-bit elements in Rs2 and then adds the result to the result of + * multiplying the top 16-bit content of 32-bit elements in Rs1 with the top 16-bit content of 32-bit + * elements in Rs2. + * For the `KMAXDA` instruction, it multiplies the top 16-bit content of 32-bit elements in Rs1 with the + * bottom 16-bit content of 32-bit elements in Rs2 and then adds the result to the result of multiplying + * the bottom 16-bit content of 32-bit elements in Rs1 with the top 16-bit content of 32-bit elements in + * Rs2. + * The result is added to the content of 32-bit elements in Rd. If the addition result is beyond the Q31 + * number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and the OV bit is set to 1. The 32-bit + * results after saturation are written to Rd. The 16-bit contents of Rs1 and Rs2 are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * // KMADA + * res[x] = Rd.W[x] + (Rs1.W[x].H[1] * Rs2.W[x].H[1]) + (Rs1.W[x].H[0] * Rs2.W[x].H[0]); + * // KMAXDA + * res[x] = Rd.W[x] + (Rs1.W[x].H[1] * Rs2.W[x].H[0]) + (Rs1.W[x].H[0] * Rs2.W[x].H[1]); + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMAXDA(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmaxda %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.39.2. KMAXDA ===== */ + +/* ===== Inline Function Start for 3.40.1. KMADS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief KMADS (SIMD Saturating Signed Multiply Two Halfs & Subtract & Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMADS Rd, Rs1, Rs2 + * KMADRS Rd, Rs1, Rs2 + * KMAXDS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from 32-bit elements in two registers; and then + * perform a subtraction operation between the two 32-bit results. Then add the subtraction result to + * the corresponding 32-bit elements in a third register. The addition result may be saturated. + * * KMADS: rd.W[x] + (top*top - bottom*bottom) (per 32-bit element) + * * KMADRS: rd.W[x] + (bottom*bottom - top*top) (per 32-bit element) + * * KMAXDS: rd.W[x] + (top*bottom - bottom*top) (per 32-bit element) + * + * **Description**:\n + * For the `KMADS` instruction, it multiplies the bottom 16-bit content of 32-bit elements in Rs1 with + * the bottom 16-bit content of 32-bit elements in Rs2 and then subtracts the result from the result of + * multiplying the top 16-bit content of 32-bit elements in Rs1 with the top 16-bit content of 32-bit + * elements in Rs2. + * For the `KMADRS` instruction, it multiplies the top 16-bit content of 32-bit elements in Rs1 with the + * top 16-bit content of 32-bit elements in Rs2 and then subtracts the result from the result of + * multiplying the bottom 16-bit content of 32-bit elements in Rs1 with the bottom 16-bit content of 32- + * bit elements in Rs2. + * For the `KMAXDS` instruction, it multiplies the bottom 16-bit content of 32-bit elements in Rs1 with + * the top 16-bit content of 32-bit elements in Rs2 and then subtracts the result from the result of + * multiplying the top 16-bit content of 32-bit elements in Rs1 with the bottom 16-bit content of 32-bit + * elements in Rs2. + * The subtraction result is then added to the content of the corresponding 32-bit elements in Rd. If the + * addition result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and + * the OV bit is set to 1. The 32-bit results after saturation are written to Rd. The 16-bit contents of Rs1 + * and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * // KMADS + * res[x] = Rd.W[x] + (Rs1.W[x].H[1] * Rs2.W[x].H[1]) - (Rs1.W[x].H[0] * Rs2.W[x].H[0]); + * // KMADRS + * res[x] = Rd.W[x] + (Rs1.W[x].H[0] * Rs2.W[x].H[0]) - (Rs1.W[x].H[1] * Rs2.W[x].H[1]); + * // KMAXDS + * res[x] = Rd.W[x] + (Rs1.W[x].H[1] * Rs2.W[x].H[0]) - (Rs1.W[x].H[0] * Rs2.W[x].H[1]); + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMADS(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmads %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.40.1. KMADS ===== */ + +/* ===== Inline Function Start for 3.40.2. KMADRS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief KMADRS (SIMD Saturating Signed Multiply Two Halfs & Reverse Subtract & Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMADS Rd, Rs1, Rs2 + * KMADRS Rd, Rs1, Rs2 + * KMAXDS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from 32-bit elements in two registers; and then + * perform a subtraction operation between the two 32-bit results. Then add the subtraction result to + * the corresponding 32-bit elements in a third register. The addition result may be saturated. + * * KMADS: rd.W[x] + (top*top - bottom*bottom) (per 32-bit element) + * * KMADRS: rd.W[x] + (bottom*bottom - top*top) (per 32-bit element) + * * KMAXDS: rd.W[x] + (top*bottom - bottom*top) (per 32-bit element) + * + * **Description**:\n + * For the `KMADS` instruction, it multiplies the bottom 16-bit content of 32-bit elements in Rs1 with + * the bottom 16-bit content of 32-bit elements in Rs2 and then subtracts the result from the result of + * multiplying the top 16-bit content of 32-bit elements in Rs1 with the top 16-bit content of 32-bit + * elements in Rs2. + * For the `KMADRS` instruction, it multiplies the top 16-bit content of 32-bit elements in Rs1 with the + * top 16-bit content of 32-bit elements in Rs2 and then subtracts the result from the result of + * multiplying the bottom 16-bit content of 32-bit elements in Rs1 with the bottom 16-bit content of 32- + * bit elements in Rs2. + * For the `KMAXDS` instruction, it multiplies the bottom 16-bit content of 32-bit elements in Rs1 with + * the top 16-bit content of 32-bit elements in Rs2 and then subtracts the result from the result of + * multiplying the top 16-bit content of 32-bit elements in Rs1 with the bottom 16-bit content of 32-bit + * elements in Rs2. + * The subtraction result is then added to the content of the corresponding 32-bit elements in Rd. If the + * addition result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and + * the OV bit is set to 1. The 32-bit results after saturation are written to Rd. The 16-bit contents of Rs1 + * and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * // KMADS + * res[x] = Rd.W[x] + (Rs1.W[x].H[1] * Rs2.W[x].H[1]) - (Rs1.W[x].H[0] * Rs2.W[x].H[0]); + * // KMADRS + * res[x] = Rd.W[x] + (Rs1.W[x].H[0] * Rs2.W[x].H[0]) - (Rs1.W[x].H[1] * Rs2.W[x].H[1]); + * // KMAXDS + * res[x] = Rd.W[x] + (Rs1.W[x].H[1] * Rs2.W[x].H[0]) - (Rs1.W[x].H[0] * Rs2.W[x].H[1]); + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMADRS(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmadrs %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.40.2. KMADRS ===== */ + +/* ===== Inline Function Start for 3.40.3. KMAXDS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief KMAXDS (SIMD Saturating Signed Crossed Multiply Two Halfs & Subtract & Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMADS Rd, Rs1, Rs2 + * KMADRS Rd, Rs1, Rs2 + * KMAXDS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from 32-bit elements in two registers; and then + * perform a subtraction operation between the two 32-bit results. Then add the subtraction result to + * the corresponding 32-bit elements in a third register. The addition result may be saturated. + * * KMADS: rd.W[x] + (top*top - bottom*bottom) (per 32-bit element) + * * KMADRS: rd.W[x] + (bottom*bottom - top*top) (per 32-bit element) + * * KMAXDS: rd.W[x] + (top*bottom - bottom*top) (per 32-bit element) + * + * **Description**:\n + * For the `KMADS` instruction, it multiplies the bottom 16-bit content of 32-bit elements in Rs1 with + * the bottom 16-bit content of 32-bit elements in Rs2 and then subtracts the result from the result of + * multiplying the top 16-bit content of 32-bit elements in Rs1 with the top 16-bit content of 32-bit + * elements in Rs2. + * For the `KMADRS` instruction, it multiplies the top 16-bit content of 32-bit elements in Rs1 with the + * top 16-bit content of 32-bit elements in Rs2 and then subtracts the result from the result of + * multiplying the bottom 16-bit content of 32-bit elements in Rs1 with the bottom 16-bit content of 32- + * bit elements in Rs2. + * For the `KMAXDS` instruction, it multiplies the bottom 16-bit content of 32-bit elements in Rs1 with + * the top 16-bit content of 32-bit elements in Rs2 and then subtracts the result from the result of + * multiplying the top 16-bit content of 32-bit elements in Rs1 with the bottom 16-bit content of 32-bit + * elements in Rs2. + * The subtraction result is then added to the content of the corresponding 32-bit elements in Rd. If the + * addition result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and + * the OV bit is set to 1. The 32-bit results after saturation are written to Rd. The 16-bit contents of Rs1 + * and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * // KMADS + * res[x] = Rd.W[x] + (Rs1.W[x].H[1] * Rs2.W[x].H[1]) - (Rs1.W[x].H[0] * Rs2.W[x].H[0]); + * // KMADRS + * res[x] = Rd.W[x] + (Rs1.W[x].H[0] * Rs2.W[x].H[0]) - (Rs1.W[x].H[1] * Rs2.W[x].H[1]); + * // KMAXDS + * res[x] = Rd.W[x] + (Rs1.W[x].H[1] * Rs2.W[x].H[0]) - (Rs1.W[x].H[0] * Rs2.W[x].H[1]); + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMAXDS(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmaxds %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.40.3. KMAXDS ===== */ + +/* ===== Inline Function Start for 3.41. KMAR64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_32B_MULT_64B_ADDSUB + * \brief KMAR64 (Signed Multiply and Saturating Add to 64-Bit Data) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * KMAR64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the 32-bit signed elements in two registers and add the 64-bit multiplication + * results to the 64-bit signed data of a pair of registers (RV32) or a register (RV64). The result is + * saturated to the Q63 range and written back to the pair of registers (RV32) or the register (RV64). + * + * **RV32 Description**:\n + * This instruction multiplies the 32-bit signed data of Rs1 with that of Rs2. It adds + * the 64-bit multiplication result to the 64-bit signed data of an even/odd pair of registers specified by + * Rd(4,1) with unlimited precision. If the 64-bit addition result is beyond the Q63 number range (-2^63 <= + * Q63 <= 2^63-1), it is saturated to the range and the OV bit is set to 1. The saturated result is written back + * to the even/odd pair of registers specified by Rd(4,1). + * Rx(4,1), i.e., value d, determines the even/odd pair group of two registers. Specifically, the register + * pair includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * + * **RV64 Description**:\n + * This instruction multiplies the 32-bit signed elements of Rs1 with that of Rs2. It + * adds the 64-bit multiplication results to the 64-bit signed data of Rd with unlimited precision. If the + * 64-bit addition result is beyond the Q63 number range (-2^63 <= Q63 <= 2^63-1), it is saturated to the range + * and the OV bit is set to 1. The saturated result is written back to Rd. + * + * **Operations**:\n + * ~~~ + * RV32: + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * result = R[t_H].R[t_L] + (Rs1 * Rs2); + * if (result > (2^63)-1) { + * result = (2^63)-1; OV = 1; + * } else if (result < -2^63) { + * result = -2^63; OV = 1; + * } + * R[t_H].R[t_L] = result; + * RV64: + * // `result` has unlimited precision + * result = Rd + (Rs1.W[0] * Rs2.W[0]) + (Rs1.W[1] * Rs2.W[1]); + * if (result > (2^63)-1) { + * result = (2^63)-1; OV = 1; + * } else if (result < -2^63) { + * result = -2^63; OV = 1; + * } + * Rd = result; + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a long type of value stored in a + * \param [in] b long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_KMAR64(long long t, long a, long b) +{ + __ASM volatile("kmar64 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.41. KMAR64 ===== */ + +/* ===== Inline Function Start for 3.42.1. KMDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief KMDA (SIMD Signed Multiply Two Halfs and Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMDA Rd, Rs1, Rs2 + * KMXDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then + * adds the two 32-bit results together. The addition result may be saturated. + * * KMDA: top*top + bottom*bottom (per 32-bit element) + * * KMXDA: top*bottom + bottom*top (per 32-bit element) + * + * **Description**:\n + * For the `KMDA` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2 and then adds the result to the result of + * multiplying the top 16-bit content of the 32-bit elements of Rs1 with the top 16-bit content of the 32- + * bit elements of Rs2. + * For the `KMXDA` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2 and then adds the result to the result of + * multiplying the top 16-bit content of the 32-bit elements of Rs1 with the bottom 16-bit content of the + * 32-bit elements of Rs2. + * The addition result is checked for saturation. If saturation happens, the result is saturated to 2^31-1. + * The final results are written to Rd. The 16-bit contents are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * if Rs1.W[x] != 0x80008000) or (Rs2.W[x] != 0x80008000 { // KMDA Rd.W[x] = Rs1.W[x].H[1] * + * Rs2.W[x].H[1]) + (Rs1.W[x].H[0] * Rs2.W[x].H[0]; // KMXDA Rd.W[x] = Rs1.W[x].H[1] * Rs2.W[x].H[0]) + * + (Rs1.W[x].H[0] * Rs2.W[x].H[1]; } else { Rd.W[x] = 0x7fffffff; OV = 1; } for RV32: x=0 for RV64: + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMDA(unsigned long a, unsigned long b) +{ + long result; + __ASM volatile("kmda %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.42.1. KMDA ===== */ + +/* ===== Inline Function Start for 3.42.2. KMXDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief KMXDA (SIMD Signed Crossed Multiply Two Halfs and Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMDA Rd, Rs1, Rs2 + * KMXDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then + * adds the two 32-bit results together. The addition result may be saturated. + * * KMDA: top*top + bottom*bottom (per 32-bit element) + * * KMXDA: top*bottom + bottom*top (per 32-bit element) + * + * **Description**:\n + * For the `KMDA` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2 and then adds the result to the result of + * multiplying the top 16-bit content of the 32-bit elements of Rs1 with the top 16-bit content of the 32- + * bit elements of Rs2. + * For the `KMXDA` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2 and then adds the result to the result of + * multiplying the top 16-bit content of the 32-bit elements of Rs1 with the bottom 16-bit content of the + * 32-bit elements of Rs2. + * The addition result is checked for saturation. If saturation happens, the result is saturated to 2^31-1. + * The final results are written to Rd. The 16-bit contents are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * if Rs1.W[x] != 0x80008000) or (Rs2.W[x] != 0x80008000 { // KMDA Rd.W[x] = Rs1.W[x].H[1] * + * Rs2.W[x].H[1]) + (Rs1.W[x].H[0] * Rs2.W[x].H[0]; // KMXDA Rd.W[x] = Rs1.W[x].H[1] * Rs2.W[x].H[0]) + * + (Rs1.W[x].H[0] * Rs2.W[x].H[1]; } else { Rd.W[x] = 0x7fffffff; OV = 1; } for RV32: x=0 for RV64: + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMXDA(unsigned long a, unsigned long b) +{ + long result; + __ASM volatile("kmxda %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.42.2. KMXDA ===== */ + +/* ===== Inline Function Start for 3.43.1. KMMAC ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X32_MAC + * \brief KMMAC (SIMD Saturating MSW Signed Multiply Word and Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMMAC Rd, Rs1, Rs2 + * KMMAC.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of two registers and add the most significant + * 32-bit results with the signed 32-bit integer elements of a third register. The addition results are + * saturated first and then written back to the third register. The `.u` form performs an additional + * rounding up operation on the multiplication results before adding the most significant 32-bit part + * of the results. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit elements of Rs1 with the signed 32-bit elements of Rs2 + * and adds the most significant 32-bit multiplication results with the signed 32-bit elements of Rd. If + * the addition result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range + * and the OV bit is set to 1. The results after saturation are written to Rd. The `.u` form of the + * instruction additionally rounds up the most significant 32-bit of the 64-bit multiplication results by + * adding a 1 to bit 31 of the results. + * + * **Operations**:\n + * ~~~ + * Mres[x][63:0] = Rs1.W[x] * Rs2.W[x]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][63:31] + 1; + * res[x] = Rd.W[x] + Round[x][32:1]; + * } else { + * res[x] = Rd.W[x] + Mres[x][63:32]; + * } + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a long type of value stored in a + * \param [in] b long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMMAC(long t, long a, long b) +{ + __ASM volatile("kmmac %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.43.1. KMMAC ===== */ + +/* ===== Inline Function Start for 3.43.2. KMMAC.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X32_MAC + * \brief KMMAC.u (SIMD Saturating MSW Signed Multiply Word and Add with Rounding) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMMAC Rd, Rs1, Rs2 + * KMMAC.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of two registers and add the most significant + * 32-bit results with the signed 32-bit integer elements of a third register. The addition results are + * saturated first and then written back to the third register. The `.u` form performs an additional + * rounding up operation on the multiplication results before adding the most significant 32-bit part + * of the results. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit elements of Rs1 with the signed 32-bit elements of Rs2 + * and adds the most significant 32-bit multiplication results with the signed 32-bit elements of Rd. If + * the addition result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range + * and the OV bit is set to 1. The results after saturation are written to Rd. The `.u` form of the + * instruction additionally rounds up the most significant 32-bit of the 64-bit multiplication results by + * adding a 1 to bit 31 of the results. + * + * **Operations**:\n + * ~~~ + * Mres[x][63:0] = Rs1.W[x] * Rs2.W[x]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][63:31] + 1; + * res[x] = Rd.W[x] + Round[x][32:1]; + * } else { + * res[x] = Rd.W[x] + Mres[x][63:32]; + * } + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a long type of value stored in a + * \param [in] b long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMMAC_U(long t, long a, long b) +{ + __ASM volatile("kmmac.u %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.43.2. KMMAC.u ===== */ + +/* ===== Inline Function Start for 3.44.1. KMMAWB ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC + * \brief KMMAWB (SIMD Saturating MSW Signed Multiply Word and Bottom Half and Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMMAWB Rd, Rs1, Rs2 + * KMMAWB.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of one register and the bottom 16-bit of the + * corresponding 32-bit elements of another register and add the most significant 32-bit results with + * the corresponding signed 32-bit elements of a third register. The addition result is written to the + * corresponding 32-bit elements of the third register. The `.u` form rounds up the multiplication + * results from the most significant discarded bit before the addition operations. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit elements of Rs1 with the signed bottom 16-bit content + * of the corresponding 32-bit elements of Rs2 and adds the most significant 32-bit multiplication + * results with the corresponding signed 32-bit elements of Rd. If the addition result is beyond the Q31 + * number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and the OV bit is set to 1. The results + * after saturation are written to the corresponding 32-bit elements of Rd. The `.u` form of the + * instruction rounds up the most significant 32-bit of the 48-bit multiplication results by adding a 1 to + * bit 15 of the result before the addition operations. + * + * **Operations**:\n + * ~~~ + * Mres[x][47:0] = Rs1.W[x] * Rs2.W[x].H[0]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][47:15] + 1; + * res[x] = Rd.W[x] + Round[x][32:1]; + * } else { + * res[x] = Rd.W[x] + Mres[x][47:16]; + * } + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMMAWB(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmmawb %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.44.1. KMMAWB ===== */ + +/* ===== Inline Function Start for 3.44.2. KMMAWB.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC + * \brief KMMAWB.u (SIMD Saturating MSW Signed Multiply Word and Bottom Half and Add with Rounding) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMMAWB Rd, Rs1, Rs2 + * KMMAWB.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of one register and the bottom 16-bit of the + * corresponding 32-bit elements of another register and add the most significant 32-bit results with + * the corresponding signed 32-bit elements of a third register. The addition result is written to the + * corresponding 32-bit elements of the third register. The `.u` form rounds up the multiplication + * results from the most significant discarded bit before the addition operations. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit elements of Rs1 with the signed bottom 16-bit content + * of the corresponding 32-bit elements of Rs2 and adds the most significant 32-bit multiplication + * results with the corresponding signed 32-bit elements of Rd. If the addition result is beyond the Q31 + * number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and the OV bit is set to 1. The results + * after saturation are written to the corresponding 32-bit elements of Rd. The `.u` form of the + * instruction rounds up the most significant 32-bit of the 48-bit multiplication results by adding a 1 to + * bit 15 of the result before the addition operations. + * + * **Operations**:\n + * ~~~ + * Mres[x][47:0] = Rs1.W[x] * Rs2.W[x].H[0]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][47:15] + 1; + * res[x] = Rd.W[x] + Round[x][32:1]; + * } else { + * res[x] = Rd.W[x] + Mres[x][47:16]; + * } + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMMAWB_U(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmmawb.u %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.44.2. KMMAWB.u ===== */ + +/* ===== Inline Function Start for 3.45.1. KMMAWB2 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC + * \brief KMMAWB2 (SIMD Saturating MSW Signed Multiply Word and Bottom Half & 2 and Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMMAWB2 Rd, Rs1, Rs2 + * KMMAWB2.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit elements of one register and the bottom 16-bit of the + * corresponding 32-bit elements of another register, double the multiplication results and add the + * saturated most significant 32-bit results with the corresponding signed 32-bit elements of a third + * register. The saturated addition result is written to the corresponding 32-bit elements of the third + * register. The `.u` form rounds up the multiplication results from the most significant discarded bit + * before the addition operations. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit Q31 elements of Rs1 with the signed bottom 16-bit Q15 + * content of the corresponding 32-bit elements of Rs2, doubles the Q46 results to Q47 numbers and + * adds the saturated most significant 32-bit Q31 multiplication results with the corresponding signed + * 32-bit elements of Rd. If the addition result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is + * saturated to the range and the OV bit is set to 1. The results after saturation are written to the + * corresponding 32-bit elements of Rd. The `.u` form of the instruction rounds up the most significant + * 32-bit of the 48-bit Q47 multiplication results by adding a 1 to bit 15 (i.e., bit 14 before doubling) of + * the result before the addition operations. + * + * **Operations**:\n + * ~~~ + * if ((Rs1.W[x] == 0x80000000) & (Rs2.W[x].H[0] == 0x8000)) { + * addop.W[x] = 0x7fffffff; + * OV = 1; + * } else { + * Mres[x][47:0] = Rs1.W[x] s* Rs2.W[x].H[0]; + * if (`.u` form) { + * Mres[x][47:14] = Mres[x][47:14] + 1; + * } + * addop.W[x] = Mres[x][46:15]; // doubling + * } + * res[x] = Rd.W[x] + addop.W[x]; + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMMAWB2(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmmawb2 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.45.1. KMMAWB2 ===== */ + +/* ===== Inline Function Start for 3.45.2. KMMAWB2.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC + * \brief KMMAWB2.u (SIMD Saturating MSW Signed Multiply Word and Bottom Half & 2 and Add with Rounding) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMMAWB2 Rd, Rs1, Rs2 + * KMMAWB2.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit elements of one register and the bottom 16-bit of the + * corresponding 32-bit elements of another register, double the multiplication results and add the + * saturated most significant 32-bit results with the corresponding signed 32-bit elements of a third + * register. The saturated addition result is written to the corresponding 32-bit elements of the third + * register. The `.u` form rounds up the multiplication results from the most significant discarded bit + * before the addition operations. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit Q31 elements of Rs1 with the signed bottom 16-bit Q15 + * content of the corresponding 32-bit elements of Rs2, doubles the Q46 results to Q47 numbers and + * adds the saturated most significant 32-bit Q31 multiplication results with the corresponding signed + * 32-bit elements of Rd. If the addition result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is + * saturated to the range and the OV bit is set to 1. The results after saturation are written to the + * corresponding 32-bit elements of Rd. The `.u` form of the instruction rounds up the most significant + * 32-bit of the 48-bit Q47 multiplication results by adding a 1 to bit 15 (i.e., bit 14 before doubling) of + * the result before the addition operations. + * + * **Operations**:\n + * ~~~ + * if ((Rs1.W[x] == 0x80000000) & (Rs2.W[x].H[0] == 0x8000)) { + * addop.W[x] = 0x7fffffff; + * OV = 1; + * } else { + * Mres[x][47:0] = Rs1.W[x] s* Rs2.W[x].H[0]; + * if (`.u` form) { + * Mres[x][47:14] = Mres[x][47:14] + 1; + * } + * addop.W[x] = Mres[x][46:15]; // doubling + * } + * res[x] = Rd.W[x] + addop.W[x]; + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMMAWB2_U(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmmawb2.u %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.45.2. KMMAWB2.u ===== */ + +/* ===== Inline Function Start for 3.46.1. KMMAWT ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC + * \brief KMMAWT (SIMD Saturating MSW Signed Multiply Word and Top Half and Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMMAWT Rd, Rs1, Rs2 + * KMMAWT.u Rd Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of one register and the signed top 16-bit of the + * corresponding 32-bit elements of another register and add the most significant 32-bit results with + * the corresponding signed 32-bit elements of a third register. The addition results are written to the + * corresponding 32-bit elements of the third register. The `.u` form rounds up the multiplication + * results from the most significant discarded bit before the addition operations. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit elements of Rs1 with the signed top 16-bit of the + * corresponding 32-bit elements of Rs2 and adds the most significant 32-bit multiplication results + * with the corresponding signed 32-bit elements of Rd. If the addition result is beyond the Q31 + * number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and the OV bit is set to 1. The results + * after saturation are written to the corresponding 32-bit elements of Rd. The `.u` form of the + * instruction rounds up the most significant 32-bit of the 48-bit multiplication results by adding a 1 to + * bit 15 of the result before the addition operations. + * + * **Operations**:\n + * ~~~ + * Mres[x][47:0] = Rs1.W[x] * Rs2.W[x].H[1]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][47:15] + 1; + * res[x] = Rd.W[x] + Round[x][32:1]; + * } else { + * res[x] = Rd.W[x] + Mres[x][47:16]; + * } + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMMAWT(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmmawt %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.46.1. KMMAWT ===== */ + +/* ===== Inline Function Start for 3.46.2. KMMAWT.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC + * \brief KMMAWT.u (SIMD Saturating MSW Signed Multiply Word and Top Half and Add with Rounding) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMMAWT Rd, Rs1, Rs2 + * KMMAWT.u Rd Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of one register and the signed top 16-bit of the + * corresponding 32-bit elements of another register and add the most significant 32-bit results with + * the corresponding signed 32-bit elements of a third register. The addition results are written to the + * corresponding 32-bit elements of the third register. The `.u` form rounds up the multiplication + * results from the most significant discarded bit before the addition operations. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit elements of Rs1 with the signed top 16-bit of the + * corresponding 32-bit elements of Rs2 and adds the most significant 32-bit multiplication results + * with the corresponding signed 32-bit elements of Rd. If the addition result is beyond the Q31 + * number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and the OV bit is set to 1. The results + * after saturation are written to the corresponding 32-bit elements of Rd. The `.u` form of the + * instruction rounds up the most significant 32-bit of the 48-bit multiplication results by adding a 1 to + * bit 15 of the result before the addition operations. + * + * **Operations**:\n + * ~~~ + * Mres[x][47:0] = Rs1.W[x] * Rs2.W[x].H[1]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][47:15] + 1; + * res[x] = Rd.W[x] + Round[x][32:1]; + * } else { + * res[x] = Rd.W[x] + Mres[x][47:16]; + * } + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMMAWT_U(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmmawt.u %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.46.2. KMMAWT.u ===== */ + +/* ===== Inline Function Start for 3.47.1. KMMAWT2 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC + * \brief KMMAWT2 (SIMD Saturating MSW Signed Multiply Word and Top Half & 2 and Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMMAWT2 Rd, Rs1, Rs2 + * KMMAWT2.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit elements of one register and the top 16-bit of the + * corresponding 32-bit elements of another register, double the multiplication results and add the + * saturated most significant 32-bit results with the corresponding signed 32-bit elements of a third + * register. The saturated addition result is written to the corresponding 32-bit elements of the third + * register. The `.u` form rounds up the multiplication results from the most significant discarded bit + * before the addition operations. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit Q31 elements of Rs1 with the signed top 16-bit Q15 + * content of the corresponding 32-bit elements of Rs2, doubles the Q46 results to Q47 numbers and + * adds the saturated most significant 32-bit Q31 multiplication results with the corresponding signed + * 32-bit elements of Rd. If the addition result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is + * saturated to the range and the OV bit is set to 1. The results after saturation are written to the + * corresponding 32-bit elements of Rd. The `.u` form of the instruction rounds up the most significant + * 32-bit of the 48-bit Q47 multiplication results by adding a 1 to bit 15 (i.e., bit 14 before doubling) of + * the result before the addition operations. + * + * **Operations**:\n + * ~~~ + * if ((Rs1.W[x] == 0x80000000) & (Rs2.W[x].H[1] == 0x8000)) { + * addop.W[x] = 0x7fffffff; + * OV = 1; + * } else { + * Mres[x][47:0] = Rs1.W[x] s* Rs2.W[x].H[1]; + * if (`.u` form) { + * Mres[x][47:14] = Mres[x][47:14] + 1; + * } + * addop.W[x] = Mres[x][46:15]; // doubling + * } + * res[x] = Rd.W[x] + addop.W[x]; + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMMAWT2(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmmawt2 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.47.1. KMMAWT2 ===== */ + +/* ===== Inline Function Start for 3.47.2. KMMAWT2.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC + * \brief KMMAWT2.u (SIMD Saturating MSW Signed Multiply Word and Top Half & 2 and Add with Rounding) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMMAWT2 Rd, Rs1, Rs2 + * KMMAWT2.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit elements of one register and the top 16-bit of the + * corresponding 32-bit elements of another register, double the multiplication results and add the + * saturated most significant 32-bit results with the corresponding signed 32-bit elements of a third + * register. The saturated addition result is written to the corresponding 32-bit elements of the third + * register. The `.u` form rounds up the multiplication results from the most significant discarded bit + * before the addition operations. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit Q31 elements of Rs1 with the signed top 16-bit Q15 + * content of the corresponding 32-bit elements of Rs2, doubles the Q46 results to Q47 numbers and + * adds the saturated most significant 32-bit Q31 multiplication results with the corresponding signed + * 32-bit elements of Rd. If the addition result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is + * saturated to the range and the OV bit is set to 1. The results after saturation are written to the + * corresponding 32-bit elements of Rd. The `.u` form of the instruction rounds up the most significant + * 32-bit of the 48-bit Q47 multiplication results by adding a 1 to bit 15 (i.e., bit 14 before doubling) of + * the result before the addition operations. + * + * **Operations**:\n + * ~~~ + * if ((Rs1.W[x] == 0x80000000) & (Rs2.W[x].H[1] == 0x8000)) { + * addop.W[x] = 0x7fffffff; + * OV = 1; + * } else { + * Mres[x][47:0] = Rs1.W[x] s* Rs2.W[x].H[1]; + * if (`.u` form) { + * Mres[x][47:14] = Mres[x][47:14] + 1; + * } + * addop.W[x] = Mres[x][46:15]; // doubling + * } + * res[x] = Rd.W[x] + addop.W[x]; + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMMAWT2_U(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmmawt2.u %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.47.2. KMMAWT2.u ===== */ + +/* ===== Inline Function Start for 3.48.1. KMMSB ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X32_MAC + * \brief KMMSB (SIMD Saturating MSW Signed Multiply Word and Subtract) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMMSB Rd, Rs1, Rs2 + * KMMSB.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of two registers and subtract the most + * significant 32-bit results from the signed 32-bit elements of a third register. The subtraction results + * are written to the third register. The `.u` form performs an additional rounding up operation on + * the multiplication results before subtracting the most significant 32-bit part of the results. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit elements of Rs1 with the signed 32-bit elements of Rs2 + * and subtracts the most significant 32-bit multiplication results from the signed 32-bit elements of + * Rd. If the subtraction result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the + * range and the OV bit is set to 1. The results after saturation are written to Rd. The `.u` form of the + * instruction additionally rounds up the most significant 32-bit of the 64-bit multiplication results by + * adding a 1 to bit 31 of the results. + * + * **Operations**:\n + * ~~~ + * Mres[x][63:0] = Rs1.W[x] * Rs2.W[x]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][63:31] + 1; + * res[x] = Rd.W[x] - Round[x][32:1]; + * } else { + * res[x] = Rd.W[x] - Mres[x][63:32]; + * } + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a long type of value stored in a + * \param [in] b long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMMSB(long t, long a, long b) +{ + __ASM volatile("kmmsb %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.48.1. KMMSB ===== */ + +/* ===== Inline Function Start for 3.48.2. KMMSB.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X32_MAC + * \brief KMMSB.u (SIMD Saturating MSW Signed Multiply Word and Subtraction with Rounding) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMMSB Rd, Rs1, Rs2 + * KMMSB.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of two registers and subtract the most + * significant 32-bit results from the signed 32-bit elements of a third register. The subtraction results + * are written to the third register. The `.u` form performs an additional rounding up operation on + * the multiplication results before subtracting the most significant 32-bit part of the results. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit elements of Rs1 with the signed 32-bit elements of Rs2 + * and subtracts the most significant 32-bit multiplication results from the signed 32-bit elements of + * Rd. If the subtraction result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the + * range and the OV bit is set to 1. The results after saturation are written to Rd. The `.u` form of the + * instruction additionally rounds up the most significant 32-bit of the 64-bit multiplication results by + * adding a 1 to bit 31 of the results. + * + * **Operations**:\n + * ~~~ + * Mres[x][63:0] = Rs1.W[x] * Rs2.W[x]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][63:31] + 1; + * res[x] = Rd.W[x] - Round[x][32:1]; + * } else { + * res[x] = Rd.W[x] - Mres[x][63:32]; + * } + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a long type of value stored in a + * \param [in] b long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMMSB_U(long t, long a, long b) +{ + __ASM volatile("kmmsb.u %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.48.2. KMMSB.u ===== */ + +/* ===== Inline Function Start for 3.49.1. KMMWB2 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC + * \brief KMMWB2 (SIMD Saturating MSW Signed Multiply Word and Bottom Half & 2) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMMWB2 Rd, Rs1, Rs2 + * KMMWB2.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of one register and the bottom 16-bit of the + * corresponding 32-bit elements of another register, double the multiplication results and write the + * saturated most significant 32-bit results to the corresponding 32-bit elements of a register. The `.u` + * form rounds up the results from the most significant discarded bit. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit Q31 elements of Rs1 with the signed bottom 16-bit Q15 + * content of the corresponding 32-bit elements of Rs2, doubles the Q46 results to Q47 numbers and + * writes the saturated most significant 32-bit Q31 multiplication results to the corresponding 32-bit + * elements of Rd. The `.u` form of the instruction rounds up the most significant 32-bit of the 48-bit + * Q47 multiplication results by adding a 1 to bit 15 (i.e., bit 14 before doubling) of the results. + * + * **Operations**:\n + * ~~~ + * if ((Rs1.W[x] == 0x80000000) & (Rs2.W[x].H[0] == 0x8000)) { + * Rd.W[x] = 0x7fffffff; + * OV = 1; + * } else { + * Mres[x][47:0] = Rs1.W[x] s* Rs2.W[x].H[0]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][46:14] + 1; + * Rd.W[x] = Round[x][32:1]; + * } else { + * Rd.W[x] = Mres[x][46:15]; + * } + * } + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMMWB2(long a, unsigned long b) +{ + long result; + __ASM volatile("kmmwb2 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.49.1. KMMWB2 ===== */ + +/* ===== Inline Function Start for 3.49.2. KMMWB2.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC + * \brief KMMWB2.u (SIMD Saturating MSW Signed Multiply Word and Bottom Half & 2 with Rounding) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMMWB2 Rd, Rs1, Rs2 + * KMMWB2.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of one register and the bottom 16-bit of the + * corresponding 32-bit elements of another register, double the multiplication results and write the + * saturated most significant 32-bit results to the corresponding 32-bit elements of a register. The `.u` + * form rounds up the results from the most significant discarded bit. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit Q31 elements of Rs1 with the signed bottom 16-bit Q15 + * content of the corresponding 32-bit elements of Rs2, doubles the Q46 results to Q47 numbers and + * writes the saturated most significant 32-bit Q31 multiplication results to the corresponding 32-bit + * elements of Rd. The `.u` form of the instruction rounds up the most significant 32-bit of the 48-bit + * Q47 multiplication results by adding a 1 to bit 15 (i.e., bit 14 before doubling) of the results. + * + * **Operations**:\n + * ~~~ + * if ((Rs1.W[x] == 0x80000000) & (Rs2.W[x].H[0] == 0x8000)) { + * Rd.W[x] = 0x7fffffff; + * OV = 1; + * } else { + * Mres[x][47:0] = Rs1.W[x] s* Rs2.W[x].H[0]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][46:14] + 1; + * Rd.W[x] = Round[x][32:1]; + * } else { + * Rd.W[x] = Mres[x][46:15]; + * } + * } + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMMWB2_U(long a, unsigned long b) +{ + long result; + __ASM volatile("kmmwb2.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.49.2. KMMWB2.u ===== */ + +/* ===== Inline Function Start for 3.50.1. KMMWT2 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC + * \brief KMMWT2 (SIMD Saturating MSW Signed Multiply Word and Top Half & 2) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMMWT2 Rd, Rs1, Rs2 + * KMMWT2.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of one register and the top 16-bit of the + * corresponding 32-bit elements of another register, double the multiplication results and write the + * saturated most significant 32-bit results to the corresponding 32-bit elements of a register. The `.u` + * form rounds up the results from the most significant discarded bit. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit Q31 elements of Rs1 with the signed top 16-bit Q15 + * content of the corresponding 32-bit elements of Rs2, doubles the Q46 results to Q47 numbers and + * writes the saturated most significant 32-bit Q31 multiplication results to the corresponding 32-bit + * elements of Rd. The `.u` form of the instruction rounds up the most significant 32-bit of the 48-bit + * Q47 multiplication results by adding a 1 to bit 15 (i.e., bit 14 before doubling) of the results. + * + * **Operations**:\n + * ~~~ + * if ((Rs1.W[x] == 0x80000000) & (Rs2.W[x].H[1] == 0x8000)) { + * Rd.W[x] = 0x7fffffff; + * OV = 1; + * } else { + * Mres[x][47:0] = Rs1.W[x] s* Rs2.W[x].H[1]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][46:14] + 1; + * Rd.W[x] = Round[x][32:1]; + * } else { + * Rd.W[x] = Mres[x][46:15]; + * } + * } + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMMWT2(long a, unsigned long b) +{ + long result; + __ASM volatile("kmmwt2 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.50.1. KMMWT2 ===== */ + +/* ===== Inline Function Start for 3.50.2. KMMWT2.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC + * \brief KMMWT2.u (SIMD Saturating MSW Signed Multiply Word and Top Half & 2 with Rounding) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMMWT2 Rd, Rs1, Rs2 + * KMMWT2.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of one register and the top 16-bit of the + * corresponding 32-bit elements of another register, double the multiplication results and write the + * saturated most significant 32-bit results to the corresponding 32-bit elements of a register. The `.u` + * form rounds up the results from the most significant discarded bit. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit Q31 elements of Rs1 with the signed top 16-bit Q15 + * content of the corresponding 32-bit elements of Rs2, doubles the Q46 results to Q47 numbers and + * writes the saturated most significant 32-bit Q31 multiplication results to the corresponding 32-bit + * elements of Rd. The `.u` form of the instruction rounds up the most significant 32-bit of the 48-bit + * Q47 multiplication results by adding a 1 to bit 15 (i.e., bit 14 before doubling) of the results. + * + * **Operations**:\n + * ~~~ + * if ((Rs1.W[x] == 0x80000000) & (Rs2.W[x].H[1] == 0x8000)) { + * Rd.W[x] = 0x7fffffff; + * OV = 1; + * } else { + * Mres[x][47:0] = Rs1.W[x] s* Rs2.W[x].H[1]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][46:14] + 1; + * Rd.W[x] = Round[x][32:1]; + * } else { + * Rd.W[x] = Mres[x][46:15]; + * } + * } + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMMWT2_U(long a, unsigned long b) +{ + long result; + __ASM volatile("kmmwt2.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.50.2. KMMWT2.u ===== */ + +/* ===== Inline Function Start for 3.51.1. KMSDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief KMSDA (SIMD Saturating Signed Multiply Two Halfs & Add & Subtract) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMSDA Rd, Rs1, Rs2 + * KMSXDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then + * subtracts the two 32-bit results from the corresponding 32-bit elements of a third register. The + * subtraction result may be saturated. + * * KMSDA: rd.W[x] - top*top - bottom*bottom (per 32-bit element) + * * KMSXDA: rd.W[x] - top*bottom - bottom*top (per 32-bit element) + * + * **Description**:\n + * For the `KMSDA` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2 and multiplies the top 16-bit content of + * the 32-bit elements of Rs1 with the top 16-bit content of the 32-bit elements of Rs2. + * For the `KMSXDA` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2 and multiplies the top 16-bit content of the + * 32-bit elements of Rs1 with the bottom 16-bit content of the 32-bit elements of Rs2. + * The two 32-bit multiplication results are then subtracted from the content of the corresponding 32- + * bit elements of Rd. If the subtraction result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is + * saturated to the range and the OV bit is set to 1. The results after saturation are written to Rd. The + * 16-bit contents are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * // KMSDA + * res[x] = Rd.W[x] - (Rs1.W[x].H[1] * Rs2.W[x].H[1]) - (Rs1.W[x].H[0] * Rs2.W[x].H[0]); + * // KMSXDA + * res[x] = Rd.W[x] - (Rs1.W[x].H[1] * Rs2.W[x].H[0]) - (Rs1.W[x].H[0] * Rs2.W[x].H[1]); + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMSDA(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmsda %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.51.1. KMSDA ===== */ + +/* ===== Inline Function Start for 3.51.2. KMSXDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief KMSXDA (SIMD Saturating Signed Crossed Multiply Two Halfs & Add & Subtract) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMSDA Rd, Rs1, Rs2 + * KMSXDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then + * subtracts the two 32-bit results from the corresponding 32-bit elements of a third register. The + * subtraction result may be saturated. + * * KMSDA: rd.W[x] - top*top - bottom*bottom (per 32-bit element) + * * KMSXDA: rd.W[x] - top*bottom - bottom*top (per 32-bit element) + * + * **Description**:\n + * For the `KMSDA` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2 and multiplies the top 16-bit content of + * the 32-bit elements of Rs1 with the top 16-bit content of the 32-bit elements of Rs2. + * For the `KMSXDA` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2 and multiplies the top 16-bit content of the + * 32-bit elements of Rs1 with the bottom 16-bit content of the 32-bit elements of Rs2. + * The two 32-bit multiplication results are then subtracted from the content of the corresponding 32- + * bit elements of Rd. If the subtraction result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is + * saturated to the range and the OV bit is set to 1. The results after saturation are written to Rd. The + * 16-bit contents are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * // KMSDA + * res[x] = Rd.W[x] - (Rs1.W[x].H[1] * Rs2.W[x].H[1]) - (Rs1.W[x].H[0] * Rs2.W[x].H[0]); + * // KMSXDA + * res[x] = Rd.W[x] - (Rs1.W[x].H[1] * Rs2.W[x].H[0]) - (Rs1.W[x].H[0] * Rs2.W[x].H[1]); + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMSXDA(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmsxda %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.51.2. KMSXDA ===== */ + +/* ===== Inline Function Start for 3.52. KMSR64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_32B_MULT_64B_ADDSUB + * \brief KMSR64 (Signed Multiply and Saturating Subtract from 64-Bit Data) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * KMSR64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the 32-bit signed elements in two registers and subtract the 64-bit multiplication + * results from the 64-bit signed data of a pair of registers (RV32) or a register (RV64). The result is + * saturated to the Q63 range and written back to the pair of registers (RV32) or the register (RV64). + * + * **RV32 Description**:\n + * This instruction multiplies the 32-bit signed data of Rs1 with that of Rs2. It + * subtracts the 64-bit multiplication result from the 64-bit signed data of an even/odd pair of registers + * specified by Rd(4,1) with unlimited precision. If the 64-bit subtraction result is beyond the Q63 + * number range (-2^63 <= Q63 <= 2^63-1), it is saturated to the range and the OV bit is set to 1. The saturated + * result is written back to the even/odd pair of registers specified by Rd(4,1). + * Rx(4,1), i.e., d, determines the even/odd pair group of two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * + * **RV64 Description**:\n + * This instruction multiplies the 32-bit signed elements of Rs1 with that of Rs2. It + * subtracts the 64-bit multiplication results from the 64-bit signed data in Rd with unlimited + * precision. If the 64-bit subtraction result is beyond the Q63 number range (-2^63 <= Q63 <= 2^63-1), it is + * saturated to the range and the OV bit is set to 1. The saturated result is written back to Rd. + * + * **Operations**:\n + * ~~~ + * RV32: + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * result = R[t_H].R[t_L] - (Rs1 * Rs2); + * if (result > (2^63)-1) { + * result = (2^63)-1; OV = 1; + * } else if (result < -2^63) { + * result = -2^63; OV = 1; + * } + * R[t_H].R[t_L] = result; + * RV64: + * // `result` has unlimited precision + * result = Rd - (Rs1.W[0] * Rs2.W[0]) - (Rs1.W[1] * Rs2.W[1]); + * if (result > (2^63)-1) { + * result = (2^63)-1; OV = 1; + * } else if (result < -2^63) { + * result = -2^63; OV = 1; + * } + * Rd = result; + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a long type of value stored in a + * \param [in] b long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_KMSR64(long long t, long a, long b) +{ + __ASM volatile("kmsr64 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.52. KMSR64 ===== */ + +/* ===== Inline Function Start for 3.53. KSLLW ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q31_SAT_ALU + * \brief KSLLW (Saturating Shift Left Logical for Word) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KSLLW Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do logical left shift operation with saturation on a 32-bit word. The shift amount is a + * variable from a GPR. + * + * **Description**:\n + * The first word data in Rs1 is left-shifted logically. The shifted out bits are filled with + * zero and the shift amount is specified by the low-order 5-bits of the value in the Rs2 register. Any + * shifted value greater than 2^31-1 is saturated to 2^31-1. Any shifted value smaller than -2^31 is saturated + * to -2^31. And the saturated result is sign-extended and written to Rd. If any saturation is performed, + * set OV bit to 1. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[4:0]; + * res[(31+sa):0] = Rs1.W[0] << sa; + * if (res > (2^31)-1) { + * res = 0x7fffffff; OV = 1; + * } else if (res < -2^31) { + * res = 0x80000000; OV = 1; + * } + * Rd[31:0] = res[31:0]; // RV32 + * Rd[63:0] = SE(res[31:0]); // RV64 + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KSLLW(long a, unsigned int b) +{ + long result; + __ASM volatile("ksllw %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.53. KSLLW ===== */ + +/* ===== Inline Function Start for 3.54. KSLLIW ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q31_SAT_ALU + * \brief KSLLIW (Saturating Shift Left Logical Immediate for Word) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KSLLIW Rd, Rs1, imm5u + * ~~~ + * + * **Purpose**:\n + * Do logical left shift operation with saturation on a 32-bit word. The shift amount is an + * immediate value. + * + * **Description**:\n + * The first word data in Rs1 is left-shifted logically. The shifted out bits are filled with + * zero and the shift amount is specified by the imm5u constant. Any shifted value greater than 2^31-1 is + * saturated to 2^31-1. Any shifted value smaller than -2^31 is saturated to -2^31. And the saturated result is + * sign-extended and written to Rd. If any saturation is performed, set OV bit to 1. + * + * **Operations**:\n + * ~~~ + * sa = imm5u; + * res[(31+sa):0] = Rs1.W[0] << sa; + * if (res > (2^31)-1) { + * res = 0x7fffffff; OV = 1; + * } else if (res < -2^31) { + * res = 0x80000000; OV = 1; + * } + * Rd[31:0] = res[31:0]; // RV32 + * Rd[63:0] = SE(res[31:0]); // RV64 + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in long type + */ +#define __RV_KSLLIW(a, b) \ + ({ \ + long result; \ + long __a = (long)(a); \ + __ASM volatile("kslliw %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.54. KSLLIW ===== */ + +/* ===== Inline Function Start for 3.55. KSLL8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_SHIFT + * \brief KSLL8 (SIMD 8-bit Saturating Shift Left Logical) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KSLL8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit elements logical left shift operations with saturation simultaneously. The shift + * amount is a variable from a GPR. + * + * **Description**:\n + * The 8-bit data elements in Rs1 are left-shifted logically. The shifted out bits are filled + * with zero and the shift amount is specified by the low-order 3-bits of the value in the Rs2 register. + * Any shifted value greater than 2^7-1 is saturated to 2^7-1. Any shifted value smaller than -2^7 is + * saturated to -2^7. And the saturated results are written to Rd. If any saturation is performed, set OV + * bit to 1. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[2:0]; + * if (sa != 0) { + * res[(7+sa):0] = Rs1.B[x] << sa; + * if (res > (2^7)-1) { + * res = 0x7f; OV = 1; + * } else if (res < -2^7) { + * res = 0x80; OV = 1; + * } + * Rd.B[x] = res[7:0]; + * } else { + * Rd = Rs1; + * } + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KSLL8(unsigned long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("ksll8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.55. KSLL8 ===== */ + +/* ===== Inline Function Start for 3.56. KSLLI8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_SHIFT + * \brief KSLLI8 (SIMD 8-bit Saturating Shift Left Logical Immediate) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KSLLI8 Rd, Rs1, imm3u + * ~~~ + * + * **Purpose**:\n + * Do 8-bit elements logical left shift operations with saturation simultaneously. The shift + * amount is an immediate value. + * + * **Description**:\n + * The 8-bit data elements in Rs1 are left-shifted logically. The shifted out bits are filled + * with zero and the shift amount is specified by the imm3u constant. Any shifted value greater than + * 2^7-1 is saturated to 2^7-1. Any shifted value smaller than -2^7 is saturated to -2^7. And the saturated + * results are written to Rd. If any saturation is performed, set OV bit to 1. + * + * **Operations**:\n + * ~~~ + * sa = imm3u[2:0]; + * if (sa != 0) { + * res[(7+sa):0] = Rs1.B[x] << sa; + * if (res > (2^7)-1) { + * res = 0x7f; OV = 1; + * } else if (res < -2^7) { + * res = 0x80; OV = 1; + * } + * Rd.B[x] = res[7:0]; + * } else { + * Rd = Rs1; + * } + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_KSLLI8(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("kslli8 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.56. KSLLI8 ===== */ + +/* ===== Inline Function Start for 3.57. KSLL16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_SHIFT + * \brief KSLL16 (SIMD 16-bit Saturating Shift Left Logical) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KSLL16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit elements logical left shift operations with saturation simultaneously. The shift + * amount is a variable from a GPR. + * + * **Description**:\n + * The 16-bit data elements in Rs1 are left-shifted logically. The shifted out bits are filled + * with zero and the shift amount is specified by the low-order 4-bits of the value in the Rs2 register. + * Any shifted value greater than 2^15-1 is saturated to 2^15-1. Any shifted value smaller than -2^15 is + * saturated to -2^15. And the saturated results are written to Rd. If any saturation is performed, set OV + * bit to 1. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[3:0]; + * if (sa != 0) { + * res[(15+sa):0] = Rs1.H[x] << sa; + * if (res > (2^15)-1) { + * res = 0x7fff; OV = 1; + * } else if (res < -2^15) { + * res = 0x8000; OV = 1; + * } + * Rd.H[x] = res[15:0]; + * } else { + * Rd = Rs1; + * } + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KSLL16(unsigned long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("ksll16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.57. KSLL16 ===== */ + +/* ===== Inline Function Start for 3.58. KSLLI16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_SHIFT + * \brief KSLLI16 (SIMD 16-bit Saturating Shift Left Logical Immediate) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KSLLI16 Rd, Rs1, imm4u + * ~~~ + * + * **Purpose**:\n + * Do 16-bit elements logical left shift operations with saturation simultaneously. The shift + * amount is an immediate value. + * + * **Description**:\n + * The 16-bit data elements in Rs1 are left-shifted logically. The shifted out bits are filled + * with zero and the shift amount is specified by the imm4u constant. Any shifted value greater than + * 2^15-1 is saturated to 2^15-1. Any shifted value smaller than -2^15 is saturated to -2^15. And the saturated + * results are written to Rd. If any saturation is performed, set OV bit to 1. + * + * **Operations**:\n + * ~~~ + * sa = imm4u[3:0]; + * if (sa != 0) { + * res[(15+sa):0] = Rs1.H[x] << sa; + * if (res > (2^15)-1) { + * res = 0x7fff; OV = 1; + * } else if (res < -2^15) { + * res = 0x8000; OV = 1; + * } + * Rd.H[x] = res[15:0]; + * } else { + * Rd = Rs1; + * } + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_KSLLI16(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("kslli16 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.58. KSLLI16 ===== */ + +/* ===== Inline Function Start for 3.59.1. KSLRA8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_SHIFT + * \brief KSLRA8 (SIMD 8-bit Shift Left Logical with Saturation or Shift Right Arithmetic) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KSLRA8 Rd, Rs1, Rs2 + * KSLRA8.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit elements logical left (positive) or arithmetic right (negative) shift operation with + * Q7 saturation for the left shift. The `.u` form performs additional rounding up operations for the + * right shift. + * + * **Description**:\n + * The 8-bit data elements of Rs1 are left-shifted logically or right-shifted arithmetically + * based on the value of Rs2[3:0]. Rs2[3:0] is in the signed range of [-2^3, 2^3-1]. A positive Rs2[3:0] means + * logical left shift and a negative Rs2[3:0] means arithmetic right shift. The shift amount is the + * absolute value of Rs2[3:0]. However, the behavior of `Rs2[3:0]==-2^3 (0x8)` is defined to be + * equivalent to the behavior of `Rs2[3:0]==-(2^3-1) (0x9)`. + * The left-shifted results are saturated to the 8-bit signed integer range of [-2^7, 2^7-1]. For the `.u` form + * of the instruction, the right-shifted results are added a 1 to the most significant discarded bit + * position for rounding effect. After the shift, saturation, or rounding, the final results are written to + * Rd. If any saturation happens, this instruction sets the OV flag. The value of Rs2[31:4] will not affect + * this instruction. + * + * **Operations**:\n + * ~~~ + * if (Rs2[3:0] < 0) { + * sa = -Rs2[3:0]; + * sa = (sa == 8)? 7 : sa; + * if (`.u` form) { + * res[7:-1] = SE9(Rs1.B[x][7:sa-1]) + 1; + * Rd.B[x] = res[7:0]; + * } else { + * Rd.B[x] = SE8(Rs1.B[x][7:sa]); + * } + * } else { + * sa = Rs2[2:0]; + * res[(7+sa):0] = Rs1.B[x] <<(logic) sa; + * if (res > (2^7)-1) { + * res[7:0] = 0x7f; OV = 1; + * } else if (res < -2^7) { + * res[7:0] = 0x80; OV = 1; + * } + * Rd.B[x] = res[7:0]; + * } + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KSLRA8(unsigned long a, int b) +{ + unsigned long result; + __ASM volatile("kslra8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.59.1. KSLRA8 ===== */ + +/* ===== Inline Function Start for 3.59.2. KSLRA8.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_SHIFT + * \brief KSLRA8.u (SIMD 8-bit Shift Left Logical with Saturation or Rounding Shift Right Arithmetic) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KSLRA8 Rd, Rs1, Rs2 + * KSLRA8.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit elements logical left (positive) or arithmetic right (negative) shift operation with + * Q7 saturation for the left shift. The `.u` form performs additional rounding up operations for the + * right shift. + * + * **Description**:\n + * The 8-bit data elements of Rs1 are left-shifted logically or right-shifted arithmetically + * based on the value of Rs2[3:0]. Rs2[3:0] is in the signed range of [-2^3, 2^3-1]. A positive Rs2[3:0] means + * logical left shift and a negative Rs2[3:0] means arithmetic right shift. The shift amount is the + * absolute value of Rs2[3:0]. However, the behavior of `Rs2[3:0]==-2^3 (0x8)` is defined to be + * equivalent to the behavior of `Rs2[3:0]==-(2^3-1) (0x9)`. + * The left-shifted results are saturated to the 8-bit signed integer range of [-2^7, 2^7-1]. For the `.u` form + * of the instruction, the right-shifted results are added a 1 to the most significant discarded bit + * position for rounding effect. After the shift, saturation, or rounding, the final results are written to + * Rd. If any saturation happens, this instruction sets the OV flag. The value of Rs2[31:4] will not affect + * this instruction. + * + * **Operations**:\n + * ~~~ + * if (Rs2[3:0] < 0) { + * sa = -Rs2[3:0]; + * sa = (sa == 8)? 7 : sa; + * if (`.u` form) { + * res[7:-1] = SE9(Rs1.B[x][7:sa-1]) + 1; + * Rd.B[x] = res[7:0]; + * } else { + * Rd.B[x] = SE8(Rs1.B[x][7:sa]); + * } + * } else { + * sa = Rs2[2:0]; + * res[(7+sa):0] = Rs1.B[x] <<(logic) sa; + * if (res > (2^7)-1) { + * res[7:0] = 0x7f; OV = 1; + * } else if (res < -2^7) { + * res[7:0] = 0x80; OV = 1; + * } + * Rd.B[x] = res[7:0]; + * } + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KSLRA8_U(unsigned long a, int b) +{ + unsigned long result; + __ASM volatile("kslra8.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.59.2. KSLRA8.u ===== */ + +/* ===== Inline Function Start for 3.60.1. KSLRA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_SHIFT + * \brief KSLRA16 (SIMD 16-bit Shift Left Logical with Saturation or Shift Right Arithmetic) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KSLRA16 Rd, Rs1, Rs2 + * KSLRA16.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit elements logical left (positive) or arithmetic right (negative) shift operation with + * Q15 saturation for the left shift. The `.u` form performs additional rounding up operations for the + * right shift. + * + * **Description**:\n + * The 16-bit data elements of Rs1 are left-shifted logically or right-shifted arithmetically + * based on the value of Rs2[4:0]. Rs2[4:0] is in the signed range of [-2^4, 2^4-1]. A positive Rs2[4:0] means + * logical left shift and a negative Rs2[4:0] means arithmetic right shift. The shift amount is the + * absolute value of Rs2[4:0]. However, the behavior of `Rs2[4:0]==-2^4 (0x10)` is defined to be + * equivalent to the behavior of `Rs2[4:0]==-(2^4-1) (0x11)`. + * The left-shifted results are saturated to the 16-bit signed integer range of [-2^15, 2^15-1]. For the `.u` + * form of the instruction, the right-shifted results are added a 1 to the most significant discarded bit + * position for rounding effect. After the shift, saturation, or rounding, the final results are written to + * Rd. If any saturation happens, this instruction sets the OV flag. The value of Rs2[31:5] will not affect + * this instruction. + * + * **Operations**:\n + * ~~~ + * if (Rs2[4:0] < 0) { + * sa = -Rs2[4:0]; + * sa = (sa == 16)? 15 : sa; + * if (`.u` form) { + * res[15:-1] = SE17(Rs1.H[x][15:sa-1]) + 1; + * Rd.H[x] = res[15:0]; + * } else { + * Rd.H[x] = SE16(Rs1.H[x][15:sa]); + * } + * } else { + * sa = Rs2[3:0]; + * res[(15+sa):0] = Rs1.H[x] <<(logic) sa; + * if (res > (2^15)-1) { + * res[15:0] = 0x7fff; OV = 1; + * } else if (res < -2^15) { + * res[15:0] = 0x8000; OV = 1; + * } + * d.H[x] = res[15:0]; + * } + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KSLRA16(unsigned long a, int b) +{ + unsigned long result; + __ASM volatile("kslra16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.60.1. KSLRA16 ===== */ + +/* ===== Inline Function Start for 3.60.2. KSLRA16.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_SHIFT + * \brief KSLRA16.u (SIMD 16-bit Shift Left Logical with Saturation or Rounding Shift Right Arithmetic) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KSLRA16 Rd, Rs1, Rs2 + * KSLRA16.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit elements logical left (positive) or arithmetic right (negative) shift operation with + * Q15 saturation for the left shift. The `.u` form performs additional rounding up operations for the + * right shift. + * + * **Description**:\n + * The 16-bit data elements of Rs1 are left-shifted logically or right-shifted arithmetically + * based on the value of Rs2[4:0]. Rs2[4:0] is in the signed range of [-2^4, 2^4-1]. A positive Rs2[4:0] means + * logical left shift and a negative Rs2[4:0] means arithmetic right shift. The shift amount is the + * absolute value of Rs2[4:0]. However, the behavior of `Rs2[4:0]==-2^4 (0x10)` is defined to be + * equivalent to the behavior of `Rs2[4:0]==-(2^4-1) (0x11)`. + * The left-shifted results are saturated to the 16-bit signed integer range of [-2^15, 2^15-1]. For the `.u` + * form of the instruction, the right-shifted results are added a 1 to the most significant discarded bit + * position for rounding effect. After the shift, saturation, or rounding, the final results are written to + * Rd. If any saturation happens, this instruction sets the OV flag. The value of Rs2[31:5] will not affect + * this instruction. + * + * **Operations**:\n + * ~~~ + * if (Rs2[4:0] < 0) { + * sa = -Rs2[4:0]; + * sa = (sa == 16)? 15 : sa; + * if (`.u` form) { + * res[15:-1] = SE17(Rs1.H[x][15:sa-1]) + 1; + * Rd.H[x] = res[15:0]; + * } else { + * Rd.H[x] = SE16(Rs1.H[x][15:sa]); + * } + * } else { + * sa = Rs2[3:0]; + * res[(15+sa):0] = Rs1.H[x] <<(logic) sa; + * if (res > (2^15)-1) { + * res[15:0] = 0x7fff; OV = 1; + * } else if (res < -2^15) { + * res[15:0] = 0x8000; OV = 1; + * } + * d.H[x] = res[15:0]; + * } + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KSLRA16_U(unsigned long a, int b) +{ + unsigned long result; + __ASM volatile("kslra16.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.60.2. KSLRA16.u ===== */ + +/* ===== Inline Function Start for 3.61. KSLRAW ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q31_SAT_ALU + * \brief KSLRAW (Shift Left Logical with Q31 Saturation or Shift Right Arithmetic) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KSLRAW Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Perform a logical left (positive) or arithmetic right (negative) shift operation with Q31 + * saturation for the left shift on a 32-bit data. + * + * **Description**:\n + * The lower 32-bit content of Rs1 is left-shifted logically or right-shifted arithmetically + * based on the value of Rs2[5:0]. Rs2[5:0] is in the signed range of [-25, 25-1]. A positive Rs2[5:0] means + * logical left shift and a negative Rs2[5:0] means arithmetic right shift. The shift amount is the + * absolute value of Rs2[5:0] clamped to the actual shift range of [0, 31]. + * The left-shifted result is saturated to the 32-bit signed integer range of [-2^31, 2^31-1]. After the shift + * operation, the final result is bit-31 sign-extended and written to Rd. If any saturation happens, this + * instruction sets the OV flag. The value of Rs2[31:6] will not affected the operation of this instruction. + * + * **Operations**:\n + * ~~~ + * if (Rs2[5:0] < 0) { + * sa = -Rs2[5:0]; + * sa = (sa == 32)? 31 : sa; + * res[31:0] = Rs1.W[0] >>(arith) sa; + * } else { + * sa = Rs2[5:0]; + * tmp = Rs1.W[0] <<(logic) sa; + * if (tmp > (2^31)-1) { + * res[31:0] = (2^31)-1; + * OV = 1; + * } else if (tmp < -2^31) { + * res[31:0] = -2^31; + * OV = 1 + * } else { + * res[31:0] = tmp[31:0]; + * } + * } + * Rd = res[31:0]; // RV32 + * Rd = SE64(res[31:0]); // RV64 + * ~~~ + * + * \param [in] a int type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KSLRAW(int a, int b) +{ + long result; + __ASM volatile("kslraw %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.61. KSLRAW ===== */ + +/* ===== Inline Function Start for 3.62. KSLRAW.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q31_SAT_ALU + * \brief KSLRAW.u (Shift Left Logical with Q31 Saturation or Rounding Shift Right Arithmetic) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KSLRAW.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Perform a logical left (positive) or arithmetic right (negative) shift operation with Q31 + * saturation for the left shift and a rounding up operation for the right shift on a 32-bit data. + * + * **Description**:\n + * The lower 32-bit content of Rs1 is left-shifted logically or right-shifted arithmetically + * based on the value of Rs2[5:0]. Rs2[5:0] is in the signed range of [-25, 25-1]. A positive Rs2[5:0] means + * logical left shift and a negative Rs2[5:0] means arithmetic right shift. The shift amount is the + * absolute value of Rs2[5:0] clamped to the actual shift range of [0, 31]. + * The left-shifted result is saturated to the 32-bit signed integer range of [-2^31, 2^31-1]. The right-shifted + * result is added a 1 to the most significant discarded bit position for rounding effect. After the shift, + * saturation, or rounding, the final result is bit-31 sign-extended and written to Rd. If any saturation + * happens, this instruction sets the OV flag. The value of Rs2[31:6] will not affect the operation of this + * instruction. + * + * **Operations**:\n + * ~~~ + * if (Rs2[5:0] < 0) { + * sa = -Rs2[5:0]; + * sa = (sa == 32)? 31 : sa; + * res[31:-1] = SE33(Rs1[31:(sa-1)]) + 1; + * rst[31:0] = res[31:0]; + * } else { + * sa = Rs2[5:0]; + * tmp = Rs1.W[0] <<(logic) sa; + * if (tmp > (2^31)-1) { + * rst[31:0] = (2^31)-1; + * OV = 1; + * } else if (tmp < -2^31) { + * rst[31:0] = -2^31; + * OV = 1 + * } else { + * rst[31:0] = tmp[31:0]; + * } + * } + * Rd = rst[31:0]; // RV32 + * Rd = SE64(rst[31:0]); // RV64 + * ~~~ + * + * \param [in] a int type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KSLRAW_U(int a, int b) +{ + long result; + __ASM volatile("kslraw.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.62. KSLRAW.u ===== */ + +/* ===== Inline Function Start for 3.63. KSTAS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief KSTAS16 (SIMD 16-bit Signed Saturating Straight Addition & Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KSTAS16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element saturating addition and 16-bit signed integer element + * saturating subtraction in a 32-bit chunk simultaneously. Operands are from corresponding + * positions in 32-bit chunks. + * + * **Description**:\n + * This instruction adds the 16-bit signed integer element in [31:16] of 32-bit chunks in + * Rs1 with the 16-bit signed integer element in [31:16] of 32-bit chunks in Rs2; at the same time, it + * subtracts the 16-bit signed integer element in [15:0] of 32-bit chunks in Rs2 from the 16-bit signed + * integer element in [15:0] of 32-bit chunks in Rs1. If any of the results are beyond the Q15 number + * range (-2^15 <= Q15 <= 2^15-1), they are saturated to the range and the OV bit is set to 1. The saturated + * results are written to [31:16] of 32-bit chunks in Rd for addition and [15:0] of 32-bit chunks in Rd for + * subtraction. + * + * **Operations**:\n + * ~~~ + * res1 = Rs1.W[x][31:16] + Rs2.W[x][31:16]; + * res2 = Rs1.W[x][15:0] - Rs2.W[x][15:0]; + * for (res in [res1, res2]) { + * if (res > (2^15)-1) { + * res = (2^15)-1; + * OV = 1; + * } else if (res < -2^15) { + * res = -2^15; + * OV = 1; + * } + * } + * Rd.W[x][31:16] = res1; + * Rd.W[x][15:0] = res2; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KSTAS16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("kstas16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.63. KSTAS16 ===== */ + +/* ===== Inline Function Start for 3.64. KSTSA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief KSTSA16 (SIMD 16-bit Signed Saturating Straight Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KSTSA16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element saturating subtraction and 16-bit signed integer element + * saturating addition in a 32-bit chunk simultaneously. Operands are from corresponding positions in + * 32-bit chunks. + * + * **Description**:\n + * This instruction subtracts the 16-bit signed integer element in [31:16] of 32-bit chunks + * in Rs2 from the 16-bit signed integer element in [31:16] of 32-bit chunks in Rs1; at the same time, it + * adds the 16-bit signed integer element in [15:0] of 32-bit chunks in Rs2 with the 16-bit signed integer + * element in [15:0] of 32-bit chunks in Rs1. If any of the results are beyond the Q15 number range (-2^15 + * <= Q15 <= 2^15-1), they are saturated to the range and the OV bit is set to 1. The saturated results are + * written to [31:16] of 32-bit chunks in Rd for subtraction and [15:0] of 32-bit chunks in Rd for + * addition. + * + * **Operations**:\n + * ~~~ + * res1 = Rs1.W[x][31:16] - Rs2.W[x][31:16]; + * res2 = Rs1.W[x][15:0] + Rs2.W[x][15:0]; + * for (res in [res1, res2]) { + * if (res > (2^15)-1) { + * res = (2^15)-1; + * OV = 1; + * } else if (res < -2^15) { + * res = -2^15; + * OV = 1; + * } + * } + * Rd.W[x][31:16] = res1; + * Rd.W[x][15:0] = res2; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KSTSA16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("kstsa16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.64. KSTSA16 ===== */ + +/* ===== Inline Function Start for 3.65. KSUB8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_ADDSUB + * \brief KSUB8 (SIMD 8-bit Signed Saturating Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KSUB8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit signed elements saturating subtractions simultaneously. + * + * **Description**:\n + * This instruction subtracts the 8-bit signed integer elements in Rs2 from the 8-bit + * signed integer elements in Rs1. If any of the results are beyond the Q7 number range (-2^7 <= Q7 <= 27 + * -1), they are saturated to the range and the OV bit is set to 1. The saturated results are written to Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.B[x] - Rs2.B[x]; + * if (res[x] > (2^7)-1) { + * res[x] = (2^7)-1; + * OV = 1; + * } else if (res[x] < -2^7) { + * res[x] = -2^7; + * OV = 1; + * } + * Rd.B[x] = res[x]; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KSUB8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ksub8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.65. KSUB8 ===== */ + +/* ===== Inline Function Start for 3.66. KSUB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief KSUB16 (SIMD 16-bit Signed Saturating Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KSUB16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer elements saturating subtractions simultaneously. + * + * **Description**:\n + * This instruction subtracts the 16-bit signed integer elements in Rs2 from the 16-bit + * signed integer elements in Rs1. If any of the results are beyond the Q15 number range (-2^15 <= Q15 <= + * 2^15-1), they are saturated to the range and the OV bit is set to 1. The saturated results are written to + * Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.H[x] - Rs2.H[x]; + * if (res[x] > (2^15)-1) { + * res[x] = (2^15)-1; + * OV = 1; + * } else if (res[x] < -2^15) { + * res[x] = -2^15; + * OV = 1; + * } + * Rd.H[x] = res[x]; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KSUB16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ksub16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.66. KSUB16 ===== */ + +/* ===== Inline Function Start for 3.67. KSUB64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_64B_ADDSUB + * \brief KSUB64 (64-bit Signed Saturating Subtraction) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * KSUB64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Perform a 64-bit signed integer subtraction. The result is saturated to the Q63 range. + * + * **RV32 Description**:\n + * This instruction subtracts the 64-bit signed integer of an even/odd pair of + * registers specified by Rs2(4,1) from the 64-bit signed integer of an even/odd pair of registers + * specified by Rs1(4,1). If the 64-bit result is beyond the Q63 number range (-2^63 <= Q63 <= 2^63-1), it is + * saturated to the range and the OV bit is set to 1. The saturated result is then written to an even/odd + * pair of registers specified by Rd(4,1). + * Rx(4,1), i.e., d, determines the even/odd pair group of two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the operand and the even `2d` + * register of the pair contains the low 32-bit of the operand. + * + * **RV64 Description**:\n + * This instruction subtracts the 64-bit signed integer of Rs2 from the 64-bit signed + * integer of Rs1. If the 64-bit result is beyond the Q63 number range (-2^63 <= Q63 <= 2^63-1), it is saturated + * to the range and the OV bit is set to 1. The saturated result is then written to Rd. + * + * **Operations**:\n + * ~~~ + * RV32: + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * a_L = CONCAT(Rs1(4,1),1'b0); a_H = CONCAT(Rs1(4,1),1'b1); + * b_L = CONCAT(Rs2(4,1),1'b0); b_H = CONCAT(Rs2(4,1),1'b1); + * result = R[a_H].R[a_L] - R[b_H].R[b_L]; + * if (result > (2^63)-1) { + * result = (2^63)-1; OV = 1; + * } else if (result < -2^63) { + * result = -2^63; OV = 1; + * } + * R[t_H].R[t_L] = result; + * RV64: + * result = Rs1 - Rs2; + * if (result > (2^63)-1) { + * result = (2^63)-1; OV = 1; + * } else if (result < -2^63) { + * result = -2^63; OV = 1; + * } + * Rd = result; + * ~~~ + * + * \param [in] a long long type of value stored in a + * \param [in] b long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_KSUB64(long long a, long long b) +{ + long long result; + __ASM volatile("ksub64 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.67. KSUB64 ===== */ + +/* ===== Inline Function Start for 3.68. KSUBH ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q15_SAT_ALU + * \brief KSUBH (Signed Subtraction with Q15 Saturation) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KSUBH Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Subtract the signed lower 32-bit content of two registers with Q15 saturation. + * + * **Description**:\n + * The signed lower 32-bit content of Rs2 is subtracted from the signed lower 32-bit + * content of Rs1. And the result is saturated to the 16-bit signed integer range of [-2^15, 2^15-1] and then + * sign-extended and written to Rd. If saturation happens, this instruction sets the OV flag. + * + * **Operations**:\n + * ~~~ + * tmp = Rs1.W[0] - Rs2.W[0]; + * if (tmp > (2^15)-1) { + * res = (2^15)-1; + * OV = 1; + * } else if (tmp < -2^15) { + * res = -2^15; + * OV = 1 + * } else { + * res = tmp; + * } + * Rd = SE(res[15:0]); + * ~~~ + * + * \param [in] a int type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KSUBH(int a, int b) +{ + long result; + __ASM volatile("ksubh %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.68. KSUBH ===== */ + +/* ===== Inline Function Start for 3.69. KSUBW ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q31_SAT_ALU + * \brief KSUBW (Signed Subtraction with Q31 Saturation) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KSUBW Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Subtract the signed lower 32-bit content of two registers with Q31 saturation. + * + * **Description**:\n + * The signed lower 32-bit content of Rs2 is subtracted from the signed lower 32-bit + * content of Rs1. And the result is saturated to the 32-bit signed integer range of [-2^31, 2^31-1] and then + * sign-extened and written to Rd. If saturation happens, this instruction sets the OV flag. + * + * **Operations**:\n + * ~~~ + * tmp = Rs1.W[0] - Rs2.W[0]; + * if (tmp > (2^31)-1) { + * res = (2^31)-1; + * OV = 1; + * } else if (tmp < -2^31) { + * res = -2^31; + * OV = 1 + * } else { + * res = tmp; + * } + * Rd = res[31:0]; // RV32 + * Rd = SE(res[31:0]); // RV64 + * ~~~ + * + * \param [in] a int type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KSUBW(int a, int b) +{ + long result; + __ASM volatile("ksubw %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.69. KSUBW ===== */ + +/* ===== Inline Function Start for 3.70.1. KWMMUL ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X32_MAC + * \brief KWMMUL (SIMD Saturating MSW Signed Multiply Word & Double) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KWMMUL Rd, Rs1, Rs2 + * KWMMUL.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of two registers, shift the results left 1-bit, + * saturate, and write the most significant 32-bit results to a register. The `.u` form additionally + * rounds up the multiplication results from the most signification discarded bit. + * + * **Description**:\n + * This instruction multiplies the 32-bit elements of Rs1 with the 32-bit elements of Rs2. It then shifts + * the multiplication results one bit to the left and takes the most significant 32-bit results. If the + * shifted result is greater than 2^31-1, it is saturated to 2^31-1 and the OV flag is set to 1. The final element + * result is written to Rd. The 32-bit elements of Rs1 and Rs2 are treated as signed integers. The `.u` + * form of the instruction additionally rounds up the 64-bit multiplication results by adding a 1 to bit + * 30 before the shift and saturation operations. + * + * **Operations**:\n + * ~~~ + * if ((0x80000000 != Rs1.W[x]) | (0x80000000 != Rs2.W[x])) { + * Mres[x][63:0] = Rs1.W[x] * Rs2.W[x]; + * if (`.u` form) { + * Round[x][33:0] = Mres[x][63:30] + 1; + * Rd.W[x] = Round[x][32:1]; + * } else { + * Rd.W[x] = Mres[x][62:31]; + * } + * } else { + * Rd.W[x] = 0x7fffffff; + * OV = 1; + * } + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KWMMUL(long a, long b) +{ + long result; + __ASM volatile("kwmmul %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.70.1. KWMMUL ===== */ + +/* ===== Inline Function Start for 3.70.2. KWMMUL.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X32_MAC + * \brief KWMMUL.u (SIMD Saturating MSW Signed Multiply Word & Double with Rounding) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KWMMUL Rd, Rs1, Rs2 + * KWMMUL.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of two registers, shift the results left 1-bit, + * saturate, and write the most significant 32-bit results to a register. The `.u` form additionally + * rounds up the multiplication results from the most signification discarded bit. + * + * **Description**:\n + * This instruction multiplies the 32-bit elements of Rs1 with the 32-bit elements of Rs2. It then shifts + * the multiplication results one bit to the left and takes the most significant 32-bit results. If the + * shifted result is greater than 2^31-1, it is saturated to 2^31-1 and the OV flag is set to 1. The final element + * result is written to Rd. The 32-bit elements of Rs1 and Rs2 are treated as signed integers. The `.u` + * form of the instruction additionally rounds up the 64-bit multiplication results by adding a 1 to bit + * 30 before the shift and saturation operations. + * + * **Operations**:\n + * ~~~ + * if ((0x80000000 != Rs1.W[x]) | (0x80000000 != Rs2.W[x])) { + * Mres[x][63:0] = Rs1.W[x] * Rs2.W[x]; + * if (`.u` form) { + * Round[x][33:0] = Mres[x][63:30] + 1; + * Rd.W[x] = Round[x][32:1]; + * } else { + * Rd.W[x] = Mres[x][62:31]; + * } + * } else { + * Rd.W[x] = 0x7fffffff; + * OV = 1; + * } + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KWMMUL_U(long a, long b) +{ + long result; + __ASM volatile("kwmmul.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.70.2. KWMMUL.u ===== */ + +/* ===== Inline Function Start for 3.71. MADDR32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_MISC + * \brief MADDR32 (Multiply and Add to 32-Bit Word) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * MADDR32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the 32-bit contents of two registers and add the lower 32-bit multiplication result + * to the 32-bit content of a destination register. Write the final result back to the destination register. + * + * **Description**:\n + * This instruction multiplies the lower 32-bit content of Rs1 with that of Rs2. It adds the + * lower 32-bit multiplication result to the lower 32-bit content of Rd and writes the final result (RV32) + * or sign-extended result (RV64) back to Rd. The contents of Rs1 and Rs2 can be either signed or + * unsigned integers. + * + * **Operations**:\n + * ~~~ + * RV32: + * Mresult = Rs1 * Rs2; + * Rd = Rd + Mresult.W[0]; + * RV64: + * Mresult = Rs1.W[0] * Rs2.W[0]; + * tres[31:0] = Rd.W[0] + Mresult.W[0]; + * Rd = SE64(tres[31:0]); + * ~~~ + * + * \param [in] t unsigned long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_MADDR32(unsigned long t, unsigned long a, unsigned long b) +{ + __ASM volatile("maddr32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.71. MADDR32 ===== */ + +/* ===== Inline Function Start for 3.72. MAXW ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_32B_COMPUTATION + * \brief MAXW (32-bit Signed Word Maximum) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * MAXW Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Get the larger value from the 32-bit contents of two general registers. + * + * **Description**:\n + * This instruction compares two signed 32-bit integers stored in Rs1 and Rs2, picks the + * larger value as the result, and writes the result to Rd. + * + * **Operations**:\n + * ~~~ + * if (Rs1.W[0] >= Rs2.W[0]) { + * Rd = SE(Rs1.W[0]); + * } else { + * Rd = SE(Rs2.W[0]); + * } + * ~~~ + * + * \param [in] a int type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_MAXW(int a, int b) +{ + long result; + __ASM volatile("maxw %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.72. MAXW ===== */ + +/* ===== Inline Function Start for 3.73. MINW ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_32B_COMPUTATION + * \brief MINW (32-bit Signed Word Minimum) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * MINW Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Get the smaller value from the 32-bit contents of two general registers. + * + * **Description**:\n + * This instruction compares two signed 32-bit integers stored in Rs1 and Rs2, picks the + * smaller value as the result, and writes the result to Rd. + * + * **Operations**:\n + * ~~~ + * if (Rs1.W[0] >= Rs2.W[0]) { Rd = SE(Rs2.W[0]); } else { Rd = SE(Rs1.W[0]); } + * ~~~ + * + * \param [in] a int type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_MINW(int a, int b) +{ + long result; + __ASM volatile("minw %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.73. MINW ===== */ + +/* ===== Inline Function Start for 3.74. MSUBR32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_MISC + * \brief MSUBR32 (Multiply and Subtract from 32-Bit Word) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * MSUBR32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the 32-bit contents of two registers and subtract the lower 32-bit multiplication + * result from the 32-bit content of a destination register. Write the final result back to the destination + * register. + * + * **Description**:\n + * This instruction multiplies the lower 32-bit content of Rs1 with that of Rs2, subtracts + * the lower 32-bit multiplication result from the lower 32-bit content of Rd, then writes the final + * result (RV32) or sign-extended result (RV64) back to Rd. The contents of Rs1 and Rs2 can be either + * signed or unsigned integers. + * + * **Operations**:\n + * ~~~ + * RV32: + * Mresult = Rs1 * Rs2; + * Rd = Rd - Mresult.W[0]; + * RV64: + * Mresult = Rs1.W[0] * Rs2.W[0]; + * tres[31:0] = Rd.W[0] - Mresult.W[0]; + * Rd = SE64(tres[31:0]); + * ~~~ + * + * \param [in] t unsigned long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_MSUBR32(unsigned long t, unsigned long a, unsigned long b) +{ + __ASM volatile("msubr32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.74. MSUBR32 ===== */ + +/* ===== Inline Function Start for 3.75. MULR64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_32B_COMPUTATION + * \brief MULR64 (Multiply Word Unsigned to 64-bit Data) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * MULR64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the 32-bit unsigned integer contents of two registers and write the 64-bit result. + * + * **RV32 Description**:\n + * This instruction multiplies the 32-bit content of Rs1 with that of Rs2 and writes the 64-bit + * multiplication result to an even/odd pair of registers containing Rd. Rd(4,1) index d determines the + * even/odd pair group of the two registers. Specifically, the register pair includes register 2d and + * 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * The lower 32-bit contents of Rs1 and Rs2 are treated as unsigned integers. + * + * **RV64 Description**:\n + * This instruction multiplies the lower 32-bit content of Rs1 with that of Rs2 and writes the 64-bit + * multiplication result to Rd. + * The lower 32-bit contents of Rs1 and Rs2 are treated as unsigned integers. + * + * **Operations**:\n + * ~~~ + * RV32: + * Mresult = CONCAT(1`b0,Rs1) u* CONCAT(1`b0,Rs2); + * R[Rd(4,1).1(0)][31:0] = Mresult[63:32]; + * R[Rd(4,1).0(0)][31:0] = Mresult[31:0]; + * RV64: + * Rd = Mresult[63:0]; + * Mresult = CONCAT(1`b0,Rs1.W[0]) u* CONCAT(1`b0,Rs2.W[0]); + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_MULR64(unsigned long a, unsigned long b) +{ + unsigned long long result; + __ASM volatile("mulr64 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.75. MULR64 ===== */ + +/* ===== Inline Function Start for 3.76. MULSR64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_32B_COMPUTATION + * \brief MULSR64 (Multiply Word Signed to 64-bit Data) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * MULSR64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the 32-bit signed integer contents of two registers and write the 64-bit result. + * + * **RV32 Description**:\n + * This instruction multiplies the lower 32-bit content of Rs1 with the lower 32-bit content of Rs2 and + * writes the 64-bit multiplication result to an even/odd pair of registers containing Rd. Rd(4,1) index d + * determines the even/odd pair group of the two registers. Specifically, the register pair includes + * register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * The lower 32-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **RV64 Description**:\n + * This instruction multiplies the lower 32-bit content of Rs1 with the lower 32-bit content of Rs2 and + * writes the 64-bit multiplication result to Rd. + * The lower 32-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * RV32: + * Mresult = Ra s* Rb; + * R[Rd(4,1).1(0)][31:0] = Mresult[63:32]; + * R[Rd(4,1).0(0)][31:0] = Mresult[31:0]; + * RV64: + * Mresult = Ra.W[0] s* Rb.W[0]; + * Rd = Mresult[63:0]; + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_MULSR64(long a, long b) +{ + long long result; + __ASM volatile("mulsr64 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.76. MULSR64 ===== */ + +/* ===== Inline Function Start for 3.77. PBSAD ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_PART_SIMD_MISC + * \brief PBSAD (Parallel Byte Sum of Absolute Difference) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * PBSAD Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Calculate the sum of absolute difference of unsigned 8-bit data elements. + * + * **Description**:\n + * This instruction subtracts the un-signed 8-bit elements of Rs2 from those of Rs1. Then + * it adds the absolute value of each difference together and writes the result to Rd. + * + * **Operations**:\n + * ~~~ + * absdiff[x] = ABS(Rs1.B[x] - Rs2.B[x]); + * Rd = SUM(absdiff[x]); + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_PBSAD(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("pbsad %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.77. PBSAD ===== */ + +/* ===== Inline Function Start for 3.78. PBSADA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_PART_SIMD_MISC + * \brief PBSADA (Parallel Byte Sum of Absolute Difference Accum) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * PBSADA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Calculate the sum of absolute difference of four unsigned 8-bit data elements and + * accumulate it into a register. + * + * **Description**:\n + * This instruction subtracts the un-signed 8-bit elements of Rs2 from those of Rs1. It + * then adds the absolute value of each difference together along with the content of Rd and writes the + * accumulated result back to Rd. + * + * **Operations**:\n + * ~~~ + * absdiff[x] = ABS(Rs1.B[x] - Rs2.B[x]); + * Rd = Rd + SUM(absdiff[x]); + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] t unsigned long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_PBSADA(unsigned long t, unsigned long a, unsigned long b) +{ + __ASM volatile("pbsada %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.78. PBSADA ===== */ + +/* ===== Inline Function Start for 3.79.1. PKBB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_PACK + * \brief PKBB16 (Pack Two 16-bit Data from Both Bottom Half) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * PKBB16 Rd, Rs1, Rs2 + * PKBT16 Rd, Rs1, Rs2 + * PKTT16 Rd, Rs1, Rs2 + * PKTB16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Pack 16-bit data from 32-bit chunks in two registers. + * * PKBB16: bottom.bottom + * * PKBT16 bottom.top + * * PKTT16 top.top + * * PKTB16 top.bottom + * + * **Description**:\n + * (PKBB16) moves Rs1.W[x][15:0] to Rd.W[x][31:16] and moves Rs2.W[x] [15:0] to + * Rd.W[x] [15:0]. + * (PKBT16) moves Rs1.W[x] [15:0] to Rd.W[x] [31:16] and moves Rs2.W[x] [31:16] to Rd.W[x] [15:0]. + * (PKTT16) moves Rs1.W[x] [31:16] to Rd.W[x] [31:16] and moves Rs2.W[x] [31:16] to Rd.W[x] [15:0]. + * (PKTB16) moves Rs1.W[x] [31:16] to Rd.W[x] [31:16] and moves Rs2.W[x] [15:0] to Rd.W[x] [15:0]. + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][15:0], Rs2.W[x][15:0]); // PKBB16 + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][15:0], Rs2.W[x][31:16]); // PKBT16 + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][31:16], Rs2.W[x][15:0]); // PKTB16 + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][31:16], Rs2.W[x][31:16]); // PKTT16 + * for RV32: x=0, + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_PKBB16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("pkbb16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.79.1. PKBB16 ===== */ + +/* ===== Inline Function Start for 3.79.2. PKBT16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_PACK + * \brief PKBT16 (Pack Two 16-bit Data from Bottom and Top Half) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * PKBB16 Rd, Rs1, Rs2 + * PKBT16 Rd, Rs1, Rs2 + * PKTT16 Rd, Rs1, Rs2 + * PKTB16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Pack 16-bit data from 32-bit chunks in two registers. + * * PKBB16: bottom.bottom + * * PKBT16 bottom.top + * * PKTT16 top.top + * * PKTB16 top.bottom + * + * **Description**:\n + * (PKBB16) moves Rs1.W[x][15:0] to Rd.W[x][31:16] and moves Rs2.W[x] [15:0] to + * Rd.W[x] [15:0]. + * (PKBT16) moves Rs1.W[x] [15:0] to Rd.W[x] [31:16] and moves Rs2.W[x] [31:16] to Rd.W[x] [15:0]. + * (PKTT16) moves Rs1.W[x] [31:16] to Rd.W[x] [31:16] and moves Rs2.W[x] [31:16] to Rd.W[x] [15:0]. + * (PKTB16) moves Rs1.W[x] [31:16] to Rd.W[x] [31:16] and moves Rs2.W[x] [15:0] to Rd.W[x] [15:0]. + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][15:0], Rs2.W[x][15:0]); // PKBB16 + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][15:0], Rs2.W[x][31:16]); // PKBT16 + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][31:16], Rs2.W[x][15:0]); // PKTB16 + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][31:16], Rs2.W[x][31:16]); // PKTT16 + * for RV32: x=0, + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_PKBT16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("pkbt16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.79.2. PKBT16 ===== */ + +/* ===== Inline Function Start for 3.79.3. PKTT16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_PACK + * \brief PKTT16 (Pack Two 16-bit Data from Both Top Half) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * PKBB16 Rd, Rs1, Rs2 + * PKBT16 Rd, Rs1, Rs2 + * PKTT16 Rd, Rs1, Rs2 + * PKTB16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Pack 16-bit data from 32-bit chunks in two registers. + * * PKBB16: bottom.bottom + * * PKBT16 bottom.top + * * PKTT16 top.top + * * PKTB16 top.bottom + * + * **Description**:\n + * (PKBB16) moves Rs1.W[x][15:0] to Rd.W[x][31:16] and moves Rs2.W[x] [15:0] to + * Rd.W[x] [15:0]. + * (PKBT16) moves Rs1.W[x] [15:0] to Rd.W[x] [31:16] and moves Rs2.W[x] [31:16] to Rd.W[x] [15:0]. + * (PKTT16) moves Rs1.W[x] [31:16] to Rd.W[x] [31:16] and moves Rs2.W[x] [31:16] to Rd.W[x] [15:0]. + * (PKTB16) moves Rs1.W[x] [31:16] to Rd.W[x] [31:16] and moves Rs2.W[x] [15:0] to Rd.W[x] [15:0]. + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][15:0], Rs2.W[x][15:0]); // PKBB16 + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][15:0], Rs2.W[x][31:16]); // PKBT16 + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][31:16], Rs2.W[x][15:0]); // PKTB16 + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][31:16], Rs2.W[x][31:16]); // PKTT16 + * for RV32: x=0, + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_PKTT16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("pktt16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.79.3. PKTT16 ===== */ + +/* ===== Inline Function Start for 3.79.4. PKTB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_PACK + * \brief PKTB16 (Pack Two 16-bit Data from Top and Bottom Half) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * PKBB16 Rd, Rs1, Rs2 + * PKBT16 Rd, Rs1, Rs2 + * PKTT16 Rd, Rs1, Rs2 + * PKTB16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Pack 16-bit data from 32-bit chunks in two registers. + * * PKBB16: bottom.bottom + * * PKBT16 bottom.top + * * PKTT16 top.top + * * PKTB16 top.bottom + * + * **Description**:\n + * (PKBB16) moves Rs1.W[x][15:0] to Rd.W[x][31:16] and moves Rs2.W[x] [15:0] to + * Rd.W[x] [15:0]. + * (PKBT16) moves Rs1.W[x] [15:0] to Rd.W[x] [31:16] and moves Rs2.W[x] [31:16] to Rd.W[x] [15:0]. + * (PKTT16) moves Rs1.W[x] [31:16] to Rd.W[x] [31:16] and moves Rs2.W[x] [31:16] to Rd.W[x] [15:0]. + * (PKTB16) moves Rs1.W[x] [31:16] to Rd.W[x] [31:16] and moves Rs2.W[x] [15:0] to Rd.W[x] [15:0]. + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][15:0], Rs2.W[x][15:0]); // PKBB16 + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][15:0], Rs2.W[x][31:16]); // PKBT16 + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][31:16], Rs2.W[x][15:0]); // PKTB16 + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][31:16], Rs2.W[x][31:16]); // PKTT16 + * for RV32: x=0, + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_PKTB16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("pktb16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.79.4. PKTB16 ===== */ + +/* ===== Inline Function Start for 3.80. RADD8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_ADDSUB + * \brief RADD8 (SIMD 8-bit Signed Halving Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * RADD8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit signed integer element additions simultaneously. The element results are halved + * to avoid overflow or saturation. + * + * **Description**:\n + * This instruction adds the 8-bit signed integer elements in Rs1 with the 8-bit signed + * integer elements in Rs2. The results are first arithmetically right-shifted by 1 bit and then written to + * Rd. + * + * **Examples**:\n + * ~~~ + * * Rs1 = 0x7F, Rs2 = 0x7F, Rd = 0x7F + * * Rs1 = 0x80, Rs2 = 0x80, Rd = 0x80 + * * Rs1 = 0x40, Rs2 = 0x80, Rd = 0xE0 + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.B[x] = (Rs1.B[x] + Rs2.B[x]) s>> 1; for RV32: x=3...0, for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_RADD8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("radd8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.80. RADD8 ===== */ + +/* ===== Inline Function Start for 3.81. RADD16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief RADD16 (SIMD 16-bit Signed Halving Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * RADD16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element additions simultaneously. The results are halved to avoid + * overflow or saturation. + * + * **Description**:\n + * This instruction adds the 16-bit signed integer elements in Rs1 with the 16-bit signed + * integer elements in Rs2. The results are first arithmetically right-shifted by 1 bit and then written to + * Rd. + * + * **Examples**:\n + * ~~~ + * * Rs1 = 0x7FFF, Rs2 = 0x7FFF, Rd = 0x7FFF + * * Rs1 = 0x8000, Rs2 = 0x8000, Rd = 0x8000 + * * Rs1 = 0x4000, Rs2 = 0x8000, Rd = 0xE000 + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = (Rs1.H[x] + Rs2.H[x]) s>> 1; for RV32: x=1...0, for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_RADD16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("radd16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.81. RADD16 ===== */ + +/* ===== Inline Function Start for 3.82. RADD64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_64B_ADDSUB + * \brief RADD64 (64-bit Signed Halving Addition) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * RADD64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Add two 64-bit signed integers. The result is halved to avoid overflow or saturation. + * + * **RV32 Description**:\n + * This instruction adds the 64-bit signed integer of an even/odd pair of registers + * specified by Rs1(4,1) with the 64-bit signed integer of an even/odd pair of registers specified by + * Rs2(4,1). The 64-bit addition result is first arithmetically right-shifted by 1 bit and then written to an + * even/odd pair of registers specified by Rd(4,1). + * Rx(4,1), i.e., value d, determines the even/odd pair group of two registers. Specifically, the register + * pair includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * + * **RV64 Description**:\n + * This instruction adds the 64-bit signed integer in Rs1 with the 64-bit signed + * integer in Rs2. The 64-bit addition result is first arithmetically right-shifted by 1 bit and then + * written to Rd. + * + * **Operations**:\n + * ~~~ + * RV32: + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * a_L = CONCAT(Rs1(4,1),1'b0); a_H = CONCAT(Rs1(4,1),1'b1); + * b_L = CONCAT(Rs2(4,1),1'b0); b_H = CONCAT(Rs2(4,1),1'b1); + * R[t_H].R[t_L] = (R[a_H].R[a_L] + R[b_H].R[b_L]) s>> 1; + * RV64: + * Rd = (Rs1 + Rs2) s>> 1; + * ~~~ + * + * \param [in] a long long type of value stored in a + * \param [in] b long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_RADD64(long long a, long long b) +{ + long long result; + __ASM volatile("radd64 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.82. RADD64 ===== */ + +/* ===== Inline Function Start for 3.83. RADDW ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_32B_COMPUTATION + * \brief RADDW (32-bit Signed Halving Addition) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * RADDW Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Add 32-bit signed integers and the results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction adds the first 32-bit signed integer in Rs1 with the first 32-bit signed + * integer in Rs2. The result is first arithmetically right-shifted by 1 bit and then sign-extended and + * written to Rd. + * + * **Examples**:\n + * ~~~ + * * Rs1 = 0x7FFFFFFF, Rs2 = 0x7FFFFFFF, Rd = 0x7FFFFFFF + * * Rs1 = 0x80000000, Rs2 = 0x80000000, Rd = 0x80000000 + * * Rs1 = 0x40000000, Rs2 = 0x80000000, Rd = 0xE0000000 + * ~~~ + * + * **Operations**:\n + * ~~~ + * RV32: + * Rd[31:0] = (Rs1[31:0] + Rs2[31:0]) s>> 1; + * RV64: + * resw[31:0] = (Rs1[31:0] + Rs2[31:0]) s>> 1; + * Rd[63:0] = SE(resw[31:0]); + * ~~~ + * + * \param [in] a int type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_RADDW(int a, int b) +{ + long result; + __ASM volatile("raddw %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.83. RADDW ===== */ + +/* ===== Inline Function Start for 3.84. RCRAS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief RCRAS16 (SIMD 16-bit Signed Halving Cross Addition & Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * RCRAS16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element addition and 16-bit signed integer element subtraction in + * a 32-bit chunk simultaneously. Operands are from crossed positions in 32-bit chunks. The results + * are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction adds the 16-bit signed integer element in [31:16] of 32-bit chunks in + * Rs1 with the 16-bit signed integer element in [15:0] of 32-bit chunks in Rs2, and subtracts the 16-bit + * signed integer element in [31:16] of 32-bit chunks in Rs2 from the 16-bit signed integer element in + * [15:0] of 32-bit chunks in Rs1. The element results are first arithmetically right-shifted by 1 bit and + * then written to [31:16] of 32-bit chunks in Rd and [15:0] of 32-bit chunks in Rd. + * + * **Examples**:\n + * ~~~ + * Please see `RADD16` and `RSUB16` instructions. + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:16] = (Rs1.W[x][31:16] + Rs2.W[x][15:0]) s>> 1; + * Rd.W[x][15:0] = (Rs1.W[x][15:0] - Rs2.W[x][31:16]) s>> 1; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_RCRAS16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("rcras16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.84. RCRAS16 ===== */ + +/* ===== Inline Function Start for 3.85. RCRSA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief RCRSA16 (SIMD 16-bit Signed Halving Cross Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * RCRSA16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element subtraction and 16-bit signed integer element addition in + * a 32-bit chunk simultaneously. Operands are from crossed positions in 32-bit chunks. The results + * are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 16-bit signed integer element in [15:0] of 32-bit chunks + * in Rs2 from the 16-bit signed integer element in [31:16] of 32-bit chunks in Rs1, and adds the 16-bit + * signed element integer in [15:0] of 32-bit chunks in Rs1 with the 16-bit signed integer element in + * [31:16] of 32-bit chunks in Rs2. The two results are first arithmetically right-shifted by 1 bit and + * then written to [31:16] of 32-bit chunks in Rd and [15:0] of 32-bit chunks in Rd. + * + * **Examples**:\n + * ~~~ + * Please see `RADD16` and `RSUB16` instructions. + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:16] = (Rs1.W[x][31:16] - Rs2.W[x][15:0]) s>> 1; + * Rd.W[x][15:0] = (Rs1.W[x][15:0] + Rs2.W[x][31:16]) s>> 1; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_RCRSA16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("rcrsa16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.85. RCRSA16 ===== */ + +/* ===== Inline Function Start for 3.86. RDOV ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_OV_FLAG_SC + * \brief RDOV (Read OV flag) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * RDOV Rd # pseudo mnemonic + * ~~~ + * + * **Purpose**:\n + * This pseudo instruction is an alias to `CSRR Rd, ucode` instruction which maps to the real + * instruction of `CSRRS Rd, ucode, x0`. + * + * + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_RDOV(void) +{ + unsigned long result; + __ASM volatile("rdov %0" : "=r"(result)); + return result; +} +/* ===== Inline Function End for 3.86. RDOV ===== */ + +/* ===== Inline Function Start for 3.87. RSTAS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief RSTAS16 (SIMD 16-bit Signed Halving Straight Addition & Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * RSTAS16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element addition and 16-bit signed integer element subtraction in + * a 32-bit chunk simultaneously. Operands are from corresponding positions in 32-bit chunks. The + * results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction adds the 16-bit signed integer element in [31:16] of 32-bit chunks in + * Rs1 with the 16-bit signed integer element in [31:16] of 32-bit chunks in Rs2, and subtracts the 16-bit + * signed integer element in [15:0] of 32-bit chunks in Rs2 from the 16-bit signed integer element in + * [15:0] of 32-bit chunks in Rs1. The element results are first arithmetically right-shifted by 1 bit and + * then written to [31:16] of 32-bit chunks in Rd and [15:0] of 32-bit chunks in Rd. + * + * **Examples**:\n + * ~~~ + * Please see `RADD16` and `RSUB16` instructions. + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:16] = (Rs1.W[x][31:16] + Rs2.W[x][31:16]) s>> 1; + * Rd.W[x][15:0] = (Rs1.W[x][15:0] - Rs2.W[x][15:0]) s>> 1; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_RSTAS16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("rstas16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.87. RSTAS16 ===== */ + +/* ===== Inline Function Start for 3.88. RSTSA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief RSTSA16 (SIMD 16-bit Signed Halving Straight Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * RSTSA16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element subtraction and 16-bit signed integer element addition in + * a 32-bit chunk simultaneously. Operands are from corresponding positions in 32-bit chunks. The + * results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 16-bit signed integer element in [31:16] of 32-bit chunks + * in Rs2 from the 16-bit signed integer element in [31:16] of 32-bit chunks in Rs1, and adds the 16-bit + * signed element integer in [15:0] of 32-bit chunks in Rs1 with the 16-bit signed integer element in + * [15:0] of 32-bit chunks in Rs2. The two results are first arithmetically right-shifted by 1 bit and then + * written to [31:16] of 32-bit chunks in Rd and [15:0] of 32-bit chunks in Rd. + * + * **Examples**:\n + * ~~~ + * Please see `RADD16` and `RSUB16` instructions. + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:16] = (Rs1.W[x][31:16] - Rs2.W[x][31:16]) s>> 1; + * Rd.W[x][15:0] = (Rs1.W[x][15:0] + Rs2.W[x][15:0]) s>> 1; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_RSTSA16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("rstsa16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.88. RSTSA16 ===== */ + +/* ===== Inline Function Start for 3.89. RSUB8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_ADDSUB + * \brief RSUB8 (SIMD 8-bit Signed Halving Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * RSUB8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit signed integer element subtractions simultaneously. The results are halved to + * avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 8-bit signed integer elements in Rs2 from the 8-bit + * signed integer elements in Rs1. The results are first arithmetically right-shifted by 1 bit and then + * written to Rd. + * + * **Examples**:\n + * ~~~ + * * Rs1 = 0x7F, Rs2 = 0x80, Rd = 0x7F + * * Rs1 = 0x80, Rs2 = 0x7F, Rd = 0x80 + * * Rs1= 0x80, Rs2 = 0x40, Rd = 0xA0 + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.B[x] = (Rs1.B[x] - Rs2.B[x]) s>> 1; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_RSUB8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("rsub8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.89. RSUB8 ===== */ + +/* ===== Inline Function Start for 3.90. RSUB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief RSUB16 (SIMD 16-bit Signed Halving Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * RSUB16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element subtractions simultaneously. The results are halved to + * avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 16-bit signed integer elements in Rs2 from the 16-bit + * signed integer elements in Rs1. The results are first arithmetically right-shifted by 1 bit and then + * written to Rd. + * + * **Examples**:\n + * ~~~ + * * Ra = 0x7FFF, Rb = 0x8000, Rt = 0x7FFF + * * Ra = 0x8000, Rb = 0x7FFF, Rt = 0x8000 + * * Ra = 0x8000, Rb = 0x4000, Rt = 0xA000 + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = (Rs1.H[x] - Rs2.H[x]) s>> 1; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_RSUB16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("rsub16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.90. RSUB16 ===== */ + +/* ===== Inline Function Start for 3.91. RSUB64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_64B_ADDSUB + * \brief RSUB64 (64-bit Signed Halving Subtraction) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * RSUB64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Perform a 64-bit signed integer subtraction. The result is halved to avoid overflow or + * saturation. + * + * **RV32 Description**:\n + * This instruction subtracts the 64-bit signed integer of an even/odd pair of + * registers specified by Rb(4,1) from the 64-bit signed integer of an even/odd pair of registers + * specified by Ra(4,1). The subtraction result is first arithmetically right-shifted by 1 bit and then + * written to an even/odd pair of registers specified by Rt(4,1). + * Rx(4,1), i.e., value d, determines the even/odd pair group of two registers. Specifically, the register + * pair includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * + * **RV64 Description**:\n + * This instruction subtracts the 64-bit signed integer in Rs2 from the 64-bit signed + * integer in Rs1. The 64-bit subtraction result is first arithmetically right-shifted by 1 bit and then + * written to Rd. + * + * **Operations**:\n + * ~~~ + * RV32: + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * a_L = CONCAT(Rs1(4,1),1'b0); a_H = CONCAT(Rs1(4,1),1'b1); + * b_L = CONCAT(Rs2(4,1),1'b0); b_H = CONCAT(Rs2(4,1),1'b1); + * R[t_H].R[t_L] = (R[a_H].R[a_L] - R[b_H].R[b_L]) s>> 1; + * RV64: + * Rd = (Rs1 - Rs2) s>> 1; + * ~~~ + * + * \param [in] a long long type of value stored in a + * \param [in] b long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_RSUB64(long long a, long long b) +{ + long long result; + __ASM volatile("rsub64 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.91. RSUB64 ===== */ + +/* ===== Inline Function Start for 3.92. RSUBW ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_32B_COMPUTATION + * \brief RSUBW (32-bit Signed Halving Subtraction) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * RSUBW Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Subtract 32-bit signed integers and the result is halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the first 32-bit signed integer in Rs2 from the first 32-bit + * signed integer in Rs1. The result is first arithmetically right-shifted by 1 bit and then sign-extended + * and written to Rd. + * + * **Examples**:\n + * ~~~ + * * Rs1 = 0x7FFFFFFF, Rs2 = 0x80000000, Rd = 0x7FFFFFFF + * * Rs1 = 0x80000000, Rs2 = 0x7FFFFFFF, Rd = 0x80000000 + * * Rs1 = 0x80000000, Rs2 = 0x40000000, Rd = 0xA0000000 + * ~~~ + * + * **Operations**:\n + * ~~~ + * RV32: + * Rd[31:0] = (Rs1[31:0] - Rs2[31:0]) s>> 1; + * RV64: + * resw[31:0] = (Rs1[31:0] - Rs2[31:0]) s>> 1; + * Rd[63:0] = SE(resw[31:0]); + * ~~~ + * + * \param [in] a int type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_RSUBW(int a, int b) +{ + long result; + __ASM volatile("rsubw %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.92. RSUBW ===== */ + +/* ===== Inline Function Start for 3.93. SCLIP8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_MISC + * \brief SCLIP8 (SIMD 8-bit Signed Clip Value) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SCLIP8 Rd, Rs1, imm3u[2:0] + * ~~~ + * + * **Purpose**:\n + * Limit the 8-bit signed integer elements of a register into a signed range simultaneously. + * + * **Description**:\n + * This instruction limits the 8-bit signed integer elements stored in Rs1 into a signed + * integer range between 2^imm3u-1 and -2^imm3u, and writes the limited results to Rd. For example, if + * imm3u is 3, the 8-bit input values should be saturated between 7 and -8. If saturation is performed, + * set OV bit to 1. + * + * **Operations**:\n + * ~~~ + * src = Rs1.B[x]; + * if (src > (2^imm3u)-1) { + * src = (2^imm3u)-1; + * OV = 1; + * } else if (src < -2^imm3u) { + * src = -2^imm3u; + * OV = 1; + * } + * Rd.B[x] = src + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SCLIP8(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("sclip8 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.93. SCLIP8 ===== */ + +/* ===== Inline Function Start for 3.94. SCLIP16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_MISC + * \brief SCLIP16 (SIMD 16-bit Signed Clip Value) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SCLIP16 Rd, Rs1, imm4u[3:0] + * ~~~ + * + * **Purpose**:\n + * Limit the 16-bit signed integer elements of a register into a signed range simultaneously. + * + * **Description**:\n + * This instruction limits the 16-bit signed integer elements stored in Rs1 into a signed + * integer range between 2imm4u-1 and -2imm4u, and writes the limited results to Rd. For example, if + * imm4u is 3, the 16-bit input values should be saturated between 7 and -8. If saturation is performed, + * set OV bit to 1. + * + * **Operations**:\n + * ~~~ + * src = Rs1.H[x]; + * if (src > (2^imm4u)-1) { + * src = (2^imm4u)-1; + * OV = 1; + * } else if (src < -2^imm4u) { + * src = -2^imm4u; + * OV = 1; + * } + * Rd.H[x] = src + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SCLIP16(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("sclip16 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.94. SCLIP16 ===== */ + +/* ===== Inline Function Start for 3.95. SCLIP32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_PART_SIMD_MISC + * \brief SCLIP32 (SIMD 32-bit Signed Clip Value) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * SCLIP32 Rd, Rs1, imm5u[4:0] + * ~~~ + * + * **Purpose**:\n + * Limit the 32-bit signed integer elements of a register into a signed range simultaneously. + * + * **Description**:\n + * This instruction limits the 32-bit signed integer elements stored in Rs1 into a signed + * integer range between 2imm5u-1 and -2imm5u, and writes the limited results to Rd. For example, if + * imm5u is 3, the 32-bit input values should be saturated between 7 and -8. If saturation is performed, + * set OV bit to 1. + * + * **Operations**:\n + * ~~~ + * src = Rs1.W[x]; + * if (src > (2^imm5u)-1) { + * src = (2^imm5u)-1; + * OV = 1; + * } else if (src < -2^imm5u) { + * src = -2^imm5u; + * OV = 1; + * } + * Rd.W[x] = src + * for RV32: x=0, + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in long type + */ +#define __RV_SCLIP32(a, b) \ + ({ \ + long result; \ + long __a = (long)(a); \ + __ASM volatile("sclip32 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.95. SCLIP32 ===== */ + +/* ===== Inline Function Start for 3.96. SCMPLE8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_CMP + * \brief SCMPLE8 (SIMD 8-bit Signed Compare Less Than & Equal) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SCMPLE8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit signed integer elements less than & equal comparisons simultaneously. + * + * **Description**:\n + * This instruction compares the 8-bit signed integer elements in Rs1 with the 8-bit + * signed integer elements in Rs2 to see if the one in Rs1 is less than or equal to the one in Rs2. If it is + * true, the result is 0xFF; otherwise, the result is 0x0. The element comparison results are written to + * Rd + * + * **Operations**:\n + * ~~~ + * Rd.B[x] = (Rs1.B[x] {le} Rs2.B[x])? 0xff : 0x0; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SCMPLE8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("scmple8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.96. SCMPLE8 ===== */ + +/* ===== Inline Function Start for 3.97. SCMPLE16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_CMP + * \brief SCMPLE16 (SIMD 16-bit Signed Compare Less Than & Equal) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SCMPLE16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer elements less than & equal comparisons simultaneously. + * + * **Description**:\n + * This instruction compares the 16-bit signed integer elements in Rs1 with the 16-bit + * signed integer elements in Rs2 to see if the one in Rs1 is less than or equal to the one in Rs2. If it is + * true, the result is 0xFFFF; otherwise, the result is 0x0. The element comparison results are written + * to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = (Rs1.H[x] {le} Rs2.H[x])? 0xffff : 0x0; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SCMPLE16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("scmple16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.97. SCMPLE16 ===== */ + +/* ===== Inline Function Start for 3.98. SCMPLT8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_CMP + * \brief SCMPLT8 (SIMD 8-bit Signed Compare Less Than) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SCMPLT8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit signed integer elements less than comparisons simultaneously. + * + * **Description**:\n + * This instruction compares the 8-bit signed integer elements in Rs1 with the 8-bit + * signed integer elements in Rs2 to see if the one in Rs1 is less than the one in Rs2. If it is true, the + * result is 0xFF; otherwise, the result is 0x0. The element comparison results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.B[x] = (Rs1.B[x] < Rs2.B[x])? 0xff : 0x0; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SCMPLT8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("scmplt8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.98. SCMPLT8 ===== */ + +/* ===== Inline Function Start for 3.99. SCMPLT16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_CMP + * \brief SCMPLT16 (SIMD 16-bit Signed Compare Less Than) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SCMPLT16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer elements less than comparisons simultaneously. + * + * **Description**:\n + * This instruction compares the 16-bit signed integer elements in Rs1 with the two 16- + * bit signed integer elements in Rs2 to see if the one in Rs1 is less than the one in Rs2. If it is true, the + * result is 0xFFFF; otherwise, the result is 0x0. The element comparison results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = (Rs1.H[x] < Rs2.H[x])? 0xffff : 0x0; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SCMPLT16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("scmplt16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.99. SCMPLT16 ===== */ + +/* ===== Inline Function Start for 3.100. SLL8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_SHIFT + * \brief SLL8 (SIMD 8-bit Shift Left Logical) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SLL8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit elements logical left shift operations simultaneously. The shift amount is a + * variable from a GPR. + * + * **Description**:\n + * The 8-bit elements in Rs1 are left-shifted logically. And the results are written to Rd. + * The shifted out bits are filled with zero and the shift amount is specified by the low-order 3-bits of + * the value in the Rs2 register. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[2:0]; + * Rd.B[x] = Rs1.B[x] << sa; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SLL8(unsigned long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("sll8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.100. SLL8 ===== */ + +/* ===== Inline Function Start for 3.101. SLLI8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_SHIFT + * \brief SLLI8 (SIMD 8-bit Shift Left Logical Immediate) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SLLI8 Rd, Rs1, imm3u + * ~~~ + * + * **Purpose**:\n + * Do 8-bit elements logical left shift operations simultaneously. The shift amount is an + * immediate value. + * + * **Description**:\n + * The 8-bit elements in Rs1 are left-shifted logically. And the results are written to Rd. + * The shifted out bits are filled with zero and the shift amount is specified by the imm3u constant. + * + * **Operations**:\n + * ~~~ + * sa = imm3u[2:0]; + * Rd.B[x] = Rs1.B[x] << sa; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SLLI8(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("slli8 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.101. SLLI8 ===== */ + +/* ===== Inline Function Start for 3.102. SLL16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_SHIFT + * \brief SLL16 (SIMD 16-bit Shift Left Logical) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SLL16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit elements logical left shift operations simultaneously. The shift amount is a + * variable from a GPR. + * + * **Description**:\n + * The 16-bit elements in Rs1 are left-shifted logically. And the results are written to Rd. + * The shifted out bits are filled with zero and the shift amount is specified by the low-order 4-bits of + * the value in the Rs2 register. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[3:0]; + * Rd.H[x] = Rs1.H[x] << sa; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SLL16(unsigned long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("sll16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.102. SLL16 ===== */ + +/* ===== Inline Function Start for 3.103. SLLI16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_SHIFT + * \brief SLLI16 (SIMD 16-bit Shift Left Logical Immediate) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SLLI16 Rd, Rs1, imm4[3:0] + * ~~~ + * + * **Purpose**:\n + * Do 16-bit element logical left shift operations simultaneously. The shift amount is an + * immediate value. + * + * **Description**:\n + * The 16-bit elements in Rs1 are left-shifted logically. The shifted out bits are filled with + * zero and the shift amount is specified by the imm4[3:0] constant. And the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = imm4[3:0]; + * Rd.H[x] = Rs1.H[x] << sa; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SLLI16(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("slli16 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.103. SLLI16 ===== */ + +/* ===== Inline Function Start for 3.104. SMAL ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_64B_ADDSUB + * \brief SMAL (Signed Multiply Halfs & Add 64-bit) + * \details + * **Type**: Partial-SIMD + * + * **Syntax**:\n + * ~~~ + * SMAL Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed bottom 16-bit content of the 32-bit elements of a register with the top + * 16-bit content of the same 32-bit elements of the same register, and add the results with a 64-bit + * value of an even/odd pair of registers (RV32) or a register (RV64). The addition result is written back + * to another even/odd pair of registers (RV32) or a register (RV64). + * + * **RV32 Description**:\n + * This instruction multiplies the bottom 16-bit content of the lower 32-bit of Rs2 with the top 16-bit + * content of the lower 32-bit of Rs2 and adds the result with the 64-bit value of an even/odd pair of + * registers specified by Rs1(4,1). The 64-bit addition result is written back to an even/odd pair of + * registers specified by Rd(4,1). The 16-bit values of Rs2, and the 64-bit value of the Rs1(4,1) register- + * pair are treated as signed integers. + * Rx(4,1), i.e., d, determines the even/odd pair group of the two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the operand and the even `2d` + * register of the pair contains the low 32-bit of the operand. + * + * **RV64 Description**:\n + * This instruction multiplies the bottom 16-bit content of the 32-bit elements of Rs2 with the top 16-bit + * content of the same 32-bit elements of Rs2 and adds the results with the 64-bit value of Rs1. The 64- + * bit addition result is written back to Rd. The 16-bit values of Rs2, and the 64-bit value of Rs1 are + * treated as signed integers. + * + * **Operations**:\n + * ~~~ + * RV32: + * Mres[31:0] = Rs2.H[1] * Rs2.H[0]; + * Idx0 = CONCAT(Rs1(4,1),1'b0); Idx1 = CONCAT(Rs1(4,1),1'b1); + + * Idx2 = CONCAT(Rd(4,1),1'b0); Idx3 = CONCAT(Rd(4,1),1'b1); + * R[Idx3].R[Idx2] = R[Idx1].R[Idx0] + SE64(Mres[31:0]); + * RV64: + * Mres[0][31:0] = Rs2.W[0].H[1] * Rs2.W[0].H[0]; + * Mres[1][31:0] = Rs2.W[1].H[1] * Rs2.W[1].H[0]; + * Rd = Rs1 + SE64(Mres[1][31:0]) + SE64(Mres[0][31:0]); + * ~~~ + * + * \param [in] a long long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_SMAL(long long a, unsigned long b) +{ + long long result; + __ASM volatile("smal %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.104. SMAL ===== */ + +/* ===== Inline Function Start for 3.105.1. SMALBB ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_64B_ADDSUB + * \brief SMALBB (Signed Multiply Bottom Halfs & Add 64-bit) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * SMALBB Rd, Rs1, Rs2 + * SMALBT Rd, Rs1, Rs2 + * SMALTT Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 16-bit content of the 32-bit elements of a register with the 16-bit + * content of the corresponding 32-bit elements of another register and add the results with a 64-bit + * value of an even/odd pair of registers (RV32) or a register (RV64). The addition result is written back + * to the register-pair (RV32) or the register (RV64). + * * SMALBB: rt pair + bottom*bottom (all 32-bit elements) + * * SMALBT rt pair + bottom*top (all 32-bit elements) + * * SMALTT rt pair + top*top (all 32-bit elements) + * + * **RV32 Description**:\n + * For the `SMALBB` instruction, it multiplies the bottom 16-bit content of Rs1 with the bottom 16-bit + * content of Rs2. + * For the `SMALBT` instruction, it multiplies the bottom 16-bit content of Rs1 with the top 16-bit + * content of Rs2. + * For the `SMALTT` instruction, it multiplies the top 16-bit content of Rs1 with the top 16-bit content + * of Rs2. + * The multiplication result is added with the 64-bit value of an even/odd pair of registers specified by + * Rd(4,1). The 64-bit addition result is written back to the register-pair. The 16-bit values of Rs1 and + * Rs2, and the 64-bit value of the register-pair are treated as signed integers. + * Rd(4,1), i.e., d, determines the even/odd pair group of the two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the operand and the even `2d` + * register of the pair contains the low 32-bit of the operand. + * + * **RV64 Description**:\n + * For the `SMALBB` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2. + * For the `SMALBT` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2. + * For the `SMALTT` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 with + * the top 16-bit content of the 32-bit elements of Rs2. + * The multiplication results are added with the 64-bit value of Rd. The 64-bit addition result is written + * back to Rd. The 16-bit values of Rs1 and Rs2, and the 64-bit value of Rd are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * RV32: + * Mres[31:0] = Rs1.H[0] * Rs2.H[0]; // SMALBB + * Mres[31:0] = Rs1.H[0] * Rs2.H[1]; // SMALBT + * Mres[31:0] = Rs1.H[1] * Rs2.H[1]; // SMALTT + * Idx0 = CONCAT(Rd(4,1),1'b0); Idx1 = CONCAT(Rd(4,1),1'b1); + * R[Idx1].R[Idx0] = R[Idx1].R[Idx0] + SE64(Mres[31:0]); + * RV64: + * // SMALBB + * Mres[0][31:0] = Rs1.W[0].H[0] * Rs2.W[0].H[0]; + * Mres[1][31:0] = Rs1.W[1].H[0] * Rs2.W[1].H[0]; + * // SMALBT + * Mres[0][31:0] = Rs1.W[0].H[0] * Rs2.W[0].H[1]; + * Mres[1][31:0] = Rs1.W[1].H[0] * Rs2.W[1].H[1]; + * // SMALTT + * Mres[0][31:0] = Rs1.W[0].H[1] * Rs2.W[0].H[1]; + * Mres[1][31:0] = Rs1.W[1].H[1] * Rs2.W[1].H[1]; + * Rd = Rd + SE64(Mres[0][31:0]) + SE64(Mres[1][31:0]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_SMALBB(long long t, unsigned long a, unsigned long b) +{ + __ASM volatile("smalbb %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.105.1. SMALBB ===== */ + +/* ===== Inline Function Start for 3.105.2. SMALBT ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_64B_ADDSUB + * \brief SMALBT (Signed Multiply Bottom Half & Top Half & Add 64-bit) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * SMALBB Rd, Rs1, Rs2 + * SMALBT Rd, Rs1, Rs2 + * SMALTT Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 16-bit content of the 32-bit elements of a register with the 16-bit + * content of the corresponding 32-bit elements of another register and add the results with a 64-bit + * value of an even/odd pair of registers (RV32) or a register (RV64). The addition result is written back + * to the register-pair (RV32) or the register (RV64). + * * SMALBB: rt pair + bottom*bottom (all 32-bit elements) + * * SMALBT rt pair + bottom*top (all 32-bit elements) + * * SMALTT rt pair + top*top (all 32-bit elements) + * + * **RV32 Description**:\n + * For the `SMALBB` instruction, it multiplies the bottom 16-bit content of Rs1 with the bottom 16-bit + * content of Rs2. + * For the `SMALBT` instruction, it multiplies the bottom 16-bit content of Rs1 with the top 16-bit + * content of Rs2. + * For the `SMALTT` instruction, it multiplies the top 16-bit content of Rs1 with the top 16-bit content + * of Rs2. + * The multiplication result is added with the 64-bit value of an even/odd pair of registers specified by + * Rd(4,1). The 64-bit addition result is written back to the register-pair. The 16-bit values of Rs1 and + * Rs2, and the 64-bit value of the register-pair are treated as signed integers. + * Rd(4,1), i.e., d, determines the even/odd pair group of the two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the operand and the even `2d` + * register of the pair contains the low 32-bit of the operand. + * + * **RV64 Description**:\n + * For the `SMALBB` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2. + * For the `SMALBT` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2. + * For the `SMALTT` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 with + * the top 16-bit content of the 32-bit elements of Rs2. + * The multiplication results are added with the 64-bit value of Rd. The 64-bit addition result is written + * back to Rd. The 16-bit values of Rs1 and Rs2, and the 64-bit value of Rd are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * RV32: + * Mres[31:0] = Rs1.H[0] * Rs2.H[0]; // SMALBB + * Mres[31:0] = Rs1.H[0] * Rs2.H[1]; // SMALBT + * Mres[31:0] = Rs1.H[1] * Rs2.H[1]; // SMALTT + * Idx0 = CONCAT(Rd(4,1),1'b0); Idx1 = CONCAT(Rd(4,1),1'b1); + * R[Idx1].R[Idx0] = R[Idx1].R[Idx0] + SE64(Mres[31:0]); + * RV64: + * // SMALBB + * Mres[0][31:0] = Rs1.W[0].H[0] * Rs2.W[0].H[0]; + * Mres[1][31:0] = Rs1.W[1].H[0] * Rs2.W[1].H[0]; + * // SMALBT + * Mres[0][31:0] = Rs1.W[0].H[0] * Rs2.W[0].H[1]; + * Mres[1][31:0] = Rs1.W[1].H[0] * Rs2.W[1].H[1]; + * // SMALTT + * Mres[0][31:0] = Rs1.W[0].H[1] * Rs2.W[0].H[1]; + * Mres[1][31:0] = Rs1.W[1].H[1] * Rs2.W[1].H[1]; + * Rd = Rd + SE64(Mres[0][31:0]) + SE64(Mres[1][31:0]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_SMALBT(long long t, unsigned long a, unsigned long b) +{ + __ASM volatile("smalbt %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.105.2. SMALBT ===== */ + +/* ===== Inline Function Start for 3.105.3. SMALTT ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_64B_ADDSUB + * \brief SMALTT (Signed Multiply Top Halfs & Add 64-bit) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * SMALBB Rd, Rs1, Rs2 + * SMALBT Rd, Rs1, Rs2 + * SMALTT Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 16-bit content of the 32-bit elements of a register with the 16-bit + * content of the corresponding 32-bit elements of another register and add the results with a 64-bit + * value of an even/odd pair of registers (RV32) or a register (RV64). The addition result is written back + * to the register-pair (RV32) or the register (RV64). + * * SMALBB: rt pair + bottom*bottom (all 32-bit elements) + * * SMALBT rt pair + bottom*top (all 32-bit elements) + * * SMALTT rt pair + top*top (all 32-bit elements) + * + * **RV32 Description**:\n + * For the `SMALBB` instruction, it multiplies the bottom 16-bit content of Rs1 with the bottom 16-bit + * content of Rs2. + * For the `SMALBT` instruction, it multiplies the bottom 16-bit content of Rs1 with the top 16-bit + * content of Rs2. + * For the `SMALTT` instruction, it multiplies the top 16-bit content of Rs1 with the top 16-bit content + * of Rs2. + * The multiplication result is added with the 64-bit value of an even/odd pair of registers specified by + * Rd(4,1). The 64-bit addition result is written back to the register-pair. The 16-bit values of Rs1 and + * Rs2, and the 64-bit value of the register-pair are treated as signed integers. + * Rd(4,1), i.e., d, determines the even/odd pair group of the two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the operand and the even `2d` + * register of the pair contains the low 32-bit of the operand. + * + * **RV64 Description**:\n + * For the `SMALBB` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2. + * For the `SMALBT` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2. + * For the `SMALTT` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 with + * the top 16-bit content of the 32-bit elements of Rs2. + * The multiplication results are added with the 64-bit value of Rd. The 64-bit addition result is written + * back to Rd. The 16-bit values of Rs1 and Rs2, and the 64-bit value of Rd are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * RV32: + * Mres[31:0] = Rs1.H[0] * Rs2.H[0]; // SMALBB + * Mres[31:0] = Rs1.H[0] * Rs2.H[1]; // SMALBT + * Mres[31:0] = Rs1.H[1] * Rs2.H[1]; // SMALTT + * Idx0 = CONCAT(Rd(4,1),1'b0); Idx1 = CONCAT(Rd(4,1),1'b1); + * R[Idx1].R[Idx0] = R[Idx1].R[Idx0] + SE64(Mres[31:0]); + * RV64: + * // SMALBB + * Mres[0][31:0] = Rs1.W[0].H[0] * Rs2.W[0].H[0]; + * Mres[1][31:0] = Rs1.W[1].H[0] * Rs2.W[1].H[0]; + * // SMALBT + * Mres[0][31:0] = Rs1.W[0].H[0] * Rs2.W[0].H[1]; + * Mres[1][31:0] = Rs1.W[1].H[0] * Rs2.W[1].H[1]; + * // SMALTT + * Mres[0][31:0] = Rs1.W[0].H[1] * Rs2.W[0].H[1]; + * Mres[1][31:0] = Rs1.W[1].H[1] * Rs2.W[1].H[1]; + * Rd = Rd + SE64(Mres[0][31:0]) + SE64(Mres[1][31:0]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_SMALTT(long long t, unsigned long a, unsigned long b) +{ + __ASM volatile("smaltt %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.105.3. SMALTT ===== */ + +/* ===== Inline Function Start for 3.106.1. SMALDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_64B_ADDSUB + * \brief SMALDA (Signed Multiply Two Halfs and Two Adds 64-bit) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * SMALDA Rd, Rs1, Rs2 + * SMALXDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then + * adds the two 32-bit results and the 64-bit value of an even/odd pair of registers together. + * * SMALDA: rt pair+ top*top + bottom*bottom (all 32-bit elements) + * * SMALXDA: rt pair+ top*bottom + bottom*top (all 32-bit elements) + * + * **RV32 Description**:\n + * For the `SMALDA` instruction, it multiplies the bottom 16-bit content of Rs1 with the bottom 16-bit + * content of Rs2 and then adds the result to the result of multiplying the top 16-bit content of Rs1 with + * the top 16-bit content of Rs2 with unlimited precision. + * For the `SMALXDA` instruction, it multiplies the top 16-bit content of Rs1 with the bottom 16-bit + * content of Rs2 and then adds the result to the result of multiplying the bottom 16-bit content of Rs1 + * with the top 16-bit content of Rs2 with unlimited precision. + * The result is added to the 64-bit value of an even/odd pair of registers specified by Rd(4,1). The 64- + * bit addition result is written back to the register-pair. The 16-bit values of Rs1 and Rs2, and the 64- + * bit value of the register-pair are treated as signed integers. + * Rd(4,1), i.e., d, determines the even/odd pair group of the two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the operand and the even `2d` + * register of the pair contains the low 32-bit of the operand. + * + * **RV64 Description**:\n + * For the `SMALDA` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2 and then adds the result to the result of + * multiplying the top 16-bit content of the 32-bit elements of Rs1 with the top 16-bit content of the 32- + * bit elements of Rs2 with unlimited precision. + * For the `SMALXDA` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2 and then adds the result to the result of + * multiplying the bottom 16-bit content of the 32-bit elements of Rs1 with the top 16-bit content of the + * 32-bit elements of Rs2 with unlimited precision. + * The results are added to the 64-bit value of Rd. The 64-bit addition result is written back to Rd. The + * 16-bit values of Rs1 and Rs2, and the 64-bit value of Rd are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * RV32: + * // SMALDA + * Mres0[31:0] = (Rs1.H[0] * Rs2.H[0]); + * Mres1[31:0] = (Rs1.H[1] * Rs2.H[1]); + * // SMALXDA + * Mres0[31:0] = (Rs1.H[0] * Rs2.H[1]); + * Mres1[31:0] = (Rs1.H[1] * Rs2.H[0]); + * Idx0 = CONCAT(Rd(4,1),1'b0); Idx1 = CONCAT(Rd(4,1),1'b1); + * R[Idx1].R[Idx0] = R[Idx1].R[Idx0] + SE64(Mres0[31:0]) + SE64(Mres1[31:0]); + * RV64: + * // SMALDA + * Mres0[0][31:0] = (Rs1.W[0].H[0] * Rs2.W[0].H[0]); + * Mres1[0][31:0] = (Rs1.W[0].H[1] * Rs2.W[0].H[1]); + * Mres0[1][31:0] = (Rs1.W[1].H[0] * Rs2.W[1].H[0]); + * Mres1[1][31:0] = (Rs1.W[1].H[1] * Rs2.W[1].H[1]); + * // SMALXDA + * Mres0[0][31:0] = (Rs1.W[0].H[0] * Rs2.W[0].H[1]); + * Mres1[0][31:0] = (Rs1.W[0].H[1] * Rs2.W[0].H[0]); + * Mres0[1][31:0] = (Rs1.W[1].H[0] * Rs2.W[1].H[1]); + * Mres1[1][31:0] = (Rs1.W[1].H[1] * Rs2.W[1].H[0]); + * Rd = Rd + SE64(Mres0[0][31:0]) + SE64(Mres1[0][31:0]) + SE64(Mres0[1][31:0]) + + * SE64(Mres1[1][31:0]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_SMALDA(long long t, unsigned long a, unsigned long b) +{ + __ASM volatile("smalda %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.106.1. SMALDA ===== */ + +/* ===== Inline Function Start for 3.106.2. SMALXDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_64B_ADDSUB + * \brief SMALXDA (Signed Crossed Multiply Two Halfs and Two Adds 64-bit) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * SMALDA Rd, Rs1, Rs2 + * SMALXDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then + * adds the two 32-bit results and the 64-bit value of an even/odd pair of registers together. + * * SMALDA: rt pair+ top*top + bottom*bottom (all 32-bit elements) + * * SMALXDA: rt pair+ top*bottom + bottom*top (all 32-bit elements) + * + * **RV32 Description**:\n + * For the `SMALDA` instruction, it multiplies the bottom 16-bit content of Rs1 with the bottom 16-bit + * content of Rs2 and then adds the result to the result of multiplying the top 16-bit content of Rs1 with + * the top 16-bit content of Rs2 with unlimited precision. + * For the `SMALXDA` instruction, it multiplies the top 16-bit content of Rs1 with the bottom 16-bit + * content of Rs2 and then adds the result to the result of multiplying the bottom 16-bit content of Rs1 + * with the top 16-bit content of Rs2 with unlimited precision. + * The result is added to the 64-bit value of an even/odd pair of registers specified by Rd(4,1). The 64- + * bit addition result is written back to the register-pair. The 16-bit values of Rs1 and Rs2, and the 64- + * bit value of the register-pair are treated as signed integers. + * Rd(4,1), i.e., d, determines the even/odd pair group of the two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the operand and the even `2d` + * register of the pair contains the low 32-bit of the operand. + * + * **RV64 Description**:\n + * For the `SMALDA` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2 and then adds the result to the result of + * multiplying the top 16-bit content of the 32-bit elements of Rs1 with the top 16-bit content of the 32- + * bit elements of Rs2 with unlimited precision. + * For the `SMALXDA` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2 and then adds the result to the result of + * multiplying the bottom 16-bit content of the 32-bit elements of Rs1 with the top 16-bit content of the + * 32-bit elements of Rs2 with unlimited precision. + * The results are added to the 64-bit value of Rd. The 64-bit addition result is written back to Rd. The + * 16-bit values of Rs1 and Rs2, and the 64-bit value of Rd are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * RV32: + * // SMALDA + * Mres0[31:0] = (Rs1.H[0] * Rs2.H[0]); + * Mres1[31:0] = (Rs1.H[1] * Rs2.H[1]); + * // SMALXDA + * Mres0[31:0] = (Rs1.H[0] * Rs2.H[1]); + * Mres1[31:0] = (Rs1.H[1] * Rs2.H[0]); + * Idx0 = CONCAT(Rd(4,1),1'b0); Idx1 = CONCAT(Rd(4,1),1'b1); + * R[Idx1].R[Idx0] = R[Idx1].R[Idx0] + SE64(Mres0[31:0]) + SE64(Mres1[31:0]); + * RV64: + * // SMALDA + * Mres0[0][31:0] = (Rs1.W[0].H[0] * Rs2.W[0].H[0]); + * Mres1[0][31:0] = (Rs1.W[0].H[1] * Rs2.W[0].H[1]); + * Mres0[1][31:0] = (Rs1.W[1].H[0] * Rs2.W[1].H[0]); + * Mres1[1][31:0] = (Rs1.W[1].H[1] * Rs2.W[1].H[1]); + * // SMALXDA + * Mres0[0][31:0] = (Rs1.W[0].H[0] * Rs2.W[0].H[1]); + * Mres1[0][31:0] = (Rs1.W[0].H[1] * Rs2.W[0].H[0]); + * Mres0[1][31:0] = (Rs1.W[1].H[0] * Rs2.W[1].H[1]); + * Mres1[1][31:0] = (Rs1.W[1].H[1] * Rs2.W[1].H[0]); + * Rd = Rd + SE64(Mres0[0][31:0]) + SE64(Mres1[0][31:0]) + SE64(Mres0[1][31:0]) + + * SE64(Mres1[1][31:0]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_SMALXDA(long long t, unsigned long a, unsigned long b) +{ + __ASM volatile("smalxda %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.106.2. SMALXDA ===== */ + +/* ===== Inline Function Start for 3.107.1. SMALDS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_64B_ADDSUB + * \brief SMALDS (Signed Multiply Two Halfs & Subtract & Add 64-bit) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * SMALDS Rd, Rs1, Rs2 + * SMALDRS Rd, Rs1, Rs2 + * SMALXDS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then + * perform a subtraction operation between the two 32-bit results. Then add the subtraction result to + * the 64-bit value of an even/odd pair of registers (RV32) or a register (RV64). The addition result is + * written back to the register-pair. + * * SMALDS: rt pair + (top*top - bottom*bottom) (all 32-bit elements) + * * SMALDRS: rt pair + (bottom*bottom - top*top) (all 32-bit elements) + * * SMALXDS: rt pair + (top*bottom - bottom*top) (all 32-bit elements) + * + * **RV32 Description**:\n + * For the `SMALDS` instruction, it multiplies the bottom 16-bit content of Rs1 with the bottom 16-bit + * content of Rs2 and then subtracts the result from the result of multiplying the top 16-bit content of + * Rs1 with the top 16-bit content of Rs2. + * For the `SMALDRS` instruction, it multiplies the top 16-bit content of Rs1 with the top 16-bit content + * of Rs2 and then subtracts the result from the result of multiplying the bottom 16-bit content of Rs1 + * with the bottom 16-bit content of Rs2. + * For the `SMALXDS` instruction, it multiplies the bottom 16-bit content of Rs1 with the top 16-bit + * content of Rs2 and then subtracts the result from the result of multiplying the top 16-bit content of + * Rs1 with the bottom 16-bit content of Rs2. + * The subtraction result is then added to the 64-bit value of an even/odd pair of registers specified by + * Rd(4,1). The 64-bit addition result is written back to the register-pair. The 16-bit values of Rs1 and + * Rs2, and the 64-bit value of the register-pair are treated as signed integers. + * Rd(4,1), i.e., d, determines the even/odd pair group of the two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the operand and the even `2d` + * register of the pair contains the low 32-bit of the operand. + * + * **RV64 Description**:\n + * For the `SMALDS` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the + * result of multiplying the top 16-bit content of the 32-bit elements of Rs1 with the top 16-bit content + * of the 32-bit elements of Rs2. + * For the `SMALDRS` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 with + * the top 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the result of + * multiplying the bottom 16-bit content of the 32-bit elements of Rs1 with the bottom 16-bit content of + * the 32-bit elements of Rs2. + * For the `SMALXDS` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the + * result of multiplying the top 16-bit content of the 32-bit elements of Rs1 with the bottom 16-bit + * content of the 32-bit elements of Rs2. + * The subtraction results are then added to the 64-bit value of Rd. The 64-bit addition result is written + * back to Rd. The 16-bit values of Rs1 and Rs2, and the 64-bit value of Rd are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * * RV32: + * Mres[31:0] = (Rs1.H[1] * Rs2.H[1]) - (Rs1.H[0] * Rs2.H[0]); // SMALDS + * Mres[31:0] = (Rs1.H[0] * Rs2.H[0]) - (Rs1.H[1] * Rs2.H[1]); // SMALDRS + * Mres[31:0] = (Rs1.H[1] * Rs2.H[0]) - (Rs1.H[0] * Rs2.H[1]); // SMALXDS + * Idx0 = CONCAT(Rd(4,1),1'b0); Idx1 = CONCAT(Rd(4,1),1'b1); + * R[Idx1].R[Idx0] = R[Idx1].R[Idx0] + SE64(Mres[31:0]); + * * RV64: + * // SMALDS + * Mres[0][31:0] = (Rs1.W[0].H[1] * Rs2.W[0].H[1]) - (Rs1.W[0].H[0] * Rs2.W[0].H[0]); + * Mres[1][31:0] = (Rs1.W[1].H[1] * Rs2.W[0].H[1]) - (Rs1.W[1].H[0] * Rs2.W[1].H[0]); + * // SMALDRS + * Mres[0][31:0] = (Rs1.W[0].H[0] * Rs2.W[0].H[0]) - (Rs1.W[0].H[1] * Rs2.W[0].H[1]); + * Mres[1][31:0] = (Rs1.W[1].H[0] * Rs2.W[0].H[0]) - (Rs1.W[1].H[1] * Rs2.W[1].H[1]); + * // SMALXDS + * Mres[0][31:0] = (Rs1.W[0].H[1] * Rs2.W[0].H[0]) - (Rs1.W[0].H[0] * Rs2.W[0].H[1]); + * Mres[1][31:0] = (Rs1.W[1].H[1] * Rs2.W[0].H[0]) - (Rs1.W[1].H[0] * Rs2.W[1].H[1]); + * Rd = Rd + SE64(Mres[0][31:0]) + SE64(Mres[1][31:0]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_SMALDS(long long t, unsigned long a, unsigned long b) +{ + __ASM volatile("smalds %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.107.1. SMALDS ===== */ + +/* ===== Inline Function Start for 3.107.2. SMALDRS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_64B_ADDSUB + * \brief SMALDRS (Signed Multiply Two Halfs & Reverse Subtract & Add 64- bit) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * SMALDS Rd, Rs1, Rs2 + * SMALDRS Rd, Rs1, Rs2 + * SMALXDS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then + * perform a subtraction operation between the two 32-bit results. Then add the subtraction result to + * the 64-bit value of an even/odd pair of registers (RV32) or a register (RV64). The addition result is + * written back to the register-pair. + * * SMALDS: rt pair + (top*top - bottom*bottom) (all 32-bit elements) + * * SMALDRS: rt pair + (bottom*bottom - top*top) (all 32-bit elements) + * * SMALXDS: rt pair + (top*bottom - bottom*top) (all 32-bit elements) + * + * **RV32 Description**:\n + * For the `SMALDS` instruction, it multiplies the bottom 16-bit content of Rs1 with the bottom 16-bit + * content of Rs2 and then subtracts the result from the result of multiplying the top 16-bit content of + * Rs1 with the top 16-bit content of Rs2. + * For the `SMALDRS` instruction, it multiplies the top 16-bit content of Rs1 with the top 16-bit content + * of Rs2 and then subtracts the result from the result of multiplying the bottom 16-bit content of Rs1 + * with the bottom 16-bit content of Rs2. + * For the `SMALXDS` instruction, it multiplies the bottom 16-bit content of Rs1 with the top 16-bit + * content of Rs2 and then subtracts the result from the result of multiplying the top 16-bit content of + * Rs1 with the bottom 16-bit content of Rs2. + * The subtraction result is then added to the 64-bit value of an even/odd pair of registers specified by + * Rd(4,1). The 64-bit addition result is written back to the register-pair. The 16-bit values of Rs1 and + * Rs2, and the 64-bit value of the register-pair are treated as signed integers. + * Rd(4,1), i.e., d, determines the even/odd pair group of the two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the operand and the even `2d` + * register of the pair contains the low 32-bit of the operand. + * + * **RV64 Description**:\n + * For the `SMALDS` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the + * result of multiplying the top 16-bit content of the 32-bit elements of Rs1 with the top 16-bit content + * of the 32-bit elements of Rs2. + * For the `SMALDRS` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 with + * the top 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the result of + * multiplying the bottom 16-bit content of the 32-bit elements of Rs1 with the bottom 16-bit content of + * the 32-bit elements of Rs2. + * For the `SMALXDS` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the + * result of multiplying the top 16-bit content of the 32-bit elements of Rs1 with the bottom 16-bit + * content of the 32-bit elements of Rs2. + * The subtraction results are then added to the 64-bit value of Rd. The 64-bit addition result is written + * back to Rd. The 16-bit values of Rs1 and Rs2, and the 64-bit value of Rd are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * * RV32: + * Mres[31:0] = (Rs1.H[1] * Rs2.H[1]) - (Rs1.H[0] * Rs2.H[0]); // SMALDS + * Mres[31:0] = (Rs1.H[0] * Rs2.H[0]) - (Rs1.H[1] * Rs2.H[1]); // SMALDRS + * Mres[31:0] = (Rs1.H[1] * Rs2.H[0]) - (Rs1.H[0] * Rs2.H[1]); // SMALXDS + * Idx0 = CONCAT(Rd(4,1),1'b0); Idx1 = CONCAT(Rd(4,1),1'b1); + * R[Idx1].R[Idx0] = R[Idx1].R[Idx0] + SE64(Mres[31:0]); + * * RV64: + * // SMALDS + * Mres[0][31:0] = (Rs1.W[0].H[1] * Rs2.W[0].H[1]) - (Rs1.W[0].H[0] * Rs2.W[0].H[0]); + * Mres[1][31:0] = (Rs1.W[1].H[1] * Rs2.W[0].H[1]) - (Rs1.W[1].H[0] * Rs2.W[1].H[0]); + * // SMALDRS + * Mres[0][31:0] = (Rs1.W[0].H[0] * Rs2.W[0].H[0]) - (Rs1.W[0].H[1] * Rs2.W[0].H[1]); + * Mres[1][31:0] = (Rs1.W[1].H[0] * Rs2.W[0].H[0]) - (Rs1.W[1].H[1] * Rs2.W[1].H[1]); + * // SMALXDS + * Mres[0][31:0] = (Rs1.W[0].H[1] * Rs2.W[0].H[0]) - (Rs1.W[0].H[0] * Rs2.W[0].H[1]); + * Mres[1][31:0] = (Rs1.W[1].H[1] * Rs2.W[0].H[0]) - (Rs1.W[1].H[0] * Rs2.W[1].H[1]); + * Rd = Rd + SE64(Mres[0][31:0]) + SE64(Mres[1][31:0]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_SMALDRS(long long t, unsigned long a, unsigned long b) +{ + __ASM volatile("smaldrs %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.107.2. SMALDRS ===== */ + +/* ===== Inline Function Start for 3.107.3. SMALXDS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_64B_ADDSUB + * \brief SMALXDS (Signed Crossed Multiply Two Halfs & Subtract & Add 64- bit) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * SMALDS Rd, Rs1, Rs2 + * SMALDRS Rd, Rs1, Rs2 + * SMALXDS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then + * perform a subtraction operation between the two 32-bit results. Then add the subtraction result to + * the 64-bit value of an even/odd pair of registers (RV32) or a register (RV64). The addition result is + * written back to the register-pair. + * * SMALDS: rt pair + (top*top - bottom*bottom) (all 32-bit elements) + * * SMALDRS: rt pair + (bottom*bottom - top*top) (all 32-bit elements) + * * SMALXDS: rt pair + (top*bottom - bottom*top) (all 32-bit elements) + * + * **RV32 Description**:\n + * For the `SMALDS` instruction, it multiplies the bottom 16-bit content of Rs1 with the bottom 16-bit + * content of Rs2 and then subtracts the result from the result of multiplying the top 16-bit content of + * Rs1 with the top 16-bit content of Rs2. + * For the `SMALDRS` instruction, it multiplies the top 16-bit content of Rs1 with the top 16-bit content + * of Rs2 and then subtracts the result from the result of multiplying the bottom 16-bit content of Rs1 + * with the bottom 16-bit content of Rs2. + * For the `SMALXDS` instruction, it multiplies the bottom 16-bit content of Rs1 with the top 16-bit + * content of Rs2 and then subtracts the result from the result of multiplying the top 16-bit content of + * Rs1 with the bottom 16-bit content of Rs2. + * The subtraction result is then added to the 64-bit value of an even/odd pair of registers specified by + * Rd(4,1). The 64-bit addition result is written back to the register-pair. The 16-bit values of Rs1 and + * Rs2, and the 64-bit value of the register-pair are treated as signed integers. + * Rd(4,1), i.e., d, determines the even/odd pair group of the two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the operand and the even `2d` + * register of the pair contains the low 32-bit of the operand. + * + * **RV64 Description**:\n + * For the `SMALDS` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the + * result of multiplying the top 16-bit content of the 32-bit elements of Rs1 with the top 16-bit content + * of the 32-bit elements of Rs2. + * For the `SMALDRS` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 with + * the top 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the result of + * multiplying the bottom 16-bit content of the 32-bit elements of Rs1 with the bottom 16-bit content of + * the 32-bit elements of Rs2. + * For the `SMALXDS` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the + * result of multiplying the top 16-bit content of the 32-bit elements of Rs1 with the bottom 16-bit + * content of the 32-bit elements of Rs2. + * The subtraction results are then added to the 64-bit value of Rd. The 64-bit addition result is written + * back to Rd. The 16-bit values of Rs1 and Rs2, and the 64-bit value of Rd are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * * RV32: + * Mres[31:0] = (Rs1.H[1] * Rs2.H[1]) - (Rs1.H[0] * Rs2.H[0]); // SMALDS + * Mres[31:0] = (Rs1.H[0] * Rs2.H[0]) - (Rs1.H[1] * Rs2.H[1]); // SMALDRS + * Mres[31:0] = (Rs1.H[1] * Rs2.H[0]) - (Rs1.H[0] * Rs2.H[1]); // SMALXDS + * Idx0 = CONCAT(Rd(4,1),1'b0); Idx1 = CONCAT(Rd(4,1),1'b1); + * R[Idx1].R[Idx0] = R[Idx1].R[Idx0] + SE64(Mres[31:0]); + * * RV64: + * // SMALDS + * Mres[0][31:0] = (Rs1.W[0].H[1] * Rs2.W[0].H[1]) - (Rs1.W[0].H[0] * Rs2.W[0].H[0]); + * Mres[1][31:0] = (Rs1.W[1].H[1] * Rs2.W[0].H[1]) - (Rs1.W[1].H[0] * Rs2.W[1].H[0]); + * // SMALDRS + * Mres[0][31:0] = (Rs1.W[0].H[0] * Rs2.W[0].H[0]) - (Rs1.W[0].H[1] * Rs2.W[0].H[1]); + * Mres[1][31:0] = (Rs1.W[1].H[0] * Rs2.W[0].H[0]) - (Rs1.W[1].H[1] * Rs2.W[1].H[1]); + * // SMALXDS + * Mres[0][31:0] = (Rs1.W[0].H[1] * Rs2.W[0].H[0]) - (Rs1.W[0].H[0] * Rs2.W[0].H[1]); + * Mres[1][31:0] = (Rs1.W[1].H[1] * Rs2.W[0].H[0]) - (Rs1.W[1].H[0] * Rs2.W[1].H[1]); + * Rd = Rd + SE64(Mres[0][31:0]) + SE64(Mres[1][31:0]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_SMALXDS(long long t, unsigned long a, unsigned long b) +{ + __ASM volatile("smalxds %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.107.3. SMALXDS ===== */ + +/* ===== Inline Function Start for 3.108. SMAR64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_32B_MULT_64B_ADDSUB + * \brief SMAR64 (Signed Multiply and Add to 64-Bit Data) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * SMAR64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the 32-bit signed elements in two registers and add the 64-bit multiplication + * result to the 64-bit signed data of a pair of registers (RV32) or a register (RV64). The result is written + * back to the pair of registers (RV32) or a register (RV64). + * + * **RV32 Description**:\n + * This instruction multiplies the 32-bit signed data of Rs1 with that of Rs2. It adds + * the 64-bit multiplication result to the 64-bit signed data of an even/odd pair of registers specified by + * Rd(4,1). The addition result is written back to the even/odd pair of registers specified by Rd(4,1). + * Rx(4,1), i.e., d, determines the even/odd pair group of two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * + * **RV64 Description**:\n + * This instruction multiplies the 32-bit signed elements of Rs1 with that of Rs2. It + * adds the 64-bit multiplication results to the 64-bit signed data of Rd. The addition result is written + * back to Rd. + * + * **Operations**:\n + * ~~~ + * * RV32: + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * R[t_H].R[t_L] = R[t_H].R[t_L] + (Rs1 * Rs2); + * * RV64: + * Rd = Rd + (Rs1.W[0] * Rs2.W[0]) + (Rs1.W[1] * Rs2.W[1]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a long type of value stored in a + * \param [in] b long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_SMAR64(long long t, long a, long b) +{ + __ASM volatile("smar64 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.108. SMAR64 ===== */ + +/* ===== Inline Function Start for 3.109. SMAQA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_8B_MULT_32B_ADD + * \brief SMAQA (Signed Multiply Four Bytes with 32-bit Adds) + * \details + * **Type**: Partial-SIMD (Reduction) + * + * **Syntax**:\n + * ~~~ + * SMAQA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do four signed 8-bit multiplications from 32-bit chunks of two registers; and then adds + * the four 16-bit results and the content of corresponding 32-bit chunks of a third register together. + * + * **Description**:\n + * This instruction multiplies the four signed 8-bit elements of 32-bit chunks of Rs1 with the four + * signed 8-bit elements of 32-bit chunks of Rs2 and then adds the four results together with the signed + * content of the corresponding 32-bit chunks of Rd. The final results are written back to the + * corresponding 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rd.W[x] + + * (Rs1.W[x].B[3] s* Rs2.W[x].B[3]) + (Rs1.W[x].B[2] s* Rs2.W[x].B[2]) + + * (Rs1.W[x].B[1] s* Rs2.W[x].B[1]) + (Rs1.W[x].B[0] s* Rs2.W[x].B[0]); + * Rd.W[x] = res[x]; + * for RV32: x=0, + * for RV64: x=1,0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMAQA(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("smaqa %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.109. SMAQA ===== */ + +/* ===== Inline Function Start for 3.110. SMAQA.SU ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_8B_MULT_32B_ADD + * \brief SMAQA.SU (Signed and Unsigned Multiply Four Bytes with 32-bit Adds) + * \details + * **Type**: Partial-SIMD (Reduction) + * + * **Syntax**:\n + * ~~~ + * SMAQA.SU Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do four `signed x unsigned` 8-bit multiplications from 32-bit chunks of two registers; and + * then adds the four 16-bit results and the content of corresponding 32-bit chunks of a third register + * together. + * + * **Description**:\n + * This instruction multiplies the four signed 8-bit elements of 32-bit chunks of Rs1 with the four + * unsigned 8-bit elements of 32-bit chunks of Rs2 and then adds the four results together with the + * signed content of the corresponding 32-bit chunks of Rd. The final results are written back to the + * corresponding 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rd.W[x] + + * (Rs1.W[x].B[3] su* Rs2.W[x].B[3]) + (Rs1.W[x].B[2] su* Rs2.W[x].B[2]) + + * (Rs1.W[x].B[1] su* Rs2.W[x].B[1]) + (Rs1.W[x].B[0] su* Rs2.W[x].B[0]); + * Rd.W[x] = res[x]; + * for RV32: x=0, + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMAQA_SU(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("smaqa.su %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.110. SMAQA.SU ===== */ + +/* ===== Inline Function Start for 3.111. SMAX8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_MISC + * \brief SMAX8 (SIMD 8-bit Signed Maximum) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMAX8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit signed integer elements finding maximum operations simultaneously. + * + * **Description**:\n + * This instruction compares the 8-bit signed integer elements in Rs1 with the 8-bit + * signed integer elements in Rs2 and selects the numbers that is greater than the other one. The + * selected results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.B[x] = (Rs1.B[x] > Rs2.B[x])? Rs1.B[x] : Rs2.B[x]; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SMAX8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("smax8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.111. SMAX8 ===== */ + +/* ===== Inline Function Start for 3.112. SMAX16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_MISC + * \brief SMAX16 (SIMD 16-bit Signed Maximum) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMAX16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer elements finding maximum operations simultaneously. + * + * **Description**:\n + * This instruction compares the 16-bit signed integer elements in Rs1 with the 16-bit + * signed integer elements in Rs2 and selects the numbers that is greater than the other one. The + * selected results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = (Rs1.H[x] > Rs2.H[x])? Rs1.H[x] : Rs2.H[x]; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SMAX16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("smax16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.112. SMAX16 ===== */ + +/* ===== Inline Function Start for 3.113.1. SMBB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief SMBB16 (SIMD Signed Multiply Bottom Half & Bottom Half) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMBB16 Rd, Rs1, Rs2 + * SMBT16 Rd, Rs1, Rs2 + * SMTT16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 16-bit content of the 32-bit elements of a register with the signed 16- + * bit content of the 32-bit elements of another register and write the result to a third register. + * * SMBB16: W[x].bottom*W[x].bottom + * * SMBT16: W[x].bottom *W[x].top + * * SMTT16: W[x].top * W[x].top + * + * **Description**:\n + * For the `SMBB16` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2. + * For the `SMBT16` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2. + * For the `SMTT16` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 with + * the top 16-bit content of the 32-bit elements of Rs2. + * The multiplication results are written to Rd. The 16-bit contents of Rs1 and Rs2 are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = Rs1.W[x].H[0] * Rs2.W[x].H[0]; // SMBB16 + * Rd.W[x] = Rs1.W[x].H[0] * Rs2.W[x].H[1]; // SMBT16 + * Rd.W[x] = Rs1.W[x].H[1] * Rs2.W[x].H[1]; // SMTT16 + * for RV32: x=0, + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMBB16(unsigned long a, unsigned long b) +{ + long result; + __ASM volatile("smbb16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.113.1. SMBB16 ===== */ + +/* ===== Inline Function Start for 3.113.2. SMBT16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief SMBT16 (SIMD Signed Multiply Bottom Half & Top Half) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMBB16 Rd, Rs1, Rs2 + * SMBT16 Rd, Rs1, Rs2 + * SMTT16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 16-bit content of the 32-bit elements of a register with the signed 16- + * bit content of the 32-bit elements of another register and write the result to a third register. + * * SMBB16: W[x].bottom*W[x].bottom + * * SMBT16: W[x].bottom *W[x].top + * * SMTT16: W[x].top * W[x].top + * + * **Description**:\n + * For the `SMBB16` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2. + * For the `SMBT16` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2. + * For the `SMTT16` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 with + * the top 16-bit content of the 32-bit elements of Rs2. + * The multiplication results are written to Rd. The 16-bit contents of Rs1 and Rs2 are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = Rs1.W[x].H[0] * Rs2.W[x].H[0]; // SMBB16 + * Rd.W[x] = Rs1.W[x].H[0] * Rs2.W[x].H[1]; // SMBT16 + * Rd.W[x] = Rs1.W[x].H[1] * Rs2.W[x].H[1]; // SMTT16 + * for RV32: x=0, + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMBT16(unsigned long a, unsigned long b) +{ + long result; + __ASM volatile("smbt16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.113.2. SMBT16 ===== */ + +/* ===== Inline Function Start for 3.113.3. SMTT16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief SMTT16 (SIMD Signed Multiply Top Half & Top Half) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMBB16 Rd, Rs1, Rs2 + * SMBT16 Rd, Rs1, Rs2 + * SMTT16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 16-bit content of the 32-bit elements of a register with the signed 16- + * bit content of the 32-bit elements of another register and write the result to a third register. + * * SMBB16: W[x].bottom*W[x].bottom + * * SMBT16: W[x].bottom *W[x].top + * * SMTT16: W[x].top * W[x].top + * + * **Description**:\n + * For the `SMBB16` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2. + * For the `SMBT16` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2. + * For the `SMTT16` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 with + * the top 16-bit content of the 32-bit elements of Rs2. + * The multiplication results are written to Rd. The 16-bit contents of Rs1 and Rs2 are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = Rs1.W[x].H[0] * Rs2.W[x].H[0]; // SMBB16 + * Rd.W[x] = Rs1.W[x].H[0] * Rs2.W[x].H[1]; // SMBT16 + * Rd.W[x] = Rs1.W[x].H[1] * Rs2.W[x].H[1]; // SMTT16 + * for RV32: x=0, + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMTT16(unsigned long a, unsigned long b) +{ + long result; + __ASM volatile("smtt16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.113.3. SMTT16 ===== */ + +/* ===== Inline Function Start for 3.114.1. SMDS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief SMDS (SIMD Signed Multiply Two Halfs and Subtract) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMDS Rd, Rs1, Rs2 + * SMDRS Rd, Rs1, Rs2 + * SMXDS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then + * perform a subtraction operation between the two 32-bit results. + * * SMDS: top*top - bottom*bottom (per 32-bit element) + * * SMDRS: bottom*bottom - top*top (per 32-bit element) + * * SMXDS: top*bottom - bottom*top (per 32-bit element) + * + * **Description**:\n + * For the `SMDS` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 with + * the bottom 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the result + * of multiplying the top 16-bit content of the 32-bit elements of Rs1 with the top 16-bit content of the + * 32-bit elements of Rs2. + * For the `SMDRS` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 with + * the top 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the result of + * multiplying the bottom 16-bit content of the 32-bit elements of Rs1 with the bottom 16-bit content of + * the 32-bit elements of Rs2. + * For the `SMXDS` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the + * result of multiplying the top 16-bit content of the 32-bit elements of Rs1 with the bottom 16-bit + * content of the 32-bit elements of Rs2. + * The subtraction result is written to the corresponding 32-bit element of Rd. The 16-bit contents of + * multiplication are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * * SMDS: + * Rd.W[x] = (Rs1.W[x].H[1] * Rs2.W[x].H[1]) - (Rs1.W[x].H[0] * Rs2.W[x].H[0]); + * * SMDRS: + * Rd.W[x] = (Rs1.W[x].H[0] * Rs2.W[x].H[0]) - (Rs1.W[x].H[1] * Rs2.W[x].H[1]); + * * SMXDS: + * Rd.W[x] = (Rs1.W[x].H[1] * Rs2.W[x].H[0]) - (Rs1.W[x].H[0] * Rs2.W[x].H[1]); + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMDS(unsigned long a, unsigned long b) +{ + long result; + __ASM volatile("smds %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.114.1. SMDS ===== */ + +/* ===== Inline Function Start for 3.114.2. SMDRS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief SMDRS (SIMD Signed Multiply Two Halfs and Reverse Subtract) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMDS Rd, Rs1, Rs2 + * SMDRS Rd, Rs1, Rs2 + * SMXDS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then + * perform a subtraction operation between the two 32-bit results. + * * SMDS: top*top - bottom*bottom (per 32-bit element) + * * SMDRS: bottom*bottom - top*top (per 32-bit element) + * * SMXDS: top*bottom - bottom*top (per 32-bit element) + * + * **Description**:\n + * For the `SMDS` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 with + * the bottom 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the result + * of multiplying the top 16-bit content of the 32-bit elements of Rs1 with the top 16-bit content of the + * 32-bit elements of Rs2. + * For the `SMDRS` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 with + * the top 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the result of + * multiplying the bottom 16-bit content of the 32-bit elements of Rs1 with the bottom 16-bit content of + * the 32-bit elements of Rs2. + * For the `SMXDS` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the + * result of multiplying the top 16-bit content of the 32-bit elements of Rs1 with the bottom 16-bit + * content of the 32-bit elements of Rs2. + * The subtraction result is written to the corresponding 32-bit element of Rd. The 16-bit contents of + * multiplication are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * * SMDS: + * Rd.W[x] = (Rs1.W[x].H[1] * Rs2.W[x].H[1]) - (Rs1.W[x].H[0] * Rs2.W[x].H[0]); + * * SMDRS: + * Rd.W[x] = (Rs1.W[x].H[0] * Rs2.W[x].H[0]) - (Rs1.W[x].H[1] * Rs2.W[x].H[1]); + * * SMXDS: + * Rd.W[x] = (Rs1.W[x].H[1] * Rs2.W[x].H[0]) - (Rs1.W[x].H[0] * Rs2.W[x].H[1]); + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMDRS(unsigned long a, unsigned long b) +{ + long result; + __ASM volatile("smdrs %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.114.2. SMDRS ===== */ + +/* ===== Inline Function Start for 3.114.3. SMXDS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief SMXDS (SIMD Signed Crossed Multiply Two Halfs and Subtract) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMDS Rd, Rs1, Rs2 + * SMDRS Rd, Rs1, Rs2 + * SMXDS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then + * perform a subtraction operation between the two 32-bit results. + * * SMDS: top*top - bottom*bottom (per 32-bit element) + * * SMDRS: bottom*bottom - top*top (per 32-bit element) + * * SMXDS: top*bottom - bottom*top (per 32-bit element) + * + * **Description**:\n + * For the `SMDS` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 with + * the bottom 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the result + * of multiplying the top 16-bit content of the 32-bit elements of Rs1 with the top 16-bit content of the + * 32-bit elements of Rs2. + * For the `SMDRS` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 with + * the top 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the result of + * multiplying the bottom 16-bit content of the 32-bit elements of Rs1 with the bottom 16-bit content of + * the 32-bit elements of Rs2. + * For the `SMXDS` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the + * result of multiplying the top 16-bit content of the 32-bit elements of Rs1 with the bottom 16-bit + * content of the 32-bit elements of Rs2. + * The subtraction result is written to the corresponding 32-bit element of Rd. The 16-bit contents of + * multiplication are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * * SMDS: + * Rd.W[x] = (Rs1.W[x].H[1] * Rs2.W[x].H[1]) - (Rs1.W[x].H[0] * Rs2.W[x].H[0]); + * * SMDRS: + * Rd.W[x] = (Rs1.W[x].H[0] * Rs2.W[x].H[0]) - (Rs1.W[x].H[1] * Rs2.W[x].H[1]); + * * SMXDS: + * Rd.W[x] = (Rs1.W[x].H[1] * Rs2.W[x].H[0]) - (Rs1.W[x].H[0] * Rs2.W[x].H[1]); + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMXDS(unsigned long a, unsigned long b) +{ + long result; + __ASM volatile("smxds %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.114.3. SMXDS ===== */ + +/* ===== Inline Function Start for 3.115. SMIN8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_MISC + * \brief SMIN8 (SIMD 8-bit Signed Minimum) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMIN8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit signed integer elements finding minimum operations simultaneously. + * + * **Description**:\n + * This instruction compares the 8-bit signed integer elements in Rs1 with the 8-bit + * signed integer elements in Rs2 and selects the numbers that is less than the other one. The selected + * results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.B[x] = (Rs1.B[x] < Rs2.B[x])? Rs1.B[x] : Rs2.B[x]; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SMIN8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("smin8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.115. SMIN8 ===== */ + +/* ===== Inline Function Start for 3.116. SMIN16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_MISC + * \brief SMIN16 (SIMD 16-bit Signed Minimum) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMIN16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer elements finding minimum operations simultaneously. + * + * **Description**:\n + * This instruction compares the 16-bit signed integer elements in Rs1 with the 16-bit + * signed integer elements in Rs2 and selects the numbers that is less than the other one. The selected + * results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = (Rs1.H[x] < Rs2.H[x])? Rs1.H[x] : Rs2.H[x]; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SMIN16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("smin16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.116. SMIN16 ===== */ + +/* ===== Inline Function Start for 3.117.1. SMMUL ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X32_MAC + * \brief SMMUL (SIMD MSW Signed Multiply Word) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMMUL Rd, Rs1, Rs2 + * SMMUL.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the 32-bit signed integer elements of two registers and write the most significant + * 32-bit results to the corresponding 32-bit elements of a register. The `.u` form performs an + * additional rounding up operation on the multiplication results before taking the most significant + * 32-bit part of the results. + * + * **Description**:\n + * This instruction multiplies the 32-bit elements of Rs1 with the 32-bit elements of Rs2 and writes the + * most significant 32-bit multiplication results to the corresponding 32-bit elements of Rd. The 32-bit + * elements of Rs1 and Rs2 are treated as signed integers. The `.u` form of the instruction rounds up + * the most significant 32-bit of the 64-bit multiplication results by adding a 1 to bit 31 of the results. + * * For `smmul/RV32` instruction, it is an alias to `mulh/RV32` instruction. + * + * **Operations**:\n + * ~~~ + * Mres[x][63:0] = Rs1.W[x] * Rs2.W[x]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][63:31] + 1; + * Rd.W[x] = Round[x][32:1]; + * } else { + * Rd.W[x] = Mres[x][63:32]; + * } + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMMUL(long a, long b) +{ + long result; + __ASM volatile("smmul %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.117.1. SMMUL ===== */ + +/* ===== Inline Function Start for 3.117.2. SMMUL.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X32_MAC + * \brief SMMUL.u (SIMD MSW Signed Multiply Word with Rounding) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMMUL Rd, Rs1, Rs2 + * SMMUL.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the 32-bit signed integer elements of two registers and write the most significant + * 32-bit results to the corresponding 32-bit elements of a register. The `.u` form performs an + * additional rounding up operation on the multiplication results before taking the most significant + * 32-bit part of the results. + * + * **Description**:\n + * This instruction multiplies the 32-bit elements of Rs1 with the 32-bit elements of Rs2 and writes the + * most significant 32-bit multiplication results to the corresponding 32-bit elements of Rd. The 32-bit + * elements of Rs1 and Rs2 are treated as signed integers. The `.u` form of the instruction rounds up + * the most significant 32-bit of the 64-bit multiplication results by adding a 1 to bit 31 of the results. + * * For `smmul/RV32` instruction, it is an alias to `mulh/RV32` instruction. + * + * **Operations**:\n + * ~~~ + * Mres[x][63:0] = Rs1.W[x] * Rs2.W[x]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][63:31] + 1; + * Rd.W[x] = Round[x][32:1]; + * } else { + * Rd.W[x] = Mres[x][63:32]; + * } + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMMUL_U(long a, long b) +{ + long result; + __ASM volatile("smmul.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.117.2. SMMUL.u ===== */ + +/* ===== Inline Function Start for 3.118.1. SMMWB ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC + * \brief SMMWB (SIMD MSW Signed Multiply Word and Bottom Half) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMMWB Rd, Rs1, Rs2 + * SMMWB.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of one register and the bottom 16-bit of the + * corresponding 32-bit elements of another register, and write the most significant 32-bit results to + * the corresponding 32-bit elements of a register. The `.u` form rounds up the results from the most + * significant discarded bit. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit elements of Rs1 with the signed bottom 16-bit content + * of the corresponding 32-bit elements of Rs2 and writes the most significant 32-bit multiplication + * results to the corresponding 32-bit elements of Rd. The `.u` form of the instruction rounds up the + * most significant 32-bit of the 48-bit multiplication results by adding a 1 to bit 15 of the results. + * + * **Operations**:\n + * ~~~ + * Mres[x][47:0] = Rs1.W[x] * Rs2.W[x].H[0]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][47:15] + 1; + * Rd.W[x] = Round[x][32:1]; + * } else { + * Rd.W[x] = Mres[x][47:16]; + * } + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMMWB(long a, unsigned long b) +{ + long result; + __ASM volatile("smmwb %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.118.1. SMMWB ===== */ + +/* ===== Inline Function Start for 3.118.2. SMMWB.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC + * \brief SMMWB.u (SIMD MSW Signed Multiply Word and Bottom Half with Rounding) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMMWB Rd, Rs1, Rs2 + * SMMWB.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of one register and the bottom 16-bit of the + * corresponding 32-bit elements of another register, and write the most significant 32-bit results to + * the corresponding 32-bit elements of a register. The `.u` form rounds up the results from the most + * significant discarded bit. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit elements of Rs1 with the signed bottom 16-bit content + * of the corresponding 32-bit elements of Rs2 and writes the most significant 32-bit multiplication + * results to the corresponding 32-bit elements of Rd. The `.u` form of the instruction rounds up the + * most significant 32-bit of the 48-bit multiplication results by adding a 1 to bit 15 of the results. + * + * **Operations**:\n + * ~~~ + * Mres[x][47:0] = Rs1.W[x] * Rs2.W[x].H[0]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][47:15] + 1; + * Rd.W[x] = Round[x][32:1]; + * } else { + * Rd.W[x] = Mres[x][47:16]; + * } + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMMWB_U(long a, unsigned long b) +{ + long result; + __ASM volatile("smmwb.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.118.2. SMMWB.u ===== */ + +/* ===== Inline Function Start for 3.119.1. SMMWT ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC + * \brief SMMWT (SIMD MSW Signed Multiply Word and Top Half) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMMWT Rd, Rs1, Rs2 + * SMMWT.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of one register and the top 16-bit of the + * corresponding 32-bit elements of another register, and write the most significant 32-bit results to + * the corresponding 32-bit elements of a register. The `.u` form rounds up the results from the most + * significant discarded bit. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit elements of Rs1 with the top signed 16-bit content of + * the corresponding 32-bit elements of Rs2 and writes the most significant 32-bit multiplication + * results to the corresponding 32-bit elements of Rd. The `.u` form of the instruction rounds up the + * most significant 32-bit of the 48-bit multiplication results by adding a 1 to bit 15 of the results. + * + * **Operations**:\n + * ~~~ + * Mres[x][47:0] = Rs1.W[x] * Rs2.W[x].H[1]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][47:15] + 1; + * Rd.W[x] = Round[x][32:1]; + * } else { + * Rd.W[x] = Mres[x][47:16]; + * } + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMMWT(long a, unsigned long b) +{ + long result; + __ASM volatile("smmwt %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.119.1. SMMWT ===== */ + +/* ===== Inline Function Start for 3.119.2. SMMWT.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC + * \brief SMMWT.u (SIMD MSW Signed Multiply Word and Top Half with Rounding) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMMWT Rd, Rs1, Rs2 + * SMMWT.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of one register and the top 16-bit of the + * corresponding 32-bit elements of another register, and write the most significant 32-bit results to + * the corresponding 32-bit elements of a register. The `.u` form rounds up the results from the most + * significant discarded bit. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit elements of Rs1 with the top signed 16-bit content of + * the corresponding 32-bit elements of Rs2 and writes the most significant 32-bit multiplication + * results to the corresponding 32-bit elements of Rd. The `.u` form of the instruction rounds up the + * most significant 32-bit of the 48-bit multiplication results by adding a 1 to bit 15 of the results. + * + * **Operations**:\n + * ~~~ + * Mres[x][47:0] = Rs1.W[x] * Rs2.W[x].H[1]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][47:15] + 1; + * Rd.W[x] = Round[x][32:1]; + * } else { + * Rd.W[x] = Mres[x][47:16]; + * } + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMMWT_U(long a, unsigned long b) +{ + long result; + __ASM volatile("smmwt.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.119.2. SMMWT.u ===== */ + +/* ===== Inline Function Start for 3.120.1. SMSLDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_64B_ADDSUB + * \brief SMSLDA (Signed Multiply Two Halfs & Add & Subtract 64-bit) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * SMSLDA Rd, Rs1, Rs2 + * SMSLXDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then + * subtracts the two 32-bit results from the 64-bit value of an even/odd pair of registers (RV32) or a + * register (RV64). The subtraction result is written back to the register-pair. + * * SMSLDA: rd pair - top*top - bottom*bottom (all 32-bit elements) + * * SMSLXDA: rd pair - top*bottom - bottom*top (all 32-bit elements) + * + * **RV32 Description**:\n + * For the `SMSLDA` instruction, it multiplies the bottom 16-bit content of Rs1 with the bottom 16-bit + * content Rs2 and multiplies the top 16-bit content of Rs1 with the top 16-bit content of Rs2. + * For the `SMSLXDA` instruction, it multiplies the top 16-bit content of Rs1 with the bottom 16-bit + * content of Rs2 and multiplies the bottom 16-bit content of Rs1 with the top 16-bit content of Rs2. + * The two multiplication results are subtracted from the 64-bit value of an even/odd pair of registers + * specified by Rd(4,1). The 64-bit subtraction result is written back to the register-pair. The 16-bit + * values of Rs1 and Rs2, and the 64-bit value of the register-pair are treated as signed integers. + * Rd(4,1), i.e., d, determines the even/odd pair group of the two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * + * **RV64 Description**:\n + * For the `SMSLDA` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2 and multiplies the top 16-bit content of + * the 32-bit elements of Rs1 with the top 16-bit content of the 32-bit elements of Rs2. + * For the `SMSLXDA` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 with + * the bottom 16-bit content of the 32-bit elements of Rs2 and multiplies the bottom 16-bit content of + * the 32-bit elements of Rs1 with the top 16-bit content of the 32-bit elements of Rs2. + * The four multiplication results are subtracted from the 64-bit value of Rd. The 64-bit subtraction + * result is written back to Rd. The 16-bit values of Rs1 and Rs2, and the 64-bit value of Rd are treated + * as signed integers. + * + * **Operations**:\n + * ~~~ + * * RV32: + * // SMSLDA + * Mres0[31:0] = (Rs1.H[0] * Rs2.H[0]); + * Mres1[31:0] = (Rs1.H[1] * Rs2.H[1]); + * // SMSLXDA + * Mres0[31:0] = (Rs1.H[0] * Rs2.H[1]); + * Mres1[31:0] = (Rs1.H[1] * Rs2.H[0]); + * Idx0 = CONCAT(Rd(4,1),1'b0); Idx1 = CONCAT(Rd(4,1),1'b1); + * R[Idx1].R[Idx0] = R[Idx1].R[Idx0] - SE64(Mres0[31:0]) - SE64(Mres1[31:0]); + * * RV64: + * // SMSLDA + * Mres0[0][31:0] = (Rs1.W[0].H[0] * Rs2.W[0].H[0]); + * Mres1[0][31:0] = (Rs1.W[0].H[1] * Rs2.W[0].H[1]); + * Mres0[1][31:0] = (Rs1.W[1].H[0] * Rs2.W[1].H[0]); + * Mres1[1][31:0] = (Rs1.W[1].H[1] * Rs2.W[1].H[1]); + * // SMSLXDA + * Mres0[0][31:0] = (Rs1.W[0].H[0] * Rs2.W[0].H[1]); + * Mres1[0][31:0] = (Rs1.W[0].H[1] * Rs2.W[0].H[0]); + * Mres0[1][31:0] = (Rs1.W[1].H[0] * Rs2.W[1].H[1]); + * Mres1[1][31:0] = (Rs1.W[1].H[1] * Rs2.W[1].H[0]); + * Rd = Rd - SE64(Mres0[0][31:0]) - SE64(Mres1[0][31:0]) - SE64(Mres0[1][31:0]) - + * SE64(Mres1[1][31:0]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_SMSLDA(long long t, unsigned long a, unsigned long b) +{ + __ASM volatile("smslda %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.120.1. SMSLDA ===== */ + +/* ===== Inline Function Start for 3.120.2. SMSLXDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_64B_ADDSUB + * \brief SMSLXDA (Signed Crossed Multiply Two Halfs & Add & Subtract 64- bit) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * SMSLDA Rd, Rs1, Rs2 + * SMSLXDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then + * subtracts the two 32-bit results from the 64-bit value of an even/odd pair of registers (RV32) or a + * register (RV64). The subtraction result is written back to the register-pair. + * * SMSLDA: rd pair - top*top - bottom*bottom (all 32-bit elements) + * * SMSLXDA: rd pair - top*bottom - bottom*top (all 32-bit elements) + * + * **RV32 Description**:\n + * For the `SMSLDA` instruction, it multiplies the bottom 16-bit content of Rs1 with the bottom 16-bit + * content Rs2 and multiplies the top 16-bit content of Rs1 with the top 16-bit content of Rs2. + * For the `SMSLXDA` instruction, it multiplies the top 16-bit content of Rs1 with the bottom 16-bit + * content of Rs2 and multiplies the bottom 16-bit content of Rs1 with the top 16-bit content of Rs2. + * The two multiplication results are subtracted from the 64-bit value of an even/odd pair of registers + * specified by Rd(4,1). The 64-bit subtraction result is written back to the register-pair. The 16-bit + * values of Rs1 and Rs2, and the 64-bit value of the register-pair are treated as signed integers. + * Rd(4,1), i.e., d, determines the even/odd pair group of the two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * + * **RV64 Description**:\n + * For the `SMSLDA` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2 and multiplies the top 16-bit content of + * the 32-bit elements of Rs1 with the top 16-bit content of the 32-bit elements of Rs2. + * For the `SMSLXDA` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 with + * the bottom 16-bit content of the 32-bit elements of Rs2 and multiplies the bottom 16-bit content of + * the 32-bit elements of Rs1 with the top 16-bit content of the 32-bit elements of Rs2. + * The four multiplication results are subtracted from the 64-bit value of Rd. The 64-bit subtraction + * result is written back to Rd. The 16-bit values of Rs1 and Rs2, and the 64-bit value of Rd are treated + * as signed integers. + * + * **Operations**:\n + * ~~~ + * * RV32: + * // SMSLDA + * Mres0[31:0] = (Rs1.H[0] * Rs2.H[0]); + * Mres1[31:0] = (Rs1.H[1] * Rs2.H[1]); + * // SMSLXDA + * Mres0[31:0] = (Rs1.H[0] * Rs2.H[1]); + * Mres1[31:0] = (Rs1.H[1] * Rs2.H[0]); + * Idx0 = CONCAT(Rd(4,1),1'b0); Idx1 = CONCAT(Rd(4,1),1'b1); + * R[Idx1].R[Idx0] = R[Idx1].R[Idx0] - SE64(Mres0[31:0]) - SE64(Mres1[31:0]); + * * RV64: + * // SMSLDA + * Mres0[0][31:0] = (Rs1.W[0].H[0] * Rs2.W[0].H[0]); + * Mres1[0][31:0] = (Rs1.W[0].H[1] * Rs2.W[0].H[1]); + * Mres0[1][31:0] = (Rs1.W[1].H[0] * Rs2.W[1].H[0]); + * Mres1[1][31:0] = (Rs1.W[1].H[1] * Rs2.W[1].H[1]); + * // SMSLXDA + * Mres0[0][31:0] = (Rs1.W[0].H[0] * Rs2.W[0].H[1]); + * Mres1[0][31:0] = (Rs1.W[0].H[1] * Rs2.W[0].H[0]); + * Mres0[1][31:0] = (Rs1.W[1].H[0] * Rs2.W[1].H[1]); + * Mres1[1][31:0] = (Rs1.W[1].H[1] * Rs2.W[1].H[0]); + * Rd = Rd - SE64(Mres0[0][31:0]) - SE64(Mres1[0][31:0]) - SE64(Mres0[1][31:0]) - + * SE64(Mres1[1][31:0]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_SMSLXDA(long long t, unsigned long a, unsigned long b) +{ + __ASM volatile("smslxda %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.120.2. SMSLXDA ===== */ + +/* ===== Inline Function Start for 3.121. SMSR64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_32B_MULT_64B_ADDSUB + * \brief SMSR64 (Signed Multiply and Subtract from 64- Bit Data) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * SMSR64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the 32-bit signed elements in two registers and subtract the 64-bit multiplication + * results from the 64-bit signed data of a pair of registers (RV32) or a register (RV64). The result is + * written back to the pair of registers (RV32) or a register (RV64). + * + * **RV32 Description**:\n + * This instruction multiplies the 32-bit signed data of Rs1 with that of Rs2. It + * subtracts the 64-bit multiplication result from the 64-bit signed data of an even/odd pair of registers + * specified by Rd(4,1). The subtraction result is written back to the even/odd pair of registers + * specified by Rd(4,1). + * Rx(4,1), i.e., d, determines the even/odd pair group of two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * + * **RV64 Description**:\n + * This instruction multiplies the 32-bit signed elements of Rs1 with that of Rs2. It + * subtracts the 64-bit multiplication results from the 64-bit signed data of Rd. The subtraction result is + * written back to Rd. + * + * **Operations**:\n + * ~~~ + * * RV32: + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * R[t_H].R[t_L] = R[t_H].R[t_L] - (Rs1 * Rs2); + * * RV64: + * Rd = Rd - (Rs1.W[0] * Rs2.W[0]) - (Rs1.W[1] * Rs2.W[1]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a long type of value stored in a + * \param [in] b long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_SMSR64(long long t, long a, long b) +{ + __ASM volatile("smsr64 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.121. SMSR64 ===== */ + +/* ===== Inline Function Start for 3.122.1. SMUL8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_MULTIPLY + * \brief SMUL8 (SIMD Signed 8-bit Multiply) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMUL8 Rd, Rs1, Rs2 + * SMULX8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do signed 8-bit multiplications and generate four 16-bit results simultaneously. + * + * **RV32 Description**:\n + * For the `SMUL8` instruction, multiply the 8-bit data elements of Rs1 with the + * corresponding 8-bit data elements of Rs2. + * For the `SMULX8` instruction, multiply the first and second 8-bit data elements of Rs1 with the + * second and first 8-bit data elements of Rs2. At the same time, multiply the third and fourth 8-bit data + * elements of Rs1 with the fourth and third 8-bit data elements of Rs2. + * The four 16-bit results are then written into an even/odd pair of registers specified by Rd(4,1). + * Rd(4,1), i.e., d, determines the even/odd pair group of two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the two 16-bit results calculated from the top part of + * Rs1 and the even `2d` register of the pair contains the two 16-bit results calculated from the bottom + * part of Rs1. + * + * **RV64 Description**:\n + * For the `SMUL8` instruction, multiply the 8-bit data elements of Rs1 with the + * corresponding 8-bit data elements of Rs2. + * For the `SMULX8` instruction, multiply the first and second 8-bit data elements of Rs1 with the + * second and first 8-bit data elements of Rs2. At the same time, multiply the third and fourth 8-bit data + * elements of Rs1 with the fourth and third 8-bit data elements of Rs2. + * The four 16-bit results are then written into Rd. The Rd.W[1] contains the two 16-bit results + * calculated from the top part of Rs1 and the Rd.W[0] contains the two 16-bit results calculated from + * the bottom part of Rs1. + * + * **Operations**:\n + * ~~~ + * * RV32: + * if (is `SMUL8`) { + * op1t[x/2] = Rs1.B[x+1]; op2t[x/2] = Rs2.B[x+1]; // top + * op1b[x/2] = Rs1.B[x]; op2b[x/2] = Rs2.B[x]; // bottom + * } else if (is `SMULX8`) { + * op1t[x/2] = Rs1.B[x+1]; op2t[x/2] = Rs2.B[x]; // Rs1 top + * op1b[x/2] = Rs1.B[x]; op2b[x/2] = Rs2.B[x+1]; // Rs1 bottom + * } + * rest[x/2] = op1t[x/2] s* op2t[x/2]; + * resb[x/2] = op1b[x/2] s* op2b[x/2]; + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * R[t_H].H[1] = rest[1]; R[t_H].H[0] = resb[1]; + * R[t_L].H[1] = rest[0]; R[t_L].H[0] = resb[0]; + * x = 0 and 2 + * * RV64: + * if (is `SMUL8`) { + * op1t[x/2] = Rs1.B[x+1]; op2t[x/2] = Rs2.B[x+1]; // top + * op1b[x/2] = Rs1.B[x]; op2b[x/2] = Rs2.B[x]; // bottom + * } else if (is `SMULX8`) { + * op1t[x/2] = Rs1.B[x+1]; op2t[x/2] = Rs2.B[x]; // Rs1 top + * op1b[x/2] = Rs1.B[x]; op2b[x/2] = Rs2.B[x+1]; // Rs1 bottom + * } + * rest[x/2] = op1t[x/2] s* op2t[x/2]; + * resb[x/2] = op1b[x/2] s* op2b[x/2]; + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * Rd.W[1].H[1] = rest[1]; Rd.W[1].H[0] = resb[1]; + * Rd.W[0].H[1] = rest[0]; Rd.W[0].H[0] = resb[0]; + * x = 0 and 2 + * ~~~ + * + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_SMUL8(unsigned int a, unsigned int b) +{ + unsigned long long result; + __ASM volatile("smul8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.122.1. SMUL8 ===== */ + +/* ===== Inline Function Start for 3.122.2. SMULX8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_MULTIPLY + * \brief SMULX8 (SIMD Signed Crossed 8-bit Multiply) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMUL8 Rd, Rs1, Rs2 + * SMULX8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do signed 8-bit multiplications and generate four 16-bit results simultaneously. + * + * **RV32 Description**:\n + * For the `SMUL8` instruction, multiply the 8-bit data elements of Rs1 with the + * corresponding 8-bit data elements of Rs2. + * For the `SMULX8` instruction, multiply the first and second 8-bit data elements of Rs1 with the + * second and first 8-bit data elements of Rs2. At the same time, multiply the third and fourth 8-bit data + * elements of Rs1 with the fourth and third 8-bit data elements of Rs2. + * The four 16-bit results are then written into an even/odd pair of registers specified by Rd(4,1). + * Rd(4,1), i.e., d, determines the even/odd pair group of two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the two 16-bit results calculated from the top part of + * Rs1 and the even `2d` register of the pair contains the two 16-bit results calculated from the bottom + * part of Rs1. + * + * **RV64 Description**:\n + * For the `SMUL8` instruction, multiply the 8-bit data elements of Rs1 with the + * corresponding 8-bit data elements of Rs2. + * For the `SMULX8` instruction, multiply the first and second 8-bit data elements of Rs1 with the + * second and first 8-bit data elements of Rs2. At the same time, multiply the third and fourth 8-bit data + * elements of Rs1 with the fourth and third 8-bit data elements of Rs2. + * The four 16-bit results are then written into Rd. The Rd.W[1] contains the two 16-bit results + * calculated from the top part of Rs1 and the Rd.W[0] contains the two 16-bit results calculated from + * the bottom part of Rs1. + * + * **Operations**:\n + * ~~~ + * * RV32: + * if (is `SMUL8`) { + * op1t[x/2] = Rs1.B[x+1]; op2t[x/2] = Rs2.B[x+1]; // top + * op1b[x/2] = Rs1.B[x]; op2b[x/2] = Rs2.B[x]; // bottom + * } else if (is `SMULX8`) { + * op1t[x/2] = Rs1.B[x+1]; op2t[x/2] = Rs2.B[x]; // Rs1 top + * op1b[x/2] = Rs1.B[x]; op2b[x/2] = Rs2.B[x+1]; // Rs1 bottom + * } + * rest[x/2] = op1t[x/2] s* op2t[x/2]; + * resb[x/2] = op1b[x/2] s* op2b[x/2]; + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * R[t_H].H[1] = rest[1]; R[t_H].H[0] = resb[1]; + * R[t_L].H[1] = rest[0]; R[t_L].H[0] = resb[0]; + * x = 0 and 2 + * * RV64: + * if (is `SMUL8`) { + * op1t[x/2] = Rs1.B[x+1]; op2t[x/2] = Rs2.B[x+1]; // top + * op1b[x/2] = Rs1.B[x]; op2b[x/2] = Rs2.B[x]; // bottom + * } else if (is `SMULX8`) { + * op1t[x/2] = Rs1.B[x+1]; op2t[x/2] = Rs2.B[x]; // Rs1 top + * op1b[x/2] = Rs1.B[x]; op2b[x/2] = Rs2.B[x+1]; // Rs1 bottom + * } + * rest[x/2] = op1t[x/2] s* op2t[x/2]; + * resb[x/2] = op1b[x/2] s* op2b[x/2]; + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * Rd.W[1].H[1] = rest[1]; Rd.W[1].H[0] = resb[1]; + * Rd.W[0].H[1] = rest[0]; Rd.W[0].H[0] = resb[0]; + * x = 0 and 2 + * ~~~ + * + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_SMULX8(unsigned int a, unsigned int b) +{ + unsigned long long result; + __ASM volatile("smulx8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.122.2. SMULX8 ===== */ + +/* ===== Inline Function Start for 3.123.1. SMUL16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_MULTIPLY + * \brief SMUL16 (SIMD Signed 16-bit Multiply) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMUL16 Rd, Rs1, Rs2 + * SMULX16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do signed 16-bit multiplications and generate two 32-bit results simultaneously. + * + * **RV32 Description**:\n + * For the `SMUL16` instruction, multiply the top 16-bit Q15 content of Rs1 with + * the top 16-bit Q15 content of Rs2. At the same time, multiply the bottom 16-bit Q15 content of Rs1 + * with the bottom 16-bit Q15 content of Rs2. + * For the `SMULX16` instruction, multiply the top 16-bit Q15 content of Rs1 with the bottom 16-bit + * Q15 content of Rs2. At the same time, multiply the bottom 16-bit Q15 content of Rs1 with the top 16- + * bit Q15 content of Rs2. + * The two Q30 results are then written into an even/odd pair of registers specified by Rd(4,1). Rd(4,1), + * i.e., d, determines the even/odd pair group of two registers. Specifically, the register pair includes + * register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the 32-bit result calculated from the top part of Rs1 and + * the even `2d` register of the pair contains the 32-bit result calculated from the bottom part of Rs1. + * + * **RV64 Description**:\n + * For the `SMUL16` instruction, multiply the top 16-bit Q15 content of the lower + * 32-bit word in Rs1 with the top 16-bit Q15 content of the lower 32-bit word in Rs2. At the same time, + * multiply the bottom 16-bit Q15 content of the lower 32-bit word in Rs1 with the bottom 16-bit Q15 + * content of the lower 32-bit word in Rs2. + * For the `SMULX16` instruction, multiply the top 16-bit Q15 content of the lower 32-bit word in Rs1 + * with the bottom 16-bit Q15 content of the lower 32-bit word in Rs2. At the same time, multiply the + * bottom 16-bit Q15 content of the lower 32-bit word in Rs1 with the top 16-bit Q15 content of the + * lower 32-bit word in Rs2. + * The two 32-bit Q30 results are then written into Rd. The result calculated from the top 16-bit of the + * lower 32-bit word in Rs1 is written to Rd.W[1]. And the result calculated from the bottom 16-bit of + * the lower 32-bit word in Rs1 is written to Rd.W[0] + * + * **Operations**:\n + * ~~~ + * * RV32: + * if (is `SMUL16`) { + * op1t = Rs1.H[1]; op2t = Rs2.H[1]; // top + * op1b = Rs1.H[0]; op2b = Rs2.H[0]; // bottom + * } else if (is `SMULX16`) { + * op1t = Rs1.H[1]; op2t = Rs2.H[0]; // Rs1 top + * op1b = Rs1.H[0]; op2b = Rs2.H[1]; // Rs1 bottom + * } + * for ((aop,bop,res) in [(op1t,op2t,rest), (op1b,op2b,resb)]) { + * res = aop s* bop; + * } + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * R[t_H] = rest; + * R[t_L] = resb; + * * RV64: + * if (is `SMUL16`) { + * op1t = Rs1.H[1]; op2t = Rs2.H[1]; // top + * op1b = Rs1.H[0]; op2b = Rs2.H[0]; // bottom + * } else if (is `SMULX16`) { + * op1t = Rs1.H[1]; op2t = Rs2.H[0]; // Rs1 top + * op1b = Rs1.H[0]; op2b = Rs2.H[1]; // Rs1 bottom + * } + * for ((aop,bop,res) in [(op1t,op2t,rest), (op1b,op2b,resb)]) { + * res = aop s* bop; + * } + * Rd.W[1] = rest; + * Rd.W[0] = resb; + * ~~~ + * + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_SMUL16(unsigned int a, unsigned int b) +{ + unsigned long long result; + __ASM volatile("smul16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.123.1. SMUL16 ===== */ + +/* ===== Inline Function Start for 3.123.2. SMULX16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_MULTIPLY + * \brief SMULX16 (SIMD Signed Crossed 16-bit Multiply) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMUL16 Rd, Rs1, Rs2 + * SMULX16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do signed 16-bit multiplications and generate two 32-bit results simultaneously. + * + * **RV32 Description**:\n + * For the `SMUL16` instruction, multiply the top 16-bit Q15 content of Rs1 with + * the top 16-bit Q15 content of Rs2. At the same time, multiply the bottom 16-bit Q15 content of Rs1 + * with the bottom 16-bit Q15 content of Rs2. + * For the `SMULX16` instruction, multiply the top 16-bit Q15 content of Rs1 with the bottom 16-bit + * Q15 content of Rs2. At the same time, multiply the bottom 16-bit Q15 content of Rs1 with the top 16- + * bit Q15 content of Rs2. + * The two Q30 results are then written into an even/odd pair of registers specified by Rd(4,1). Rd(4,1), + * i.e., d, determines the even/odd pair group of two registers. Specifically, the register pair includes + * register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the 32-bit result calculated from the top part of Rs1 and + * the even `2d` register of the pair contains the 32-bit result calculated from the bottom part of Rs1. + * + * **RV64 Description**:\n + * For the `SMUL16` instruction, multiply the top 16-bit Q15 content of the lower + * 32-bit word in Rs1 with the top 16-bit Q15 content of the lower 32-bit word in Rs2. At the same time, + * multiply the bottom 16-bit Q15 content of the lower 32-bit word in Rs1 with the bottom 16-bit Q15 + * content of the lower 32-bit word in Rs2. + * For the `SMULX16` instruction, multiply the top 16-bit Q15 content of the lower 32-bit word in Rs1 + * with the bottom 16-bit Q15 content of the lower 32-bit word in Rs2. At the same time, multiply the + * bottom 16-bit Q15 content of the lower 32-bit word in Rs1 with the top 16-bit Q15 content of the + * lower 32-bit word in Rs2. + * The two 32-bit Q30 results are then written into Rd. The result calculated from the top 16-bit of the + * lower 32-bit word in Rs1 is written to Rd.W[1]. And the result calculated from the bottom 16-bit of + * the lower 32-bit word in Rs1 is written to Rd.W[0] + * + * **Operations**:\n + * ~~~ + * * RV32: + * if (is `SMUL16`) { + * op1t = Rs1.H[1]; op2t = Rs2.H[1]; // top + * op1b = Rs1.H[0]; op2b = Rs2.H[0]; // bottom + * } else if (is `SMULX16`) { + * op1t = Rs1.H[1]; op2t = Rs2.H[0]; // Rs1 top + * op1b = Rs1.H[0]; op2b = Rs2.H[1]; // Rs1 bottom + * } + * for ((aop,bop,res) in [(op1t,op2t,rest), (op1b,op2b,resb)]) { + * res = aop s* bop; + * } + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * R[t_H] = rest; + * R[t_L] = resb; + * * RV64: + * if (is `SMUL16`) { + * op1t = Rs1.H[1]; op2t = Rs2.H[1]; // top + * op1b = Rs1.H[0]; op2b = Rs2.H[0]; // bottom + * } else if (is `SMULX16`) { + * op1t = Rs1.H[1]; op2t = Rs2.H[0]; // Rs1 top + * op1b = Rs1.H[0]; op2b = Rs2.H[1]; // Rs1 bottom + * } + * for ((aop,bop,res) in [(op1t,op2t,rest), (op1b,op2b,resb)]) { + * res = aop s* bop; + * } + * Rd.W[1] = rest; + * Rd.W[0] = resb; + * ~~~ + * + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_SMULX16(unsigned int a, unsigned int b) +{ + unsigned long long result; + __ASM volatile("smulx16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.123.2. SMULX16 ===== */ + +/* ===== Inline Function Start for 3.124. SRA.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_MISC + * \brief SRA.u (Rounding Shift Right Arithmetic) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * SRA.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Perform an arithmetic right shift operation with rounding. The shift amount is a variable + * from a GPR. + * + * **Description**:\n + * This instruction right-shifts the content of Rs1 arithmetically. The shifted out bits are + * filled with the sign-bit and the shift amount is specified by the low-order 5-bits (RV32) or 6-bits + * (RV64) of the Rs2 register. For the rounding operation, a value of 1 is added to the most significant + * discarded bit of the data to calculate the final result. And the result is written to Rd. + * + * **Operations**:\n + * ~~~ + * * RV32: + * sa = Rs2[4:0]; + * if (sa > 0) { + * res[31:-1] = SE33(Rs1[31:(sa-1)]) + 1; + * Rd = res[31:0]; + * } else { + * Rd = Rs1; + * } + * * RV64: + * sa = Rs2[5:0]; + * if (sa > 0) { + * res[63:-1] = SE65(Rs1[63:(sa-1)]) + 1; + * Rd = res[63:0]; + * } else { + * Rd = Rs1; + * } + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SRA_U(long a, unsigned int b) +{ + long result; + __ASM volatile("sra.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.124. SRA.u ===== */ + +/* ===== Inline Function Start for 3.125. SRAI.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_MISC + * \brief SRAI.u (Rounding Shift Right Arithmetic Immediate) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * SRAI.u Rd, Rs1, imm6u[4:0] (RV32) + * SRAI.u Rd, Rs1, imm6u[5:0] (RV64) + * ~~~ + * + * **Purpose**:\n + * Perform an arithmetic right shift operation with rounding. The shift amount is an + * immediate value. + * + * **Description**:\n + * This instruction right-shifts the content of Rs1 arithmetically. The shifted out bits are + * filled with the sign-bit and the shift amount is specified by the imm6u[4:0] (RV32) or imm6u[5:0] + * (RV64) constant . For the rounding operation, a value of 1 is added to the most significant discarded + * bit of the data to calculate the final result. And the result is written to Rd. + * + * **Operations**:\n + * ~~~ + * * RV32: + * sa = imm6u[4:0]; + * if (sa > 0) { + * res[31:-1] = SE33(Rs1[31:(sa-1)]) + 1; + * Rd = res[31:0]; + * } else { + * Rd = Rs1; + * } + * * RV64: + * sa = imm6u[5:0]; + * if (sa > 0) { + * res[63:-1] = SE65(Rs1[63:(sa-1)]) + 1; + * Rd = res[63:0]; + * } else { + * Rd = Rs1; + * } + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in long type + */ +#define __RV_SRAI_U(a, b) \ + ({ \ + long result; \ + long __a = (long)(a); \ + __ASM volatile("srai.u %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.125. SRAI.u ===== */ + +/* ===== Inline Function Start for 3.126.1. SRA8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_SHIFT + * \brief SRA8 (SIMD 8-bit Shift Right Arithmetic) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SRA8 Rd, Rs1, Rs2 + * SRA8.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit element arithmetic right shift operations simultaneously. The shift amount is a + * variable from a GPR. The `.u` form performs additional rounding up operations on the shifted + * results. + * + * **Description**:\n + * The 8-bit data elements in Rs1 are right-shifted arithmetically, that is, the shifted out + * bits are filled with the sign-bit of the data elements. The shift amount is specified by the low-order + * 3-bits of the value in the Rs2 register. For the rounding operation of the `.u` form, a value of 1 is + * added to the most significant discarded bit of each 8-bit data element to calculate the final results. + * And the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[2:0]; + * if (sa > 0) { + * if (`.u` form) { // SRA8.u + * res[7:-1] = SE9(Rs1.B[x][7:sa-1]) + 1; + * Rd.B[x] = res[7:0]; + * } else { // SRA8 + * Rd.B[x] = SE8(Rd.B[x][7:sa]) + * } + * } else { + * Rd = Rs1; + * } + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SRA8(unsigned long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("sra8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.126.1. SRA8 ===== */ + +/* ===== Inline Function Start for 3.126.2. SRA8.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_SHIFT + * \brief SRA8.u (SIMD 8-bit Rounding Shift Right Arithmetic) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SRA8 Rd, Rs1, Rs2 + * SRA8.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit element arithmetic right shift operations simultaneously. The shift amount is a + * variable from a GPR. The `.u` form performs additional rounding up operations on the shifted + * results. + * + * **Description**:\n + * The 8-bit data elements in Rs1 are right-shifted arithmetically, that is, the shifted out + * bits are filled with the sign-bit of the data elements. The shift amount is specified by the low-order + * 3-bits of the value in the Rs2 register. For the rounding operation of the `.u` form, a value of 1 is + * added to the most significant discarded bit of each 8-bit data element to calculate the final results. + * And the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[2:0]; + * if (sa > 0) { + * if (`.u` form) { // SRA8.u + * res[7:-1] = SE9(Rs1.B[x][7:sa-1]) + 1; + * Rd.B[x] = res[7:0]; + * } else { // SRA8 + * Rd.B[x] = SE8(Rd.B[x][7:sa]) + * } + * } else { + * Rd = Rs1; + * } + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SRA8_U(unsigned long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("sra8.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.126.2. SRA8.u ===== */ + +/* ===== Inline Function Start for 3.127.1. SRAI8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_SHIFT + * \brief SRAI8 (SIMD 8-bit Shift Right Arithmetic Immediate) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SRAI8 Rd, Rs1, imm3u + * SRAI8.u Rd, Rs1, imm3u + * ~~~ + * + * **Purpose**:\n + * Do 8-bit element arithmetic right shift operations simultaneously. The shift amount is an + * immediate value. The `.u` form performs additional rounding up operations on the shifted results. + * + * **Description**:\n + * The 8-bit data elements in Rs1 are right-shifted arithmetically, that is, the shifted out + * bits are filled with the sign-bit of the data elements. The shift amount is specified by the imm3u + * constant. For the rounding operation of the `.u` form, a value of 1 is added to the most significant + * discarded bit of each 8-bit data element to calculate the final results. And the results are written to + * Rd. + * + * **Operations**:\n + * ~~~ + * sa = imm3u[2:0]; + * if (sa > 0) { + * if (`.u` form) { // SRA8.u + * res[7:-1] = SE9(Rs1.B[x][7:sa-1]) + 1; + * Rd.B[x] = res[7:0]; + * } else { // SRA8 + * Rd.B[x] = SE8(Rd.B[x][7:sa]) + * } + * } else { + * Rd = Rs1; + * } + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SRAI8(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("srai8 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.127.1. SRAI8 ===== */ + +/* ===== Inline Function Start for 3.127.2. SRAI8.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_SHIFT + * \brief SRAI8.u (SIMD 8-bit Rounding Shift Right Arithmetic Immediate) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SRAI8 Rd, Rs1, imm3u + * SRAI8.u Rd, Rs1, imm3u + * ~~~ + * + * **Purpose**:\n + * Do 8-bit element arithmetic right shift operations simultaneously. The shift amount is an + * immediate value. The `.u` form performs additional rounding up operations on the shifted results. + * + * **Description**:\n + * The 8-bit data elements in Rs1 are right-shifted arithmetically, that is, the shifted out + * bits are filled with the sign-bit of the data elements. The shift amount is specified by the imm3u + * constant. For the rounding operation of the `.u` form, a value of 1 is added to the most significant + * discarded bit of each 8-bit data element to calculate the final results. And the results are written to + * Rd. + * + * **Operations**:\n + * ~~~ + * sa = imm3u[2:0]; + * if (sa > 0) { + * if (`.u` form) { // SRA8.u + * res[7:-1] = SE9(Rs1.B[x][7:sa-1]) + 1; + * Rd.B[x] = res[7:0]; + * } else { // SRA8 + * Rd.B[x] = SE8(Rd.B[x][7:sa]) + * } + * } else { + * Rd = Rs1; + * } + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SRAI8_U(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("srai8.u %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.127.2. SRAI8.u ===== */ + +/* ===== Inline Function Start for 3.128.1. SRA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_SHIFT + * \brief SRA16 (SIMD 16-bit Shift Right Arithmetic) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SRA16 Rd, Rs1, Rs2 + * SRA16.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit element arithmetic right shift operations simultaneously. The shift amount is a + * variable from a GPR. The `.u` form performs additional rounding up operations on the shifted + * results. + * + * **Description**:\n + * The 16-bit data elements in Rs1 are right-shifted arithmetically, that is, the shifted out + * bits are filled with the sign-bit of the data elements. The shift amount is specified by the low-order + * 4-bits of the value in the Rs2 register. For the rounding operation of the `.u` form, a value of 1 is + * added to the most significant discarded bit of each 16-bit data element to calculate the final results. + * And the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[3:0]; + * if (sa != 0) { + * if (`.u` form) { // SRA16.u + * res[15:-1] = SE17(Rs1.H[x][15:sa-1]) + 1; + * Rd.H[x] = res[15:0]; + * } else { // SRA16 + * Rd.H[x] = SE16(Rs1.H[x][15:sa]) + * } + * } else { + * Rd = Rs1; + * } + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SRA16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("sra16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.128.1. SRA16 ===== */ + +/* ===== Inline Function Start for 3.128.2. SRA16.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_SHIFT + * \brief SRA16.u (SIMD 16-bit Rounding Shift Right Arithmetic) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SRA16 Rd, Rs1, Rs2 + * SRA16.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit element arithmetic right shift operations simultaneously. The shift amount is a + * variable from a GPR. The `.u` form performs additional rounding up operations on the shifted + * results. + * + * **Description**:\n + * The 16-bit data elements in Rs1 are right-shifted arithmetically, that is, the shifted out + * bits are filled with the sign-bit of the data elements. The shift amount is specified by the low-order + * 4-bits of the value in the Rs2 register. For the rounding operation of the `.u` form, a value of 1 is + * added to the most significant discarded bit of each 16-bit data element to calculate the final results. + * And the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[3:0]; + * if (sa != 0) { + * if (`.u` form) { // SRA16.u + * res[15:-1] = SE17(Rs1.H[x][15:sa-1]) + 1; + * Rd.H[x] = res[15:0]; + * } else { // SRA16 + * Rd.H[x] = SE16(Rs1.H[x][15:sa]) + * } + * } else { + * Rd = Rs1; + * } + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SRA16_U(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("sra16.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.128.2. SRA16.u ===== */ + +/* ===== Inline Function Start for 3.129.1. SRAI16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_SHIFT + * \brief SRAI16 (SIMD 16-bit Shift Right Arithmetic Immediate) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SRAI16 Rd, Rs1, imm4u + * SRAI16.u Rd, Rs1, imm4u + * ~~~ + * + * **Purpose**:\n + * Do 16-bit elements arithmetic right shift operations simultaneously. The shift amount is + * an immediate value. The `.u` form performs additional rounding up operations on the shifted + * results. + * + * **Description**:\n + * The 16-bit data elements in Rs1 are right-shifted arithmetically, that is, the shifted out + * bits are filled with the sign-bit of the 16-bit data elements. The shift amount is specified by the + * imm4u constant. For the rounding operation of the `.u` form, a value of 1 is added to the most + * significant discarded bit of each 16-bit data to calculate the final results. And the results are written + * to Rd. + * + * **Operations**:\n + * ~~~ + * sa = imm4u[3:0]; + * if (sa > 0) { + * if (`.u` form) { // SRAI16.u + * res[15:-1] = SE17(Rs1.H[x][15:sa-1]) + 1; + * Rd.H[x] = res[15:0]; + * } else { // SRAI16 + * Rd.H[x] = SE16(Rs1.H[x][15:sa]); + * } + * } else { + * Rd = Rs1; + * } + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SRAI16(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("srai16 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.129.1. SRAI16 ===== */ + +/* ===== Inline Function Start for 3.129.2. SRAI16.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_SHIFT + * \brief SRAI16.u (SIMD 16-bit Rounding Shift Right Arithmetic Immediate) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SRAI16 Rd, Rs1, imm4u + * SRAI16.u Rd, Rs1, imm4u + * ~~~ + * + * **Purpose**:\n + * Do 16-bit elements arithmetic right shift operations simultaneously. The shift amount is + * an immediate value. The `.u` form performs additional rounding up operations on the shifted + * results. + * + * **Description**:\n + * The 16-bit data elements in Rs1 are right-shifted arithmetically, that is, the shifted out + * bits are filled with the sign-bit of the 16-bit data elements. The shift amount is specified by the + * imm4u constant. For the rounding operation of the `.u` form, a value of 1 is added to the most + * significant discarded bit of each 16-bit data to calculate the final results. And the results are written + * to Rd. + * + * **Operations**:\n + * ~~~ + * sa = imm4u[3:0]; + * if (sa > 0) { + * if (`.u` form) { // SRAI16.u + * res[15:-1] = SE17(Rs1.H[x][15:sa-1]) + 1; + * Rd.H[x] = res[15:0]; + * } else { // SRAI16 + * Rd.H[x] = SE16(Rs1.H[x][15:sa]); + * } + * } else { + * Rd = Rs1; + * } + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SRAI16_U(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("srai16.u %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.129.2. SRAI16.u ===== */ + +/* ===== Inline Function Start for 3.130.1. SRL8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_SHIFT + * \brief SRL8 (SIMD 8-bit Shift Right Logical) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SRL8 Rt, Ra, Rb + * SRL8.u Rt, Ra, Rb + * ~~~ + * + * **Purpose**:\n + * Do 8-bit elements logical right shift operations simultaneously. The shift amount is a + * variable from a GPR. The `.u` form performs additional rounding up operations on the shifted + * results. + * + * **Description**:\n + * The 8-bit data elements in Rs1 are right-shifted logically, that is, the shifted out bits are + * filled with zero. The shift amount is specified by the low-order 3-bits of the value in the Rs2 register. + * For the rounding operation of the `.u` form, a value of 1 is added to the most significant discarded + * bit of each 8-bit data element to calculate the final results. And the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[2:0]; + * if (sa > 0) { + * if (`.u` form) { // SRL8.u + * res[8:0] = ZE9(Rs1.B[x][7:sa-1]) + 1; + * Rd.B[x] = res[8:1]; + * } else { // SRL8 + * Rd.B[x] = ZE8(Rs1.B[x][7:sa]); + * } + * } else { + * Rd = Rs1; + * } + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SRL8(unsigned long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("srl8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.130.1. SRL8 ===== */ + +/* ===== Inline Function Start for 3.130.2. SRL8.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_SHIFT + * \brief SRL8.u (SIMD 8-bit Rounding Shift Right Logical) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SRL8 Rt, Ra, Rb + * SRL8.u Rt, Ra, Rb + * ~~~ + * + * **Purpose**:\n + * Do 8-bit elements logical right shift operations simultaneously. The shift amount is a + * variable from a GPR. The `.u` form performs additional rounding up operations on the shifted + * results. + * + * **Description**:\n + * The 8-bit data elements in Rs1 are right-shifted logically, that is, the shifted out bits are + * filled with zero. The shift amount is specified by the low-order 3-bits of the value in the Rs2 register. + * For the rounding operation of the `.u` form, a value of 1 is added to the most significant discarded + * bit of each 8-bit data element to calculate the final results. And the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[2:0]; + * if (sa > 0) { + * if (`.u` form) { // SRL8.u + * res[8:0] = ZE9(Rs1.B[x][7:sa-1]) + 1; + * Rd.B[x] = res[8:1]; + * } else { // SRL8 + * Rd.B[x] = ZE8(Rs1.B[x][7:sa]); + * } + * } else { + * Rd = Rs1; + * } + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SRL8_U(unsigned long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("srl8.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.130.2. SRL8.u ===== */ + +/* ===== Inline Function Start for 3.131.1. SRLI8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_SHIFT + * \brief SRLI8 (SIMD 8-bit Shift Right Logical Immediate) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SRLI8 Rt, Ra, imm3u + * SRLI8.u Rt, Ra, imm3u + * ~~~ + * + * **Purpose**:\n + * Do 8-bit elements logical right shift operations simultaneously. The shift amount is an + * immediate value. The `.u` form performs additional rounding up operations on the shifted results. + * + * **Description**:\n + * The 8-bit data elements in Rs1 are right-shifted logically, that is, the shifted out bits are + * filled with zero. The shift amount is specified by the imm3u constant. For the rounding operation of + * the `.u` form, a value of 1 is added to the most significant discarded bit of each 8-bit data element to + * calculate the final results. And the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = imm3u[2:0]; + * if (sa > 0) { + * if (`.u` form) { // SRLI8.u + * res[8:0] = ZE9(Rs1.B[x][7:sa-1]) + 1; + * Rd.B[x] = res[8:1]; + * } else { // SRLI8 + * Rd.B[x] = ZE8(Rs1.B[x][7:sa]); + * } + * } else { + * Rd = Rs1; + * } + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SRLI8(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("srli8 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.131.1. SRLI8 ===== */ + +/* ===== Inline Function Start for 3.131.2. SRLI8.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_SHIFT + * \brief SRLI8.u (SIMD 8-bit Rounding Shift Right Logical Immediate) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SRLI8 Rt, Ra, imm3u + * SRLI8.u Rt, Ra, imm3u + * ~~~ + * + * **Purpose**:\n + * Do 8-bit elements logical right shift operations simultaneously. The shift amount is an + * immediate value. The `.u` form performs additional rounding up operations on the shifted results. + * + * **Description**:\n + * The 8-bit data elements in Rs1 are right-shifted logically, that is, the shifted out bits are + * filled with zero. The shift amount is specified by the imm3u constant. For the rounding operation of + * the `.u` form, a value of 1 is added to the most significant discarded bit of each 8-bit data element to + * calculate the final results. And the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = imm3u[2:0]; + * if (sa > 0) { + * if (`.u` form) { // SRLI8.u + * res[8:0] = ZE9(Rs1.B[x][7:sa-1]) + 1; + * Rd.B[x] = res[8:1]; + * } else { // SRLI8 + * Rd.B[x] = ZE8(Rs1.B[x][7:sa]); + * } + * } else { + * Rd = Rs1; + * } + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SRLI8_U(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("srli8.u %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.131.2. SRLI8.u ===== */ + +/* ===== Inline Function Start for 3.132.1. SRL16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_SHIFT + * \brief SRL16 (SIMD 16-bit Shift Right Logical) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SRL16 Rt, Ra, Rb + * SRL16.u Rt, Ra, Rb + * ~~~ + * + * **Purpose**:\n + * Do 16-bit elements logical right shift operations simultaneously. The shift amount is a variable from a GPR. The `.u` form performs additional rounding upoperations on the shifted results. + * + * **Description**:\n + * The 16-bit data elements in Rs1 are right-shifted logically, that is, the shifted out bits + * are filled with zero. The shift amount is specified by the low-order 4-bits of the value in the Rs2 + * register. For the rounding operation of the `.u` form, a value of 1 is added to the most significant + * discarded bit of each 16-bit data element to calculate the final results. And the results are written to + * Rd. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[3:0]; + * if (sa > 0) { + * if (`.u` form) { // SRL16.u + * res[16:0] = ZE17(Rs1.H[x][15:sa-1]) + 1; + * Rd.H[x] = res[16:1]; + * } else { // SRL16 + * Rd.H[x] = ZE16(Rs1.H[x][15:sa]); + * } + * } else { + * Rd = Rs1; + * } + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SRL16(unsigned long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("srl16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.132.1. SRL16 ===== */ + +/* ===== Inline Function Start for 3.132.2. SRL16.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_SHIFT + * \brief SRL16.u (SIMD 16-bit Rounding Shift Right Logical) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SRL16 Rt, Ra, Rb + * SRL16.u Rt, Ra, Rb + * ~~~ + * + * **Purpose**:\n + * Do 16-bit elements logical right shift operations simultaneously. The shift amount is a variable from a GPR. The `.u` form performs additional rounding upoperations on the shifted results. + * + * **Description**:\n + * The 16-bit data elements in Rs1 are right-shifted logically, that is, the shifted out bits + * are filled with zero. The shift amount is specified by the low-order 4-bits of the value in the Rs2 + * register. For the rounding operation of the `.u` form, a value of 1 is added to the most significant + * discarded bit of each 16-bit data element to calculate the final results. And the results are written to + * Rd. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[3:0]; + * if (sa > 0) { + * if (`.u` form) { // SRL16.u + * res[16:0] = ZE17(Rs1.H[x][15:sa-1]) + 1; + * Rd.H[x] = res[16:1]; + * } else { // SRL16 + * Rd.H[x] = ZE16(Rs1.H[x][15:sa]); + * } + * } else { + * Rd = Rs1; + * } + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SRL16_U(unsigned long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("srl16.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.132.2. SRL16.u ===== */ + +/* ===== Inline Function Start for 3.133.1. SRLI16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_SHIFT + * \brief SRLI16 (SIMD 16-bit Shift Right Logical Immediate) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SRLI16 Rt, Ra, imm4u + * SRLI16.u Rt, Ra, imm4u + * ~~~ + * + * **Purpose**:\n + * Do 16-bit elements logical right shift operations simultaneously. The shift amount is an + * immediate value. The `.u` form performs additional rounding up operations on the shifted results. + * + * **Description**:\n + * The 16-bit data elements in Rs1 are right-shifted logically, that is, the shifted out bits + * are filled with zero. The shift amount is specified by the imm4u constant. For the rounding + * operation of the `.u` form, a value of 1 is added to the most significant discarded bit of each 16-bit + * data element to calculate the final results. And the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = imm4u; + * if (sa > 0) { + * if (`.u` form) { // SRLI16.u + * res[16:0] = ZE17(Rs1.H[x][15:sa-1]) + 1; + * Rd.H[x] = res[16:1]; + * } else { // SRLI16 + * Rd.H[x] = ZE16(Rs1.H[x][15:sa]); + * } + * } else { + * Rd = Rs1; + * } + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SRLI16(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("srli16 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.133.1. SRLI16 ===== */ + +/* ===== Inline Function Start for 3.133.2. SRLI16.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_SHIFT + * \brief SRLI16.u (SIMD 16-bit Rounding Shift Right Logical Immediate) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SRLI16 Rt, Ra, imm4u + * SRLI16.u Rt, Ra, imm4u + * ~~~ + * + * **Purpose**:\n + * Do 16-bit elements logical right shift operations simultaneously. The shift amount is an + * immediate value. The `.u` form performs additional rounding up operations on the shifted results. + * + * **Description**:\n + * The 16-bit data elements in Rs1 are right-shifted logically, that is, the shifted out bits + * are filled with zero. The shift amount is specified by the imm4u constant. For the rounding + * operation of the `.u` form, a value of 1 is added to the most significant discarded bit of each 16-bit + * data element to calculate the final results. And the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = imm4u; + * if (sa > 0) { + * if (`.u` form) { // SRLI16.u + * res[16:0] = ZE17(Rs1.H[x][15:sa-1]) + 1; + * Rd.H[x] = res[16:1]; + * } else { // SRLI16 + * Rd.H[x] = ZE16(Rs1.H[x][15:sa]); + * } + * } else { + * Rd = Rs1; + * } + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SRLI16_U(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("srli16.u %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.133.2. SRLI16.u ===== */ + +/* ===== Inline Function Start for 3.134. STAS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief STAS16 (SIMD 16-bit Straight Addition & Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * STAS16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit integer element addition and 16-bit integer element subtraction in a 32-bit + * chunk simultaneously. Operands are from corresponding positions in 32-bit chunks. + * + * **Description**:\n + * This instruction adds the 16-bit integer element in [31:16] of 32-bit chunks in Rs1 with + * the 16-bit integer element in [31:16] of 32-bit chunks in Rs2, and writes the result to [31:16] of 32-bit + * chunks in Rd; at the same time, it subtracts the 16-bit integer element in [15:0] of 32-bit chunks in + * Rs2 from the 16-bit integer element in [15:0] of 32-bit chunks, and writes the result to [15:0] of 32- + * bit chunks in Rd. + * + * **Note**:\n + * This instruction can be used for either signed or unsigned operations. + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:16] = Rs1.W[x][31:16] + Rs2.W[x][31:16]; + * Rd.W[x][15:0] = Rs1.W[x][15:0] - Rs2.W[x][15:0]; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_STAS16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("stas16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.134. STAS16 ===== */ + +/* ===== Inline Function Start for 3.135. STSA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief STSA16 (SIMD 16-bit Straight Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * STSA16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit integer element subtraction and 16-bit integer element addition in a 32-bit + * chunk simultaneously. Operands are from corresponding positions in 32-bit chunks. + * + * **Description**:\n + * This instruction subtracts the 16-bit integer element in [31:16] of 32-bit chunks in Rs2 + * from the 16-bit integer element in [31:16] of 32-bit chunks in Rs1, and writes the result to [31:16] of + * 32-bit chunks in Rd; at the same time, it adds the 16-bit integer element in [15:0] of 32-bit chunks in + * Rs2 with the 16-bit integer element in [15:0] of 32-bit chunks in Rs1, and writes the result to [15:0] of + * 32-bit chunks in Rd. + * + * **Note**:\n + * This instruction can be used for either signed or unsigned operations. + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:16] = Rs1.W[x][31:16] - Rs2.W[x][31:16]; + * Rd.W[x][15:0] = Rs1.W[x][15:0] + Rs2.W[x][15:0]; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_STSA16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("stsa16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.135. STSA16 ===== */ + +/* ===== Inline Function Start for 3.136. SUB8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_ADDSUB + * \brief SUB8 (SIMD 8-bit Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SUB8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit integer element subtractions simultaneously. + * + * **Description**:\n + * This instruction subtracts the 8-bit integer elements in Rs2 from the 8-bit integer + * elements in Rs1, and then writes the result to Rd. + * + * **Note**:\n + * This instruction can be used for either signed or unsigned subtraction. + * + * **Operations**:\n + * ~~~ + * Rd.B[x] = Rs1.B[x] - Rs2.B[x]; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SUB8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("sub8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.136. SUB8 ===== */ + +/* ===== Inline Function Start for 3.137. SUB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief SUB16 (SIMD 16-bit Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SUB16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit integer element subtractions simultaneously. + * + * **Description**:\n + * This instruction subtracts the 16-bit integer elements in Rs2 from the 16-bit integer + * elements in Rs1, and then writes the result to Rd. + * + * **Note**:\n + * This instruction can be used for either signed or unsigned subtraction. + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = Rs1.H[x] - Rs2.H[x]; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SUB16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("sub16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.137. SUB16 ===== */ + +/* ===== Inline Function Start for 3.138. SUB64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_64B_ADDSUB + * \brief SUB64 (64-bit Subtraction) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * SUB64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Perform a 64-bit signed or unsigned integer subtraction. + * + * **RV32 Description**:\n + * This instruction subtracts the 64-bit integer of an even/odd pair of registers + * specified by Rs2(4,1) from the 64-bit integer of an even/odd pair of registers specified by Rs1(4,1), + * and then writes the 64-bit result to an even/odd pair of registers specified by Rd(4,1). + * Rx(4,1), i.e., d, determines the even/odd pair group of two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the operand and the even `2d` + * register of the pair contains the low 32-bit of the operand. + * + * **RV64 Description**:\n + * This instruction subtracts the 64-bit integer of Rs2 from the 64-bit integer of Rs1, + * and then writes the 64-bit result to Rd. + * + * **Note**:\n + * This instruction can be used for either signed or unsigned subtraction. + * + * **Operations**:\n + * ~~~ + * * RV32: + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * a_L = CONCAT(Rs1(4,1),1'b0); a_H = CONCAT(Rs1(4,1),1'b1); + * b_L = CONCAT(Rs2(4,1),1'b0); b_H = CONCAT(Rs2(4,1),1'b1); + * R[t_H].R[t_L] = R[a_H].R[a_L] - R[b_H].R[b_L]; + * * RV64: + * Rd = Rs1 - Rs2; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_SUB64(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("sub64 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.138. SUB64 ===== */ + +/* ===== Inline Function Start for 3.139.1. SUNPKD810 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_UNPACK + * \brief SUNPKD810 (Signed Unpacking Bytes 1 & 0) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * SUNPKD8xy Rd, Rs1 + * xy = {10, 20, 30, 31, 32} + * ~~~ + * + * **Purpose**:\n + * Unpack byte *x and byte y* of 32-bit chunks in a register into two 16-bit signed halfwords + * of 32-bit chunks in a register. + * + * **Description**:\n + * For the `SUNPKD8(x)(*y*)` instruction, it unpacks byte *x and byte y* of 32-bit chunks in Rs1 into + * two 16-bit signed halfwords and writes the results to the top part and the bottom part of 32-bit + * chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = SE16(Rs1.W[m].B[x]) + * Rd.W[m].H[0] = SE16(Rs1.W[m].B[y]) + * // SUNPKD810, x=1,y=0 + * // SUNPKD820, x=2,y=0 + * // SUNPKD830, x=3,y=0 + * // SUNPKD831, x=3,y=1 + * // SUNPKD832, x=3,y=2 + * for RV32: m=0, + * for RV64: m=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SUNPKD810(unsigned long a) +{ + unsigned long result; + __ASM volatile("sunpkd810 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.139.1. SUNPKD810 ===== */ + +/* ===== Inline Function Start for 3.139.2. SUNPKD820 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_UNPACK + * \brief SUNPKD820 (Signed Unpacking Bytes 2 & 0) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * SUNPKD8xy Rd, Rs1 + * xy = {10, 20, 30, 31, 32} + * ~~~ + * + * **Purpose**:\n + * Unpack byte *x and byte y* of 32-bit chunks in a register into two 16-bit signed halfwords + * of 32-bit chunks in a register. + * + * **Description**:\n + * For the `SUNPKD8(x)(*y*)` instruction, it unpacks byte *x and byte y* of 32-bit chunks in Rs1 into + * two 16-bit signed halfwords and writes the results to the top part and the bottom part of 32-bit + * chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = SE16(Rs1.W[m].B[x]) + * Rd.W[m].H[0] = SE16(Rs1.W[m].B[y]) + * // SUNPKD810, x=1,y=0 + * // SUNPKD820, x=2,y=0 + * // SUNPKD830, x=3,y=0 + * // SUNPKD831, x=3,y=1 + * // SUNPKD832, x=3,y=2 + * for RV32: m=0, + * for RV64: m=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SUNPKD820(unsigned long a) +{ + unsigned long result; + __ASM volatile("sunpkd820 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.139.2. SUNPKD820 ===== */ + +/* ===== Inline Function Start for 3.139.3. SUNPKD830 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_UNPACK + * \brief SUNPKD830 (Signed Unpacking Bytes 3 & 0) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * SUNPKD8xy Rd, Rs1 + * xy = {10, 20, 30, 31, 32} + * ~~~ + * + * **Purpose**:\n + * Unpack byte *x and byte y* of 32-bit chunks in a register into two 16-bit signed halfwords + * of 32-bit chunks in a register. + * + * **Description**:\n + * For the `SUNPKD8(x)(*y*)` instruction, it unpacks byte *x and byte y* of 32-bit chunks in Rs1 into + * two 16-bit signed halfwords and writes the results to the top part and the bottom part of 32-bit + * chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = SE16(Rs1.W[m].B[x]) + * Rd.W[m].H[0] = SE16(Rs1.W[m].B[y]) + * // SUNPKD810, x=1,y=0 + * // SUNPKD820, x=2,y=0 + * // SUNPKD830, x=3,y=0 + * // SUNPKD831, x=3,y=1 + * // SUNPKD832, x=3,y=2 + * for RV32: m=0, + * for RV64: m=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SUNPKD830(unsigned long a) +{ + unsigned long result; + __ASM volatile("sunpkd830 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.139.3. SUNPKD830 ===== */ + +/* ===== Inline Function Start for 3.139.4. SUNPKD831 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_UNPACK + * \brief SUNPKD831 (Signed Unpacking Bytes 3 & 1) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * SUNPKD8xy Rd, Rs1 + * xy = {10, 20, 30, 31, 32} + * ~~~ + * + * **Purpose**:\n + * Unpack byte *x and byte y* of 32-bit chunks in a register into two 16-bit signed halfwords + * of 32-bit chunks in a register. + * + * **Description**:\n + * For the `SUNPKD8(x)(*y*)` instruction, it unpacks byte *x and byte y* of 32-bit chunks in Rs1 into + * two 16-bit signed halfwords and writes the results to the top part and the bottom part of 32-bit + * chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = SE16(Rs1.W[m].B[x]) + * Rd.W[m].H[0] = SE16(Rs1.W[m].B[y]) + * // SUNPKD810, x=1,y=0 + * // SUNPKD820, x=2,y=0 + * // SUNPKD830, x=3,y=0 + * // SUNPKD831, x=3,y=1 + * // SUNPKD832, x=3,y=2 + * for RV32: m=0, + * for RV64: m=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SUNPKD831(unsigned long a) +{ + unsigned long result; + __ASM volatile("sunpkd831 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.139.4. SUNPKD831 ===== */ + +/* ===== Inline Function Start for 3.139.5. SUNPKD832 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_UNPACK + * \brief SUNPKD832 (Signed Unpacking Bytes 3 & 2) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * SUNPKD8xy Rd, Rs1 + * xy = {10, 20, 30, 31, 32} + * ~~~ + * + * **Purpose**:\n + * Unpack byte *x and byte y* of 32-bit chunks in a register into two 16-bit signed halfwords + * of 32-bit chunks in a register. + * + * **Description**:\n + * For the `SUNPKD8(x)(*y*)` instruction, it unpacks byte *x and byte y* of 32-bit chunks in Rs1 into + * two 16-bit signed halfwords and writes the results to the top part and the bottom part of 32-bit + * chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = SE16(Rs1.W[m].B[x]) + * Rd.W[m].H[0] = SE16(Rs1.W[m].B[y]) + * // SUNPKD810, x=1,y=0 + * // SUNPKD820, x=2,y=0 + * // SUNPKD830, x=3,y=0 + * // SUNPKD831, x=3,y=1 + * // SUNPKD832, x=3,y=2 + * for RV32: m=0, + * for RV64: m=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SUNPKD832(unsigned long a) +{ + unsigned long result; + __ASM volatile("sunpkd832 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.139.5. SUNPKD832 ===== */ + +/* ===== Inline Function Start for 3.140. SWAP8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_MISC + * \brief SWAP8 (Swap Byte within Halfword) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * SWAP8 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Swap the bytes within each halfword of a register. + * + * **Description**:\n + * This instruction swaps the bytes within each halfword of Rs1 and writes the result to + * Rd. + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = CONCAT(Rs1.H[x][7:0],Rs1.H[x][15:8]); + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SWAP8(unsigned long a) +{ + unsigned long result; + __ASM volatile("swap8 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.140. SWAP8 ===== */ + +/* ===== Inline Function Start for 3.141. SWAP16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_MISC + * \brief SWAP16 (Swap Halfword within Word) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * SWAP16 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Swap the 16-bit halfwords within each word of a register. + * + * **Description**:\n + * This instruction swaps the 16-bit halfwords within each word of Rs1 and writes the + * result to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = CONCAT(Rs1.W[x][15:0],Rs1.H[x][31:16]); + * for RV32: x=0, + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SWAP16(unsigned long a) +{ + unsigned long result; + __ASM volatile("swap16 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.141. SWAP16 ===== */ + +/* ===== Inline Function Start for 3.142. UCLIP8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_MISC + * \brief UCLIP8 (SIMD 8-bit Unsigned Clip Value) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * UCLIP8 Rt, Ra, imm3u + * ~~~ + * + * **Purpose**:\n + * Limit the 8-bit signed elements of a register into an unsigned range simultaneously. + * + * **Description**:\n + * This instruction limits the 8-bit signed elements stored in Rs1 into an unsigned integer + * range between 2^imm3u-1 and 0, and writes the limited results to Rd. For example, if imm3u is 3, the 8- + * bit input values should be saturated between 7 and 0. If saturation is performed, set OV bit to 1. + * + * **Operations**:\n + * ~~~ + * src = Rs1.H[x]; + * if (src > (2^imm3u)-1) { + * src = (2^imm3u)-1; + * OV = 1; + * } else if (src < 0) { + * src = 0; + * OV = 1; + * } + * Rd.H[x] = src; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_UCLIP8(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("uclip8 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.142. UCLIP8 ===== */ + +/* ===== Inline Function Start for 3.143. UCLIP16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_MISC + * \brief UCLIP16 (SIMD 16-bit Unsigned Clip Value) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * UCLIP16 Rt, Ra, imm4u + * ~~~ + * + * **Purpose**:\n + * Limit the 16-bit signed elements of a register into an unsigned range simultaneously. + * + * **Description**:\n + * This instruction limits the 16-bit signed elements stored in Rs1 into an unsigned + * integer range between 2imm4u-1 and 0, and writes the limited results to Rd. For example, if imm4u is + * 3, the 16-bit input values should be saturated between 7 and 0. If saturation is performed, set OV bit + * to 1. + * + * **Operations**:\n + * ~~~ + * src = Rs1.H[x]; + * if (src > (2^imm4u)-1) { + * src = (2^imm4u)-1; + * OV = 1; + * } else if (src < 0) { + * src = 0; + * OV = 1; + * } + * Rd.H[x] = src; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_UCLIP16(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("uclip16 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.143. UCLIP16 ===== */ + +/* ===== Inline Function Start for 3.144. UCLIP32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_PART_SIMD_MISC + * \brief UCLIP32 (SIMD 32-bit Unsigned Clip Value) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * UCLIP32 Rd, Rs1, imm5u[4:0] + * ~~~ + * + * **Purpose**:\n + * Limit the 32-bit signed integer elements of a register into an unsigned range + * simultaneously. + * + * **Description**:\n + * This instruction limits the 32-bit signed integer elements stored in Rs1 into an + * unsigned integer range between 2imm5u-1 and 0, and writes the limited results to Rd. For example, if + * imm5u is 3, the 32-bit input values should be saturated between 7 and 0. If saturation is performed, + * set OV bit to 1. + * + * **Operations**:\n + * ~~~ + * src = Rs1.W[x]; + * if (src > (2^imm5u)-1) { + * src = (2^imm5u)-1; + * OV = 1; + * } else if (src < 0) { + * src = 0; + * OV = 1; + * } + * Rd.W[x] = src + * for RV32: x=0, + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_UCLIP32(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("uclip32 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.144. UCLIP32 ===== */ + +/* ===== Inline Function Start for 3.145. UCMPLE8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_CMP + * \brief UCMPLE8 (SIMD 8-bit Unsigned Compare Less Than & Equal) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * UCMPLE8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit unsigned integer elements less than & equal comparisons simultaneously. + * + * **Description**:\n + * This instruction compares the 8-bit unsigned integer elements in Rs1 with the 8-bit + * unsigned integer elements in Rs2 to see if the one in Rs1 is less than or equal to the one in Rs2. If it + * is true, the result is 0xFF; otherwise, the result is 0x0. The four comparison results are written to + * Rd. + * + * **Operations**:\n + * ~~~ + * Rd.B[x] = (Rs1.B[x] <=u Rs2.B[x])? 0xff : 0x0; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UCMPLE8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ucmple8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.145. UCMPLE8 ===== */ + +/* ===== Inline Function Start for 3.146. UCMPLE16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_CMP + * \brief UCMPLE16 (SIMD 16-bit Unsigned Compare Less Than & Equal) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * UCMPLE16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit unsigned integer elements less than & equal comparisons simultaneously. + * + * **Description**:\n + * This instruction compares the 16-bit unsigned integer elements in Rs1 with the 16-bit + * unsigned integer elements in Rs2 to see if the one in Rs1 is less than or equal to the one in Rs2. If it + * is true, the result is 0xFFFF; otherwise, the result is 0x0. The element comparison results are + * written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = (Rs1.H[x] <=u Rs2.H[x])? 0xffff : 0x0; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UCMPLE16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ucmple16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.146. UCMPLE16 ===== */ + +/* ===== Inline Function Start for 3.147. UCMPLT8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_CMP + * \brief UCMPLT8 (SIMD 8-bit Unsigned Compare Less Than) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * UCMPLT8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit unsigned integer elements less than comparisons simultaneously. + * + * **Description**:\n + * This instruction compares the 8-bit unsigned integer elements in Rs1 with the 8-bit + * unsigned integer elements in Rs2 to see if the one in Rs1 is less than the one in Rs2. If it is true, the + * result is 0xFF; otherwise, the result is 0x0. The element comparison results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.B[x] = (Rs1.B[x] (2^8)-1) { + * res[x] = (2^8)-1; + * OV = 1; + * } + * Rd.B[x] = res[x]; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKADD8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ukadd8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.149. UKADD8 ===== */ + +/* ===== Inline Function Start for 3.150. UKADD16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief UKADD16 (SIMD 16-bit Unsigned Saturating Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * UKADD16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit unsigned integer element saturating additions simultaneously. + * + * **Description**:\n + * This instruction adds the 16-bit unsigned integer elements in Rs1 with the 16-bit + * unsigned integer elements in Rs2. If any of the results are beyond the 16-bit unsigned number + * range (0 <= RES <= 2^16-1), they are saturated to the range and the OV bit is set to 1. The saturated + * results are written to Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.H[x] + Rs2.H[x]; + * if (res[x] > (2^16)-1) { + * res[x] = (2^16)-1; + * OV = 1; + * } + * Rd.H[x] = res[x]; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKADD16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ukadd16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.150. UKADD16 ===== */ + +/* ===== Inline Function Start for 3.151. UKADD64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_64B_ADDSUB + * \brief UKADD64 (64-bit Unsigned Saturating Addition) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * UKADD64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Add two 64-bit unsigned integers. The result is saturated to the U64 range. + * + * **RV32 Description**:\n + * This instruction adds the 64-bit unsigned integer of an even/odd pair of registers + * specified by Rs1(4,1) with the 64-bit unsigned integer of an even/odd pair of registers specified by + * Rs2(4,1). If the 64-bit result is beyond the U64 number range (0 <= U64 <= 2^64-1), it is saturated to the + * range and the OV bit is set to 1. The saturated result is written to an even/odd pair of registers + * specified by Rd(4,1). + * Rx(4,1), i.e., d, determines the even/odd pair group of two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * + * **RV64 Description**:\n + * This instruction adds the 64-bit unsigned integer in Rs1 with the 64-bit unsigned + * integer in Rs2. If the 64-bit result is beyond the U64 number range (0 <= U64 <= 2^64-1), it is saturated to + * the range and the OV bit is set to 1. The saturated result is written to Rd. + * + * **Operations**:\n + * ~~~ + * * RV32: + * t_L = CONCAT(Rt(4,1),1'b0); t_H = CONCAT(Rt(4,1),1'b1); + * a_L = CONCAT(Ra(4,1),1'b0); a_H = CONCAT(Ra(4,1),1'b1); + * b_L = CONCAT(Rb(4,1),1'b0); b_H = CONCAT(Rb(4,1),1'b1); + * result = R[a_H].R[a_L] + R[b_H].R[b_L]; + * if (result > (2^64)-1) { + * result = (2^64)-1; OV = 1; + * } + * R[t_H].R[t_L] = result; + * * RV64: + * result = Rs1 + Rs2; + * if (result > (2^64)-1) { + * result = (2^64)-1; OV = 1; + * } + * Rd = result; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_UKADD64(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("ukadd64 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.151. UKADD64 ===== */ + +/* ===== Inline Function Start for 3.152. UKADDH ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q15_SAT_ALU + * \brief UKADDH (Unsigned Addition with U16 Saturation) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * UKADDH Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Add the unsigned lower 32-bit content of two registers with U16 saturation. + * + * **Description**:\n + * The unsigned lower 32-bit content of Rs1 is added with the unsigned lower 32-bit + * content of Rs2. And the result is saturated to the 16-bit unsigned integer range of [0, 2^16-1] and then + * sign-extended and written to Rd. If saturation happens, this instruction sets the OV flag. + * + * **Operations**:\n + * ~~~ + * tmp = Rs1.W[0] + Rs2.W[0]; + * if (tmp > (2^16)-1) { + * tmp = (2^16)-1; + * OV = 1; + * } + * Rd = SE(tmp[15:0]); + * ~~~ + * + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKADDH(unsigned int a, unsigned int b) +{ + unsigned long result; + __ASM volatile("ukaddh %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.152. UKADDH ===== */ + +/* ===== Inline Function Start for 3.153. UKADDW ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q31_SAT_ALU + * \brief UKADDW (Unsigned Addition with U32 Saturation) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * UKADDW Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Add the unsigned lower 32-bit content of two registers with U32 saturation. + * + * **Description**:\n + * The unsigned lower 32-bit content of Rs1 is added with the unsigned lower 32-bit + * content of Rs2. And the result is saturated to the 32-bit unsigned integer range of [0, 2^32-1] and then + * sign-extended and written to Rd. If saturation happens, this instruction sets the OV flag. + * + * **Operations**:\n + * ~~~ + * tmp = Rs1.W[0] + Rs2.W[0]; + * if (tmp > (2^32)-1) { + * tmp[31:0] = (2^32)-1; + * OV = 1; + * } + * Rd = tmp[31:0]; // RV32 + * Rd = SE(tmp[31:0]); // RV64 + * ~~~ + * + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKADDW(unsigned int a, unsigned int b) +{ + unsigned long result; + __ASM volatile("ukaddw %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.153. UKADDW ===== */ + +/* ===== Inline Function Start for 3.154. UKCRAS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief UKCRAS16 (SIMD 16-bit Unsigned Saturating Cross Addition & Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * UKCRAS16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do one 16-bit unsigned integer element saturating addition and one 16-bit unsigned + * integer element saturating subtraction in a 32-bit chunk simultaneously. Operands are from crossed + * positions in 32-bit chunks. + * + * **Description**:\n + * This instruction adds the 16-bit unsigned integer element in [31:16] of 32-bit chunks in + * Rs1 with the 16-bit unsigned integer element in [15:0] of 32-bit chunks in Rs2; at the same time, it + * subtracts the 16-bit unsigned integer element in [31:16] of 32-bit chunks in Rs2 from the 16-bit + * unsigned integer element in [15:0] of 32-bit chunks in Rs1. If any of the results are beyond the 16-bit + * unsigned number range (0 <= RES <= 2^16-1), they are saturated to the range and the OV bit is set to 1. + * The saturated results are written to [31:16] of 32-bit chunks in Rd for addition and [15:0] of 32-bit + * chunks in Rd for subtraction. + * + * **Operations**:\n + * ~~~ + * res1 = Rs1.W[x][31:16] + Rs2.W[x][15:0]; + * res2 = Rs1.W[x][15:0] - Rs2.W[x][31:16]; + * if (res1 > (2^16)-1) { + * res1 = (2^16)-1; + * OV = 1; + * } + * if (res2 < 0) { + * res2 = 0; + * OV = 1; + * } + * Rd.W[x][31:16] = res1; + * Rd.W[x][15:0] = res2; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKCRAS16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ukcras16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.154. UKCRAS16 ===== */ + +/* ===== Inline Function Start for 3.155. UKCRSA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief UKCRSA16 (SIMD 16-bit Unsigned Saturating Cross Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * UKCRSA16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do one 16-bit unsigned integer element saturating subtraction and one 16-bit unsigned + * integer element saturating addition in a 32-bit chunk simultaneously. Operands are from crossed + * positions in 32-bit chunks. + * + * **Description**:\n + * This instruction subtracts the 16-bit unsigned integer element in [15:0] of 32-bit + * chunks in Rs2 from the 16-bit unsigned integer element in [31:16] of 32-bit chunks in Rs1; at the + * same time, it adds the 16-bit unsigned integer element in [31:16] of 32-bit chunks in Rs2 with the 16- + * bit unsigned integer element in [15:0] of 32-bit chunks in Rs1. If any of the results are beyond the + * 16-bit unsigned number range (0 <= RES <= 2^16-1), they are saturated to the range and the OV bit is set + * to 1. The saturated results are written to [31:16] of 32-bit chunks in Rd for subtraction and [15:0] of + * 32-bit chunks in Rd for addition. + * + * **Operations**:\n + * ~~~ + * res1 = Rs1.W[x][31:16] - Rs2.W[x][15:0]; + * res2 = Rs1.W[x][15:0] + Rs2.W[x][31:16]; + * if (res1 < 0) { + * res1 = 0; + * OV = 1; + * } else if (res2 > (2^16)-1) { + * res2 = (2^16)-1; + * OV = 1; + * } + * Rd.W[x][31:16] = res1; + * Rd.W[x][15:0] = res2; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKCRSA16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ukcrsa16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.155. UKCRSA16 ===== */ + +/* ===== Inline Function Start for 3.156. UKMAR64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_32B_MULT_64B_ADDSUB + * \brief UKMAR64 (Unsigned Multiply and Saturating Add to 64-Bit Data) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * UKMAR64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the 32-bit unsigned elements in two registers and add the 64-bit multiplication + * results to the 64-bit unsigned data of a pair of registers (RV32) or a register (RV64). The result is + * saturated to the U64 range and written back to the pair of registers (RV32) or the register (RV64). + * + * **RV32 Description**:\n + * This instruction multiplies the 32-bit unsigned data of Rs1 with that of Rs2. It + * adds the 64-bit multiplication result to the 64-bit unsigned data of an even/odd pair of registers + * specified by Rd(4,1) with unlimited precision. If the 64-bit addition result is beyond the U64 number + * range (0 <= U64 <= 2^64-1), it is saturated to the range and the OV bit is set to 1. The saturated result is + * written back to the even/odd pair of registers specified by Rd(4,1). + * Rx(4,1), i.e., d, determines the even/odd pair group of two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * + * **RV64 Description**:\n + * This instruction multiplies the 32-bit unsigned elements of Rs1 with that of Rs2. + * It adds the 64-bit multiplication results to the 64-bit unsigned data in Rd with unlimited precision. If + * the 64-bit addition result is beyond the U64 number range (0 <= U64 <= 2^64-1), it is saturated to the + * range and the OV bit is set to 1. The saturated result is written back to Rd. + * + * **Operations**:\n + * ~~~ + * * RV32: + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * result = R[t_H].R[t_L] + (Rs1 * Rs2); + * if (result > (2^64)-1) { + * result = (2^64)-1; OV = 1; + * } + * R[t_H].R[t_L] = result; + * * RV64: + * // `result` has unlimited precision + * result = Rd + (Rs1.W[0] u* Rs2.W[0]) + (Rs1.W[1] u* Rs2.W[1]); + * if (result > (2^64)-1) { + * result = (2^64)-1; OV = 1; + * } + * Rd = result; + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_UKMAR64(unsigned long long t, unsigned long a, unsigned long b) +{ + __ASM volatile("ukmar64 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.156. UKMAR64 ===== */ + +/* ===== Inline Function Start for 3.157. UKMSR64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_32B_MULT_64B_ADDSUB + * \brief UKMSR64 (Unsigned Multiply and Saturating Subtract from 64-Bit Data) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * UKMSR64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the 32-bit unsigned elements in two registers and subtract the 64-bit + * multiplication results from the 64-bit unsigned data of a pair of registers (RV32) or a register (RV64). + * The result is saturated to the U64 range and written back to the pair of registers (RV32) or a register + * (RV64). + * + * **RV32 Description**:\n + * This instruction multiplies the 32-bit unsigned data of Rs1 with that of Rs2. It + * subtracts the 64-bit multiplication result from the 64-bit unsigned data of an even/odd pair of + * registers specified by Rd(4,1) with unlimited precision. If the 64-bit subtraction result is beyond the + * U64 number range (0 <= U64 <= 2^64-1), it is saturated to the range and the OV bit is set to 1. The + * saturated result is written back to the even/odd pair of registers specified by Rd(4,1). + * Rx(4,1), i.e., d, determines the even/odd pair group of two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * + * **RV64 Description**:\n + * This instruction multiplies the 32-bit unsigned elements of Rs1 with that of Rs2. + * It subtracts the 64-bit multiplication results from the 64-bit unsigned data of Rd with unlimited + * precision. If the 64-bit subtraction result is beyond the U64 number range (0 <= U64 <= 2^64-1), it is + * saturated to the range and the OV bit is set to 1. The saturated result is written back to Rd. + * + * **Operations**:\n + * ~~~ + * * RV32: + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * result = R[t_H].R[t_L] - (Rs1 u* Rs2); + * if (result < 0) { + * result = 0; OV = 1; + * } + * R[t_H].R[t_L] = result; + * * RV64: + * // `result` has unlimited precision + * result = Rd - (Rs1.W[0] u* Rs2.W[0]) - (Rs1.W[1] u* Rs2.W[1]); + * if (result < 0) { + * result = 0; OV = 1; + * } + * Rd = result; + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_UKMSR64(unsigned long long t, unsigned long a, unsigned long b) +{ + __ASM volatile("ukmsr64 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.157. UKMSR64 ===== */ + +/* ===== Inline Function Start for 3.158. UKSTAS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief UKSTAS16 (SIMD 16-bit Unsigned Saturating Straight Addition & Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * UKSTAS16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do one 16-bit unsigned integer element saturating addition and one 16-bit unsigned + * integer element saturating subtraction in a 32-bit chunk simultaneously. Operands are from + * corresponding positions in 32-bit chunks. + * + * **Description**:\n + * This instruction adds the 16-bit unsigned integer element in [31:16] of 32-bit chunks in + * Rs1 with the 16-bit unsigned integer element in [31:16] of 32-bit chunks in Rs2; at the same time, it + * subtracts the 16-bit unsigned integer element in [15:0] of 32-bit chunks in Rs2 from the 16-bit + * unsigned integer element in [15:0] of 32-bit chunks in Rs1. If any of the results are beyond the 16-bit + * unsigned number range (0 <= RES <= 2^16-1), they are saturated to the range and the OV bit is set to 1. + * The saturated results are written to [31:16] of 32-bit chunks in Rd for addition and [15:0] of 32-bit + * chunks in Rd for subtraction. + * + * **Operations**:\n + * ~~~ + * res1 = Rs1.W[x][31:16] + Rs2.W[x][31:16]; + * res2 = Rs1.W[x][15:0] - Rs2.W[x][15:0]; + * if (res1 > (2^16)-1) { + * res1 = (2^16)-1; + * OV = 1; + * } + * if (res2 < 0) { + * res2 = 0; + * OV = 1; + * } + * Rd.W[x][31:16] = res1; + * Rd.W[x][15:0] = res2; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKSTAS16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ukstas16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.158. UKSTAS16 ===== */ + +/* ===== Inline Function Start for 3.159. UKSTSA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief UKSTSA16 (SIMD 16-bit Unsigned Saturating Straight Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * UKSTSA16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do one 16-bit unsigned integer element saturating subtraction and one 16-bit unsigned + * integer element saturating addition in a 32-bit chunk simultaneously. Operands are from + * corresponding positions in 32-bit chunks. + * + * **Description**:\n + * This instruction subtracts the 16-bit unsigned integer element in [31:16] of 32-bit + * chunks in Rs2 from the 16-bit unsigned integer element in [31:16] of 32-bit chunks in Rs1; at the + * same time, it adds the 16-bit unsigned integer element in [15:0] of 32-bit chunks in Rs2 with the 16- + * bit unsigned integer element in [15:0] of 32-bit chunks in Rs1. If any of the results are beyond the + * 16-bit unsigned number range (0 <= RES <= 2^16-1), they are saturated to the range and the OV bit is set + * to 1. The saturated results are written to [31:16] of 32-bit chunks in Rd for subtraction and [15:0] of + * 32-bit chunks in Rd for addition. + * + * **Operations**:\n + * ~~~ + * res1 = Rs1.W[x][31:16] - Rs2.W[x][31:16]; + * res2 = Rs1.W[x][15:0] + Rs2.W[x][15:0]; + * if (res1 < 0) { + * res1 = 0; + * OV = 1; + * } else if (res2 > (2^16)-1) { + * res2 = (2^16)-1; + * OV = 1; + * } + * Rd.W[x][31:16] = res1; + * Rd.W[x][15:0] = res2; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKSTSA16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ukstsa16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.159. UKSTSA16 ===== */ + +/* ===== Inline Function Start for 3.160. UKSUB8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_ADDSUB + * \brief UKSUB8 (SIMD 8-bit Unsigned Saturating Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * UKSUB8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit unsigned integer elements saturating subtractions simultaneously. + * + * **Description**:\n + * This instruction subtracts the 8-bit unsigned integer elements in Rs2 from the 8-bit + * unsigned integer elements in Rs1. If any of the results are beyond the 8-bit unsigned number range + * (0 <= RES <= 28-1), they are saturated to the range and the OV bit is set to 1. The saturated results are + * written to Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.B[x] - Rs2.B[x]; + * if (res[x] < 0) { + * res[x] = 0; + * OV = 1; + * } + * Rd.B[x] = res[x]; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKSUB8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("uksub8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.160. UKSUB8 ===== */ + +/* ===== Inline Function Start for 3.161. UKSUB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief UKSUB16 (SIMD 16-bit Unsigned Saturating Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * UKSUB16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit unsigned integer elements saturating subtractions simultaneously. + * + * **Description**:\n + * This instruction subtracts the 16-bit unsigned integer elements in Rs2 from the 16-bit + * unsigned integer elements in Rs1. If any of the results are beyond the 16-bit unsigned number + * range (0 <= RES <= 2^16-1), they are saturated to the range and the OV bit is set to 1. The saturated + * results are written to Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.H[x] - Rs2.H[x]; + * if (res[x] < 0) { + * res[x] = 0; + * OV = 1; + * } + * Rd.H[x] = res[x]; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKSUB16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("uksub16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.161. UKSUB16 ===== */ + +/* ===== Inline Function Start for 3.162. UKSUB64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_64B_ADDSUB + * \brief UKSUB64 (64-bit Unsigned Saturating Subtraction) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * UKSUB64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Perform a 64-bit signed integer subtraction. The result is saturated to the U64 range. + * + * **RV32 Description**:\n + * This instruction subtracts the 64-bit unsigned integer of an even/odd pair of + * registers specified by Rs2(4,1) from the 64-bit unsigned integer of an even/odd pair of registers + * specified by Rs1(4,1). If the 64-bit result is beyond the U64 number range (0 <= U64 <= 2^64-1), it is + * saturated to the range and the OV bit is set to 1. The saturated result is then written to an even/odd + * pair of registers specified by Rd(4,1). + * Rx(4,1), i.e., d, determines the even/odd pair group of two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the operand and the even `2d` + * register of the pair contains the low 32-bit of the operand. + * + * **RV64 Description**:\n + * This instruction subtracts the 64-bit unsigned integer of Rs2 from the 64-bit + * unsigned integer of an even/odd pair of Rs1. If the 64-bit result is beyond the U64 number range (0 <= + * U64 <= 2^64-1), it is saturated to the range and the OV bit is set to 1. The saturated result is then written + * to Rd. + * + * **Operations**:\n + * ~~~ + * * RV32: + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * a_L = CONCAT(Rs1(4,1),1'b0); a_H = CONCAT(Rs1(4,1),1'b1); + * b_L = CONCAT(Rs2(4,1),1'b0); b_H = CONCAT(Rs2(4,1),1'b1); + * result = R[a_H].R[a_L] - R[b_H].R[b_L]; + * if (result < 0) { + * result = 0; OV = 1; + * } + * R[t_H].R[t_L] = result; + * * RV64 + * result = Rs1 - Rs2; + * if (result < 0) { + * result = 0; OV = 1; + * } + * Rd = result; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_UKSUB64(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("uksub64 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.162. UKSUB64 ===== */ + +/* ===== Inline Function Start for 3.163. UKSUBH ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q15_SAT_ALU + * \brief UKSUBH (Unsigned Subtraction with U16 Saturation) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * UKSUBH Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Subtract the unsigned lower 32-bit content of two registers with U16 saturation. + * + * **Description**:\n + * The unsigned lower 32-bit content of Rs2 is subtracted from the unsigned lower 32-bit + * content of Rs1. And the result is saturated to the 16-bit unsigned integer range of [0, 2^16-1] and then + * sign-extended and written to Rd. If saturation happens, this instruction sets the OV flag. + * + * **Operations**:\n + * ~~~ + * tmp = Rs1.W[0] - Rs2.W[0]; + * if (tmp > (2^16)-1) { + * tmp = (2^16)-1; + * OV = 1; + * } + * else if (tmp < 0) { + * tmp = 0; + * OV = 1; + * } + * Rd = SE(tmp[15:0]); + * ~~~ + * + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKSUBH(unsigned int a, unsigned int b) +{ + unsigned long result; + __ASM volatile("uksubh %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.163. UKSUBH ===== */ + +/* ===== Inline Function Start for 3.164. UKSUBW ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q31_SAT_ALU + * \brief UKSUBW (Unsigned Subtraction with U32 Saturation) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * UKSUBW Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Subtract the unsigned lower 32-bit content of two registers with unsigned 32-bit + * saturation. + * + * **Description**:\n + * The unsigned lower 32-bit content of Rs2 is subtracted from the unsigned lower 32-bit + * content of Rs1. And the result is saturated to the 32-bit unsigned integer range of [0, 2^32-1] and then + * sign-extended and written to Rd. If saturation happens, this instruction sets the OV flag. + * + * **Operations**:\n + * ~~~ + * tmp = Rs1.W[0] - Rs2.W[0]; + * if (tmp < 0) { + * tmp[31:0] = 0; + * OV = 1; + * } + * Rd = tmp[31:0]; // RV32 + * Rd = SE(tmp[31:0]); // RV64 + * ~~~ + * + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKSUBW(unsigned int a, unsigned int b) +{ + unsigned long result; + __ASM volatile("uksubw %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.164. UKSUBW ===== */ + +/* ===== Inline Function Start for 3.165. UMAR64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_32B_MULT_64B_ADDSUB + * \brief UMAR64 (Unsigned Multiply and Add to 64-Bit Data) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * UMAR64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the 32-bit unsigned elements in two registers and add the 64-bit multiplication + * results to the 64-bit unsigned data of a pair of registers (RV32) or a register (RV64). The result is + * written back to the pair of registers (RV32) or a register (RV64). + * + * **RV32 Description**:\n + * This instruction multiplies the 32-bit unsigned data of Rs1 with that of Rs2. It + * adds the 64-bit multiplication result to the 64-bit unsigned data of an even/odd pair of registers + * specified by Rd(4,1). The addition result is written back to the even/odd pair of registers specified by + * Rd(4,1). + * Rx(4,1), i.e., d, determines the even/odd pair group of two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * + * **RV64 Description**:\n + * This instruction multiplies the 32-bit unsigned elements of Rs1 with that of Rs2. + * It adds the 64-bit multiplication results to the 64-bit unsigned data of Rd. The addition result is + * written back to Rd. + * + * **Operations**:\n + * ~~~ + * * RV32: + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * R[t_H].R[t_L] = R[t_H].R[t_L] + (Rs1 * Rs2); + * * RV64: + * Rd = Rd + (Rs1.W[0] u* Rs2.W[0]) + (Rs1.W[1] u* Rs2.W[1]); + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_UMAR64(unsigned long long t, unsigned long a, unsigned long b) +{ + __ASM volatile("umar64 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.165. UMAR64 ===== */ + +/* ===== Inline Function Start for 3.166. UMAQA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_8B_MULT_32B_ADD + * \brief UMAQA (Unsigned Multiply Four Bytes with 32- bit Adds) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * UMAQA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do four unsigned 8-bit multiplications from 32-bit chunks of two registers; and then adds + * the four 16-bit results and the content of corresponding 32-bit chunks of a third register together. + * + * **Description**:\n + * This instruction multiplies the four unsigned 8-bit elements of 32-bit chunks of Rs1 with the four + * unsigned 8-bit elements of 32-bit chunks of Rs2 and then adds the four results together with the + * unsigned content of the corresponding 32-bit chunks of Rd. The final results are written back to the + * corresponding 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rd.W[x] + (Rs1.W[x].B[3] u* Rs2.W[x].B[3]) + + * (Rs1.W[x].B[2] u* Rs2.W[x].B[2]) + (Rs1.W[x].B[1] u* Rs2.W[x].B[1]) + + * (Rs1.W[x].B[0] u* Rs2.W[x].B[0]); + * Rd.W[x] = res[x]; + * for RV32: x=0, + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t unsigned long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UMAQA(unsigned long t, unsigned long a, unsigned long b) +{ + __ASM volatile("umaqa %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.166. UMAQA ===== */ + +/* ===== Inline Function Start for 3.167. UMAX8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_MISC + * \brief UMAX8 (SIMD 8-bit Unsigned Maximum) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * UMAX8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit unsigned integer elements finding maximum operations simultaneously. + * + * **Description**:\n + * This instruction compares the 8-bit unsigned integer elements in Rs1 with the four 8- + * bit unsigned integer elements in Rs2 and selects the numbers that is greater than the other one. The + * two selected results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.B[x] = (Rs1.B[x] >u Rs2.B[x])? Rs1.B[x] : Rs2.B[x]; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UMAX8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("umax8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.167. UMAX8 ===== */ + +/* ===== Inline Function Start for 3.168. UMAX16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_MISC + * \brief UMAX16 (SIMD 16-bit Unsigned Maximum) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * UMAX16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit unsigned integer elements finding maximum operations simultaneously. + * + * **Description**:\n + * This instruction compares the 16-bit unsigned integer elements in Rs1 with the 16-bit + * unsigned integer elements in Rs2 and selects the numbers that is greater than the other one. The + * selected results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = (Rs1.H[x] >u Rs2.H[x])? Rs1.H[x] : Rs2.H[x]; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UMAX16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("umax16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.168. UMAX16 ===== */ + +/* ===== Inline Function Start for 3.169. UMIN8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_MISC + * \brief UMIN8 (SIMD 8-bit Unsigned Minimum) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * UMIN8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit unsigned integer elements finding minimum operations simultaneously. + * + * **Description**:\n + * This instruction compares the 8-bit unsigned integer elements in Rs1 with the 8-bit + * unsigned integer elements in Rs2 and selects the numbers that is less than the other one. The + * selected results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.B[x] = (Rs1.B[x] > 1; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_URADD8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("uradd8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.174. URADD8 ===== */ + +/* ===== Inline Function Start for 3.175. URADD16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief URADD16 (SIMD 16-bit Unsigned Halving Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * URADD16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit unsigned integer element additions simultaneously. The results are halved to + * avoid overflow or saturation. + * + * **Description**:\n + * This instruction adds the 16-bit unsigned integer elements in Rs1 with the 16-bit + * unsigned integer elements in Rs2. The results are first logically right-shifted by 1 bit and then + * written to Rd. + * + * **Examples**:\n + * ~~~ + * * Ra = 0x7FFF, Rb = 0x7FFF Rt = 0x7FFF + * * Ra = 0x8000, Rb = 0x8000 Rt = 0x8000 + * * Ra = 0x4000, Rb = 0x8000 Rt = 0x6000 + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = (Rs1.H[x] + Rs2.H[x]) u>> 1; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_URADD16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("uradd16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.175. URADD16 ===== */ + +/* ===== Inline Function Start for 3.176. URADD64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_64B_ADDSUB + * \brief URADD64 (64-bit Unsigned Halving Addition) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * URADD64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Add two 64-bit unsigned integers. The result is halved to avoid overflow or saturation. + * + * **RV32 Description**:\n + * This instruction adds the 64-bit unsigned integer of an even/odd pair of registers + * specified by Rs1(4,1) with the 64-bit unsigned integer of an even/odd pair of registers specified by + * Rs2(4,1). The 64-bit addition result is first logically right-shifted by 1 bit and then written to an + * even/odd pair of registers specified by Rd(4,1). + * Rx(4,1), i.e., d, determines the even/odd pair group of two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * + * **RV64 Description**:\n + * This instruction adds the 64-bit unsigned integer in Rs1 with the 64-bit unsigned + * integer Rs2. The 64-bit addition result is first logically right-shifted by 1 bit and then written to Rd. + * + * **Operations**:\n + * ~~~ + * * RV32: + * t_L = CONCAT(Rt(4,1),1'b0); t_H = CONCAT(Rt(4,1),1'b1); + * a_L = CONCAT(Ra(4,1),1'b0); a_H = CONCAT(Ra(4,1),1'b1); + * b_L = CONCAT(Rb(4,1),1'b0); b_H = CONCAT(Rb(4,1),1'b1); + * R[t_H].R[t_L] = (R[a_H].R[a_L] + R[b_H].R[b_L]) u>> 1; + * * RV64: + * Rd = (Rs1 + Rs2) u>> 1; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_URADD64(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("uradd64 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.176. URADD64 ===== */ + +/* ===== Inline Function Start for 3.177. URADDW ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_32B_COMPUTATION + * \brief URADDW (32-bit Unsigned Halving Addition) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * URADDW Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Add 32-bit unsigned integers and the results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction adds the first 32-bit unsigned integer in Rs1 with the first 32-bit + * unsigned integer in Rs2. The result is first logically right-shifted by 1 bit and then sign-extended and + * written to Rd. + * + * **Examples**:\n + * ~~~ + * * Ra = 0x7FFFFFFF, Rb = 0x7FFFFFFF Rt = 0x7FFFFFFF + * * Ra = 0x80000000, Rb = 0x80000000 Rt = 0x80000000 + * * Ra = 0x40000000, Rb = 0x80000000 Rt = 0x60000000 + * ~~~ + * + * **Operations**:\n + * ~~~ + * * RV32: + * Rd[31:0] = (Rs1[31:0] + Rs2[31:0]) u>> 1; + * * RV64: + * resw[31:0] = (Rs1[31:0] + Rs2[31:0]) u>> 1; + * Rd[63:0] = SE(resw[31:0]); + * ~~~ + * + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_URADDW(unsigned int a, unsigned int b) +{ + unsigned long result; + __ASM volatile("uraddw %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.177. URADDW ===== */ + +/* ===== Inline Function Start for 3.178. URCRAS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief URCRAS16 (SIMD 16-bit Unsigned Halving Cross Addition & Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * URCRAS16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit unsigned integer element addition and 16-bit unsigned integer element + * subtraction in a 32-bit chunk simultaneously. Operands are from crossed positions in 32-bit chunks. + * The results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction adds the 16-bit unsigned integer in [31:16] of 32-bit chunks in Rs1 + * with the 16-bit unsigned integer in [15:0] of 32-bit chunks in Rs2, and subtracts the 16-bit unsigned + * integer in [31:16] of 32-bit chunks in Rs2 from the 16-bit unsigned integer in [15:0] of 32-bit chunks + * in Rs1. The element results are first logically right-shifted by 1 bit and then written to [31:16] of 32- + * bit chunks in Rd and [15:0] of 32-bit chunks in Rd. + * + * **Examples**:\n + * ~~~ + * Please see `URADD16` and `URSUB16` instructions. + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:16] = (Rs1.W[x][31:16] + Rs2.W[x][15:0]) u>> 1; + * Rd.W[x][15:0] = (Rs1.W[x][15:0] - Rs2.W[x][31:16]) u>> 1; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_URCRAS16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("urcras16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.178. URCRAS16 ===== */ + +/* ===== Inline Function Start for 3.179. URCRSA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief URCRSA16 (SIMD 16-bit Unsigned Halving Cross Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * URCRSA16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit unsigned integer element subtraction and 16-bit unsigned integer element + * addition in a 32-bit chunk simultaneously. Operands are from crossed positions in 32-bit chunks. + * The results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 16-bit unsigned integer in [15:0] of 32-bit chunks in Rs2 + * from the 16-bit unsigned integer in [31:16] of 32-bit chunks in Rs1, and adds the 16-bit unsigned + * integer in [15:0] of 32-bit chunks in Rs1 with the 16-bit unsigned integer in [31:16] of 32-bit chunks + * in Rs2. The two results are first logically right-shifted by 1 bit and then written to [31:16] of 32-bit + * chunks in Rd and [15:0] of 32-bit chunks in Rd. + * + * **Examples**:\n + * ~~~ + * Please see `URADD16` and `URSUB16` instructions. + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:16] = (Rs1.W[x][31:16] - Rs2.W[x][15:0]) u>> 1; + * Rd.W[x][15:0] = (Rs1.W[x][15:0] + Rs2.W[x][31:16]) u>> 1; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_URCRSA16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("urcrsa16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.179. URCRSA16 ===== */ + +/* ===== Inline Function Start for 3.180. URSTAS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief URSTAS16 (SIMD 16-bit Unsigned Halving Straight Addition & Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * URSTAS16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit unsigned integer element addition and 16-bit unsigned integer element + * subtraction in a 32-bit chunk simultaneously. Operands are from corresponding positions in 32-bit + * chunks. The results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction adds the 16-bit unsigned integer in [31:16] of 32-bit chunks in Rs1 + * with the 16-bit unsigned integer in [31:16] of 32-bit chunks in Rs2, and subtracts the 16-bit unsigned + * integer in [15:0] of 32-bit chunks in Rs2 from the 16-bit unsigned integer in [15:0] of 32-bit chunks + * in Rs1. The element results are first logically right-shifted by 1 bit and then written to [31:16] of 32- + * bit chunks in Rd and [15:0] of 32-bit chunks in Rd. + * + * **Examples**:\n + * ~~~ + * Please see `URADD16` and `URSUB16` instructions. + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:16] = (Rs1.W[x][31:16] + Rs2.W[x][31:16]) u>> 1; + * Rd.W[x][15:0] = (Rs1.W[x][15:0] - Rs2.W[x][15:0]) u>> 1; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_URSTAS16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("urstas16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.180. URSTAS16 ===== */ + +/* ===== Inline Function Start for 3.181. URSTSA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief URSTSA16 (SIMD 16-bit Unsigned Halving Straight Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * URCRSA16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit unsigned integer element subtraction and 16-bit unsigned integer element + * addition in a 32-bit chunk simultaneously. Operands are from corresponding positions in 32-bit + * chunks. The results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 16-bit unsigned integer in [31:16] of 32-bit chunks in Rs2 + * from the 16-bit unsigned integer in [31:16] of 32-bit chunks in Rs1, and adds the 16-bit unsigned + * integer in [15:0] of 32-bit chunks in Rs1 with the 16-bit unsigned integer in [15:0] of 32-bit chunks in + * Rs2. The two results are first logically right-shifted by 1 bit and then written to [31:16] of 32-bit + * chunks in Rd and [15:0] of 32-bit chunks in Rd. + * + * **Examples**:\n + * ~~~ + * Please see `URADD16` and `URSUB16` instructions. + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:16] = (Rs1.W[x][31:16] - Rs2.W[x][31:16]) u>> 1; + * Rd.W[x][15:0] = (Rs1.W[x][15:0] + Rs2.W[x][15:0]) u>> 1; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_URSTSA16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("urstsa16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.181. URSTSA16 ===== */ + +/* ===== Inline Function Start for 3.182. URSUB8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_ADDSUB + * \brief URSUB8 (SIMD 8-bit Unsigned Halving Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * URSUB8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit unsigned integer element subtractions simultaneously. The results are halved to + * avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 8-bit unsigned integer elements in Rs2 from the 8-bit + * unsigned integer elements in Rs1. The results are first logically right-shifted by 1 bit and then + * written to Rd. + * + * **Examples**:\n + * ~~~ + * * Ra = 0x7F, Rb = 0x80 Rt = 0xFF + * * Ra = 0x80, Rb = 0x7F Rt = 0x00 + * * Ra = 0x80, Rb = 0x40 Rt = 0x20 + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.B[x] = (Rs1.B[x] - Rs2.B[x]) u>> 1; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_URSUB8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ursub8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.182. URSUB8 ===== */ + +/* ===== Inline Function Start for 3.183. URSUB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief URSUB16 (SIMD 16-bit Unsigned Halving Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * URSUB16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit unsigned integer element subtractions simultaneously. The results are halved to + * avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 16-bit unsigned integer elements in Rs2 from the 16-bit + * unsigned integer elements in Rs1. The results are first logically right-shifted by 1 bit and then + * written to Rd. + * + * **Examples**:\n + * ~~~ + * * Ra = 0x7FFF, Rb = 0x8000 Rt = 0xFFFF + * * Ra = 0x8000, Rb = 0x7FFF Rt = 0x0000 + * * Ra = 0x8000, Rb = 0x4000 Rt = 0x2000 + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = (Rs1.H[x] - Rs2.H[x]) u>> 1; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_URSUB16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ursub16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.183. URSUB16 ===== */ + +/* ===== Inline Function Start for 3.184. URSUB64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_64B_ADDSUB + * \brief URSUB64 (64-bit Unsigned Halving Subtraction) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * URSUB64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Perform a 64-bit unsigned integer subtraction. The result is halved to avoid overflow or + * saturation. + * + * **RV32 Description**:\n + * This instruction subtracts the 64-bit unsigned integer of an even/odd pair of + * registers specified by Rs2(4,1) from the 64-bit unsigned integer of an even/odd pair of registers + * specified by Rs1(4,1). The subtraction result is first logically right-shifted by 1 bit and then written + * to an even/odd pair of registers specified by Rd(4,1). + * Rx(4,1), i.e., d, determines the even/odd pair group of two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * + * **RV64 Description**:\n + * This instruction subtracts the 64-bit unsigned integer in Rs2 from the 64-bit + * unsigned integer in Rs1. The subtraction result is first logically right-shifted by 1 bit and then + * written to Rd. + * + * **Operations**:\n + * ~~~ + * * RV32: + * t_L = CONCAT(Rt(4,1),1'b0); t_H = CONCAT(Rt(4,1),1'b1); + * a_L = CONCAT(Ra(4,1),1'b0); a_H = CONCAT(Ra(4,1),1'b1); + * b_L = CONCAT(Rb(4,1),1'b0); b_H = CONCAT(Rb(4,1),1'b1); + * R[t_H].R[t_L] = (R[a_H].R[a_L] - R[b_H].R[b_L]) u>> 1; + * * RV64: + * Rd = (Rs1 - Rs2) u>> 1; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_URSUB64(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("ursub64 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.184. URSUB64 ===== */ + +/* ===== Inline Function Start for 3.185. URSUBW ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_32B_COMPUTATION + * \brief URSUBW (32-bit Unsigned Halving Subtraction) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * URSUBW Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Subtract 32-bit unsigned integers and the result is halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the first 32-bit signed integer in Rs2 from the first 32-bit + * signed integer in Rs1. The result is first logically right-shifted by 1 bit and then sign-extended and + * written to Rd. + * + * **Examples**:\n + * ~~~ + * * Ra = 0x7FFFFFFF, Rb = 0x80000000 Rt = 0xFFFFFFFF + * * Ra = 0x80000000, Rb = 0x7FFFFFFF Rt = 0x00000000 + * * Ra = 0x80000000, Rb = 0x40000000 Rt = 0x20000000 + * ~~~ + * + * **Operations**:\n + * ~~~ + * * RV32: + * Rd[31:0] = (Rs1[31:0] - Rs2[31:0]) u>> 1; + * * RV64: + * resw[31:0] = (Rs1[31:0] - Rs2[31:0]) u>> 1; + * Rd[63:0] = SE(resw[31:0]); + * ~~~ + * + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_URSUBW(unsigned int a, unsigned int b) +{ + unsigned long result; + __ASM volatile("ursubw %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.185. URSUBW ===== */ + +/* ===== Inline Function Start for 3.186. WEXTI ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_MISC + * \brief WEXTI (Extract Word from 64-bit Immediate) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * WEXTI Rd, Rs1, #LSBloc + * ~~~ + * + * **Purpose**:\n + * Extract a 32-bit word from a 64-bit value stored in an even/odd pair of registers (RV32) or + * a register (RV64) starting from a specified immediate LSB bit position. + * + * **RV32 Description**:\n + * This instruction extracts a 32-bit word from a 64-bit value of an even/odd pair of registers specified + * by Rs1(4,1) starting from a specified immediate LSB bit position, #LSBloc. The extracted word is + * written to Rd. + * Rs1(4,1), i.e., d, determines the even/odd pair group of the two registers. Specifically, the register + * pair includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the 64-bit value and the even `2d` + * register of the pair contains the low 32-bit of the 64-bit value. + * + * **RV64 Description**:\n + * This instruction extracts a 32-bit word from a 64-bit value in Rs1 starting from a specified + * immediate LSB bit position, #LSBloc. The extracted word is sign-extended and written to lower 32- + * bit of Rd. + * + * **Operations**:\n + * ~~~ + * * RV32: + * Idx0 = CONCAT(Rs1(4,1),1'b0); Idx1 = CONCAT(Rs2(4,1),1'b1); + * src[63:0] = Concat(R[Idx1], R[Idx0]); + * Rd = src[31+LSBloc:LSBloc]; + * * RV64: + * ExtractW = Rs1[31+LSBloc:LSBloc]; + * Rd = SE(ExtractW) + * ~~~ + * + * \param [in] a long long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_WEXTI(a, b) \ + ({ \ + unsigned long result; \ + long long __a = (long long)(a); \ + __ASM volatile("wexti %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.186. WEXTI ===== */ + +/* ===== Inline Function Start for 3.187. WEXT ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_MISC + * \brief WEXT (Extract Word from 64-bit) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * WEXT Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Extract a 32-bit word from a 64-bit value stored in an even/odd pair of registers (RV32) or + * a register (RV64) starting from a specified LSB bit position in a register. + * + * **RV32 Description**:\n + * This instruction extracts a 32-bit word from a 64-bit value of an even/odd pair of registers specified + * by Rs1(4,1) starting from a specified LSB bit position, specified in Rs2[4:0]. The extracted word is + * written to Rd. + * Rs1(4,1), i.e., d, determines the even/odd pair group of the two registers. Specifically, the register + * pair includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the 64-bit value and the even `2d` + * register of the pair contains the low 32-bit of the 64-bit value. + * + * **Operations**:\n + * ~~~ + * * RV32: + * Idx0 = CONCAT(Rs1(4,1),1'b0); Idx1 = CONCAT(Rs1(4,1),1'b1); + * src[63:0] = Concat(R[Idx1], R[Idx0]); + * LSBloc = Rs2[4:0]; + * Rd = src[31+LSBloc:LSBloc]; + * * RV64: + * LSBloc = Rs2[4:0]; + * ExtractW = Rs1[31+LSBloc:LSBloc]; + * Rd = SE(ExtractW) + * ~~~ + * + * \param [in] a long long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_WEXT(long long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("wext %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.187. WEXT ===== */ + +/* ===== Inline Function Start for 3.188.1. ZUNPKD810 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_UNPACK + * \brief ZUNPKD810 (Unsigned Unpacking Bytes 1 & 0) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * ZUNPKD8xy Rd, Rs1 + * xy = {10, 20, 30, 31, 32} + * ~~~ + * + * **Purpose**:\n + * Unpack byte x and byte y of 32-bit chunks in a register into two 16-bit unsigned + * halfwords of 32-bit chunks in a register. + * + * **Description**:\n + * For the `ZUNPKD8(x)(*y*)` instruction, it unpacks byte *x and byte y* of 32-bit chunks in Rs1 into + * two 16-bit unsigned halfwords and writes the results to the top part and the bottom part of 32-bit + * chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = ZE16(Rs1.W[m].B[x]) + * Rd.W[m].H[0] = ZE16(Rs1.W[m].B[y]) + * // ZUNPKD810, x=1,y=0 + * // ZUNPKD820, x=2,y=0 + * // ZUNPKD830, x=3,y=0 + * // ZUNPKD831, x=3,y=1 + * // ZUNPKD832, x=3,y=2 + * for RV32: m=0, + * for RV64: m=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_ZUNPKD810(unsigned long a) +{ + unsigned long result; + __ASM volatile("zunpkd810 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.188.1. ZUNPKD810 ===== */ + +/* ===== Inline Function Start for 3.188.2. ZUNPKD820 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_UNPACK + * \brief ZUNPKD820 (Unsigned Unpacking Bytes 2 & 0) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * ZUNPKD8xy Rd, Rs1 + * xy = {10, 20, 30, 31, 32} + * ~~~ + * + * **Purpose**:\n + * Unpack byte x and byte y of 32-bit chunks in a register into two 16-bit unsigned + * halfwords of 32-bit chunks in a register. + * + * **Description**:\n + * For the `ZUNPKD8(x)(*y*)` instruction, it unpacks byte *x and byte y* of 32-bit chunks in Rs1 into + * two 16-bit unsigned halfwords and writes the results to the top part and the bottom part of 32-bit + * chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = ZE16(Rs1.W[m].B[x]) + * Rd.W[m].H[0] = ZE16(Rs1.W[m].B[y]) + * // ZUNPKD810, x=1,y=0 + * // ZUNPKD820, x=2,y=0 + * // ZUNPKD830, x=3,y=0 + * // ZUNPKD831, x=3,y=1 + * // ZUNPKD832, x=3,y=2 + * for RV32: m=0, + * for RV64: m=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_ZUNPKD820(unsigned long a) +{ + unsigned long result; + __ASM volatile("zunpkd820 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.188.2. ZUNPKD820 ===== */ + +/* ===== Inline Function Start for 3.188.3. ZUNPKD830 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_UNPACK + * \brief ZUNPKD830 (Unsigned Unpacking Bytes 3 & 0) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * ZUNPKD8xy Rd, Rs1 + * xy = {10, 20, 30, 31, 32} + * ~~~ + * + * **Purpose**:\n + * Unpack byte x and byte y of 32-bit chunks in a register into two 16-bit unsigned + * halfwords of 32-bit chunks in a register. + * + * **Description**:\n + * For the `ZUNPKD8(x)(*y*)` instruction, it unpacks byte *x and byte y* of 32-bit chunks in Rs1 into + * two 16-bit unsigned halfwords and writes the results to the top part and the bottom part of 32-bit + * chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = ZE16(Rs1.W[m].B[x]) + * Rd.W[m].H[0] = ZE16(Rs1.W[m].B[y]) + * // ZUNPKD810, x=1,y=0 + * // ZUNPKD820, x=2,y=0 + * // ZUNPKD830, x=3,y=0 + * // ZUNPKD831, x=3,y=1 + * // ZUNPKD832, x=3,y=2 + * for RV32: m=0, + * for RV64: m=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_ZUNPKD830(unsigned long a) +{ + unsigned long result; + __ASM volatile("zunpkd830 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.188.3. ZUNPKD830 ===== */ + +/* ===== Inline Function Start for 3.188.4. ZUNPKD831 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_UNPACK + * \brief ZUNPKD831 (Unsigned Unpacking Bytes 3 & 1) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * ZUNPKD8xy Rd, Rs1 + * xy = {10, 20, 30, 31, 32} + * ~~~ + * + * **Purpose**:\n + * Unpack byte x and byte y of 32-bit chunks in a register into two 16-bit unsigned + * halfwords of 32-bit chunks in a register. + * + * **Description**:\n + * For the `ZUNPKD8(x)(*y*)` instruction, it unpacks byte *x and byte y* of 32-bit chunks in Rs1 into + * two 16-bit unsigned halfwords and writes the results to the top part and the bottom part of 32-bit + * chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = ZE16(Rs1.W[m].B[x]) + * Rd.W[m].H[0] = ZE16(Rs1.W[m].B[y]) + * // ZUNPKD810, x=1,y=0 + * // ZUNPKD820, x=2,y=0 + * // ZUNPKD830, x=3,y=0 + * // ZUNPKD831, x=3,y=1 + * // ZUNPKD832, x=3,y=2 + * for RV32: m=0, + * for RV64: m=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_ZUNPKD831(unsigned long a) +{ + unsigned long result; + __ASM volatile("zunpkd831 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.188.4. ZUNPKD831 ===== */ + +/* ===== Inline Function Start for 3.188.5. ZUNPKD832 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_UNPACK + * \brief ZUNPKD832 (Unsigned Unpacking Bytes 3 & 2) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * ZUNPKD8xy Rd, Rs1 + * xy = {10, 20, 30, 31, 32} + * ~~~ + * + * **Purpose**:\n + * Unpack byte x and byte y of 32-bit chunks in a register into two 16-bit unsigned + * halfwords of 32-bit chunks in a register. + * + * **Description**:\n + * For the `ZUNPKD8(x)(*y*)` instruction, it unpacks byte *x and byte y* of 32-bit chunks in Rs1 into + * two 16-bit unsigned halfwords and writes the results to the top part and the bottom part of 32-bit + * chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = ZE16(Rs1.W[m].B[x]) + * Rd.W[m].H[0] = ZE16(Rs1.W[m].B[y]) + * // ZUNPKD810, x=1,y=0 + * // ZUNPKD820, x=2,y=0 + * // ZUNPKD830, x=3,y=0 + * // ZUNPKD831, x=3,y=1 + * // ZUNPKD832, x=3,y=2 + * for RV32: m=0, + * for RV64: m=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_ZUNPKD832(unsigned long a) +{ + unsigned long result; + __ASM volatile("zunpkd832 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.188.5. ZUNPKD832 ===== */ + +#if (__RISCV_XLEN == 64) || defined(__ONLY_FOR_DOXYGEN_DOCUMENT_GENERATION__) + +/* ===== Inline Function Start for 4.1. ADD32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief ADD32 (SIMD 32-bit Addition) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * ADD32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit integer element additions simultaneously. + * + * **Description**:\n + * This instruction adds the 32-bit integer elements in Rs1 with the 32-bit integer + * elements in Rs2, and then writes the 32-bit element results to Rd. + * + * **Note**:\n + * This instruction can be used for either signed or unsigned addition. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = Rs1.W[x] + Rs2.W[x]; + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_ADD32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("add32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.1. ADD32 ===== */ + +/* ===== Inline Function Start for 4.2. CRAS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief CRAS32 (SIMD 32-bit Cross Addition & Subtraction) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * CRAS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit integer element addition and 32-bit integer element subtraction in a 64-bit + * chunk simultaneously. Operands are from crossed 32-bit elements. + * + * **Description**:\n + * This instruction adds the 32-bit integer element in [63:32] of Rs1 with the 32-bit + * integer element in [31:0] of Rs2, and writes the result to [63:32] of Rd; at the same time, it subtracts + * the 32-bit integer element in [63:32] of Rs2 from the 32-bit integer element in [31:0] of Rs1, and + * writes the result to [31:0] of Rd. + * + * **Note**:\n + * This instruction can be used for either signed or unsigned operations. + * + * **Operations**:\n + * ~~~ + * Rd.W[1] = Rs1.W[1] + Rs2.W[0]; + * Rd.W[0] = Rs1.W[0] - Rs2.W[1]; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_CRAS32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("cras32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.2. CRAS32 ===== */ + +/* ===== Inline Function Start for 4.3. CRSA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief CRSA32 (SIMD 32-bit Cross Subtraction & Addition) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * CRSA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit integer element subtraction and 32-bit integer element addition in a 64-bit + * chunk simultaneously. Operands are from crossed 32-bit elements. + * *Description: * + * This instruction subtracts the 32-bit integer element in [31:0] of Rs2 from the 32-bit integer element + * in [63:32] of Rs1, and writes the result to [63:32] of Rd; at the same time, it adds the 32-bit integer + * element in [31:0] of Rs1 with the 32-bit integer element in [63:32] of Rs2, and writes the result to + * [31:0] of Rd + * + * **Note**:\n + * This instruction can be used for either signed or unsigned operations. + * + * **Operations**:\n + * ~~~ + * Rd.W[1] = Rs1.W[1] - Rs2.W[0]; + * Rd.W[0] = Rs1.W[0] + Rs2.W[1]; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_CRSA32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("crsa32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.3. CRSA32 ===== */ + +/* ===== Inline Function Start for 4.4. KABS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_MISC + * \brief KABS32 (Scalar 32-bit Absolute Value with Saturation) + * \details + * **Type**: DSP (RV64 Only) +24 20 +19 15 +14 12 +11 7 +KABS32 +10010 +Rs1 +000 +Rd +6 0 +GE80B +1111111 + * + * **Syntax**:\n + * ~~~ + * KABS32 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Get the absolute value of signed 32-bit integer elements in a general register. + * + * **Description**:\n + * This instruction calculates the absolute value of signed 32-bit integer elements stored + * in Rs1. The results are written to Rd. This instruction with the minimum negative integer input of + * 0x80000000 will produce a saturated output of maximum positive integer of 0x7fffffff and the OV + * flag will be set to 1. + * + * **Operations**:\n + * ~~~ + * if (Rs1.W[x] >= 0) { + * res[x] = Rs1.W[x]; + * } else { + * If (Rs1.W[x] == 0x80000000) { + * res[x] = 0x7fffffff; + * OV = 1; + * } else { + * res[x] = -Rs1.W[x]; + * } + * } + * Rd.W[x] = res[x]; + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KABS32(unsigned long a) +{ + unsigned long result; + __ASM volatile("kabs32 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 4.4. KABS32 ===== */ + +/* ===== Inline Function Start for 4.5. KADD32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief KADD32 (SIMD 32-bit Signed Saturating Addition) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KADD32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element saturating additions simultaneously. + * + * **Description**:\n + * This instruction adds the 32-bit signed integer elements in Rs1 with the 32-bit signed + * integer elements in Rs2. If any of the results are beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), + * they are saturated to the range and the OV bit is set to 1. The saturated results are written to Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.W[x] + Rs2.W[x]; + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KADD32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("kadd32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.5. KADD32 ===== */ + +/* ===== Inline Function Start for 4.6. KCRAS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief KCRAS32 (SIMD 32-bit Signed Saturating Cross Addition & Subtraction) + * \details + * **Type**: SIM (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KCRAS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element saturating addition and 32-bit signed integer element + * saturating subtraction in a 64-bit chunk simultaneously. Operands are from crossed 32-bit elements. + * + * **Description**:\n + * This instruction adds the 32-bit integer element in [63:32] of Rs1 with the 32-bit + * integer element in [31:0] of Rs2; at the same time, it subtracts the 32-bit integer element in [63:32] of + * Rs2 from the 32-bit integer element in [31:0] of Rs1. If any of the results are beyond the Q31 number + * range (-2^31 <= Q31 <= 2^31-1), they are saturated to the range and the OV bit is set to 1. The saturated + * results are written to [63:32] of Rd for addition and [31:0] of Rd for subtraction. + * + * **Operations**:\n + * ~~~ + * res[1] = Rs1.W[1] + Rs2.W[0]; + * res[0] = Rs1.W[0] - Rs2.W[1]; + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[1] = res[1]; + * Rd.W[0] = res[0]; + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KCRAS32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("kcras32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.6. KCRAS32 ===== */ + +/* ===== Inline Function Start for 4.7. KCRSA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief KCRSA32 (SIMD 32-bit Signed Saturating Cross Subtraction & Addition) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KCRSA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element saturating subtraction and 32-bit signed integer element + * saturating addition in a 64-bit chunk simultaneously. Operands are from crossed 32-bit elements. + * *Description: * + * This instruction subtracts the 32-bit integer element in [31:0] of Rs2 from the 32-bit integer element + * in [63:32] of Rs1; at the same time, it adds the 32-bit integer element in [31:0] of Rs1 with the 32-bit + * integer element in [63:32] of Rs2. If any of the results are beyond the Q31 number range (-2^31 <= Q31 + * <= 2^31-1), they are saturated to the range and the OV bit is set to 1. The saturated results are written to + * [63:32] of Rd for subtraction and [31:0] of Rd for addition. + * + * **Operations**:\n + * ~~~ + * res[1] = Rs1.W[1] - Rs2.W[0]; + * res[0] = Rs1.W[0] + Rs2.W[1]; + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[1] = res[1]; + * Rd.W[0] = res[0]; + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KCRSA32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("kcrsa32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.7. KCRSA32 ===== */ + +/* ===== Inline Function Start for 4.8.1. KDMBB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_Q15_SAT_MULT + * \brief KDMBB16 (SIMD Signed Saturating Double Multiply B16 x B16) + * \details + * **Type**: SIMD (RV64 only) + * + * **Syntax**:\n + * ~~~ + * KDMxy16 Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion + * of the 32-bit chunks in registers and then double and saturate the Q31 results into the 32-bit chunks + * in the destination register. If saturation happens, an overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the 32-bit portions in Rs1 with the top + * or bottom 16-bit Q15 content of the 32-bit portions in Rs2. The Q30 results are then doubled and + * saturated into Q31 values. The Q31 values are then written into the 32-bit chunks in Rd. When both + * the two Q15 inputs are 0x8000, saturation will happen. The result will be saturated to 0x7FFFFFFF + * and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * // KDMBB16: (x,y,z)=(0,0,0),(2,2,1) + * // KDMBT16: (x,y,z)=(0,1,0),(2,3,1) + * // KDMTT16: (x,y,z)=(1,1,0),(3,3,1) + * aop[z] = Rs1.H[x]; bop[z] = Rs2.H[y]; + * If (0x8000 != aop[z] | 0x8000 != bop[z]) { + * Mresult[z] = aop[z] * bop[z]; + * resQ31[z] = Mresult[z] << 1; + * } else { + * resQ31[z] = 0x7FFFFFFF; + * OV = 1; + * } + * Rd.W[z] = resQ31[z]; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KDMBB16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("kdmbb16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.8.1. KDMBB16 ===== */ + +/* ===== Inline Function Start for 4.8.2. KDMBT16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_Q15_SAT_MULT + * \brief KDMBT16 (SIMD Signed Saturating Double Multiply B16 x T16) + * \details + * **Type**: SIMD (RV64 only) + * + * **Syntax**:\n + * ~~~ + * KDMxy16 Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion + * of the 32-bit chunks in registers and then double and saturate the Q31 results into the 32-bit chunks + * in the destination register. If saturation happens, an overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the 32-bit portions in Rs1 with the top + * or bottom 16-bit Q15 content of the 32-bit portions in Rs2. The Q30 results are then doubled and + * saturated into Q31 values. The Q31 values are then written into the 32-bit chunks in Rd. When both + * the two Q15 inputs are 0x8000, saturation will happen. The result will be saturated to 0x7FFFFFFF + * and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * // KDMBB16: (x,y,z)=(0,0,0),(2,2,1) + * // KDMBT16: (x,y,z)=(0,1,0),(2,3,1) + * // KDMTT16: (x,y,z)=(1,1,0),(3,3,1) + * aop[z] = Rs1.H[x]; bop[z] = Rs2.H[y]; + * If (0x8000 != aop[z] | 0x8000 != bop[z]) { + * Mresult[z] = aop[z] * bop[z]; + * resQ31[z] = Mresult[z] << 1; + * } else { + * resQ31[z] = 0x7FFFFFFF; + * OV = 1; + * } + * Rd.W[z] = resQ31[z]; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KDMBT16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("kdmbt16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.8.2. KDMBT16 ===== */ + +/* ===== Inline Function Start for 4.8.3. KDMTT16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_Q15_SAT_MULT + * \brief KDMTT16 (SIMD Signed Saturating Double Multiply T16 x T16) + * \details + * **Type**: SIMD (RV64 only) + * + * **Syntax**:\n + * ~~~ + * KDMxy16 Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion + * of the 32-bit chunks in registers and then double and saturate the Q31 results into the 32-bit chunks + * in the destination register. If saturation happens, an overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the 32-bit portions in Rs1 with the top + * or bottom 16-bit Q15 content of the 32-bit portions in Rs2. The Q30 results are then doubled and + * saturated into Q31 values. The Q31 values are then written into the 32-bit chunks in Rd. When both + * the two Q15 inputs are 0x8000, saturation will happen. The result will be saturated to 0x7FFFFFFF + * and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * // KDMBB16: (x,y,z)=(0,0,0),(2,2,1) + * // KDMBT16: (x,y,z)=(0,1,0),(2,3,1) + * // KDMTT16: (x,y,z)=(1,1,0),(3,3,1) + * aop[z] = Rs1.H[x]; bop[z] = Rs2.H[y]; + * If (0x8000 != aop[z] | 0x8000 != bop[z]) { + * Mresult[z] = aop[z] * bop[z]; + * resQ31[z] = Mresult[z] << 1; + * } else { + * resQ31[z] = 0x7FFFFFFF; + * OV = 1; + * } + * Rd.W[z] = resQ31[z]; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KDMTT16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("kdmtt16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.8.3. KDMTT16 ===== */ + +/* ===== Inline Function Start for 4.9.1. KDMABB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_Q15_SAT_MULT + * \brief KDMABB16 (SIMD Signed Saturating Double Multiply Addition B16 x B16) + * \details + * **Type**: SIMD (RV64 only) + * + * **Syntax**:\n + * ~~~ + * KDMAxy16 Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion + * of the 32-bit chunks in registers and then double and saturate the Q31 results, add the results with + * the values of the corresponding 32-bit chunks from the destination register and write the saturated + * addition results back into the corresponding 32-bit chunks of the destination register. If saturation + * happens, an overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the 32-bit portions in Rs1 with the top + * or bottom 16-bit Q15 content of the corresponding 32-bit portions in Rs2. The Q30 results are then + * doubled and saturated into Q31 values. The Q31 values are then added with the content of the + * corresponding 32-bit portions of Rd. If the addition results are beyond the Q31 number range (-2^31 <= + * Q31 <= 2^31-1), they are saturated to the range and the OV flag is set to 1. The results after saturation + * are written back to Rd. + * When both the two Q15 inputs are 0x8000, saturation will happen and the overflow flag OV will be + * set. + * + * **Operations**:\n + * ~~~ + * // KDMABB16: (x,y,z)=(0,0,0),(2,2,1) + * // KDMABT16: (x,y,z)=(0,1,0),(2,3,1) + * // KDMATT16: (x,y,z)=(1,1,0),(3,3,1) + * aop[z] = Rs1.H[x]; bop[z] = Rs2.H[y]; + * If (0x8000 != aop[z] | 0x8000 != bop[z]) { + * Mresult[z] = aop[z] * bop[z]; + * resQ31[z] = Mresult[z] << 1; + * } else { + * resQ31[z] = 0x7FFFFFFF; + * OV = 1; + * } + * resadd[z] = Rd.W[z] + resQ31[z]; + * if (resadd[z] > (2^31)-1) { + * resadd[z] = (2^31)-1; + * OV = 1; + * } else if (resadd[z] < -2^31) { + * resadd[z] = -2^31; + * OV = 1; + * } + * Rd.W[z] = resadd[z]; + * ~~~ + * + * \param [in] t unsigned long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KDMABB16(unsigned long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kdmabb16 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 4.9.1. KDMABB16 ===== */ + +/* ===== Inline Function Start for 4.9.2. KDMABT16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_Q15_SAT_MULT + * \brief KDMABT16 (SIMD Signed Saturating Double Multiply Addition B16 x T16) + * \details + * **Type**: SIMD (RV64 only) + * + * **Syntax**:\n + * ~~~ + * KDMAxy16 Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion + * of the 32-bit chunks in registers and then double and saturate the Q31 results, add the results with + * the values of the corresponding 32-bit chunks from the destination register and write the saturated + * addition results back into the corresponding 32-bit chunks of the destination register. If saturation + * happens, an overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the 32-bit portions in Rs1 with the top + * or bottom 16-bit Q15 content of the corresponding 32-bit portions in Rs2. The Q30 results are then + * doubled and saturated into Q31 values. The Q31 values are then added with the content of the + * corresponding 32-bit portions of Rd. If the addition results are beyond the Q31 number range (-2^31 <= + * Q31 <= 2^31-1), they are saturated to the range and the OV flag is set to 1. The results after saturation + * are written back to Rd. + * When both the two Q15 inputs are 0x8000, saturation will happen and the overflow flag OV will be + * set. + * + * **Operations**:\n + * ~~~ + * // KDMABB16: (x,y,z)=(0,0,0),(2,2,1) + * // KDMABT16: (x,y,z)=(0,1,0),(2,3,1) + * // KDMATT16: (x,y,z)=(1,1,0),(3,3,1) + * aop[z] = Rs1.H[x]; bop[z] = Rs2.H[y]; + * If (0x8000 != aop[z] | 0x8000 != bop[z]) { + * Mresult[z] = aop[z] * bop[z]; + * resQ31[z] = Mresult[z] << 1; + * } else { + * resQ31[z] = 0x7FFFFFFF; + * OV = 1; + * } + * resadd[z] = Rd.W[z] + resQ31[z]; + * if (resadd[z] > (2^31)-1) { + * resadd[z] = (2^31)-1; + * OV = 1; + * } else if (resadd[z] < -2^31) { + * resadd[z] = -2^31; + * OV = 1; + * } + * Rd.W[z] = resadd[z]; + * ~~~ + * + * \param [in] t unsigned long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KDMABT16(unsigned long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kdmabt16 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 4.9.2. KDMABT16 ===== */ + +/* ===== Inline Function Start for 4.9.3. KDMATT16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_Q15_SAT_MULT + * \brief KDMATT16 (SIMD Signed Saturating Double Multiply Addition T16 x T16) + * \details + * **Type**: SIMD (RV64 only) + * + * **Syntax**:\n + * ~~~ + * KDMAxy16 Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion + * of the 32-bit chunks in registers and then double and saturate the Q31 results, add the results with + * the values of the corresponding 32-bit chunks from the destination register and write the saturated + * addition results back into the corresponding 32-bit chunks of the destination register. If saturation + * happens, an overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the 32-bit portions in Rs1 with the top + * or bottom 16-bit Q15 content of the corresponding 32-bit portions in Rs2. The Q30 results are then + * doubled and saturated into Q31 values. The Q31 values are then added with the content of the + * corresponding 32-bit portions of Rd. If the addition results are beyond the Q31 number range (-2^31 <= + * Q31 <= 2^31-1), they are saturated to the range and the OV flag is set to 1. The results after saturation + * are written back to Rd. + * When both the two Q15 inputs are 0x8000, saturation will happen and the overflow flag OV will be + * set. + * + * **Operations**:\n + * ~~~ + * // KDMABB16: (x,y,z)=(0,0,0),(2,2,1) + * // KDMABT16: (x,y,z)=(0,1,0),(2,3,1) + * // KDMATT16: (x,y,z)=(1,1,0),(3,3,1) + * aop[z] = Rs1.H[x]; bop[z] = Rs2.H[y]; + * If (0x8000 != aop[z] | 0x8000 != bop[z]) { + * Mresult[z] = aop[z] * bop[z]; + * resQ31[z] = Mresult[z] << 1; + * } else { + * resQ31[z] = 0x7FFFFFFF; + * OV = 1; + * } + * resadd[z] = Rd.W[z] + resQ31[z]; + * if (resadd[z] > (2^31)-1) { + * resadd[z] = (2^31)-1; + * OV = 1; + * } else if (resadd[z] < -2^31) { + * resadd[z] = -2^31; + * OV = 1; + * } + * Rd.W[z] = resadd[z]; + * ~~~ + * + * \param [in] t unsigned long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KDMATT16(unsigned long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kdmatt16 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 4.9.3. KDMATT16 ===== */ + +/* ===== Inline Function Start for 4.10.1. KHMBB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_Q15_SAT_MULT + * \brief KHMBB16 (SIMD Signed Saturating Half Multiply B16 x B16) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KHMxy16 Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion + * of the 32-bit chunks in registers and then right-shift 15 bits to turn the Q30 results into Q15 + * numbers again and saturate the Q15 results into the destination register. If saturation happens, an + * overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the 32-bit portions in Rs1 with the top + * or bottom 16-bit Q15 content of the 32-bit portion in Rs2. The Q30 results are then right-shifted 15- + * bits and saturated into Q15 values. The 32-bit Q15 values are then written into the 32-bit chunks in + * Rd. When both the two Q15 inputs are 0x8000, saturation will happen. The result will be saturated + * to 0x7FFF and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * // KHMBB16: (x,y,z)=(0,0,0),(2,2,1) + * // KHMBT16: (x,y,z)=(0,1,0),(2,3,1) + * // KHMTT16: (x,y,z)=(1,1,0),(3,3,1) + * aop = Rs1.H[x]; bop = Rs2.H[y]; + * If (0x8000 != aop | 0x8000 != bop) { + * Mresult[31:0] = aop * bop; + * res[15:0] = Mresult[30:15]; + * } else { + * res[15:0] = 0x7FFF; + * OV = 1; + * } + * Rd.W[z] = SE32(res[15:0]); + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KHMBB16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("khmbb16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.10.1. KHMBB16 ===== */ + +/* ===== Inline Function Start for 4.10.2. KHMBT16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_Q15_SAT_MULT + * \brief KHMBT16 (SIMD Signed Saturating Half Multiply B16 x T16) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KHMxy16 Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion + * of the 32-bit chunks in registers and then right-shift 15 bits to turn the Q30 results into Q15 + * numbers again and saturate the Q15 results into the destination register. If saturation happens, an + * overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the 32-bit portions in Rs1 with the top + * or bottom 16-bit Q15 content of the 32-bit portion in Rs2. The Q30 results are then right-shifted 15- + * bits and saturated into Q15 values. The 32-bit Q15 values are then written into the 32-bit chunks in + * Rd. When both the two Q15 inputs are 0x8000, saturation will happen. The result will be saturated + * to 0x7FFF and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * // KHMBB16: (x,y,z)=(0,0,0),(2,2,1) + * // KHMBT16: (x,y,z)=(0,1,0),(2,3,1) + * // KHMTT16: (x,y,z)=(1,1,0),(3,3,1) + * aop = Rs1.H[x]; bop = Rs2.H[y]; + * If (0x8000 != aop | 0x8000 != bop) { + * Mresult[31:0] = aop * bop; + * res[15:0] = Mresult[30:15]; + * } else { + * res[15:0] = 0x7FFF; + * OV = 1; + * } + * Rd.W[z] = SE32(res[15:0]); + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KHMBT16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("khmbt16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.10.2. KHMBT16 ===== */ + +/* ===== Inline Function Start for 4.10.3. KHMTT16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_Q15_SAT_MULT + * \brief KHMTT16 (SIMD Signed Saturating Half Multiply T16 x T16) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KHMxy16 Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion + * of the 32-bit chunks in registers and then right-shift 15 bits to turn the Q30 results into Q15 + * numbers again and saturate the Q15 results into the destination register. If saturation happens, an + * overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the 32-bit portions in Rs1 with the top + * or bottom 16-bit Q15 content of the 32-bit portion in Rs2. The Q30 results are then right-shifted 15- + * bits and saturated into Q15 values. The 32-bit Q15 values are then written into the 32-bit chunks in + * Rd. When both the two Q15 inputs are 0x8000, saturation will happen. The result will be saturated + * to 0x7FFF and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * // KHMBB16: (x,y,z)=(0,0,0),(2,2,1) + * // KHMBT16: (x,y,z)=(0,1,0),(2,3,1) + * // KHMTT16: (x,y,z)=(1,1,0),(3,3,1) + * aop = Rs1.H[x]; bop = Rs2.H[y]; + * If (0x8000 != aop | 0x8000 != bop) { + * Mresult[31:0] = aop * bop; + * res[15:0] = Mresult[30:15]; + * } else { + * res[15:0] = 0x7FFF; + * OV = 1; + * } + * Rd.W[z] = SE32(res[15:0]); + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KHMTT16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("khmtt16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.10.3. KHMTT16 ===== */ + +/* ===== Inline Function Start for 4.11.1. KMABB32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_MULT_ADD + * \brief KMABB32 (Saturating Signed Multiply Bottom Words & Add) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KMABB32 Rd, Rs1, Rs2 + * KMABT32 Rd, Rs1, Rs2 + * KMATT32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element in a register with the 32-bit element in another register + * and add the result to the content of 64-bit data in the third register. The addition result may be + * saturated and is written to the third register. + * * KMABB32: rd + bottom*bottom + * * KMABT32: rd + bottom*top + * * KMATT32: rd + top*top + * + * **Description**:\n + * For the `KMABB32` instruction, it multiplies the bottom 32-bit element in Rs1 with the bottom 32-bit + * element in Rs2. + * For the `KMABT32` instruction, it multiplies the bottom 32-bit element in Rs1 with the top 32-bit + * element in Rs2. + * For the `KMATT32` instruction, it multiplies the top 32-bit element in Rs1 with the top 32-bit + * element in Rs2. + * The multiplication result is added to the content of 64-bit data in Rd. If the addition result is beyond + * the Q63 number range (-2^63 <= Q63 <= 2^63-1), it is saturated to the range and the OV bit is set to 1. The + * result after saturation is written to Rd. The 32-bit contents of Rs1 and Rs2 are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * res = Rd + (Rs1.W[0] * Rs2.W[0]); // KMABB32 + * res = Rd + (Rs1.W[0] * Rs2.W[1]); // KMABT32 + * res = Rd + (Rs1.W[1] * Rs2.W[1]); // KMATT32 + * if (res > (2^63)-1) { + * res = (2^63)-1; + * OV = 1; + * } else if (res < -2^63) { + * res = -2^63; + * OV = 1; + * } + * Rd = res; + * *Exceptions:* None + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMABB32(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmabb32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 4.11.1. KMABB32 ===== */ + +/* ===== Inline Function Start for 4.11.2. KMABT32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_MULT_ADD + * \brief KMABT32 (Saturating Signed Multiply Bottom & Top Words & Add) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KMABB32 Rd, Rs1, Rs2 + * KMABT32 Rd, Rs1, Rs2 + * KMATT32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element in a register with the 32-bit element in another register + * and add the result to the content of 64-bit data in the third register. The addition result may be + * saturated and is written to the third register. + * * KMABB32: rd + bottom*bottom + * * KMABT32: rd + bottom*top + * * KMATT32: rd + top*top + * + * **Description**:\n + * For the `KMABB32` instruction, it multiplies the bottom 32-bit element in Rs1 with the bottom 32-bit + * element in Rs2. + * For the `KMABT32` instruction, it multiplies the bottom 32-bit element in Rs1 with the top 32-bit + * element in Rs2. + * For the `KMATT32` instruction, it multiplies the top 32-bit element in Rs1 with the top 32-bit + * element in Rs2. + * The multiplication result is added to the content of 64-bit data in Rd. If the addition result is beyond + * the Q63 number range (-2^63 <= Q63 <= 2^63-1), it is saturated to the range and the OV bit is set to 1. The + * result after saturation is written to Rd. The 32-bit contents of Rs1 and Rs2 are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * res = Rd + (Rs1.W[0] * Rs2.W[0]); // KMABB32 + * res = Rd + (Rs1.W[0] * Rs2.W[1]); // KMABT32 + * res = Rd + (Rs1.W[1] * Rs2.W[1]); // KMATT32 + * if (res > (2^63)-1) { + * res = (2^63)-1; + * OV = 1; + * } else if (res < -2^63) { + * res = -2^63; + * OV = 1; + * } + * Rd = res; + * *Exceptions:* None + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMABT32(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmabt32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 4.11.2. KMABT32 ===== */ + +/* ===== Inline Function Start for 4.11.3. KMATT32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_MULT_ADD + * \brief KMATT32 (Saturating Signed Multiply Top Words & Add) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KMABB32 Rd, Rs1, Rs2 + * KMABT32 Rd, Rs1, Rs2 + * KMATT32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element in a register with the 32-bit element in another register + * and add the result to the content of 64-bit data in the third register. The addition result may be + * saturated and is written to the third register. + * * KMABB32: rd + bottom*bottom + * * KMABT32: rd + bottom*top + * * KMATT32: rd + top*top + * + * **Description**:\n + * For the `KMABB32` instruction, it multiplies the bottom 32-bit element in Rs1 with the bottom 32-bit + * element in Rs2. + * For the `KMABT32` instruction, it multiplies the bottom 32-bit element in Rs1 with the top 32-bit + * element in Rs2. + * For the `KMATT32` instruction, it multiplies the top 32-bit element in Rs1 with the top 32-bit + * element in Rs2. + * The multiplication result is added to the content of 64-bit data in Rd. If the addition result is beyond + * the Q63 number range (-2^63 <= Q63 <= 2^63-1), it is saturated to the range and the OV bit is set to 1. The + * result after saturation is written to Rd. The 32-bit contents of Rs1 and Rs2 are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * res = Rd + (Rs1.W[0] * Rs2.W[0]); // KMABB32 + * res = Rd + (Rs1.W[0] * Rs2.W[1]); // KMABT32 + * res = Rd + (Rs1.W[1] * Rs2.W[1]); // KMATT32 + * if (res > (2^63)-1) { + * res = (2^63)-1; + * OV = 1; + * } else if (res < -2^63) { + * res = -2^63; + * OV = 1; + * } + * Rd = res; + * *Exceptions:* None + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMATT32(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmatt32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 4.11.3. KMATT32 ===== */ + +/* ===== Inline Function Start for 4.12.1. KMADA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PARALLEL_MAC + * \brief KMADA32 (Saturating Signed Multiply Two Words and Two Adds) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KMADA32 Rd, Rs1, Rs2 + * KMAXDA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32-bit multiplications from 32-bit data in two registers; and then adds the + * two 64-bit results and 64-bit data in a third register together. The addition result may be saturated. + * * KMADA32: rd + top*top + bottom*bottom + * * KMAXDA32: rd + top*bottom + bottom*top + * + * **Description**:\n + * For the `KMADA32` instruction, it multiplies the bottom 32-bit element in Rs1 with the bottom 32- + * bit element in Rs2 and then adds the result to the result of multiplying the top 32-bit element in Rs1 + * with the top 32-bit element in Rs2. It is actually an alias of the `KMAR64` instruction. + * For the `KMAXDA32` instruction, it multiplies the top 32-bit element in Rs1 with the bottom 32-bit + * element in Rs2 and then adds the result to the result of multiplying the bottom 32-bit element in Rs1 + * with the top 32-bit element in Rs2. + * The result is added to the content of 64-bit data in Rd. If the addition result is beyond the Q63 + * number range (-2^63 <= Q63 <= 2^63-1), it is saturated to the range and the OV bit is set to 1. The 64-bit + * result is written to Rd. The 32-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * res = Rd + (Rs1.W[1] * Rs2.w[1]) + (Rs1.W[0] * Rs2.W[0]); // KMADA32 + * res = Rd + (Rs1.W[1] * Rs2.W[0]) + (Rs1.W[0] * Rs2.W[1]); // KMAXDA32 + * if (res > (2^63)-1) { + * res = (2^63)-1; + * OV = 1; + * } else if (res < -2^63) { + * res = -2^63; + * OV = 1; + * } + * Rd = res; + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMADA32(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmada32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 4.12.1. KMADA32 ===== */ + +/* ===== Inline Function Start for 4.12.2. KMAXDA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PARALLEL_MAC + * \brief KMAXDA32 (Saturating Signed Crossed Multiply Two Words and Two Adds) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KMADA32 Rd, Rs1, Rs2 + * KMAXDA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32-bit multiplications from 32-bit data in two registers; and then adds the + * two 64-bit results and 64-bit data in a third register together. The addition result may be saturated. + * * KMADA32: rd + top*top + bottom*bottom + * * KMAXDA32: rd + top*bottom + bottom*top + * + * **Description**:\n + * For the `KMADA32` instruction, it multiplies the bottom 32-bit element in Rs1 with the bottom 32- + * bit element in Rs2 and then adds the result to the result of multiplying the top 32-bit element in Rs1 + * with the top 32-bit element in Rs2. It is actually an alias of the `KMAR64` instruction. + * For the `KMAXDA32` instruction, it multiplies the top 32-bit element in Rs1 with the bottom 32-bit + * element in Rs2 and then adds the result to the result of multiplying the bottom 32-bit element in Rs1 + * with the top 32-bit element in Rs2. + * The result is added to the content of 64-bit data in Rd. If the addition result is beyond the Q63 + * number range (-2^63 <= Q63 <= 2^63-1), it is saturated to the range and the OV bit is set to 1. The 64-bit + * result is written to Rd. The 32-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * res = Rd + (Rs1.W[1] * Rs2.w[1]) + (Rs1.W[0] * Rs2.W[0]); // KMADA32 + * res = Rd + (Rs1.W[1] * Rs2.W[0]) + (Rs1.W[0] * Rs2.W[1]); // KMAXDA32 + * if (res > (2^63)-1) { + * res = (2^63)-1; + * OV = 1; + * } else if (res < -2^63) { + * res = -2^63; + * OV = 1; + * } + * Rd = res; + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMAXDA32(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmaxda32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 4.12.2. KMAXDA32 ===== */ + +/* ===== Inline Function Start for 4.13.1. KMDA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PARALLEL_MAC + * \brief KMDA32 (Signed Multiply Two Words and Add) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KMDA32 Rd, Rs1, Rs2 + * KMXDA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32-bit multiplications from the 32-bit element of two registers; and then + * adds the two 64-bit results together. The addition result may be saturated. + * * KMDA32: top*top + bottom*bottom + * * KMXDA32: top*bottom + bottom*top + * + * **Description**:\n + * For the `KMDA32` instruction, it multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit + * element of Rs2 and then adds the result to the result of multiplying the top 32-bit element of Rs1 + * with the top 32-bit element of Rs2. + * For the `KMXDA32` instruction, it multiplies the bottom 32-bit element of Rs1 with the top 32-bit + * element of Rs2 and then adds the result to the result of multiplying the top 32-bit element of Rs1 + * with the bottom 32-bit element of Rs2. + * The addition result is checked for saturation. If saturation happens, the result is saturated to 2^63-1. + * The final result is written to Rd. The 32-bit contents are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * if ((Rs1 != 0x8000000080000000) or (Rs2 != 0x8000000080000000)) { + * Rd = (Rs1.W[1] * Rs2.W[1]) + (Rs1.W[0] * Rs2.W[0]); // KMDA32 + * Rd = (Rs1.W[1] * Rs2.W[0]) + (Rs1.W[0] * Rs2.W[1]); // KMXDA32 + * } else { + * Rd = 0x7fffffffffffffff; + * OV = 1; + * } + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMDA32(unsigned long a, unsigned long b) +{ + long result; + __ASM volatile("kmda32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.13.1. KMDA32 ===== */ + +/* ===== Inline Function Start for 4.13.2. KMXDA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PARALLEL_MAC + * \brief KMXDA32 (Signed Crossed Multiply Two Words and Add) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KMDA32 Rd, Rs1, Rs2 + * KMXDA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32-bit multiplications from the 32-bit element of two registers; and then + * adds the two 64-bit results together. The addition result may be saturated. + * * KMDA32: top*top + bottom*bottom + * * KMXDA32: top*bottom + bottom*top + * + * **Description**:\n + * For the `KMDA32` instruction, it multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit + * element of Rs2 and then adds the result to the result of multiplying the top 32-bit element of Rs1 + * with the top 32-bit element of Rs2. + * For the `KMXDA32` instruction, it multiplies the bottom 32-bit element of Rs1 with the top 32-bit + * element of Rs2 and then adds the result to the result of multiplying the top 32-bit element of Rs1 + * with the bottom 32-bit element of Rs2. + * The addition result is checked for saturation. If saturation happens, the result is saturated to 2^63-1. + * The final result is written to Rd. The 32-bit contents are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * if ((Rs1 != 0x8000000080000000) or (Rs2 != 0x8000000080000000)) { + * Rd = (Rs1.W[1] * Rs2.W[1]) + (Rs1.W[0] * Rs2.W[0]); // KMDA32 + * Rd = (Rs1.W[1] * Rs2.W[0]) + (Rs1.W[0] * Rs2.W[1]); // KMXDA32 + * } else { + * Rd = 0x7fffffffffffffff; + * OV = 1; + * } + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMXDA32(unsigned long a, unsigned long b) +{ + long result; + __ASM volatile("kmxda32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.13.2. KMXDA32 ===== */ + +/* ===== Inline Function Start for 4.14.1. KMADS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PARALLEL_MAC + * \brief KMADS32 (Saturating Signed Multiply Two Words & Subtract & Add) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KMADS32 Rd, Rs1, Rs2 + * KMADRS32 Rd, Rs1, Rs2 + * KMAXDS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32-bit multiplications from 32-bit elements in two registers; and then + * perform a subtraction operation between the two 64-bit results. Then add the subtraction result to + * 64-bit data in a third register. The addition result may be saturated. + * * KMADS32: rd + (top*top - bottom*bottom) + * * KMADRS32: rd + (bottom*bottom - top*top) + * * KMAXDS32: rd + (top*bottom - bottom*top) + * + * **Description**:\n + * For the `KMADS32` instruction, it multiplies the bottom 32-bit element in Rs1 with the bottom 32-bit + * element in Rs2 and then subtracts the result from the result of multiplying the top 32-bit element in + * Rs1 with the top 32-bit element in Rs2. + * For the `KMADRS32` instruction, it multiplies the top 32-bit element in Rs1 with the top 32-bit + * element in Rs2 and then subtracts the result from the result of multiplying the bottom 32-bit + * element in Rs1 with the bottom 32-bit element in Rs2. + * For the `KMAXDS32` instruction, it multiplies the bottom 32-bit element in Rs1 with the top 32-bit + * element in Rs2 and then subtracts the result from the result of multiplying the top 32-bit element in + * Rs1 with the bottom 32-bit element in Rs2. + * The subtraction result is then added to the content of 64-bit data in Rd. If the addition result is + * beyond the Q63 number range (-2^63 <= Q63 <= 2^63-1), it is saturated to the range and the OV bit is set to + * 1. The 64-bit result after saturation is written to Rd. The 32-bit contents of Rs1 and Rs2 are treated + * as signed integers. + * + * **Operations**:\n + * ~~~ + * res = Rd + (Rs1.W[1] * Rs2.W[1]) - (Rs1.W[0] * Rs2.W[0]); // KMADS32 + * res = Rd + (Rs1.W[0] * Rs2.W[0]) - (Rs1.W[1] * Rs2.W[1]); // KMADRS32 + * res = Rd + (Rs1.W[1] * Rs2.W[0]) - (Rs1.W[0] * Rs2.W[1]); // KMAXDS32 + * if (res > (2^63)-1) { + * res = (2^63)-1; + * OV = 1; + * } else if (res < -2^63) { + * res = -2^63; + * OV = 1; + * } + * Rd = res; + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMADS32(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmads32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 4.14.1. KMADS32 ===== */ + +/* ===== Inline Function Start for 4.14.2. KMADRS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PARALLEL_MAC + * \brief KMADRS32 (Saturating Signed Multiply Two Words & Reverse Subtract & Add) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KMADS32 Rd, Rs1, Rs2 + * KMADRS32 Rd, Rs1, Rs2 + * KMAXDS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32-bit multiplications from 32-bit elements in two registers; and then + * perform a subtraction operation between the two 64-bit results. Then add the subtraction result to + * 64-bit data in a third register. The addition result may be saturated. + * * KMADS32: rd + (top*top - bottom*bottom) + * * KMADRS32: rd + (bottom*bottom - top*top) + * * KMAXDS32: rd + (top*bottom - bottom*top) + * + * **Description**:\n + * For the `KMADS32` instruction, it multiplies the bottom 32-bit element in Rs1 with the bottom 32-bit + * element in Rs2 and then subtracts the result from the result of multiplying the top 32-bit element in + * Rs1 with the top 32-bit element in Rs2. + * For the `KMADRS32` instruction, it multiplies the top 32-bit element in Rs1 with the top 32-bit + * element in Rs2 and then subtracts the result from the result of multiplying the bottom 32-bit + * element in Rs1 with the bottom 32-bit element in Rs2. + * For the `KMAXDS32` instruction, it multiplies the bottom 32-bit element in Rs1 with the top 32-bit + * element in Rs2 and then subtracts the result from the result of multiplying the top 32-bit element in + * Rs1 with the bottom 32-bit element in Rs2. + * The subtraction result is then added to the content of 64-bit data in Rd. If the addition result is + * beyond the Q63 number range (-2^63 <= Q63 <= 2^63-1), it is saturated to the range and the OV bit is set to + * 1. The 64-bit result after saturation is written to Rd. The 32-bit contents of Rs1 and Rs2 are treated + * as signed integers. + * + * **Operations**:\n + * ~~~ + * res = Rd + (Rs1.W[1] * Rs2.W[1]) - (Rs1.W[0] * Rs2.W[0]); // KMADS32 + * res = Rd + (Rs1.W[0] * Rs2.W[0]) - (Rs1.W[1] * Rs2.W[1]); // KMADRS32 + * res = Rd + (Rs1.W[1] * Rs2.W[0]) - (Rs1.W[0] * Rs2.W[1]); // KMAXDS32 + * if (res > (2^63)-1) { + * res = (2^63)-1; + * OV = 1; + * } else if (res < -2^63) { + * res = -2^63; + * OV = 1; + * } + * Rd = res; + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMADRS32(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmadrs32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 4.14.2. KMADRS32 ===== */ + +/* ===== Inline Function Start for 4.14.3. KMAXDS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PARALLEL_MAC + * \brief KMAXDS32 (Saturating Signed Crossed Multiply Two Words & Subtract & Add) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KMADS32 Rd, Rs1, Rs2 + * KMADRS32 Rd, Rs1, Rs2 + * KMAXDS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32-bit multiplications from 32-bit elements in two registers; and then + * perform a subtraction operation between the two 64-bit results. Then add the subtraction result to + * 64-bit data in a third register. The addition result may be saturated. + * * KMADS32: rd + (top*top - bottom*bottom) + * * KMADRS32: rd + (bottom*bottom - top*top) + * * KMAXDS32: rd + (top*bottom - bottom*top) + * + * **Description**:\n + * For the `KMADS32` instruction, it multiplies the bottom 32-bit element in Rs1 with the bottom 32-bit + * element in Rs2 and then subtracts the result from the result of multiplying the top 32-bit element in + * Rs1 with the top 32-bit element in Rs2. + * For the `KMADRS32` instruction, it multiplies the top 32-bit element in Rs1 with the top 32-bit + * element in Rs2 and then subtracts the result from the result of multiplying the bottom 32-bit + * element in Rs1 with the bottom 32-bit element in Rs2. + * For the `KMAXDS32` instruction, it multiplies the bottom 32-bit element in Rs1 with the top 32-bit + * element in Rs2 and then subtracts the result from the result of multiplying the top 32-bit element in + * Rs1 with the bottom 32-bit element in Rs2. + * The subtraction result is then added to the content of 64-bit data in Rd. If the addition result is + * beyond the Q63 number range (-2^63 <= Q63 <= 2^63-1), it is saturated to the range and the OV bit is set to + * 1. The 64-bit result after saturation is written to Rd. The 32-bit contents of Rs1 and Rs2 are treated + * as signed integers. + * + * **Operations**:\n + * ~~~ + * res = Rd + (Rs1.W[1] * Rs2.W[1]) - (Rs1.W[0] * Rs2.W[0]); // KMADS32 + * res = Rd + (Rs1.W[0] * Rs2.W[0]) - (Rs1.W[1] * Rs2.W[1]); // KMADRS32 + * res = Rd + (Rs1.W[1] * Rs2.W[0]) - (Rs1.W[0] * Rs2.W[1]); // KMAXDS32 + * if (res > (2^63)-1) { + * res = (2^63)-1; + * OV = 1; + * } else if (res < -2^63) { + * res = -2^63; + * OV = 1; + * } + * Rd = res; + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMAXDS32(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmaxds32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 4.14.3. KMAXDS32 ===== */ + +/* ===== Inline Function Start for 4.15.1. KMSDA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PARALLEL_MAC + * \brief KMSDA32 (Saturating Signed Multiply Two Words & Add & Subtract) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KMSDA32 Rd, Rs1, Rs2 + * KMSXDA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32-bit multiplications from the 32-bit element of two registers; and then + * subtracts the two 64-bit results from a third register. The subtraction result may be saturated. + * * KMSDA: rd - top*top - bottom*bottom + * * KMSXDA: rd - top*bottom - bottom*top + * + * **Description**:\n + * For the `KMSDA32` instruction, it multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit + * element of Rs2 and multiplies the top 32-bit element of Rs1 with the top 32-bit element of Rs2. + * For the `KMSXDA32` instruction, it multiplies the bottom 32-bit element of Rs1 with the top 32-bit + * element of Rs2 and multiplies the top 32-bit element of Rs1 with the bottom 32-bit element of Rs2. + * The two 64-bit multiplication results are then subtracted from the content of Rd. If the subtraction + * result is beyond the Q63 number range (-2^63 <= Q63 <= 2^63-1), it is saturated to the range and the OV bit + * is set to 1. The result after saturation is written to Rd. The 32-bit contents are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * res = Rd - (Rs1.W[1] * Rs2.W[1]) - (Rs1.W[0] * Rs2.W[0]); // KMSDA32 + * res = Rd - (Rs1.W[1] * Rs2.W[0]) - (Rs1.W[0] * Rs2.W[1]); // KMSXDA32 + * if (res > (2^63)-1) { + * res = (2^63)-1; + * OV = 1; + * } else if (res < -2^63) { + * res = -2^63; + * OV = 1; + * } + * Rd = res; + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMSDA32(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmsda32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 4.15.1. KMSDA32 ===== */ + +/* ===== Inline Function Start for 4.15.2. KMSXDA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PARALLEL_MAC + * \brief KMSXDA32 (Saturating Signed Crossed Multiply Two Words & Add & Subtract) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KMSDA32 Rd, Rs1, Rs2 + * KMSXDA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32-bit multiplications from the 32-bit element of two registers; and then + * subtracts the two 64-bit results from a third register. The subtraction result may be saturated. + * * KMSDA: rd - top*top - bottom*bottom + * * KMSXDA: rd - top*bottom - bottom*top + * + * **Description**:\n + * For the `KMSDA32` instruction, it multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit + * element of Rs2 and multiplies the top 32-bit element of Rs1 with the top 32-bit element of Rs2. + * For the `KMSXDA32` instruction, it multiplies the bottom 32-bit element of Rs1 with the top 32-bit + * element of Rs2 and multiplies the top 32-bit element of Rs1 with the bottom 32-bit element of Rs2. + * The two 64-bit multiplication results are then subtracted from the content of Rd. If the subtraction + * result is beyond the Q63 number range (-2^63 <= Q63 <= 2^63-1), it is saturated to the range and the OV bit + * is set to 1. The result after saturation is written to Rd. The 32-bit contents are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * res = Rd - (Rs1.W[1] * Rs2.W[1]) - (Rs1.W[0] * Rs2.W[0]); // KMSDA32 + * res = Rd - (Rs1.W[1] * Rs2.W[0]) - (Rs1.W[0] * Rs2.W[1]); // KMSXDA32 + * if (res > (2^63)-1) { + * res = (2^63)-1; + * OV = 1; + * } else if (res < -2^63) { + * res = -2^63; + * OV = 1; + * } + * Rd = res; + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMSXDA32(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmsxda32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 4.15.2. KMSXDA32 ===== */ + +/* ===== Inline Function Start for 4.16. KSLL32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_SHIFT + * \brief KSLL32 (SIMD 32-bit Saturating Shift Left Logical) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KSLL32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit elements logical left shift operations with saturation simultaneously. The shift + * amount is a variable from a GPR. + * + * **Description**:\n + * The 32-bit data elements in Rs1 are left-shifted logically. The shifted out bits are filled + * with zero and the shift amount is specified by the low-order 5-bits of the value in the Rs2 register. + * Any shifted value greater than 2^31-1 is saturated to 2^31-1. Any shifted value smaller than -2^31 is + * saturated to -2^31. And the saturated results are written to Rd. If any saturation is performed, set OV + * bit to 1. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[4:0]; + * if (sa != 0) { + * res[(31+sa):0] = Rs1.W[x] << sa; + * if (res > (2^31)-1) { + * res = 0x7fffffff; OV = 1; + * } else if (res < -2^31) { + * res = 0x80000000; OV = 1; + * } + * Rd.W[x] = res[31:0]; + * } else { + * Rd = Rs1; + * } + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KSLL32(unsigned long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("ksll32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.16. KSLL32 ===== */ + +/* ===== Inline Function Start for 4.17. KSLLI32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_SHIFT + * \brief KSLLI32 (SIMD 32-bit Saturating Shift Left Logical Immediate) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KSLLI32 Rd, Rs1, imm5u + * ~~~ + * + * **Purpose**:\n + * Do 32-bit elements logical left shift operations with saturation simultaneously. The shift + * amount is an immediate value. + * + * **Description**:\n + * The 32-bit data elements in Rs1 are left-shifted logically. The shifted out bits are filled + * with zero and the shift amount is specified by the imm5u constant. Any shifted value greater than + * 2^31-1 is saturated to 2^31-1. Any shifted value smaller than -2^31 is saturated to -2^31. And the saturated + * results are written to Rd. If any saturation is performed, set OV bit to 1. + * + * **Operations**:\n + * ~~~ + * sa = imm5u[4:0]; + * if (sa != 0) { + * res[(31+sa):0] = Rs1.W[x] << sa; + * if (res > (2^31)-1) { + * res = 0x7fffffff; OV = 1; + * } else if (res < -2^31) { + * res = 0x80000000; OV = 1; + * } + * Rd.W[x] = res[31:0]; + * } else { + * Rd = Rs1; + * } + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_KSLLI32(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("kslli32 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 4.17. KSLLI32 ===== */ + +/* ===== Inline Function Start for 4.18.1. KSLRA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_SHIFT + * \brief KSLRA32 (SIMD 32-bit Shift Left Logical with Saturation or Shift Right Arithmetic) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KSLRA32 Rd, Rs1, Rs2 + * KSLRA32.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit elements logical left (positive) or arithmetic right (negative) shift operation with + * Q31 saturation for the left shift. The `.u` form performs additional rounding up operations for the + * right shift. + * + * **Description**:\n + * The 32-bit data elements of Rs1 are left-shifted logically or right-shifted arithmetically + * based on the value of Rs2[5:0]. Rs2[5:0] is in the signed range of [-25, 25-1]. A positive Rs2[5:0] means + * logical left shift and a negative Rs2[5:0] means arithmetic right shift. The shift amount is the + * absolute value of Rs2[5:0]. However, the behavior of `Rs2[5:0]==-25 (0x20)` is defined to be + * equivalent to the behavior of `Rs2[5:0]==-(25-1) (0x21)`. + * The left-shifted results are saturated to the 32-bit signed integer range of [-2^31, 2^31-1]. For the `.u` + * form of the instruction, the right-shifted results are added a 1 to the most significant discarded bit + * position for rounding effect. After the shift, saturation, or rounding, the final results are written to + * Rd. If any saturation happens, this instruction sets the OV flag. The value of Rs2[31:6] will not affect + * this instruction. + * + * **Operations**:\n + * ~~~ + * if (Rs2[5:0] < 0) { + * sa = -Rs2[5:0]; + * sa = (sa == 32)? 31 : sa; + * if (`.u` form) { + * res[31:-1] = SE33(Rs1.W[x][31:sa-1]) + 1; + * Rd.W[x] = res[31:0]; + * } else { + * Rd.W[x] = SE32(Rs1.W[x][31:sa]); + * } + * } else { + * sa = Rs2[4:0]; + * res[(31+sa):0] = Rs1.W[x] <<(logic) sa; + * if (res > (2^31)-1) { + * res[31:0] = 0x7fffffff; OV = 1; + * } else if (res < -2^31) { + * res[31:0] = 0x80000000; OV = 1; + * } + * Rd.W[x] = res[31:0]; + * } + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KSLRA32(unsigned long a, int b) +{ + unsigned long result; + __ASM volatile("kslra32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.18.1. KSLRA32 ===== */ + +/* ===== Inline Function Start for 4.18.2. KSLRA32.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_SHIFT + * \brief KSLRA32.u (SIMD 32-bit Shift Left Logical with Saturation or Rounding Shift Right Arithmetic) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KSLRA32 Rd, Rs1, Rs2 + * KSLRA32.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit elements logical left (positive) or arithmetic right (negative) shift operation with + * Q31 saturation for the left shift. The `.u` form performs additional rounding up operations for the + * right shift. + * + * **Description**:\n + * The 32-bit data elements of Rs1 are left-shifted logically or right-shifted arithmetically + * based on the value of Rs2[5:0]. Rs2[5:0] is in the signed range of [-25, 25-1]. A positive Rs2[5:0] means + * logical left shift and a negative Rs2[5:0] means arithmetic right shift. The shift amount is the + * absolute value of Rs2[5:0]. However, the behavior of `Rs2[5:0]==-25 (0x20)` is defined to be + * equivalent to the behavior of `Rs2[5:0]==-(25-1) (0x21)`. + * The left-shifted results are saturated to the 32-bit signed integer range of [-2^31, 2^31-1]. For the `.u` + * form of the instruction, the right-shifted results are added a 1 to the most significant discarded bit + * position for rounding effect. After the shift, saturation, or rounding, the final results are written to + * Rd. If any saturation happens, this instruction sets the OV flag. The value of Rs2[31:6] will not affect + * this instruction. + * + * **Operations**:\n + * ~~~ + * if (Rs2[5:0] < 0) { + * sa = -Rs2[5:0]; + * sa = (sa == 32)? 31 : sa; + * if (`.u` form) { + * res[31:-1] = SE33(Rs1.W[x][31:sa-1]) + 1; + * Rd.W[x] = res[31:0]; + * } else { + * Rd.W[x] = SE32(Rs1.W[x][31:sa]); + * } + * } else { + * sa = Rs2[4:0]; + * res[(31+sa):0] = Rs1.W[x] <<(logic) sa; + * if (res > (2^31)-1) { + * res[31:0] = 0x7fffffff; OV = 1; + * } else if (res < -2^31) { + * res[31:0] = 0x80000000; OV = 1; + * } + * Rd.W[x] = res[31:0]; + * } + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KSLRA32_U(unsigned long a, int b) +{ + unsigned long result; + __ASM volatile("kslra32.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.18.2. KSLRA32.u ===== */ + +/* ===== Inline Function Start for 4.19. KSTAS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief KSTAS32 (SIMD 32-bit Signed Saturating Straight Addition & Subtraction) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KSTAS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element saturating addition and 32-bit signed integer element + * saturating subtraction in a 64-bit chunk simultaneously. Operands are from corresponding 32-bit + * elements. + * + * **Description**:\n + * This instruction adds the 32-bit integer element in [63:32] of Rs1 with the 32-bit + * integer element in [63:32] of Rs2; at the same time, it subtracts the 32-bit integer element in [31:0] of + * Rs2 from the 32-bit integer element in [31:0] of Rs1. If any of the results are beyond the Q31 number + * range (-2^31 <= Q31 <= 2^31-1), they are saturated to the range and the OV bit is set to 1. The saturated + * results are written to [63:32] of Rd for addition and [31:0] of Rd for subtraction. + * + * **Operations**:\n + * ~~~ + * res[1] = Rs1.W[1] + Rs2.W[1]; + * res[0] = Rs1.W[0] - Rs2.W[0]; + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[1] = res[1]; + * Rd.W[0] = res[0]; + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KSTAS32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("kstas32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.19. KSTAS32 ===== */ + +/* ===== Inline Function Start for 4.20. KSTSA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief KSTSA32 (SIMD 32-bit Signed Saturating Straight Subtraction & Addition) + * \details + * **Type**: SIM (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KSTSA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element saturating subtraction and 32-bit signed integer element + * saturating addition in a 64-bit chunk simultaneously. Operands are from corresponding 32-bit + * elements. + * *Description: * + * This instruction subtracts the 32-bit integer element in [63:32] of Rs2 from the 32-bit integer + * element in [63:32] of Rs1; at the same time, it adds the 32-bit integer element in [31:0] of Rs1 with + * the 32-bit integer element in [31:0] of Rs2. If any of the results are beyond the Q31 number range ( + * -2^31 <= Q31 <= 2^31-1), they are saturated to the range and the OV bit is set to 1. The saturated results are + * written to [63:32] of Rd for subtraction and [31:0] of Rd for addition. + * + * **Operations**:\n + * ~~~ + * res[1] = Rs1.W[1] - Rs2.W[1]; + * res[0] = Rs1.W[0] + Rs2.W[0]; + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[1] = res[1]; + * Rd.W[0] = res[0]; + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KSTSA32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("kstsa32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.20. KSTSA32 ===== */ + +/* ===== Inline Function Start for 4.21. KSUB32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief KSUB32 (SIMD 32-bit Signed Saturating Subtraction) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KSUB32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer elements saturating subtractions simultaneously. + * + * **Description**:\n + * This instruction subtracts the 32-bit signed integer elements in Rs2 from the 32-bit + * signed integer elements in Rs1. If any of the results are beyond the Q31 number range (-2^31 <= Q31 <= + * 2^31-1), they are saturated to the range and the OV bit is set to 1. The saturated results are written to + * Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.W[x] - Rs2.W[x]; + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KSUB32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ksub32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.21. KSUB32 ===== */ + +/* ===== Inline Function Start for 4.22.1. PKBB32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PACK + * \brief PKBB32 (Pack Two 32-bit Data from Both Bottom Half) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * PKBB32 Rd, Rs1, Rs2 + * PKBT32 Rd, Rs1, Rs2 + * PKTT32 Rd, Rs1, Rs2 + * PKTB32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Pack 32-bit data from 64-bit chunks in two registers. + * * PKBB32: bottom.bottom + * * PKBT32: bottom.top + * * PKTT32: top.top + * * PKTB32: top.bottom + * + * **Description**:\n + * (PKBB32) moves Rs1.W[0] to Rd.W[1] and moves Rs2.W[0] to Rd.W[0]. + * (PKBT32) moves Rs1.W[0] to Rd.W[1] and moves Rs2.W[1] to Rd.W[0]. + * (PKTT32) moves Rs1.W[1] to Rd.W[1] and moves Rs2.W[1] to Rd.W[0]. + * (PKTB32) moves Rs1.W[1] to Rd.W[1] and moves Rs2.W[0] to Rd.W[0]. + * + * **Operations**:\n + * ~~~ + * Rd = CONCAT(Rs1.W[_*0*_], Rs2.W[_*0*_]); // PKBB32 + * Rd = CONCAT(Rs1.W[_*0*_], Rs2.W[_*1*_]); // PKBT32 + * Rd = CONCAT(Rs1.W[_*1*_], Rs2.W[_*1*_]); // PKTT32 + * Rd = CONCAT(Rs1.W[_*1*_], Rs2.W[_*0*_]); // PKTB32 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_PKBB32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("pkbb32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.22.1. PKBB32 ===== */ + +/* ===== Inline Function Start for 4.22.2. PKBT32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PACK + * \brief PKBT32 (Pack Two 32-bit Data from Bottom and Top Half) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * PKBB32 Rd, Rs1, Rs2 + * PKBT32 Rd, Rs1, Rs2 + * PKTT32 Rd, Rs1, Rs2 + * PKTB32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Pack 32-bit data from 64-bit chunks in two registers. + * * PKBB32: bottom.bottom + * * PKBT32: bottom.top + * * PKTT32: top.top + * * PKTB32: top.bottom + * + * **Description**:\n + * (PKBB32) moves Rs1.W[0] to Rd.W[1] and moves Rs2.W[0] to Rd.W[0]. + * (PKBT32) moves Rs1.W[0] to Rd.W[1] and moves Rs2.W[1] to Rd.W[0]. + * (PKTT32) moves Rs1.W[1] to Rd.W[1] and moves Rs2.W[1] to Rd.W[0]. + * (PKTB32) moves Rs1.W[1] to Rd.W[1] and moves Rs2.W[0] to Rd.W[0]. + * + * **Operations**:\n + * ~~~ + * Rd = CONCAT(Rs1.W[_*0*_], Rs2.W[_*0*_]); // PKBB32 + * Rd = CONCAT(Rs1.W[_*0*_], Rs2.W[_*1*_]); // PKBT32 + * Rd = CONCAT(Rs1.W[_*1*_], Rs2.W[_*1*_]); // PKTT32 + * Rd = CONCAT(Rs1.W[_*1*_], Rs2.W[_*0*_]); // PKTB32 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_PKBT32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("pkbt32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.22.2. PKBT32 ===== */ + +/* ===== Inline Function Start for 4.22.3. PKTT32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PACK + * \brief PKTT32 (Pack Two 32-bit Data from Both Top Half) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * PKBB32 Rd, Rs1, Rs2 + * PKBT32 Rd, Rs1, Rs2 + * PKTT32 Rd, Rs1, Rs2 + * PKTB32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Pack 32-bit data from 64-bit chunks in two registers. + * * PKBB32: bottom.bottom + * * PKBT32: bottom.top + * * PKTT32: top.top + * * PKTB32: top.bottom + * + * **Description**:\n + * (PKBB32) moves Rs1.W[0] to Rd.W[1] and moves Rs2.W[0] to Rd.W[0]. + * (PKBT32) moves Rs1.W[0] to Rd.W[1] and moves Rs2.W[1] to Rd.W[0]. + * (PKTT32) moves Rs1.W[1] to Rd.W[1] and moves Rs2.W[1] to Rd.W[0]. + * (PKTB32) moves Rs1.W[1] to Rd.W[1] and moves Rs2.W[0] to Rd.W[0]. + * + * **Operations**:\n + * ~~~ + * Rd = CONCAT(Rs1.W[_*0*_], Rs2.W[_*0*_]); // PKBB32 + * Rd = CONCAT(Rs1.W[_*0*_], Rs2.W[_*1*_]); // PKBT32 + * Rd = CONCAT(Rs1.W[_*1*_], Rs2.W[_*1*_]); // PKTT32 + * Rd = CONCAT(Rs1.W[_*1*_], Rs2.W[_*0*_]); // PKTB32 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_PKTT32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("pktt32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.22.3. PKTT32 ===== */ + +/* ===== Inline Function Start for 4.22.4. PKTB32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PACK + * \brief PKTB32 (Pack Two 32-bit Data from Top and Bottom Half) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * PKBB32 Rd, Rs1, Rs2 + * PKBT32 Rd, Rs1, Rs2 + * PKTT32 Rd, Rs1, Rs2 + * PKTB32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Pack 32-bit data from 64-bit chunks in two registers. + * * PKBB32: bottom.bottom + * * PKBT32: bottom.top + * * PKTT32: top.top + * * PKTB32: top.bottom + * + * **Description**:\n + * (PKBB32) moves Rs1.W[0] to Rd.W[1] and moves Rs2.W[0] to Rd.W[0]. + * (PKBT32) moves Rs1.W[0] to Rd.W[1] and moves Rs2.W[1] to Rd.W[0]. + * (PKTT32) moves Rs1.W[1] to Rd.W[1] and moves Rs2.W[1] to Rd.W[0]. + * (PKTB32) moves Rs1.W[1] to Rd.W[1] and moves Rs2.W[0] to Rd.W[0]. + * + * **Operations**:\n + * ~~~ + * Rd = CONCAT(Rs1.W[_*0*_], Rs2.W[_*0*_]); // PKBB32 + * Rd = CONCAT(Rs1.W[_*0*_], Rs2.W[_*1*_]); // PKBT32 + * Rd = CONCAT(Rs1.W[_*1*_], Rs2.W[_*1*_]); // PKTT32 + * Rd = CONCAT(Rs1.W[_*1*_], Rs2.W[_*0*_]); // PKTB32 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_PKTB32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("pktb32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.22.4. PKTB32 ===== */ + +/* ===== Inline Function Start for 4.23. RADD32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief RADD32 (SIMD 32-bit Signed Halving Addition) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * RADD32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element additions simultaneously. The results are halved to avoid + * overflow or saturation. + * + * **Description**:\n + * This instruction adds the 32-bit signed integer elements in Rs1 with the 32-bit signed + * integer elements in Rs2. The results are first arithmetically right-shifted by 1 bit and then written to + * Rd. + * + * **Examples**:\n + * ~~~ + * * Rs1 = 0x7FFFFFFF, Rs2 = 0x7FFFFFFF Rd = 0x7FFFFFFF + * * Rs1 = 0x80000000, Rs2 = 0x80000000 Rd = 0x80000000 + * * Rs1 = 0x40000000, Rs2 = 0x80000000 Rd = 0xE0000000 + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = (Rs1.W[x] + Rs2.W[x]) s>> 1; + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_RADD32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("radd32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.23. RADD32 ===== */ + +/* ===== Inline Function Start for 4.24. RCRAS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief RCRAS32 (SIMD 32-bit Signed Halving Cross Addition & Subtraction) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * RCRAS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element addition and 32-bit signed integer element subtraction in + * a 64-bit chunk simultaneously. Operands are from crossed 32-bit elements. The results are halved to + * avoid overflow or saturation. + * + * **Description**:\n + * This instruction adds the 32-bit signed integer element in [63:32] of Rs1 with the 32-bit + * signed integer element in [31:0] of Rs2, and subtracts the 32-bit signed integer element in [63:32] of + * Rs2 from the 32-bit signed integer element in [31:0] of Rs1. The element results are first + * arithmetically right-shifted by 1 bit and then written to [63:32] of Rd for addition and [31:0] of Rd + * for subtraction. + * + * **Examples**:\n + * ~~~ + * Please see `RADD32` and `RSUB32` instructions. + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[1] = (Rs1.W[1] + Rs2.W[0]) s>> 1; + * Rd.W[0] = (Rs1.W[0] - Rs2.W[1]) s>> 1; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_RCRAS32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("rcras32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.24. RCRAS32 ===== */ + +/* ===== Inline Function Start for 4.25. RCRSA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief RCRSA32 (SIMD 32-bit Signed Halving Cross Subtraction & Addition) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * RCRSA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element subtraction and 32-bit signed integer element addition in + * a 64-bit chunk simultaneously. Operands are from crossed 32-bit elements. The results are halved to + * avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 32-bit signed integer element in [31:0] of Rs2 from the + * 32-bit signed integer element in [63:32] of Rs1, and adds the 32-bit signed element integer in [31:0] + * of Rs1 with the 32-bit signed integer element in [63:32] of Rs2. The two results are first + * arithmetically right-shifted by 1 bit and then written to [63:32] of Rd for subtraction and [31:0] of + * Rd for addition. + * + * **Examples**:\n + * ~~~ + * Please see `RADD32` and `RSUB32` instructions. + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[1] = (Rs1.W[1] - Rs2.W[0]) s>> 1; + * Rd.W[0] = (Rs1.W[0] + Rs2.W[1]) s>> 1; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_RCRSA32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("rcrsa32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.25. RCRSA32 ===== */ + +/* ===== Inline Function Start for 4.26. RSTAS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief RSTAS32 (SIMD 32-bit Signed Halving Straight Addition & Subtraction) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * RSTAS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element addition and 32-bit signed integer element subtraction in + * a 64-bit chunk simultaneously. Operands are from corresponding 32-bit elements. The results are + * halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction adds the 32-bit signed integer element in [63:32] of Rs1 with the 32-bit + * signed integer element in [63:32] of Rs2, and subtracts the 32-bit signed integer element in [31:0] of + * Rs2 from the 32-bit signed integer element in [31:0] of Rs1. The element results are first + * arithmetically right-shifted by 1 bit and then written to [63:32] of Rd for addition and [31:0] of Rd + * for subtraction. + * + * **Examples**:\n + * ~~~ + * Please see `RADD32` and `RSUB32` instructions. + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[1] = (Rs1.W[1] + Rs2.W[1]) s>> 1; + * Rd.W[0] = (Rs1.W[0] - Rs2.W[0]) s>> 1; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_RSTAS32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("rstas32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.26. RSTAS32 ===== */ + +/* ===== Inline Function Start for 4.27. RSTSA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief RSTSA32 (SIMD 32-bit Signed Halving Straight Subtraction & Addition) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * RSTSA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element subtraction and 32-bit signed integer element addition in + * a 64-bit chunk simultaneously. Operands are from corresponding 32-bit elements. The results are + * halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 32-bit signed integer element in [63:32] of Rs2 from the + * 32-bit signed integer element in [63:32] of Rs1, and adds the 32-bit signed element integer in [31:0] + * of Rs1 with the 32-bit signed integer element in [31:0] of Rs2. The two results are first arithmetically + * right-shifted by 1 bit and then written to [63:32] of Rd for subtraction and [31:0] of Rd for addition. + * + * **Examples**:\n + * ~~~ + * Please see `RADD32` and `RSUB32` instructions. + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[1] = (Rs1.W[1] - Rs2.W[1]) s>> 1; + * Rd.W[0] = (Rs1.W[0] + Rs2.W[0]) s>> 1; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_RSTSA32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("rstsa32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.27. RSTSA32 ===== */ + +/* ===== Inline Function Start for 4.28. RSUB32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief RSUB32 (SIMD 32-bit Signed Halving Subtraction) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * RSUB32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element subtractions simultaneously. The results are halved to + * avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 32-bit signed integer elements in Rs2 from the 32-bit + * signed integer elements in Rs1. The results are first arithmetically right-shifted by 1 bit and then + * written to Rd. + * + * **Examples**:\n + * ~~~ + * * Ra = 0x7FFFFFFF, Rb = 0x80000000 Rt = 0x7FFFFFFF + * * Ra = 0x80000000, Rb = 0x7FFFFFFF Rt = 0x80000000 + * * Ra = 0x80000000, Rb = 0x40000000 Rt = 0xA0000000 + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = (Rs1.W[x] - Rs2.W[x]) s>> 1; + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_RSUB32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("rsub32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.28. RSUB32 ===== */ + +/* ===== Inline Function Start for 4.29. SLL32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_SHIFT + * \brief SLL32 (SIMD 32-bit Shift Left Logical) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SLL32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit elements logical left shift operations simultaneously. The shift amount is a + * variable from a GPR. + * + * **Description**:\n + * The 32-bit elements in Rs1 are left-shifted logically. And the results are written to Rd. + * The shifted out bits are filled with zero and the shift amount is specified by the low-order 5-bits of + * the value in the Rs2 register. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[4:0]; + * Rd.W[x] = Rs1.W[x] << sa; + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SLL32(unsigned long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("sll32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.29. SLL32 ===== */ + +/* ===== Inline Function Start for 4.30. SLLI32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_SHIFT + * \brief SLLI32 (SIMD 32-bit Shift Left Logical Immediate) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SLLI32 Rd, Rs1, imm5u[4:0] + * ~~~ + * + * **Purpose**:\n + * Do 32-bit element logical left shift operations simultaneously. The shift amount is an + * immediate value. + * + * **Description**:\n + * The 32-bit elements in Rs1 are left-shifted logically. The shifted out bits are filled with + * zero and the shift amount is specified by the imm5u[4:0] constant. And the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = imm5u[4:0]; + * Rd.W[x] = Rs1.W[x] << sa; + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SLLI32(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("slli32 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 4.30. SLLI32 ===== */ + +/* ===== Inline Function Start for 4.31. SMAX32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_MISC + * \brief SMAX32 (SIMD 32-bit Signed Maximum) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SMAX32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer elements finding maximum operations simultaneously. + * + * **Description**:\n + * This instruction compares the 32-bit signed integer elements in Rs1 with the 32-bit + * signed integer elements in Rs2 and selects the numbers that is greater than the other one. The + * selected results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = (Rs1.W[x] > Rs2.W[x])? Rs1.W[x] : Rs2.W[x]; + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SMAX32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("smax32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.31. SMAX32 ===== */ + +/* ===== Inline Function Start for 4.32.1. SMBB32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_MULT + * \brief SMBB32 (Signed Multiply Bottom Word & Bottom Word) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SMBB32 Rd, Rs1, Rs2 + * SMBT32 Rd, Rs1, Rs2 + * SMTT32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element of a register with the signed 32-bit element of another + * register and write the 64-bit result to a third register. + * * SMBB32: bottom*bottom + * * SMBT32: bottom*top + * * SMTT32: top*top + * + * **Description**:\n + * For the `SMBB32` instruction, it multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit + * element of Rs2. It is actually an alias of `MULSR64` instruction. + * For the `SMBT32` instruction, it multiplies the bottom 32-bit element of Rs1 with the top 32-bit + * element of Rs2. + * For the `SMTT32` instruction, it multiplies the top 32-bit element of Rs1 with the top 32-bit element + * of Rs2. + * The 64-bit multiplication result is written to Rd. The 32-bit contents of Rs1 and Rs2 are treated as + * signed integers. + * + * **Operations**:\n + * ~~~ + * res = Rs1.W[0] * Rs2.W[0]; // SMBB32 res = Rs1.W[0] * Rs2.w[1]; // SMBT32 res = Rs1.W[1] * Rs2.W[1]; + * // SMTT32 Rd = res; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMBB32(unsigned long a, unsigned long b) +{ + long result; + __ASM volatile("smbb32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.32.1. SMBB32 ===== */ + +/* ===== Inline Function Start for 4.32.2. SMBT32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_MULT + * \brief SMBT32 (Signed Multiply Bottom Word & Top Word) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SMBB32 Rd, Rs1, Rs2 + * SMBT32 Rd, Rs1, Rs2 + * SMTT32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element of a register with the signed 32-bit element of another + * register and write the 64-bit result to a third register. + * * SMBB32: bottom*bottom + * * SMBT32: bottom*top + * * SMTT32: top*top + * + * **Description**:\n + * For the `SMBB32` instruction, it multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit + * element of Rs2. It is actually an alias of `MULSR64` instruction. + * For the `SMBT32` instruction, it multiplies the bottom 32-bit element of Rs1 with the top 32-bit + * element of Rs2. + * For the `SMTT32` instruction, it multiplies the top 32-bit element of Rs1 with the top 32-bit element + * of Rs2. + * The 64-bit multiplication result is written to Rd. The 32-bit contents of Rs1 and Rs2 are treated as + * signed integers. + * + * **Operations**:\n + * ~~~ + * res = Rs1.W[0] * Rs2.W[0]; // SMBB32 res = Rs1.W[0] * Rs2.w[1]; // SMBT32 res = Rs1.W[1] * Rs2.W[1]; + * // SMTT32 Rd = res; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMBT32(unsigned long a, unsigned long b) +{ + long result; + __ASM volatile("smbt32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.32.2. SMBT32 ===== */ + +/* ===== Inline Function Start for 4.32.3. SMTT32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_MULT + * \brief SMTT32 (Signed Multiply Top Word & Top Word) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SMBB32 Rd, Rs1, Rs2 + * SMBT32 Rd, Rs1, Rs2 + * SMTT32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element of a register with the signed 32-bit element of another + * register and write the 64-bit result to a third register. + * * SMBB32: bottom*bottom + * * SMBT32: bottom*top + * * SMTT32: top*top + * + * **Description**:\n + * For the `SMBB32` instruction, it multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit + * element of Rs2. It is actually an alias of `MULSR64` instruction. + * For the `SMBT32` instruction, it multiplies the bottom 32-bit element of Rs1 with the top 32-bit + * element of Rs2. + * For the `SMTT32` instruction, it multiplies the top 32-bit element of Rs1 with the top 32-bit element + * of Rs2. + * The 64-bit multiplication result is written to Rd. The 32-bit contents of Rs1 and Rs2 are treated as + * signed integers. + * + * **Operations**:\n + * ~~~ + * res = Rs1.W[0] * Rs2.W[0]; // SMBB32 res = Rs1.W[0] * Rs2.w[1]; // SMBT32 res = Rs1.W[1] * Rs2.W[1]; + * // SMTT32 Rd = res; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMTT32(unsigned long a, unsigned long b) +{ + long result; + __ASM volatile("smtt32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.32.3. SMTT32 ===== */ + +/* ===== Inline Function Start for 4.33.1. SMDS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PARALLEL_MAC + * \brief SMDS32 (Signed Multiply Two Words and Subtract) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SMDS32 Rd, Rs1, Rs2 + * SMDRS32 Rd, Rs1, Rs2 + * SMXDS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32-bit multiplications from the l 32-bit element of two registers; and then + * perform a subtraction operation between the two 64-bit results. + * * SMDS32: top*top - bottom*bottom + * * SMDRS32: bottom*bottom - top*top + * * SMXDS32: top*bottom - bottom*top + * + * **Description**:\n + * For the `SMDS32` instruction, it multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit + * element of Rs2 and then subtracts the result from the result of multiplying the top 32-bit element of + * Rs1 with the top 32-bit element of Rs2. + * For the `SMDRS32` instruction, it multiplies the top 32-bit element of Rs1 with the top 32-bit + * element of Rs2 and then subtracts the result from the result of multiplying the bottom 32-bit + * element of Rs1 with the bottom 32-bit element of Rs2. + * For the `SMXDS32` instruction, it multiplies the bottom 32-bit element of Rs1 with the top 32-bit + * element of Rs2 and then subtracts the result from the result of multiplying the top 32-bit element of + * Rs1 with the bottom 32-bit element of Rs2. + * The subtraction result is written to Rd. The 32-bit contents of Rs1 and Rs2 are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * Rt = (Rs1.W[1] * Rs2.W[1]) - (Rs1.W[0] * Rs2.W[0]); // SMDS32 + * Rt = (Rs1.W[0] * Rs2.W[0]) - (Rs1.W[1] * Rs2.W[1]); // SMDRS32 + * Rt = (Rs1.W[1] * Rs2.W[0]) - (Rs1.W[0] * Rs2.W[1]); // SMXDS32 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMDS32(unsigned long a, unsigned long b) +{ + long result; + __ASM volatile("smds32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.33.1. SMDS32 ===== */ + +/* ===== Inline Function Start for 4.33.2. SMDRS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PARALLEL_MAC + * \brief SMDRS32 (Signed Multiply Two Words and Reverse Subtract) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SMDS32 Rd, Rs1, Rs2 + * SMDRS32 Rd, Rs1, Rs2 + * SMXDS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32-bit multiplications from the l 32-bit element of two registers; and then + * perform a subtraction operation between the two 64-bit results. + * * SMDS32: top*top - bottom*bottom + * * SMDRS32: bottom*bottom - top*top + * * SMXDS32: top*bottom - bottom*top + * + * **Description**:\n + * For the `SMDS32` instruction, it multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit + * element of Rs2 and then subtracts the result from the result of multiplying the top 32-bit element of + * Rs1 with the top 32-bit element of Rs2. + * For the `SMDRS32` instruction, it multiplies the top 32-bit element of Rs1 with the top 32-bit + * element of Rs2 and then subtracts the result from the result of multiplying the bottom 32-bit + * element of Rs1 with the bottom 32-bit element of Rs2. + * For the `SMXDS32` instruction, it multiplies the bottom 32-bit element of Rs1 with the top 32-bit + * element of Rs2 and then subtracts the result from the result of multiplying the top 32-bit element of + * Rs1 with the bottom 32-bit element of Rs2. + * The subtraction result is written to Rd. The 32-bit contents of Rs1 and Rs2 are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * Rt = (Rs1.W[1] * Rs2.W[1]) - (Rs1.W[0] * Rs2.W[0]); // SMDS32 + * Rt = (Rs1.W[0] * Rs2.W[0]) - (Rs1.W[1] * Rs2.W[1]); // SMDRS32 + * Rt = (Rs1.W[1] * Rs2.W[0]) - (Rs1.W[0] * Rs2.W[1]); // SMXDS32 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMDRS32(unsigned long a, unsigned long b) +{ + long result; + __ASM volatile("smdrs32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.33.2. SMDRS32 ===== */ + +/* ===== Inline Function Start for 4.33.3. SMXDS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PARALLEL_MAC + * \brief SMXDS32 (Signed Crossed Multiply Two Words and Subtract) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SMDS32 Rd, Rs1, Rs2 + * SMDRS32 Rd, Rs1, Rs2 + * SMXDS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32-bit multiplications from the l 32-bit element of two registers; and then + * perform a subtraction operation between the two 64-bit results. + * * SMDS32: top*top - bottom*bottom + * * SMDRS32: bottom*bottom - top*top + * * SMXDS32: top*bottom - bottom*top + * + * **Description**:\n + * For the `SMDS32` instruction, it multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit + * element of Rs2 and then subtracts the result from the result of multiplying the top 32-bit element of + * Rs1 with the top 32-bit element of Rs2. + * For the `SMDRS32` instruction, it multiplies the top 32-bit element of Rs1 with the top 32-bit + * element of Rs2 and then subtracts the result from the result of multiplying the bottom 32-bit + * element of Rs1 with the bottom 32-bit element of Rs2. + * For the `SMXDS32` instruction, it multiplies the bottom 32-bit element of Rs1 with the top 32-bit + * element of Rs2 and then subtracts the result from the result of multiplying the top 32-bit element of + * Rs1 with the bottom 32-bit element of Rs2. + * The subtraction result is written to Rd. The 32-bit contents of Rs1 and Rs2 are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * Rt = (Rs1.W[1] * Rs2.W[1]) - (Rs1.W[0] * Rs2.W[0]); // SMDS32 + * Rt = (Rs1.W[0] * Rs2.W[0]) - (Rs1.W[1] * Rs2.W[1]); // SMDRS32 + * Rt = (Rs1.W[1] * Rs2.W[0]) - (Rs1.W[0] * Rs2.W[1]); // SMXDS32 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMXDS32(unsigned long a, unsigned long b) +{ + long result; + __ASM volatile("smxds32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.33.3. SMXDS32 ===== */ + +/* ===== Inline Function Start for 4.34. SMIN32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_MISC + * \brief SMIN32 (SIMD 32-bit Signed Minimum) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SMIN32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer elements finding minimum operations simultaneously. + * + * **Description**:\n + * This instruction compares the 32-bit signed integer elements in Rs1 with the 32-bit + * signed integer elements in Rs2 and selects the numbers that is less than the other one. The selected + * results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = (Rs1.W[x] < Rs2.W[x])? Rs1.W[x] : Rs2.W[x]; + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SMIN32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("smin32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.34. SMIN32 ===== */ + +/* ===== Inline Function Start for 4.35.1. SRA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_SHIFT + * \brief SRA32 (SIMD 32-bit Shift Right Arithmetic) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SRA32 Rd, Rs1, Rs2 + * SRA32.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit element arithmetic right shift operations simultaneously. The shift amount is a + * variable from a GPR. The `.u` form performs additional rounding up operations on the shifted + * results. + * + * **Description**:\n + * The 32-bit data elements in Rs1 are right-shifted arithmetically, that is, the shifted out + * bits are filled with the sign-bit of the data elements. The shift amount is specified by the low-order + * 5-bits of the value in the Rs2 register. For the rounding operation of the `.u` form, a value of 1 is + * added to the most significant discarded bit of each 32-bit data element to calculate the final results. + * And the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[4:0]; + * if (sa > 0) { + * if (`.u` form) { // SRA32.u + * res[31:-1] = SE33(Rs1.W[x][31:sa-1]) + 1; + * Rd.W[x] = res[31:0]; + * else { // SRA32 + * Rd.W[x] = SE32(Rs1.W[x][31:sa]) + * } + * } else { + * Rd = Rs1; + * } + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SRA32(unsigned long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("sra32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.35.1. SRA32 ===== */ + +/* ===== Inline Function Start for 4.35.2. SRA32.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_SHIFT + * \brief SRA32.u (SIMD 32-bit Rounding Shift Right Arithmetic) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SRA32 Rd, Rs1, Rs2 + * SRA32.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit element arithmetic right shift operations simultaneously. The shift amount is a + * variable from a GPR. The `.u` form performs additional rounding up operations on the shifted + * results. + * + * **Description**:\n + * The 32-bit data elements in Rs1 are right-shifted arithmetically, that is, the shifted out + * bits are filled with the sign-bit of the data elements. The shift amount is specified by the low-order + * 5-bits of the value in the Rs2 register. For the rounding operation of the `.u` form, a value of 1 is + * added to the most significant discarded bit of each 32-bit data element to calculate the final results. + * And the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[4:0]; + * if (sa > 0) { + * if (`.u` form) { // SRA32.u + * res[31:-1] = SE33(Rs1.W[x][31:sa-1]) + 1; + * Rd.W[x] = res[31:0]; + * else { // SRA32 + * Rd.W[x] = SE32(Rs1.W[x][31:sa]) + * } + * } else { + * Rd = Rs1; + * } + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SRA32_U(unsigned long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("sra32.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.35.2. SRA32.u ===== */ + +/* ===== Inline Function Start for 4.36.1. SRAI32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_SHIFT + * \brief SRAI32 (SIMD 32-bit Shift Right Arithmetic Immediate) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SRAI32 Rd, Rs1, imm5u + * SRAI32.u Rd, Rs1, imm5u + * ~~~ + * + * **Purpose**:\n + * Do 32-bit elements arithmetic right shift operations simultaneously. The shift amount is + * an immediate value. The `.u` form performs additional rounding up operations on the shifted + * results. + * + * **Description**:\n + * The 32-bit data elements in Rs1 are right-shifted arithmetically, that is, the shifted out + * bits are filled with the sign-bit of the 32-bit data elements. The shift amount is specified by the + * imm5u constant. For the rounding operation of the `.u` form, a value of 1 is added to the most + * significant discarded bit of each 32-bit data to calculate the final results. And the results are written + * to Rd. + * + * **Operations**:\n + * ~~~ + * sa = imm5u[4:0]; + * if (sa > 0) { + * if (`.u` form) { // SRAI32.u + * res[31:-1] = SE33(Rs1.W[x][31:sa-1]) + 1; + * Rd.W[x] = res[31:0]; + * else { // SRAI32 + * Rd.W[x] = SE32(Rs1.W[x][31:sa]); + * } + * } else { + * Rd = Rs1; + * } + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SRAI32(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("srai32 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 4.36.1. SRAI32 ===== */ + +/* ===== Inline Function Start for 4.36.2. SRAI32.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_SHIFT + * \brief SRAI32.u (SIMD 32-bit Rounding Shift Right Arithmetic Immediate) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SRAI32 Rd, Rs1, imm5u + * SRAI32.u Rd, Rs1, imm5u + * ~~~ + * + * **Purpose**:\n + * Do 32-bit elements arithmetic right shift operations simultaneously. The shift amount is + * an immediate value. The `.u` form performs additional rounding up operations on the shifted + * results. + * + * **Description**:\n + * The 32-bit data elements in Rs1 are right-shifted arithmetically, that is, the shifted out + * bits are filled with the sign-bit of the 32-bit data elements. The shift amount is specified by the + * imm5u constant. For the rounding operation of the `.u` form, a value of 1 is added to the most + * significant discarded bit of each 32-bit data to calculate the final results. And the results are written + * to Rd. + * + * **Operations**:\n + * ~~~ + * sa = imm5u[4:0]; + * if (sa > 0) { + * if (`.u` form) { // SRAI32.u + * res[31:-1] = SE33(Rs1.W[x][31:sa-1]) + 1; + * Rd.W[x] = res[31:0]; + * else { // SRAI32 + * Rd.W[x] = SE32(Rs1.W[x][31:sa]); + * } + * } else { + * Rd = Rs1; + * } + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SRAI32_U(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("srai32.u %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 4.36.2. SRAI32.u ===== */ + +/* ===== Inline Function Start for 4.37. SRAIW.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_NON_SIMD_32B_SHIFT + * \brief SRAIW.u (Rounding Shift Right Arithmetic Immediate Word) + * \details + * **Type**: DSP (RV64 only) + * + * **Syntax**:\n + * ~~~ + * SRAIW.u Rd, Rs1, imm5u + * ~~~ + * + * **Purpose**:\n + * Perform a 32-bit arithmetic right shift operation with rounding. The shift amount is an + * immediate value. + * + * **Description**:\n + * This instruction right-shifts the lower 32-bit content of Rs1 arithmetically. The shifted + * out bits are filled with the sign-bit Rs1(31) and the shift amount is specified by the imm5u constant. + * For the rounding operation, a value of 1 is added to the most significant discarded bit of the data to + * calculate the final result. And the result is sign-extended and written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = imm5u; + * if (sa != 0) { + * res[31:-1] = SE33(Rs1[31:(sa-1)]) + 1; + * Rd = SE32(res[31:0]); + * } else { + * Rd = SE32(Rs1.W[0]); + * } + * ~~~ + * + * \param [in] a int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in long type + */ +#define __RV_SRAIW_U(a, b) \ + ({ \ + long result; \ + int __a = (int)(a); \ + __ASM volatile("sraiw.u %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 4.37. SRAIW.u ===== */ + +/* ===== Inline Function Start for 4.38.1. SRL32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_SHIFT + * \brief SRL32 (SIMD 32-bit Shift Right Logical) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SRL32 Rd, Rs1, Rs2 + * SRL32.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit element logical right shift operations simultaneously. The shift amount is a + * variable from a GPR. The `.u` form performs additional rounding up operations on the shifted + * results. + * + * **Description**:\n + * The 32-bit data elements in Rs1 are right-shifted logically, that is, the shifted out bits + * are filled with zero. The shift amount is specified by the low-order 5-bits of the value in the Rs2 + * register. For the rounding operation of the `.u` form, a value of 1 is added to the most significant + * discarded bit of each 32-bit data element to calculate the final results. And the results are written to + * Rd. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[4:0]; + * if (sa > 0) { + * if (`.u` form) { // SRA32.u + * res[31:-1] = ZE33(Rs1.W[x][31:sa-1]) + 1; + * Rd.W[x] = res[31:0]; + * else { // SRA32 + * Rd.W[x] = ZE32(Rs1.W[x][31:sa]) + * } + * } else { + * Rd = Rs1; + * } + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SRL32(unsigned long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("srl32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.38.1. SRL32 ===== */ + +/* ===== Inline Function Start for 4.38.2. SRL32.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_SHIFT + * \brief SRL32.u (SIMD 32-bit Rounding Shift Right Logical) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SRL32 Rd, Rs1, Rs2 + * SRL32.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit element logical right shift operations simultaneously. The shift amount is a + * variable from a GPR. The `.u` form performs additional rounding up operations on the shifted + * results. + * + * **Description**:\n + * The 32-bit data elements in Rs1 are right-shifted logically, that is, the shifted out bits + * are filled with zero. The shift amount is specified by the low-order 5-bits of the value in the Rs2 + * register. For the rounding operation of the `.u` form, a value of 1 is added to the most significant + * discarded bit of each 32-bit data element to calculate the final results. And the results are written to + * Rd. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[4:0]; + * if (sa > 0) { + * if (`.u` form) { // SRA32.u + * res[31:-1] = ZE33(Rs1.W[x][31:sa-1]) + 1; + * Rd.W[x] = res[31:0]; + * else { // SRA32 + * Rd.W[x] = ZE32(Rs1.W[x][31:sa]) + * } + * } else { + * Rd = Rs1; + * } + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SRL32_U(unsigned long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("srl32.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.38.2. SRL32.u ===== */ + +/* ===== Inline Function Start for 4.39.1. SRLI32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_SHIFT + * \brief SRLI32 (SIMD 32-bit Shift Right Logical Immediate) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SRLI32 Rd, Rs1, imm5u + * SRLI32.u Rd, Rs1, imm5u + * ~~~ + * + * **Purpose**:\n + * Do 32-bit elements logical right shift operations simultaneously. The shift amount is an + * immediate value. The `.u` form performs additional rounding up operations on the shifted results. + * + * **Description**:\n + * The 32-bit data elements in Rs1 are right-shifted logically, that is, the shifted out bits + * are filled with zero. The shift amount is specified by the imm5u constant. For the rounding + * operation of the `.u` form, a value of 1 is added to the most significant discarded bit of each 32-bit + * data to calculate the final results. And the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = imm5u[4:0]; + * if (sa > 0) { + * if (`.u` form) { // SRLI32.u + * res[31:-1] = ZE33(Rs1.W[x][31:sa-1]) + 1; + * Rd.W[x] = res[31:0]; + * else { // SRLI32 + * Rd.W[x] = ZE32(Rs1.W[x][31:sa]); + * } + * } else { + * Rd = Rs1; + * } + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SRLI32(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("srli32 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 4.39.1. SRLI32 ===== */ + +/* ===== Inline Function Start for 4.39.2. SRLI32.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_SHIFT + * \brief SRLI32.u (SIMD 32-bit Rounding Shift Right Logical Immediate) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SRLI32 Rd, Rs1, imm5u + * SRLI32.u Rd, Rs1, imm5u + * ~~~ + * + * **Purpose**:\n + * Do 32-bit elements logical right shift operations simultaneously. The shift amount is an + * immediate value. The `.u` form performs additional rounding up operations on the shifted results. + * + * **Description**:\n + * The 32-bit data elements in Rs1 are right-shifted logically, that is, the shifted out bits + * are filled with zero. The shift amount is specified by the imm5u constant. For the rounding + * operation of the `.u` form, a value of 1 is added to the most significant discarded bit of each 32-bit + * data to calculate the final results. And the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = imm5u[4:0]; + * if (sa > 0) { + * if (`.u` form) { // SRLI32.u + * res[31:-1] = ZE33(Rs1.W[x][31:sa-1]) + 1; + * Rd.W[x] = res[31:0]; + * else { // SRLI32 + * Rd.W[x] = ZE32(Rs1.W[x][31:sa]); + * } + * } else { + * Rd = Rs1; + * } + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SRLI32_U(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("srli32.u %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 4.39.2. SRLI32.u ===== */ + +/* ===== Inline Function Start for 4.40. STAS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief STAS32 (SIMD 32-bit Straight Addition & Subtraction) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * STAS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit integer element addition and 32-bit integer element subtraction in a 64-bit + * chunk simultaneously. Operands are from corresponding 32-bit elements. + * + * **Description**:\n + * This instruction adds the 32-bit integer element in [63:32] of Rs1 with the 32-bit + * integer element in [63:32] of Rs2, and writes the result to [63:32] of Rd; at the same time, it subtracts + * the 32-bit integer element in [31:0] of Rs2 from the 32-bit integer element in [31:0] of Rs1, and + * writes the result to [31:0] of Rd. + * + * **Note**:\n + * This instruction can be used for either signed or unsigned operations. + * + * **Operations**:\n + * ~~~ + * Rd.W[1] = Rs1.W[1] + Rs2.W[1]; + * Rd.W[0] = Rs1.W[0] - Rs2.W[0]; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_STAS32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("stas32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.40. STAS32 ===== */ + +/* ===== Inline Function Start for 4.41. STSA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief STSA32 (SIMD 32-bit Straight Subtraction & Addition) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * STSA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit integer element subtraction and 32-bit integer element addition in a 64-bit + * chunk simultaneously. Operands are from corresponding 32-bit elements. + * *Description: * + * This instruction subtracts the 32-bit integer element in [63:32] of Rs2 from the 32-bit integer + * element in [63:32] of Rs1, and writes the result to [63:32] of Rd; at the same time, it adds the 32-bit + * integer element in [31:0] of Rs1 with the 32-bit integer element in [31:0] of Rs2, and writes the result + * to [31:0] of Rd + * + * **Note**:\n + * This instruction can be used for either signed or unsigned operations. + * + * **Operations**:\n + * ~~~ + * Rd.W[1] = Rs1.W[1] - Rs2.W[1]; + * Rd.W[0] = Rs1.W[0] + Rs2.W[0]; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_STSA32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("stsa32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.41. STSA32 ===== */ + +/* ===== Inline Function Start for 4.42. SUB32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief SUB32 (SIMD 32-bit Subtraction) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SUB32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit integer element subtractions simultaneously. + * + * **Description**:\n + * This instruction subtracts the 32-bit integer elements in Rs2 from the 32-bit integer + * elements in Rs1, and then writes the results to Rd. + * + * **Note**:\n + * This instruction can be used for either signed or unsigned subtraction. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = Rs1.W[x] - Rs2.W[x]; + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SUB32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("sub32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.42. SUB32 ===== */ + +/* ===== Inline Function Start for 4.43. UKADD32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief UKADD32 (SIMD 32-bit Unsigned Saturating Addition) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * UKADD32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit unsigned integer element saturating additions simultaneously. + * + * **Description**:\n + * This instruction adds the 32-bit unsigned integer elements in Rs1 with the 32-bit + * unsigned integer elements in Rs2. If any of the results are beyond the 32-bit unsigned number + * range (0 <= RES <= 2^32-1), they are saturated to the range and the OV bit is set to 1. The saturated + * results are written to Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.W[x] + Rs2.W[x]; + * if (res[x] > (2^32)-1) { + * res[x] = (2^32)-1; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKADD32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ukadd32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.43. UKADD32 ===== */ + +/* ===== Inline Function Start for 4.44. UKCRAS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief UKCRAS32 (SIMD 32-bit Unsigned Saturating Cross Addition & Subtraction) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * UKCRAS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do one 32-bit unsigned integer element saturating addition and one 32-bit unsigned + * integer element saturating subtraction in a 64-bit chunk simultaneously. Operands are from crossed + * 32-bit elements. + * + * **Description**:\n + * This instruction adds the 32-bit unsigned integer element in [63:32] of Rs1 with the 32- + * bit unsigned integer element in [31:0] of Rs2; at the same time, it subtracts the 32-bit unsigned + * integer element in [63:32] of Rs2 from the 32-bit unsigned integer element in [31:0] Rs1. If any of the + * results are beyond the 32-bit unsigned number range (0 <= RES <= 2^32-1), they are saturated to the + * range and the OV bit is set to 1. The saturated results are written to [63:32] of Rd for addition and + * [31:0] of Rd for subtraction. + * + * **Operations**:\n + * ~~~ + * res1 = Rs1.W[1] + Rs2.W[0]; + * res2 = Rs1.W[0] - Rs2.W[1]; + * if (res1 > (2^32)-1) { + * res1 = (2^32)-1; + * OV = 1; + * } + * if (res2 < 0) { + * res2 = 0; + * OV = 1; + * } + * Rd.W[1] = res1; + * Rd.W[0] = res2; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKCRAS32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ukcras32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.44. UKCRAS32 ===== */ + +/* ===== Inline Function Start for 4.45. UKCRSA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief UKCRSA32 (SIMD 32-bit Unsigned Saturating Cross Subtraction & Addition) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * UKCRSA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do one 32-bit unsigned integer element saturating subtraction and one 32-bit unsigned + * integer element saturating addition in a 64-bit chunk simultaneously. Operands are from crossed + * 32-bit elements. + * + * **Description**:\n + * This instruction subtracts the 32-bit unsigned integer element in [31:0] of Rs2 from the + * 32-bit unsigned integer element in [63:32] of Rs1; at the same time, it adds the 32-bit unsigned + * integer element in [63:32] of Rs2 with the 32-bit unsigned integer element in [31:0] Rs1. If any of the + * results are beyond the 32-bit unsigned number range (0 <= RES <= 2^32-1), they are saturated to the + * range and the OV bit is set to 1. The saturated results are written to [63:32] of Rd for subtraction and + * [31:0] of Rd for addition. + * + * **Operations**:\n + * ~~~ + * res1 = Rs1.W[1] - Rs2.W[0]; + * res2 = Rs1.W[0] + Rs2.W[1]; + * if (res1 < 0) { + * res1 = 0; + * OV = 1; + * } else if (res2 > (2^32)-1) { + * res2 = (2^32)-1; + * OV = 1; + * } + * Rd.W[1] = res1; + * Rd.W[0] = res2; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKCRSA32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ukcrsa32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.45. UKCRSA32 ===== */ + +/* ===== Inline Function Start for 4.46. UKSTAS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief UKSTAS32 (SIMD 32-bit Unsigned Saturating Straight Addition & Subtraction) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * UKSTAS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do one 32-bit unsigned integer element saturating addition and one 32-bit unsigned + * integer element saturating subtraction in a 64-bit chunk simultaneously. Operands are from + * corresponding 32-bit elements. + * + * **Description**:\n + * This instruction adds the 32-bit unsigned integer element in [63:32] of Rs1 with the 32- + * bit unsigned integer element in [63:32] of Rs2; at the same time, it subtracts the 32-bit unsigned + * integer element in [31:0] of Rs2 from the 32-bit unsigned integer element in [31:0] Rs1. If any of the + * results are beyond the 32-bit unsigned number range (0 <= RES <= 2^32-1), they are saturated to the + * range and the OV bit is set to 1. The saturated results are written to [63:32] of Rd for addition and + * [31:0] of Rd for subtraction. + * + * **Operations**:\n + * ~~~ + * res1 = Rs1.W[1] + Rs2.W[1]; + * res2 = Rs1.W[0] - Rs2.W[0]; + * if (res1 > (2^32)-1) { + * res1 = (2^32)-1; + * OV = 1; + * } + * if (res2 < 0) { + * res2 = 0; + * OV = 1; + * } + * Rd.W[1] = res1; + * Rd.W[0] = res2; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKSTAS32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ukstas32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.46. UKSTAS32 ===== */ + +/* ===== Inline Function Start for 4.47. UKSTSA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief UKSTSA32 (SIMD 32-bit Unsigned Saturating Straight Subtraction & Addition) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * UKSTSA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do one 32-bit unsigned integer element saturating subtraction and one 32-bit unsigned + * integer element saturating addition in a 64-bit chunk simultaneously. Operands are from + * corresponding 32-bit elements. + * + * **Description**:\n + * This instruction subtracts the 32-bit unsigned integer element in [63:32] of Rs2 from + * the 32-bit unsigned integer element in [63:32] of Rs1; at the same time, it adds the 32-bit unsigned + * integer element in [31:0] of Rs2 with the 32-bit unsigned integer element in [31:0] Rs1. If any of the + * results are beyond the 32-bit unsigned number range (0 <= RES <= 2^32-1), they are saturated to the + * range and the OV bit is set to 1. The saturated results are written to [63:32] of Rd for subtraction and + * [31:0] of Rd for addition. + * + * **Operations**:\n + * ~~~ + * res1 = Rs1.W[1] - Rs2.W[1]; + * res2 = Rs1.W[0] + Rs2.W[0]; + * if (res1 < 0) { + * res1 = 0; + * OV = 1; + * } else if (res2 > (2^32)-1) { + * res2 = (2^32)-1; + * OV = 1; + * } + * Rd.W[1] = res1; + * Rd.W[0] = res2; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKSTSA32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ukstsa32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.47. UKSTSA32 ===== */ + +/* ===== Inline Function Start for 4.48. UKSUB32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief UKSUB32 (SIMD 32-bit Unsigned Saturating Subtraction) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * UKSUB32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit unsigned integer elements saturating subtractions simultaneously. + * + * **Description**:\n + * This instruction subtracts the 32-bit unsigned integer elements in Rs2 from the 32-bit + * unsigned integer elements in Rs1. If any of the results are beyond the 32-bit unsigned number + * range (0 <= RES <= 2^32-1), they are saturated to the range and the OV bit is set to 1. The saturated + * results are written to Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.W[x] - Rs2.W[x]; + * if (res[x] < 0) { + * res[x] = 0; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKSUB32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("uksub32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.48. UKSUB32 ===== */ + +/* ===== Inline Function Start for 4.49. UMAX32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_MISC + * \brief UMAX32 (SIMD 32-bit Unsigned Maximum) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * UMAX32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit unsigned integer elements finding maximum operations simultaneously. + * + * **Description**:\n + * This instruction compares the 32-bit unsigned integer elements in Rs1 with the 32-bit + * unsigned integer elements in Rs2 and selects the numbers that is greater than the other one. The + * selected results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = (Rs1.W[x] u> Rs2.W[x])? Rs1.W[x] : Rs2.W[x]; + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UMAX32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("umax32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.49. UMAX32 ===== */ + +/* ===== Inline Function Start for 4.50. UMIN32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_MISC + * \brief UMIN32 (SIMD 32-bit Unsigned Minimum) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * UMIN32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit unsigned integer elements finding minimum operations simultaneously. + * + * **Description**:\n + * This instruction compares the 32-bit unsigned integer elements in Rs1 with the 32-bit + * unsigned integer elements in Rs2 and selects the numbers that is less than the other one. The + * selected results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = (Rs1.W[x] > 1; + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_URADD32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("uradd32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.51. URADD32 ===== */ + +/* ===== Inline Function Start for 4.52. URCRAS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief URCRAS32 (SIMD 32-bit Unsigned Halving Cross Addition & Subtraction) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * URCRAS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit unsigned integer element addition and 32-bit unsigned integer element + * subtraction in a 64-bit chunk simultaneously. Operands are from crossed 32-bit elements. The + * results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction adds the 32-bit unsigned integer element in [63:32] of Rs1 with the 32- + * bit unsigned integer element in [31:0] of Rs2, and subtracts the 32-bit unsigned integer element in + * [63:32] of Rs2 from the 32-bit unsigned integer element in [31:0] of Rs1. The element results are first + * logically right-shifted by 1 bit and then written to [63:32] of Rd for addition and [31:0] of Rd for + * subtraction. + * + * **Examples**:\n + * ~~~ + * Please see `URADD32` and `URSUB32` instructions. + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[1] = (Rs1.W[1] + Rs2.W[0]) u>> 1; + * Rd.W[0] = (Rs1.W[0] - Rs2.W[1]) u>> 1; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_URCRAS32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("urcras32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.52. URCRAS32 ===== */ + +/* ===== Inline Function Start for 4.53. URCRSA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief URCRSA32 (SIMD 32-bit Unsigned Halving Cross Subtraction & Addition) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * URCRSA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit unsigned integer element subtraction and 32-bit unsigned integer element + * addition in a 64-bit chunk simultaneously. Operands are from crossed 32-bit elements. The results + * are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 32-bit unsigned integer element in [31:0] of Rs2 from the + * 32-bit unsigned integer element in [63:32] of Rs1, and adds the 32-bit unsigned element integer in + * [31:0] of Rs1 with the 32-bit unsigned integer element in [63:32] of Rs2. The two results are first + * logically right-shifted by 1 bit and then written to [63:32] of Rd for subtraction and [31:0] of Rd for + * addition. + * + * **Examples**:\n + * ~~~ + * Please see `URADD32` and `URSUB32` instructions. + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[1] = (Rs1.W[1] - Rs2.W[0]) u>> 1; + * Rd.W[0] = (Rs1.W[0] + Rs2.W[1]) u>> 1; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_URCRSA32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("urcrsa32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.53. URCRSA32 ===== */ + +/* ===== Inline Function Start for 4.54. URSTAS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief URSTAS32 (SIMD 32-bit Unsigned Halving Straight Addition & Subtraction) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * URSTAS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit unsigned integer element addition and 32-bit unsigned integer element + * subtraction in a 64-bit chunk simultaneously. Operands are from corresponding 32-bit elements. + * The results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction adds the 32-bit unsigned integer element in [63:32] of Rs1 with the 32- + * bit unsigned integer element in [63:32] of Rs2, and subtracts the 32-bit unsigned integer element in + * [31:0] of Rs2 from the 32-bit unsigned integer element in [31:0] of Rs1. The element results are first + * logically right-shifted by 1 bit and then written to [63:32] of Rd for addition and [31:0] of Rd for + * subtraction. + * + * **Examples**:\n + * ~~~ + * Please see `URADD32` and `URSUB32` instructions. + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[1] = (Rs1.W[1] + Rs2.W[1]) u>> 1; + * Rd.W[0] = (Rs1.W[0] - Rs2.W[0]) u>> 1; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_URSTAS32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("urstas32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.54. URSTAS32 ===== */ + +/* ===== Inline Function Start for 4.55. URSTSA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief URSTSA32 (SIMD 32-bit Unsigned Halving Straight Subtraction & Addition) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * URSTSA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit unsigned integer element subtraction and 32-bit unsigned integer element + * addition in a 64-bit chunk simultaneously. Operands are from corresponding 32-bit elements. The + * results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 32-bit unsigned integer element in [63:32] of Rs2 from + * the 32-bit unsigned integer element in [63:32] of Rs1, and adds the 32-bit unsigned element integer + * in [31:0] of Rs1 with the 32-bit unsigned integer element in [31:0] of Rs2. The two results are first + * logically right-shifted by 1 bit and then written to [63:32] of Rd for subtraction and [31:0] of Rd for + * addition. + * + * **Examples**:\n + * ~~~ + * Please see `URADD32` and `URSUB32` instructions. + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[1] = (Rs1.W[1] - Rs2.W[1]) u>> 1; + * Rd.W[0] = (Rs1.W[0] + Rs2.W[0]) u>> 1; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_URSTSA32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("urstsa32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.55. URSTSA32 ===== */ + +/* ===== Inline Function Start for 4.56. URSUB32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief URSUB32 (SIMD 32-bit Unsigned Halving Subtraction) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * URSUB32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit unsigned integer element subtractions simultaneously. The results are halved to + * avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 32-bit unsigned integer elements in Rs2 from the 32-bit + * unsigned integer elements in Rs1. The results are first logically right-shifted by 1 bit and then + * written to Rd. + * + * **Examples**:\n + * ~~~ + * * Ra = 0x7FFFFFFF, Rb = 0x80000000, Rt = 0xFFFFFFFF + * * Ra = 0x80000000, Rb = 0x7FFFFFFF, Rt = 0x00000000 + * * Ra = 0x80000000, Rb = 0x40000000, Rt = 0x20000000 + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = (Rs1.W[x] - Rs2.W[x]) u>> 1; + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_URSUB32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ursub32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.56. URSUB32 ===== */ + +#endif /* __RISCV_XLEN == 64 */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_NUCLEI_Default Nuclei Default SIMD DSP Additional Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic + * \brief (RV32 & RV64)Nuclei Customized DSP Instructions + * \details This is Nuclei customized DSP instructions for both RV32 and RV64 + */ + +/* ===== Inline Function Start for EXPD80 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_Default + * \brief EXPD80 (Expand and Copy Byte 0 to 32bit(when rv32) or 64bit(when rv64)) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * EXPD80 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * When rv32, Copy 8-bit data from 32-bit chunks into 4 bytes in a register. + * When rv64, Copy 8-bit data from 64-bit chunks into 8 bytes in a register. + * + * **Description**:\n + * Moves Rs1.B[0][7:0] to Rd.[0][7:0], Rd.[1][7:0], Rd.[2][7:0], Rd.[3][7:0] + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:0] = CONCAT(Rs1.B[0][7:0], Rs1.B[0][7:0], Rs1.B[0][7:0], Rs1.B[0][7:0]); + * for RV32: x=0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_EXPD80(unsigned long a) +{ + unsigned long result; + __ASM volatile("expd80 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for EXPD80 ===== */ + +/* ===== Inline Function Start for EXPD81 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_Default + * \brief EXPD81 (Expand and Copy Byte 1 to 32bit(rv32) or 64bit(when rv64)) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * EXPD81 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Copy 8-bit data from 32-bit chunks into 4 bytes in a register. + * + * **Description**:\n + * Moves Rs1.B[1][7:0] to Rd.[0][7:0], Rd.[1][7:0], Rd.[2][7:0], Rd.[3][7:0] + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:0] = CONCAT(Rs1.B[1][7:0], Rs1.B[1][7:0], Rs1.B[1][7:0], Rs1.B[1][7:0]); + * for RV32: x=0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_EXPD81(unsigned long a) +{ + unsigned long result; + __ASM volatile("expd81 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for EXPD81 ===== */ + +/* ===== Inline Function Start for EXPD82 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_Default + * \brief EXPD82 (Expand and Copy Byte 2 to 32bit(rv32) or 64bit(when rv64)) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * EXPD82 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Copy 8-bit data from 32-bit chunks into 4 bytes in a register. + * + * **Description**:\n + * Moves Rs1.B[2][7:0] to Rd.[0][7:0], Rd.[1][7:0], Rd.[2][7:0], Rd.[3][7:0] + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:0] = CONCAT(Rs1.B[2][7:0], Rs1.B[2][7:0], Rs1.B[2][7:0], Rs1.B[2][7:0]); + * for RV32: x=0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_EXPD82(unsigned long a) +{ + unsigned long result; + __ASM volatile("expd82 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for EXPD82 ===== */ + +/* ===== Inline Function Start for EXPD83 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_Default + * \brief EXPD83 (Expand and Copy Byte 3 to 32bit(rv32) or 64bit(when rv64)) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * EXPD83 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Copy 8-bit data from 32-bit chunks into 4 bytes in a register. + * + * **Description**:\n + * Moves Rs1.B[3][7:0] to Rd.[0][7:0], Rd.[1][7:0], Rd.[2][7:0], Rd.[3][7:0] + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:0] = CONCAT(Rs1.B[3][7:0], Rs1.B[3][7:0], Rs1.B[3][7:0], Rs1.B[3][7:0]); + * for RV32: x=0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_EXPD83(unsigned long a) +{ + unsigned long result; + __ASM volatile("expd83 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for EXPD83 ===== */ + +#if (__RISCV_XLEN == 64) +/* ===== Inline Function Start for EXPD84 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_Default + * \brief EXPD84 (Expand and Copy Byte 4 to 64bit) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * EXPD84 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Only RV64, copy 8-bit data from 64-bit chunks into 8 bytes in a register. + * + * **Description**:\n + * Moves Rs1.B[4][7:0] to Rd.[0][7:0], Rd.[1][7:0], Rd.[2][7:0], Rd.[3][7:0] + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:0] = CONCAT(Rs1.B[4][7:0], Rs1.B[4][7:0], Rs1.B[4][7:0], Rs1.B[4][7:0]); + * for RV32: x=0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_EXPD84(unsigned long a) +{ + unsigned long result; + __ASM volatile("expd84 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for EXPD84 ===== */ + +/* ===== Inline Function Start for EXPD85 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_Default + * \brief EXPD85 (Expand and Copy Byte 5 to 64bit) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * EXPD85 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Only RV64, copy 8-bit data from 64-bit chunks into 8 bytes in a register. + * + * **Description**:\n + * Moves Rs1.B[5][7:0] to Rd.[0][7:0], Rd.[1][7:0], Rd.[2][7:0], Rd.[3][7:0] + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:0] = CONCAT(Rs1.B[5][7:0], Rs1.B[5][7:0], Rs1.B[5][7:0], Rs1.B[5][7:0]); + * for RV32: x=0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_EXPD85(unsigned long a) +{ + unsigned long result; + __ASM volatile("expd85 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for EXPD85 ===== */ + +/* ===== Inline Function Start for EXPD86 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_Default + * \brief EXPD86 (Expand and Copy Byte 6 to 64bit) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * EXPD86 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Only RV64, copy 8-bit data from 64-bit chunks into 8 bytes in a register. + * + * **Description**:\n + * Moves Rs1.B[6][7:0] to Rd.[0][7:0], Rd.[1][7:0], Rd.[2][7:0], Rd.[3][7:0] + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:0] = CONCAT(Rs1.B[6][7:0], Rs1.B[6][7:0], Rs1.B[6][7:0], Rs1.B[6][7:0]); + * for RV32: x=0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_EXPD86(unsigned long a) +{ + unsigned long result; + __ASM volatile("expd86 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for EXPD86 ===== */ + +/* ===== Inline Function Start for EXPD87 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_Default + * \brief EXPD87 (Expand and Copy Byte 7 to 64bit) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * EXPD87 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Only RV64, copy 8-bit data from 64-bit chunks into 8 bytes in a register. + * + * **Description**:\n + * Moves Rs1.B[7][7:0] to Rd.[0][7:0], Rd.[1][7:0], Rd.[2][7:0], Rd.[3][7:0] + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:0] = CONCAT(Rs1.B[7][7:0], Rs1.B[7][7:0], Rs1.B[7][7:0], Rs1.B[7][7:0]); + * for RV32: x=0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_EXPD87(unsigned long a) +{ + unsigned long result; + __ASM volatile("expd87 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for EXPD87 ===== */ +#endif /* __RISCV_XLEN == 64 */ + +#if (__RISCV_XLEN == 32) || defined(__ONLY_FOR_DOXYGEN_DOCUMENT_GENERATION__) +/* XXXXX Nuclei Extended DSP Instructions for RV32 XXXXX */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N1 Nuclei N1 SIMD DSP Additional Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic + * \brief (RV32 only)Nuclei Customized N1 DSP Instructions + * \details This is Nuclei customized DSP N1 instructions only for RV32 + */ +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 Nuclei N2 SIMD DSP Additional Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic + * \brief (RV32 only)Nuclei Customized N2 DSP Instructions + * \details This is Nuclei customized DSP N2 instructions only for RV32 + */ +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 Nuclei N3 SIMD DSP Additional Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic + * \brief (RV32 only)Nuclei Customized N3 DSP Instructions + * \details This is Nuclei customized DSP N3 instructions only for RV32 + */ + +/* ===== Inline Function Start for DKHM8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N1 + * \brief DKHM8 (64-bit SIMD Signed Saturating Q7 Multiply) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKHM8 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do Q7xQ7 element multiplications simultaneously. The Q14 results are then reduced to Q7 + * numbers again. + * + * **Description**:\n + * For the `DKHM8` instruction, multiply the top 8-bit Q7 content of 16-bit chunks in Rs1 + * with the top 8-bit Q7 content of 16-bit chunks in Rs2. At the same time, multiply the bottom 8-bit Q7 + * content of 16-bit chunks in Rs1 with the bottom 8-bit Q7 content of 16-bit chunks in Rs2. + * + * The Q14 results are then right-shifted 7-bits and saturated into Q7 values. The Q7 results are then + * written into Rd. When both the two Q7 inputs of a multiplication are 0x80, saturation will happen. + * The result will be saturated to 0x7F and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.B[x+1]; op2t = Rs2.B[x+1]; // top + * op1b = Rs1.B[x]; op2b = Rs2.B[x]; // bottom + * for ((aop,bop,res) in [(op1t,op2t,rest), (op1b,op2b,resb)]) { + * if (0x80 != aop | 0x80 != bop) { + * res = (aop s* bop) >> 7; + * } else { + * res= 0x7F; + * OV = 1; + * } + * } + * Rd.H[x/2] = concat(rest, resb); + * for RV32, x=0,2,4,6 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKHM8(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkhm8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKHM8 ===== */ + +/* ===== Inline Function Start for DKHM16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N1 + * \brief DKHM16 (64-bit SIMD Signed Saturating Q15 Multiply) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKHM16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do Q15xQ15 element multiplications simultaneously. The Q30 results are then reduced to + * Q15 numbers again. + * + * **Description**:\n + * For the `DKHM16` instruction, multiply the top 16-bit Q15 content of 32-bit chunks in + * Rs1 with the top 16-bit Q15 content of 32-bit chunks in Rs2. At the same time, multiply the bottom + * 16-bit Q15 content of 32-bit chunks in Rs1 with the bottom 16-bit Q15 content of 32-bit chunks in + * Rs2. + * + * The Q30 results are then right-shifted 15-bits and saturated into Q15 values. The Q15 results are + * then written into Rd. When both the two Q15 inputs of a multiplication are 0x8000, saturation will + * happen. The result will be saturated to 0x7FFF and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.H[x+1]; op2t = Rs2.H[x+1]; // top + * op1b = Rs1.H[x]; op2b = Rs2.H[x]; // bottom + * for ((aop,bop,res) in [(op1t,op2t,rest), (op1b,op2b,resb)]) { + * if (0x8000 != aop | 0x8000 != bop) { + * res = (aop s* bop) >> 15; + * } else { + * res= 0x7FFF; + * OV = 1; + * } + * } + * Rd.W[x/2] = concat(rest, resb); + * for RV32: x=0, 2 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKHM16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkhm16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKHM16 ===== */ + +/* ===== Inline Function Start for DKABS8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N1 + * \brief DKABS8 (64-bit SIMD 8-bit Saturating Absolute) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKABS8 Rd, Rs1 + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Get the absolute value of 8-bit signed integer elements simultaneously. + * + * **Description**:\n + * This instruction calculates the absolute value of 8-bit signed integer elements stored + * in Rs1 and writes the element results to Rd. If the input number is 0x80, this instruction generates + * 0x7f as the output and sets the OV bit to 1. + * + * **Operations**:\n + * ~~~ + * src = Rs1.B[x]; + * if (src == 0x80) { + * src = 0x7f; + * OV = 1; + * } else if (src[7] == 1) + * src = -src; + * } + * Rd.B[x] = src; + * for RV32: x=7...0, + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKABS8(unsigned long long a) +{ + unsigned long long result; + __ASM volatile("dkabs8 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for DKABS8 ===== */ + +/* ===== Inline Function Start for DKABS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N1 + * \brief DKABS16 (64-bit SIMD 16-bit Saturating Absolute) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKABS16 Rd, Rs1 + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Get the absolute value of 16-bit signed integer elements simultaneously. + * + * **Description**:\n + * This instruction calculates the absolute value of 16-bit signed integer elements stored + * in Rs1 and writes the element results to Rd. If the input number is 0x8000, this instruction + * generates 0x7fff as the output and sets the OV bit to 1. + * + * **Operations**:\n + * ~~~ + * src = Rs1.H[x]; + * if (src == 0x8000) { + * src = 0x7fff; + * OV = 1; + * } else if (src[15] == 1) + * src = -src; + * } + * Rd.H[x] = src; + * for RV32: x=3...0, + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKABS16(unsigned long long a) +{ + unsigned long long result; + __ASM volatile("dkabs16 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for DKABS16 ===== */ + +/* ===== Inline Function Start for DKSLRA8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N1 + * \brief DKSLRA8 (64-bit SIMD 8-bit Shift Left Logical with Saturation or Shift Right Arithmetic) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKSLRA8 Rd, Rs1, Rs2 + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 8-bit elements logical left (positive) or arithmetic right (negative) shift operation with + * Q7 saturation for the left shift. + * + * **Description**:\n + * The 8-bit data elements of Rs1 are left-shifted logically or right-shifted arithmetically + * based on the value of Rs2[3:0]. Rs2[3:0] is in the signed range of [-2^3, 2^3-1]. A positive Rs2[3:0] means + * logical left shift and a negative Rs2[3:0] means arithmetic right shift. The shift amount is the + * absolute value of Rs2[3:0]. However, the behavior of `Rs2[3:0]==-2^3 (0x8)` is defined to be + * equivalent to the behavior of `Rs2[3:0]==-(2^3-1) (0x9)`. + * The left-shifted results are saturated to the 8-bit signed integer range of [-2^7, 2^7-1]. + * If any saturation happens, this instruction sets the OV flag. The value of Rs2[31:4] will not affect + * this instruction. + * + * **Operations**:\n + * ~~~ + * if (Rs2[3:0] < 0) { + * sa = -Rs2[3:0]; + * sa = (sa == 8)? 7 : sa; + * Rd.B[x] = SE8(Rs1.B[x][7:sa]); + * } else { + * sa = Rs2[2:0]; + * res[(7+sa):0] = Rs1.B[x] <<(logic) sa; + * if (res > (2^7)-1) { + * res[7:0] = 0x7f; OV = 1; + * } else if (res < -2^7) { + * res[7:0] = 0x80; OV = 1; + * } + * Rd.B[x] = res[7:0]; + * } + * for RV32: x=7...0, + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKSLRA8(unsigned long long a, int b) +{ + unsigned long long result; + __ASM volatile("dkslra8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKSLRA8 ===== */ + +/* ===== Inline Function Start for DKSLRA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N1 + * \brief DKSLRA16 (64-bit SIMD 16-bit Shift Left Logical with Saturation or Shift Right Arithmetic) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKSLRA16 Rd, Rs1, Rs2 + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 16-bit elements logical left (positive) or arithmetic right (negative) shift operation with + * Q15 saturation for the left shift. + * + * **Description**:\n + * The 16-bit data elements of Rs1 are left-shifted logically or right-shifted arithmetically + * based on the value of Rs2[4:0]. Rs2[4:0] is in the signed range of [-2^4, 2^4-1]. A positive Rs2[4:0] means + * logical left shift and a negative Rs2[4:0] means arithmetic right shift. The shift amount is the + * absolute value of Rs2[4:0]. However, the behavior of `Rs2[4:0]==-2^4 (0x10)` is defined to be + * equivalent to the behavior of `Rs2[4:0]==-(2^4-1) (0x11)`. + * The left-shifted results are saturated to the 16-bit signed integer range of [-2^15, 2^15-1]. + * After the shift, saturation, or rounding, the final results are written to + * Rd. If any saturation happens, this instruction sets the OV flag. The value of Rs2[31:5] will not affect + * this instruction. + * + * **Operations**:\n + * ~~~ + * if (Rs2[4:0] < 0) { + * sa = -Rs2[4:0]; + * sa = (sa == 16)? 15 : sa; + * Rd.H[x] = SE16(Rs1.H[x][15:sa]); + * } else { + * sa = Rs2[3:0]; + * res[(15+sa):0] = Rs1.H[x] <<(logic) sa; + * if (res > (2^15)-1) { + * res[15:0] = 0x7fff; OV = 1; + * } else if (res < -2^15) { + * res[15:0] = 0x8000; OV = 1; + * } + * d.H[x] = res[15:0]; + * } + * for RV32: x=3...0, + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKSLRA16(unsigned long long a, int b) +{ + unsigned long long result; + __ASM volatile("dkslra16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKSLRA16 ===== */ + +/* ===== Inline Function Start for DKADD8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N1 + * \brief DKADD8 (64-bit SIMD 8-bit Signed Saturating Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKADD8 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 8-bit signed integer element saturating additions simultaneously. + * + * **Description**:\n + * This instruction adds the 8-bit signed integer elements in Rs1 with the 8-bit signed + * integer elements in Rs2. If any of the results are beyond the Q7 number range (-2^7 <= Q7 <= 2^7-1), they + * are saturated to the range and the OV bit is set to 1. The saturated results are written to Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.B[x] + Rs2.B[x]; + * if (res[x] > 127) { + * res[x] = 127; + * OV = 1; + * } else if (res[x] < -128) { + * res[x] = -128; + * OV = 1; + * } + * Rd.B[x] = res[x]; + * for RV32: x=7...0, + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKADD8(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkadd8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKADD8 ===== */ + +/* ===== Inline Function Start for DKADD16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N1 + * \brief DKADD16 (64-bit SIMD 16-bit Signed Saturating Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKADD16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element saturating additions simultaneously. + * + * **Description**:\n + * This instruction adds the 16-bit signed integer elements in Rs1 with the 16-bit signed + * integer elements in Rs2. If any of the results are beyond the Q15 number range (-2^15 <= Q15 <= 2^15-1), + * they are saturated to the range and the OV bit is set to 1. The saturated results are written to Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.H[x] + Rs2.H[x]; + * if (res[x] > 32767) { + * res[x] = 32767; + * OV = 1; + * } else if (res[x] < -32768) { + * res[x] = -32768; + * OV = 1; + * } + * Rd.H[x] = res[x]; + * for RV32: x=3...0, + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKADD16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkadd16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKADD16 ===== */ + +/* ===== Inline Function Start for DKSUB8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N1 + * \brief DKSUB8 (64-bit SIMD 8-bit Signed Saturating Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKSUB8 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 8-bit signed elements saturating subtractions simultaneously. + * + * **Description**:\n + * This instruction subtracts the 8-bit signed integer elements in Rs2 from the 8-bit + * signed integer elements in Rs1. If any of the results are beyond the Q7 number range (-2^7 <= Q7 <= 2^7-1), + * they are saturated to the range and the OV bit is set to 1. The saturated results are written to Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.B[x] - Rs2.B[x]; + * if (res[x] > (2^7)-1) { + * res[x] = (2^7)-1; + * OV = 1; + * } else if (res[x] < -2^7) { + * res[x] = -2^7; + * OV = 1; + * } + * Rd.B[x] = res[x]; + * for RV32: x=7...0, + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKSUB8(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dksub8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKSUB8 ===== */ + +/* ===== Inline Function Start for DKSUB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N1 + * \brief DKSUB16 (64-bit SIMD 16-bit Signed Saturating Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKSUB16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer elements saturating subtractions simultaneously. + * + * **Description**:\n + * This instruction subtracts the 16-bit signed integer elements in Rs2 from the 16-bit + * signed integer elements in Rs1. If any of the results are beyond the Q15 number range (-2^15 <= Q15 <= + * 2^15-1), they are saturated to the range and the OV bit is set to 1. The saturated results are written to + * Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.H[x] - Rs2.H[x]; + * if (res[x] > (2^15)-1) { + * res[x] = (2^15)-1; + * OV = 1; + * } else if (res[x] < -2^15) { + * res[x] = -2^15; + * OV = 1; + * } + * Rd.H[x] = res[x]; + * for RV32: x=3...0, + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKSUB16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dksub16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKSUB16 ===== */ + +/* ===== Inline Function Start for DKHMX8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKHMX8 (64-bit SIMD Signed Crossed Saturating Q7 Multiply) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKHMX8 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do Q7xQ7 element crossed multiplications simultaneously. The Q15 results are then reduced to Q7 numbers again. + * + * **Description**:\n + * For the `KHM8` instruction, multiply the top 8-bit Q7 content of 16-bit chunks in Rs1 with the + * bottom 8-bit Q7 content of 16-bit chunks in Rs2. At the same time, multiply the bottom 8-bit Q7 + * content of 16-bit chunks in Rs1 with the top 8-bit Q7 content of 16-bit chunks in Rs2. + * + * The Q14 results are then right-shifted 7-bits and saturated into Q7 values. The Q7 results are then + * written into Rd. When both the two Q7 inputs of a multiplication are 0x80, saturation will happen. + * The result will be saturated to 0x7F and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.B[x+1]; op2t = Rs2.B[x]; // top + * op1b = Rs1.B[x]; op2b = Rs2.B[x+1]; // bottom + * for ((aop,bop,res) in [(op1t,op2t,rest), (op1b,op2b,resb)]) { + * if (0x80 != aop | 0x80 != bop) { + * res = (aop s* bop) >> 7; + * } else { + * res= 0x7F; + * OV = 1; + * } + * } + * Rd.H[x/2] = concat(rest, resb); + * for RV32, x=0,2,4,6 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKHMX8(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkhmx8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKHMX8 ===== */ + +/* ===== Inline Function Start for DKHMX16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKHMX16 (64-bit SIMD Signed Crossed Saturating Q15 Multiply) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKHMX16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do Q15xQ15 element crossed multiplications simultaneously. The Q31 results are then reduced to Q15 numbers again. + * + * **Description**:\n + * For the `KHMX16` instruction, multiply the top 16-bit Q15 content of 32-bit chunks in Rs1 with the + * bottom 16-bit Q15 content of 32-bit chunks in Rs2. At the same time, multiply the bottom 16-bit Q15 + * content of 32-bit chunks in Rs1 with the top 16-bit Q15 content of 32-bit chunks in Rs2. + * + * The Q30 results are then right-shifted 15-bits and saturated into Q15 values. The Q15 results are + * then written into Rd. When both the two Q15 inputs of a multiplication are 0x8000, saturation will + * happen. The result will be saturated to 0x7FFF and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.H[x+1]; op2t = Rs2.H[x]; // top + * op1b = Rs1.H[x]; op2b = Rs2.H[x+1]; // bottom + * for ((aop,bop,res) in [(op1t,op2t,rest), (op1b,op2b,resb)]) { + * if (0x8000 != aop | 0x8000 != bop) { + * res = (aop s* bop) >> 15; + * } else { + * res= 0x7FFF; + * OV = 1; + * } + * } + * Rd.W[x/2] = concat(rest, resb); + * for RV32, x=0,2 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKHMX16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkhmx16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKHMX16 ===== */ + +/* ===== Inline Function Start for DSMMUL ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSMMUL (64-bit MSW 32x32 Signed Multiply) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMMUL Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do MSW 32x32 element signed multiplications simultaneously. The results are written into Rd. + * + * **Description**:\n + * This instruction multiplies the 32-bit elements of Rs1 with the 32-bit elements of Rs2 and writes the + * most significant 32-bit multiplication results to the corresponding 32-bit elements of Rd. The 32-bit + * elements of Rs1 and Rs2 are treated as signed integers. The .u form of the instruction rounds up + * the most significant 32-bit of the 64-bit multiplication results by adding a 1 to bit 31 of the results. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * for ((aop,bop,res) in [(op1t,op2t,rest), (op1b,op2b,resb)]) { + * res = (aop s* bop)[63:32]; + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSMMUL(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dsmmul %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMMUL ===== */ + +/* ===== Inline Function Start for DSMMUL.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSMMUL.u (64-bit MSW 32x32 Unsigned Multiply) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMMUL.u Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do MSW 32x32 element unsigned multiplications simultaneously. The results are written into Rd. + * + * **Description**:\n + * This instruction multiplies the 32-bit elements of Rs1 with the 32-bit elements of Rs2 and writes the + * most significant 32-bit multiplication results to the corresponding 32-bit elements of Rd. The 32-bit + * elements of Rs1 and Rs2 are treated as unsigned integers. The .u form of the instruction rounds up + * the most significant 32-bit of the 64-bit multiplication results by adding a 1 to bit 31 of the results. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * for ((aop,bop,res) in [(op1t,op2t,rest), (op1b,op2b,resb)]) { + * res = RUND(aop u* bop)[63:32]; + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSMMUL_U(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dsmmul.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMMUL.u ===== */ + +/* ===== Inline Function Start for DKWMMUL ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKWMMUL (64-bit MSW 32x32 Signed Multiply & Double) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKWMMUL Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do MSW 32x32 element signed multiplications simultaneously and double. The results are written into Rd. + * + * **Description**:\n + * This instruction multiplies the 32-bit elements of Rs1 with the 32-bit elements of Rs2. It then shifts + * the multiplication results one bit to the left and takes the most significant 32-bit results. If the + * shifted result is greater than 2^31-1, it is saturated to 2^31-1 and the OV flag is set to 1. The final element + * result is written to Rd. The 32-bit elements of Rs1 and Rs2 are treated as signed integers. The .u + * form of the instruction additionally rounds up the 64-bit multiplication results by adding a 1 to bit + * 30 before the shift and saturation operations. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * for ((aop,bop,res) in [(op1t,op2t,rest), (op1b,op2b,resb)]) { + * res = sat.q31((aop s* bop) << 1)[63:32]; + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKWMMUL(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkwmmul %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKWMMUL ===== */ + +/* ===== Inline Function Start for DKWMMUL.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKWMMUL.u (64-bit MSW 32x32 Unsigned Multiply & Double) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKWMMUL.u Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do MSW 32x32 element unsigned multiplications simultaneously and double. The results are written into Rd. + * + * **Description**:\n + * This instruction multiplies the 32-bit elements of Rs1 with the 32-bit elements of Rs2. It then shifts + * the multiplication results one bit to the left and takes the most significant 32-bit results. If the + * shifted result is greater than 2^31-1, it is saturated to 2^31-1 and the OV flag is set to 1. The final element + * result is written to Rd. The 32-bit elements of Rs1 and Rs2 are treated as signed integers. The .u + * form of the instruction additionally rounds up the 64-bit multiplication results by adding a 1 to bit + * 30 before the shift and saturation operations. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * for ((aop,bop,res) in [(op1t,op2t,rest), (op1b,op2b,resb)]) { + * res = sat.q31(RUND(aop u* bop) << 1)[63:32]; + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKWMMUL_U(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkwmmul.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKWMMUL.u ===== */ + +/* ===== Inline Function Start for DKABS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKABS32 (64-bit SIMD 32-bit Saturating Absolute) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKABS32 Rd, Rs1 + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Get the absolute value of 32-bit signed integer elements simultaneously. + * + * **Description**:\n + * This instruction calculates the absolute value of 32-bit signed integer elements stored in Rs1 and writes the element + * results to Rd. If the input number is 0x8000_0000, this instruction generates 0x7fff_ffff as the output and sets the OV + * bit to 1. + * + * **Operations**:\n + * ~~~ + * src = Rs1.W[x]; + * if (src == 0x8000_0000) { + * src = 0x7fff_ffff; + * OV = 1; + * } else if (src[31] == 1) + * src = -src; + * } + * Rd.W[x] = src; + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKABS32(unsigned long long a) +{ + unsigned long long result; + __ASM volatile("dkabs32 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for DKABS32 ===== */ + +/* ===== Inline Function Start for DKSLRA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKSLRA32 (64-bit SIMD 32-bit Shift Left Logical with Saturation or Shift Right Arithmetic) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKSLRA32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 31-bit elements logical left (positive) or arithmetic right (negative) shift operation with Q31 saturation for the left shift. + * + * **Description**:\n + * The 31-bit data elements of Rs1 are left-shifted logically or right-shifted arithmetically based on the value of Rs2[5:0]. + * Rs2[5:0] is in the signed range of [-2^5, 2^5-1]. A positive Rs2[5:0] means logical left shift and a negative Rs2[4:0] + * means arithmetic right shift. The shift amount is the absolute value of Rs2[5:0]. However, the behavior of Rs2[5:0]==- + * 2^5 (0x20) is defined to be equivalent to the behavior of Rs2[5:0]==-(2^5-1) (0x21). + * + * **Operations**:\n + * ~~~ + * if (Rs2[5:0] < 0) { + * sa = -Rs2[5:0]; + * sa = (sa == 32)? 31 : sa; + * Rd.W[x] = SE32(Rs1.W[x][31:sa]); + * } else { + * sa = Rs2[4:0]; + * res[(31+sa):0] = Rs1.W[x] <<(logic) sa; + * if (res > (2^31)-1) { + * res[31:0] = 0x7fff_ffff; OV = 1; + * } else if (res < -2^31) { + * res[31:0] = 0x8000_0000; OV = 1; + * } + * Rd.W[x] = res[31:0]; + * } + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKSLRA32(unsigned long long a, int b) +{ + unsigned long long result; + __ASM volatile("dkslra32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKSLRA32 ===== */ + +/* ===== Inline Function Start for DKADD32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKADD32(64-bit SIMD 32-bit Signed Saturating Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKADD32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element saturating additions simultaneously. + * + * **Description**:\n + * This instruction adds the 32-bit signed integer elements in Rs1 with the 32-bit signed integer elements in Rs2. If any + * of the results are beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), they are saturated to the range and the OV + * bit is set to 1. The saturated results are written to Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.W[x] + Rs2.W[x]; + * if (res[x] > 0x7fff_ffff) { + * res[x] = 0x7fff_ffff; + * OV = 1; + * } else if (res[x] < 0x8000_0000) { + * res[x] = 0x8000_0000; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKADD32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkadd32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKADD32 ===== */ + +/* ===== Inline Function Start for DKSUB32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKSUB32 (64-bit SIMD 32-bit Signed Saturating Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKSUB32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element saturating subtractions simultaneously. + * + * **Description**:\n + * This instruction subtracts the 32-bit signed integer elements in Rs2 from the 32-bit signed integer elements in Rs1. If + * any of the results are beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), they are saturated to the range and the + * OV bit is set to 1. The saturated results are written to Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.W[x] - Rs2.W[x]; + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKSUB32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dksub32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKSUB32 ===== */ + +/* ===== Inline Function Start for DRADD16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DRADD16 (64-bit SIMD 16-bit Halving Signed Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DRADD16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element additions simultaneously. The results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction adds the 16-bit signed integer elements in Rs1 with the 16-bit signed integer elements in Rs2. The results + * are first arithmetically right-shifted by 1 bit and then written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = [(Rs1.H[x]) + (Rs2.H[x])] s>> 1; + * x=3...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DRADD16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dradd16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DRADD16 ===== */ + +/* ===== Inline Function Start for DSUB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSUB16 (64-bit SIMD 16-bit Halving Signed Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSUB16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 16-bit integer element subtractions simultaneously. + * + * **Description**:\n + * This instruction adds the 16-bit signed integer elements in Rs1 with the 16-bit signed integer elements in Rs2. The results + * are first arithmetically right-shifted by 1 bit and then written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = [(Rs1.H[x]) - (Rs2.H[x])] ; + * x=3...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSUB16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dsub16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSUB16 ===== */ + +/* ===== Inline Function Start for DRADD32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DRADD32 (64-bit SIMD 32-bit Halving Signed Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DRADD32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element additions simultaneously. The results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction adds the 32-bit signed integer elements in Rs1 with the 32-bit signed integer elements in Rs2. The results + * are first arithmetically right-shifted by 1 bit and then written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = [(Rs1.W[x]) + (Rs2.W[x])] s>> 1; + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DRADD32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dradd32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DRADD32 ===== */ + +/* ===== Inline Function Start for DSUB32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSUB32 (64-bit SIMD 32-bit Halving Signed Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSUB32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 32-bit integer element subtractions simultaneously. + * + * **Description**:\n + * This instruction subtracts the 32-bit signed integer elements in Rs2 from the 32-bit signed integer elements in Rs1 . The + * results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = [(Rs1.E[x]) - (Rs2.E[x])] ; + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSUB32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dsub32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSUB32 ===== */ + +/* ===== Inline Function Start for DMSR16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DMSR16 (Signed Multiply Halfs with Right Shift 16-bit and Cross Multiply Halfs with Right Shift 16-bit) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DMSR16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications and cross multiplications from the 16-bit elements of two registers; and each multiplications performs a right shift operation. + * + * **Description**:\n + * For the `DMSR16` instruction, multiply the top 16-bit Q15 content of 32-bit chunks in Rs1 with the top 16-bit Q15 content + * of 32-bit chunks in Rs2, multiply the bottom 16-bit Q15 content of 32-bit chunks in Rs1 with the bottom 16-bit Q15 content + * of 32-bit chunks in Rs2. + * At the same time, multiply the top 16-bit Q15 content of 32-bit chunks in Rs1 with the bottom16-bit Q15 content of 32-bit + * chunks in Rs2 and multiply the bottom16-bit Q15 content of 32-bit chunks in Rs1 with the top16-bit Q15 content of 32-bit + * chunks in Rs2. The Q31 results are then right-shifted 16-bits and clipped to Q15 values. The Q15 results are then written + * into Rd. + * + * **Operations**:\n + * ~~~ + * Rd.H[0] = (Rs1.H[0] s* Rs2.H[0]) s>> 16 + * Rd.H[1] = (Rs1.H[1] s* Rs2.H[1]) s>> 16 + * Rd.H[2] = (Rs1.H[1] s* Rs2.H[0]) s>> 16 + * Rd.H[3] = (Rs1.H[0] s* Rs2.H[1]) s>> 16 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DMSR16(unsigned long a, unsigned long b) +{ + unsigned long long result; + __ASM volatile("dmsr16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DMSR16 ===== */ + +/* ===== Inline Function Start for DMSR17 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DMSR17 (Signed Multiply Halfs with Right Shift 17-bit and Cross Multiply Halfs with Right Shift 17-bit) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DMSR17 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications and cross multiplications from the 16-bit elements of two registers; + * and each multiplications performs a right shift operation. + * + * **Description**:\n + * For the `DMSR17` instruction, multiply the top 16-bit Q15 content of 32-bit chunks in Rs1 with the top 16-bit Q15 content + * of 32-bit chunks in Rs2, multiply the bottom 16-bit Q15 content of 32-bit chunks in Rs1 with the bottom 16-bit Q15 content + * of 32-bit chunks in Rs2. + * At the same time, multiply the top 16-bit Q15 content of 32-bit chunks in Rs1 with the bottom 16-bit Q15 content of 32-bit + * chunks in Rs2 and multiply the bottom 16-bit Q15 content of 32-bit chunks in Rs1 with the top 16-bit Q15 content of 32-bit + * chunks in Rs2. The Q31 results are then right-shifted 17-bits and clipped to Q15 values. The Q15 results are then written + * into Rd. + * + * **Operations**:\n + * ~~~ + * Rd.H[0] = (Rs1.H[0] s* Rs2.H[0]) s>> 17 + * Rd.H[1] = (Rs1.H[1] s* Rs2.H[1]) s>> 17 + * Rd.H[2] = (Rs1.H[1] s* Rs2.H[0]) s>> 17 + * Rd.H[3] = (Rs1.H[0] s* Rs2.H[1]) s>> 17 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DMSR17(unsigned long a, unsigned long b) +{ + unsigned long long result; + __ASM volatile("dmsr17 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DMSR17 ===== */ + +/* ===== Inline Function Start for DMSR33 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DMSR33 (Signed Multiply with Right Shift 33-bit and Cross Multiply with Right Shift 33-bit) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DMSR33 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do two signed 32-bit multiplications from the 32-bit elements of two registers, and each multiplications performs a right + * shift operation. + * + * **Description**:\n + * For the `DMSR33` instruction, multiply the top 32-bit Q31 content of 64-bit chunks in Rs1 with the top 32-bit Q31 content + * of 64-bit chunks in Rs2. At the same time, multiply the bottom 32-bit Q31 content of 64bit chunks in Rs1 with the bottom + * 32-bit Q31 content of 64-bit. + * The Q64 results are then right-shifted 33-bits and clipped to Q31 values. The Q31 results are then written into Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[0] = (Rs1.W[0] s* Rs2.W[0]) s>> 33 + * Rd.W[1] = (Rs1.W[1] s* Rs2.W[1]) s>> 33 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DMSR33(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dmsr33 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DMSR33 ===== */ + +/* ===== Inline Function Start for DMXSR33 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DMXSR33 (Signed Multiply with Right Shift 33-bit and Cross Multiply with Right Shift 33-bit) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DMXSR33 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do two signed 32-bit cross multiplications from the 32-bit elements of two registers, and each multiplications performs a + * right shift operation. + * + * **Description**:\n + * For the `DMXSR33` instruction, multiply the top 32-bit Q31 content of 64-bit chunks in Rs1 with the bottom 32-bit Q31 + * content of 64-bit chunks in Rs2. At the same time, multiply the bottom 32-bit Q31 content of 64-bit chunks in Rs1 with + * the top 32-bit Q31 content of 64-bit chunks in Rs2. + * The Q63 results are then right-shifted 33-bits and clipped to Q31 values. The Q31 results are then written into Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[0] = (Rs1.W[0] s* Rs2.W[1]) s>> 33 + * Rd.W[1] = (Rs1.W[1] s* Rs2.W[0]) s>> 33 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DMXSR33(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dmxsr33 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DMXSR33 ===== */ + +/* ===== Inline Function Start for DREDAS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DREDAS16 (Reduced Addition and Reduced Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DREDAS16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do halfs reduced subtraction and halfs reduced addition from a register. The result is written to Rd. + * + * **Description**:\n + * For the `DREDAS16` instruction, subtract the top 16-bit Q15 element from the bottom 16-bit Q15 element of the bottom + * 32-bit Q31 content of 64-bit chunks in Rs1. At the same time, add the the top16-bit Q15 element with the bottom16-bit + * Q15 element of the top 32-bit Q31 content of 64-bit chunks in Rs1. The two Q15 results are then written into Rd. + * + * **Operations**:\n + * ~~~ + * Rd.H[0] = Rs1.H[0] - Rs1.H[1] + * Rd.H[1] = Rs1.H[2] + Rs1.H[3] + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_DREDAS16(unsigned long long a) +{ + unsigned long result; + __ASM volatile("dredas16 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for DREDAS16 ===== */ + +/* ===== Inline Function Start for DREDSA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DREDSA16 (Reduced Subtraction and Reduced Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DREDSA16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do halfs reduced subtraction and halfs reduced addition from a register. The result is written to Rd. + * + * **Description**:\n + * For the `DREDSA16` instruction, add the top 16-bit Q15 element from the bottom 16-bit Q15 element of the bottom 32-bit Q31 content of 64-bit chunks in Rs1. At the same time, subtract the the top16-bit Q15 element with the bottom16-bit Q15 element of the top 32-bit Q31 content of 64-bit chunks in Rs1. The two Q15 results are then written into Rd. + * + * **Operations**:\n + * ~~~ + * Rd.H[0] = Rs1.H[0] + Rs1.H[1] + * Rd.H[1] = Rs1.H[2] - Rs1.H[3] + * ~~~ + * + * \param [in] a unsigned long longtype of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_DREDSA16(unsigned long long a) +{ + unsigned long result; + __ASM volatile("dredsa16 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for DREDSA16 ===== */ + +/* ===== Inline Function Start for DKCLIP64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKCLIP64 (64-bit Clipped to 16-bit Saturation Value) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKCLIP64 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 15-bit element arithmetic right shift operations and limit result into 32-bit int,then do saturate operation to 16-bit and + * clip result to 16-bit Q15. + * + * **Description**:\n + * For the `DKCLIP64` instruction, shift the input 15 bits to the right and data convert the result to 32-bit int type, after + * which the input is saturated to limit the data to between 2^15-1 and -2^15. the result is converted to 16-bits q15 type. The + * final results are written to Rd. + * + * **Operations**:\n + * ~~~ + * const int32_t max = (int32_t)((1U << 15U) - 1U); + * const int32_t min = -1 - max ; + * int32_t val = (int32_t)(Rs s>> 15); + * if (val > max) { + * Rd = max; + * } else if (val < min) { + * Rd = min; + * } else { + * Rd = (int16_t)val; + * } + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \return value stored in int16_t type + */ +__STATIC_FORCEINLINE int16_t __RV_DKCLIP64(unsigned long long a) +{ + int16_t result; + __ASM volatile("dkclip64 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for DKCLIP64 ===== */ + +/* ===== Inline Function Start for DKMDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKMDA (Signed Multiply Two Halfs and Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKMDA Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then adds the two 32-bit results together. + * The addition result may be saturated. + * + * **Description**:\n + * This instruction multiplies the bottom 16-bit content of the 32-bit elements of Rs1 with the bottom 16-bit content of the + * 32-bit elements of Rs2 and then adds the result to the result of multiplying the top 16-bit content of the 32-bit elements of + * Rs1 with the top 16-bit content of the 32-bit elements of Rs2. + * The addition result is checked for saturation. If saturation happens, the result is saturated to 2^31-1 The final results are + * written to Rd. The 16-bit contents are treated as signed integers + * + * **Operations**:\n + * ~~~ + * if (Rs1.W[x] != 0x80008000) or (Rs2.W[x] != 0x80008000){ + * Rd.W[x] = (Rs1.W[x].H[1] * Rs2.W[x].H[1]) + (Rs1.W[x].H[0] * Rs2.W[x].H[0]); + * } else { + * Rd.W[x] = 0x7fffffff; + * OV = 1; + * } + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKMDA(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkmda %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKMDA ===== */ + +/* ===== Inline Function Start for DKMXDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKMXDA (Signed Crossed Multiply Two Halfs and Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKMXDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then adds the two 32-bit results together. + * The addition result may be saturated. + * * DKMXDA: top*bottom + top*bottom (per 32-bit element) + * + * **Description**:\n + * This instruction multiplies the bottom 16-bit content of the 32-bit elements of Rs1 with the top 16-bit content of the 32-bit + * elements of Rs2 and then adds the result to the result of multiplying the top 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2. + * The addition result is checked for saturation.If saturation happens, the result is saturated to 2^31-1 The final results are + * written to Rd. The 16-bit contents are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * if (Rs1.W[x] != 0x80008000) or (Rs2.W[x] != 0x80008000){ + * Rd.W[x] = (Rs1.W[x].H[1] * Rs2.W[x].H[0]) + (Rs1.W[x].H[0] * Rs2.W[x].H[1]); + * } else { + * Rd.W[x] = 0x7fffffff; + * OV = 1; + * } + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKMXDA(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkmxda %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKMXDA ===== */ + +/* ===== Inline Function Start for DSMDRS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSMDRS (Signed Multiply Two Halfs and Reverse Subtract) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMDRS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then perform a subtraction operation + * between the two 32-bit results. + * * DSMDRS: bottom*bottom - top*top (per 32-bit element) + * + * **Description**:\n + * This instruction multiplies the top 16-bit content of the 32-bit elements of Rs1 with the top 16-bit content of the 32-bit + * elements of Rs2 and then subtracts the result from the result of multiplying the bottom 16-bit content of the 32-bit elements + * of Rs1 with the bottom 16-bit content of the 32-bit elements of Rs2. + * The subtraction result is written to the corresponding 32-bit element of Rd (The 16-bit contents of multiplication are + * treated as signed integers). + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = (Rs1.W[x].H[0] * Rs2.W[x].H[0]) - (Rs1.W[x].H[1] * Rs2.W[x].H[1]); x = 1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSMDRS(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dsmdrs %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMDRS ===== */ + +/* ===== Inline Function Start for DSMXDS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSMXDS (Signed Crossed Multiply Two Halfs and Subtract) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMXDS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then perform a subtraction operation + * between the two 32-bit results. + * * DSMXDS: top*bottom - bottom*top (per 32-bit element) + * + * **Description**:\n + * This instruction multiplies the bottom 16-bit content of the 32-bit elements of Rs1 with the top 16-bit content of the 32-bit + * elements of Rs2 and then subtracts the result from the result of multiplying the top 16-bit content of the 32-bit elements + * of Rs1 with the bottom 16-bit content of the 32-bit elements of Rs2. + * The subtraction result is written to the corresponding 32-bit element of Rd. The 16-bit contents of multiplication are + * treated as signed integers. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = (Rs1.W[x].H[1] * Rs2.W[x].H[0]) - (Rs1.W[x].H[0] * Rs2.W[x].H[1]); x = 1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSMXDS(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dsmxds %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMXDS ===== */ + +/* ===== Inline Function Start for DSMBB32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSMBB32 (Signed Multiply Bottom Word & Bottom Word) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMBB32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element of a register with the signed 32-bit element of another register and write the 64-bit result to a third register. + * * DSMBB32: bottom*bottom + * + * **Description**:\n + * This instruction multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit element of Rs2. The 64-bit multiplication result is written to Rd. + * The 32-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * res = (Rs1.W[0] * Rs2.W[0]); + * Rd = res; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMBB32(unsigned long long a, unsigned long long b) +{ + long long result; + __ASM volatile("dsmbb32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMBB32 ===== */ + +/* ===== Inline Function Start for DSMBB32.sra14 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSMBB32.sra14 (Signed Crossed Multiply Two Halfs and Subtract with Right Shift 14) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMBB32.sra14 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element of a register with the signed 32-bit element of another register, then right shift 14- + * bit,finally write the 64-bit result to a third register. + * * DSMBB32.sra14: bottom*bottom s>> 14 + * + * **Description**:\n + * This instruction multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit element of Rs2. The 64-bit multiplication result is written to Rd after right shift 14-bit. + * The 32-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * res = (Rs1.W[0] * Rs2.W[0]) s>> 14; + * Rd = res; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMBB32_SRA14(unsigned long long a, unsigned long long b) +{ + long long result; + __ASM volatile("dsmbb32.sra14 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMBB32.sra14 ===== */ + +/* ===== Inline Function Start for DSMBB32.sra32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSMBB32.sra32 (Signed Crossed Multiply Two Halfs and Subtract with Right Shift 32) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMBB32.sra32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element of a register with the signed 32-bit element of another register, then right shift 32- + * bit,finally write the 64-bit result to a third register. + * * DSMBB32.sra32: bottom*bottom s >> 32 + * + * **Description**:\n + * This instruction multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit element of Rs2. + * The 64-bit multiplication result is written to Rd after right shift 32-bit. The 32-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * res = (Rs1.W[0] * Rs2.W[0]) s>> 32; + * Rd = res; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMBB32_SRA32(unsigned long long a, unsigned long long b) +{ + long long result; + __ASM volatile("dsmbb32.sra32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMBB32.sra32 ===== */ + +/* ===== Inline Function Start for DSMBT32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief SMBT32 (Signed Multiply Bottom Word & Top Word) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMBT32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element of a register with the signed 32-bit element of another register and write the 64-bit + * result to a third register. + * * DSMBT32: bottom*top + * + * **Description**:\n + * This instruction multiplies the bottom 32-bit element of Rs1 with the top 32-bit element of Rs2. The 64-bit multiplication + * result is written to Rd. The 32-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * res = (Rs1.W[0] * Rs2.W[0]); + * Rd = res; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMBT32(unsigned long long a, unsigned long long b) +{ + long long result; + __ASM volatile("dsmbt32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMBT32 ===== */ + +/* ===== Inline Function Start for DSMBT32.sra14 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSMBT32.sra14 (Signed Multiply Bottom Word & Top Word with Right Shift 14) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMBT32.sra14 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element of a register with the signed 32-bit element of another register, then right shift 14- + * bit,finally write the 64-bit result to a third register. + * * DSMBT32.sra14: bottom*bottom s>> 14 + * + * **Description**:\n + * This instruction multiplies the bottom 32-bit element of Rs1 with the top 32-bit element of Rs2. The 64-bit multiplication + * result is written to Rd after right shift 14-bit. The 32-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * res = (Rs1.W[0] * Rs2.W[0]) s>> 14; + * Rd = res; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMBT32_SRA14(unsigned long long a, unsigned long long b) +{ + long long result; + __ASM volatile("dsmbt32.sra14 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMBT32.sra14 ===== */ + +/* ===== Inline Function Start for DSMBT32.sra32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSMBT32.sra32 (Signed Crossed Multiply Two Halfs and Subtract with Right Shift 32) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMBT32.sra32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element of a register with the signed 32-bit element of another register, then right shift 32- + * bit,finally write the 64-bit result to a third register. + * * DSMBT32.sra32: bottom*bottom s>> 32 + * + * **Description**:\n + * This instruction multiplies the bottom 32-bit element of Rs1 with the top 32-bit element of Rs2. The 64-bit multiplication + * result is written to Rd after right shift 32-bit. The 32-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * res = (Rs1.W[0] * Rs2.W[0]) s>> 14; + * Rd = res; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMBT32_SRA32(unsigned long long a, unsigned long long b) +{ + long long result; + __ASM volatile("dsmbt32.sra32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMBT32.sra32 ===== */ + +/* ===== Inline Function Start for DSMTT32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSMTT32 (Signed Multiply Top Word & Top Word) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMTT32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element of a register with the signed 32-bit element of another register and write the 64-bit + * result to a third register. + * * DSMTT32: top*top + * + * **Description**:\n + * This instruction multiplies the top 32-bit element of Rs1 with the top 32-bit element of Rs2. The 64-bit multiplication + * result is written to Rd. The 32-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * res = Rs1.W[1] * Rs2.W[1]; + * Rd = res; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMTT32(unsigned long long a, unsigned long long b) +{ + long long result; + __ASM volatile("dsmtt32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMTT32 ===== */ + +/* ===== Inline Function Start for DSMTT32.sra14 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSMTT32.sra14 (Signed Multiply Top Word & Top Word with Right Shift 14-bit) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMTT32.sra14 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element of a register with the signed 32-bit element of another register,then right shift 14-bit, + * finally write the 64-bit result to a third register. + * * DSMTT32.sra14: top*top s>> 14 + * + * **Description**:\n + * This instruction multiplies the top 32-bit element of Rs1 with the top 32-bit element of Rs2. The 64-bit multiplication + * result is written to Rd after right shift 14-bit. The 32-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * res = Rs1.W[1] * Rs2.W[1] >> 14; + * Rd = res; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMTT32_SRA14(unsigned long long a, unsigned long long b) +{ + long long result; + __ASM volatile("dsmtt32.sra14 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMTT32.sra14 ===== */ + +/* ===== Inline Function Start for DSMTT32.sra32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSMTT32.sra32 (Signed Multiply Top Word & Top Word with Right Shift 32-bit) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMTT32.sra32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element of a register with the signed 32-bit element of another register,then right shift 32-bit, + * finally write the 64-bit result to a third register. + * * DSMTT32.sra32: top*top s>> 32 + * + * **Description**:\n + * This instruction multiplies the top 32-bit element of Rs1 with the top 32-bit element of Rs2. The 64-bit multiplication + * result is written to Rd after right shift 32-bit. The 32-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * res = Rs1.W[1] * Rs2.W[1] >> 32; + * Rd = res; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMTT32_SRA32(unsigned long long a, unsigned long long b) +{ + long long result; + __ASM volatile("dsmtt32.sra32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMTT32.sra32 ===== */ + +/* ===== Inline Function Start for DPKBB32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DPKBB32 (Pack Two 32-bit Data from Both Bottom Half) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DPKBB32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Pack 32-bit data from 64-bit chunks in two registers. + * * DPKBB32: bottom.bottom + * + * **Description**:\n + * This instruction moves Rs1.W[0] to Rd.W[1] and moves Rs2.W[0] to Rd.W[0]. + * + * **Operations**:\n + * ~~~ + * Rd = CONCAT(Rs1.W[0], Rs2.W[0]); + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DPKBB32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dpkbb32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DPKBB32 ===== */ + +/* ===== Inline Function Start for DPKBT32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DPKBT32 (Pack Two 32-bit Data from Bottom and Top Half) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DPKBT32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Pack 32-bit data from 64-bit chunks in two registers. + * * DPKBT32: bottom.top + * + * **Description**:\n + * This instruction moves Rs1.W[0] to Rd.W[1] and moves Rs2.W[1] to Rd.W[0]. + * + * **Operations**:\n + * ~~~ + * Rd = CONCAT(Rs1.W[0], Rs2.W[1]); + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DPKBT32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dpkbt32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DPKBT32 ===== */ + +/* ===== Inline Function Start for DPKTT32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DPKTT32 (Pack Two 32-bit Data from Both Top Half) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DPKTT32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Pack 32-bit data from 64-bit chunks in two registers. + * * DPKTT32: top.top + * + * **Description**:\n + * This instruction moves Rs1.W[1] to Rd.W[0] and moves Rs2.W[1] to Rd.W[0]. + * + * **Operations**:\n + * ~~~ + * Rd = CONCAT(Rs1.W[1], Rs2.W[1]); + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DPKTT32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dpktt32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DPKTT32 ===== */ + +/* ===== Inline Function Start for DPKTB32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DPKTB32 (Pack Two 32-bit Data from Top and Bottom Half) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DPKTB32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Pack 32-bit data from 64-bit chunks in two registers. + * * DPKTB32: top.bottom + * + * **Description**:\n + * This instruction moves Rs1.W[1] to Rd.W[1] and moves Rs2.W[0] to Rd.W[0]. + * + * **Operations**:\n + * ~~~ + * Rd = CONCAT(Rs1.W[1], Rs2.W[0]); + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DPKTB32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dpktb32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DPKTB32 ===== */ + +/* ===== Inline Function Start for DPKTB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DPKTB16 (Pack Two 32-bit Data from Top and Bottom Half) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DPKTB16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Pack 16-bit data from 32-bit chunks in two registers. + * * DPKTB16: top.bottom + * + * **Description**:\n + * This instruction moves Rs1.W[x] [31:16] to Rd.W[x] [31:16] and moves Rs2.W[x] [15:0] to Rd.W[x] [15:0]. + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][31:16], Rs2.W[x][15:0]); + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DPKTB16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dpktb16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DPKTB16 ===== */ + +/* ===== Inline Function Start for DPKBB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DPKBB16 (Pack Two 16-bit Data from Both Bottom Half) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DPKBB16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Pack 16-bit data from 32-bit chunks in two registers. + * * PKBB16: bottom.bottom + * + * **Description**:\n + * This instruction moves Rs1.W[x][15:0] to Rd.W[x][31:16] and moves Rs2.W[x] [15:0] to Rd.W[x] [15:0]. + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][15:0], Rs2.W[x][15:0]); + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DPKBB16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dpkbb16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DPKBB16 ===== */ + +/* ===== Inline Function Start for DPKBT16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DPKBT16 (Pack Two 16-bit Data from Bottom and Top Half) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DPKBT16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Pack 16-bit data from 32-bit chunks in two registers. + * * PKBT16: bottom.top + * + * **Description**:\n + * This instruction moves Rs1.W[x] [15:0] to Rd.W[x] [31:16] and moves Rs2.W[x] [31:16] to Rd.W[x] [15:0]. + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][15:0], Rs2.W[x][31:16]); + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DPKBT16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dpkbt16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DPKBT16 ===== */ + +/* ===== Inline Function Start for DPKTT16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DPKTT16 (Pack Two 16-bit Data from Both Top Half) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DPKTT16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Pack 16-bit data from 32-bit chunks in two registers. + * * PKTT16 top.top + * + * **Description**:\n + * This instruction moves Rs1.W[x] [31:16] to Rd.W[x] [31:16] and moves Rs2.W[x] [31:16] to Rd.W[x] [15:0]. + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][31:16], Rs2.W[x][31:16]); + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DPKTT16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dpktt16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DPKTT16 ===== */ + +/* ===== Inline Function Start for DSRA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSRA16 (SIMD 16-bit Shift Right Arithmetic) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSRA16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 16-bit element arithmetic right shift operations simultaneously. The shift amount is a variable from a GPR. + * + * **Description**:\n + * The 16-bit data elements in Rs1 are right-shifted arithmetically, that is, the shifted out bits are filled with the sign-bit of + * the data elements. The shift amount is specified by the low-order 4-bits of the value in the Rs2 register. And the results + * are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[3:0]; + * if (sa != 0) + * { + * Rd.H[x] = SE16(Rs1.H[x][15:sa]); + * } else { + * Rd = Rs1; + * } + * x=3...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSRA16(unsigned long long a, unsigned long b) +{ + unsigned long long result; + __ASM volatile("dsra16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSRA16 ===== */ + +/* ===== Inline Function Start for DADD16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DADD16 (16-bit Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DADD16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 16-bit integer element additions simultaneously. + * + * **Description**:\n + * This instruction adds the 16-bit unsigned integer elements in Rs1 with the 16-bit unsigned integer elements in Rs2. And + * the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = Rs1.H[x] + Rs2.H[x]; + * x=3...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DADD16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dadd16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DADD16 ===== */ + +/* ===== Inline Function Start for DADD32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DADD32 (32-bit Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DADD32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 32-bit integer element additions simultaneously. + * + * **Description**:\n + * This instruction adds the 32-bit integer elements in Rs1 with the 32-bit integer elements in Rs2, and then writes the 32-bit + * element results to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = Rs1.W[x] + Rs2.W[x]; + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DADD32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dadd32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DADD32 ===== */ + +/* ===== Inline Function Start for DSMBB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSMBB16 (Signed Multiply Bottom Half & Bottom Half) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMBB16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 16-bit content of the 32-bit elements of a register with the signed 16-bit content of the 32-bit elements + * of another register and write the result to a third register. + * * DSMBB16: W[x].bottom*W[x].bottom + * + * **Description**:\n + * For the `DSMBB16` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 with the bottom + * 16-bit content of the 32-bit elements of Rs2. + * The multiplication results are written to Rd. The 16-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = Rs1.W[x].H[0] * Rs2.W[x].H[0]; + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSMBB16(unsigned long long a, unsigned long long b) /* pass */ +{ + unsigned long long result; + __ASM volatile("dsmbb16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMBB16 ===== */ + +/* ===== Inline Function Start for DSMBT16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSMBT16 (Signed Multiply Bottom Half & Top Half) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMBT16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 16-bit content of the 32-bit elements of a register with the signed 16-bit content of the 32-bit + * elements of another register and write the result to a third register. + * * DSMBT16: W[x].bottom *W[x].top + * + * **Description**:\n + * For the `DSMBT16` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 with the top 16-bit + * content of the 32-bit elements of Rs2. + * The multiplication results are written to Rd. The 16-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = Rs1.W[x].H[0] * Rs2.W[x].H[1]; + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSMBT16(unsigned long long a, unsigned long long b) /* pass */ +{ + unsigned long long result; + __ASM volatile("dsmbt16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMBT16 ===== */ + +/* ===== Inline Function Start for DSMTT16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSMTT16 (Signed Multiply Top Half & Top Half) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMTT16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 16-bit content of the 32-bit elements of a register with the signed 16-bit content of the 32-bit + * elements of another register and write the result to a third register. + * * DSMTT16: W[x].top * W[x].top + * + * **Description**:\n + * For the `DSMTT16` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 with the top 16-bit + * content of the 32-bit elements of Rs2. + * The multiplication results are written to Rd. The 16-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = Rs1.W[x].H[1] * Rs2.W[x].H[1]; + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSMTT16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dsmtt16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMTT16 ===== */ + +/* ===== Inline Function Start for DRCRSA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DRCRSA16 (16-bit Signed Halving Cross Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DRCRSA16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element subtraction and 16-bit signed integer element addition in a 32-bit chunk simultaneously. + * Operands are from crossed positions in 32-bit chunks. The results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 16-bit signed integer in [31:16] of 32-bit chunks in Rs1 with the 16-bit signed integer in + * [15:0] of 32-bit chunks in Rs2, and adds the 16-bit signed integer in [31:16] of 32-bit chunks in Rs2 from the 16-bit signed + * integer in [15:0] of 32-bit chunks in Rs1. The element results are first logically right-shifted by 1 bit and then written to + * [31:16] of 32- bit chunks in Rd and [15:0] of 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:16] = (Rs1.W[x][31:16] - Rs2.W[x][15:0]) s>> 1; + * Rd.W[x][15:0] = (Rs1.W[x][15:0] + Rs2.W[x][31:16]) s>> 1; + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DRCRSA16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("drcrsa16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DRCRSA16 ===== */ + +/* ===== Inline Function Start for DRCRSA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DRCRSA32 (32-bit Signed Halving Cross Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DRCRSA32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element subtraction and 32-bit signed integer element addition in a 64-bit chunk simultaneously. + * Operands are from crossed 32-bit elements. The results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 32-bit signed integer element in [63:32] of Rs1 with the 32-bit signed integer element in + * [31:0] of Rs2, and adds the 32-bit signed integer element in [63:32] of Rs2 from the 32-bit signed integer element in [31:0] + * of Rs1. The element results are first arithmetically right-shifted by 1 bit and then written to [63:32] of Rd for addition and + * [31:0] of Rd for subtraction. + * + * **Operations**:\n + * ~~~ + * Rd.W[1] = (Rs1.W[1] - Rs2.W[0]) s>> 1; + * Rd.W[0] = (Rs1.W[0] + Rs2.W[1]) s>> 1; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DRCRSA32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("drcrsa32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DRCRSA32 ===== */ + +/* ===== Inline Function Start for DRCRAS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DRCRAS16 (16-bit Signed Halving Cross Addition & Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DRCRAS16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element subtraction and 16-bit signed integer element addition in a 32-bit chunk simultaneously. + * Operands are from crossed positions in 32-bit chunks. The results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction adds the 16-bit unsigned integer in [31:16] of 32-bit chunks in Rs1 with the 16-bit unsigned integer in + * [15:0] of 32-bit chunks in Rs2, and subtracts the 16-bit unsigned integer in [31:16] of 32-bit chunks in Rs2 from the 16-bit + * unsigned integer in [15:0] of 32-bit chunks in Rs1. The element results are first logically right-shifted by 1 bit and then + * written to [31:16] of 32-bit chunks in Rd and [15:0] of 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:16] = (Rs1.W[x][31:16] + Rs2.W[x][15:0]) s>> 1; + * Rd.W[x][15:0] = (Rs1.W[x][15:0] - Rs2.W[x][31:16]) s>> 1; + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DRCRAS16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("drcras16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DRCRAS16 ===== */ + +/* ===== Inline Function Start for DRCRAS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DRCRAS32 (32-bit Signed Cross Addition & Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DRCRAS32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element addition and 32-bit signed integer element subtraction in a 64-bit chunk simultaneously. + * Operands are from crossed 32-bit elements. The results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction adds the 32-bit signed integer element in [63:32] of Rs1 with the 32-bit signed integer element in [31:0] + * of Rs2, and subtracts the 32-bit signed integer element in [63:32] of Rs2 from the 32-bit signed integer element in [31:0] + * of Rs1. The element results are first arithmetically right-shifted by 1 bit and then written to [63:32] of Rd for addition + * and [31:0] of Rd for subtraction. + * + * **Operations**:\n + * ~~~ + * Rd.W[1] = (Rs1.W[1] + Rs2.W[0]) s>> 1; + * Rd.W[0] = (Rs1.W[0] - Rs2.W[1]) s>> 1; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DRCRAS32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("DRCRAS32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DRCRAS32 ===== */ + +/* ===== Inline Function Start for DKCRAS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKCRAS16 (16-bit Signed Saturating Cross Addition & Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKCRAS16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element saturating addition and 16-bit signed integer element saturating subtraction in a 32-bit + * chunk simultaneously. Operands are from crossed positions in 32-bit chunks. + * + * **Description**:\n + * This instruction adds the 16-bit signed integer element in [31:16] of 32-bit chunks in Rs1 with the 16-bit signed integer + * element in [15:0] of 32-bit chunks in Rs2; at the same time, it subtracts the 16-bit signed integer element in [31:16] of + * 32-bit chunks in Rs2 from the 16-bit signed integer element in [15:0] of 32-bit chunks in Rs1. + * If any of the results are beyond the Q15 number range (-2^15 <= Q15 <= 2^15-1), they are saturated to the range and the OV + * bit is set to 1. The saturated results are written to [31:16] of 32-bit chunks in Rd for subtraction and [15:0] of 32-bit chunks + * in Rd for addition. + * + * **Operations**:\n + * ~~~ + * res1 = Rs1.W[x][31:16] - Rs2.W[x][15:0]; + * res2 = Rs1.W[x][15:0] + Rs2.W[x][31:16]; + * for (res in [res1, res2]) { + * if (res > (2^15)-1) { + * res = (2^15)-1; + * OV = 1; + * } else if (res < -2^15) { + * res = -2^15; + * OV = 1; + * } + * } + * Rd.W[x][31:16] = res1; + * Rd.W[x][15:0] = res2; + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKCRAS16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkcras16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKCRAS16 ===== */ + +/* ===== Inline Function Start for DKCRSA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKCRSA16 (16-bit Signed Saturating Cross Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKCRSA16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element saturating subtraction and 16-bit signed integer element saturating addition in a 32-bit + * chunk simultaneously. Operands are from crossed positions in 32-bit chunks. + * + * **Description**:\n + * This instruction subtracts the 16-bit signed integer element in [15:0] of 32-bit chunks in Rs2 from the 16-bit signed integer + * element in [31:16] of 32-bit chunks in Rs1; at the same time, it adds the 16-bit signed integer element in [31:16] of 32-bit + * chunks in Rs2 with the 16-bit signed integer element in [15:0] of 32-bit chunks in Rs1. + * If any of the results are beyond the Q15 number range (-2^15 <= Q15 <= 2^15-1), they are saturated to the range and the OV + * bit is set to 1. The saturated results are written to [31:16] of 32-bit chunks in Rd for addition and [15:0] of 32-bit chunks + * in Rd for subtraction. + * + * **Operations**:\n + * ~~~ + * res1 = Rs1.W[x][31:16] + Rs2.W[x][15:0]; + * res2 = Rs1.W[x][15:0] - Rs2.W[x][31:16]; + * for (res in [res1, res2]) { + * if (res > (2^15)-1) { + * res = (2^15)-1; + * OV = 1; + * } else if (res < -2^15) { + * res = -2^15; + * OV = 1; + * } + * } + * Rd.W[x][31:16] = res1; + * Rd.W[x][15:0] = res2; + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKCRSA16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkcrsa16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKCRSA16 ===== */ + +/* ===== Inline Function Start for DRSUB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DRSUB16 (16-bit Signed Halving Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DRSUB16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element subtractions simultaneously. The results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 16-bit signed integer elements in Rs2 from the 16-bit signed integer elements in Rs1. The + * results are first arithmetically right-shifted by 1 bit and then written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = (Rs1.H[x] - Rs2.H[x]) s>> 1; + * x=3...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DRSUB16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("drsub16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DRSUB16 ===== */ + +/* ===== Inline Function Start for DSTSA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSTSA32 (32-bit Straight Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSTSA32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 32-bit integer element subtraction and 32-bit integer element addition in a 64-bit chunk simultaneously. Operands are + * from corresponding 32-bit elements. + * + * **Description**:\n + * This instruction subtracts the 32-bit integer element in [63:32] of Rs2 from the 32-bit integer element in [63:32] of Rs1, + * and writes the result to [63:32] of Rd; at the same time, it adds the 32-bit integer element in [31:0] of Rs1 with the 32-bit + * integer element in [31:0] of Rs2, and writes the result to [31:0] of Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[1] = Rs1.W[1] - Rs2.W[1]; + * Rd.W[0] = Rs1.W[0] + Rs2.W[0]; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSTSA32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dstsa32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSTSA32 ===== */ + +/* ===== Inline Function Start for DSTAS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSTAS32 (SIMD 32-bit Straight Addition & Subtractionn) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSTAS32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 32-bit integer element addition and 32-bit integer element subtraction in a 64-bit chunk simultaneously. Operands are + * from corresponding 32-bit elements. + * + * **Description**:\n + * This instruction adds the 32-bit integer element in [63:32] of Rs1 with the 32-bit integer element in [63:32] of Rs2, + * and writes the result to [63:32] of Rd; at the same time, it subtracts the 32-bit integer element in [31:0] of Rs2 + * from the 32-bit integer element in [31:0] of Rs1, and writes the result to [31:0] of Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[1] = Rs1.W[1] + Rs2.W[1]; + * Rd.W[0] = Rs1.W[0] - Rs2.W[0]; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSTAS32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("DSTAS32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSTAS32 ===== */ + +/* ===== Inline Function Start for DKCRSA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKCRSA32 (32-bit Signed Saturating Cross Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKCRSA32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element saturating subtraction and 32-bit signed integer element saturating addition in a 64-bit + * chunk simultaneously. Operands are from crossed 32-bit elements. + * + * **Description**:\n + * This instruction subtracts the 32-bit integer element in [31:0] of Rs2 from the 32-bit integer element in [63:32] of Rs1; at + * the same time, it adds the 32-bit integer element in [31:0] of Rs1 with the 32-bit integer element in [63:32] of Rs2. If any + * of the results are beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), they are saturated to the range and the OV bit is + * set to 1. The saturated results are written to [63:32] of Rd for subtraction and [31:0] of Rd for addition. + * + * **Operations**:\n + * ~~~ + * res[1] = Rs1.W[1] - Rs2.W[0]; + * res[0] = Rs1.W[0] + Rs2.W[1]; + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[1] = res[1]; + * Rd.W[0] = res[0]; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKCRSA32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkcrsa32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKCRSA32 ===== */ + +/* ===== Inline Function Start for DKCRAS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKCRAS32 (32-bit Signed Saturating Cross Addition & Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKCRAS32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element saturating subtraction and 32-bit signed integer element saturating addition in a 64-bit + * chunk simultaneously. Operands are from crossed 32-bit elements. + * + * **Description**:\n + * This instruction adds the 32-bit integer element in [31:0] of Rs2 from the 32-bit integer element in [63:32] of Rs1; at the + * same time, it subtracts the 32-bit integer element in [31:0] of Rs1 with the 32-bit integer element in [63:32] of Rs2. If any + * of the results are beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), they are saturated to the range and the OV bit is + * set to 1. The saturated results are written to [63:32] of Rd for subtraction and [31:0] of Rd for addition. + * + * **Operations**:\n + * ~~~ + * res[1] = Rs1.W[1] + Rs2.W[0]; + * res[0] = Rs1.W[0] - Rs2.W[1]; + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[1] = res[1]; + * Rd.W[0] = res[0]; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKCRAS32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkcras32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKCRAS32 ===== */ + +/* ===== Inline Function Start for DCRSA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DCRSA32 (32-bit Cross Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DCRSA32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 32-bit integer element subtraction and 32-bit integer element addition in a 64-bit chunk simultaneously. Operands are + * from crossed 32-bit elements. + * + * **Description**:\n + * This instruction adds the 32-bit integer element in [63:32] of Rs1 with the 32-bit integer element in [31:0] of Rs2, and + * writes the result to [63:32] of Rd; at the same time, it subtracts the 32-bit integer element in [63:32] of Rs2 from the 32-bit + * integer element in [31:0] of Rs1, and writes the result to [31:0] of Rd. + * + * **Operations**:\n + * ~~~ + * res[1] = Rs1.W[1] - Rs2.W[0]; + * res[0] = Rs1.W[0] + Rs2.W[1]; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DCRSA32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dcrsa32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DCRSA32 ===== */ + +/* ===== Inline Function Start for DCRAS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DCRAS32 (32-bit Cross Addition & Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DCRAS32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 32-bit integer element addition and 32-bit integer element subtraction in a 64-bit chunk simultaneously. Operands are + * from crossed 32-bit elements. + * + * **Description**:\n + * This instruction subtracts the 32-bit integer element in [63:32] of Rs1 with the 32-bit integer element in [31:0] of Rs2, and + * writes the result to [63:32] of Rd; at the same time, it adds the 32-bit integer element in [63:32] of Rs2 from the 32-bit + * integer element in [31:0] of Rs1, and writes the result to [31:0] of Rd. + * + * **Operations**:\n + * ~~~ + * res[1] = Rs1.W[1] - Rs2.W[0]; + * res[0] = Rs1.W[0] + Rs2.W[1]; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DCRAS32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dcras32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DCRAS32 ===== */ + +/* ===== Inline Function Start for DKSTSA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKSTSA16 (16-bit Signed Saturating Straight Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKSTSA16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element saturating subtraction and 16-bit signed integer element saturating addition in a 32-bit + * chunk simultaneously. Operands are from corresponding positions in 32-bit chunks. + * + * **Description**:\n + * This instruction subtracts the 16-bit signed integer element in [31:16] of 32-bit chunks in Rs2 from the 16-bit signed integer + * element in [31:16] of 32-bit chunks in Rs1; at the same time, it adds the 16-bit signed integer element in [15:0] of 32-bit + * chunks in Rs2 with the 16-bit signed integer element in [15:0] of 32-bit chunks in Rs1. + * If any of the results are beyond the Q15 number range (-2^15 <= Q15 <= 2^15-1), they are saturated to the range and the OV + * bit is set to 1. The saturated results are written to [31:16] of 32-bit chunks in Rd for subtraction and [15:0] of 32-bit chunks + * in Rd for addition. + * + * **Operations**:\n + * ~~~ + * res1 = Rs1.W[x][31:16] - Rs2.W[x][31:16]; + * res2 = Rs1.W[x][15:0] + Rs2.W[x][15:0]; + * for (res in [res1, res2]) { + * if (res > (2^15)-1) { + * res = (2^15)-1; + * OV = 1; + * } else if (res < -2^15) { + * res = -2^15; + * OV = 1; + * } + * } + * Rd.W[x][31:16] = res1; + * Rd.W[x][15:0] = res2; + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKSTSA16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkstsa16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKSTSA16 ===== */ + +/* ===== Inline Function Start for DKSTAS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKSTAS16 (16-bit Signed Saturating Straight Addition & Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKSTAS16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element saturating addition and 16-bit signed integer element saturating subtraction in a 32-bit + * chunk simultaneously. Operands are from corresponding positions in 32-bit chunks. + * + * **Description**:\n + * This instruction adds the 16-bit signed integer element in [31:16] of 32-bit chunks in Rs1 with the 16-bit signed integer + * element in [31:16] of 32-bit chunks in Rs2; at the same time, it subtracts the 16-bit signed integer element in [15:0] of + * 32-bit chunks in Rs2 from the 16-bit signed integer element in [15:0] of 32-bit chunks in Rs1. + * If any of the results are beyond the Q15 number range (-2^15 <= Q15 <= 2^15-1), they are saturated to the range and the OV + * bit is set to 1. The saturated results are written to [31:16] of 32-bit chunks in Rd for subtraction and [15:0] of 32-bit chunks + * in Rd for addition. + * + * **Operations**:\n + * ~~~ + * res1 = Rs1.W[x][31:16] + Rs2.W[x][31:16]; + * res2 = Rs1.W[x][15:0] - Rs2.W[x][15:0]; + * for (res in [res1, res2]) { + * if (res > (2^15)-1) { + * res = (2^15)-1; + * OV = 1; + * } else if (res < -2^15) { + * res = -2^15; + * OV = 1; + * } + * } + * Rd.W[x][31:16] = res1; + * Rd.W[x][15:0] = res2; + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKSTAS16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkstas16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKSTAS16 ===== */ + +/* ===== Inline Function Start for DSCLIP8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSCLIP8 (8-bit Signed Saturation and Clip) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSCLIP8 Rd, Rs1, imm3u[2:0] + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Limit the 8-bit signed integer elements of a register into a signed range simultaneously. + * + * **Description**:\n + * This instruction limits the 8-bit signed integer elements stored in Rs1 into a signed integer range between -2^imm3u and + * 2^imm3u-1, and writes the limited results to Rd. For example, if imm3u is 3, the 8-bit input values should be saturated + * between 7 and -8. If saturation is performed, set OV bit to 1. + * + * **Operations**:\n + * ~~~ + * src = Rs1.B[x]; + * if (src > (2^imm3u)-1) { + * src = (2^imm3u)-1; + * OV = 1; + * } else if (src < -2^imm3u) { + * src = -2^imm3u; + * OV = 1; + * } + * Rd.B[x] = src + * x=7...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +#define __RV_DSCLIP8(a, b) \ + ({ \ + unsigned long long result; \ + unsigned long long __a = (unsigned long long)(a); \ + __ASM volatile("dsclip8 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for DSCLIP8 ===== */ + +/* ===== Inline Function Start for DSCLIP16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSCLIP16 (16-bit Signed Saturation and Clip) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSCLIP16 Rd, Rs1, imm4u[3:0] + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Limit the 16-bit signed integer elements of a register into a signed range simultaneously. + * + * **Description**:\n + * This instruction limits the 16-bit signed integer elements stored in Rs1 into a signed integer range between -2^imm4u and + * 2^imm4u-1, and writes the limited results to Rd. For example, if imm4u is 3, the 32-bit input values should be saturated + * between 7 and -8. If saturation is performed, set OV bit to 1. + * + * **Operations**:\n + * ~~~ + * src = Rs1.H[x]; + * if (src > (2^imm4u)-1) { + * src = (2^imm4u)-1; + * OV = 1; + * } else if (src < -2^imm4u) { + * src = -2^imm4u; + * OV = 1; + * } + * Rd.H[x] = src + * x=3...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +#define __RV_DSCLIP16(a, b) \ + ({ \ + unsigned long long result; \ + unsigned long long __a = (unsigned long long)(a); \ + __ASM volatile("dsclip16 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for DSCLIP16 ===== */ + +/* ===== Inline Function Start for DSCLIP32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSCLIP32 (32-bit Signed Saturation and Clip) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSCLIP32 Rd, Rs1, imm5u[4:0] + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Limit the 32-bit signed integer elements of a register into a signed range simultaneously. + * + * **Description**:\n + * This instruction limits the 32-bit signed integer elements stored in Rs1 into a signed integer range between -2^imm5u and + * 2^imm5u-1, and writes the limited results to Rd. For example, if imm5u is 3, the 32-bit input values should be saturated + * between 7 and -8. If saturation is performed, set OV bit to 1. + * + * **Operations**:\n + * ~~~ + * src = Rs1.W[x]; + * if (src > (2^imm5u)-1) { + * src = (2^imm5u)-1; + * OV = 1; + * } else if (src < -2^imm5u) { + * src = -2^imm5u; + * OV = 1; + * } + * Rd.W[x] = src + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +#define __RV_DSCLIP32(a, b) \ + ({ \ + unsigned long long result; \ + unsigned long long __a = (unsigned long long)(a); \ + __ASM volatile("dsclip32 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for DSCLIP32 ===== */ + +/* ===== Inline Function Start for DRSUB32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DRSUB32 (32-bit Signed Halving Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DRSUB32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element subtractions simultaneously. The results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 32-bit signed integer elements in Rs2 from the 32-bit signed integer elements in Rs1. The + * results are first arithmetically right-shifted by 1 bit and then written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = (Rs1.W[x] - Rs2.W[x]) s>> 1; + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DRSUB32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("drsub32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DRSUB32 ===== */ + +/* ===== Inline Function Start for DPACK32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DPACK32 (SIMD Pack Two 32-bit Data To 64-bit) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DPACK32 Rd, Rs1, Rs2 + * # Rd is even/odd pair of register + * ~~~ + * + * **Purpose**:\n + * Pack two 32-bit datas which from two registers into a 64-bit data. + * + * **Description**:\n + * This instruction moves 32-bit Rs1 to Rd.W[1] and moves 32-bit Rs2 to Rd.W[0]. + * + * **Operations**:\n + * ~~~ + * Rd = CONCAT(Rs1.W , Rs2.W); + * ~~~ + * + * \param [in] a signed long type of value stored in a + * \param [in] b signed long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DPACK32(signed long a, signed long b) +{ + unsigned long long result; + __ASM volatile("dpack32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DPACK32 ===== */ + +/* ===== Inline Function Start for DSUNPKD810 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSUNPKD810 (Signed Unpacking Bytes 1 & 0) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSUNPKD810 Rd, Rs1 + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Unpack byte 1 and byte 0 of 32-bit chunks in a register into two 16-bit signed halfwords of 32-bit chunks in a register. + * + * **Description**:\n + * For the `DSUNPKD810` instruction, it unpacks byte 1 and byte 0 of 32-bit chunks in Rs1 into two 16-bit signed halfwords + * and writes the results to the top part and the bottom part of 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = SE16(Rs1.W[m].B[1]) + * Rd.W[m].H[0] = SE16(Rs1.W[m].B[0]) + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSUNPKD810(unsigned long long a) +{ + unsigned long long result; + __ASM volatile("dsunpkd810 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for DSUNPKD810 ===== */ + +/* ===== Inline Function Start for DSUNPKD820 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSUNPKD820 (Signed Unpacking Bytes 2 & 0) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSUNPKD820 Rd, Rs1 + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Unpack byte 2 and byte 0 of 32-bit chunks in a register into two 16-bit signed halfwords of 32-bit chunks in a register. + * + * **Description**:\n + * For the `DSUNPKD820` instruction, it unpacks byte 2 and byte 0 of 32-bit chunks in Rs1 into two 16-bit signed halfwords + * and writes the results to the top part and the bottom part of 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = SE16(Rs1.W[m].B[2]) + * Rd.W[m].H[0] = SE16(Rs1.W[m].B[0]) + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSUNPKD820(unsigned long long a) +{ + unsigned long long result; + __ASM volatile("dsunpkd820 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for DSUNPKD820 ===== */ + +/* ===== Inline Function Start for DSUNPKD830 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSUNPKD830 (Signed Unpacking Bytes 3 & 0) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSUNPKD830 Rd, Rs1 + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Unpack byte 3 and byte 0 of 32-bit chunks in a register into two 16-bit signed halfwords of 32-bit chunks in a register. + * + * **Description**:\n + * For the `DSUNPKD830` instruction, it unpacks byte 3 and byte 0 of 32-bit chunks in Rs1 into two 16-bit signed halfwords + * and writes the results to the top part and the bottom part of 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = SE16(Rs1.W[m].B[3]) + * Rd.W[m].H[0] = SE16(Rs1.W[m].B[0]) + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSUNPKD830(unsigned long long a) +{ + unsigned long long result; + __ASM volatile("dsunpkd830 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for DSUNPKD830 ===== */ + +/* ===== Inline Function Start for DSUNPKD831 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSUNPKD831 (Signed Unpacking Bytes 3 & 1) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSUNPKD831 Rd, Rs1 + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Unpack byte 3 and byte 1 of 32-bit chunks in a register into two 16-bit signed halfwords of 32-bit chunks in a register. + * + * **Description**:\n + * For the `DSUNPKD831` instruction, it unpacks byte 3 and byte 1 of 32-bit chunks in Rs1 into two 16-bit signed halfwords + * and writes the results to the top part and the bottom part of 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = SE16(Rs1.W[m].B[3]) + * Rd.W[m].H[0] = SE16(Rs1.W[m].B[1]) + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSUNPKD831(unsigned long long a) +{ + unsigned long long result; + __ASM volatile("dsunpkd831 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for DSUNPKD831 ===== */ + +/* ===== Inline Function Start for DSUNPKD832 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSUNPKD832 (Signed Unpacking Bytes 3 & 2) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSUNPKD832 Rd, Rs1 + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Unpack byte 3 and byte 2 of 32-bit chunks in a register into two 16-bit signed halfwords of 32-bit chunks in a register. + * + * **Description**:\n + * For the `DSUNPKD832` instruction, it unpacks byte 3 and byte 2 of 32-bit chunks in Rs1 into two 16-bit signed halfwords + * and writes the results to the top part and the bottom part of 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = SE16(Rs1.W[m].B[3]) + * Rd.W[m].H[0] = SE16(Rs1.W[m].B[2]) + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSUNPKD832(unsigned long long a) +{ + unsigned long long result; + __ASM volatile("dsunpkd832 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for DSUNPKD832 ===== */ + +/* ===== Inline Function Start for DZUNPKD810 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DZUNPKD810 (UnSigned Unpacking Bytes 1 & 0) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DZUNPKD810 Rd, Rs1 + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Unpack byte 1 and byte 0 of 32-bit chunks in a register into two 16-bit unsigned halfwords of 32-bit chunks in a register. + * + * **Description**:\n + * For the `DZUNPKD810` instruction, it unpacks byte 1 and byte 0 of 32-bit chunks in Rs1 into two 16-bit unsigned halfwords + * and writes the results to the top part and the bottom part of 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = SE16(Rs1.W[m].B[1]) + * Rd.W[m].H[0] = SE16(Rs1.W[m].B[0]) + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DZUNPKD810(unsigned long long a) +{ + unsigned long long result; + __ASM volatile("dzunpkd810 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for DZUNPKD810 ===== */ + +/* ===== Inline Function Start for DZUNPKD820 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DZUNPKD820 (UnSigned Unpacking Bytes 2 & 0) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DZUNPKD820 Rd, Rs1 + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Unpack byte 2 and byte 0 of 32-bit chunks in a register into two 16-bit unsigned halfwords of 32-bit chunks in a register. + * + * **Description**:\n + * For the `DZUNPKD820` instruction, it unpacks byte 2 and byte 0 of 32-bit chunks in Rs1 into two 16-bit unsigned halfwords + * and writes the results to the top part and the bottom part of 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = SE16(Rs1.W[m].B[2]) + * Rd.W[m].H[0] = SE16(Rs1.W[m].B[0]) + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DZUNPKD820(unsigned long long a) +{ + unsigned long long result; + __ASM volatile("dzunpkd820 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for DZUNPKD820 ===== */ + +/* ===== Inline Function Start for DZUNPKD830 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DZUNPKD830 (UnSigned Unpacking Bytes 3 & 0) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DZUNPKD830 Rd, Rs1 + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Unpack byte 3 and byte 0 of 32-bit chunks in a register into two 16-bit unsigned halfwords of 32-bit chunks in a register. + * + * **Description**:\n + * For the `DZUNPKD830` instruction, it unpacks byte 3 and byte 0 of 32-bit chunks in Rs1 into two 16-bit unsigned halfwords + * and writes the results to the top part and the bottom part of 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = SE16(Rs1.W[m].B[3]) + * Rd.W[m].H[0] = SE16(Rs1.W[m].B[0]) + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DZUNPKD830(unsigned long long a) +{ + unsigned long long result; + __ASM volatile("dzunpkd830 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for DZUNPKD830 ===== */ + +/* ===== Inline Function Start for DZUNPKD831 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DZUNPKD831 (UnSigned Unpacking Bytes 3 & 1) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DZUNPKD831 Rd, Rs1 + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Unpack byte 3 and byte 1 of 32-bit chunks in a register into two 16-bit unsigned halfwords of 32-bit chunks in a register. + * + * **Description**:\n + * For the `DZUNPKD831` instruction, it unpacks byte 3 and byte 1 of 32-bit chunks in Rs1 into two 16-bit unsigned halfwords + * and writes the results to the top part and the bottom part of 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = SE16(Rs1.W[m].B[3]) + * Rd.W[m].H[0] = SE16(Rs1.W[m].B[1]) + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DZUNPKD831(unsigned long long a) +{ + unsigned long long result; + __ASM volatile("dzunpkd831 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for DZUNPKD831 ===== */ + +/* ===== Inline Function Start for DZUNPKD832 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DZUNPKD832 (UnSigned Unpacking Bytes 3 & 2) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DZUNPKD832 Rd, Rs1 + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Unpack byte 3 and byte 2 of 32-bit chunks in a register into two 16-bit unsigned halfwords of 32-bit chunks in a register. + * + * **Description**:\n + * For the `DZUNPKD832` instruction, it unpacks byte 3 and byte 2 of 32-bit chunks in Rs1 into two 16-bit unsigned halfwords + * and writes the results to the top part and the bottom part of 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = SE16(Rs1.W[m].B[3]) + * Rd.W[m].H[0] = SE16(Rs1.W[m].B[2]) + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DZUNPKD832(unsigned long long a) +{ + unsigned long long result; + __ASM volatile("dzunpkd832 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for DZUNPKD832 ===== */ + +/* ===== Inline Function Start for DKMMAC ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMMAC (64-bit MSW 32x32 Signed Multiply and Saturating Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKMMAC Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do MSW 32x32 element signed multiplications and saturating addition simultaneously. The results are written into Rd. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit elements of Rs1 with the signed 32-bit elements of Rs2 + * and adds the most significant 32-bit multiplication results with the signed 32-bit elements of Rd. If + * the addition result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range + * and the OV bit is set to 1. The results after saturation are written to Rd. The .u form of the + * instruction additionally rounds up the most significant 32-bit of the 64-bit multiplication results by + * adding a 1 to bit 31 of the results. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; op3t = Rd.W[x+1] // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; op3b = Rd.W[x] // bottom + * for ((aop,bop,dop,res) in [(op1t,op2t,op3t,rest), (op1b,op2b,op3b,resb)]) { + * res = sat.q31(dop + (aop s* bop)[63:32]); + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKMMAC(unsigned long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmmac %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMMAC ===== */ + +/* ===== Inline Function Start for DKMMAC.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMMAC.u (64-bit MSW 32x32 Unsigned Multiply and Saturating Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKMMAC.u Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do MSW 32x32 element unsigned multiplications and saturating addition simultaneously. The results are written into Rd. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit elements of Rs1 with the signed 32-bit elements of Rs2 + * and adds the most significant 32-bit multiplication results with the signed 32-bit elements of Rd. If + * the addition result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range + * and the OV bit is set to 1. The results after saturation are written to Rd. The .u form of the + * instruction additionally rounds up the most significant 32-bit of the 64-bit multiplication results by + * adding a 1 to bit 31 of the results. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; op3t = Rd.W[x+1] // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; op3b = Rd.W[x] // bottom + * for ((aop,bop,dop,res) in [(op1t,op2t,op3t,rest), (op1b,op2b,op3b,resb)]) { + * res = sat.q31(dop + RUND(aop u* bop)[63:32]); + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKMMAC_U(unsigned long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmmac.u %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMMAC.u ===== */ + +/* ===== Inline Function Start for DKMMSB ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMMSB (64-bit MSW 32x32 Signed Multiply and Saturating Sub) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKMMSB Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do MSW 32x32 element signed multiplications and saturating subtraction simultaneously. The results are written into Rd. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit elements of Rs1 with the signed 32-bit elements of Rs2 + * and subtracts the most significant 32-bit multiplication results from the signed 32-bit elements of + * Rd. If the subtraction result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the + * range and the OV bit is set to 1. The results after saturation are written to Rd. The .u form of the + * instruction additionally rounds up the most significant 32-bit of the 64-bit multiplication results by + * adding a 1 to bit 31 of the results. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; op3t = Rd.W[x+1] // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; op3b = Rd.W[x] // bottom + * for ((aop,bop,dop,res) in [(op1t,op2t,op3t,rest), (op1b,op2b,op3b,resb)]) { + * res = sat.q31(dop - (aop s* bop)[63:32]); + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKMMSB(unsigned long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmmsb %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMMSB ===== */ + +/* ===== Inline Function Start for DKMMSB.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMMSB.u (64-bit MSW 32x32 Unsigned Multiply and Saturating Sub) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKMMSB.u Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do MSW 32x32 element unsigned multiplications and saturating subtraction simultaneously. The results are written into Rd. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit elements of Rs1 with the signed 32-bit elements of Rs2 + * and subtracts the most significant 32-bit multiplication results from the signed 32-bit elements of + * Rd. If the subtraction result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the + * range and the OV bit is set to 1. The results after saturation are written to Rd. The .u form of the + * instruction additionally rounds up the most significant 32-bit of the 64-bit multiplication results by + * adding a 1 to bit 31 of the results. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; op3t = Rd.W[x+1] // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; op3b = Rd.W[x] // bottom + * for ((aop,bop,dop,res) in [(op1t,op2t,op3t,rest), (op1b,op2b,op3b,resb)]) { + * res = sat.q31(dop - (aop u* bop)[63:32]); + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKMMSB_U(unsigned long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmmsb.u %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMMSB.u ===== */ + +/* ===== Inline Function Start for DKMADA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMADA (Saturating Signed Multiply Two Halfs and Two Adds) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DKMADA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two 16x16 with 32-bit signed double addition simultaneously. The results are written into Rd. + * + * **Description**:\n + * It multiplies the bottom 16-bit content of 32-bit elements in Rs1 with + * the bottom 16-bit content of 32-bit elements in Rs2 and then adds the result to the result of + * multiplying the top 16-bit content of 32-bit elements in Rs1 with the top 16-bit content of 32-bit + * elements in Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; op3t = Rd.W[x+1] // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; op3b = Rd.W[x] // bottom + * + * for ((aop,bop,dop,res) in [(op1t,op2t,op3t,rest), (op1b,op2b,op3b,resb)]) { + * mul1 = aop.H[1] s* bop.H[1]; + * mul2 = aop.H[0] s* bop.H[0]; + * res = sat.q31(dop + mul1 + mul2); + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKMADA(unsigned long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmada %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMADA ===== */ + +/* ===== Inline Function Start for DKMAXDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMAXDA (Two Cross 16x16 with 32-bit Signed Double Add) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DKMAXDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two cross 16x16 with 32-bit signed double addition simultaneously. The results are written into Rd. + * + * **Description**:\n + * It multiplies the top 16-bit content of 32-bit elements in Rs1 with the bottom 16-bit content of 32-bit + * elements in Rs2 and then adds the result to the result of multiplying the bottom 16-bit content of + * 32-bit elements in Rs1 with the top 16-bit content of 32-bit elements in elements in Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; op3t = Rd.W[x+1] // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; op3b = Rd.W[x] // bottom + * + * for ((aop,bop,dop,res) in [(op1t,op2t,op3t,rest), (op1b,op2b,op3b,resb)]) { + * mul1 = aop.H[1] s* bop.H[0]; + * mul2 = aop.H[0] s* bop.H[1]; + * res = sat.q31(dop + mul1 + mul2); + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKMAXDA(unsigned long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmaxda %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMAXDA ===== */ + +/* ===== Inline Function Start for DKMADS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMADS (Two 16x16 with 32-bit Signed Add and Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DKMADS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two 16x16 with 32-bit signed addition and subtraction simultaneously. The results are written into Rd. + * + * **Description**:\n + * It multiplies the bottom 16-bit content of 32-bit elements in Rs1 with + * the bottom 16-bit content of 32-bit elements in Rs2 and then subtracts the result from the result of + * multiplying the top 16-bit content of 32-bit elements in Rs1 with the top 16-bit content of 32-bit + * elements in Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; op3t = Rd.W[x+1] // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; op3b = Rd.W[x] // bottom + * + * for ((aop,bop,dop,res) in [(op1t,op2t,op3t,rest), (op1b,op2b,op3b,resb)]) { + * mul1 = aop.H[1] s* bop.H[1]; + * mul2 = aop.H[0] s* bop.H[0]; + * res = sat.q31(dop + mul1 - mul2); + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKMADS(unsigned long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmads %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMADS ===== */ + +/* ===== Inline Function Start for DKMADRS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMADRS (Two 16x16 with 32-bit Signed Add and Reversed Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DKMADRS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two 16x16 with 32-bit signed addition and revered subtraction simultaneously. The results are written into Rd. + * + * **Description**:\n + * it multiplies the top 16-bit content of 32-bit elements in Rs1 with the + * top 16-bit content of 32-bit elements in Rs2 and then subtracts the result from the result of + * multiplying the bottom 16-bit content of 32-bit elements in Rs1 with the bottom 16-bit content of 32- + * bit elements in Rs2 + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; op3t = Rd.W[x+1] // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; op3b = Rd.W[x] // bottom + * + * for ((aop,bop,dop,res) in [(op1t,op2t,op3t,rest), (op1b,op2b,op3b,resb)]) { + * mul1 = aop.H[1] s* bop.H[1]; + * mul2 = aop.H[0] s* bop.H[0]; + * res = sat.q31(dop - mul1 + mul2); + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKMADRS(unsigned long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmadrs %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMADRS ===== */ + +/* ===== Inline Function Start for DKMAXDS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMAXDS (Saturating Signed Crossed Multiply Two Halfs & Subtract & Add) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DKMAXDS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two cross 16x16 with 32-bit signed addition and subtraction simultaneously. The results are written into Rd. + * + * **Description**:\n + * Do two signed 16-bit multiplications from 32-bit elements in two registers; and then + * perform a subtraction operation between the two 32-bit results. Then add the subtraction result to + * the corresponding 32-bit elements in a third register. The addition result may be saturated. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; op3t = Rd.W[x+1] // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; op3b = Rd.W[x] // bottom + * + * for ((aop,bop,dop,res) in [(op1t,op2t,op3t,rest), (op1b,op2b,op3b,resb)]) { + * mul1 = aop.H[1] s* bop.H[0]; + * mul2 = aop.H[0] s* bop.H[1]; + * res = sat.q31(dop + mul1 - mul2); + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKMAXDS(unsigned long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmaxds %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMAXDS ===== */ + +/* ===== Inline Function Start for DKMSDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMSDA (Two 16x16 with 32-bit Signed Double Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DKMSDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two 16x16 with 32-bit signed double subtraction simultaneously. The results are written into Rd. + * + * **Description**:\n + * it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2 and multiplies the top 16-bit content of + * the 32-bit elements of Rs1 with the top 16-bit content of the 32-bit elements of Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; op3t = Rd.W[x+1] // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; op3b = Rd.W[x] // bottom + * + * for ((aop,bop,dop,res) in [(op1t,op2t,op3t,rest), (op1b,op2b,op3b,resb)]) { + * mul1 = aop.H[1] s* bop.H[0]; + * mul2 = aop.H[0] s* bop.H[1]; + * res = sat.q31(dop - mul1 - mul2); + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKMSDA(unsigned long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmsda %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMSDA ===== */ + +/* ===== Inline Function Start for DKMSXDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMSXDA (Two Cross 16x16 with 32-bit Signed Double Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DKMSXDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two cross 16x16 with 32-bit signed double subtraction simultaneously. The results are written into Rd. + * + * **Description**:\n + * It multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2 and multiplies the top 16-bit content of the + * 32-bit elements of Rs1 with the bottom 16-bit content of the 32-bit elements of Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; op3t = Rd.W[x+1] // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; op3b = Rd.W[x] // bottom + * + * for ((aop,bop,dop,res) in [(op1t,op2t,op3t,rest), (op1b,op2b,op3b,resb)]) { + * mul1 = aop.H[1] s* bop.H[0]; + * mul2 = aop.H[0] s* bop.H[1]; + * res = sat.q31(dop - mul1 - mul2); + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKMSXDA(unsigned long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmsxda %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMSXDA ===== */ + +/* ===== Inline Function Start for DSMAQA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMAQA (Four Signed 8x8 with 32-bit Signed Add) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DSMAQA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do four signed 8x8 with 32-bit signed addition simultaneously. The results are written into Rd. + * + * **Description**:\n + * This instruction multiplies the four signed 8-bit elements of 32-bit chunks of Rs1 with the four + * signed 8-bit elements of 32-bit chunks of Rs2 and then adds the four results together with the signed + * content of the corresponding 32-bit chunks of Rd. The final results are written back to the + * corresponding 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; op3t = Rd.W[x+1] // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; op3b = Rd.W[x] // bottom + * + * for ((aop,bop,dop,res) in [(op1t,op2t,op3t,rest), (op1b,op2b,op3b,resb)]) { + * m0 = aop.B[0] s* bop.B[0]; + * m1 = aop.B[1] s* bop.B[1]; + * m2 = aop.B[2] s* bop.B[2]; + * m3 = aop.B[3] s* bop.B[3]; + * res = dop + m0 + m1 + m2 + m3; + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSMAQA(unsigned long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dsmaqa %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DSMAQA ===== */ + +/* ===== Inline Function Start for DSMAQA.SU ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMAQA.SU (Four Signed 8 x Unsigned 8 with 32-bit Signed Add) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DSMAQA.SU Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do four Signed 8 x Unsigned 8 with 32-bit unsigned addition simultaneously. The results are written into Rd. + * + * **Description**:\n + * This instruction multiplies the four unsigned 8-bit elements of 32-bit chunks of Rs1 with the four + * signed 8-bit elements of 32-bit chunks of Rs2 and then adds the four results together with the unsigned + * content of the corresponding 32-bit chunks of Rd. The final results are written back to the + * corresponding 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; op3t = Rd.W[x+1] // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; op3b = Rd.W[x] // bottom + * + * for ((aop,bop,dop,res) in [(op1t,op2t,op3t,rest), (op1b,op2b,op3b,resb)]) { + * m0 = aop.B[0] su* bop.B[0]; + * m1 = aop.B[1] su* bop.B[1]; + * m2 = aop.B[2] su* bop.B[2]; + * m3 = aop.B[3] su* bop.B[3]; + * res = dop + m0 + m1 + m2 + m3; + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSMAQA_SU(unsigned long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dsmaqa.su %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DSMAQA.SU ===== */ + +/* ===== Inline Function Start for DUMAQA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DUMAQA (Four Unsigned 8x8 with 32-bit Unsigned Add) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DUMAQA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do four unsigned 8x8 with 32-bit unsigned addition simultaneously. The results are written into Rd. + * + * **Description**:\n + * This instruction multiplies the four unsigned 8-bit elements of 32-bit chunks of Rs1 with the four + * unsigned 8-bit elements of 32-bit chunks of Rs2 and then adds the four results together with the + * unsigned content of the corresponding 32-bit chunks of Rd. The final results are written back to the + * corresponding 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; op3t = Rd.W[x+1] // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; op3b = Rd.W[x] // bottom + * + * for ((aop,bop,dop,res) in [(op1t,op2t,op3t,rest), (op1b,op2b,op3b,resb)]) { + * m0 = aop.B[0] su* bop.B[0]; + * m1 = aop.B[1] su* bop.B[1]; + * m2 = aop.B[2] su* bop.B[2]; + * m3 = aop.B[3] su* bop.B[3]; + * res = dop + m0 + m1 + m2 + m3; + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DUMAQA(unsigned long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dumaqa %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DUMAQA ===== */ + +/* ===== Inline Function Start for DKMDA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMDA32 (Two Signed 32x32 with 64-bit Saturation Add) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DKMDA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32x32 add the signed multiplication results with Q63 saturation. The results are written into Rd. + * + * **Description**:\n + * For the `KMDA32` instruction, it multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit + * element of Rs2 and then adds the result to the result of multiplying the top 32-bit element of Rs1 + * with the top 32-bit element of Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * t0 = op1b s* op2b; + * t1 = op1t s* op2t; + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DKMDA32(unsigned long long a, unsigned long long b) +{ + long long result; + __ASM volatile("dkmda32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKMDA32 ===== */ + +/* ===== Inline Function Start for DKMXDA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMXDA32 (Two Cross Signed 32x32 with 64-bit Saturation Add) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DKMXDA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two cross signed 32x32 and add the signed multiplication results with Q63 saturation. The results are written into Rd. + * + * **Description**:\n + * It multiplies the bottom 32-bit element of Rs1 with the top 32-bit + * element of Rs2 and then adds the result to the result of multiplying the top 32-bit element of Rs1 + * with the bottom 32-bit element of Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * t01 = op1b s* op2t; + * t10 = op1t s* op2b; + * Rd = sat.q63(t01 + t10); + * x=0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DKMXDA32(unsigned long long a, unsigned long long b) +{ + long long result; + __ASM volatile("dkmxda32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKMXDA32 ===== */ + +/* ===== Inline Function Start for DKMADA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMADA32 (Two Signed 32x32 with 64-bit Saturation Add) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DKMADA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32x32 and add the signed multiplication results and a third register with Q63 saturation. The results are written into Rd. + * + * **Description**:\n + * It multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit + * element of Rs2 and then adds the result to the result of multiplying the top 32-bit element of Rs1 + * with the top 32-bit element of Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * t01 = op1b s* op2b; + * t10 = op1t s* op2t; + * Rd = sat.q63(t01 + t10); + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DKMADA32(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmada32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMADA32 ===== */ + +/* ===== Inline Function Start for DKMAXDA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMAXDA32 (Two Cross Signed 32x32 with 64-bit Saturation Add) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DKMAXDA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two cross signed 32x32 and add the signed multiplication results and a third register with Q63 saturation. The + * results are written into Rd. + * + * **Description**:\n + * It multiplies the top 32-bit element in Rs1 with the bottom 32-bit + * element in Rs2 and then adds the result to the result of multiplying the bottom 32-bit element in Rs1 + * with the top 32-bit element in Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * t01 = op1b s* op2t; + * t10 = op1t s* op2b; + * Rd = sat.q63(Rd + t01 + t10); + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DKMAXDA32(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmaxda32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMAXDA32 ===== */ + +/* ===== Inline Function Start for DKMADS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMADS32 (Two Signed 32x32 with 64-bit Saturation Add and Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DKMADS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32x32 and add the top signed multiplication results and subtraction bottom signed multiplication results + * and add a third register with Q63 saturation. The results are written into Rd. + * + * **Description**:\n + * It multiplies the top 32-bit element in Rs1 with the bottom 32-bit + * element in Rs2 and then subtracts the result to the result of multiplying the top 32-bit element in Rs1 + * with the top 32-bit element in Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * t0 = op1b s* op2b; + * t1 = op1t s* op2t; + * Rd = sat.q63(Rd - t0 + t1); + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DKMADS32(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmads32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMADS32 ===== */ + +/* ===== Inline Function Start for DKMADRS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMADRS32 (Two Signed 32x32 with 64-bit Saturation Revered Add and Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DKMADRS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32x32 and add the signed multiplication results and a third register with Q63 saturation. The results + * are written into Rd.Do two signed 32x32 and subtraction the top signed multiplication results and add bottom signed + * multiplication results and add a third register with Q63 saturation. The results are written into Rd. + * + * **Description**:\n + * It multiplies the top 32-bit element in Rs1 with the top 32-bit + * element in Rs2 and then subtracts the result from the result of multiplying the bottom 32-bit + * element in Rs1 with the bottom 32-bit element in Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * t0 = op1b s* op2b; + * t1 = op1t s* op2t; + * Rd = sat.q63(Rd + t0 - t1); + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DKMADRS32(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmadrs32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMADRS32 ===== */ + +/* ===== Inline Function Start for DKMAXDS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMAXDS32 (Two Cross Signed 32x32 with 64-bit Saturation Add and Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DKMAXDS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32x32 and add the top signed multiplication results and subtraction bottom signed multiplication results + * and add a third register with Q63 saturation. The results are written into Rd. + * + * **Description**:\n + * It multiplies the bottom 32-bit element in Rs1 with the top 32-bit + * element in Rs2 and then subtracts the result from the result of multiplying the top 32-bit element in + * Rs1 with the bottom 32-bit element in Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * t01 = op1b s* op2t; + * t10 = op1t s* op2b; + * Rd = sat.q63(Rd - t01 + t10); + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DKMAXDS32(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmaxds32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMAXDS32 ===== */ + +/* ===== Inline Function Start for DKMSDA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMSDA32 (Two Signed 32x32 with 64-bit Saturation Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DKMSDA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32x32 and subtraction the top signed multiplication results and subtraction bottom signed multiplication + * results and add a third register with Q63 saturation. The results are written into Rd. + * + * **Description**:\n + * It multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit + * element of Rs2 and multiplies the top 32-bit element of Rs1 with the top 32-bit element of Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * t0 = op1b s* op2b; + * t1 = op1t s* op2t; + * Rd = sat.q63(Rd - t0 - t1); + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DKMSDA32(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmsda32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMSDA32 ===== */ + +/* ===== Inline Function Start for DKMSXDA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMSXDA32 (Two Cross Signed 32x32 with 64-bit Saturation Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DKMSXDA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two cross signed 32x32 and subtraction the top signed multiplication results and subtraction bottom signed multiplication + * results and add a third register with Q63 saturation. The results are written into Rd. + * + * **Description**:\n + * It multiplies the bottom 32-bit element of Rs1 with the top 32-bit + * element of Rs2 and multiplies the top 32-bit element of Rs1 with the bottom 32-bit element of Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * t0 = op1b s* op2t; + * t1 = op1t s* op2b; + * Rd = sat.q63(Rd - t0 - t1); + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DKMSXDA32(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmsxda32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMSXDA32 ===== */ + +/* ===== Inline Function Start for DSMDS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMDS32 (Two Signed 32x32 with 64-bit Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DSMDS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32x32 and add the top signed multiplication results and subtraction bottom signed multiplication. The + * results are written into Rd. + * + * **Description**:\n + * It multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit + * element of Rs2 and then subtracts the result from the result of multiplying the top 32-bit element of + * Rs1 with the top 32-bit element of Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * t0 = op1b s* op2t; + * t1 = op1t s* op2b; + * Rd = t1 - t0; + * x=0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMDS32(unsigned long long a, unsigned long long b) +{ + long long result; + __ASM volatile("dsmds32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMDS32 ===== */ + +/* ===== Inline Function Start for DSMDRS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMDRS32 (Two Signed 32x32 with 64-bit Revered Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DSMDRS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32x32 and subtraction the top signed multiplication results and add bottom signed multiplication. The results are written into Rd + * + * **Description**:\n + * It multiplies the top 32-bit element of Rs1 with the top 32-bit + * element of Rs2 and then subtracts the result from the result of multiplying the bottom 32-bit + * element of Rs1 with the bottom 32-bit element of Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * t0 = op1b s* op2b; + * t1 = op1t s* op2t; + * Rd = t1 - t0; + * x=0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMDRS32(unsigned long long a, unsigned long long b) +{ + long long result; + __ASM volatile("dsmdrs32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMDRS32 ===== */ + +/* ===== Inline Function Start for DSMXDS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMXDS32 (Two Cross Signed 32x32 with 64-bit Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DSMXDS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two cross signed 32x32 and add the top signed multiplication results and subtraction bottom signed multiplication. + * The results are written into Rd. + * + * **Description**:\n + * It multiplies the bottom 32-bit element of Rs1 with the top 32-bit + * element of Rs2 and then subtracts the result from the result of multiplying the top 32-bit element of + * Rs1 with the bottom 32-bit element of Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * t01 = op1b s* op2t; + * t10 = op1t s* op2b; + * Rd = t1 - t0; + * x=0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMXDS32(unsigned long long a, unsigned long long b) +{ + long long result; + __ASM volatile("dsmxds32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMXDS32 ===== */ + +/* ===== Inline Function Start for DSMALDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMALDA (Four Signed 16x16 with 64-bit Add) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DSMALDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do four signed 16x16 and add signed multiplication results and a third register. The results are written into Rd. + * + * **Description**:\n + * It multiplies the bottom 16-bit content of Rs1 with the bottom 16-bit + * content of Rs2 and then adds the result to the result of multiplying the top 16-bit content of Rs1 with + * the top 16-bit content of Rs2 with unlimited precision + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * m0 = op1b.H[0] s* op2b.H[0]; + * m1 = op1b.H[1] s* op2b.H[1]; + * m2 = op1t.H[0] s* op2t.H[0]; + * m3 = op1t.H[1] s* op2t.H[1]; + * + * Rd = Rd + m0 + m1 + m2 + m3; + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMALDA(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dsmalda %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DSMALDA ===== */ + +/* ===== Inline Function Start for DSMALXDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMALXDA (Four Signed 16x16 with 64-bit Add) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DSMALXDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do four cross signed 16x16 and add signed multiplication results and a third register. The results are written into Rd. + * + * **Description**:\n + * It multiplies the top 16-bit content of Rs1 with the bottom 16-bit + * content of Rs2 and then adds the result to the result of multiplying the bottom 16-bit content of Rs1 + * with the top 16-bit content of Rs2 with unlimited precision. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * m0 = op1b.H[0] s* op2b.H[1]; + * m1 = op1b.H[1] s* op2b.H[0]; + * m2 = op1t.H[0] s* op2t.H[1]; + * m3 = op1t.H[1] s* op2t.H[0]; + * + * Rd = Rd + m0 + m1 + m2 + m3; + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMALXDA(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dsmalxda %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DSMALXDA ===== */ + +/* ===== Inline Function Start for DSMALDS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMALDS (Four Signed 16x16 with 64-bit Add and Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DSMALDS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do four signed 16x16 and add and subtraction signed multiplication results and a third register. The results are written into Rd. + * + * **Description**:\n + * It multiplies the bottom 16-bit content of Rs1 with the bottom 16-bit + * content of Rs2 and then subtracts the result from the result of multiplying the top 16-bit content of + * Rs1 with the top 16-bit content of Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * m0 = op1b.H[1] s* op2b.H[1]; + * m1 = op1b.H[0] s* op2b.H[0]; + * m2 = op1t.H[1] s* op2t.H[1]; + * m3 = op1t.H[0] s* op2t.H[0]; + * + * Rd = Rd + m0 - m1 + m2 - m3; + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMALDS(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dsmalds %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DSMALDS ===== */ + +/* ===== Inline Function Start for DSMALDRS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMALDRS (Four Signed 16x16 with 64-bit Add and Revered Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DSMALDRS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16x16 and add and revered subtraction signed multiplication results and a third register. The results are written into Rd. + * + * **Description**:\n + * It multiplies the top 16-bit content of Rs1 with the top 16-bit content + * of Rs2 and then subtracts the result from the result of multiplying the bottom 16-bit content of Rs1 + * with the bottom 16-bit content of Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * m0 = op1b.H[0] s* op2b.H[0]; + * m1 = op1b.H[1] s* op2b.H[1]; + * m2 = op1t.H[0] s* op2t.H[0]; + * m3 = op1t.H[1] s* op2t.H[1]; + * + * Rd = Rd + m0 - m1 + m2 - m3; + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMALDRS(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dsmaldrs %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DSMALDRS ===== */ + +/* ===== Inline Function Start for DSMALXDS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMALXDS (Four Cross Signed 16x16 with 64-bit Add and Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DSMALXDS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do four cross signed 16x16 and add and subtraction signed multiplication results and a third register. The results are written into Rd. + * + * **Description**:\n + * It multiplies the bottom 16-bit content of Rs1 with the top 16-bit + * content of Rs2 and then subtracts the result from the result of multiplying the top 16-bit content of + * Rs1 with the bottom 16-bit content of Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * m0 = op1b.H[1] s* op2b.H[0]; + * m1 = op1b.H[0] s* op2b.H[1]; + * m2 = op1t.H[1] s* op2t.H[0]; + * m3 = op1t.H[0] s* op2t.H[1]; + * + * Rd = Rd + m0 - m1 + m2 - m3; + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMALXDS(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dsmalxds %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DSMALXDS ===== */ + +/* ===== Inline Function Start for DSMSLDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMSLDA (Four Signed 16x16 with 64-bit Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DSMSLDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do four signed 16x16 and subtraction signed multiplication results and add a third register. The results are written into Rd. + * + * **Description**:\n + * It multiplies the bottom 16-bit content of Rs1 with the bottom 16-bit + * content Rs2 and multiplies the top 16-bit content of Rs1 with the top 16-bit content of Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * m0 = op1b.H[0] s* op2b.H[0]; + * m1 = op1b.H[1] s* op2b.H[1]; + * m2 = op1t.H[0] s* op2t.H[0]; + * m3 = op1t.H[1] s* op2t.H[1]; + * + * Rd = Rd - m0 - m1 - m2 - m3; + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMSLDA(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dsmslda %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DSMSLDA ===== */ + +/* ===== Inline Function Start for DSMSLXDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMSLXDA (Four Cross Signed 16x16 with 64-bit Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DSMSLXDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do four signed 16x16 and subtraction signed multiplication results and add a third register. The results are written into Rd. + * + * **Description**:\n + * It multiplies the top 16-bit content of Rs1 with the bottom 16-bit + * content of Rs2 and multiplies the bottom 16-bit content of Rs1 with the top 16-bit content of Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * m0 = op1b.H[0] s* op2b.H[1]; + * m1 = op1b.H[1] s* op2b.H[0]; + * m2 = op1t.H[0] s* op2t.H[1]; + * m3 = op1t.H[1] s* op2t.H[0]; + * + * Rd = Rd - m0 - m1 - m2 - m3; + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMSLXDA(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dsmslxda %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DSMSLXDA ===== */ + +/* ===== Inline Function Start for DDSMAQA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DDSMAQA (Eight Signed 8x8 with 64-bit Add) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DDSMAQA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do eight signed 8x8 and add signed multiplication results and a third register. The results are written into Rd. + * + * **Description**:\n + * Do eight signed 8-bit multiplications from eight 8-bit chunks of two registers; and then adds + * the eight 16-bit results and the content of 64-bit chunks of a third register. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * m0 = op1b.B[0] s* op2b.B[0]; + * m1 = op1b.B[1] s* op2b.B[1]; + * m2 = op1b.B[2] s* op2b.B[2]; + * m3 = op1b.B[3] s* op2b.B[3]; + * m4 = op1t.B[0] s* op2t.B[0]; + * m5 = op1t.B[1] s* op2t.B[1]; + * m6 = op1t.B[2] s* op2t.B[2]; + * m7 = op1t.B[3] s* op2t.B[3]; + * + * s0 = m0 + m1 + m2 + m3; + * s1 = m4 + m5 + m6 + m7; + * Rd = Rd + s0 + s1; + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DDSMAQA(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("ddsmaqa %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DDSMAQA ===== */ + +/* ===== Inline Function Start for DDSMAQA.SU ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DDSMAQA.SU (Eight Signed 8 x Unsigned 8 with 64-bit Add) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DDSMAQA.SU Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do eight signed 8 x unsigned 8 and add signed multiplication results and a third register. The results are written into Rd. + * + * **Description**:\n + * Do eight signed 8 x unsigned 8 and add signed multiplication results and a third register; and then adds + * the eight 16-bit results and the content of 64-bit chunks of a third register. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * m0 = op1b.B[0] su* op2b.B[0]; + * m1 = op1b.B[1] su* op2b.B[1]; + * m2 = op1b.B[2] su* op2b.B[2]; + * m3 = op1b.B[3] su* op2b.B[3]; + * m4 = op1t.B[0] su* op2t.B[0]; + * m5 = op1t.B[1] su* op2t.B[1]; + * m6 = op1t.B[2] su* op2t.B[2]; + * m7 = op1t.B[3] su* op2t.B[3]; + * + * s0 = m0 + m1 + m2 + m3; + * s1 = m4 + m5 + m6 + m7; + * Rd = Rd + s0 + s1; + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DDSMAQA_SU(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("ddsmaqa.su %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DDSMAQA.SU ===== */ + +/* ===== Inline Function Start for DDUMAQA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DDUMAQA (Eight Unsigned 8x8 with 64-bit Unsigned Add) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DDUMAQA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do eight unsigned 8x8 and add unsigned multiplication results and a third register. The results are written into Rd. + * + * **Description**:\n + * Do eight unsigned 8x8 and add unsigned multiplication results and a third register; and then adds + * the eight 16-bit results and the content of 64-bit chunks of a third register. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * m0 = op1b.B[0] u* op2b.B[0]; + * m1 = op1b.B[1] u* op2b.B[1]; + * m2 = op1b.B[2] u* op2b.B[2]; + * m3 = op1b.B[3] u* op2b.B[3]; + * m4 = op1t.B[0] u* op2t.B[0]; + * m5 = op1t.B[1] u* op2t.B[1]; + * m6 = op1t.B[2] u* op2t.B[2]; + * m7 = op1t.B[3] u* op2t.B[3]; + * + * s0 = m0 + m1 + m2 + m3; + * s1 = m4 + m5 + m6 + m7; + * Rd = Rd + s0 + s1; + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DDUMAQA(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("ddumaqa %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DDUMAQA ===== */ + +/* ===== Inline Function Start for DSMA32.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMA32.u (64-bit SIMD 32-bit Signed Multiply Addition With Rounding and Clip) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DSMA32.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32x32 and add signed multiplication results with Rounding, then right shift 32-bit and clip q63 to q31. + * The result is written to Rd. + * + * **Description**:\n + * For the `DSMA32.u` instruction, multiply the top 32-bit Q31 content of 64-bit chunks in Rs1 with the top 32-bit Q31 + * content of 64-bit chunks in Rs2. At the same time, multiply the bottom 32-bit Q31 content of 64-bit chunks in Rs1 with + * the bottom 32-bit Q31 content of 64-bit chunks in Rs2. + * Then, do the addtion for the results above and perform the addtional rounding operations, and then move the data to the right + * by 32-bit, and clip the 64-bit data into 32-bit.The result is written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd = (q31_t)((Rs1.W[x] s* Rs2.W[x] + Rs1.W[x + 1] s* Rs2.W[x + 1] + 0x80000000LL) s>> 32); + * x=0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_DSMA32_U(unsigned long long a, unsigned long long b) +{ + long result; + __ASM volatile("dsma32.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMA32.u ===== */ + +/* ===== Inline Function Start for DSMXS32.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMXS32.u (64-bit SIMD 32-bit Signed Multiply Cross Subtraction With Rounding and Clip) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DSMXS32.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two cross signed 32x32 and sub signed multiplication results with Rounding, then right shift 32-bit and clip q63 to + * q31. The result is written to Rd. + * + * **Description**:\n + * For the `DSMXS32.u` instruction, multiply the top 32-bit Q31 content of 64-bit chunks in Rs1 with the bottom 32-bit + * Q31 content of 64-bit chunks in Rs2. At the same time, multiply the bottom 32-bit Q31 content of 64-bit chunks in Rs1 + * with the top 32-bit Q31 content of 64-bit chunks in Rs2. + * Then, do the subtraction for the results above and perform the addtional rounding operations, and then move the data to the right by + * 32-bit, and clip the 64-bit data into 32-bit.The result is written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd = (q31_t)((Rs1.W[x + 1] s* Rs2.W[x] - Rs1.W[x] s* Rs2.W[x + 1] + 0x80000000LL) s>> 32); + * x=0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_DSMXS32_U(unsigned long long a, unsigned long long b) +{ + long result; + __ASM volatile("dsmxs32.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMXS32.u ===== */ + +/* ===== Inline Function Start for DSMXA32.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMXA32.u (64-bit SIMD 32-bit Signed Cross Multiply Addition with Rounding and Clip) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DSMXA32.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two cross signed 32x32 and add signed multiplication results with Rounding, then right shift 32-bit and clip q63 to + * q31. The result is written to Rd. + * + * **Description**:\n + * For the `DSMXA32.u` instruction,multiply the top 32-bit Q31 content of 64-bit chunks in Rs1 with the bottom 32-bit Q31 + * content of 64-bit chunks in Rs2. At the same time, multiply the bottom 32-bit Q31 content of 64-bit chunks in Rs1 with + * the top 32-bit Q31 content of 64-bit chunks in Rs2. + * Then, do the addtion for the results above and perform the addtional rounding operations, and then move the data to the right + * by 32-bit, and clip the 64-bit data into 32-bit.The result is written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd = (q31_t)((Rs1.W[x + 1] s* Rs2.W[x] + Rs1.W[x] s* Rs2.W[x + 1] + 0x80000000LL) s>> 32); + * x=0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_DSMXA32_U(unsigned long long a, unsigned long long b) +{ + long result; + __ASM volatile("dsmxa32.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMXA32.u ===== */ + +/* ===== Inline Function Start for DSMS32.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMS32.u (64-bit SIMD 32-bit Signed Multiply Subtraction with Rounding and Clip) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DSMS32.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32x32 and sub signed multiplication results with Rounding, then right shift 32-bit and clip q63 to q31. The + * result is written to Rd. + * + * **Description**:\n + * For the `DSMS32.u` instruction, multiply the bottom 32-bit Q31 content of 64-bit chunks in Rs1 with the bottom 32-bit + * Q31 content of 64-bit chunks in Rs2. At the same time, multiply the top 32-bit Q31 content of 64-bit chunks in Rs1 with + * the top 32-bit Q31 content of 64-bit chunks in Rs2. + * Then, do the subtraction for the results above and perform the addtional rounding operations, and then move the data to the right by + * 32-bit, and clip the 64-bit data into 32-bit.The result is written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd = (q31_t)((Rs1.W[x] s* Rs2.W[x] - Rs1.W[x + 1] s* Rs2.W[x + 1] + 0x80000000LL) s>> 32); + * x=0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_DSMS32_U(unsigned long long a, unsigned long long b) +{ + long result; + __ASM volatile("dsms32.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMS32.u ===== */ + +/* ===== Inline Function Start for DSMADA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMADA16 (Signed Multiply Two Halfs and Two Adds 32-bit) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMADA16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications of two 32-bit registers; and then adds the 32-bit results and the 32-bit value of an + * even/odd pair of registers together. + * * DSMADA16: rt pair+ top*top + bottom*bottom + * + * **Description**:\n + * This instruction multiplies the per 16-bit content of the 32-bit elements of Rs1 with the corresponding 16-bit content of + * the 32-bit elements of Rs2. The result is added to the 32-bit value of an even/odd pair of registers specified by Rd(4,1). + * The 32-bit addition result is written back to the register-pair. The 16-bit values of Rs1 and Rs2, and the 32-bit value of the + * register-pair are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * Mres0[0][31:0] = (Rs1.W[0].H[0] * Rs2.W[0].H[0]); + * Mres1[0][31:0] = (Rs1.W[0].H[1] * Rs2.W[0].H[1]); + * Mres0[1][31:0] = (Rs1.W[1].H[0] * Rs2.W[1].H[0]); + * Mres1[1][31:0] = (Rs1.W[1].H[1] * Rs2.W[1].H[1]); + * Rd.W = Rd.W + SE32(Mres0[0][31:0]) + SE32(Mres1[0][31:0]) + SE32(Mres0[1][31:0]) + SE32(Mres1[1][31:0]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_DSMADA16(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dsmada16 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return (long)t; +} +/* ===== Inline Function End for DSMADA16 ===== */ + +/* ===== Inline Function Start for DSMAXDA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMAXDA16 (Signed Crossed Multiply Two Halfs and Two Adds 32-bit) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMAXDA16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications of two 32-bit registers; and then adds the 32-bit results and the 32-bit value of an + * even/odd pair of registers together. + * * DSMAXDA: rt pair+ top*bottom + bottom*top (all 32-bit elements) + * + * **Description**:\n + * This instruction crossly multiplies the top 16-bit content of the 32-bit elements of Rs1 with the bottom 16-bit content of the 32-bit + * elements of Rs2 and then adds the result to the result of multiplying the bottom 16-bit content of the 32-bit elements of + * Rs1 with the top 16-bit content of the 32-bit elements of Rs2 with unlimited precision. The result is added to the 64-bit + * value of an even/odd pair of registers specified by Rd(4,1).The 64-bit addition result is clipped to 32-bit result. + * + * **Operations**:\n + * ~~~ + * Mres0[0][31:0] = (Rs1.W[0].H[0] * Rs2.W[0].H[1]); + * Mres1[0][31:0] = (Rs1.W[0].H[1] * Rs2.W[0].H[0]); + * Mres0[1][31:0] = (Rs1.W[1].H[0] * Rs2.W[1].H[1]); + * Mres1[1][31:0] = (Rs1.W[1].H[1] * Rs2.W[1].H[0]); + * Rd.W = Rd.W + SE32(Mres0[0][31:0]) + SE32(Mres1[0][31:0]) + SE32(Mres0[1][31:0]) + SE32(Mres1[1][31:0]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_DSMAXDA16(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dsmaxda16 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return (long)t; +} +/* ===== Inline Function End for DSMAXDA16 ===== */ + +/* ===== Inline Function Start for DKSMS32.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKSMS32.u (Two Signed Multiply Shift-clip and Saturation with Rounding) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKSMS32.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Computes saturated multiplication of two pairs of q31 type with shifted rounding. + * + * **Description**:\n + * Compute the multiplication of Rs1 and Rs2 of type q31_t, intercept [47:16] for the resulting 64-bit product + * to get the 32-bit number, then add 1 to it to do rounding, and finally saturate the result after rounding. + * + * **Operations**:\n + * ~~~ + * Mres[x][63:0] = Rs1.W[x] s* Rs2.W[x]; + * Round[x][32:0] = Mres[x][47:15] + 1; + * Rd.W[x] = sat.31(Rd.W[x] + Round[x][32:1]); + * x=1...0 + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKSMS32_U(unsigned long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dksms32.u %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKSMS32.u ===== */ + +/* ===== Inline Function Start for DMADA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DMADA32 ((Two Cross Signed 32x32 with 64-bit Add and Clip to 32-bit) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DMADA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two cross signed 32x32 and add the signed multiplication results to q63, then clip the q63 result to q31 , the final results + * are written into Rd. + * + * **Description**:\n + * For the `DMADA32` instruction, it multiplies the top 32-bit element in Rs1 with the bottom 32-bit element in Rs2 and + * then adds the result to the result of multiplying the bottom 32-bit element in Rs1 with the top 32-bit element in Rs2, then + * clip the q63 result to q31. + * + * **Operations**:\n + * ~~~ + * res = (q31_t)((((q63_t) Rd.w[0] << 32) + (q63_t)Rs1.w[0] s* Rs2.w[1] + (q63_t)Rs1.w[1] s* Rs2.w[0]) s>> 32); + * rd = res; + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_DMADA32(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dmada32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return (long)t; +} +/* ===== Inline Function End for DMADA32 ===== */ + +/* ===== Inline Function Start for DSMALBB ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMALBB (Signed Multiply Bottom Halfs & Add 64-bit) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMALBB Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 16-bit content of the 32-bit elements of a register with the 16-bit content of the corresponding 32-bit + * elements of another register and add the results with a 64-bit value of an even/odd pair of registers. The addition result + * is written back to the register-pair. + * * DSMALBB: rt pair + bottom*bottom (all 32-bit elements) + * + * **Description**:\n + * For the `DSMALBB` instruction, it multiplies the bottom 16-bit content of Rs1 with the bottom 16-bit content of Rs2.The + * multiplication results are added with the 64-bit value of Rd. The 64-bit addition result is written back to Rd. + * + * **Operations**:\n + * ~~~ + * Mres[0][31:0] = Rs1.W[0].H[0] * Rs2.W[0].H[0]; + * Mres[1][31:0] = Rs1.W[1].H[0] * Rs2.W[1].H[0]; + * Rd = Rd + SE64(Mres[0][31:0]) + SE64(Mres[1][31:0]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMALBB(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dsmalbb %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DSMALBB ===== */ + +/* ===== Inline Function Start for DSMALBT ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMALBT (Signed Multiply Bottom Half & Top Half & Add 64-bit) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMALBT Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 16-bit content of the 32-bit elements of a register with the 16-bit content of the corresponding 32-bit + * elements of another register and add the results with a 64-bit value of an even/odd pair of registers. The addition result + * is written back to the register-pair. + * * DSMALBT: rt pair + bottom*top (all 32-bit elements) + * + * **Description**:\n + * For the `DSMALBT` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 with the top 16-bit + * content of the 32-bit elements of Rs2. + * The multiplication results are added with the 64-bit value of Rd. The 64-bit addition result is written back to Rd. The + * 16-bit values of Rs1 and Rs2, and the 64-bit value of Rd are treated as signed integers + * + * **Operations**:\n + * ~~~ + * Mres[0][31:0] = Rs1.W[0].H[0] * Rs2.W[0].H[1]; + * Mres[1][31:0] = Rs1.W[1].H[0] * Rs2.W[1].H[1]; + * Rd = Rd + SE64(Mres[0][31:0]) + SE64(Mres[1][31:0]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMALBT(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dsmalbt %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DSMALBT ===== */ + +/* ===== Inline Function Start for DSMALTT ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMALTT (Signed Multiply Top Half & Add 64-bit) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMALTT Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 16-bit content of the 32-bit elements of a register with the 16-bit content of the corresponding 32-bit + * elements of another register and add the results with a 64-bit value of an even/odd pair of registers. The addition result + * is written back to the register-pair. + * * DSMALTT: DSMALTT rt pair + top*top (all 32-bit elements) + * + * **Description**:\n + * For the `DSMALTT` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 with the top 16-bit + * content of the 32-bit elements of Rs2. + * The multiplication results are added with the 64-bit value of Rd. The 64-bit addition result is written back to Rd. The + * 16-bit values of Rs1 and Rs2, and the 64-bit value of Rd are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * Mres[0][31:0] = Rs1.W[0].H[1] * Rs2.W[0].H[1]; + * Mres[1][31:0] = Rs1.W[1].H[1] * Rs2.W[1].H[1]; + * Rd = Rd + SE64(Mres[0][31:0]) + SE64(Mres[1][31:0]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMALTT(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dsmaltt %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DSMALTT ===== */ + +/* ===== Inline Function Start for DKMABB32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMABB32 (Saturating Signed Multiply Bottom Words & Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKMABB32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element in a register with the 32-bit element in another register and add the result to the content + * of 64-bit data in the third register. The addition result may besaturated and is written to the third register. + * * DKMABB32: rd + bottom*bottom + * + * **Description**:\n + * For the `DKMABB32` instruction, it multiplies the bottom 32-bit element in Rs1 with the bottom 32-bit element in Rs2 + * The multiplication result is added to the content of 64-bit data in Rd. If the addition result is beyond the Q63 number range + * (-2^63 <= Q63 <= 2^63-1), it is saturated to the range and the OV bit is set to 1. The result after saturation is written to Rd. + * The 32-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * res = Rd + (Rs1.W[0] * Rs2.W[0]); + * if (res > (2^63)-1) { + * res = (2^63)-1; + * OV = 1; + * } else if (res < -2^63) { + * res = -2^63; + * OV = 1; + * } + * Rd = res; + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DKMABB32(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmabb32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMABB32 ===== */ + +/* ===== Inline Function Start for DKMABT32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMABT32 (Saturating Signed Multiply Bottom & Top Words & Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKMABT32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element in a register with the 32-bit element in another register and add the result to the content + * of 64-bit data in the third register. The addition result may be saturated and is written to the third register. + * * DKMABT32: rd + bottom*top + * + * **Description**:\n + * For the `DKMABT32` instruction, it multiplies the bottom 32-bit element in Rs1 with the top 32-bit element in Rs2 + * The multiplication result is added to the content of 64-bit data in Rd. If the addition result is beyond the Q63 number range + * (-2^63 <= Q63 <= 2^63-1), it is saturated to the range and the OV bit is set to 1. The result after saturation is written to Rd. + * The 32-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * res = Rd + (Rs1.W[0] * Rs2.W[1]); + * if (res > (2^63)-1) { + * res = (2^63)-1; + * OV = 1; + * } else if (res < -2^63) { + * res = -2^63; + * OV = 1; + * } + * Rd = res; + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DKMABT32(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmabt32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMABT32 ===== */ + +/* ===== Inline Function Start for DKMATT32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMATT32 (Saturating Signed Multiply Bottom & Top Words & Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKMATT32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element in a register with the 32-bit element in another register and add the result to the content + * of 64-bit data in the third register. The addition result may be saturated and is written to the third register. + * * DKMATT32: rd + top*top + * + * **Description**:\n + * For the `DKMATT32` instruction, it multiplies the top 32-bit element in Rs1 with the top 32-bit element in Rs2 + * The multiplication result is added to the content of 64-bit data in Rd. If the addition result is beyond the Q63 number range + * (-2^63 <= Q63 <= 2^63-1), it is saturated to the range and the OV bit is set to 1. The result after saturation is written to Rd. + * The 32-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * res = Rd + (Rs1.W[1] * Rs2.W[1]); + * if (res > (2^63)-1) { + * res = (2^63)-1; + * OV = 1; + * } else if (res < -2^63) { + * res = -2^63; + * OV = 1; + * } + * Rd = res; + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE long long __RV_DKMATT32(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmatt32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMATT32 ===== */ +#endif /* __RISCV_XLEN == 32 */ + +#elif defined (__ICCRISCV__) + +#if __riscv_xlen == 32 +#include "iar_nds32_intrinsic.h" +#elif __riscv_xlen == 64 +#include "iar_nds64_intrinsic.h" +#else +#error "Unexpected RISC-V XLEN size." +#endif /* __riscv_xlen == 32 */ + +#pragma language=save +#pragma language=extended + +// Redefine those compatible instruction name supplied by IAR +#define __RV_CLROV __nds__clrov +#define __RV_RDOV __nds__rdov +#define __RV_ADD8 __nds__add8 +#define __RV_SUB8 __nds__sub8 +#define __RV_ADD16 __nds__add16 +#define __RV_SUB16 __nds__sub16 +#define __RV_ADD64 __nds__add64 +#define __RV_SUB64 __nds__sub64 +#define __RV_RADD8 __nds__radd8 +#define __RV_RSUB8 __nds__rsub8 +#define __RV_RADD16 __nds__radd16 +#define __RV_RSUB16 __nds__rsub16 +#define __RV_RADD64 __nds__radd64 +#define __RV_RSUB64 __nds__rsub64 +#define __RV_RADDW __nds__raddw +#define __RV_RSUBW __nds__rsubw +#define __RV_URADD8 __nds__uradd8 +#define __RV_URSUB8 __nds__ursub8 +#define __RV_URADD16 __nds__uradd16 +#define __RV_URSUB16 __nds__ursub16 +#define __RV_URADD64 __nds__uradd64 +#define __RV_URSUB64 __nds__ursub64 +#define __RV_URADDW __nds__uraddw +#define __RV_URSUBW __nds__ursubw +#define __RV_KADD8 __nds__kadd8 +#define __RV_KSUB8 __nds__ksub8 +#define __RV_KADD16 __nds__kadd16 +#define __RV_KSUB16 __nds__ksub16 +#define __RV_KADD64 __nds__kadd64 +#define __RV_KSUB64 __nds__ksub64 +#define __RV_KADDH __nds__kaddh +#define __RV_KSUBH __nds__ksubh +#define __RV_KADDW __nds__kaddw +#define __RV_KSUBW __nds__ksubw +#define __RV_UKADD8 __nds__ukadd8 +#define __RV_UKSUB8 __nds__uksub8 +#define __RV_UKADD16 __nds__ukadd16 +#define __RV_UKSUB16 __nds__uksub16 +#define __RV_UKADD64 __nds__ukadd64 +#define __RV_UKSUB64 __nds__uksub64 +#define __RV_UKADDH __nds__ukaddh +#define __RV_UKSUBH __nds__uksubh +#define __RV_UKADDW __nds__ukaddw +#define __RV_UKSUBW __nds__uksubw +#define __RV_CRAS16 __nds__cras16 +#define __RV_CRSA16 __nds__crsa16 +#define __RV_RCRAS16 __nds__rcras16 +#define __RV_RCRSA16 __nds__rcrsa16 +#define __RV_URCRAS16 __nds__urcras16 +#define __RV_URCRSA16 __nds__urcrsa16 +#define __RV_KCRAS16 __nds__kcras16 +#define __RV_KCRSA16 __nds__kcrsa16 +#define __RV_UKCRAS16 __nds__ukcras16 +#define __RV_UKCRSA16 __nds__ukcrsa16 +#define __RV_SRA8 __nds__sra8 +#define __RV_SRAI8 __nds__sra8 +#define __RV_SRA16 __nds__sra16 +#define __RV_SRAI16 __nds__sra16 +#define __RV_SRL8 __nds__srl8 +#define __RV_SRL16 __nds__srl16 +#define __RV_SLL8 __nds__sll8 +#define __RV_SLL16 __nds__sll16 +#define __RV_SRA_U __nds__sra_u +#define __RV_SRA8_U __nds__sra8_u +#define __RV_SRA16_U __nds__sra16_u +#define __RV_SRL8_U __nds__srl8_u +#define __RV_SRL16_U __nds__srl16_u +#define __RV_KSLL8 __nds__ksll8 +#define __RV_KSLL16 __nds__ksll16 +#define __RV_KSLLW __nds__ksllw +#define __RV_KSLRA8 __nds__kslra8 +#define __RV_KSLRA8_U __nds__kslra8_u +#define __RV_KSLRA16 __nds__kslra16 +#define __RV_KSLRA16_U __nds__kslra16_u +#define __RV_KSLRAW __nds__kslraw +#define __RV_KSLRAW_U __nds__kslraw_u +#define __RV_CMPEQ8 __nds__cmpeq8 +#define __RV_CMPEQ16 __nds__cmpeq16 +#define __RV_SCMPLE8 __nds__scmple8 +#define __RV_SCMPLE16 __nds__scmple16 +#define __RV_SCMPLT8 __nds__scmplt8 +#define __RV_SCMPLT16 __nds__scmplt16 +#define __RV_UCMPLE8 __nds__ucmple8 +#define __RV_UCMPLE16 __nds__ucmple16 +#define __RV_UCMPLT8 __nds__ucmplt8 +#define __RV_UCMPLT16 __nds__ucmplt16 +#define __RV_SMUL8 __nds__smul8 +#define __RV_UMUL8 __nds__umul8 +#define __RV_SMUL16 __nds__smul16 +#define __RV_UMUL16 __nds__umul16 +#define __RV_SMULX8 __nds__smulx8 +#define __RV_UMULX8 __nds__umulx8 +#define __RV_SMULX16 __nds__smulx16 +#define __RV_UMULX16 __nds__umulx16 +#define __RV_KHM8 __nds__khm8 +#define __RV_KHMX8 __nds__khmx8 +#define __RV_KHM16 __nds__khm16 +#define __RV_KHMX16 __nds__khmx16 +#define __RV_MULR64 __nds__mulr64 +#define __RV_MULSR64 __nds__mulsr64 +#define __RV_SMMUL __nds__smmul +#define __RV_SMMUL_U __nds__smmul_u +#define __RV_WEXT __nds__wext +#define __RV_SUNPKD810 __nds__sunpkd810 +#define __RV_SUNPKD820 __nds__sunpkd820 +#define __RV_SUNPKD830 __nds__sunpkd830 +#define __RV_SUNPKD831 __nds__sunpkd831 +#define __RV_SUNPKD832 __nds__sunpkd832 +#define __RV_ZUNPKD810 __nds__zunpkd810 +#define __RV_ZUNPKD820 __nds__zunpkd820 +#define __RV_ZUNPKD830 __nds__zunpkd830 +#define __RV_ZUNPKD831 __nds__zunpkd831 +#define __RV_ZUNPKD832 __nds__zunpkd832 +#define __RV_PKBB16 __nds__pkbb16 +#define __RV_PKBT16 __nds__pkbt16 +#define __RV_PKTT16 __nds__pktt16 +#define __RV_PKTB16 __nds__pktb16 +#define __RV_KMMAC __nds__kmmac +#define __RV_KMMAC_U __nds__kmmac_u +#define __RV_KMMSB __nds__kmmsb +#define __RV_KMMSB_U __nds__kmmsb_u +#define __RV_KWMMUL __nds__kwmmul +#define __RV_KWMMUL_U __nds__kwmmul_u +#define __RV_SMMWB __nds__smmwb +#define __RV_SMMWB_U __nds__smmwb_u +#define __RV_SMMWT __nds__smmwt +#define __RV_SMMWT_U __nds__smmwt_u +#define __RV_KMMAWB __nds__kmmawb +#define __RV_KMMAWB_U __nds__kmmawb_u +#define __RV_KMMAWT __nds__kmmawt +#define __RV_KMMAWT_U __nds__kmmawt_u +#define __RV_KMMWB2 __nds__kmmwb2 +#define __RV_KMMWB2_U __nds__kmmwb2_u +#define __RV_KMMWT2 __nds__kmmwt2 +#define __RV_KMMWT2_U __nds__kmmwt2_u +#define __RV_KMMAWB2 __nds__kmmawb2 +#define __RV_KMMAWB2_U __nds__kmmawb2_u +#define __RV_KMMAWT2 __nds__kmmawt2 +#define __RV_KMMAWT2_U __nds__kmmawt2_u +#define __RV_SMBB16 __nds__smbb16 +#define __RV_SMBT16 __nds__smbt16 +#define __RV_SMTT16 __nds__smtt16 +#define __RV_KMDA __nds__kmda +#define __RV_KMXDA __nds__kmxda +#define __RV_SMDS __nds__smds +#define __RV_SMDRS __nds__smdrs +#define __RV_SMXDS __nds__smxds +#define __RV_KMABB __nds__kmabb +#define __RV_KMABT __nds__kmabt +#define __RV_KMATT __nds__kmatt +#define __RV_KMADA __nds__kmada +#define __RV_KMAXDA __nds__kmaxda +#define __RV_KMADS __nds__kmads +#define __RV_KMADRS __nds__kmadrs +#define __RV_KMAXDS __nds__kmaxds +#define __RV_KMSDA __nds__kmsda +#define __RV_KMSXDA __nds__kmsxda +#define __RV_SMAL __nds__smal +#define __RV_SMAQA __nds__smaqa +#define __RV_UMAQA __nds__umaqa +#define __RV_SMAQA_SU __nds__smaqa_su +#define __RV_SMAR64 __nds__smar64 +#define __RV_SMSR64 __nds__smsr64 +#define __RV_UMAR64 __nds__umar64 +#define __RV_UMSR64 __nds__umsr64 +#define __RV_KMAR64 __nds__kmar64 +#define __RV_KMSR64 __nds__kmsr64 +#define __RV_UKMAR64 __nds__ukmar64 +#define __RV_UKMSR64 __nds__ukmsr64 +#define __RV_SMALBB __nds__smalbb +#define __RV_SMALBT __nds__smalbt +#define __RV_SMALTT __nds__smaltt +#define __RV_SMALDA __nds__smalda +#define __RV_SMALXDA __nds__smalxda +#define __RV_SMALDS __nds__smalds +#define __RV_SMALDRS __nds__smaldrs +#define __RV_SMALXDS __nds__smalxds +#define __RV_SMSLDA __nds__smslda +#define __RV_SMSLXDA __nds__smslxda +#define __RV_MINW __nds__minw +#define __RV_MAXW __nds__maxw +#define __RV_SMIN8 __nds__smin8 +#define __RV_SMAX8 __nds__smax8 +#define __RV_SMIN16 __nds__smin16 +#define __RV_SMAX16 __nds__smax16 +#define __RV_UMIN8 __nds__umin8 +#define __RV_UMAX8 __nds__umax8 +#define __RV_UMIN16 __nds__umin16 +#define __RV_UMAX16 __nds__umax16 +#define __RV_KABS8 __nds__kabs8 +#define __RV_KABS16 __nds__kabs16 +#define __RV_KABSW __nds__kabsw +#define __RV_SCLIP8 __nds__sclip8 +#define __RV_SCLIP16 __nds__sclip16 +#define __RV_SCLIP32 __nds__sclip32 +#define __RV_UCLIP8 __nds__uclip8 +#define __RV_UCLIP16 __nds__uclip16 +#define __RV_UCLIP32 __nds__uclip32 +#define __RV_CLO8 __nds__clo8 +#define __RV_CLO16 __nds__clo16 +#define __RV_CLO32 __nds__clo32 +#define __RV_CLZ8 __nds__clz8 +#define __RV_CLZ16 __nds__clz16 +#define __RV_CLZ32 __nds__clz32 +#define __RV_CLRS8 __nds__clrs8 +#define __RV_CLRS16 __nds__clrs16 +#define __RV_CLRS32 __nds__clrs32 +#define __RV_SWAP8 __nds__swap8 +#define __RV_SWAP16 __nds__swap16 +#define __RV_KHMBB __nds__khmbb +#define __RV_KHMBT __nds__khmbt +#define __RV_KHMTT __nds__khmtt +#define __RV_KDMBB __nds__kdmbb +#define __RV_KDMBT __nds__kdmbt +#define __RV_KDMTT __nds__kdmtt +#define __RV_KDMABB __nds__kdmabb +#define __RV_KDMABT __nds__kdmabt +#define __RV_KDMATT __nds__kdmatt +#define __RV_MADDR32 __nds__maddr32 +#define __RV_MSUBR32 __nds__msubr32 +#define __RV_PBSAD __nds__pbsad +#define __RV_PBSADA __nds__pbsada +#define __RV_AVE __nds__ave +#define __RV_BITREV __nds__bitrev +#define __RV_INSB __nds__insb + +#if (__riscv_xlen == 64) +#define __RV_ADD32 __nds__add32 +#define __RV_SUB32 __nds__sub32 +#define __RV_RADD32 __nds__radd32 +#define __RV_RSUB32 __nds__rsub32 +#define __RV_URADD32 __nds__uradd32 +#define __RV_URSUB32 __nds__ursub32 +#define __RV_KADD32 __nds__kadd32 +#define __RV_KSUB32 __nds__ksub32 +#define __RV_UKADD32 __nds__ukadd32 +#define __RV_UKSUB32 __nds__uksub32 +#define __RV_CRAS32 __nds__cras32 +#define __RV_CRSA32 __nds__crsa32 +#define __RV_RCRAS32 __nds__rcras32 +#define __RV_RCRSA32 __nds__rcrsa32 +#define __RV_URCRAS32 __nds__urcras32 +#define __RV_URCRSA32 __nds__urcrsa32 +#define __RV_KCRAS32 __nds__kcras32 +#define __RV_KCRSA32 __nds__kcrsa32 +#define __RV_UKCRAS32 __nds__ukcras32 +#define __RV_UKCRSA32 __nds__ukcrsa32 +#define __RV_SRA32 __nds__sra32 +#define __RV_SRAI32 __nds__sra32 +#define __RV_SRL32 __nds__srl32 +#define __RV_SLL32 __nds__sll32 +#define __RV_SLLI32 __nds__sll32 +#define __RV_SRAW_U __nds__sraw_u +#define __RV_SRA32_U __nds__sra32_u +#define __RV_SRL32_U __nds__srl32_u +#define __RV_KSLL32 __nds__ksll32 +#define __RV_KSLRA32 __nds__kslra32 +#define __RV_KSLRA32_U __nds__kslra32_u +#define __RV_SMBB32 __nds__smbb32 +#define __RV_SMBT32 __nds__smbt32 +#define __RV_SMTT32 __nds__smtt32 +#define __RV_PKBB32 __nds__pkbb32 +#define __RV_PKBT32 __nds__pkbt32 +#define __RV_PKTT32 __nds__pktt32 +#define __RV_PKTB32 __nds__pktb32 +#define __RV_SMIN32 __nds__smin32 +#define __RV_SMAX32 __nds__smax32 +#define __RV_UMIN32 __nds__umin32 +#define __RV_UMAX32 __nds__umax32 +#define __RV_KABS32 __nds__kabs32 +#define __RV_KHMBB16 __nds__khmbb16 +#define __RV_KHMBT16 __nds__khmbt16 +#define __RV_KHMTT16 __nds__khmtt16 +#define __RV_KDMBB16 __nds__kdmbb16 +#define __RV_KDMBT16 __nds__kdmbt16 +#define __RV_KDMTT16 __nds__kdmtt16 +#define __RV_KDMABB16 __nds__kdmabb16 +#define __RV_KDMABT16 __nds__kdmabt16 +#define __RV_KDMATT16 __nds__kdmatt16 +#define __RV_KMABB32 __nds__kmabb32 +#define __RV_KMABT32 __nds__kmabt32 +#define __RV_KMATT32 __nds__kmatt32 +#define __RV_KMDA32 __nds__kmda32 +#define __RV_KMXDA32 __nds__kmxda32 +#define __RV_KMADA32 __nds__kmada32 +#define __RV_KMAXDA32 __nds__kmaxda32 +#define __RV_KMADS32 __nds__kmads32 +#define __RV_KMADRS32 __nds__kmadrs32 +#define __RV_KMAXDS32 __nds__kmaxds32 +#define __RV_KMSDA32 __nds__kmsda32 +#define __RV_KMSXDA32 __nds__kmsxda32 +#define __RV_SMDS32 __nds__smds32 +#define __RV_SMDRS32 __nds__smdrs32 +#define __RV_SMXDS32 __nds__smxds32 +#endif /* __riscv_xlen == 64 */ + +// For now, the P-extention version of IAR IDE is 0.5.0, but Nuclei's supports 0.5.4 +// so Nuclei supplies a workround to add custom instructions of those not natively +// supported by the IAR Assembler. Note that __RV_BPICK remains to be implemented in future. +// And we only implement Xxldsp Nuclei custom instruction set, bpick not implemented, expdxx +// implemented in c, not via .insn variant + +#pragma inline=forced_no_body +unsigned long __RV_STAS16(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x7A, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_RSTAS16(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x5A, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_KSTAS16(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x62, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_URSTAS16(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x6A, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_UKSTAS16(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x72, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_STSA16(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x7B, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_RSTSA16(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x5B, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_KSTSA16(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x63, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_URSTSA16(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x6B, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_UKSTSA16(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x73, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +// #pragma inline=forced_no_body +// unsigned long __RV_BPICK(unsigned long a, unsigned long b, unsigned long c) { + // TODO: remains to be done +// } + +// RV64 only +#pragma inline=forced_no_body +unsigned long __RV_STAS32(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x78, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_RSTAS32(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x58, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_KSTAS32(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x60, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_URSTAS32(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x68, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_UKSTAS32(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x70, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_STSA32(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x79, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_RSTSA32(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x59, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_KSTSA32(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x61, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_URSTSA32(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x69, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_UKSTSA32(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x71, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_EXPD80(unsigned long a) +{ + return __EXPD_BYTE((uint8_t)(a & 0xff)); +} + +#pragma inline=forced_no_body +unsigned long __RV_EXPD81(unsigned long a) +{ + return __EXPD_BYTE((uint8_t)((a >> 8) & 0xff)); +} + +#pragma inline=forced_no_body +unsigned long __RV_EXPD82(unsigned long a) +{ + return __EXPD_BYTE((uint8_t)((a >> 16) & 0xff)); +} + +#pragma inline=forced_no_body +unsigned long __RV_EXPD83(unsigned long a) +{ + return __EXPD_BYTE((uint8_t)((a >> 24) & 0xff)); +} + +#if __RISCV_XLEN == 64 +// RV64 only +#pragma inline=forced_no_body +unsigned long __RV_EXPD84(unsigned long a) +{ + return __EXPD_BYTE((uint8_t)((a >> 32) & 0xff)); +} + +#pragma inline=forced_no_body +unsigned long __RV_EXPD85(unsigned long a) +{ + return __EXPD_BYTE((uint8_t)((a >> 40) & 0xff)); +} + +#pragma inline=forced_no_body +unsigned long __RV_EXPD86(unsigned long a) +{ + return __EXPD_BYTE((uint8_t)((a >> 48) & 0xff)); +} + +#pragma inline=forced_no_body +unsigned long __RV_EXPD87(unsigned long a) +{ + return __EXPD_BYTE((uint8_t)((a >> 56) & 0xff)); +} +#endif +#pragma language=restore + +#else + #error Unknown compiler +#endif /* __ICCRISCV__ */ + + +/* XXXXX ARM Compatiable SIMD API XXXXX */ +/** \brief Q setting quad 8-bit saturating addition. */ +#define __QADD8(x, y) __RV_KADD8(x, y) +/** \brief Q setting quad 8-bit saturating subtract. */ +#define __QSUB8(x, y) __RV_KSUB8((x), (y)) +/** \brief Q setting dual 16-bit saturating addition. */ +#define __QADD16(x, y) __RV_KADD16((x), (y)) +/** \brief Dual 16-bit signed addition with halved results. */ +#define __SHADD16(x, y) __RV_RADD16((x), (y)) +/** \brief Q setting dual 16-bit saturating subtract. */ +#define __QSUB16(x, y) __RV_KSUB16((x), (y)) +/** \brief Dual 16-bit signed subtraction with halved results. */ +#define __SHSUB16(x, y) __RV_RSUB16((x), (y)) +/** \brief Q setting dual 16-bit add and subtract with exchange. */ +#define __QASX(x, y) __RV_KCRAS16((x), (y)) +/** \brief Dual 16-bit signed addition and subtraction with halved results.*/ +#define __SHASX(x, y) __RV_RCRAS16((x), (y)) +/** \brief Q setting dual 16-bit subtract and add with exchange. */ +#define __QSAX(x, y) __RV_KCRSA16((x), (y)) +/** \brief Dual 16-bit signed subtraction and addition with halved results.*/ +#define __SHSAX(x, y) __RV_RCRSA16((x), (y)) +/** \brief Dual 16-bit signed multiply with exchange returning difference. */ +#define __SMUSDX(x, y) __RV_SMXDS((y), (x)) +/** \brief Q setting sum of dual 16-bit signed multiply with exchange. */ +__STATIC_FORCEINLINE long __SMUADX (unsigned long op1, unsigned long op2) +{ + return __RV_KMXDA(op1, op2); +} +/** \brief Q setting saturating add. */ +#define __QADD(x, y) __RV_KADDW((x), (y)) +/** \brief Q setting saturating subtract. */ +#define __QSUB(x, y) __RV_KSUBW((x), (y)) +/** \brief Q setting dual 16-bit signed multiply with single 32-bit accumulator. */ +__STATIC_FORCEINLINE long __SMLAD(unsigned long op1, unsigned long op2, long acc) +{ + return __RV_KMADA(acc, op1, op2); +} +/** \brief Q setting pre-exchanged dual 16-bit signed multiply with single 32-bit accumulator. */ +__STATIC_FORCEINLINE long __SMLADX(unsigned long op1, unsigned long op2, long acc) +{ + return __RV_KMAXDA(acc, op1, op2); +} +/** \brief Q setting dual 16-bit signed multiply with exchange subtract with 32-bit accumulate. */ +__STATIC_FORCEINLINE long __SMLSDX(unsigned long op1, unsigned long op2, long acc) +{ + return (acc - __RV_SMXDS(op1, op2)); +} +/** \brief Dual 16-bit signed multiply with single 64-bit accumulator. */ +__STATIC_FORCEINLINE long long __SMLALD(unsigned long op1, unsigned long op2, long long acc) +{ + return __RV_SMALDA(acc, op1, op2); +} +/** \brief Dual 16-bit signed multiply with exchange with single 64-bit accumulator. */ +__STATIC_FORCEINLINE long long __SMLALDX(unsigned long op1, unsigned long op2, long long acc) +{ + return __RV_SMALXDA(acc, op1, op2); +} +/** \brief Q setting sum of dual 16-bit signed multiply. */ +__STATIC_FORCEINLINE long __SMUAD(unsigned long op1, unsigned long op2) +{ + return __RV_KMDA(op1, op2); +} +/** \brief Dual 16-bit signed multiply returning difference. */ +__STATIC_FORCEINLINE long __SMUSD(unsigned long op1, unsigned long op2) +{ + return __RV_SMDRS(op1, op2); +} +/** \brief Dual extract 8-bits and sign extend each to 16-bits. */ +#define __SXTB16(x) __RV_SUNPKD820(x) +/** \brief Dual extracted 8-bit to 16-bit signed addition. TODO Need test */ +__STATIC_FORCEINLINE unsigned long __SXTAB16(unsigned long op1, unsigned long op2) +{ + return __RV_ADD16(op1, __RV_SUNPKD820(op2)); +} +#define __SXTAB16_RORn(ARG1, ARG2, ROTATE) __SXTAB16(ARG1, __ROR(ARG2, ROTATE)) + +/** \brief 32-bit signed multiply with 32-bit truncated accumulator. */ +__STATIC_FORCEINLINE long __SMMLA(long op1, long op2, long acc) +{ + long mul; + mul = __RV_SMMUL(op1, op2); + return (acc + mul); +} +#define __DKHM8 __RV_DKHM8 +#define __DKHM16 __RV_DKHM16 +#define __DKSUB16 __RV_DKSUB16 +#define __SMAQA __RV_SMAQA +#define __MULSR64 __RV_MULSR64 +#define __DQADD8 __RV_DKADD8 +#define __DQSUB8 __RV_DKSUB8 +#define __DKADD16 __RV_DKADD16 +#define __PKBB16 __RV_PKBB16 +#define __DKSLRA16 __RV_DKSLRA16 +#define __DKSLRA8 __RV_DKSLRA8 +#define __KABSW __RV_KABSW +#define __DKABS8 __RV_DKABS8 +#define __DKABS16 __RV_DKABS16 +#define __SMALDA __RV_SMALDA +#define __SMSLDA __RV_SMSLDA +#define __SMALBB __RV_SMALBB +#define __SUB64 __RV_SUB64 +#define __ADD64 __RV_ADD64 +#define __SMBB16 __RV_SMBB16 +#define __SMBT16 __RV_SMBT16 +#define __SMTT16 __RV_SMTT16 +#define __EXPD80 __RV_EXPD80 +#define __SMAX8 __RV_SMAX8 +#define __SMAX16 __RV_SMAX16 +#define __PKTT16 __RV_PKTT16 +#define __KADD16 __RV_KADD16 +#define __SADD16 __RV_ADD16 +#define __SSUB8 __RV_KSUB8 +#define __SADD8 __RV_KADD8 +#define __USAT16 __RV_UCLIP16 +#define __SMALTT __RV_SMALTT + +/** \brief Halfword packing instruction. Combines bits[15:0] of val1 with bits[31:16] of val2 levitated with the val3. */ +#define __PKHBT(ARG1, ARG2, ARG3) ((ARG3 == 0) ? __RV_PKTB16(ARG2, ARG1) : \ + (ARG3 == 16) ? __RV_PKBB16(ARG2, ARG1) : \ + (((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL))) + +/** \brief Halfword packing instruction. Combines bits[31:16] of val1 with bits[15:0] of val2 right-shifted with the val3. */ +#define __PKHTB(ARG1, ARG2, ARG3) ((ARG3 == 0) ? __RV_PKTB16(ARG1, ARG2) : \ + (ARG3 == 16) ? __RV_PKTT16(ARG1, ARG2) : \ + (((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL))) + +#if __RISCV_XLEN == 64 +/** \brief Halfword packing instruction. Combines bits[15:0] of val1 with bits[31:16] of val2 levitated with the val3, + and also combines the [47:32] of val1 with bits[63:48] of val2 with the val3, finally pack the two new 32-bits to 64-bit. */ +#define __PKHBT64(ARG1, ARG2, ARG3) ((ARG3 == 0) ? __RV_PKTB16(ARG2, ARG1) : \ + (ARG3 == 16) ? __RV_PKBB16(ARG2, ARG1) : \ + ((int64_t)((((uint32_t)((uint64_t)ARG1 >> 32)) & 0x0000FFFFUL) | \ + ((((uint32_t)((uint64_t)ARG2 >> 32)) << (ARG3)) & 0xFFFF0000UL)) << 32) | \ + ((int64_t)(((((uint32_t)(ARG1))) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL)) & 0xFFFFFFFFUL)) + +/** \brief Halfword packing instruction. Combines bits[31:16] of val1 with bits[15:0] of val2 right-shifted with the val3, + and also combines bits [63:48] of val1 with bits [47:32] of val2 with the val3, finally pack the two new 32bits to 64bits. */ +#define __PKHTB64(ARG1, ARG2, ARG3) ((ARG3 == 0) ? __RV_PKTB16(ARG1, ARG2) : \ + (ARG3 == 16) ? __RV_PKTT16(ARG1, ARG2) : \ + ((uint64_t)(((uint32_t)((uint64_t)ARG1 >> 32) & 0xFFFF0000UL) | \ + ((((uint32_t)((uint64_t)ARG2 >> 32)) >> (ARG3)) & 0x0000FFFFUL)) << 32) | \ + ((uint64_t)(((uint32_t)(ARG1) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL)) & 0xFFFFFFFFUL)) +#else +/** \brief Halfword packing instruction. Combines bits[15:0] of val1 with bits[31:16] of val2 levitated with the val3, + and also combines the [47:32] of val1 with bits[63:48] of val2 with the val3, finally pack the two new 32-bits to 64-bit. */ +#define __PKHBT64(ARG1, ARG2, ARG3) ((ARG3 == 0) ? __RV_DPKTB16(ARG2, ARG1) : \ + (ARG3 == 16) ? __RV_DPKBB16(ARG2, ARG1) : \ + ((int64_t)((((uint32_t)((uint64_t)ARG1 >> 32)) & 0x0000FFFFUL) | \ + ((((uint32_t)((uint64_t)ARG2 >> 32)) << (ARG3)) & 0xFFFF0000UL)) << 32) | \ + ((int64_t)(((((uint32_t)(ARG1))) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL)) & 0xFFFFFFFFUL)) + +/** \brief Halfword packing instruction. Combines bits[31:16] of val1 with bits[15:0] of val2 right-shifted with the val3, + and also combines bits [63:48] of val1 with bits [47:32] of val2 with the val3, finally pack the two new 32bits to 64bits. */ +#define __PKHTB64(ARG1, ARG2, ARG3) ((ARG3 == 0) ? __RV_DPKTB16(ARG1, ARG2) : \ + (ARG3 == 16) ? __RV_DPKTT16(ARG1, ARG2) : \ + ((uint64_t)(((uint32_t)((uint64_t)ARG1 >> 32) & 0xFFFF0000UL) | \ + ((((uint32_t)((uint64_t)ARG2 >> 32)) >> (ARG3)) & 0x0000FFFFUL)) << 32) | \ + ((uint64_t)(((uint32_t)(ARG1) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL)) & 0xFFFFFFFFUL)) +#endif /* __RISCV_XLEN == 64 */ + +/** first rotate then extract. This is more suitable for arm compiler for it can rotate and extract in one command*/ +#define __SXTB16_RORn(ARG1, ARG2) __RV_SUNPKD820(__ROR(ARG1, ARG2)) + +#endif /* defined(__DSP_PRESENT) && (__DSP_PRESENT == 1) */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_FEATURE_DSP__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_eclic.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_eclic.h new file mode 100644 index 0000000..c898caf --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_eclic.h @@ -0,0 +1,1374 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __CORE_FEATURE_ECLIC__ +#define __CORE_FEATURE_ECLIC__ +/*! + * @file core_feature_eclic.h + * @brief ECLIC feature API header file for Nuclei N/NX Core + */ +/* + * ECLIC Feature Configuration Macro: + * 1. __ECLIC_PRESENT: Define whether Enhanced Core Local Interrupt Controller (ECLIC) Unit is present or not + * * 0: Not present + * * 1: Present + * 2. __ECLIC_BASEADDR: Base address of the ECLIC unit. + * 3. __ECLIC_INTCTLBITS: Optional, if defined, it should set to the value of ECLIC_GetInfoCtlbits(), define the number of hardware bits are actually implemented in the clicintctl registers. + * Valid number is 1 - 8. + * 4. __ECLIC_INTNUM: Define the external interrupt number of ECLIC Unit + * 5. __TEE_PRESENT: Define whether TEE feature present, if present, ECLIC will present with S-Mode ECLIC feature + * * 0: Not present + * * 1: Present + * + */ +#ifdef __cplusplus +extern "C" { +#endif + +#include "core_feature_base.h" + +#if defined(__ECLIC_PRESENT) && (__ECLIC_PRESENT == 1) +/** + * \defgroup NMSIS_Core_ECLIC_Registers Register Define and Type Definitions Of ECLIC + * \ingroup NMSIS_Core_Registers + * \brief Type definitions and defines for eclic registers. + * + * @{ + */ + +/** + * \brief Union type to access CLICFG configure register. + */ +typedef union +{ + struct { + __IM uint8_t _reserved0:1; + __IOM uint8_t nlbits:4; /*!< bit: 1..4 specified the bit-width of level and priority in the register clicintctl[i] */ + __IM uint8_t nmbits:2; /*!< bit: 5..6 ties to 1 if supervisor-level interrupt supported, or else it's reserved */ + __IM uint8_t _reserved1:1; + } b; /*!< Structure used for bit access */ + uint8_t w; /*!< Type used for byte access */ +} CLICCFG_Type; + +/** + * \brief Union type to access CLICINFO information register. + */ +typedef union { + struct { + __IM uint32_t numint:13; /*!< bit: 0..12 number of maximum interrupt inputs supported */ + __IM uint32_t version:8; /*!< bit: 13..20 20:17 for architecture version,16:13 for implementation version */ + __IM uint32_t intctlbits:4; /*!< bit: 21..24 specifies how many hardware bits are actually implemented in the clicintctl registers */ + __IM uint32_t _reserved0:7; /*!< bit: 25..31 Reserved */ + } b; /*!< Structure used for bit access */ + __IM uint32_t w; /*!< Type used for word access */ +} CLICINFO_Type; + +/** + * \brief Access to the machine mode register structure of INTIP, INTIE, INTATTR, INTCTL. + */ +typedef struct { + __IOM uint8_t INTIP; /*!< Offset: 0x000 (R/W) Interrupt set pending register */ + __IOM uint8_t INTIE; /*!< Offset: 0x001 (R/W) Interrupt set enable register */ + __IOM uint8_t INTATTR; /*!< Offset: 0x002 (R/W) Interrupt set attributes register */ + __IOM uint8_t INTCTRL; /*!< Offset: 0x003 (R/W) Interrupt configure register */ +} CLIC_CTRL_Type; + +/** + * \brief Access to the structure of ECLIC Memory Map, which is compatible with TEE. + */ +typedef struct { + __IOM uint8_t CFG; /*!< Offset: 0x000 (R/W) CLIC configuration register */ + __IM uint8_t RESERVED0[3]; + __IM uint32_t INFO; /*!< Offset: 0x004 (R/ ) CLIC information register */ + __IM uint8_t RESERVED1; +#if defined(__TEE_PRESENT) && (__TEE_PRESENT == 1) + __IOM uint8_t STH; /*!< Offset: 0x009 (R/W ) CLIC supervisor mode interrupt-level threshold */ +#else + __IM uint8_t RESERVED2; +#endif + __IM uint8_t RESERVED3; + __IOM uint8_t MTH; /*!< Offset: 0x00B(R/W) CLIC machine mode interrupt-level threshold */ + uint32_t RESERVED4[1021]; +#if defined(__TEE_PRESENT) && (__TEE_PRESENT == 1) + CLIC_CTRL_Type CTRL[1024]; /*!< Offset: 0x1000 (R/W) CLIC machine mode register structure for INTIP, INTIE, INTATTR, INTCTL */ + __IM uint32_t RESERVED5[2]; + __IM uint8_t RESERVED6; + __IOM uint8_t SSTH; /*!< Offset: 0x2009 (R) CLIC supervisor mode threshold register, which is a mirror to mintthresh.sth */ + __IM uint8_t RESERVED7; + __IM uint8_t RESERVED8; + __IM uint32_t RESERVED9[1021]; + CLIC_CTRL_Type SCTRL[1024]; /*!< Offset: 0x3000 (R/W) CLIC supervisor mode register structure for INTIP, INTIE, INTATTR, INTCTL */ +#else + CLIC_CTRL_Type CTRL[4096]; /*!< Offset: 0x1000 (R/W) CLIC machine mode register structure for INTIP, INTIE, INTATTR, INTCTL */ +#endif +} CLIC_Type; + +#define CLIC_CLICCFG_NLBIT_Pos 1U /*!< CLIC CLICCFG: NLBIT Position */ +#define CLIC_CLICCFG_NLBIT_Msk (0xFUL << CLIC_CLICCFG_NLBIT_Pos) /*!< CLIC CLICCFG: NLBIT Mask */ + +#define CLIC_CLICINFO_CTLBIT_Pos 21U /*!< CLIC INTINFO: CLICINTCTLBITS Position */ +#define CLIC_CLICINFO_CTLBIT_Msk (0xFUL << CLIC_CLICINFO_CTLBIT_Pos) /*!< CLIC INTINFO: CLICINTCTLBITS Mask */ + +#define CLIC_CLICINFO_VER_Pos 13U /*!< CLIC CLICINFO: VERSION Position */ +#define CLIC_CLICINFO_VER_Msk (0xFFUL << CLIC_CLICINFO_VER_Pos) /*!< CLIC CLICINFO: VERSION Mask */ + +#define CLIC_CLICINFO_NUM_Pos 0U /*!< CLIC CLICINFO: NUM Position */ +#define CLIC_CLICINFO_NUM_Msk (0x1FFFUL << CLIC_CLICINFO_NUM_Pos) /*!< CLIC CLICINFO: NUM Mask */ + +#define CLIC_INTIP_IP_Pos 0U /*!< CLIC INTIP: IP Position */ +#define CLIC_INTIP_IP_Msk (0x1UL << CLIC_INTIP_IP_Pos) /*!< CLIC INTIP: IP Mask */ + +#define CLIC_INTIE_IE_Pos 0U /*!< CLIC INTIE: IE Position */ +#define CLIC_INTIE_IE_Msk (0x1UL << CLIC_INTIE_IE_Pos) /*!< CLIC INTIE: IE Mask */ + +#if defined(__TEE_PRESENT) && (__TEE_PRESENT == 1) +#define CLIC_INTATTR_MODE_Pos 6U /*!< CLIC INTATTA: Mode Position */ +#define CLIC_INTATTR_MODE_Msk (0x3U << CLIC_INTATTR_MODE_Pos) /*!< CLIC INTATTA: Mode Mask */ +#endif + +#define CLIC_INTATTR_TRIG_Pos 1U /*!< CLIC INTATTR: TRIG Position */ +#define CLIC_INTATTR_TRIG_Msk (0x3UL << CLIC_INTATTR_TRIG_Pos) /*!< CLIC INTATTR: TRIG Mask */ + +#define CLIC_INTATTR_SHV_Pos 0U /*!< CLIC INTATTR: SHV Position */ +#define CLIC_INTATTR_SHV_Msk (0x1UL << CLIC_INTATTR_SHV_Pos) /*!< CLIC INTATTR: SHV Mask */ + +#define ECLIC_MAX_NLBITS 8U /*!< Max nlbit of the CLICINTCTLBITS */ +#define ECLIC_MODE_MTVEC_Msk 3U /*!< ECLIC Mode mask for MTVT CSR Register */ + +#define ECLIC_NON_VECTOR_INTERRUPT 0x0 /*!< Non-Vector Interrupt Mode of ECLIC */ +#define ECLIC_VECTOR_INTERRUPT 0x1 /*!< Vector Interrupt Mode of ECLIC */ + +/**\brief ECLIC Trigger Enum for different Trigger Type */ +typedef enum ECLIC_TRIGGER { + ECLIC_LEVEL_TRIGGER = 0x0, /*!< Level Triggerred, trig[0] = 0 */ + ECLIC_POSTIVE_EDGE_TRIGGER = 0x1, /*!< Postive/Rising Edge Triggered, trig[0] = 1, trig[1] = 0 */ + ECLIC_NEGTIVE_EDGE_TRIGGER = 0x3, /*!< Negtive/Falling Edge Triggered, trig[0] = 1, trig[1] = 1 */ + ECLIC_MAX_TRIGGER = 0x3 /*!< MAX Supported Trigger Mode */ +} ECLIC_TRIGGER_Type; + +#ifndef __ECLIC_BASEADDR +/* Base address of ECLIC(__ECLIC_BASEADDR) should be defined in */ +#error "__ECLIC_BASEADDR is not defined, please check!" +#endif + +#ifndef __ECLIC_INTCTLBITS +/* Define __ECLIC_INTCTLBITS to get via ECLIC->INFO if not defined */ +#define __ECLIC_INTCTLBITS (__ECLIC_GetInfoCtlbits()) +#endif + +/* ECLIC Memory mapping of Device */ +#define ECLIC_BASE __ECLIC_BASEADDR /*!< ECLIC Base Address */ +#define ECLIC ((CLIC_Type *) ECLIC_BASE) /*!< CLIC configuration struct */ + +/** @} */ /* end of group NMSIS_Core_ECLIC_Registers */ + +/* ########################## ECLIC functions #################################### */ +/** + * \defgroup NMSIS_Core_IntExc Interrupts and Exceptions + * \brief Functions that manage interrupts and exceptions via the ECLIC. + * + * @{ + */ + +/** + * \brief Definition of IRQn numbers + * \details + * The core interrupt enumeration names for IRQn values are defined in the file .h. + * - Interrupt ID(IRQn) from 0 to 18 are reserved for core internal interrupts. + * - Interrupt ID(IRQn) start from 19 represent device-specific external interrupts. + * - The first device-specific interrupt has the IRQn value 19. + * + * The table below describes the core interrupt names and their availability in various Nuclei Cores. + */ +/* The following enum IRQn definition in this file + * is only used for doxygen documentation generation, + * The .h is the real file to define it by vendor + */ +#if defined(__ONLY_FOR_DOXYGEN_DOCUMENT_GENERATION__) +typedef enum IRQn { + /* ========= Nuclei N/NX Core Specific Interrupt Numbers =========== */ + /* Core Internal Interrupt IRQn definitions */ + Reserved0_IRQn = 0, /*!< Internal reserved */ + Reserved1_IRQn = 1, /*!< Internal reserved */ + Reserved2_IRQn = 2, /*!< Internal reserved */ + SysTimerSW_IRQn = 3, /*!< System Timer SW interrupt */ + Reserved3_IRQn = 4, /*!< Internal reserved */ + Reserved4_IRQn = 5, /*!< Internal reserved */ + Reserved5_IRQn = 6, /*!< Internal reserved */ + SysTimer_IRQn = 7, /*!< System Timer Interrupt */ + Reserved6_IRQn = 8, /*!< Internal reserved */ + Reserved7_IRQn = 9, /*!< Internal reserved */ + Reserved8_IRQn = 10, /*!< Internal reserved */ + Reserved9_IRQn = 11, /*!< Internal reserved */ + Reserved10_IRQn = 12, /*!< Internal reserved */ + Reserved11_IRQn = 13, /*!< Internal reserved */ + Reserved12_IRQn = 14, /*!< Internal reserved */ + Reserved13_IRQn = 15, /*!< Internal reserved */ + Reserved14_IRQn = 16, /*!< Internal reserved */ + Reserved15_IRQn = 17, /*!< Internal reserved */ + Reserved16_IRQn = 18, /*!< Internal reserved */ + + /* ========= Device Specific Interrupt Numbers =================== */ + /* ToDo: add here your device specific external interrupt numbers. + * 19~max(NUM_INTERRUPT, 1023) is reserved number for user. + * Maxmum interrupt supported could get from clicinfo.NUM_INTERRUPT. + * According the interrupt handlers defined in startup_Device.S + * eg.: Interrupt for Timer#1 eclic_tim1_handler -> TIM1_IRQn */ + FirstDeviceSpecificInterrupt_IRQn = 19, /*!< First Device Specific Interrupt */ + SOC_INT_MAX, /*!< Number of total interrupts */ +} IRQn_Type; +#endif /* __ONLY_FOR_DOXYGEN_DOCUMENT_GENERATION__ */ + +#ifdef NMSIS_ECLIC_VIRTUAL + #ifndef NMSIS_ECLIC_VIRTUAL_HEADER_FILE + #define NMSIS_ECLIC_VIRTUAL_HEADER_FILE "nmsis_eclic_virtual.h" + #endif + #include NMSIS_ECLIC_VIRTUAL_HEADER_FILE +#else + #define ECLIC_SetCfgNlbits __ECLIC_SetCfgNlbits + #define ECLIC_GetCfgNlbits __ECLIC_GetCfgNlbits + #define ECLIC_GetInfoVer __ECLIC_GetInfoVer + #define ECLIC_GetInfoCtlbits __ECLIC_GetInfoCtlbits + #define ECLIC_GetInfoNum __ECLIC_GetInfoNum + #define ECLIC_SetMth __ECLIC_SetMth + #define ECLIC_GetMth __ECLIC_GetMth + #define ECLIC_EnableIRQ __ECLIC_EnableIRQ + #define ECLIC_GetEnableIRQ __ECLIC_GetEnableIRQ + #define ECLIC_DisableIRQ __ECLIC_DisableIRQ + #define ECLIC_SetPendingIRQ __ECLIC_SetPendingIRQ + #define ECLIC_GetPendingIRQ __ECLIC_GetPendingIRQ + #define ECLIC_ClearPendingIRQ __ECLIC_ClearPendingIRQ + #define ECLIC_SetTrigIRQ __ECLIC_SetTrigIRQ + #define ECLIC_GetTrigIRQ __ECLIC_GetTrigIRQ + #define ECLIC_SetShvIRQ __ECLIC_SetShvIRQ + #define ECLIC_GetShvIRQ __ECLIC_GetShvIRQ + #define ECLIC_SetCtrlIRQ __ECLIC_SetCtrlIRQ + #define ECLIC_GetCtrlIRQ __ECLIC_GetCtrlIRQ + #define ECLIC_SetLevelIRQ __ECLIC_SetLevelIRQ + #define ECLIC_GetLevelIRQ __ECLIC_GetLevelIRQ + #define ECLIC_SetPriorityIRQ __ECLIC_SetPriorityIRQ + #define ECLIC_GetPriorityIRQ __ECLIC_GetPriorityIRQ + + /* For TEE */ +#if defined(__TEE_PRESENT) && (__TEE_PRESENT == 1) + #define ECLIC_SetModeIRQ __ECLIC_SetModeIRQ + #define ECLIC_SetSth __ECLIC_SetSth + #define ECLIC_GetSth __ECLIC_GetSth + #define ECLIC_SetTrigIRQ_S __ECLIC_SetTrigIRQ_S + #define ECLIC_GetTrigIRQ_S __ECLIC_GetTrigIRQ_S + #define ECLIC_SetShvIRQ_S __ECLIC_SetShvIRQ_S + #define ECLIC_GetShvIRQ_S __ECLIC_GetShvIRQ_S + #define ECLIC_SetCtrlIRQ_S __ECLIC_SetCtrlIRQ_S + #define ECLIC_GetCtrlIRQ_S __ECLIC_GetCtrlIRQ_S + #define ECLIC_SetLevelIRQ_S __ECLIC_SetLevelIRQ_S + #define ECLIC_GetLevelIRQ_S __ECLIC_GetLevelIRQ_S + #define ECLIC_SetPriorityIRQ_S __ECLIC_SetPriorityIRQ_S + #define ECLIC_GetPriorityIRQ_S __ECLIC_GetPriorityIRQ_S + #define ECLIC_EnableIRQ_S __ECLIC_EnableIRQ_S + #define ECLIC_GetEnableIRQ_S __ECLIC_GetEnableIRQ_S + #define ECLIC_DisableIRQ_S __ECLIC_DisableIRQ_S + +#endif +#endif /* NMSIS_ECLIC_VIRTUAL */ + +#ifdef NMSIS_VECTAB_VIRTUAL + #ifndef NMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define NMSIS_VECTAB_VIRTUAL_HEADER_FILE "nmsis_vectab_virtual.h" + #endif + #include NMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define ECLIC_SetVector __ECLIC_SetVector + #define ECLIC_GetVector __ECLIC_GetVector + +#if defined(__TEE_PRESENT) && (__TEE_PRESENT == 1) + #define ECLIC_SetVector_S __ECLIC_SetVector_S + #define ECLIC_GetVector_S __ECLIC_GetVector_S +#endif +#endif /* (NMSIS_VECTAB_VIRTUAL) */ + +/** + * \brief Set nlbits value + * \details + * This function set the nlbits value of CLICCFG register. + * \param [in] nlbits nlbits value + * \remarks + * - nlbits is used to set the width of level in the CLICINTCTL[i]. + * \sa + * - \ref ECLIC_GetCfgNlbits + */ +__STATIC_FORCEINLINE void __ECLIC_SetCfgNlbits(uint32_t nlbits) +{ + ECLIC->CFG &= ~CLIC_CLICCFG_NLBIT_Msk; + ECLIC->CFG |= (uint8_t)((nlbits <CFG & CLIC_CLICCFG_NLBIT_Msk) >> CLIC_CLICCFG_NLBIT_Pos)); +} + +/** + * \brief Get the ECLIC version number + * \details + * This function gets the hardware version information from CLICINFO register. + * \return hardware version number in CLICINFO register. + * \remarks + * - This function gets harware version information from CLICINFO register. + * - Bit 20:17 for architecture version, bit 16:13 for implementation version. + * \sa + * - \ref ECLIC_GetInfoNum +*/ +__STATIC_FORCEINLINE uint32_t __ECLIC_GetInfoVer(void) +{ + return ((uint32_t)((ECLIC->INFO & CLIC_CLICINFO_VER_Msk) >> CLIC_CLICINFO_VER_Pos)); +} + +/** + * \brief Get CLICINTCTLBITS + * \details + * This function gets CLICINTCTLBITS from CLICINFO register. + * \return CLICINTCTLBITS from CLICINFO register. + * \remarks + * - In the CLICINTCTL[i] registers, with 2 <= CLICINTCTLBITS <= 8. + * - The implemented bits are kept left-justified in the most-significant bits of each 8-bit + * CLICINTCTL[I] register, with the lower unimplemented bits treated as hardwired to 1. + * \sa + * - \ref ECLIC_GetInfoNum + */ +__STATIC_FORCEINLINE uint32_t __ECLIC_GetInfoCtlbits(void) +{ + return ((uint32_t)((ECLIC->INFO & CLIC_CLICINFO_CTLBIT_Msk) >> CLIC_CLICINFO_CTLBIT_Pos)); +} + +/** + * \brief Get number of maximum interrupt inputs supported + * \details + * This function gets number of maximum interrupt inputs supported from CLICINFO register. + * \return number of maximum interrupt inputs supported from CLICINFO register. + * \remarks + * - This function gets number of maximum interrupt inputs supported from CLICINFO register. + * - The num_interrupt field specifies the actual number of maximum interrupt inputs supported in this implementation. + * \sa + * - \ref ECLIC_GetInfoCtlbits + */ +__STATIC_FORCEINLINE uint32_t __ECLIC_GetInfoNum(void) +{ + return ((uint32_t)((ECLIC->INFO & CLIC_CLICINFO_NUM_Msk) >> CLIC_CLICINFO_NUM_Pos)); +} + +/** + * \brief Set Machine Mode Interrupt Level Threshold + * \details + * This function sets machine mode interrupt level threshold. + * \param [in] mth Interrupt Level Threshold. + * \sa + * - \ref ECLIC_GetMth + */ +__STATIC_FORCEINLINE void __ECLIC_SetMth(uint8_t mth) +{ + ECLIC->MTH = mth; +} + +/** + * \brief Get Machine Mode Interrupt Level Threshold + * \details + * This function gets machine mode interrupt level threshold. + * \return Interrupt Level Threshold. + * \sa + * - \ref ECLIC_SetMth + */ +__STATIC_FORCEINLINE uint8_t __ECLIC_GetMth(void) +{ + return (ECLIC->MTH); +} + + +/** + * \brief Enable a specific interrupt + * \details + * This function enables the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_DisableIRQ + */ +__STATIC_FORCEINLINE void __ECLIC_EnableIRQ(IRQn_Type IRQn) +{ + ECLIC->CTRL[IRQn].INTIE |= CLIC_INTIE_IE_Msk; +} + +/** + * \brief Get a specific interrupt enable status + * \details + * This function returns the interrupt enable status for the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \returns + * - 0 Interrupt is not enabled + * - 1 Interrupt is pending + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_EnableIRQ + * - \ref ECLIC_DisableIRQ + */ +__STATIC_FORCEINLINE uint32_t __ECLIC_GetEnableIRQ(IRQn_Type IRQn) +{ + return ((uint32_t) (ECLIC->CTRL[IRQn].INTIE) & CLIC_INTIE_IE_Msk); +} + +/** + * \brief Disable a specific interrupt + * \details + * This function disables the specific interrupt \em IRQn. + * \param [in] IRQn Number of the external interrupt to disable + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_EnableIRQ + */ +__STATIC_FORCEINLINE void __ECLIC_DisableIRQ(IRQn_Type IRQn) +{ + ECLIC->CTRL[IRQn].INTIE &= ~CLIC_INTIE_IE_Msk; +} + +/** + * \brief Get the pending specific interrupt + * \details + * This function returns the pending status of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \returns + * - 0 Interrupt is not pending + * - 1 Interrupt is pending + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_SetPendingIRQ + * - \ref ECLIC_ClearPendingIRQ + */ +__STATIC_FORCEINLINE int32_t __ECLIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return ((uint32_t)(ECLIC->CTRL[IRQn].INTIP) & CLIC_INTIP_IP_Msk); +} + +/** + * \brief Set a specific interrupt to pending + * \details + * This function sets the pending bit for the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_GetPendingIRQ + * - \ref ECLIC_ClearPendingIRQ + */ +__STATIC_FORCEINLINE void __ECLIC_SetPendingIRQ(IRQn_Type IRQn) +{ + ECLIC->CTRL[IRQn].INTIP |= CLIC_INTIP_IP_Msk; +} + +/** + * \brief Clear a specific interrupt from pending + * \details + * This function removes the pending state of the specific interrupt \em IRQn. + * \em IRQn cannot be a negative number. + * \param [in] IRQn Interrupt number + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_SetPendingIRQ + * - \ref ECLIC_GetPendingIRQ + */ +__STATIC_FORCEINLINE void __ECLIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + ECLIC->CTRL[IRQn].INTIP &= ~CLIC_INTIP_IP_Msk; +} + +/** + * \brief Set trigger mode and polarity for a specific interrupt + * \details + * This function set trigger mode and polarity of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \param [in] trig + * - 00 level trigger, \ref ECLIC_LEVEL_TRIGGER + * - 01 positive edge trigger, \ref ECLIC_POSTIVE_EDGE_TRIGGER + * - 02 level trigger, \ref ECLIC_LEVEL_TRIGGER + * - 03 negative edge trigger, \ref ECLIC_NEGTIVE_EDGE_TRIGGER + * \remarks + * - IRQn must not be negative. + * + * \sa + * - \ref ECLIC_GetTrigIRQ + */ +__STATIC_FORCEINLINE void __ECLIC_SetTrigIRQ(IRQn_Type IRQn, uint32_t trig) +{ + ECLIC->CTRL[IRQn].INTATTR &= ~CLIC_INTATTR_TRIG_Msk; + ECLIC->CTRL[IRQn].INTATTR |= (uint8_t)(trig << CLIC_INTATTR_TRIG_Pos); +} + +/** + * \brief Get trigger mode and polarity for a specific interrupt + * \details + * This function get trigger mode and polarity of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \return + * - 00 level trigger, \ref ECLIC_LEVEL_TRIGGER + * - 01 positive edge trigger, \ref ECLIC_POSTIVE_EDGE_TRIGGER + * - 02 level trigger, \ref ECLIC_LEVEL_TRIGGER + * - 03 negative edge trigger, \ref ECLIC_NEGTIVE_EDGE_TRIGGER + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_SetTrigIRQ + */ +__STATIC_FORCEINLINE uint32_t __ECLIC_GetTrigIRQ(IRQn_Type IRQn) +{ + return ((uint32_t)(((ECLIC->CTRL[IRQn].INTATTR) & CLIC_INTATTR_TRIG_Msk) >> CLIC_INTATTR_TRIG_Pos)); +} + +/** + * \brief Set interrupt working mode for a specific interrupt + * \details + * This function set selective hardware vector or non-vector working mode of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \param [in] shv + * - 0 non-vector mode, \ref ECLIC_NON_VECTOR_INTERRUPT + * - 1 vector mode, \ref ECLIC_VECTOR_INTERRUPT + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_GetShvIRQ + */ +__STATIC_FORCEINLINE void __ECLIC_SetShvIRQ(IRQn_Type IRQn, uint32_t shv) +{ + ECLIC->CTRL[IRQn].INTATTR &= ~CLIC_INTATTR_SHV_Msk; + ECLIC->CTRL[IRQn].INTATTR |= (uint8_t)(shv << CLIC_INTATTR_SHV_Pos); +} + +/** + * \brief Get interrupt working mode for a specific interrupt + * \details + * This function get selective hardware vector or non-vector working mode of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \return shv + * - 0 non-vector mode, \ref ECLIC_NON_VECTOR_INTERRUPT + * - 1 vector mode, \ref ECLIC_VECTOR_INTERRUPT + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_SetShvIRQ + */ +__STATIC_FORCEINLINE uint32_t __ECLIC_GetShvIRQ(IRQn_Type IRQn) +{ + return ((uint32_t)(((ECLIC->CTRL[IRQn].INTATTR) & CLIC_INTATTR_SHV_Msk) >> CLIC_INTATTR_SHV_Pos)); +} + +/** + * \brief Modify ECLIC Interrupt Input Control Register for a specific interrupt + * \details + * This function modify ECLIC Interrupt Input Control(CLICINTCTL[i]) register of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \param [in] intctrl Set value for CLICINTCTL[i] register + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_GetCtrlIRQ + */ +__STATIC_FORCEINLINE void __ECLIC_SetCtrlIRQ(IRQn_Type IRQn, uint8_t intctrl) +{ + ECLIC->CTRL[IRQn].INTCTRL = intctrl; +} + +/** + * \brief Get ECLIC Interrupt Input Control Register value for a specific interrupt + * \details + * This function modify ECLIC Interrupt Input Control register of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \return value of ECLIC Interrupt Input Control register + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_SetCtrlIRQ + */ +__STATIC_FORCEINLINE uint8_t __ECLIC_GetCtrlIRQ(IRQn_Type IRQn) +{ + return (ECLIC->CTRL[IRQn].INTCTRL); +} + +/** + * \brief Set ECLIC Interrupt level of a specific interrupt + * \details + * This function set interrupt level of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \param [in] lvl_abs Interrupt level + * \remarks + * - IRQn must not be negative. + * - If lvl_abs to be set is larger than the max level allowed, it will be force to be max level. + * - When you set level value you need use clciinfo.nlbits to get the width of level. + * Then we could know the maximum of level. CLICINTCTLBITS is how many total bits are + * present in the CLICINTCTL register. + * \sa + * - \ref ECLIC_GetLevelIRQ + */ +__STATIC_FORCEINLINE void __ECLIC_SetLevelIRQ(IRQn_Type IRQn, uint8_t lvl_abs) +{ + uint8_t nlbits = __ECLIC_GetCfgNlbits(); + uint8_t intctlbits = (uint8_t)__ECLIC_INTCTLBITS; + + if (nlbits == 0) { + return; + } + + if (nlbits > intctlbits) { + nlbits = intctlbits; + } + uint8_t maxlvl = ((1 << nlbits) - 1); + if (lvl_abs > maxlvl) { + lvl_abs = maxlvl; + } + uint8_t lvl = lvl_abs << (ECLIC_MAX_NLBITS - nlbits); + uint8_t cur_ctrl = __ECLIC_GetCtrlIRQ(IRQn); + cur_ctrl = cur_ctrl << nlbits; + cur_ctrl = cur_ctrl >> nlbits; + __ECLIC_SetCtrlIRQ(IRQn, (cur_ctrl | lvl)); +} + +/** + * \brief Get ECLIC Interrupt level of a specific interrupt + * \details + * This function get interrupt level of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \return Interrupt level + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_SetLevelIRQ + */ +__STATIC_FORCEINLINE uint8_t __ECLIC_GetLevelIRQ(IRQn_Type IRQn) +{ + uint8_t nlbits = __ECLIC_GetCfgNlbits(); + uint8_t intctlbits = (uint8_t)__ECLIC_INTCTLBITS; + + if (nlbits == 0) { + return 0; + } + + if (nlbits > intctlbits) { + nlbits = intctlbits; + } + uint8_t intctrl = __ECLIC_GetCtrlIRQ(IRQn); + uint8_t lvl_abs = intctrl >> (ECLIC_MAX_NLBITS - nlbits); + return lvl_abs; +} + +/** + * \brief Get ECLIC Interrupt priority of a specific interrupt + * \details + * This function get interrupt priority of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \param [in] pri Interrupt priority + * \remarks + * - IRQn must not be negative. + * - If pri to be set is larger than the max priority allowed, it will be force to be max priority. + * - Priority width is CLICINTCTLBITS minus clciinfo.nlbits if clciinfo.nlbits + * is less than CLICINTCTLBITS. Otherwise priority width is 0. + * \sa + * - \ref ECLIC_GetPriorityIRQ + */ +__STATIC_FORCEINLINE void __ECLIC_SetPriorityIRQ(IRQn_Type IRQn, uint8_t pri) +{ + uint8_t nlbits = __ECLIC_GetCfgNlbits(); + uint8_t intctlbits = (uint8_t)__ECLIC_INTCTLBITS; + if (nlbits < intctlbits) { + uint8_t maxpri = ((1 << (intctlbits - nlbits)) - 1); + if (pri > maxpri) { + pri = maxpri; + } + pri = pri << (ECLIC_MAX_NLBITS - intctlbits); + uint8_t mask = ((uint8_t)(-1)) >> intctlbits; + pri = pri | mask; + uint8_t cur_ctrl = __ECLIC_GetCtrlIRQ(IRQn); + cur_ctrl = cur_ctrl >> (ECLIC_MAX_NLBITS - nlbits); + cur_ctrl = cur_ctrl << (ECLIC_MAX_NLBITS - nlbits); + __ECLIC_SetCtrlIRQ(IRQn, (cur_ctrl | pri)); + } +} + +/** + * \brief Get ECLIC Interrupt priority of a specific interrupt + * \details + * This function get interrupt priority of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \return Interrupt priority + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_SetPriorityIRQ + */ +__STATIC_FORCEINLINE uint8_t __ECLIC_GetPriorityIRQ(IRQn_Type IRQn) +{ + uint8_t nlbits = __ECLIC_GetCfgNlbits(); + uint8_t intctlbits = (uint8_t)__ECLIC_INTCTLBITS; + if (nlbits < intctlbits) { + uint8_t cur_ctrl = __ECLIC_GetCtrlIRQ(IRQn); + uint8_t pri = cur_ctrl << nlbits; + pri = pri >> nlbits; + pri = pri >> (ECLIC_MAX_NLBITS - intctlbits); + return pri; + } else { + return 0; + } +} + +/** + * \brief Set Interrupt Vector of a specific interrupt + * \details + * This function set interrupt handler address of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \param [in] vector Interrupt handler address + * \remarks + * - IRQn must not be negative. + * - You can set the \ref CSR_CSR_MTVT to set interrupt vector table entry address. + * - If your vector table is placed in readonly section, the vector for IRQn will not be modified. + * For this case, you need to use the correct irq handler name defined in your vector table as + * your irq handler function name. + * - This function will only work correctly when the vector table is placed in an read-write enabled section. + * \sa + * - \ref ECLIC_GetVector + */ +__STATIC_FORCEINLINE void __ECLIC_SetVector(IRQn_Type IRQn, rv_csr_t vector) +{ + volatile unsigned long vec_base; + vec_base = ((unsigned long)__RV_CSR_READ(CSR_MTVT)); + vec_base += ((unsigned long)IRQn) * sizeof(unsigned long); + (* (unsigned long *) vec_base) = vector; +#if (defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1)) +#if (defined(__CCM_PRESENT) && (__CCM_PRESENT == 1)) + MFlushDCacheLine((unsigned long)vec_base); +#endif +#endif +#if (defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1)) +#if (defined(__CCM_PRESENT) && (__CCM_PRESENT == 1)) + MInvalICacheLine((unsigned long)vec_base); +#else + __FENCE_I(); +#endif +#endif +} + +/** + * \brief Get Interrupt Vector of a specific interrupt + * \details + * This function get interrupt handler address of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \return Interrupt handler address + * \remarks + * - IRQn must not be negative. + * - You can read \ref CSR_CSR_MTVT to get interrupt vector table entry address. + * \sa + * - \ref ECLIC_SetVector + */ +__STATIC_FORCEINLINE rv_csr_t __ECLIC_GetVector(IRQn_Type IRQn) +{ +#if __RISCV_XLEN == 32 + return (*(uint32_t *)(__RV_CSR_READ(CSR_MTVT) + IRQn * 4)); +#elif __RISCV_XLEN == 64 + return (*(uint64_t *)(__RV_CSR_READ(CSR_MTVT) + IRQn * 8)); +#else // TODO Need cover for XLEN=128 case in future + return (*(uint64_t *)(__RV_CSR_READ(CSR_MTVT) + IRQn * 8)); +#endif +} + +#if defined(__TEE_PRESENT) && (__TEE_PRESENT == 1) +/** + * \brief Set privilege mode of a specific interrupt + * \details + * This function set in which privilege mode the interrupts \em IRQn should be taken. + * \param [in] IRQn Interrupt number + * \param [in] mode Privilege mode + * \remarks + * - IRQn must not be negative. + * - mode must be 1(Supervisor Mode) or 3(Machine Mode), other values are ignored. + * - M-mode can R/W this field, but S-mode can only read.And ECLIC with TEE does not + * reply on CSR mideleg to delegate interrupts. + * - Mode of S-mode ECLIC region's clicintattr can be omitted to set, which is mirror to M-mode ECLIC region's. + * Only the low 6 bits of clicintattr [i] can be written via the S-mode memory region. + */ +__STATIC_FORCEINLINE void __ECLIC_SetModeIRQ(IRQn_Type IRQn, uint32_t mode) +{ + /* + * only 1 or 3 can be assigned to mode in one step.the default value of mode is 3, + * which can't be clear to 0 firstly, then OR it to 1 + */ + ECLIC->CTRL[IRQn].INTATTR = (uint8_t)(mode << CLIC_INTATTR_MODE_Pos) + \ + (ECLIC->SCTRL[IRQn].INTATTR & (~CLIC_INTATTR_MODE_Msk)); +} + +/** + * \brief Set supervisor-mode Interrupt Level Threshold in supervisor mode + * \details + * This function sets supervisor-mode interrupt level threshold. + * \param [in] sth Interrupt Level Threshold. + * \remarks + * - S-mode ECLIC region sintthresh'sth is a mirror to M-mode ECLIC region's mintthresh.sth, + * and will be updated synchronously, here operate on mintthresh.sth. + * \sa + * - \ref ECLIC_GetSth + */ +__STATIC_FORCEINLINE void __ECLIC_SetSth(uint8_t sth) +{ + ECLIC->STH = sth; +} + +/** + * \brief Get supervisor-mode Interrupt Level Threshold in supervisor mode + * \details + * This function gets supervisor mode interrupt level threshold. + * \return Interrupt Level Threshold. + * \remarks + * - S-mode ECLIC region sintthresh'sth is a mirror to M-mode ECLIC region's mintthresh.sth, + * and will be updated synchronously, here operate on mintthresh.sth. + * \sa + * - \ref ECLIC_SetSth + */ +__STATIC_FORCEINLINE uint8_t __ECLIC_GetSth(void) +{ + return (ECLIC->STH); +} + +/** + * \brief Set trigger mode and polarity for a specific interrupt in supervisor mode + * \details + * This function set trigger mode and polarity of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \param [in] trig + * - 00 level trigger, \ref ECLIC_LEVEL_TRIGGER + * - 01 positive edge trigger, \ref ECLIC_POSTIVE_EDGE_TRIGGER + * - 02 level trigger, \ref ECLIC_LEVEL_TRIGGER + * - 03 negative edge trigger, \ref ECLIC_NEGTIVE_EDGE_TRIGGER + * \remarks + * - IRQn must not be negative. + * + * \sa + * - \ref ECLIC_GetTrigIRQ_S + */ +__STATIC_FORCEINLINE void __ECLIC_SetTrigIRQ_S(IRQn_Type IRQn, uint32_t trig) +{ + ECLIC->SCTRL[IRQn].INTATTR &= ~CLIC_INTATTR_TRIG_Msk; + ECLIC->SCTRL[IRQn].INTATTR |= (uint8_t)(trig << CLIC_INTATTR_TRIG_Pos); +} + +/** + * \brief Get trigger mode and polarity for a specific interrupt in supervisor mode + * \details + * This function get trigger mode and polarity of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \return + * - 00 level trigger, \ref ECLIC_LEVEL_TRIGGER + * - 01 positive edge trigger, \ref ECLIC_POSTIVE_EDGE_TRIGGER + * - 02 level trigger, \ref ECLIC_LEVEL_TRIGGER + * - 03 negative edge trigger, \ref ECLIC_NEGTIVE_EDGE_TRIGGER + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_SetTrigIRQ_S + */ +__STATIC_FORCEINLINE uint8_t __ECLIC_GetTrigIRQ_S(IRQn_Type IRQn) +{ + return ((uint8_t)(((ECLIC->SCTRL[IRQn].INTATTR) & CLIC_INTATTR_TRIG_Msk) >> CLIC_INTATTR_TRIG_Pos)); +} + + +/** + * \brief Set interrupt working mode for a specific interrupt in supervisor mode + * \details + * This function set selective hardware vector or non-vector working mode of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \param [in] shv + * - 0 non-vector mode, \ref ECLIC_NON_VECTOR_INTERRUPT + * - 1 vector mode, \ref ECLIC_VECTOR_INTERRUPT + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_GetShvIRQ_S + */ +__STATIC_FORCEINLINE void __ECLIC_SetShvIRQ_S(IRQn_Type IRQn, uint32_t shv) +{ + ECLIC->SCTRL[IRQn].INTATTR &= ~CLIC_INTATTR_SHV_Msk; + ECLIC->SCTRL[IRQn].INTATTR |= (uint8_t)(shv << CLIC_INTATTR_SHV_Pos); +} + +/** + * \brief Get interrupt working mode for a specific interrupt in supervisor mode + * \details + * This function get selective hardware vector or non-vector working mode of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \return shv + * - 0 non-vector mode, \ref ECLIC_NON_VECTOR_INTERRUPT + * - 1 vector mode, \ref ECLIC_VECTOR_INTERRUPT + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_SMODE_SetShvIRQ + */ +__STATIC_FORCEINLINE uint8_t __ECLIC_GetShvIRQ_S(IRQn_Type IRQn) +{ + return ((uint8_t)(((ECLIC->SCTRL[IRQn].INTATTR) & CLIC_INTATTR_SHV_Msk) >> CLIC_INTATTR_SHV_Pos)); +} + +/** + * \brief Modify ECLIC Interrupt Input Control Register for a specific interrupt in supervisor mode + * \details + * This function modify ECLIC Interrupt Input Control(CLICINTCTL[i]) register of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \param [in] intctrl Set value for CLICINTCTL[i] register + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_GetCtrlIRQ_S + */ +__STATIC_FORCEINLINE void __ECLIC_SetCtrlIRQ_S(IRQn_Type IRQn, uint8_t intctrl) +{ + ECLIC->SCTRL[IRQn].INTCTRL = intctrl; +} + +/** + * \brief Get ECLIC Interrupt Input Control Register value for a specific interrupt in supervisor mode + * \details + * This function modify ECLIC Interrupt Input Control register of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \return value of ECLIC Interrupt Input Control register + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_SetCtrlIRQ_S + */ +__STATIC_FORCEINLINE uint8_t __ECLIC_GetCtrlIRQ_S(IRQn_Type IRQn) +{ + return (ECLIC->SCTRL[IRQn].INTCTRL); +} + +/** + * \brief Set ECLIC Interrupt level of a specific interrupt in supervisor mode + * \details + * This function set interrupt level of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \param [in] lvl_abs Interrupt level + * \remarks + * - IRQn must not be negative. + * - If lvl_abs to be set is larger than the max level allowed, it will be force to be max level. + * - When you set level value you need use clciinfo.nlbits to get the width of level. + * Then we could know the maximum of level. CLICINTCTLBITS is how many total bits are + * present in the CLICINTCTL register. + * \sa + * - \ref ECLIC_GetLevelIRQ_S + */ +__STATIC_FORCEINLINE void __ECLIC_SetLevelIRQ_S(IRQn_Type IRQn, uint8_t lvl_abs) +{ + uint8_t nlbits = __ECLIC_GetCfgNlbits(); + uint8_t intctlbits = (uint8_t)__ECLIC_INTCTLBITS; + + if (nlbits == 0) { + return; + } + + if (nlbits > intctlbits) { + nlbits = intctlbits; + } + uint8_t maxlvl = ((1 << nlbits) - 1); + if (lvl_abs > maxlvl) { + lvl_abs = maxlvl; + } + uint8_t lvl = lvl_abs << (ECLIC_MAX_NLBITS - nlbits); + uint8_t cur_ctrl = __ECLIC_GetCtrlIRQ_S(IRQn); + cur_ctrl = cur_ctrl << nlbits; + cur_ctrl = cur_ctrl >> nlbits; + __ECLIC_SetCtrlIRQ_S(IRQn, (cur_ctrl | lvl)); +} + + +/** + * \brief Get ECLIC Interrupt level of a specific interrupt + * \details + * This function get interrupt level of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \return Interrupt level + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_SetLevelIRQ_S + */ +__STATIC_FORCEINLINE uint8_t __ECLIC_GetLevelIRQ_S(IRQn_Type IRQn) +{ + uint8_t nlbits = __ECLIC_GetCfgNlbits(); + uint8_t intctlbits = (uint8_t)__ECLIC_INTCTLBITS; + + if (nlbits == 0) { + return 0; + } + + if (nlbits > intctlbits) { + nlbits = intctlbits; + } + uint8_t intctrl = __ECLIC_GetCtrlIRQ_S(IRQn); + uint8_t lvl_abs = intctrl >> (ECLIC_MAX_NLBITS - nlbits); + return lvl_abs; +} + +/** + * \brief Set ECLIC Interrupt priority of a specific interrupt in supervisor mode + * \details + * This function get interrupt priority of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \param [in] pri Interrupt priority + * \remarks + * - IRQn must not be negative. + * - If pri to be set is larger than the max priority allowed, it will be force to be max priority. + * - Priority width is CLICINTCTLBITS minus clciinfo.nlbits if clciinfo.nlbits + * is less than CLICINTCTLBITS. Otherwise priority width is 0. + * \sa + * - \ref ECLIC_GetPriorityIRQ_S + */ +__STATIC_FORCEINLINE void __ECLIC_SetPriorityIRQ_S(IRQn_Type IRQn, uint8_t pri) +{ + uint8_t nlbits = __ECLIC_GetCfgNlbits(); + uint8_t intctlbits = (uint8_t)__ECLIC_INTCTLBITS; + if (nlbits < intctlbits) { + uint8_t maxpri = ((1 << (intctlbits - nlbits)) - 1); + if (pri > maxpri) { + pri = maxpri; + } + pri = pri << (ECLIC_MAX_NLBITS - intctlbits); + uint8_t mask = ((uint8_t)(-1)) >> intctlbits; + pri = pri | mask; + uint8_t cur_ctrl = __ECLIC_GetCtrlIRQ_S(IRQn); + cur_ctrl = cur_ctrl >> (ECLIC_MAX_NLBITS - nlbits); + cur_ctrl = cur_ctrl << (ECLIC_MAX_NLBITS - nlbits); + __ECLIC_SetCtrlIRQ_S(IRQn, (cur_ctrl | pri)); + } +} + +/** + * \brief Get ECLIC Interrupt priority of a specific interrupt in supervisor mode + * \details + * This function get interrupt priority of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \return Interrupt priority + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_SetPriorityIRQ_S + */ +__STATIC_FORCEINLINE uint8_t __ECLIC_GetPriorityIRQ_S(IRQn_Type IRQn) +{ + uint8_t nlbits = __ECLIC_GetCfgNlbits(); + uint8_t intctlbits = (uint8_t)__ECLIC_INTCTLBITS; + if (nlbits < intctlbits) { + uint8_t cur_ctrl = __ECLIC_GetCtrlIRQ_S(IRQn); + uint8_t pri = cur_ctrl << nlbits; + pri = pri >> nlbits; + pri = pri >> (ECLIC_MAX_NLBITS - intctlbits); + return pri; + } else { + return 0; + } +} + +/** + * \brief Enable a specific interrupt in supervisor mode + * \details + * This function enables the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_DisableIRQ + */ +__STATIC_FORCEINLINE void __ECLIC_EnableIRQ_S(IRQn_Type IRQn) +{ + ECLIC->SCTRL[IRQn].INTIE |= CLIC_INTIE_IE_Msk; +} + +/** + * \brief Get a specific interrupt enable status in supervisor mode + * \details + * This function returns the interrupt enable status for the specific interrupt \em IRQn in S MODE. + * \param [in] IRQn Interrupt number + * \returns + * - 0 Interrupt is not masked + * - 1 Interrupt is enabled + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_EnableIRQ_S + * - \ref ECLIC_DisableIRQ_S + */ +__STATIC_FORCEINLINE uint8_t __ECLIC_GetEnableIRQ_S(IRQn_Type IRQn) +{ + return ((uint8_t) (ECLIC->SCTRL[IRQn].INTIE) & CLIC_INTIE_IE_Msk); +} + +/** + * \brief Disable a specific interrupt in supervisor mode + * \details + * This function disables the specific interrupt \em IRQn. + * \param [in] IRQn Number of the external interrupt to disable + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_EnableIRQ + */ +__STATIC_FORCEINLINE void __ECLIC_DisableIRQ_S(IRQn_Type IRQn) +{ + ECLIC->SCTRL[IRQn].INTIE &= ~CLIC_INTIE_IE_Msk; +} + +/** + * \brief Set Interrupt Vector of a specific interrupt in supervisor mode + * \details + * This function set interrupt handler address of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \param [in] vector Interrupt handler address + * \remarks + * - IRQn must not be negative. + * - You can set the \ref CSR_CSR_MTVT to set interrupt vector table entry address. + * - If your vector table is placed in readonly section, the vector for IRQn will not be modified. + * For this case, you need to use the correct irq handler name defined in your vector table as + * your irq handler function name. + * - This function will only work correctly when the vector table is placed in an read-write enabled section. + * \sa + * - \ref ECLIC_GetVector_S + */ +__STATIC_FORCEINLINE void __ECLIC_SetVector_S(IRQn_Type IRQn, rv_csr_t vector) +{ + volatile unsigned long vec_base; + vec_base = ((unsigned long)__RV_CSR_READ(CSR_STVT)); + vec_base += ((unsigned long)IRQn) * sizeof(unsigned long); + (* (unsigned long *) vec_base) = vector; +#if (defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1)) +#if (defined(__CCM_PRESENT) && (__CCM_PRESENT == 1)) + SFlushDCacheLine((unsigned long)vec_base); +#endif +#endif +#if (defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1)) +#if (defined(__CCM_PRESENT) && (__CCM_PRESENT == 1)) + SInvalICacheLine((unsigned long)vec_base); +#else + __FENCE_I(); +#endif +#endif +} + +/** + * \brief Get Interrupt Vector of a specific interrupt in supervisor mode + * \details + * This function get interrupt handler address of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \return Interrupt handler address + * \remarks + * - IRQn must not be negative. + * - You can read \ref CSR_CSR_MTVT to get interrupt vector table entry address. + * \sa + * - \ref ECLIC_SMODE_SetVector + */ +__STATIC_FORCEINLINE rv_csr_t __ECLIC_GetVector_S(IRQn_Type IRQn) +{ +#if __RISCV_XLEN == 32 + return (*(uint32_t *)(__RV_CSR_READ(CSR_STVT) + IRQn * 4)); +#elif __RISCV_XLEN == 64 + return (*(uint64_t *)(__RV_CSR_READ(CSR_STVT) + IRQn * 8)); +#else // TODO Need cover for XLEN=128 case in future + return (*(uint64_t *)(__RV_CSR_READ(CSR_STVT) + IRQn * 8)); +#endif +} + +#endif /* defined(__TEE_PRESENT) && (__TEE_PRESENT == 1) */ + +/** + * \brief Set Exception entry address + * \details + * This function set exception handler address to 'CSR_MTVEC'. + * \param [in] addr Exception handler address + * \remarks + * - This function use to set exception handler address to 'CSR_MTVEC'. + * Address need to be aligned to 64 bytes. + * \sa + * - \ref __get_exc_entry + */ +__STATIC_FORCEINLINE void __set_exc_entry(rv_csr_t addr) +{ + addr &= (rv_csr_t)(~0x3F); + addr |= ECLIC_MODE_MTVEC_Msk; + __RV_CSR_WRITE(CSR_MTVEC, addr); +} + +/** + * \brief Get Exception entry address + * \details + * This function get exception handler address from 'CSR_MTVEC'. + * \return Exception handler address + * \remarks + * - This function use to get exception handler address from 'CSR_MTVEC'. + * Address need to be aligned to 64 bytes. + * \sa + * - \ref __set_exc_entry + */ +__STATIC_FORCEINLINE rv_csr_t __get_exc_entry(void) +{ + unsigned long addr = __RV_CSR_READ(CSR_MTVEC); + return (addr & ~ECLIC_MODE_MTVEC_Msk); +} + +/** + * \brief Set Non-vector interrupt entry address + * \details + * This function set Non-vector interrupt address. + * \param [in] addr Non-vector interrupt entry address + * \remarks + * - This function use to set non-vector interrupt entry address to 'CSR_MTVT2' if + * - CSR_MTVT2 bit0 is 1. If 'CSR_MTVT2' bit0 is 0 then set address to 'CSR_MTVEC' + * \sa + * - \ref __get_nonvec_entry + */ +__STATIC_FORCEINLINE void __set_nonvec_entry(rv_csr_t addr) +{ + if (__RV_CSR_READ(CSR_MTVT2) & 0x1) { + __RV_CSR_WRITE(CSR_MTVT2, addr | 0x01); + } else { + addr &= (rv_csr_t)(~0x3F); + addr |= ECLIC_MODE_MTVEC_Msk; + __RV_CSR_WRITE(CSR_MTVEC, addr); + } +} + +/** + * \brief Get Non-vector interrupt entry address + * \details + * This function get Non-vector interrupt address. + * \return Non-vector interrupt handler address + * \remarks + * - This function use to get non-vector interrupt entry address from 'CSR_MTVT2' if + * - CSR_MTVT2 bit0 is 1. If 'CSR_MTVT2' bit0 is 0 then get address from 'CSR_MTVEC'. + * \sa + * - \ref __set_nonvec_entry + */ +__STATIC_FORCEINLINE rv_csr_t __get_nonvec_entry(void) +{ + if (__RV_CSR_READ(CSR_MTVT2) & 0x1) { + return __RV_CSR_READ(CSR_MTVT2) & (~(rv_csr_t)(0x1)); + } else { + rv_csr_t addr = __RV_CSR_READ(CSR_MTVEC); + return (addr & ~ECLIC_MODE_MTVEC_Msk); + } +} + +/** + * \brief Get NMI interrupt entry from 'CSR_MNVEC' + * \details + * This function get NMI interrupt address from 'CSR_MNVEC'. + * \return NMI interrupt handler address + * \remarks + * - This function use to get NMI interrupt handler address from 'CSR_MNVEC'. If CSR_MMISC_CTL[9] = 1 'CSR_MNVEC' + * - will be equal as mtvec. If CSR_MMISC_CTL[9] = 0 'CSR_MNVEC' will be equal as reset vector. + * - NMI entry is defined via \ref CSR_MMISC_CTL, writing to \ref CSR_MNVEC will be ignored. + */ +__STATIC_FORCEINLINE rv_csr_t __get_nmi_entry(void) +{ + return __RV_CSR_READ(CSR_MNVEC); +} + +/** + * \brief Save necessary CSRs into variables for vector interrupt nesting + * \details + * This macro is used to declare variables which are used for saving + * CSRs(MCAUSE, MEPC, MSUB), and it will read these CSR content into + * these variables, it need to be used in a vector-interrupt if nesting + * is required. + * \remarks + * - Interrupt will be enabled after this macro is called + * - It need to be used together with \ref RESTORE_IRQ_CSR_CONTEXT + * - Don't use variable names __mcause, __mpec, __msubm in your ISR code + * - If you want to enable interrupt nesting feature for vector interrupt, + * you can do it like this: + * \code + * // __INTERRUPT attribute will generates function entry and exit sequences suitable + * // for use in an interrupt handler when this attribute is present + * __INTERRUPT void eclic_mtip_handler(void) + * { + * // Must call this to save CSRs + * SAVE_IRQ_CSR_CONTEXT(); + * // !!!Interrupt is enabled here!!! + * // !!!Higher priority interrupt could nest it!!! + * + * // put you own interrupt handling code here + * + * // Must call this to restore CSRs + * RESTORE_IRQ_CSR_CONTEXT(); + * } + * \endcode + */ +#define SAVE_IRQ_CSR_CONTEXT() \ + rv_csr_t __mcause = __RV_CSR_READ(CSR_MCAUSE); \ + rv_csr_t __mepc = __RV_CSR_READ(CSR_MEPC); \ + rv_csr_t __msubm = __RV_CSR_READ(CSR_MSUBM); \ + __enable_irq(); + +/*! Save necessary CSRs into variables for vector interrupt nesting in supervisor mode */ +#define SAVE_IRQ_CSR_CONTEXT_S() \ + rv_csr_t __scause = __RV_CSR_READ(CSR_SCAUSE); \ + rv_csr_t __sepc = __RV_CSR_READ(CSR_SEPC); \ + __enable_irq_s(); + + +/** + * \brief Restore necessary CSRs from variables for vector interrupt nesting + * \details + * This macro is used restore CSRs(MCAUSE, MEPC, MSUB) from pre-defined variables + * in \ref SAVE_IRQ_CSR_CONTEXT macro. + * \remarks + * - Interrupt will be disabled after this macro is called + * - It need to be used together with \ref SAVE_IRQ_CSR_CONTEXT + */ +#define RESTORE_IRQ_CSR_CONTEXT() \ + __disable_irq(); \ + __RV_CSR_WRITE(CSR_MSUBM, __msubm); \ + __RV_CSR_WRITE(CSR_MEPC, __mepc); \ + __RV_CSR_WRITE(CSR_MCAUSE, __mcause); + +/*! Restore necessary CSRs from variables for vector interrupt nesting in supervisor mode */ +#define RESTORE_IRQ_CSR_CONTEXT_S() \ + __disable_irq_s(); \ + __RV_CSR_WRITE(CSR_SEPC, __sepc); \ + __RV_CSR_WRITE(CSR_SCAUSE, __scause); +/** @} */ /* End of Doxygen Group NMSIS_Core_IntExc */ + +#endif /* defined(__ECLIC_PRESENT) && (__ECLIC_PRESENT == 1) */ + +#ifdef __cplusplus +} +#endif +#endif /* __CORE_FEATURE_ECLIC__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_fpu.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_fpu.h new file mode 100644 index 0000000..1c56293 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_fpu.h @@ -0,0 +1,308 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __CORE_FEATURE_FPU_H__ +#define __CORE_FEATURE_FPU_H__ +/*! + * @file core_feature_fpu.h + * @brief FPU feature API header file for Nuclei N/NX Core + */ +/* + * FPU Feature Configuration Macro: + * 1. __FPU_PRESENT: Define whether Floating Point Unit(FPU) is present or not + * * 0: Not present + * * 1: Single precision FPU present, __RISCV_FLEN == 32 + * * 2: Double precision FPU present, __RISCV_FLEN == 64 + */ +#ifdef __cplusplus + extern "C" { +#endif + +#include "core_feature_base.h" + +/* ===== FPU Operations ===== */ +/** + * \defgroup NMSIS_Core_FPU_Functions FPU Functions + * \ingroup NMSIS_Core + * \brief Functions that related to the RISC-V FPU (F and D extension). + * \details + * + * Nuclei provided floating point unit by RISC-V F and D extension. + * * `F extension` adds single-precision floating-point computational + * instructions compliant with the IEEE 754-2008 arithmetic standard, __RISCV_FLEN = 32. + * The F extension adds 32 floating-point registers, f0-f31, each 32 bits wide, + * and a floating-point control and status register fcsr, which contains the + * operating mode and exception status of the floating-point unit. + * * `D extension` adds double-precision floating-point computational instructions + * compliant with the IEEE 754-2008 arithmetic standard. + * The D extension widens the 32 floating-point registers, f0-f31, to 64 bits, __RISCV_FLEN = 64 + * @{ + */ +#if defined(__FPU_PRESENT) && (__FPU_PRESENT > 0) + +#if __FPU_PRESENT == 1 + /** \brief Refer to the width of the floating point register in bits(either 32 or 64) */ + #define __RISCV_FLEN 32 +#elif __FPU_PRESENT == 2 + #define __RISCV_FLEN 64 +#else + #define __RISCV_FLEN __riscv_flen +#endif /* __FPU_PRESENT == 1 */ + +/** \brief Get FCSR CSR Register */ +#define __get_FCSR() __RV_CSR_READ(CSR_FCSR) +/** \brief Set FCSR CSR Register with val */ +#define __set_FCSR(val) __RV_CSR_WRITE(CSR_FCSR, (val)) +/** \brief Get FRM CSR Register */ +#define __get_FRM() __RV_CSR_READ(CSR_FRM) +/** \brief Set FRM CSR Register with val */ +#define __set_FRM(val) __RV_CSR_WRITE(CSR_FRM, (val)) +/** \brief Get FFLAGS CSR Register */ +#define __get_FFLAGS() __RV_CSR_READ(CSR_FFLAGS) +/** \brief Set FFLAGS CSR Register with val */ +#define __set_FFLAGS(val) __RV_CSR_WRITE(CSR_FFLAGS, (val)) + +/** \brief Enable FPU Unit, and set state to initial */ +#define __enable_FPU() { __RV_CSR_CLEAR(CSR_MSTATUS, MSTATUS_FS); \ + __RV_CSR_SET(CSR_MSTATUS, MSTATUS_FS_INITIAL); \ + } +/** + * \brief Disable FPU Unit + * \details + * * We can save power by disable FPU Unit. + * * When FPU Unit is disabled, any access to FPU related CSR registers + * and FPU instructions will cause illegal Instuction Exception. + * */ +#define __disable_FPU() __RV_CSR_CLEAR(CSR_MSTATUS, MSTATUS_FS) + + +/** + * \brief Load a single-precision value from memory into float point register freg using flw instruction + * \details The FLW instruction loads a single-precision floating point value from memory + * address (addr + ofs) into floating point register freg(f0-f31) + * \param [in] freg The floating point register, eg. FREG(0), f0 + * \param [in] addr The memory base address, 4 byte aligned required + * \param [in] ofs a 12-bit immediate signed byte offset value, should be an const value + * \remarks + * * FLW and FSW operations need to make sure the address is 4 bytes aligned, + * otherwise it will cause exception code 4(Load address misaligned) or 6 (Store/AMO address misaligned) + * * FLW and FSW do not modify the bits being transferred; in particular, the payloads of non-canonical + * NaNs are preserved + * + */ +#define __RV_FLW(freg, addr, ofs) \ + ({ \ + rv_csr_t __addr = (rv_csr_t)(addr); \ + __ASM volatile("flw " STRINGIFY(freg) ", %0(%1) " \ + : : "I"(ofs), "r"(__addr) \ + : "memory"); \ + }) + +/** + * \brief Store a single-precision value from float point freg into memory using fsw instruction + * \details The FSW instruction stores a single-precision value from floating point register to memory + * \param [in] freg The floating point register(f0-f31), eg. FREG(0), f0 + * \param [in] addr The memory base address, 4 byte aligned required + * \param [in] ofs a 12-bit immediate signed byte offset value, should be an const value + * \remarks + * * FLW and FSW operations need to make sure the address is 4 bytes aligned, + * otherwise it will cause exception code 4(Load address misaligned) or 6 (Store/AMO address misaligned) + * * FLW and FSW do not modify the bits being transferred; in particular, the payloads of non-canonical + * NaNs are preserved + * + */ +#define __RV_FSW(freg, addr, ofs) \ + ({ \ + rv_csr_t __addr = (rv_csr_t)(addr); \ + __ASM volatile("fsw " STRINGIFY(freg) ", %0(%1) " \ + : : "I"(ofs), "r"(__addr) \ + : "memory"); \ + }) + +/** + * \brief Load a double-precision value from memory into float point register freg using fld instruction + * \details The FLD instruction loads a double-precision floating point value from memory + * address (addr + ofs) into floating point register freg(f0-f31) + * \param [in] freg The floating point register, eg. FREG(0), f0 + * \param [in] addr The memory base address, 8 byte aligned required + * \param [in] ofs a 12-bit immediate signed byte offset value, should be an const value + * \attention + * * Function only available for double precision floating point unit, FLEN = 64 + * \remarks + * * FLD and FSD operations need to make sure the address is 8 bytes aligned, + * otherwise it will cause exception code 4(Load address misaligned) or 6 (Store/AMO address misaligned) + * * FLD and FSD do not modify the bits being transferred; in particular, the payloads of non-canonical + * NaNs are preserved. + */ +#define __RV_FLD(freg, addr, ofs) \ + ({ \ + rv_csr_t __addr = (rv_csr_t)(addr); \ + __ASM volatile("fld " STRINGIFY(freg) ", %0(%1) " \ + : : "I"(ofs), "r"(__addr) \ + : "memory"); \ + }) + +/** + * \brief Store a double-precision value from float point freg into memory using fsd instruction + * \details The FSD instruction stores double-precision value from floating point register to memory + * \param [in] freg The floating point register(f0-f31), eg. FREG(0), f0 + * \param [in] addr The memory base address, 8 byte aligned required + * \param [in] ofs a 12-bit immediate signed byte offset value, should be an const value + * \attention + * * Function only available for double precision floating point unit, FLEN = 64 + * \remarks + * * FLD and FSD operations need to make sure the address is 8 bytes aligned, + * otherwise it will cause exception code 4(Load address misaligned) or 6 (Store/AMO address misaligned) + * * FLD and FSD do not modify the bits being transferred; in particular, the payloads of non-canonical + * NaNs are preserved. + * + */ +#define __RV_FSD(freg, addr, ofs) \ + ({ \ + rv_csr_t __addr = (rv_csr_t)(addr); \ + __ASM volatile("fsd " STRINGIFY(freg) ", %0(%1) " \ + : : "I"(ofs), "r"(__addr) \ + : "memory"); \ + }) + +/** + * \def __RV_FLOAD + * \brief Load a float point value from memory into float point register freg using flw/fld instruction + * \details + * * For Single-Precison Floating-Point Mode(__FPU_PRESENT == 1, __RISCV_FLEN == 32): + * It will call \ref __RV_FLW to load a single-precision floating point value from memory to floating point register + * * For Double-Precison Floating-Point Mode(__FPU_PRESENT == 2, __RISCV_FLEN == 64): + * It will call \ref __RV_FLD to load a double-precision floating point value from memory to floating point register + * + * \attention + * Function behaviour is different for __FPU_PRESENT = 1 or 2, please see the real function this macro represent + */ +/** + * \def __RV_FSTORE + * \brief Store a float value from float point freg into memory using fsw/fsd instruction + * \details + * * For Single-Precison Floating-Point Mode(__FPU_PRESENT == 1, __RISCV_FLEN == 32): + * It will call \ref __RV_FSW to store floating point register into memory + * * For Double-Precison Floating-Point Mode(__FPU_PRESENT == 2, __RISCV_FLEN == 64): + * It will call \ref __RV_FSD to store floating point register into memory + * + * \attention + * Function behaviour is different for __FPU_PRESENT = 1 or 2, please see the real function this macro represent + */ +#if __FPU_PRESENT == 1 +#define __RV_FLOAD __RV_FLW +#define __RV_FSTORE __RV_FSW +/** \brief Type of FPU register, depends on the FLEN defined in RISC-V */ +typedef uint32_t rv_fpu_t; +#elif __FPU_PRESENT == 2 +#define __RV_FLOAD __RV_FLD +#define __RV_FSTORE __RV_FSD +/** \brief Type of FPU register, depends on the FLEN defined in RISC-V */ +typedef uint64_t rv_fpu_t; +#endif /* __FPU_PRESENT == 2 */ + +/** + * \brief Save FPU context into variables for interrupt nesting + * \details + * This macro is used to declare variables which are used for saving + * FPU context, and it will store the nessary fpu registers into + * these variables, it need to be used in a interrupt when in this + * interrupt fpu registers are used. + * \remarks + * - It need to be used together with \ref RESTORE_FPU_CONTEXT + * - Don't use variable names __fpu_context in your ISR code + * - If you isr code will use fpu registers, and this interrupt is nested. + * Then you can do it like this: + * \code + * void eclic_mtip_handler(void) + * { + * // !!!Interrupt is enabled here!!! + * // !!!Higher priority interrupt could nest it!!! + * + * // Necessary only when you need to use fpu registers + * // in this isr handler functions + * SAVE_FPU_CONTEXT(); + * + * // put you own interrupt handling code here + * + * // pair of SAVE_FPU_CONTEXT() + * RESTORE_FPU_CONTEXT(); + * } + * \endcode + */ +#define SAVE_FPU_CONTEXT() \ + rv_fpu_t __fpu_context[20]; \ + __RV_FSTORE(FREG(0), __fpu_context, 0 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(1), __fpu_context, 1 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(2), __fpu_context, 2 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(3), __fpu_context, 3 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(4), __fpu_context, 4 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(5), __fpu_context, 5 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(6), __fpu_context, 6 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(7), __fpu_context, 7 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(10), __fpu_context, 8 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(11), __fpu_context, 9 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(12), __fpu_context, 10 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(13), __fpu_context, 11 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(14), __fpu_context, 12 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(15), __fpu_context, 13 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(16), __fpu_context, 14 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(17), __fpu_context, 15 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(28), __fpu_context, 16 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(29), __fpu_context, 17 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(30), __fpu_context, 18 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(31), __fpu_context, 19 << LOG_FPREGBYTES); + +/** + * \brief Restore necessary fpu registers from variables for interrupt nesting + * \details + * This macro is used restore necessary fpu registers from pre-defined variables + * in \ref SAVE_FPU_CONTEXT macro. + * \remarks + * - It need to be used together with \ref SAVE_FPU_CONTEXT + */ +#define RESTORE_FPU_CONTEXT() \ + __RV_FLOAD(FREG(0), __fpu_context, 0 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(1), __fpu_context, 1 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(2), __fpu_context, 2 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(3), __fpu_context, 3 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(4), __fpu_context, 4 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(5), __fpu_context, 5 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(6), __fpu_context, 6 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(7), __fpu_context, 7 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(10), __fpu_context, 8 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(11), __fpu_context, 9 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(12), __fpu_context, 10 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(13), __fpu_context, 11 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(14), __fpu_context, 12 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(15), __fpu_context, 13 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(16), __fpu_context, 14 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(17), __fpu_context, 15 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(28), __fpu_context, 16 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(29), __fpu_context, 17 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(30), __fpu_context, 18 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(31), __fpu_context, 19 << LOG_FPREGBYTES); +#else +#define SAVE_FPU_CONTEXT() +#define RESTORE_FPU_CONTEXT() +#endif /* __FPU_PRESENT > 0 */ +/** @} */ /* End of Doxygen Group NMSIS_Core_FPU_Functions */ + +#ifdef __cplusplus +} +#endif +#endif /* __CORE_FEATURE_FPU_H__ */ \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_plic.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_plic.h new file mode 100644 index 0000000..64c5f14 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_plic.h @@ -0,0 +1,426 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __CORE_FEATURE_PLIC__ +#define __CORE_FEATURE_PLIC__ +/*! + * @file core_feature_plic.h + * @brief PLIC feature API header file for RISC-V Core + */ +/* + * PLIC Feature Configuration Macro: + * 1. __PLIC_PRESENT: Define whether Platform Level Interrupt Controller (PLIC) Unit is present or not + * * 0: Not present + * * 1: Present + * 2. __PLIC_BASEADDR: Base address of the PLIC unit. + * 3. __PLIC_INTNUM : Define the external interrupt number of PLIC Unit + * + */ +#ifdef __cplusplus + extern "C" { +#endif + +#include "core_feature_base.h" + +#if defined(__PLIC_PRESENT) && (__PLIC_PRESENT == 1) +/** + * \defgroup NMSIS_Core_PLIC_Registers Register Define and Type Definitions Of PLIC + * \ingroup NMSIS_Core_Registers + * \brief Type definitions and defines for plic registers. + * + * @{ + */ + +/* 32 bits per source */ +#define PLIC_PRIORITY_OFFSET _AC(0x0000,UL) /*!< PLIC Priority register offset */ +#define PLIC_PRIORITY_SHIFT_PER_SOURCE 2 /*!< PLIC Priority register offset shift per source */ +/* 1 bit per source (1 address) */ +#define PLIC_PENDING_OFFSET _AC(0x1000,UL) /*!< PLIC Pending register offset */ +#define PLIC_PENDING_SHIFT_PER_SOURCE 0 /*!< PLIC Pending register offset shift per source */ + +/* 0x80 per context */ +#define PLIC_ENABLE_OFFSET _AC(0x2000,UL) /*!< PLIC Enable register offset */ +#define PLIC_ENABLE_SHIFT_PER_CONTEXT 7 /*!< PLIC Enable register offset shift per context */ + +#define PLIC_THRESHOLD_OFFSET _AC(0x200000,UL) /*!< PLIC Threshold register offset */ +#define PLIC_CLAIM_OFFSET _AC(0x200004,UL) /*!< PLIC Claim register offset */ +#define PLIC_THRESHOLD_SHIFT_PER_CONTEXT 12 /*!< PLIC Threshold register offset shift per context */ +#define PLIC_CLAIM_SHIFT_PER_CONTEXT 12 /*!< PLIC Claim register offset shift per context */ + +#ifndef __PLIC_BASEADDR +/* Base address of PLIC(__PLIC_BASEADDR) should be defined in */ +#error "__PLIC_BASEADDR is not defined, please check!" +#endif + +/* PLIC Memory mapping of Device */ +#define PLIC_BASE __PLIC_BASEADDR /*!< PLIC Base Address */ + +/** + * PLIC_GetHartID() is used to get plic hartid which might not be the same as cpu hart id, + * for example, cpu hartid may be 1, but plic hartid may be 0, then plic hartid offset is 1. + * If defined __PLIC_HARTID, it will use __PLIC_HARTID as plic hartid, + * otherwise, it will use __get_hart_index(). + * The cpu hartid is get by using __get_hart_id function + */ +#ifndef __PLIC_HARTID +#define PLIC_GetHartID() (__get_hart_index()) +#else +#define PLIC_GetHartID() (__PLIC_HARTID) +#endif + +#define PLIC_GetHartMContextID() (PLIC_GetHartID() << 1) +// TODO SMODE HARTID need to handle, maybe use a predefined variable of hartid +#define PLIC_GetHartSContextID() ((PLIC_GetHartID() << 1) + 1) + +#define PLIC_PRIORITY_REGADDR(source) ((PLIC_BASE) + (PLIC_PRIORITY_OFFSET) + ((source) << PLIC_PRIORITY_SHIFT_PER_SOURCE)) +#define PLIC_PENDING_REGADDR(source) ((PLIC_BASE) + (PLIC_PENDING_OFFSET) + (((source) >> 5) * 4)) +#define PLIC_ENABLE_REGADDR(ctxid, source) ((PLIC_BASE) + (PLIC_ENABLE_OFFSET) + ((ctxid) << PLIC_ENABLE_SHIFT_PER_CONTEXT) + ((source) >> 5) * 4) +#define PLIC_THRESHOLD_REGADDR(ctxid) ((PLIC_BASE) + (PLIC_THRESHOLD_OFFSET) + ((ctxid) << PLIC_THRESHOLD_SHIFT_PER_CONTEXT)) +#define PLIC_CLAIM_REGADDR(ctxid) ((PLIC_BASE) + (PLIC_CLAIM_OFFSET) + ((ctxid) << PLIC_CLAIM_SHIFT_PER_CONTEXT)) +#define PLIC_COMPLETE_REGADDR(ctxid) (PLIC_CLAIM_REGADDR(ctxid)) + + +/** @} */ /* end of group NMSIS_Core_PLIC_Registers */ + +/* ########################## PLIC functions #################################### */ +/** + * \defgroup NMSIS_Core_IntPlic PLIC Interrupt + * \brief Functions that manage interrupts via the PLIC. + * + * @{ + */ + +/** + * \brief Set priority threshold value of plic for selected context + * \details + * This function set priority threshold value of plic for selected context. + * \param [in] ctxid selected context id + * \param [in] thresh threshold value + * \remarks + * \sa + * - \ref PLIC_GetContextThreshold + */ +__STATIC_FORCEINLINE void PLIC_SetContextThreshold(uint32_t ctxid, uint32_t thresh) +{ + volatile uint32_t *thresh_reg = (uint32_t *)PLIC_THRESHOLD_REGADDR(ctxid); + + *thresh_reg = thresh; +} + +/** + * \brief Get priority threshold value of plic for selected context + * \details + * This function get priority threshold value of plic for selected context. + * \param [in] ctxid selected context id + * \return priority threshold value for selected context + * \remarks + * \sa + * - \ref PLIC_SetContextThreshold + */ +__STATIC_FORCEINLINE uint32_t PLIC_GetContextThreshold(uint32_t ctxid) +{ + volatile uint32_t *thresh_reg = (uint32_t *)PLIC_THRESHOLD_REGADDR(ctxid); + + return (*thresh_reg); +} + +/** + * \brief Enable interrupt of selected source plic for selected context + * \details + * This function enable interrupt of selected source plic for selected context. + * \param [in] ctxid selected context id + * \param [in] source interrupt source + * \remarks + * \sa + * - \ref PLIC_DisableContextInterrupt + */ +__STATIC_FORCEINLINE void PLIC_EnableContextInterrupt(uint32_t ctxid, uint32_t source) +{ + volatile uint32_t *enable_reg = (uint32_t *)PLIC_ENABLE_REGADDR(ctxid, source); + + uint32_t current = *enable_reg; + current = current | (1 << (source & 0x1F)); + *enable_reg = current; +} + +/** + * \brief Disable interrupt of selected source plic for selected context + * \details + * This function disable interrupt of selected source plic for selected context + * \param [in] ctxid selected context id + * \param [in] source interrupt source + * \remarks + * \sa + * - \ref PLIC_EnableContextInterrupt + */ +__STATIC_FORCEINLINE void PLIC_DisableContextInterrupt(uint32_t ctxid, uint32_t source) +{ + volatile uint32_t *enable_reg = (uint32_t *)PLIC_ENABLE_REGADDR(ctxid, source); + + uint32_t current = *enable_reg; + current = current & (~(1 << (source & 0x1F))); + *enable_reg = current; +} + +/** + * \brief Get interrupt enable status of selected source plic for selected context + * \details + * This function get interrupt enable of selected source plic for selected context. + * \param [in] ctxid selected context id + * \param [in] source interrupt source + * \return enable status for selected interrupt source for selected context + * \remarks + * \sa + * - \ref PLIC_EnableContextInterrupt + * - \ref PLIC_DisableContextInterrupt + */ +__STATIC_FORCEINLINE uint32_t PLIC_GetContextInterruptEnable(uint32_t ctxid, uint32_t source) +{ + volatile uint32_t *enable_reg = (uint32_t *)PLIC_ENABLE_REGADDR(ctxid, source); + + uint32_t current = *enable_reg; + current = (current >> (source & 0x1F)) & 0x1; + return current; +} + +/** + * \brief Set interrupt pending of selected source plic + * \details + * This function set interrupt pending of selected source plic. + * \param [in] source interrupt source + * \remarks + * \sa + * - \ref PLIC_GetInterruptPending + * - \ref PLIC_CLearInterruptPending + */ +__STATIC_FORCEINLINE void PLIC_SetInterruptPending(uint32_t source) +{ + volatile uint32_t *pending_reg = (uint32_t *)PLIC_PENDING_REGADDR(source); + + uint32_t current = *pending_reg; + current = current | (1 << (source & 0x1F)); + *pending_reg = current; +} + +/** + * \brief Clear interrupt pending of selected source plic + * \details + * This function clear interrupt pending of selected source plic + * \param [in] source interrupt source + * \remarks + * \sa + * - \ref PLIC_SetInterruptPending + * - \ref PLIC_GetInterruptPending + */ +__STATIC_FORCEINLINE void PLIC_ClearInterruptPending(uint32_t source) +{ + volatile uint32_t *pending_reg = (uint32_t *)PLIC_PENDING_REGADDR(source); + + uint32_t current = *pending_reg; + current = current & (~(1 << (source & 0x1F))); + *pending_reg = current; +} + +/** + * \brief Get interrupt pending status of selected source plic + * \details + * This function get interrupt pending of selected source plic + * \param [in] source interrupt source + * \return interrupt pending status for selected interrupt source + * \remarks + * \sa + * - \ref PLIC_SetInterruptPending + * - \ref PLIC_ClearInterruptPending + */ +__STATIC_FORCEINLINE uint32_t PLIC_GetInterruptPending(uint32_t source) +{ + volatile uint32_t *pending_reg = (uint32_t *)PLIC_PENDING_REGADDR(source); + + uint32_t current = *pending_reg; + current = (current >> (source & 0x1F)) & 0x1; + return current; +} + +/** + * \brief Set interrupt priority for selected source plic + * \details + * This function set interrupt priority for selected source plic. + * \param [in] source interrupt source + * \param [in] priority interrupt priority + * \remarks + * \sa + * - \ref PLIC_GetPriority + */ +__STATIC_FORCEINLINE void PLIC_SetPriority(uint32_t source, uint32_t priority) +{ + volatile uint32_t *priority_reg = (uint32_t *)PLIC_PRIORITY_REGADDR(source); + + *priority_reg = priority; +} + +/** + * \brief Get interrupt priority for selected source plic + * \details + * This function get interrupt priority for selected source plic. + * \param [in] source interrupt source + * \param [in] priority interrupt priority + * \remarks + * \sa + * - \ref PLIC_SetPriority + */ +__STATIC_FORCEINLINE uint32_t PLIC_GetPriority(uint32_t source) +{ + volatile uint32_t *priority_reg = (uint32_t *)PLIC_PRIORITY_REGADDR(source); + + return (*priority_reg); +} + +/** + * \brief Claim interrupt for plic for selected context + * \details + * This function claim interrupt for plic for selected context. + * \param [in] ctxid selected context id + * \return the ID of the highest priority pending interrupt or + * zero if there is no pending interrupt + * \remarks + * A successful claim will also atomically clear the corresponding pending bit + * on the interrupt source. The PLIC can perform a claim at any time and the + * claim operation is not affected by the setting of the priority threshold register. + * \sa + * - \ref PLIC_CompleteContextInterrupt + */ +__STATIC_FORCEINLINE uint32_t PLIC_ClaimContextInterrupt(uint32_t ctxid) +{ + volatile uint32_t *claim_reg = (uint32_t *)PLIC_CLAIM_REGADDR(ctxid); + + return (*claim_reg); +} + +/** + * \brief Complete interrupt for plic for selected context + * \details + * This function complete interrupt for plic for selected context. + * \param [in] ctxid selected context id + * \return the ID of the highest priority pending interrupt or + * zero if there is no pending interrupt + * \remarks + * The PLIC signals it has completed executing an interrupt handler by writing + * the interrupt ID it received from the claim to the claim/complete register. + * The PLIC does not check whether the completion ID is the same as the last + * claim ID for that context. + * If the completion ID does not match an interrupt source that is currently + * enabled for the context, the completion is silently ignored. + * \sa + * - \ref PLIC_ClaimContextInterrupt + */ +__STATIC_FORCEINLINE void PLIC_CompleteContextInterrupt(uint32_t ctxid, uint32_t source) +{ + volatile uint32_t *complete_reg = (uint32_t *)PLIC_COMPLETE_REGADDR(ctxid); + + *complete_reg = source; +} + +/** + * \brief Perform init for plic for selected context + * \details + * This function perform initialization steps for plic for selected context. + * \param [in] ctxid selected context id + * \param [in] num_sources plic interrupt source count number + * \param [in] enable plic interrupt enable or not + * \param [in] thresh plic interrupt threshold + * \remarks + * * Disable all interrupts + * * Set priority threshold to value specified by thresh + */ +__STATIC_FORCEINLINE void PLIC_Context_Init(uint32_t ctxid, uint32_t num_sources, uint32_t enable, uint32_t thresh) +{ + uint32_t i; + + for (i = 0; i < num_sources; i ++) { + if (enable) { + PLIC_EnableContextInterrupt(ctxid, i); + } else { + PLIC_DisableContextInterrupt(ctxid, i); + } + } + PLIC_SetContextThreshold(ctxid, thresh); +} + +#define PLIC_Init(num_sources, enable, thresh) PLIC_Context_Init(PLIC_GetHartMContextID(), (num_sources), (enable), (thresh)) +#define PLIC_Init_S(num_sources, enable, thresh) PLIC_Context_Init(PLIC_GetHartSContextID(), (num_sources), (enable), (thresh)) + +#define PLIC_ClaimInterrupt() PLIC_ClaimContextInterrupt(PLIC_GetHartMContextID()) +#define PLIC_ClaimInterrupt_S() PLIC_ClaimContextInterrupt(PLIC_GetHartSContextID()) + +#define PLIC_CompleteInterrupt(source) PLIC_CompleteContextInterrupt(PLIC_GetHartMContextID(), (source)) +#define PLIC_CompleteInterrupt_S(source) PLIC_CompleteContextInterrupt(PLIC_GetHartSContextID(), (source)) + +#define PLIC_GetInterruptEnable(source) PLIC_GetContextInterruptEnable(PLIC_GetHartMContextID(), (source)) +#define PLIC_GetInterruptEnable_S(source) PLIC_GetContextInterruptEnable(PLIC_GetHartSContextID(), (source)) + +#define PLIC_EnableInterrupt(source) PLIC_EnableContextInterrupt(PLIC_GetHartMContextID(), (source)) +#define PLIC_EnableInterrupt_S(source) PLIC_EnableContextInterrupt(PLIC_GetHartSContextID(), (source)) + +#define PLIC_DisableInterrupt(source) PLIC_DisableContextInterrupt(PLIC_GetHartMContextID(), (source)) +#define PLIC_DisableInterrupt_S(source) PLIC_DisableContextInterrupt(PLIC_GetHartSContextID(), (source)) + +#define PLIC_SetThreshold(source, thresh) PLIC_SetContextThreshold(PLIC_GetHartMContextID(), (source), (thresh)) +#define PLIC_SetThreshold_S(source, thresh) PLIC_SetContextThreshold(PLIC_GetHartSContextID(), (source), (thresh)) + +#define PLIC_GetThreshold(source) PLIC_GetContextThreshold(PLIC_GetHartMContextID(), (source)) +#define PLIC_GetThreshold_S(source) PLIC_GetContextThreshold(PLIC_GetHartSContextID(), (source)) + +/** + * \brief Set Trap entry address + * \details + * This function set trap entry address to 'CSR_MTVEC'. + * \param [in] addr trap entry address + * \remarks + * - This function use to set trap entry address to 'CSR_MTVEC'. + * \sa + * - \ref __get_trap_entry + */ +__STATIC_FORCEINLINE void __set_trap_entry(rv_csr_t addr) +{ + addr &= (rv_csr_t)(~0x7); + __RV_CSR_WRITE(CSR_MTVEC, addr); +} + +/** + * \brief Get trap entry address + * \details + * This function get trap entry address from 'CSR_MTVEC'. + * \return trap entry address + * \remarks + * - This function use to get trap entry address from 'CSR_MTVEC'. + * \sa + * - \ref __set_trap_entry + */ +__STATIC_FORCEINLINE rv_csr_t __get_trap_entry(void) +{ + unsigned long addr = __RV_CSR_READ(CSR_MTVEC); + return (addr); +} + +/** @} */ /* End of Doxygen Group NMSIS_Core_IntExc */ + +#endif /* defined(__PLIC_PRESENT) && (__PLIC_PRESENT == 1) */ + +#ifdef __cplusplus +} +#endif +#endif /** __CORE_FEATURE_PLIC__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_pmp.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_pmp.h new file mode 100644 index 0000000..9fd7ec7 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_pmp.h @@ -0,0 +1,384 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __CORE_FEATURE_PMP_H__ +#define __CORE_FEATURE_PMP_H__ +/*! + * @file core_feature_pmp.h + * @brief PMP feature API header file for Nuclei N/NX Core + */ +/* + * PMP Feature Configuration Macro: + * 1. __PMP_PRESENT: Define whether Physical Memory Protection(PMP) is present or not + * * 0: Not present + * * 1: Present + * 2. __PMP_ENTRY_NUM: Define the number of PMP entries, only 8 or 16 is configurable. + */ +#ifdef __cplusplus +extern "C" { +#endif + +#include "core_feature_base.h" +#include "core_compatiable.h" + +#if defined(__PMP_PRESENT) && (__PMP_PRESENT == 1) +/* ===== PMP Operations ===== */ +/** + * \defgroup NMSIS_Core_PMP_Functions PMP Functions + * \ingroup NMSIS_Core + * \brief Functions that related to the RISCV Phyiscal Memory Protection. + * \details + * Optional physical memory protection (PMP) unit provides per-hart machine-mode + * control registers to allow physical memory access privileges (read, write, execute) + * to be specified for each physical memory region. + * + * The PMP can supports region access control settings as small as four bytes. + * + * @{ + */ +#ifndef __PMP_ENTRY_NUM +/* numbers of PMP entries(__PMP_ENTRY_NUM) should be defined in */ +#error "__PMP_ENTRY_NUM is not defined, please check!" +#endif + +typedef struct PMP_CONFIG { + /** + * set locking bit, addressing mode, read, write, and instruction execution permissions, + * see \ref PMP_L, \ref PMP_R, \ref PMP_W, \ref PMP_X, .etc in + */ + unsigned int protection; + /** + * Size of memory region as power of 2, it has to be minimum 2 and maxium \ref __RISCV_XLEN according to the + * hard-wired granularity 2^N bytes, if N = 12, then order has to be at least 12; if not, the order read out + * is N though you configure less than N. + */ + unsigned long order; + /** + * Base address of memory region + * It must be 2^order aligned address + */ + unsigned long base_addr; +} pmp_config; + +/** + * \brief Get PMPCFGx Register by csr index + * \details Return the content of the PMPCFGx Register. + * \param [in] csr_idx PMPCFG CSR index(0-3) + * \return PMPCFGx Register value + * \remark + * - For RV64, only csr_idx = 0 and csr_idx = 2 is allowed. + * pmpcfg0 and pmpcfg2 hold the configurations + * for the 16 PMP entries, pmpcfg1 and pmpcfg3 are illegal + * - For RV32, pmpcfg0–pmpcfg3, hold the configurations + * pmp0cfg–pmp15cfg for the 16 PMP entries + */ +__STATIC_INLINE rv_csr_t __get_PMPCFGx(uint32_t csr_idx) +{ + switch (csr_idx) { + case 0: return __RV_CSR_READ(CSR_PMPCFG0); + case 1: return __RV_CSR_READ(CSR_PMPCFG1); + case 2: return __RV_CSR_READ(CSR_PMPCFG2); + case 3: return __RV_CSR_READ(CSR_PMPCFG3); + default: return 0; + } +} + +/** + * \brief Set PMPCFGx by csr index + * \details Write the given value to the PMPCFGx Register. + * \param [in] csr_idx PMPCFG CSR index(0-3) + * \param [in] pmpcfg PMPCFGx Register value to set + * \remark + * - For RV64, only csr_idx = 0 and csr_idx = 2 is allowed. + * pmpcfg0 and pmpcfg2 hold the configurations + * for the 16 PMP entries, pmpcfg1 and pmpcfg3 are illegal + * - For RV32, pmpcfg0–pmpcfg3, hold the configurations + * pmp0cfg–pmp15cfg for the 16 PMP entries + */ +__STATIC_INLINE void __set_PMPCFGx(uint32_t csr_idx, rv_csr_t pmpcfg) +{ + switch (csr_idx) { + case 0: __RV_CSR_WRITE(CSR_PMPCFG0, pmpcfg); break; + case 1: __RV_CSR_WRITE(CSR_PMPCFG1, pmpcfg); break; + case 2: __RV_CSR_WRITE(CSR_PMPCFG2, pmpcfg); break; + case 3: __RV_CSR_WRITE(CSR_PMPCFG3, pmpcfg); break; + default: return; + } +} + +/** + * \brief Get 8bit PMPxCFG Register by PMP entry index + * \details Return the content of the PMPxCFG Register. + * \param [in] entry_idx PMP region index(0-15) + * \return PMPxCFG Register value + */ +__STATIC_INLINE uint8_t __get_PMPxCFG(uint32_t entry_idx) +{ + rv_csr_t pmpcfgx = 0; + uint8_t csr_cfg_num = 0; + uint16_t csr_idx = 0; + uint16_t cfg_shift = 0; + + if (entry_idx >= __PMP_ENTRY_NUM) return 0; + +#if __RISCV_XLEN == 32 + csr_cfg_num = 4; + csr_idx = entry_idx >> 2; +#elif __RISCV_XLEN == 64 + csr_cfg_num = 8; + /* For RV64, pmpcfg0 and pmpcfg2 each hold 8 PMP entries, align by 2 */ + csr_idx = (entry_idx >> 2) & ~1; +#else + // TODO Add RV128 Handling + return 0; +#endif + pmpcfgx = __get_PMPCFGx(csr_idx); + /* + * first get specific pmpxcfg's order in one CSR composed of csr_cfg_num pmpxcfgs, + * then get pmpxcfg's bit position in one CSR by left shift 3(each pmpxcfg size is one byte) + */ + cfg_shift = (entry_idx & (csr_cfg_num - 1)) << 3; + + /* read specific pmpxcfg register value */ + return (uint8_t)(__RV_EXTRACT_FIELD(pmpcfgx, 0xFF << cfg_shift)); +} + +/** + * \brief Set 8bit PMPxCFG by pmp entry index + * \details Set the given pmpxcfg value to the PMPxCFG Register. + * \param [in] entry_idx PMPx region index(0-15) + * \param [in] pmpxcfg PMPxCFG register value to set + * \remark + * - For RV32, 4 pmpxcfgs are densely packed into one CSR in order + * For RV64, 8 pmpxcfgs are densely packed into one CSR in order + */ +__STATIC_INLINE void __set_PMPxCFG(uint32_t entry_idx, uint8_t pmpxcfg) +{ + rv_csr_t pmpcfgx = 0; + uint8_t csr_cfg_num = 0; + uint16_t csr_idx = 0; + uint16_t cfg_shift = 0; + if (entry_idx >= __PMP_ENTRY_NUM) return; + +#if __RISCV_XLEN == 32 + csr_cfg_num = 4; + csr_idx = entry_idx >> 2; +#elif __RISCV_XLEN == 64 + csr_cfg_num = 8; + /* For RV64, pmpcfg0 and pmpcfg2 each hold 8 PMP entries, align by 2 */ + csr_idx = (entry_idx >> 2) & ~1; +#else + // TODO Add RV128 Handling + return; +#endif + /* read specific pmpcfgx register value */ + pmpcfgx = __get_PMPCFGx(csr_idx); + /* + * first get specific pmpxcfg's order in one CSR composed of csr_cfg_num pmpxcfgs, + * then get pmpxcfg's bit position in one CSR by left shift 3(each pmpxcfg size is one byte) + */ + cfg_shift = (entry_idx & (csr_cfg_num - 1)) << 3; + + pmpcfgx = __RV_INSERT_FIELD(pmpcfgx, 0xFFUL << cfg_shift, pmpxcfg); + __set_PMPCFGx(csr_idx, pmpcfgx); +} + +/** + * \brief Get PMPADDRx Register by CSR index + * \details Return the content of the PMPADDRx Register. + * \param [in] csr_idx PMP region CSR index(0-15) + * \return PMPADDRx Register value + */ +__STATIC_INLINE rv_csr_t __get_PMPADDRx(uint32_t csr_idx) +{ + switch (csr_idx) { + case 0: return __RV_CSR_READ(CSR_PMPADDR0); + case 1: return __RV_CSR_READ(CSR_PMPADDR1); + case 2: return __RV_CSR_READ(CSR_PMPADDR2); + case 3: return __RV_CSR_READ(CSR_PMPADDR3); + case 4: return __RV_CSR_READ(CSR_PMPADDR4); + case 5: return __RV_CSR_READ(CSR_PMPADDR5); + case 6: return __RV_CSR_READ(CSR_PMPADDR6); + case 7: return __RV_CSR_READ(CSR_PMPADDR7); + case 8: return __RV_CSR_READ(CSR_PMPADDR8); + case 9: return __RV_CSR_READ(CSR_PMPADDR9); + case 10: return __RV_CSR_READ(CSR_PMPADDR10); + case 11: return __RV_CSR_READ(CSR_PMPADDR11); + case 12: return __RV_CSR_READ(CSR_PMPADDR12); + case 13: return __RV_CSR_READ(CSR_PMPADDR13); + case 14: return __RV_CSR_READ(CSR_PMPADDR14); + case 15: return __RV_CSR_READ(CSR_PMPADDR15); + default: return 0; + } +} + +/** + * \brief Set PMPADDRx by CSR index + * \details Write the given value to the PMPADDRx Register. + * \param [in] csr_idx PMP region CSR index(0-15) + * \param [in] pmpaddr PMPADDRx Register value to set + */ +__STATIC_INLINE void __set_PMPADDRx(uint32_t csr_idx, rv_csr_t pmpaddr) +{ + switch (csr_idx) { + case 0: __RV_CSR_WRITE(CSR_PMPADDR0, pmpaddr); break; + case 1: __RV_CSR_WRITE(CSR_PMPADDR1, pmpaddr); break; + case 2: __RV_CSR_WRITE(CSR_PMPADDR2, pmpaddr); break; + case 3: __RV_CSR_WRITE(CSR_PMPADDR3, pmpaddr); break; + case 4: __RV_CSR_WRITE(CSR_PMPADDR4, pmpaddr); break; + case 5: __RV_CSR_WRITE(CSR_PMPADDR5, pmpaddr); break; + case 6: __RV_CSR_WRITE(CSR_PMPADDR6, pmpaddr); break; + case 7: __RV_CSR_WRITE(CSR_PMPADDR7, pmpaddr); break; + case 8: __RV_CSR_WRITE(CSR_PMPADDR8, pmpaddr); break; + case 9: __RV_CSR_WRITE(CSR_PMPADDR9, pmpaddr); break; + case 10: __RV_CSR_WRITE(CSR_PMPADDR10, pmpaddr); break; + case 11: __RV_CSR_WRITE(CSR_PMPADDR11, pmpaddr); break; + case 12: __RV_CSR_WRITE(CSR_PMPADDR12, pmpaddr); break; + case 13: __RV_CSR_WRITE(CSR_PMPADDR13, pmpaddr); break; + case 14: __RV_CSR_WRITE(CSR_PMPADDR14, pmpaddr); break; + case 15: __RV_CSR_WRITE(CSR_PMPADDR15, pmpaddr); break; + default: return; + } +} + +/** + * \brief Set PMP entry by entry idx + * \details Write the given value to the PMPxCFG Register and PMPADDRx. + * \param [in] entry_idx PMP entry index(0-15) + * \param [in] pmp_cfg structure of L, X, W, R field of PMP configuration register, memory region base address + * and size of memory region as power of 2 + * \remark + * - If the size of memory region is 2^12(4KB) range, pmp_cfg->order makes 12, and the like. + * - Suppose the size of memory region is 2^X bytes range, if X >=3, the NA4 mode is not selectable, NAPOT is selected. + * - TOR of A field in PMP configuration register is not considered here. + */ +__STATIC_INLINE void __set_PMPENTRYx(uint32_t entry_idx, const pmp_config *pmp_cfg) +{ + unsigned int cfg_shift, cfg_csr_idx, addr_csr_idx = 0; + unsigned long cfgmask, addrmask = 0; + unsigned long pmpcfg, pmpaddr = 0; + unsigned long protection, csr_cfg_num = 0; + /* check parameters */ + if (entry_idx >= __PMP_ENTRY_NUM || pmp_cfg->order > __RISCV_XLEN || pmp_cfg->order < PMP_SHIFT) return; + + /* calculate PMP register and offset */ +#if __RISCV_XLEN == 32 + csr_cfg_num = 4; + cfg_csr_idx = (entry_idx >> 2); +#elif __RISCV_XLEN == 64 + csr_cfg_num = 8; + cfg_csr_idx = ((entry_idx >> 2)) & ~1; +#else + // TODO Add RV128 Handling + return; +#endif + /* + * first get specific pmpxcfg's order in one CSR composed of csr_cfg_num pmpxcfgs, + * then get pmpxcfg's bit position in one CSR by left shift 3, each pmpxcfg size is one byte + */ + cfg_shift = (entry_idx & (csr_cfg_num - 1)) << 3; + addr_csr_idx = entry_idx; + + /* encode PMP config */ + protection = (unsigned long)pmp_cfg->protection; + protection |= (PMP_SHIFT == pmp_cfg->order) ? PMP_A_NA4 : PMP_A_NAPOT; + cfgmask = ~(0xFFUL << cfg_shift); + pmpcfg = (__get_PMPCFGx(cfg_csr_idx) & cfgmask); + pmpcfg |= ((protection << cfg_shift) & ~cfgmask); + + /* encode PMP address */ + if (PMP_SHIFT == pmp_cfg->order) { /* NA4 */ + pmpaddr = (pmp_cfg->base_addr >> PMP_SHIFT); + } else { /* NAPOT */ + addrmask = (1UL << (pmp_cfg->order - PMP_SHIFT)) - 1; + pmpaddr = ((pmp_cfg->base_addr >> PMP_SHIFT) & ~addrmask); + pmpaddr |= (addrmask >> 1); + } + /* + * write csrs, update the address first, in case the entry is locked that + * we won't be able to modify it after we set the config csr. + */ + __set_PMPADDRx(addr_csr_idx, pmpaddr); + __set_PMPCFGx(cfg_csr_idx, pmpcfg); +} + +/** + * \brief Get PMP entry by entry idx + * \details Write the given value to the PMPxCFG Register and PMPADDRx. + * \param [in] entry_idx PMP entry index(0-15) + * \param [out] pmp_cfg structure of L, X, W, R, A field of PMP configuration register, memory region base + * address and size of memory region as power of 2 + * \return -1 failure, else 0 success + * \remark + * - If the size of memory region is 2^12(4KB) range, pmp_cfg->order makes 12, and the like. + * - TOR of A field in PMP configuration register is not considered here. + */ +__STATIC_INLINE int __get_PMPENTRYx(unsigned int entry_idx, pmp_config *pmp_cfg) +{ + unsigned int cfg_shift, cfg_csr_idx, addr_csr_idx = 0; + unsigned long cfgmask, pmpcfg, prot = 0; + unsigned long t1, addr, pmpaddr, len = 0; + uint8_t csr_cfg_num = 0; + /* check parameters */ + if (entry_idx >= __PMP_ENTRY_NUM || !pmp_cfg) return -1; + + /* calculate PMP register and offset */ +#if __RISCV_XLEN == 32 + csr_cfg_num = 4; + cfg_csr_idx = entry_idx >> 2; +#elif __RISCV_XLEN == 64 + csr_cfg_num = 8; + cfg_csr_idx = (entry_idx>> 2) & ~1; +#else +// TODO Add RV128 Handling + return -1; +#endif + + cfg_shift = (entry_idx & (csr_cfg_num - 1)) << 3; + addr_csr_idx = entry_idx; + + /* decode PMP config */ + cfgmask = (0xFFUL << cfg_shift); + pmpcfg = (__get_PMPCFGx(cfg_csr_idx) & cfgmask); + prot = pmpcfg >> cfg_shift; + + /* decode PMP address */ + pmpaddr = __get_PMPADDRx(addr_csr_idx); + if (PMP_A_NAPOT == (prot & PMP_A)) { + t1 = __CTZ(~pmpaddr); + addr = (pmpaddr & ~((1UL << t1) - 1)) << PMP_SHIFT; + len = (t1 + PMP_SHIFT + 1); + } else { + addr = pmpaddr << PMP_SHIFT; + len = PMP_SHIFT; + } + + /* return details */ + pmp_cfg->protection = prot; + pmp_cfg->base_addr = addr; + pmp_cfg->order = len; + + return 0; +} + +/** @} */ /* End of Doxygen Group NMSIS_Core_PMP_Functions */ +#endif /* defined(__PMP_PRESENT) && (__PMP_PRESENT == 1) */ + +#ifdef __cplusplus +} +#endif +#endif /* __CORE_FEATURE_PMP_H__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_spmp.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_spmp.h new file mode 100644 index 0000000..a722e50 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_spmp.h @@ -0,0 +1,449 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __CORE_FEATURE_SPMP_H__ +#define __CORE_FEATURE_SPMP_H__ +/*! + * @file core_feature_spmp.h + * @brief sPMP(has upgraded to S-mode Memory Protection Unit, renamed as SMPU) feature API header file for Nuclei N/NX Core + */ +/* + * sPMP Feature Configuration Macro: + * 1. __SPMP_PRESENT: Define whether sPMP is present or not + * __SMPU_PRESENT: Define whether SMPU is present or not + * * 0: Not present + * * 1: Present + * 2. __SPMP_ENTRY_NUM: Define the number of sPMP entries, only 8 or 16 is configurable + * __SMPU_ENTRY_NUM: Define the number of SMPU entries, only 8 or 16 is configurable + * __SMPU_ENTRY_NUM is the same as __SPMP_ENTRY_NUM + */ +#ifdef __cplusplus +extern "C" { +#endif + +#include "core_feature_base.h" +#include "core_compatiable.h" + +#if defined(__SPMP_PRESENT) && (__SPMP_PRESENT == 1) + +/* ===== sPMP Operations ===== */ +/** + * \defgroup NMSIS_Core_SPMP_Functions sPMP Functions + * \ingroup NMSIS_Core + * \brief Functions that related to the RISCV supervisor-mode Phyiscal Memory Protection. + * \details + * Optional superviosr physical memory protection (sPMP) unit provides per-hart supervisor-mode + * control registers to allow physical memory access privileges (read, write, execute) + * to be specified for each physical memory region. The sPMP values are checked after the physical + * address to be accessed pass PMP checks described in the RISC-V privileged spec. + * + * Like PMP, the sPMP can supports region access control settings as small as four bytes. + * + * @{ + */ +#ifndef __SPMP_ENTRY_NUM +/* Number of __SPMP_ENTRY_NUM entries should be defined in */ +#error "__SPMP_ENTRY_NUM is not defined, please check!" +#endif + +typedef struct SPMP_CONFIG { + /** + * Set permissions using macros \ref SMPU_S/\ref SMPU_R/\ref SMPU_W/\ref SMPU_X of SMPU; + * \ref SPMP_L/\ref SPMP_U/\ref SPMP_R/\ref SPMP_W/\ref SPMP_X of sPMP, + * see details in riscv spec of SMPU/sPMP + */ + unsigned int protection; + /** + * Size of memory region as power of 2, it has to be minimum 2 and maxium \ref __RISCV_XLEN according to the + * hardwired granularity 2^N bytes, if N = 12, then order has to be at least 12; if not, the order read out + * is N though you configure less than N. + */ + unsigned long order; + /** + * Base address of memory region + * It must be 2^order aligned address + */ + unsigned long base_addr; +} spmp_config; + +/** + * \brief Get sPMPCFGx Register by csr index + * \details Return the content of the sPMPCFGx Register. + * \param [in] csr_idx sPMPCFG CSR index(0-3) + * \return sPMPCFGx Register value + * \remark + * - For RV64, only csr_idx = 0 and csr_idx = 2 is allowed. + * spmpcfg0 and spmpcfg2 hold the configurations + * for the 16 sPMP entries, spmpcfg1 and spmpcfg3 are illegal + * - For RV32, spmpcfg0–spmpcfg3, hold the configurations + * spmp0cfg–spmp15cfg for the 16 sPMP entries + */ +__STATIC_INLINE rv_csr_t __get_sPMPCFGx(uint32_t csr_idx) +{ + switch (csr_idx) { + case 0: return __RV_CSR_READ(CSR_SPMPCFG0); + case 1: return __RV_CSR_READ(CSR_SPMPCFG1); + case 2: return __RV_CSR_READ(CSR_SPMPCFG2); + case 3: return __RV_CSR_READ(CSR_SPMPCFG3); + default: return 0; + } +} + +/** + * \brief Set sPMPCFGx by csr index + * \details Write the given value to the sPMPCFGx Register. + * \param [in] csr_idx sPMPCFG CSR index(0-3) + * \param [in] spmpcfg sPMPCFGx Register value to set + * \remark + * - For RV64, only csr_idx = 0 and csr_idx = 2 is allowed. + * spmpcfg0 and spmpcfg2 hold the configurations + * for the 16 sPMP entries, spmpcfg1 and spmpcfg3 are illegal + * - For RV32, spmpcfg0–spmpcfg3, hold the configurations + * spmp0cfg–spmp15cfg for the 16 sPMP entries + */ +__STATIC_INLINE void __set_sPMPCFGx(uint32_t csr_idx, rv_csr_t spmpcfg) +{ + switch (csr_idx) { + case 0: __RV_CSR_WRITE(CSR_SPMPCFG0, spmpcfg); break; + case 1: __RV_CSR_WRITE(CSR_SPMPCFG1, spmpcfg); break; + case 2: __RV_CSR_WRITE(CSR_SPMPCFG2, spmpcfg); break; + case 3: __RV_CSR_WRITE(CSR_SPMPCFG3, spmpcfg); break; + default: return; + } +} + +/** + * \brief Get 8bit sPMPxCFG Register by sPMP entry index + * \details Return the content of the sPMPxCFG Register. + * \param [in] entry_idx sPMP region index(0-15) + * \return sPMPxCFG Register value + */ +__STATIC_INLINE uint8_t __get_sPMPxCFG(uint32_t entry_idx) +{ + rv_csr_t spmpcfgx = 0; + uint8_t csr_cfg_num = 0; + uint16_t csr_idx = 0; + uint16_t cfg_shift = 0; + + if (entry_idx >= __SPMP_ENTRY_NUM) return 0; + +#if __RISCV_XLEN == 32 + csr_cfg_num = 4; + csr_idx = entry_idx >> 2; +#elif __RISCV_XLEN == 64 + csr_cfg_num = 8; + /* For RV64, spmpcfg0 and spmpcfg2 each hold 8 sPMP entries, align by 2 */ + csr_idx = (entry_idx >> 2) & ~1; +#else + // TODO Add RV128 Handling + return 0; +#endif + spmpcfgx = __get_sPMPCFGx(csr_idx); + /* + * first get specific spmpxcfg's order in one CSR composed of csr_cfg_num spmpxcfgs, + * then get spmpxcfg's bit position in one CSR by left shift 3(each spmpxcfg size is one byte) + */ + cfg_shift = (entry_idx & (csr_cfg_num - 1)) << 3; + + /* read specific spmpxcfg register value */ + return (uint8_t)(__RV_EXTRACT_FIELD(spmpcfgx, 0xFF << cfg_shift)); +} + +/** + * \brief Set 8bit sPMPxCFG by spmp entry index + * \details Set the given spmpxcfg value to the sPMPxCFG Register. + * \param [in] entry_idx sPMPx region index(0-15) + * \param [in] spmpxcfg sPMPxCFG register value to set + * \remark + * - For RV32, 4 spmpxcfgs are densely packed into one CSR in order + * For RV64, 8 spmpxcfgs are densely packed into one CSR in order + */ +__STATIC_INLINE void __set_sPMPxCFG(uint32_t entry_idx, uint8_t spmpxcfg) +{ + rv_csr_t spmpcfgx = 0; + uint8_t csr_cfg_num = 0; + uint16_t csr_idx = 0; + uint16_t cfg_shift = 0; + if (entry_idx >= __SPMP_ENTRY_NUM) return; + +#if __RISCV_XLEN == 32 + csr_cfg_num = 4; + csr_idx = entry_idx >> 2; +#elif __RISCV_XLEN == 64 + csr_cfg_num = 8; + /* For RV64, spmpcfg0 and spmpcfg2 each hold 8 sPMP entries, align by 2 */ + csr_idx = (entry_idx >> 2) & ~1; +#else + // TODO Add RV128 Handling + return; +#endif + /* read specific spmpcfgx register value */ + spmpcfgx = __get_sPMPCFGx(csr_idx); + /* + * first get specific spmpxcfg's order in one CSR composed of csr_cfg_num spmpxcfgs, + * then get spmpxcfg's bit position in one CSR by left shift 3(each spmpxcfg size is one byte) + */ + cfg_shift = (entry_idx & (csr_cfg_num - 1)) << 3; + + spmpcfgx = __RV_INSERT_FIELD(spmpcfgx, 0xFFUL << cfg_shift, spmpxcfg); + __set_sPMPCFGx(csr_idx, spmpcfgx); +} + +/** + * \brief Get sPMPADDRx Register by CSR index + * \details Return the content of the sPMPADDRx Register. + * \param [in] csr_idx sPMP region CSR index(0-15) + * \return sPMPADDRx Register value + */ +__STATIC_INLINE rv_csr_t __get_sPMPADDRx(uint32_t csr_idx) +{ + switch (csr_idx) { + case 0: return __RV_CSR_READ(CSR_SPMPADDR0); + case 1: return __RV_CSR_READ(CSR_SPMPADDR1); + case 2: return __RV_CSR_READ(CSR_SPMPADDR2); + case 3: return __RV_CSR_READ(CSR_SPMPADDR3); + case 4: return __RV_CSR_READ(CSR_SPMPADDR4); + case 5: return __RV_CSR_READ(CSR_SPMPADDR5); + case 6: return __RV_CSR_READ(CSR_SPMPADDR6); + case 7: return __RV_CSR_READ(CSR_SPMPADDR7); + case 8: return __RV_CSR_READ(CSR_SPMPADDR8); + case 9: return __RV_CSR_READ(CSR_SPMPADDR9); + case 10: return __RV_CSR_READ(CSR_SPMPADDR10); + case 11: return __RV_CSR_READ(CSR_SPMPADDR11); + case 12: return __RV_CSR_READ(CSR_SPMPADDR12); + case 13: return __RV_CSR_READ(CSR_SPMPADDR13); + case 14: return __RV_CSR_READ(CSR_SPMPADDR14); + case 15: return __RV_CSR_READ(CSR_SPMPADDR15); + default: return 0; + } +} + +/** + * \brief Set sPMPADDRx by CSR index + * \details Write the given value to the sPMPADDRx Register. + * \param [in] csr_idx sPMP region CSR index(0-15) + * \param [in] spmpaddr sPMPADDRx Register value to set + */ +__STATIC_INLINE void __set_sPMPADDRx(uint32_t csr_idx, rv_csr_t spmpaddr) +{ + switch (csr_idx) { + case 0: __RV_CSR_WRITE(CSR_SPMPADDR0, spmpaddr); break; + case 1: __RV_CSR_WRITE(CSR_SPMPADDR1, spmpaddr); break; + case 2: __RV_CSR_WRITE(CSR_SPMPADDR2, spmpaddr); break; + case 3: __RV_CSR_WRITE(CSR_SPMPADDR3, spmpaddr); break; + case 4: __RV_CSR_WRITE(CSR_SPMPADDR4, spmpaddr); break; + case 5: __RV_CSR_WRITE(CSR_SPMPADDR5, spmpaddr); break; + case 6: __RV_CSR_WRITE(CSR_SPMPADDR6, spmpaddr); break; + case 7: __RV_CSR_WRITE(CSR_SPMPADDR7, spmpaddr); break; + case 8: __RV_CSR_WRITE(CSR_SPMPADDR8, spmpaddr); break; + case 9: __RV_CSR_WRITE(CSR_SPMPADDR9, spmpaddr); break; + case 10: __RV_CSR_WRITE(CSR_SPMPADDR10, spmpaddr); break; + case 11: __RV_CSR_WRITE(CSR_SPMPADDR11, spmpaddr); break; + case 12: __RV_CSR_WRITE(CSR_SPMPADDR12, spmpaddr); break; + case 13: __RV_CSR_WRITE(CSR_SPMPADDR13, spmpaddr); break; + case 14: __RV_CSR_WRITE(CSR_SPMPADDR14, spmpaddr); break; + case 15: __RV_CSR_WRITE(CSR_SPMPADDR15, spmpaddr); break; + default: return; + } +} + +/** + * \brief Set sPMP entry by entry idx + * \details Write the given value to the sPMPxCFG Register and sPMPADDRx. + * \param [in] entry_idx sPMP entry index(0-15) + * \param [in] spmp_cfg structure of L,U,X,W,R field of sPMP configuration register, memory region base address + * and size of memory region as power of 2 + * \remark + * - If the size of memory region is 2^12(4KB) range, spmp_cfg->order makes 12, and the like. + * - Suppose the size of memory region is 2^X bytes range, if X >=3, the NA4 mode is not selectable, NAPOT is selected. + * - TOR of A field in sPMP configuration register is not considered here. + */ +__STATIC_INLINE void __set_sPMPENTRYx(uint32_t entry_idx, const spmp_config *spmp_cfg) +{ + unsigned int cfg_shift, cfg_csr_idx, addr_csr_idx = 0; + unsigned long cfgmask, addrmask = 0; + unsigned long spmpcfg, spmpaddr = 0; + unsigned long protection, csr_cfg_num = 0; + /* check parameters */ + if (entry_idx >= __SPMP_ENTRY_NUM || spmp_cfg->order > __RISCV_XLEN || spmp_cfg->order < SPMP_SHIFT) return; + + /* calculate sPMP register and offset */ +#if __RISCV_XLEN == 32 + csr_cfg_num = 4; + cfg_csr_idx = (entry_idx >> 2); +#elif __RISCV_XLEN == 64 + csr_cfg_num = 8; + cfg_csr_idx = ((entry_idx >> 2)) & ~1; +#else + // TODO Add RV128 Handling + return; +#endif + /* + * first get specific spmpxcfg's order in one CSR composed of csr_cfg_num spmpxcfgs, + * then get spmpxcfg's bit position in one CSR by left shift 3, each spmpxcfg size is one byte + */ + cfg_shift = (entry_idx & (csr_cfg_num - 1)) << 3; + addr_csr_idx = entry_idx; + + /* encode sPMP config */ + protection = (unsigned long)spmp_cfg->protection; + protection |= (SPMP_SHIFT == spmp_cfg->order) ? SPMP_A_NA4 : SPMP_A_NAPOT; + cfgmask = ~(0xFFUL << cfg_shift); + spmpcfg = (__get_sPMPCFGx(cfg_csr_idx) & cfgmask); + spmpcfg |= ((protection << cfg_shift) & ~cfgmask); + + /* encode sPMP address */ + if (SPMP_SHIFT == spmp_cfg->order) { /* NA4 */ + spmpaddr = (spmp_cfg->base_addr >> SPMP_SHIFT); + } else { /* NAPOT */ + addrmask = (1UL << (spmp_cfg->order - SPMP_SHIFT)) - 1; + spmpaddr = ((spmp_cfg->base_addr >> SPMP_SHIFT) & ~addrmask); + spmpaddr |= (addrmask >> 1); + } + /* + * write csrs, update the address first, in case the entry is locked that + * we won't be able to modify it after we set the config csr. + */ + __set_sPMPADDRx(addr_csr_idx, spmpaddr); + __set_sPMPCFGx(cfg_csr_idx, spmpcfg); +} + +/** + * \brief Get sPMP entry by entry idx + * \details Write the given value to the sPMPxCFG Register and sPMPADDRx. + * \param [in] entry_idx sPMP entry index(0-15) + * \param [out] spmp_cfg structure of L, U, X, W, R, A field of sPMP configuration register, memory region base + * address and size of memory region as power of 2 + * \return -1 failure, else 0 success + * \remark + * - If the size of memory region is 2^12(4KB) range, spmp_cfg->order makes 12, and the like. + * - TOR of A field in PMP configuration register is not considered here. + */ +__STATIC_INLINE int __get_sPMPENTRYx(unsigned int entry_idx, spmp_config *spmp_cfg) +{ + unsigned int cfg_shift, cfg_csr_idx, addr_csr_idx = 0; + unsigned long cfgmask, spmpcfg, prot = 0; + unsigned long t1, addr, spmpaddr, len = 0; + uint8_t csr_cfg_num = 0; + /* check parameters */ + if (entry_idx >= __SPMP_ENTRY_NUM || !spmp_cfg) return -1; + + /* calculate sPMP register and offset */ +#if __RISCV_XLEN == 32 + csr_cfg_num = 4; + cfg_csr_idx = entry_idx >> 2; +#elif __RISCV_XLEN == 64 + csr_cfg_num = 8; + cfg_csr_idx = (entry_idx >> 2) & ~1; +#else +// TODO Add RV128 Handling + return -1; +#endif + + cfg_shift = (entry_idx & (csr_cfg_num - 1)) << 3; + addr_csr_idx = entry_idx; + + /* decode sPMP config */ + cfgmask = (0xFFUL << cfg_shift); + spmpcfg = (__get_sPMPCFGx(cfg_csr_idx) & cfgmask); + prot = spmpcfg >> cfg_shift; + + /* decode sPMP address */ + spmpaddr = __get_sPMPADDRx(addr_csr_idx); + if (SPMP_A_NAPOT == (prot & SPMP_A)) { + t1 = __CTZ(~spmpaddr); + addr = (spmpaddr & ~((1UL << t1) - 1)) << SPMP_SHIFT; + len = (t1 + SPMP_SHIFT + 1); + } else { + addr = spmpaddr << SPMP_SHIFT; + len = SPMP_SHIFT; + } + + /* return details */ + spmp_cfg->protection = prot; + spmp_cfg->base_addr = addr; + spmp_cfg->order = len; + + return 0; +} + +#if defined(__SMPU_PRESENT) && (__SMPU_PRESENT == 1) +/** + * sPMP has upgraded to S-mode Memory Protection Unit, renamed as SMPU, but still share the apis with sPMP's + */ +typedef spmp_config smpu_config; +#define __get_SMPUCFGx __get_sPMPCFGx +#define __set_SMPUCFGx __set_sPMPCFGx +#define __get_SMPUxCFG __get_sPMPxCFG +#define __set_SMPUxCFG __set_sPMPxCFG +#define __get_SMPUADDRx __get_sPMPADDRx +#define __set_SMPUADDRx __set_sPMPADDRx +#define __set_SMPUENTRYx __set_sPMPENTRYx +#define __get_SMPUENTRYx __get_sPMPENTRYx + +/** + * \brief Set SMPU each entry's on/off status + * \details Write the given value to the SMPUSWITCHx Register. + * \param [in] val activate each entry(max to 64) or not + * \remark + * - Each bit of this register holds on/off status of the corresponding SMPU entry respectively. + * - An SMPU entry is activated only when both corresponding bits in smpuswitch and + * A field of smpuicfg are set. (i.e., smpuswitch[i] & smpu[i]cfg.A). + */ +__STATIC_INLINE void __set_SMPUSWITCHx(uint64_t val) +{ +#if __RISCV_XLEN == 32 + __RV_CSR_WRITE(CSR_SMPUSWITCH0, (uint32_t)val); + __RV_CSR_WRITE(CSR_SMPUSWITCH1, (uint32_t)(val >> 32)); +#elif __RISCV_XLEN == 64 + __RV_CSR_WRITE(CSR_SMPUSWITCH0, val); +#else + // TODO Add RV128 Handling +#endif +} + +/** + * \brief Get SMPU each entry's on/off status + * \details Get the value of the SMPUSWITCHx Register. + * \remark + * - Each bit of this register holds on/off status of the corresponding SMPU entry respectively. + * - An SMPU entry is activated only when both corresponding bits in smpuswitch and + * A field of smpuicfg are set. (i.e., smpuswitch[i] & smpu[i]cfg.A). + */ +__STATIC_INLINE uint64_t __get_SMPUSWITCHx(void) +{ +#if __RISCV_XLEN == 32 + uint32_t lo, hi = 0; + lo = __RV_CSR_READ(CSR_SMPUSWITCH0); + hi = __RV_CSR_READ(CSR_SMPUSWITCH1); + return (uint64_t)((((uint64_t)hi) << 32) | lo); +#elif __RISCV_XLEN == 64 + return (uint64_t)__RV_CSR_READ(CSR_SMPUSWITCH0); +#else + // TODO Add RV128 Handling +#endif +} + +#endif + +/** @} */ /* End of Doxygen Group NMSIS_Core_SPMP_Functions */ +#endif /* defined(__SPMP_PRESENT) && (__SPMP_PRESENT == 1) */ + +#ifdef __cplusplus +} +#endif +#endif /* __CORE_FEATURE_SPMP_H__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_timer.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_timer.h new file mode 100644 index 0000000..f1b03f7 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_timer.h @@ -0,0 +1,683 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __CORE_FEATURE_TIMER_H__ +#define __CORE_FEATURE_TIMER_H__ +/*! + * @file core_feature_timer.h + * @brief System Timer feature API header file for Nuclei N/NX Core + */ +/* + * System Timer Feature Configuration Macro: + * 1. __SYSTIMER_PRESENT: Must, Define whether Private System Timer is present or not. + * * 0: Not present + * * 1: Present + * 2. __SYSTIMER_BASEADDR: Must, Define the base address of the System Timer. + * 3. __SYSTIMER_HARTID: Optional, Define the system timer hart index of the cpu, important for case when cpu hartid and cpu hart index are different, only set it if your cpu is single core. + */ +#ifdef __cplusplus +extern "C" { +#endif + +#include "core_feature_base.h" + +#if defined(__SYSTIMER_PRESENT) && (__SYSTIMER_PRESENT == 1) +/** + * \defgroup NMSIS_Core_SysTimer_Registers Register Define and Type Definitions Of System Timer + * \ingroup NMSIS_Core_Registers + * \brief Type definitions and defines for system timer registers. + * + * @{ + */ +/** + * \brief Structure type to access the System Timer (SysTimer). + * \details + * Structure definition to access the system timer(SysTimer). + * \remarks + * - MSFTRST register is introduced in Nuclei N Core version 1.3(\ref __NUCLEI_N_REV >= 0x0103) + * - MSTOP register is renamed to MTIMECTL register in Nuclei N Core version 1.4(\ref __NUCLEI_N_REV >= 0x0104) + * - CMPCLREN and CLKSRC bit in MTIMECTL register is introduced in Nuclei N Core version 1.4(\ref __NUCLEI_N_REV >= 0x0104) + */ +typedef struct { + __IOM uint64_t MTIMER; /*!< Offset: 0x000 (R/W) System Timer current value 64bits Register */ + __IOM uint64_t MTIMERCMP; /*!< Offset: 0x008 (R/W) System Timer compare Value 64bits Register */ + __IOM uint32_t RESERVED0[0x3F8]; /*!< Offset: 0x010 - 0xFEC Reserved */ + __IOM uint32_t MSFTRST; /*!< Offset: 0xFF0 (R/W) System Timer Software Core Reset Register */ + __IOM uint32_t RESERVED1; /*!< Offset: 0xFF4 Reserved */ + __IOM uint32_t MTIMECTL; /*!< Offset: 0xFF8 (R/W) System Timer Control Register, previously MSTOP register */ + __IOM uint32_t MSIP; /*!< Offset: 0xFFC (R/W) System Timer SW interrupt Register */ +} SysTimer_Type; + +/* Timer Control / Status Register Definitions */ +#define SysTimer_MTIMECTL_TIMESTOP_Pos 0U /*!< SysTick Timer MTIMECTL: TIMESTOP bit Position */ +#define SysTimer_MTIMECTL_TIMESTOP_Msk (1UL << SysTimer_MTIMECTL_TIMESTOP_Pos) /*!< SysTick Timer MTIMECTL: TIMESTOP Mask */ +#define SysTimer_MTIMECTL_CMPCLREN_Pos 1U /*!< SysTick Timer MTIMECTL: CMPCLREN bit Position */ +#define SysTimer_MTIMECTL_CMPCLREN_Msk (1UL << SysTimer_MTIMECTL_CMPCLREN_Pos) /*!< SysTick Timer MTIMECTL: CMPCLREN Mask */ +#define SysTimer_MTIMECTL_CLKSRC_Pos 2U /*!< SysTick Timer MTIMECTL: CLKSRC bit Position */ +#define SysTimer_MTIMECTL_CLKSRC_Msk (1UL << SysTimer_MTIMECTL_CLKSRC_Pos) /*!< SysTick Timer MTIMECTL: CLKSRC Mask */ + +#define SysTimer_MSIP_MSIP_Pos 0U /*!< SysTick Timer MSIP: MSIP bit Position */ +#define SysTimer_MSIP_MSIP_Msk (1UL << SysTimer_MSIP_MSIP_Pos) /*!< SysTick Timer MSIP: MSIP Mask */ + +#define SysTimer_MTIMER_Msk (0xFFFFFFFFFFFFFFFFULL) /*!< SysTick Timer MTIMER value Mask */ +#define SysTimer_MTIMERCMP_Msk (0xFFFFFFFFFFFFFFFFULL) /*!< SysTick Timer MTIMERCMP value Mask */ +#define SysTimer_MTIMECTL_Msk (0xFFFFFFFFUL) /*!< SysTick Timer MTIMECTL/MSTOP value Mask */ +#define SysTimer_MSIP_Msk (0xFFFFFFFFUL) /*!< SysTick Timer MSIP value Mask */ +#define SysTimer_MSFTRST_Msk (0xFFFFFFFFUL) /*!< SysTick Timer MSFTRST value Mask */ + +#define SysTimer_MSFRST_KEY (0x80000A5FUL) /*!< SysTick Timer Software Reset Request Key */ + +#define SysTimer_CLINT_MSIP_OFS (0x1000UL) /*!< Software interrupt register offset of clint mode in SysTick Timer */ +#define SysTimer_CLINT_MTIMECMP_OFS (0x5000UL) /*!< MTIMECMP register offset of clint mode in SysTick Timer */ +#define SysTimer_CLINT_MTIME_OFS (0xCFF8UL) /*!< MTIME register offset of clint mode in SysTick Timer */ + +#ifndef __SYSTIMER_BASEADDR +/* Base address of SYSTIMER(__SYSTIMER_BASEADDR) should be defined in */ +#error "__SYSTIMER_BASEADDR is not defined, please check!" +#endif +/* System Timer Memory mapping of Device */ +#define SysTimer_BASE __SYSTIMER_BASEADDR /*!< SysTick Base Address */ +#define SysTimer ((SysTimer_Type *) SysTimer_BASE) /*!< SysTick configuration struct */ + +/* System Timer Clint register base */ +#define SysTimer_CLINT_MSIP_BASE(hartid) (unsigned long)((SysTimer_BASE) + (SysTimer_CLINT_MSIP_OFS) + ((hartid) << 2)) +#define SysTimer_CLINT_MTIMECMP_BASE(hartid) (unsigned long)((SysTimer_BASE) + (SysTimer_CLINT_MTIMECMP_OFS) + ((hartid) << 3)) +#define SysTimer_CLINT_MTIME_BASE (unsigned long)((SysTimer_BASE) + (SysTimer_CLINT_MTIME_OFS)) + +/** @} */ /* end of group NMSIS_Core_SysTimer_Registers */ + +/* ################################## SysTimer function ############################################ */ +/** + * \defgroup NMSIS_Core_SysTimer SysTimer Functions + * \brief Functions that configure the Core System Timer. + * @{ + */ + +/** + * SysTimer_GetHartID() is used to get timer hartid which might not be the same as cpu hart id, + * for example, cpu hartid may be 1, but timer hartid may be 0, then timer hartid offset is 1. + * If defined __SYSTIMER_HARTID, it will use __SYSTIMER_HARTID as timer hartid, + * otherwise, it will use __get_hart_index(). + * The cpu hartid is get by using __get_hart_id function + */ +#ifndef __SYSTIMER_HARTID +#define SysTimer_GetHartID() (__get_hart_index()) +#else +#define SysTimer_GetHartID() (__SYSTIMER_HARTID) +#endif + +/** + * \brief Set system timer load value + * \details + * This function set the system timer load value in MTIMER register. + * \param [in] value value to set system timer MTIMER register. + * \remarks + * - Load value is 64bits wide. + * - \ref SysTimer_GetLoadValue + */ +__STATIC_FORCEINLINE void SysTimer_SetLoadValue(uint64_t value) +{ +#if __RISCV_XLEN == 32 + uint8_t *addr; + addr = (uint8_t *)(&(SysTimer->MTIMER)); + __SW(addr, 0); // prevent carry + __SW(addr + 4, (uint32_t)(value >> 32)); + __SW(addr, (uint32_t)(value)); +#else + SysTimer->MTIMER = value; +#endif +} + +/** + * \brief Get system timer load value + * \details + * This function get the system timer current value in MTIMER register. + * \return current value(64bit) of system timer MTIMER register. + * \remarks + * - Load value is 64bits wide. + * - \ref SysTimer_SetLoadValue + */ +__STATIC_FORCEINLINE uint64_t SysTimer_GetLoadValue(void) +{ +#if __RISCV_XLEN == 32 + volatile uint32_t high0, low, high; + uint64_t full; + uint8_t *addr; + + addr = (uint8_t *)(&(SysTimer->MTIMER)); + + high0 = __LW(addr + 4); + low = __LW(addr); + high = __LW(addr + 4); + if (high0 != high) { + low = __LW(addr); + } + full = (((uint64_t)high) << 32) | low; + return full; +#else + return SysTimer->MTIMER; +#endif +} + +/** + * \brief Set system timer compare value by hartid + * \details + * This function set the system Timer compare value in MTIMERCMP register. + * \param [in] value compare value to set system timer MTIMERCMP register. + * \param [in] hartid hart ID, one hart is required to have a known hart ID of 0, other harts ID can be in 1~1023. + * \remarks + * - Compare value is 64bits wide. + * - If compare value is larger than current value timer interrupt generate. + * - Modify the load value or compare value less to clear the interrupt. + * - In S-mode, hartid can't be get by using __get_hart_id function, so this api suits S-mode particularly. + * - \ref SysTimer_GetHartCompareValue + */ +__STATIC_FORCEINLINE void SysTimer_SetHartCompareValue(uint64_t value, unsigned long hartid) +{ + if (hartid == 0) { +#if __RISCV_XLEN == 32 + uint8_t *addr; + addr = (uint8_t *)(&(SysTimer->MTIMERCMP)); + __SW(addr, -1U); // prevent load > timecmp + __SW(addr + 4, (uint32_t)(value >> 32)); + __SW(addr, (uint32_t)(value)); +#else + SysTimer->MTIMERCMP = value; +#endif + } else { + uint8_t *addr = (uint8_t *)(SysTimer_CLINT_MTIMECMP_BASE(hartid)); +#if __RISCV_XLEN == 32 + __SW(addr, -1U); // prevent load > timecmp + __SW(addr + 4, (uint32_t)(value >> 32)); + __SW(addr, (uint32_t)value); +#else + __SD(addr, value); +#endif + } +} + +/** + * \brief Set system timer compare value in machine mode + * \details + * This function set the system Timer compare value in MTIMERCMP register. + * \param [in] value compare value to set system timer MTIMERCMP register. + * \remarks + * - Compare value is 64bits wide. + * - If compare value is larger than current value timer interrupt generate. + * - Modify the load value or compare value less to clear the interrupt. + * - __get_hart_id function can only be accessed in machine mode, or else exception will occur. + * - \ref SysTimer_GetCompareValue + */ +__STATIC_FORCEINLINE void SysTimer_SetCompareValue(uint64_t value) +{ + unsigned long hartid = SysTimer_GetHartID(); + SysTimer_SetHartCompareValue(value, hartid); +} + +/** + * \brief Get system timer compare value by hartid + * \details + * This function get the system timer compare value in MTIMERCMP register. + * \param [in] hartid hart ID, one hart is required to have a known hart ID of 0, other harts ID can be in 1~1023. + * \return compare value of system timer MTIMERCMP register. + * \remarks + * - Compare value is 64bits wide. + * - In S-mode, hartid can't be get by using __get_hart_id function, so this api suits S-mode particularly. + * - \ref SysTimer_SetHartCompareValue + */ +__STATIC_FORCEINLINE uint64_t SysTimer_GetHartCompareValue(unsigned long hartid) +{ + if (hartid == 0) { + return SysTimer->MTIMERCMP; + } else { + uint64_t full; + uint8_t *addr = (uint8_t *)(SysTimer_CLINT_MTIMECMP_BASE(hartid)); +#if __RISCV_XLEN == 32 + // MTIMECMP didn't increase + uint32_t high, low; + + high = __LW(addr + 4); + low = __LW(addr); + full = (((uint64_t)high) << 32) | low; +#else + full = __LD(addr); +#endif + return full; + } +} + +/** + * \brief Get system timer compare value in machine mode + * \details + * This function get the system timer compare value in MTIMERCMP register. + * \return compare value of system timer MTIMERCMP register. + * \remarks + * - Compare value is 64bits wide. + * - \ref SysTimer_SetCompareValue + */ +__STATIC_FORCEINLINE uint64_t SysTimer_GetCompareValue(void) +{ + unsigned long hartid = SysTimer_GetHartID(); + return SysTimer_GetHartCompareValue(hartid); +} + +/** + * \brief Enable system timer counter running + * \details + * Enable system timer counter running by clear + * TIMESTOP bit in MTIMECTL register. + */ +__STATIC_FORCEINLINE void SysTimer_Start(void) +{ + SysTimer->MTIMECTL &= ~(SysTimer_MTIMECTL_TIMESTOP_Msk); +} + +/** + * \brief Stop system timer counter running + * \details + * Stop system timer counter running by set + * TIMESTOP bit in MTIMECTL register. + */ +__STATIC_FORCEINLINE void SysTimer_Stop(void) +{ + SysTimer->MTIMECTL |= SysTimer_MTIMECTL_TIMESTOP_Msk; +} + +/** + * \brief Set system timer control value + * \details + * This function set the system timer MTIMECTL register value. + * \param [in] mctl value to set MTIMECTL register + * \remarks + * - Bit TIMESTOP is used to start and stop timer. + * Clear TIMESTOP bit to 0 to start timer, otherwise to stop timer. + * - Bit CMPCLREN is used to enable auto MTIMER clear to zero when MTIMER >= MTIMERCMP. + * Clear CMPCLREN bit to 0 to stop auto clear MTIMER feature, otherwise to enable it. + * - Bit CLKSRC is used to select timer clock source. + * Clear CLKSRC bit to 0 to use *mtime_toggle_a*, otherwise use *core_clk_aon* + * - \ref SysTimer_GetControlValue + */ +__STATIC_FORCEINLINE void SysTimer_SetControlValue(uint32_t mctl) +{ + SysTimer->MTIMECTL = (mctl & SysTimer_MTIMECTL_Msk); +} + +/** + * \brief Get system timer control value + * \details + * This function get the system timer MTIMECTL register value. + * \return MTIMECTL register value + * \remarks + * - \ref SysTimer_SetControlValue + */ +__STATIC_FORCEINLINE uint32_t SysTimer_GetControlValue(void) +{ + return (SysTimer->MTIMECTL & SysTimer_MTIMECTL_Msk); +} + +/** + * \brief Trigger or set software interrupt via system timer by hartid + * \details + * This function set the system timer MSIP bit in MSIP register. + * \param [in] hartid hart ID, one hart is required to have a known hart ID of 0, other harts ID can be in 1~1023. + * \remarks + * - Set system timer MSIP bit and generate a SW interrupt. + * - In S-mode, hartid can't be get by using __get_hart_id function, so this api suits S-mode particularly. + * - \ref SysTimer_ClearHartSWIRQ + * - \ref SysTimer_GetHartMsipValue + */ +__STATIC_FORCEINLINE void SysTimer_SetHartSWIRQ(unsigned long hartid) +{ + if (hartid == 0) { + SysTimer->MSIP |= SysTimer_MSIP_MSIP_Msk; + } else { + uint8_t *addr = (uint8_t *)(SysTimer_CLINT_MSIP_BASE(hartid)); + __SW(addr, SysTimer_MSIP_MSIP_Msk); + } +} + +/** + * \brief Trigger or set software interrupt via system timer in machine mode + * \details + * This function set the system timer MSIP bit in MSIP register. + * \remarks + * - Set system timer MSIP bit and generate a SW interrupt. + * - \ref SysTimer_ClearSWIRQ + * - \ref SysTimer_GetMsipValue + */ +__STATIC_FORCEINLINE void SysTimer_SetSWIRQ(void) +{ + unsigned long hartid = SysTimer_GetHartID(); + SysTimer_SetHartSWIRQ(hartid); +} + +/** + * \brief Clear system timer software interrupt pending request by hartid + * \details + * This function clear the system timer MSIP bit in MSIP register. + * \param [in] hartid hart ID, one hart is required to have a known hart ID of 0, other harts ID can be in 1~1023. + * \remarks + * - Clear system timer MSIP bit in MSIP register to clear the software interrupt pending. + * - In S-mode, hartid can't be get by using __get_hart_id function, so this api suits S-mode particularly. + * - \ref SysTimer_SetHartSWIRQ + * - \ref SysTimer_GetHartMsipValue + */ +__STATIC_FORCEINLINE void SysTimer_ClearHartSWIRQ(unsigned long hartid) +{ + if (hartid == 0) { + SysTimer->MSIP &= ~SysTimer_MSIP_MSIP_Msk; + } else { + uint8_t *addr = (uint8_t *)(SysTimer_CLINT_MSIP_BASE(hartid)); + __SW(addr, 0); + } +} + +/** + * \brief Clear system timer software interrupt pending request in machine mode + * \details + * This function clear the system timer MSIP bit in MSIP register. + * \remarks + * - Clear system timer MSIP bit in MSIP register to clear the software interrupt pending. + * - \ref SysTimer_SetSWIRQ + * - \ref SysTimer_GetMsipValue + */ +__STATIC_FORCEINLINE void SysTimer_ClearSWIRQ(void) +{ + unsigned long hartid = SysTimer_GetHartID(); + SysTimer_ClearHartSWIRQ(hartid); +} + +/** + * \brief Get system timer MSIP register value by hartid + * \details + * This function get the system timer MSIP register value. + * \param [in] hartid hart ID, one hart is required to have a known hart ID of 0, other harts ID can be in 1~1023. + * \return Value of Timer MSIP register. + * \remarks + * - Bit0 is SW interrupt flag. + * Bit0 is 1 then SW interrupt set. Bit0 is 0 then SW interrupt clear. + * - In S-mode, hartid can't be get by using __get_hart_id function, so this api suits S-mode particularly. + * - \ref SysTimer_SetHartSWIRQ + * - \ref SysTimer_ClearHartSWIRQ + * - \ref SysTimer_SetHartMsipValue + */ +__STATIC_FORCEINLINE uint32_t SysTimer_GetHartMsipValue(unsigned long hartid) +{ + if (hartid == 0) { + return (uint32_t)(SysTimer->MSIP & SysTimer_MSIP_Msk); + } else { + uint8_t *addr = (uint8_t *)(SysTimer_CLINT_MSIP_BASE(hartid)); + return __LW(addr); + } +} + +/** + * \brief Get system timer MSIP register value in machine mode + * \details + * This function get the system timer MSIP register value. + * \return Value of Timer MSIP register. + * \remarks + * - Bit0 is SW interrupt flag. + * Bit0 is 1 then SW interrupt set. Bit0 is 0 then SW interrupt clear. + * - \ref SysTimer_SetSWIRQ + * - \ref SysTimer_ClearSWIRQ + * - \ref SysTimer_SetMsipValue + */ +__STATIC_FORCEINLINE uint32_t SysTimer_GetMsipValue(void) +{ + unsigned long hartid = SysTimer_GetHartID(); + return SysTimer_GetHartMsipValue(hartid); +} + +/** + * \brief Set system timer MSIP register value by hartid + * \details + * This function set the system timer MSIP register value. + * \param [in] msip value to set MSIP register + * \param [in] hartid hart ID, one hart is required to have a known hart ID of 0, other harts ID can be in 1~1023. + * \remarks + * - In S-mode, hartid can't be get using __get_hart_id function, so this api suits S-mode particularly. + * - \ref SysTimer_GetHartMsipValue + */ +__STATIC_FORCEINLINE void SysTimer_SetHartMsipValue(uint32_t msip, unsigned long hartid) +{ + if (hartid == 0) { + SysTimer->MSIP = (msip & SysTimer_MSIP_Msk); + } else { + uint8_t *addr = (uint8_t *)(SysTimer_CLINT_MSIP_BASE(hartid)); + __SW(addr, msip); + } +} + +/** + * \brief Set system timer MSIP register value in machine mode + * \details + * This function set the system timer MSIP register value. + * \param [in] msip value to set MSIP register + * - \ref SysTimer_GetMsipValue + */ +__STATIC_FORCEINLINE void SysTimer_SetMsipValue(uint32_t msip) +{ + unsigned long hartid = SysTimer_GetHartID(); + SysTimer_SetHartMsipValue(msip, hartid); +} + +/** + * \brief Do software reset request + * \details + * This function will do software reset request through MTIMER + * - Software need to write \ref SysTimer_MSFRST_KEY to generate software reset request + * - The software request flag can be cleared by reset operation to clear + * \remarks + * - The software reset is sent to SoC, SoC need to generate reset signal and send back to Core + * - This function will not return, it will do while(1) to wait the Core reset happened + */ +__STATIC_FORCEINLINE void SysTimer_SoftwareReset(void) +{ + SysTimer->MSFTRST = SysTimer_MSFRST_KEY; + // will reset cpu, never return + while (1); +} + +/** + * \brief send ipi to target hart using Systimer Clint + * \details + * This function send ipi using clint timer. + * \param [in] hart target hart + */ +__STATIC_FORCEINLINE void SysTimer_SendIPI(unsigned long hartid) +{ + uint8_t *addr = (uint8_t *)(SysTimer_CLINT_MSIP_BASE(hartid)); + __SW(addr, 1); +} + +/** + * \brief clear ipi to target hart using Systimer Clint + * \details + * This function clear ipi using Systimer clint timer. + * \param [in] hart target hart + */ +__STATIC_FORCEINLINE void SysTimer_ClearIPI(unsigned long hartid) +{ + uint8_t *addr = (uint8_t *)(SysTimer_CLINT_MSIP_BASE(hartid)); + __SW(addr, 0); +} + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) && defined(__ECLIC_PRESENT) && (__ECLIC_PRESENT == 1) +/** + * \brief System Tick Configuration + * \details Initializes the System Timer and its non-vector interrupt, and starts the System Tick Timer. + * + * In our default implementation, the timer counter will be set to zero, and it will start a timer compare non-vector interrupt + * when it matchs the ticks user set, during the timer interrupt user should reload the system tick using \ref SysTick_Reload function + * or similar function written by user, so it can produce period timer interrupt. + * \param [in] ticks Number of ticks between two interrupts. + * \return 0 Function succeeded. + * \return 1 Function failed. + * \remarks + * - For \ref __NUCLEI_N_REV >= 0x0104, the CMPCLREN bit in MTIMECTL is introduced, + * but we assume that the CMPCLREN bit is set to 0, so MTIMER register will not be + * auto cleared to 0 when MTIMER >= MTIMERCMP. + * - When the variable \ref __Vendor_SysTickConfig is set to 1, then the + * function \ref SysTick_Config is not included. + * - In this case, the file .h must contain a vendor-specific implementation + * of this function. + * - If user need this function to start a period timer interrupt, then in timer interrupt handler + * routine code, user should call \ref SysTick_Reload with ticks to reload the timer. + * - This function only available when __SYSTIMER_PRESENT == 1 and __ECLIC_PRESENT == 1 and __Vendor_SysTickConfig == 0 + * \sa + * - \ref SysTimer_SetCompareValue; SysTimer_SetLoadValue + */ +__STATIC_INLINE uint32_t SysTick_Config(uint64_t ticks) +{ + uint64_t loadticks = SysTimer_GetLoadValue(); + SysTimer_SetCompareValue(ticks + loadticks); + ECLIC_SetShvIRQ(SysTimer_IRQn, ECLIC_NON_VECTOR_INTERRUPT); + ECLIC_SetLevelIRQ(SysTimer_IRQn, 0); + ECLIC_EnableIRQ(SysTimer_IRQn); + return (0UL); +} + +/** + * \brief System Tick Configuration By hartid + * \details Initializes the System Timer and its non-vector interrupt, and starts the System Tick Timer. + * + * In our default implementation, the timer counter will be set to zero, and it will start a timer compare non-vector interrupt + * when it matchs the ticks user set, during the timer interrupt user should reload the system tick using \ref SysTick_Reload function + * or similar function written by user, so it can produce period timer interrupt. + * \param [in] ticks Number of ticks between two interrupts. + * \param [in] hartid hart ID, one hart is required to have a known hart ID of 0, other harts ID can be in 1~1023. + * \return 0 Function succeeded. + * \return 1 Function failed. + * \remarks + * - For \ref __NUCLEI_N_REV >= 0x0104, the CMPCLREN bit in MTIMECTL is introduced, + * but we assume that the CMPCLREN bit is set to 0, so MTIMER register will not be + * auto cleared to 0 when MTIMER >= MTIMERCMP. + * - When the variable \ref __Vendor_SysTickConfig is set to 1, then the + * function \ref SysTick_Config is not included. + * - In this case, the file .h must contain a vendor-specific implementation + * of this function. + * - If user need this function to start a period timer interrupt, then in timer interrupt handler + * routine code, user should call \ref SysTick_Reload with ticks to reload the timer. + * - This function only available when __SYSTIMER_PRESENT == 1 and __ECLIC_PRESENT == 1 and __Vendor_SysTickConfig == 0 + * - In S-mode, hartid can't be get by using __get_hart_id function, so this api suits S-mode particularly. + * \sa + * - \ref SysTimer_SetCompareValue; SysTimer_SetLoadValue + */ +__STATIC_INLINE uint32_t SysTick_HartConfig(uint64_t ticks, unsigned long hartid) +{ + uint64_t loadticks = SysTimer_GetLoadValue(); + SysTimer_SetHartCompareValue(ticks + loadticks, hartid); + ECLIC_SetShvIRQ(SysTimer_IRQn, ECLIC_NON_VECTOR_INTERRUPT); + ECLIC_SetLevelIRQ(SysTimer_IRQn, 0); + ECLIC_EnableIRQ(SysTimer_IRQn); + return (0UL); +} + +/** + * \brief System Tick Reload + * \details Reload the System Timer Tick when the MTIMECMP reached TIME value + * + * \param [in] ticks Number of ticks between two interrupts. + * \return 0 Function succeeded. + * \return 1 Function failed. + * \remarks + * - For \ref __NUCLEI_N_REV >= 0x0104, the CMPCLREN bit in MTIMECTL is introduced, + * but for this \ref SysTick_Config function, we assume this CMPCLREN bit is set to 0, + * so in interrupt handler function, user still need to set the MTIMERCMP or MTIMER to reload + * the system tick, if vendor want to use this timer's auto clear feature, they can define + * \ref __Vendor_SysTickConfig to 1, and implement \ref SysTick_Config and \ref SysTick_Reload functions. + * - When the variable \ref __Vendor_SysTickConfig is set to 1, then the + * function \ref SysTick_Reload is not included. + * - In this case, the file .h must contain a vendor-specific implementation + * of this function. + * - This function only available when __SYSTIMER_PRESENT == 1 and __ECLIC_PRESENT == 1 and __Vendor_SysTickConfig == 0 + * - Since the MTIMERCMP value might overflow, if overflowed, MTIMER will be set to 0, and MTIMERCMP set to ticks + * \sa + * - \ref SysTimer_SetCompareValue + * - \ref SysTimer_SetLoadValue + */ +__STATIC_FORCEINLINE uint32_t SysTick_Reload(uint64_t ticks) +{ + uint64_t cur_ticks = SysTimer_GetLoadValue(); + uint64_t reload_ticks = ticks + cur_ticks; + + if (__USUALLY(reload_ticks > cur_ticks)) { + SysTimer_SetCompareValue(reload_ticks); + } else { + /* When added the ticks value, then the MTIMERCMP < TIMER, + * which means the MTIMERCMP is overflowed, + * so we need to reset the counter to zero */ + SysTimer_SetLoadValue(0); + SysTimer_SetCompareValue(ticks); + } + + return (0UL); +} + +/** + * \brief System Tick Reload + * \details Reload the System Timer Tick when the MTIMECMP reached TIME value + * + * \param [in] ticks Number of ticks between two interrupts. + * \param [in] hartid hart ID, one hart is required to have a known hart ID of 0, other harts ID can be in 1~1023. + * \return 0 Function succeeded. + * \return 1 Function failed. + * \remarks + * - For \ref __NUCLEI_N_REV >= 0x0104, the CMPCLREN bit in MTIMECTL is introduced, + * but for this \ref SysTick_Config function, we assume this CMPCLREN bit is set to 0, + * so in interrupt handler function, user still need to set the MTIMERCMP or MTIMER to reload + * the system tick, if vendor want to use this timer's auto clear feature, they can define + * \ref __Vendor_SysTickConfig to 1, and implement \ref SysTick_Config and \ref SysTick_Reload functions. + * - When the variable \ref __Vendor_SysTickConfig is set to 1, then the + * function \ref SysTick_Reload is not included. + * - In this case, the file .h must contain a vendor-specific implementation + * of this function. + * - This function only available when __SYSTIMER_PRESENT == 1 and __ECLIC_PRESENT == 1 and __Vendor_SysTickConfig == 0 + * - Since the MTIMERCMP value might overflow, if overflowed, MTIMER will be set to 0, and MTIMERCMP set to ticks + * - In S-mode, hartid can't be get by using __get_hart_id function, so this api suits S-mode particularly. + * \sa + * - \ref SysTimer_SetCompareValue + * - \ref SysTimer_SetLoadValue + */ +__STATIC_FORCEINLINE uint32_t SysTick_HartReload(uint64_t ticks, unsigned long hartid) +{ + uint64_t cur_ticks = SysTimer_GetLoadValue(); + uint64_t reload_ticks = ticks + cur_ticks; + + if (__USUALLY(reload_ticks > cur_ticks)) { + SysTimer_SetHartCompareValue(reload_ticks, hartid); + } else { + /* When added the ticks value, then the MTIMERCMP < TIMER, + * which means the MTIMERCMP is overflowed, + * so we need to reset the counter to zero */ + SysTimer_SetLoadValue(0); + SysTimer_SetHartCompareValue(ticks, hartid); + } + + return (0UL); +} + +#endif /* defined(__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) */ +/** @} */ /* End of Doxygen Group NMSIS_Core_SysTimer */ + +#endif /* defined(__SYSTIMER_PRESENT) && (__SYSTIMER_PRESENT == 1) */ + +#ifdef __cplusplus +} +#endif +#endif /* __CORE_FEATURE_TIMER_H__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_vector.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_vector.h new file mode 100644 index 0000000..c95a8bb --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_vector.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __CORE_FEATURE_VECTOR__ +#define __CORE_FEATURE_VECTOR__ + +/*! + * @file core_feature_vector.h + * @brief Vector feature API header file for Nuclei N/NX Core + */ +/* + * Vector Feature Configuration Macro: + * 1. __VECTOR_PRESENT: Define whether Vector Unit is present or not + * * 0: Not present + * * 1: Present + */ +#ifdef __cplusplus + extern "C" { +#endif + +#include "core_feature_base.h" + +#if defined(__VECTOR_PRESENT) && (__VECTOR_PRESENT == 1) + +/* ########################### CPU Vector Intrinsic Functions ########################### */ +/** + * \defgroup NMSIS_Core_Vector_Intrinsic Intrinsic Functions for Vector Instructions + * \ingroup NMSIS_Core + * \brief Functions that generate RISC-V Vector instructions. + * \details + * + * RISC-V Vector Intrinsic APIs are provided directly through compiler generated intrinsic function. + * + * This intrinsic function support by compiler: + * + * For Nuclei RISC-V GCC 10.2, it is an very old and not ratified version(no longer supported). + * + * - API header file can be found in lib/gcc/riscv-nuclei-elf//include/riscv_vector.h + * + * For Nuclei RISC-V GCC 13/Clang 17, the intrinsic API supported is v0.12 version, see + * https://github.com/riscv-non-isa/rvv-intrinsic-doc/releases/tag/v0.12.0 + * + * @{ + */ + +#if defined(__INC_INTRINSIC_API) && (__INC_INTRINSIC_API == 1) +#include +#endif + +/** + * \brief Enable Vector Unit + * \details + * Set vector context status bits to enable vector unit, + * and set state to initial + */ +__STATIC_FORCEINLINE void __enable_vector(void) +{ + __RV_CSR_CLEAR(CSR_MSTATUS, MSTATUS_VS); + __RV_CSR_SET(CSR_MSTATUS, MSTATUS_VS_INITIAL); +} + +/** + * \brief Disable Vector Unit + * \details + * Clear vector context status bits to disable vector unit + */ +__STATIC_FORCEINLINE void __disable_vector(void) +{ + __RV_CSR_CLEAR(CSR_MSTATUS, MSTATUS_VS); +} + +/** @} */ /* End of Doxygen Group NMSIS_Core_Vector_Intrinsic */ +#endif /* defined(__VECTOR_PRESENT) && (__VECTOR_PRESENT == 1) */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_FEATURE_VECTOR__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_bench.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_bench.h new file mode 100644 index 0000000..10dcb57 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_bench.h @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NMSIS_BENCH__ +#define __NMSIS_BENCH__ + +/*! + * @file nmsis_bench.h + * @brief benchmark and helper related API for Nuclei N/NX Core + */ + +#ifdef __cplusplus + extern "C" { +#endif + +#include "core_feature_base.h" +#include + +/** + * \defgroup NMSIS_Core_Bench_Helpers NMSIS Bench and Test Related Helper Functions + * \ingroup NMSIS_Core + * \brief Functions that used to do benchmark and test suite. + * \details + * + * NMSIS benchmark and test related helper functions are provided to help do benchmark + * and test case pass/fail assertion. + * + * If you want to do calculate cpu cycle cost of a process, you can use BENCH_xxx macros + * defined in this. + * + * In a single c source code file, you should include `nmsis_bench.h`, and then you should place `BENCH_DECLARE_VAR();` + * before call other BENCH_xxx macros. If you want to start to do benchmark, you should only call `BENCH_INIT();` + * once in your source code, and then place `BENCH_START(proc_name);` and `BENCH_END(proc_name)` before + * and after the process you want to measure. You can refer to `/application/baremetal/demo_dsp` + * for how to use it. + * + * If you want to disable the benchmark calculation, you can place `#define DISABLE_NMSIS_BENCH` + * before include `nmsis_bench.h` + * + * If in your c test source code, you can add `NMSIS_TEST_PASS();` and `NMSIS_TEST_FAIL();` to mark c test + * is pass or fail. + * + * @{ + */ + +/** + * \brief Prepare benchmark environment + * \details + * Prepare benchmark required environment, such as turn on necessary units + * like vpu, cycle, instret counters, hpm counters + */ +__STATIC_FORCEINLINE void __prepare_bench_env(void) +{ +#ifdef __riscv_vector + __RV_CSR_SET(CSR_MSTATUS, MSTATUS_VS); +#endif + __enable_all_counter(); +} + +#ifndef READ_CYCLE +/** Read run cycle of cpu */ +#define READ_CYCLE __get_rv_cycle +#endif + +#ifndef DISABLE_NMSIS_BENCH + +/** Declare benchmark required variables, need to be placed above all BENCH_xxx macros in each c source code if BENCH_xxx used */ +#define BENCH_DECLARE_VAR() static volatile uint64_t _bc_sttcyc, _bc_endcyc, _bc_usecyc, _bc_sumcyc, _bc_lpcnt, _bc_ercd; + +/** Initialize benchmark environment, need to called in before other BENCH_xxx macros are called */ +#define BENCH_INIT() printf("Benchmark initialized\n"); \ + __prepare_bench_env(); \ + _bc_ercd = 0; _bc_sumcyc = 0; + +/** Reset benchmark sum cycle and use cycle for proc */ +#define BENCH_RESET(proc) _bc_sumcyc = 0; _bc_usecyc = 0; _bc_lpcnt = 0; _bc_ercd = 0; + +/** Start to do benchmark for proc, and record start cycle, and reset error code */ +#define BENCH_START(proc) _bc_ercd = 0; \ + _bc_sttcyc = READ_CYCLE(); + +/** Sample a benchmark for proc, and record this start -> sample cost cycle, and accumulate it to sum cycle */ +#define BENCH_SAMPLE(proc) _bc_endcyc = READ_CYCLE(); \ + _bc_usecyc = _bc_endcyc - _bc_sttcyc; \ + _bc_sumcyc += _bc_usecyc; _bc_lpcnt += 1; + +/** Mark end of benchmark for proc, and calc used cycle, and print it */ +#define BENCH_END(proc) BENCH_SAMPLE(proc); \ + printf("CSV, %s, %lu\n", #proc, (unsigned long)_bc_usecyc); + +/** Mark stop of benchmark, start -> sample -> sample -> stop, and print the sum cycle of a proc */ +#define BENCH_STOP(proc) printf("CSV, %s, %lu\n", #proc, (unsigned long)_bc_sumcyc); + +/** Show statistics of benchmark, format: STAT, proc, loopcnt, sumcyc */ +#define BENCH_STAT(proc) printf("STAT, %s, %lu, %lu\n", #proc, (unsigned long)_bc_lpcnt, (unsigned long)_bc_sumcyc); + +/** Get benchmark use cycle */ +#define BENCH_GET_USECYC() (_bc_usecyc) + +/** Get benchmark sum cycle */ +#define BENCH_GET_SUMCYC() (_bc_sumcyc) + +/** Get benchmark loop count */ +#define BENCH_GET_LPCNT() (_bc_lpcnt) + +/** Mark benchmark for proc is errored */ +#define BENCH_ERROR(proc) _bc_ercd = 1; +/** Show the status of the benchmark */ +#define BENCH_STATUS(proc) if (_bc_ercd) { \ + printf("ERROR, %s\n", #proc); \ + } else { \ + printf("SUCCESS, %s\n", #proc); \ + } +#else +#define BENCH_DECLARE_VAR() static volatile uint64_t _bc_ercd, _bc_lpcnt; +#define BENCH_INIT() _bc_ercd = 0; __prepare_bench_env(); +#define BENCH_RESET(proc) +#define BENCH_START(proc) _bc_ercd = 0; +#define BENCH_SAMPLE(proc) _bc_lpcnt += 1; +#define BENCH_END(proc) +#define BENCH_STOP(proc) +#define BENCH_STAT(proc) +#define BENCH_GET_USECYC() (0) +#define BENCH_GET_SUMCYC() (0) +#define BENCH_GET_LPCNT() (_bc_lpcnt) +#define BENCH_ERROR(proc) _bc_ercd = 1; +#define BENCH_STATUS(proc) if (_bc_ercd) { \ + printf("ERROR, %s\n", #proc); \ + } else { \ + printf("SUCCESS, %s\n", #proc); \ + } + +#endif + +// High performance monitor bench helpers +#ifndef DISABLE_NMSIS_HPM + +/* Events type select */ +#define EVENT_SEL_INSTRUCTION_COMMIT 0 +#define EVENT_SEL_MEMORY_ACCESS 1 + +/* Instruction commit events idx define*/ +#define EVENT_INSTRUCTION_COMMIT_CYCLE_COUNT 1 +#define EVENT_INSTRUCTION_COMMIT_RETIRED_COUNT 2 +/* Integer load instruction (includes LR) */ +#define EVENT_INSTRUCTION_COMMIT_INTEGER_LOAD 3 +/* Integer store instruction (includes SC) */ +#define EVENT_INSTRUCTION_COMMIT_INTEGER_STORE 4 +/* Atomic memory operation (do not include LR and SC) */ +#define EVENT_INSTRUCTION_COMMIT_ATOMIC_MEMORY_OPERATION 5 +/* System instruction */ +#define EVENT_INSTRUCTION_COMMIT_SYSTEM 6 +/* Integer computational instruction (excluding multiplication/division/remainder) */ +#define EVENT_INSTRUCTION_COMMIT_INTEGER_COMPUTATIONAL 7 +#define EVENT_INSTRUCTION_COMMIT_CONDITIONAL_BRANCH 8 +#define EVENT_INSTRUCTION_COMMIT_TAKEN_CONDITIONAL_BRANCH 9 +#define EVENT_INSTRUCTION_COMMIT_JAL 10 +#define EVENT_INSTRUCTION_COMMIT_JALR 11 +#define EVENT_INSTRUCTION_COMMIT_RETURN 12 +/* Control transfer instruction (CBR+JAL+JALR) */ +#define EVENT_INSTRUCTION_COMMIT_CONTROL_TRANSFER 13 +/* 14 Reseved */ +#define EVENT_INSTRUCTION_COMMIT_INTEGER_MULTIPLICATION 15 +/* Integer division/remainder instruction */ +#define EVENT_INSTRUCTION_COMMIT_INTEGER_DIVISION_REMAINDER 16 +#define EVENT_INSTRUCTION_COMMIT_FLOATING_POINT_LOAD 17 +#define EVENT_INSTRUCTION_COMMIT_FLOATING_POINT_STORE 18 +/* Floating-point addition/subtraction */ +#define EVENT_INSTRUCTION_COMMIT_FLOATING_POINT_ADDITION_SUBTRACTION 19 +#define EVENT_INSTRUCTION_COMMIT_FLOATING_POINT_MULTIPLICATION 20 +/* Floating-point fused multiply-add (FMADD, FMSUB, FNMSUB, FNMADD) */ +#define EVENT_INSTRUCTION_COMMIT_FLOATING_POINT_FUSED_MULTIPLY_ADD_SUB 21 +#define EVENT_INSTRUCTION_COMMIT_FLOATING_POINT_DIVISION_OR_SQUARE_ROOT 22 +#define EVENT_INSTRUCTION_COMMIT_OTHER_FLOATING_POINT_INSTRUCTION 23 +#define EVENT_INSTRUCTION_COMMIT_CONDITIONAL_BRANCH_PREDICTION_FAIL 24 +#define EVENT_INSTRUCTION_COMMIT_JAL_PREDICTION_FAIL 25 +#define EVENT_INSTRUCTION_COMMIT_JALR_PREDICTION_FAIL 26 + +/* Memory access events idx define*/ +#define EVENT_MEMORY_ACCESS_ICACHE_MISS 1 +#define EVENT_MEMORY_ACCESS_DCACHE_MISS 2 +#define EVENT_MEMORY_ACCESS_ITLB_MISS 3 +#define EVENT_MEMORY_ACCESS_DTLB_MISS 4 +#define EVENT_MEMORY_ACCESS_MAIN_DTLB_MISS 5 + +/* Enable the corresponding performance monitor counter increment for events in Machine/Supervisor/User Mode */ +#define MSU_EVENT_ENABLE 0x0F +#define MEVENT_EN 0x08 +#define SEVENT_EN 0x02 +#define UEVENT_EN 0x01 + +/** Declare high performance monitor counter idx benchmark required variables, need to be placed above all HPM_xxx macros in each c source code if HPM_xxx used */ +#define HPM_DECLARE_VAR(idx) static volatile uint64_t __hpm_sttcyc##idx, __hpm_endcyc##idx, __hpm_usecyc##idx, __hpm_sumcyc##idx, __hpm_lpcnt##idx, __hpm_val##idx; + +#define HPM_SEL_ENABLE(ena) (ena << 28) +#define HPM_SEL_EVENT(sel, idx) ((sel) | (idx << 4)) + +/** Construct a event variable to be set(sel -> event_sel, idx -> event_idx, ena -> m/s/u_enable) */ +#define HPM_EVENT(sel, idx, ena) (HPM_SEL_ENABLE(ena) | HPM_SEL_EVENT(sel, idx)) + +/** Initialize high performance monitor environment, need to called in before other HPM_xxx macros are called */ +#define HPM_INIT() printf("High performance monitor initialized\n"); \ + __prepare_bench_env(); + +/** Reset high performance benchmark for proc using counter which index is idx */ +#define HPM_RESET(idx, proc, event) __hpm_sumcyc##idx = 0; __hpm_lpcnt##idx = 0; + +/** Start to do high performance benchmark for proc, and record start hpm counter */ +#define HPM_START(idx, proc, event) \ + __hpm_val##idx = (event); \ + __set_hpm_event(idx, __hpm_val##idx); \ + __set_hpm_counter(idx, 0); \ + __hpm_sttcyc##idx = __get_hpm_counter(idx); + +/** Do high performance benchmark sample for proc, and sum it into sum counter */ +#define HPM_SAMPLE(idx, proc, event) \ + __hpm_endcyc##idx = __get_hpm_counter(idx); \ + __hpm_usecyc##idx = __hpm_endcyc##idx - __hpm_sttcyc##idx; \ + __hpm_sumcyc##idx += __hpm_usecyc##idx; \ + __hpm_lpcnt##idx += 1; + +/** Mark end of high performance benchmark for proc, and calc used hpm counter value */ +#define HPM_END(idx, proc, event) \ + HPM_SAMPLE(idx, proc, event); \ + printf("HPM%d:0x%x, %s, %lu\n", idx, event, #proc, (unsigned long)__hpm_usecyc##idx); + +/** Mark stop of hpm benchmark, start -> sample -> sample -> stop, and print the sum cycle of a proc */ +#define HPM_STOP(idx, proc, event) \ + printf("HPM%d:0x%x, %s, %lu\n", idx, event, #proc, (unsigned long)__hpm_sumcyc##idx); + +/** Show statistics of hpm benchmark, format: STATHPM#idx:event, proc, loopcnt, sumcyc */ +#define HPM_STAT(idx, proc, event) \ + printf("STATHPM%d:0x%x, %s, %lu, %lu\n", idx, event, #proc, (unsigned long)__hpm_lpcnt##idx, (unsigned long)__hpm_sumcyc##idx); + +/** Get hpm benchmark use cycle for counter idx */ +#define HPM_GET_USECYC(idx) (__hpm_usecyc##idx) + +/** Get hpm benchmark sum cycle for counter idx */ +#define HPM_GET_SUMCYC(idx) (__hpm_sumcyc##idx) + +/** Get hpm benchmark loop count for counter idx */ +#define HPM_GET_LPCNT(idx) (__hpm_lpcnt##idx) + +#else +#define HPM_DECLARE_VAR(idx) +#define HPM_EVENT(sel, idx, ena) +#define HPM_INIT() +#define HPM_RESET(idx, proc, event) +#define HPM_START(idx, proc, event) +#define HPM_SAMPLE(idx, proc, event) +#define HPM_END(idx, proc, event) +#define HPM_STOP(idx, proc, event) +#define HPM_STAT(idx, proc, event) +#define HPM_GET_USECYC(idx) (0) +#define HPM_GET_SUMCYC(idx) (0) +#define HPM_GET_LPCNT(idx) (1) +#endif + +// NMSIS Helpers +#ifndef DISABLE_NMSIS_HELPER +/** Mark test or application passed */ +#define NMSIS_TEST_PASS() printf("\nNMSIS_TEST_PASS\n"); +/** Mark test or application failed */ +#define NMSIS_TEST_FAIL() printf("\nNMSIS_TEST_FAIL\n"); +#else +#define NMSIS_TEST_PASS() +#define NMSIS_TEST_FAIL() +#endif + +/** @} */ /* End of Doxygen Group NMSIS_Core_Bench_Helpers */ +#ifdef __cplusplus +} +#endif +#endif /* __NMSIS_BENCH__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_compiler.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_compiler.h new file mode 100644 index 0000000..eb2b582 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_compiler.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NMSIS_COMPILER_H +#define __NMSIS_COMPILER_H + +#include + +/*! + * @file nmsis_compiler.h + * @brief NMSIS compiler generic header file + */ +#if defined ( __GNUC__ ) + /* GNU GCC Compiler */ + #include "nmsis_gcc.h" +#elif defined ( __ICCRISCV__ ) + /* IAR Compiler */ + #include "nmsis_iar.h" +#else + #error Unknown compiler. +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + * \defgroup NMSIS_Core_PeriphAccess Peripheral Access + * \brief Naming conventions and optional features for accessing peripherals. + * + * The section below describes the naming conventions, requirements, and optional features + * for accessing device specific peripherals. + * Most of the rules also apply to the core peripherals. + * + * The **Device Header File ** contains typically these definition + * and also includes the core specific header files. + * + * @{ + */ +/** \brief Defines 'read only' permissions */ +#ifdef __cplusplus + #define __I volatile +#else + #define __I volatile const +#endif +/** \brief Defines 'write only' permissions */ +#define __O volatile +/** \brief Defines 'read / write' permissions */ +#define __IO volatile + +/* following defines should be used for structure members */ +/** \brief Defines 'read only' structure member permissions */ +#define __IM volatile const +/** \brief Defines 'write only' structure member permissions */ +#define __OM volatile +/** \brief Defines 'read/write' structure member permissions */ +#define __IOM volatile + +/** + * \brief Mask and shift a bit field value for use in a register bit range. + * \details The macro \ref _VAL2FLD uses the #define's _Pos and _Msk of the related bit + * field to shift bit-field values for assigning to a register. + * + * **Example**: + * \code + * ECLIC->CFG = _VAL2FLD(CLIC_CLICCFG_NLBIT, 3); + * \endcode + * \param[in] field Name of the register bit field. + * \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + * \return Masked and shifted value. + */ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + * \brief Mask and shift a register value to extract a bit filed value. + * \details The macro \ref _FLD2VAL uses the #define's _Pos and _Msk of the related bit + * field to extract the value of a bit field from a register. + * + * **Example**: + * \code + * nlbits = _FLD2VAL(CLIC_CLICCFG_NLBIT, ECLIC->CFG); + * \endcode + * \param[in] field Name of the register bit field. + * \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + * \return Masked and shifted bit field value. + */ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/** @} */ /* end of group NMSIS_Core_PeriphAccess */ + + +#endif /* __NMSIS_COMPILER_H */ + diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_core.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_core.h new file mode 100644 index 0000000..6346d12 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_core.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2009-2019 Arm Limited. All rights reserved. + * -- Adaptable modifications made for Nuclei Processors. -- + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include + +#ifdef __cplusplus + extern "C" { +#endif + +#include "nmsis_version.h" + +/** + * \ingroup NMSIS_Core_VersionControl + * @{ + */ +/* The following macro __NUCLEI_N_REV/__NUCLEI_NX_REV/ + * __NUCLEI_CPU_REV/__NUCLEI_CPU_SERIES definition in this file + * is only used for doxygen documentation generation, + * The .h is the real file to define it by vendor + */ +#if defined(__ONLY_FOR_DOXYGEN_DOCUMENT_GENERATION__) +/** + * \brief Nuclei N class core revision number + * \details + * Reversion number format: [15:8] revision number, [7:0] patch number + * \attention + * Deprecated, this define is exclusive with \ref __NUCLEI_NX_REV + */ +#define __NUCLEI_N_REV (0x0309) +/** + * \brief Nuclei NX class core revision number + * \details + * Reversion number format: [15:8] revision number, [7:0] patch number + * \attention + * Deprecated, this define is exclusive with \ref __NUCLEI_N_REV + */ +#define __NUCLEI_NX_REV (0x0207) +/** + * \brief Nuclei CPU core revision number + * \details + * Nuclei RISC-V CPU Revision Number vX.Y.Z, eg. v3.10.1 + * \attention + * This define is exclusive with \ref __NUCLEI_CPU_SERIES + */ +#define __NUCLEI_CPU_REV (0x030A01) +/** + * \brief Nuclei CPU core series + * \details + * Nuclei RISC-V CPU Series Number, eg, 0x200, 0x300, 0x600, 0x900 + * for 200, 300, 600, 900 series. + * \attention + * This define is used together with \ref __NUCLEI_CPU_REV + */ +#define __NUCLEI_CPU_SERIES (0x0200) +#endif /* __ONLY_FOR_DOXYGEN_DOCUMENT_GENERATION__ */ +/** @} */ /* End of Group NMSIS_Core_VersionControl */ + +#include "nmsis_compiler.h" /* NMSIS compiler specific defines */ + +/* === Include Nuclei Core Related Headers === */ +/* Include core base feature header file */ +#include "core_feature_base.h" + +/* Include core fpu feature header file */ +#include "core_feature_fpu.h" +/* Include core dsp feature header file */ +#include "core_feature_dsp.h" +/* Include core vector feature header file */ +#include "core_feature_vector.h" +/* Include core bitmanip feature header file */ +#include "core_feature_bitmanip.h" +/* Include core pmp feature header file */ +#include "core_feature_pmp.h" +/* Include core spmp feature header file */ + #include "core_feature_spmp.h" +/* Include core cache feature header file */ +#include "core_feature_cache.h" +/* Include core cidu feature header file */ + #include "core_feature_cidu.h" + +/* Include compatiable functions header file */ +#include "core_compatiable.h" + +#ifndef __NMSIS_GENERIC +/* Include core eclic feature header file */ +#include "core_feature_eclic.h" +/* Include core plic feature header file */ +#include "core_feature_plic.h" +/* Include core systimer feature header file */ +#include "core_feature_timer.h" +#endif + +#ifdef __cplusplus +} +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_gcc.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_gcc.h new file mode 100644 index 0000000..100019d --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_gcc.h @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NMSIS_GCC_H__ +#define __NMSIS_GCC_H__ +/*! + * @file nmsis_gcc.h + * @brief NMSIS compiler GCC header file + */ +#include + +#ifdef __cplusplus + extern "C" { +#endif + +#include "riscv_encoding.h" + +/* ######################### Startup and Lowlevel Init ######################## */ +/** + * \defgroup NMSIS_Core_CompilerControl Compiler Control + * \ingroup NMSIS_Core + * \brief Compiler agnostic \#define symbols for generic c/c++ source code + * \details + * + * The NMSIS-Core provides the header file nmsis_compiler.h with consistent \#define symbols for generate C or C++ source files that should be compiler agnostic. + * Each NMSIS compliant compiler should support the functionality described in this section. + * + * The header file nmsis_compiler.h is also included by each Device Header File so that these definitions are available. + * @{ + */ + +/* Fallback for __has_builtin */ +#ifndef __has_builtin + #define __has_builtin(x) (0) +#endif + +/* NMSIS compiler specific defines */ +/** \brief Pass information from the compiler to the assembler. */ +#ifndef __ASM + #define __ASM __asm +#endif + +/** \brief Recommend that function should be inlined by the compiler. */ +#ifndef __INLINE + #define __INLINE inline +#endif + +/** \brief Define a static function that may be inlined by the compiler. */ +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif + +/** \brief Define a static function that should be always inlined by the compiler. */ +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline +#endif + +/** \brief Inform the compiler that a function does not return. */ +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif + +/** \brief Inform that a variable shall be retained in executable image. */ +#ifndef __USED + #define __USED __attribute__((used)) +#endif + +/** \brief restrict pointer qualifier to enable additional optimizations. */ +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif + +/** \brief specified the vector size of the variable, measured in bytes */ +#ifndef __VECTOR_SIZE + #define __VECTOR_SIZE(x) __attribute__((vector_size(x))) +#endif + +/** \brief Request smallest possible alignment. */ +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif + +/** \brief Request smallest possible alignment for a structure. */ +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif + +/** \brief Request smallest possible alignment for a union. */ +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif + +#ifndef __UNALIGNED_UINT16_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + /** \brief Packed struct for unaligned uint16_t write access */ + __PACKED_STRUCT T_UINT16_WRITE { + uint16_t v; + }; + #pragma GCC diagnostic pop + /** \brief Pointer for unaligned write of a uint16_t variable. */ + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif + +#ifndef __UNALIGNED_UINT16_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + /** \brief Packed struct for unaligned uint16_t read access */ + __PACKED_STRUCT T_UINT16_READ { + uint16_t v; + }; + #pragma GCC diagnostic pop + /** \brief Pointer for unaligned read of a uint16_t variable. */ + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif + +#ifndef __UNALIGNED_UINT32_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + /** \brief Packed struct for unaligned uint32_t write access */ + __PACKED_STRUCT T_UINT32_WRITE { + uint32_t v; + }; + #pragma GCC diagnostic pop + /** \brief Pointer for unaligned write of a uint32_t variable. */ + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif + +#ifndef __UNALIGNED_UINT32_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + /** \brief Packed struct for unaligned uint32_t read access */ + __PACKED_STRUCT T_UINT32_READ { + uint32_t v; + }; + #pragma GCC diagnostic pop + /** \brief Pointer for unaligned read of a uint32_t variable. */ + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif + +/** \brief Minimum `x` bytes alignment for a variable. */ +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif + +/** \brief restrict pointer qualifier to enable additional optimizations. */ +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + +/** \brief Barrier to prevent compiler from reordering instructions. */ +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + +/** \brief provide the compiler with branch prediction information, the branch is usually true */ +#ifndef __USUALLY + #define __USUALLY(exp) __builtin_expect((exp), 1) +#endif + +/** \brief provide the compiler with branch prediction information, the branch is rarely true */ +#ifndef __RARELY + #define __RARELY(exp) __builtin_expect((exp), 0) +#endif + +/** \brief Use this attribute to indicate that the specified function is an interrupt handler run in Machine Mode. */ +#ifndef __INTERRUPT + #define __INTERRUPT __attribute__((interrupt)) +#endif + +/** \brief Use this attribute to indicate that the specified function is an interrupt handler run in Machine Mode. */ +#ifndef __MACHINE_INTERRUPT + #define __MACHINE_INTERRUPT __attribute__ ((interrupt ("machine"))) +#endif + +/** \brief Use this attribute to indicate that the specified function is an interrupt handler run in Supervisor Mode. */ +#ifndef __SUPERVISOR_INTERRUPT + #define __SUPERVISOR_INTERRUPT __attribute__ ((interrupt ("supervisor"))) +#endif + +/** \brief Use this attribute to indicate that the specified function is an interrupt handler run in User Mode. */ +#ifndef __USER_INTERRUPT + #define __USER_INTERRUPT __attribute__ ((interrupt ("user"))) +#endif + +/** @} */ /* End of Doxygen Group NMSIS_Core_CompilerControl */ + +#ifdef __cplusplus +} +#endif +#endif /* __NMSIS_GCC_H__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_iar.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_iar.h new file mode 100644 index 0000000..8c5ffc0 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_iar.h @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NMSIS_IAR_H__ +#define __NMSIS_IAR_H__ +/*! + * @file nmsis_iar.h + * @brief NMSIS compiler IAR header file + */ +#include + +#ifdef __cplusplus + extern "C" { +#endif + +#include "riscv_encoding.h" + +/* ######################### Startup and Lowlevel Init ######################## */ +/** + * \defgroup NMSIS_Core_CompilerControl Compiler Control + * \ingroup NMSIS_Core + * \brief Compiler agnostic \#define symbols for generic c/c++ source code + * \details + * + * The NMSIS-Core provides the header file nmsis_compiler.h with consistent \#define symbols for generate C or C++ source files that should be compiler agnostic. + * Each NMSIS compliant compiler should support the functionality described in this section. + * + * The header file nmsis_compiler.h is also included by each Device Header File so that these definitions are available. + * @{ + */ + +/* Fallback for __has_builtin */ +#ifndef __has_builtin + #define __has_builtin(x) (0) +#endif + +/* NMSIS compiler specific defines */ +/** \brief Pass information from the compiler to the assembler. */ +#ifndef __ASM + #define __ASM __asm +#endif + +/** \brief Recommend that function should be inlined by the compiler. */ +#ifndef __INLINE + #define __INLINE inline +#endif + +/** \brief Define a static function that may be inlined by the compiler. */ +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif + +/** \brief Define a static function that should be always inlined by the compiler. */ +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline +#endif + +/** \brief Inform the compiler that a function does not return. */ +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif + +/** \brief Inform that a variable shall be retained in executable image. */ +#ifndef __USED + #define __USED __attribute__((used)) +#endif + +/** \brief restrict pointer qualifier to enable additional optimizations. */ +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif + +/** \brief specified the vector size of the variable, measured in bytes, not supported in IAR */ +#ifndef __VECTOR_SIZE + #define __VECTOR_SIZE(x) +#endif + +/** \brief Request smallest possible alignment. */ +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif + +/** \brief Request smallest possible alignment for a structure. */ +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif + +/** \brief Request smallest possible alignment for a union. */ +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif + +#ifndef __UNALIGNED_UINT16_WRITE + #pragma language=save + #pragma language=extended + /** \brief Packed struct for unaligned uint16_t write access */ + __PACKED_STRUCT T_UINT16_WRITE { + uint16_t v; + }; + #pragma language=restore + /** \brief Pointer for unaligned write of a uint16_t variable. */ + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif + +#ifndef __UNALIGNED_UINT16_READ + #pragma language=save + #pragma language=extended + /** \brief Packed struct for unaligned uint16_t read access */ + __PACKED_STRUCT T_UINT16_READ { + uint16_t v; + }; + #pragma language=restore + /** \brief Pointer for unaligned read of a uint16_t variable. */ + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif + +#ifndef __UNALIGNED_UINT32_WRITE + #pragma language=save + #pragma language=extended + /** \brief Packed struct for unaligned uint32_t write access */ + __PACKED_STRUCT T_UINT32_WRITE { + uint32_t v; + }; + #pragma language=restore + /** \brief Pointer for unaligned write of a uint32_t variable. */ + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif + +#ifndef __UNALIGNED_UINT32_READ + #pragma language=save + #pragma language=extended + /** \brief Packed struct for unaligned uint32_t read access */ + __PACKED_STRUCT T_UINT32_READ { + uint32_t v; + }; + #pragma language=restore + /** \brief Pointer for unaligned read of a uint32_t variable. */ + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif + +/** \brief Minimum `x` bytes alignment for a variable. */ +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif + +/** \brief restrict pointer qualifier to enable additional optimizations. */ +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + +/** \brief Barrier to prevent compiler from reordering instructions. */ +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + +/** \brief provide the compiler with branch prediction information, the branch is usually true */ +#ifndef __USUALLY + #define __USUALLY(exp) (exp) +#endif + +/** \brief provide the compiler with branch prediction information, the branch is rarely true */ +#ifndef __RARELY + #define __RARELY(exp) (exp) +#endif + +/** \brief Use this attribute to indicate that the specified function is an interrupt handler run in Machine Mode. */ +#ifndef __INTERRUPT + #define __INTERRUPT __machine __interrupt +#endif + +/** \brief Use this attribute to indicate that the specified function is an interrupt handler run in Machine Mode. */ +#ifndef __MACHINE_INTERRUPT + #define __MACHINE_INTERRUPT __machine __interrupt +#endif + +/** \brief Use this attribute to indicate that the specified function is an interrupt handler run in Supervisor Mode. */ +#ifndef __SUPERVISOR_INTERRUPT + #define __SUPERVISOR_INTERRUPT __supervisor __interrupt +#endif + +/** \brief Use this attribute to indicate that the specified function is an interrupt handler run in User Mode. */ +#ifndef __USER_INTERRUPT + #define __USER_INTERRUPT __user __interrupt +#endif + +/** @} */ /* End of Doxygen Group NMSIS_Core_CompilerControl */ + +#ifdef __cplusplus +} +#endif +#endif /* __NMSIS_GCC_H__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_version.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_version.h new file mode 100644 index 0000000..7c2f5b4 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_version.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __NMSIS_VERSION_H +#define __NMSIS_VERSION_H + +/** + * \defgroup NMSIS_Core_VersionControl Version Control + * \ingroup NMSIS_Core + * \brief Version \#define symbols for NMSIS release specific C/C++ source code + * \details + * + * We followed the [semantic versioning 2.0.0](https://semver.org/) to control NMSIS version. + * The version format is **MAJOR.MINOR.PATCH**, increment the: + * 1. MAJOR version when you make incompatible API changes, + * 2. MINOR version when you add functionality in a backwards compatible manner, and + * 3. PATCH version when you make backwards compatible bug fixes. + * + * The header file `nmsis_version.h` is included by each core header so that these definitions are available. + * + * **Example Usage for NMSIS Version Check**: + * \code + * #if defined(__NMSIS_VERSION) && (__NMSIS_VERSION >= 0x00010105) + * #warning "Yes, we have NMSIS 1.1.5 or later" + * #else + * #error "We need NMSIS 1.1.5 or later!" + * #endif + * \endcode + * + * @{ + */ + +/*! + * \file nmsis_version.h + * \brief NMSIS Version definitions + **/ + +/** + * \brief Represent the NMSIS major version + * \details + * The NMSIS major version can be used to + * differentiate between NMSIS major releases. + * */ +#define __NMSIS_VERSION_MAJOR (1U) + +/** + * \brief Represent the NMSIS minor version + * \details + * The NMSIS minor version can be used to + * query a NMSIS release update including new features. + * + **/ +#define __NMSIS_VERSION_MINOR (3U) + +/** + * \brief Represent the NMSIS patch version + * \details + * The NMSIS patch version can be used to + * show bug fixes in this package. + **/ +#define __NMSIS_VERSION_PATCH (1U) +/** + * \brief Represent the NMSIS Version + * \details + * NMSIS Version format: **MAJOR.MINOR.PATCH** + * * MAJOR: \ref __NMSIS_VERSION_MAJOR, stored in `bits [31:16]` of \ref __NMSIS_VERSION + * * MINOR: \ref __NMSIS_VERSION_MINOR, stored in `bits [15:8]` of \ref __NMSIS_VERSION + * * PATCH: \ref __NMSIS_VERSION_PATCH, stored in `bits [7:0]` of \ref __NMSIS_VERSION + **/ +#define __NMSIS_VERSION ((__NMSIS_VERSION_MAJOR << 16U) | (__NMSIS_VERSION_MINOR << 8) | __NMSIS_VERSION_PATCH) + +/** @} */ /* End of Doxygen Group NMSIS_Core_VersionControl */ +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/riscv_bits.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/riscv_bits.h new file mode 100644 index 0000000..75550e7 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/riscv_bits.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __RISCV_BITS_H__ +#define __RISCV_BITS_H__ + +#ifdef __cplusplus + extern "C" { +#endif + +#if __riscv_xlen == 64 +# define SLL32 sllw +# define STORE sd +# define LOAD ld +# define LWU lwu +# define LOG_REGBYTES 3 +#else +# define SLL32 sll +# define STORE sw +# define LOAD lw +# define LWU lw +# define LOG_REGBYTES 2 +#endif /* __riscv_xlen */ + +#define REGBYTES (1 << LOG_REGBYTES) + +#if defined(__riscv_flen) +#if __riscv_flen == 64 +# define FPSTORE fsd +# define FPLOAD fld +# define LOG_FPREGBYTES 3 +#else +# define FPSTORE fsw +# define FPLOAD flw +# define LOG_FPREGBYTES 2 +#endif /* __riscv_flen == 64 */ +#define FPREGBYTES (1 << LOG_FPREGBYTES) +#endif /* __riscv_flen */ + +#ifdef __GNUC__ +#define __rv_likely(x) __builtin_expect((x), 1) +#define __rv_unlikely(x) __builtin_expect((x), 0) +#else +#define __rv_likely(x) (x) +#define __rv_unlikely(x) (x) +#endif + +#define __RV_ROUNDUP(a, b) ((((a)-1)/(b)+1)*(b)) +#define __RV_ROUNDDOWN(a, b) ((a)/(b)*(b)) + +#define __RV_MAX(a, b) ((a) > (b) ? (a) : (b)) +#define __RV_MIN(a, b) ((a) < (b) ? (a) : (b)) +#define __RV_CLAMP(a, lo, hi) __RV_MIN(__RV_MAX(a, lo), hi) + +#define __RV_EXTRACT_FIELD(val, which) (((val) & (which)) / ((which) & ~((which)-1))) +#define __RV_INSERT_FIELD(val, which, fieldval) (((val) & ~(which)) | ((fieldval) * ((which) & ~((which)-1)))) + +#ifdef __ASSEMBLY__ +#define _AC(X,Y) X +#define _AT(T,X) X +#else +#define __AC(X,Y) (X##Y) +#define _AC(X,Y) __AC(X,Y) +#define _AT(T,X) ((T)(X)) +#endif /* __ASSEMBLY__ */ + +#define _UL(x) (_AC(x, UL)) +#define _ULL(x) (_AC(x, ULL)) + +#define _BITUL(x) (_UL(1) << (x)) +#define _BITULL(x) (_ULL(1) << (x)) + +#define UL(x) (_UL(x)) +#define ULL(x) (_ULL(x)) + +#define STR(x) XSTR(x) +#define XSTR(x) #x +#define __STR(s) #s +#define STRINGIFY(s) __STR(s) + +#ifdef __cplusplus +} +#endif + +#endif /* __RISCV_BITS_H__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/riscv_encoding.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/riscv_encoding.h new file mode 100644 index 0000000..72fba8f --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/riscv_encoding.h @@ -0,0 +1,1104 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __RISCV_ENCODING_H__ +#define __RISCV_ENCODING_H__ + +#ifdef __cplusplus + extern "C" { +#endif + +#include "riscv_bits.h" + +/** + * \defgroup NMSIS_Core_CSR_Encoding Core CSR Encodings + * \ingroup NMSIS_Core + * \brief NMSIS Core CSR Encodings + * \details + * + * The following macros are used for CSR encodings + * @{ + */ +/* === Standard CSR bit mask === */ +#define MSTATUS_UIE 0x00000001 +#define MSTATUS_SIE 0x00000002 +#define MSTATUS_HIE 0x00000004 +#define MSTATUS_MIE 0x00000008 +#define MSTATUS_UPIE 0x00000010 +#define MSTATUS_SPIE 0x00000020 +#define MSTATUS_UBE 0x00000040 +#define MSTATUS_MPIE 0x00000080 +#define MSTATUS_SPP 0x00000100 +#define MSTATUS_VS 0x00000600 +#define MSTATUS_MPP 0x00001800 +#define MSTATUS_FS 0x00006000 +#define MSTATUS_XS 0x00018000 +#define MSTATUS_MPRV 0x00020000 +#define MSTATUS_SUM 0x00040000 +#define MSTATUS_MXR 0x00080000 +#define MSTATUS_TVM 0x00100000 +#define MSTATUS_TW 0x00200000 +#define MSTATUS_TSR 0x00400000 +#define MSTATUS32_SD 0x80000000 +#define MSTATUS_UXL 0x0000000300000000 +#define MSTATUS_SXL 0x0000000C00000000 +#define MSTATUS_SBE 0x0000001000000000 +#define MSTATUS_MBE 0x0000002000000000 +#define MSTATUS_GVA 0x0000004000000000 +#define MSTATUS_MPV 0x0000008000000000 +#define MSTATUS64_SD 0x8000000000000000 + +#define MSTATUS_FS_INITIAL 0x00002000 +#define MSTATUS_FS_CLEAN 0x00004000 +#define MSTATUS_FS_DIRTY 0x00006000 + +#define MSTATUS_VS_INITIAL 0x00000200 +#define MSTATUS_VS_CLEAN 0x00000400 +#define MSTATUS_VS_DIRTY 0x00000600 + +#define MSTATUSH_SBE 0x00000010 +#define MSTATUSH_MBE 0x00000020 +#define MSTATUSH_GVA 0x00000040 +#define MSTATUSH_MPV 0x00000080 + +#define SSTATUS_UIE 0x00000001 +#define SSTATUS_SIE 0x00000002 +#define SSTATUS_UPIE 0x00000010 +#define SSTATUS_SPIE 0x00000020 +#define SSTATUS_UBE 0x00000040 +#define SSTATUS_SPP 0x00000100 +#define SSTATUS_VS 0x00000600 +#define SSTATUS_FS 0x00006000 +#define SSTATUS_XS 0x00018000 +#define SSTATUS_SUM 0x00040000 +#define SSTATUS_MXR 0x00080000 +#define SSTATUS32_SD 0x80000000 +#define SSTATUS_UXL 0x0000000300000000 +#define SSTATUS64_SD 0x8000000000000000 + +#define USTATUS_UIE 0x00000001 +#define USTATUS_UPIE 0x00000010 + +#define DCSR_XDEBUGVER (3U<<30) +#define DCSR_NDRESET (1<<29) +#define DCSR_FULLRESET (1<<28) +#define DCSR_EBREAKM (1<<15) +#define DCSR_EBREAKH (1<<14) +#define DCSR_EBREAKS (1<<13) +#define DCSR_EBREAKU (1<<12) +#define DCSR_STOPCYCLE (1<<10) +#define DCSR_STOPTIME (1<<9) +#define DCSR_CAUSE (7<<6) +#define DCSR_DEBUGINT (1<<5) +#define DCSR_HALT (1<<3) +#define DCSR_STEP (1<<2) +#define DCSR_PRV (3<<0) + +#define DCSR_CAUSE_NONE 0 +#define DCSR_CAUSE_SWBP 1 +#define DCSR_CAUSE_HWBP 2 +#define DCSR_CAUSE_DEBUGINT 3 +#define DCSR_CAUSE_STEP 4 +#define DCSR_CAUSE_HALT 5 + +#define MCONTROL_TYPE(xlen) (0xfULL<<((xlen)-4)) +#define MCONTROL_DMODE(xlen) (1ULL<<((xlen)-5)) +#define MCONTROL_MASKMAX(xlen) (0x3fULL<<((xlen)-11)) + +#define MCONTROL_SELECT (1<<19) +#define MCONTROL_TIMING (1<<18) +#define MCONTROL_ACTION (0x3f<<12) +#define MCONTROL_CHAIN (1<<11) +#define MCONTROL_MATCH (0xf<<7) +#define MCONTROL_M (1<<6) +#define MCONTROL_H (1<<5) +#define MCONTROL_S (1<<4) +#define MCONTROL_U (1<<3) +#define MCONTROL_EXECUTE (1<<2) +#define MCONTROL_STORE (1<<1) +#define MCONTROL_LOAD (1<<0) + +#define MCONTROL_TYPE_NONE 0 +#define MCONTROL_TYPE_MATCH 2 + +#define MCONTROL_ACTION_DEBUG_EXCEPTION 0 +#define MCONTROL_ACTION_DEBUG_MODE 1 +#define MCONTROL_ACTION_TRACE_START 2 +#define MCONTROL_ACTION_TRACE_STOP 3 +#define MCONTROL_ACTION_TRACE_EMIT 4 + +#define MCONTROL_MATCH_EQUAL 0 +#define MCONTROL_MATCH_NAPOT 1 +#define MCONTROL_MATCH_GE 2 +#define MCONTROL_MATCH_LT 3 +#define MCONTROL_MATCH_MASK_LOW 4 +#define MCONTROL_MATCH_MASK_HIGH 5 + +#define MIP_SSIP (1 << IRQ_S_SOFT) +#define MIP_HSIP (1 << IRQ_H_SOFT) +#define MIP_MSIP (1 << IRQ_M_SOFT) +#define MIP_STIP (1 << IRQ_S_TIMER) +#define MIP_HTIP (1 << IRQ_H_TIMER) +#define MIP_MTIP (1 << IRQ_M_TIMER) +#define MIP_SEIP (1 << IRQ_S_EXT) +#define MIP_HEIP (1 << IRQ_H_EXT) +#define MIP_MEIP (1 << IRQ_M_EXT) + +#define MIE_SSIE MIP_SSIP +#define MIE_HSIE MIP_HSIP +#define MIE_MSIE MIP_MSIP +#define MIE_STIE MIP_STIP +#define MIE_HTIE MIP_HTIP +#define MIE_MTIE MIP_MTIP +#define MIE_SEIE MIP_SEIP +#define MIE_HEIE MIP_HEIP +#define MIE_MEIE MIP_MEIP + +#define SIP_SSIP MIP_SSIP +#define SIP_STIP MIP_STIP +#define SIP_SEIP MIP_SEIP + +#define SIE_SSIE MIP_SSIP +#define SIE_STIE MIP_STIP +#define SIE_SEIE MIP_SEIP + +#define MCAUSE_INTR (1ULL << (__riscv_xlen - 1)) +#define MCAUSE_CAUSE 0x00000FFFUL +#define SCAUSE_INTR MCAUSE_INTR +#define SCAUSE_CAUSE 0x000003FFUL + +#define MENVCFG_CBIE_EN (0x11 << 4) +#define MENVCFG_CBIE_FLUSH (0x01 << 4) +#define MENVCFG_CBIE_INVAL (0x11 << 4) +#define MENVCFG_CBCFE (0x1 << 6) +#define MENVCFG_CBZE (0x1 << 7) +#define SENVCFG_CBIE_EN (0x11 << 4) +#define SENVCFG_CBIE_FLUSH (0x01 << 4) +#define SENVCFG_CBIE_INVAL (0x11 << 4) +#define SENVCFG_CBCFE (0x1 << 6) +#define SENVCFG_CBZE (0x1 << 7) + +/* === P-ext CSR bit mask === */ + +#define UCODE_OV (0x1) + +/* === Nuclei custom CSR bit mask === */ +#define CSR_MCACHE_CTL_IE 0x00000001 +#define CSR_MCACHE_CTL_DE 0x00010000 + +#define WFE_WFE (0x1) +#define TXEVT_TXEVT (0x1) +#define SLEEPVALUE_SLEEPVALUE (0x1) + +#define MCOUNTINHIBIT_IR (1<<2) +#define MCOUNTINHIBIT_CY (1<<0) + +#define MILM_CTL_ILM_BPA (((1ULL<<((__riscv_xlen)-10))-1)<<10) +#define MILM_CTL_ILM_ECC_CHK_EN (1<<4) +#define MILM_CTL_ILM_RWECC (1<<3) +#define MILM_CTL_ILM_ECC_INJ_EN (1<<3) +#define MILM_CTL_ILM_ECC_EXCP_EN (1<<2) +#define MILM_CTL_ILM_ECC_EN (1<<1) +#define MILM_CTL_ILM_EN (1<<0) + +#define MDLM_CTL_DLM_BPA (((1ULL<<((__riscv_xlen)-10))-1)<<10) +#define MDLM_CTL_DLM_ECC_CHK_EN (1<<4) +#define MDLM_CTL_DLM_RWECC (1<<3) +#define MDLM_CTL_DLM_ECC_INJ_EN (1<<3) +#define MDLM_CTL_DLM_ECC_EXCP_EN (1<<2) +#define MDLM_CTL_DLM_ECC_EN (1<<1) +#define MDLM_CTL_DLM_EN (1<<0) + +#define MSUBM_PTYP (0x3<<8) +#define MSUBM_TYP (0x3<<6) + +#define MDCAUSE_MDCAUSE (0x7) + +#define MMISC_CTL_LDSPEC_ENABLE (1<<12) +#define MMISC_CTL_SIJUMP_ENABLE (1<<11) +#define MMISC_CTL_IMRETURN_ENABLE (1<<10) +#define MMISC_CTL_NMI_CAUSE_FFF (1<<9) +#define MMISC_CTL_CODE_BUS_ERR (1<<8) +#define MMISC_CTL_MISALIGN (1<<6) +#define MMISC_CTL_ZC (1<<7) +#define MMISC_CTL_BPU (1<<3) + +#define MCACHE_CTL_IC_EN (1<<0) +#define MCACHE_CTL_IC_SCPD_MOD (1<<1) +#define MCACHE_CTL_IC_ECC_EN (1<<2) +#define MCACHE_CTL_IC_ECC_EXCP_EN (1<<3) +#define MCACHE_CTL_IC_TRAM_ECC_INJ_EN (1<<4) +#define MCACHE_CTL_IC_RWTECC (1<<4) +#define MCACHE_CTL_IC_RWDECC (1<<5) +#define MCACHE_CTL_IC_DRAM_ECC_INJ_EN (1<<5) +#define MCACHE_CTL_IC_PF_EN (1<<6) +#define MCACHE_CTL_IC_CANCEL_EN (1<<7) +#define MCACHE_CTL_IC_ECC_CHK_EN (1<<8) +#define MCACHE_CTL_DC_EN (1<<16) +#define MCACHE_CTL_DC_ECC_EN (1<<17) +#define MCACHE_CTL_DC_ECC_EXCP_EN (1<<18) +#define MCACHE_CTL_DC_TRAM_ECC_INJ_EN (1<<19) +#define MCACHE_CTL_DC_RWTECC (1<<19) +#define MCACHE_CTL_DC_RWDECC (1<<20) +#define MCACHE_CTL_DC_DRAM_ECC_INJ_EN (1<<20) +#define MCACHE_CTL_DC_ECC_CHK_EN (1<<21) + +#define MTVT2_MTVT2EN (1<<0) +#define MTVT2_COMMON_CODE_ENTRY (((1ULL<<((__riscv_xlen)-2))-1)<<2) + +#define MCFG_INFO_TEE (1<<0) +#define MCFG_INFO_ECC (1<<1) +#define MCFG_INFO_CLIC (1<<2) +#define MCFG_INFO_PLIC (1<<3) +#define MCFG_INFO_FIO (1<<4) +#define MCFG_INFO_PPI (1<<5) +#define MCFG_INFO_NICE (1<<6) +#define MCFG_INFO_ILM (1<<7) +#define MCFG_INFO_DLM (1<<8) +#define MCFG_INFO_ICACHE (1<<9) +#define MCFG_INFO_DCACHE (1<<10) +#define MCFG_INFO_SMP (1<<11) +#define MCFG_INFO_DSP_N1 (1<<12) +#define MCFG_INFO_DSP_N2 (1<<13) +#define MCFG_INFO_DSP_N3 (1<<14) +#define MCFG_INFO_IREGION_EXIST (1<<16) +#define MCFG_INFO_VP (0x3<<17) + +#define MICFG_IC_SET (0xF<<0) +#define MICFG_IC_WAY (0x7<<4) +#define MICFG_IC_LSIZE (0x7<<7) +#define MICFG_IC_ECC (0x1<<10) +#define MICFG_ILM_SIZE (0x1F<<16) +#define MICFG_ILM_XONLY (0x1<<21) +#define MICFG_ILM_ECC (0x1<<22) + +#define MDCFG_DC_SET (0xF<<0) +#define MDCFG_DC_WAY (0x7<<4) +#define MDCFG_DC_LSIZE (0x7<<7) +#define MDCFG_DC_ECC (0x1<<10) +#define MDCFG_DLM_SIZE (0x1F<<16) +#define MDCFG_DLM_ECC (0x1<<21) + +#define MIRGB_INFO_IRG_BASE_ADDR_BOFS (10) +#define MIRGB_INFO_IREGION_SIZE_BOFS (1) + +#define MPPICFG_INFO_PPI_SIZE (0x1F<<1) +#define MPPICFG_INFO_PPI_BPA (((1ULL<<((__riscv_xlen)-10))-1)<<10) + +#define MFIOCFG_INFO_FIO_SIZE (0x1F<<1) +#define MFIOCFG_INFO_FIO_BPA (((1ULL<<((__riscv_xlen)-10))-1)<<10) + +#define MECC_LOCK_ECC_LOCK (0x1) + +#define MECC_CODE_CODE (0x1FF) +#define MECC_CODE_RAMID (0x1F<<16) +#define MECC_CODE_SRAMID (0x1F<<24) + +#define CCM_SUEN_SUEN (0x1<<0) +#define CCM_DATA_DATA (0x7<<0) +#define CCM_COMMAND_COMMAND (0x1F<<0) + +/* IREGION Offsets */ +#define IREGION_IINFO_OFS (0x0) +#define IREGION_DEBUG_OFS (0x10000) +#define IREGION_ECLIC_OFS (0x20000) +#define IREGION_TIMER_OFS (0x30000) +#define IREGION_SMP_OFS (0x40000) +#define IREGION_IDU_OFS (0x50000) +#define IREGION_PL2_OFS (0x60000) +#define IREGION_DPREFETCH_OFS (0x70000) +#define IREGION_PLIC_OFS (0x4000000) + +/* === Stack protect === */ +#define MSTACK_CTRL_MODE (0x1<<2) +#define MSTACK_CTRL_UDF_EN (0x1<<1) +#define MSTACK_CTRL_OVF_TRACK_EN (0x1) + +#define SIP_SSIP MIP_SSIP +#define SIP_STIP MIP_STIP + +#define PRV_U 0 +#define PRV_S 1 +#define PRV_H 2 +#define PRV_M 3 + +#define VM_MBARE 0 +#define VM_MBB 1 +#define VM_MBBID 2 +#define VM_SV32 8 +#define VM_SV39 9 +#define VM_SV48 10 + +#define SATP32_MODE 0x80000000 +#define SATP32_ASID 0x7FC00000 +#define SATP32_PPN 0x003FFFFF +#define SATP64_MODE 0xF000000000000000 +#define SATP64_ASID 0x0FFFF00000000000 +#define SATP64_PPN 0x00000FFFFFFFFFFF + +#define SATP_MODE_OFF 0 +#define SATP_MODE_SV32 1 +#define SATP_MODE_SV39 8 +#define SATP_MODE_SV48 9 +#define SATP_MODE_SV57 10 +#define SATP_MODE_SV64 11 + +#define IRQ_S_SOFT 1 +#define IRQ_H_SOFT 2 +#define IRQ_M_SOFT 3 +#define IRQ_S_TIMER 5 +#define IRQ_H_TIMER 6 +#define IRQ_M_TIMER 7 +#define IRQ_S_EXT 9 +#define IRQ_H_EXT 10 +#define IRQ_M_EXT 11 +#define IRQ_COP 12 +#define IRQ_HOST 13 + + +/* === FPU FRM Rounding Mode === */ +/** FPU Round to Nearest, ties to Even*/ +#define FRM_RNDMODE_RNE 0x0 +/** FPU Round Towards Zero */ +#define FRM_RNDMODE_RTZ 0x1 +/** FPU Round Down (towards -inf) */ +#define FRM_RNDMODE_RDN 0x2 +/** FPU Round Up (towards +inf) */ +#define FRM_RNDMODE_RUP 0x3 +/** FPU Round to nearest, ties to Max Magnitude */ +#define FRM_RNDMODE_RMM 0x4 +/** + * In instruction's rm, selects dynamic rounding mode. + * In Rounding Mode register, Invalid */ +#define FRM_RNDMODE_DYN 0x7 + +/* === FPU FFLAGS Accrued Exceptions === */ +/** FPU Inexact */ +#define FFLAGS_AE_NX (1<<0) +/** FPU Underflow */ +#define FFLAGS_AE_UF (1<<1) +/** FPU Overflow */ +#define FFLAGS_AE_OF (1<<2) +/** FPU Divide by Zero */ +#define FFLAGS_AE_DZ (1<<3) +/** FPU Invalid Operation */ +#define FFLAGS_AE_NV (1<<4) + +/** Floating Point Register f0-f31, eg. f0 -> FREG(0) */ +#define FREG(idx) f##idx + + +/* === PMP CFG Bits === */ +#define PMP_R 0x01 +#define PMP_W 0x02 +#define PMP_X 0x04 +#define PMP_A 0x18 +#define PMP_A_TOR 0x08 +#define PMP_A_NA4 0x10 +#define PMP_A_NAPOT 0x18 +#define PMP_L 0x80 + +#define PMP_SHIFT 2 +#define PMP_COUNT 16 + +/* === sPMP CFG Bits === */ +#define SPMP_R PMP_R +#define SPMP_W PMP_W +#define SPMP_X PMP_X +#define SPMP_A PMP_A +#define SPMP_A_TOR PMP_A_TOR +#define SPMP_A_NA4 PMP_A_NA4 +#define SPMP_A_NAPOT PMP_A_NAPOT +#define SPMP_U 0x40 +#define SPMP_L PMP_L + +#define SPMP_SHIFT PMP_SHIFT +#define SPMP_COUNT 16 + +/* === SMPU CFG Bits === */ +#define SMPU_R SPMP_R +#define SMPU_W SPMP_W +#define SMPU_X SPMP_X +#define SMPU_A SPMP_A +#define SMPU_A_TOR SPMP_A_TOR +#define SMPU_A_NA4 SPMP_A_NA4 +#define SMPU_A_NAPOT SPMP_A_NAPOT +#define SMPU_S 0x80 + +#define SMPU_SHIFT PMP_SHIFT + +// page table entry (PTE) fields +#define PTE_V 0x001 // Valid +#define PTE_R 0x002 // Read +#define PTE_W 0x004 // Write +#define PTE_X 0x008 // Execute +#define PTE_U 0x010 // User +#define PTE_G 0x020 // Global +#define PTE_A 0x040 // Accessed +#define PTE_D 0x080 // Dirty +#define PTE_SOFT 0x300 // Reserved for Software + +#define PTE_PPN_SHIFT 10 + +#define PTE_TABLE(PTE) (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V) + +#ifdef __riscv + +#ifdef __riscv64 +# define MSTATUS_SD MSTATUS64_SD +# define SSTATUS_SD SSTATUS64_SD +# define RISCV_PGLEVEL_BITS 9 +#else +# define MSTATUS_SD MSTATUS32_SD +# define SSTATUS_SD SSTATUS32_SD +# define RISCV_PGLEVEL_BITS 10 +#endif /* __riscv64 */ + +#define RISCV_PGSHIFT 12 +#define RISCV_PGSIZE (1 << RISCV_PGSHIFT) + +#endif /* __riscv */ + +/** + * \defgroup NMSIS_Core_CSR_Registers Core CSR Registers + * \ingroup NMSIS_Core + * \brief NMSIS Core CSR Register Definitions + * \details + * + * The following macros are used for CSR Register Defintions. + * @{ + */ +/* === Standard RISC-V CSR Registers === */ +#define CSR_USTATUS 0x0 +#define CSR_FFLAGS 0x1 +#define CSR_FRM 0x2 +#define CSR_FCSR 0x3 +#define CSR_VSTART 0x8 +#define CSR_VXSAT 0x9 +#define CSR_VXRM 0xa +#define CSR_VCSR 0xf +#define CSR_SEED 0x15 +#define CSR_JVT 0x17 +#define CSR_CYCLE 0xc00 +#define CSR_TIME 0xc01 +#define CSR_INSTRET 0xc02 +#define CSR_HPMCOUNTER3 0xc03 +#define CSR_HPMCOUNTER4 0xc04 +#define CSR_HPMCOUNTER5 0xc05 +#define CSR_HPMCOUNTER6 0xc06 +#define CSR_HPMCOUNTER7 0xc07 +#define CSR_HPMCOUNTER8 0xc08 +#define CSR_HPMCOUNTER9 0xc09 +#define CSR_HPMCOUNTER10 0xc0a +#define CSR_HPMCOUNTER11 0xc0b +#define CSR_HPMCOUNTER12 0xc0c +#define CSR_HPMCOUNTER13 0xc0d +#define CSR_HPMCOUNTER14 0xc0e +#define CSR_HPMCOUNTER15 0xc0f +#define CSR_HPMCOUNTER16 0xc10 +#define CSR_HPMCOUNTER17 0xc11 +#define CSR_HPMCOUNTER18 0xc12 +#define CSR_HPMCOUNTER19 0xc13 +#define CSR_HPMCOUNTER20 0xc14 +#define CSR_HPMCOUNTER21 0xc15 +#define CSR_HPMCOUNTER22 0xc16 +#define CSR_HPMCOUNTER23 0xc17 +#define CSR_HPMCOUNTER24 0xc18 +#define CSR_HPMCOUNTER25 0xc19 +#define CSR_HPMCOUNTER26 0xc1a +#define CSR_HPMCOUNTER27 0xc1b +#define CSR_HPMCOUNTER28 0xc1c +#define CSR_HPMCOUNTER29 0xc1d +#define CSR_HPMCOUNTER30 0xc1e +#define CSR_HPMCOUNTER31 0xc1f +#define CSR_VL 0xc20 +#define CSR_VTYPE 0xc21 +#define CSR_VLENB 0xc22 +#define CSR_SSTATUS 0x100 +#define CSR_SEDELEG 0x102 +#define CSR_SIDELEG 0x103 +#define CSR_SIE 0x104 +#define CSR_STVEC 0x105 +#define CSR_STVT 0x107 +#define CSR_SCOUNTEREN 0x106 +#define CSR_SENVCFG 0x10a +#define CSR_SSTATEEN0 0x10c +#define CSR_SSTATEEN1 0x10d +#define CSR_SSTATEEN2 0x10e +#define CSR_SSTATEEN3 0x10f +#define CSR_SSCRATCH 0x140 +#define CSR_SEPC 0x141 +#define CSR_SCAUSE 0x142 +#define CSR_STVAL 0x143 +#define CSR_SIP 0x144 +#define CSR_STIMECMP 0x14d +#define CSR_SATP 0x180 +#define CSR_SCONTEXT 0x5a8 +#define CSR_VSSTATUS 0x200 +#define CSR_VSIE 0x204 +#define CSR_VSTVEC 0x205 +#define CSR_VSSCRATCH 0x240 +#define CSR_VSEPC 0x241 +#define CSR_VSCAUSE 0x242 +#define CSR_VSTVAL 0x243 +#define CSR_VSIP 0x244 +#define CSR_VSTIMECMP 0x24d +#define CSR_VSATP 0x280 +#define CSR_HSTATUS 0x600 +#define CSR_HEDELEG 0x602 +#define CSR_HIDELEG 0x603 +#define CSR_HIE 0x604 +#define CSR_HTIMEDELTA 0x605 +#define CSR_HCOUNTEREN 0x606 +#define CSR_HGEIE 0x607 +#define CSR_HENVCFG 0x60a +#define CSR_HSTATEEN0 0x60c +#define CSR_HSTATEEN1 0x60d +#define CSR_HSTATEEN2 0x60e +#define CSR_HSTATEEN3 0x60f +#define CSR_HTVAL 0x643 +#define CSR_HIP 0x644 +#define CSR_HVIP 0x645 +#define CSR_HTINST 0x64a +#define CSR_HGATP 0x680 +#define CSR_HCONTEXT 0x6a8 +#define CSR_HGEIP 0xe12 +#define CSR_SCOUNTOVF 0xda0 +#define CSR_UTVT 0x7 +#define CSR_UNXTI 0x45 +#define CSR_UINTSTATUS 0x46 +#define CSR_USCRATCHCSW 0x48 +#define CSR_USCRATCHCSWL 0x49 +#define CSR_STVT 0x107 +#define CSR_SNXTI 0x145 +#define CSR_SINTSTATUS 0x146 +#define CSR_SSCRATCHCSW 0x148 +#define CSR_SSCRATCHCSWL 0x149 +#define CSR_MTVT 0x307 +#define CSR_MNXTI 0x345 +#define CSR_MINTSTATUS 0x346 +#define CSR_MSCRATCHCSW 0x348 +#define CSR_MSCRATCHCSWL 0x349 +#define CSR_MSTATUS 0x300 +#define CSR_MISA 0x301 +#define CSR_MEDELEG 0x302 +#define CSR_MIDELEG 0x303 +#define CSR_MIE 0x304 +#define CSR_MTVEC 0x305 +#define CSR_MCOUNTEREN 0x306 +#define CSR_MENVCFG 0x30a +#define CSR_MSTATEEN0 0x30c +#define CSR_MSTATEEN1 0x30d +#define CSR_MSTATEEN2 0x30e +#define CSR_MSTATEEN3 0x30f +#define CSR_MCOUNTINHIBIT 0x320 +#define CSR_MSCRATCH 0x340 +#define CSR_MEPC 0x341 +#define CSR_MCAUSE 0x342 +#define CSR_MTVAL 0x343 +#define CSR_MBADADDR 0x343 +#define CSR_MIP 0x344 +#define CSR_MTINST 0x34a +#define CSR_MTVAL2 0x34b +#define CSR_PMPCFG0 0x3a0 +#define CSR_PMPCFG1 0x3a1 +#define CSR_PMPCFG2 0x3a2 +#define CSR_PMPCFG3 0x3a3 +#define CSR_PMPCFG4 0x3a4 +#define CSR_PMPCFG5 0x3a5 +#define CSR_PMPCFG6 0x3a6 +#define CSR_PMPCFG7 0x3a7 +#define CSR_PMPCFG8 0x3a8 +#define CSR_PMPCFG9 0x3a9 +#define CSR_PMPCFG10 0x3aa +#define CSR_PMPCFG11 0x3ab +#define CSR_PMPCFG12 0x3ac +#define CSR_PMPCFG13 0x3ad +#define CSR_PMPCFG14 0x3ae +#define CSR_PMPCFG15 0x3af +#define CSR_PMPADDR0 0x3b0 +#define CSR_PMPADDR1 0x3b1 +#define CSR_PMPADDR2 0x3b2 +#define CSR_PMPADDR3 0x3b3 +#define CSR_PMPADDR4 0x3b4 +#define CSR_PMPADDR5 0x3b5 +#define CSR_PMPADDR6 0x3b6 +#define CSR_PMPADDR7 0x3b7 +#define CSR_PMPADDR8 0x3b8 +#define CSR_PMPADDR9 0x3b9 +#define CSR_PMPADDR10 0x3ba +#define CSR_PMPADDR11 0x3bb +#define CSR_PMPADDR12 0x3bc +#define CSR_PMPADDR13 0x3bd +#define CSR_PMPADDR14 0x3be +#define CSR_PMPADDR15 0x3bf +#define CSR_PMPADDR16 0x3c0 +#define CSR_PMPADDR17 0x3c1 +#define CSR_PMPADDR18 0x3c2 +#define CSR_PMPADDR19 0x3c3 +#define CSR_PMPADDR20 0x3c4 +#define CSR_PMPADDR21 0x3c5 +#define CSR_PMPADDR22 0x3c6 +#define CSR_PMPADDR23 0x3c7 +#define CSR_PMPADDR24 0x3c8 +#define CSR_PMPADDR25 0x3c9 +#define CSR_PMPADDR26 0x3ca +#define CSR_PMPADDR27 0x3cb +#define CSR_PMPADDR28 0x3cc +#define CSR_PMPADDR29 0x3cd +#define CSR_PMPADDR30 0x3ce +#define CSR_PMPADDR31 0x3cf +#define CSR_PMPADDR32 0x3d0 +#define CSR_PMPADDR33 0x3d1 +#define CSR_PMPADDR34 0x3d2 +#define CSR_PMPADDR35 0x3d3 +#define CSR_PMPADDR36 0x3d4 +#define CSR_PMPADDR37 0x3d5 +#define CSR_PMPADDR38 0x3d6 +#define CSR_PMPADDR39 0x3d7 +#define CSR_PMPADDR40 0x3d8 +#define CSR_PMPADDR41 0x3d9 +#define CSR_PMPADDR42 0x3da +#define CSR_PMPADDR43 0x3db +#define CSR_PMPADDR44 0x3dc +#define CSR_PMPADDR45 0x3dd +#define CSR_PMPADDR46 0x3de +#define CSR_PMPADDR47 0x3df +#define CSR_PMPADDR48 0x3e0 +#define CSR_PMPADDR49 0x3e1 +#define CSR_PMPADDR50 0x3e2 +#define CSR_PMPADDR51 0x3e3 +#define CSR_PMPADDR52 0x3e4 +#define CSR_PMPADDR53 0x3e5 +#define CSR_PMPADDR54 0x3e6 +#define CSR_PMPADDR55 0x3e7 +#define CSR_PMPADDR56 0x3e8 +#define CSR_PMPADDR57 0x3e9 +#define CSR_PMPADDR58 0x3ea +#define CSR_PMPADDR59 0x3eb +#define CSR_PMPADDR60 0x3ec +#define CSR_PMPADDR61 0x3ed +#define CSR_PMPADDR62 0x3ee +#define CSR_PMPADDR63 0x3ef +#define CSR_MSECCFG 0x747 +#define CSR_TSELECT 0x7a0 +#define CSR_TDATA1 0x7a1 +#define CSR_TDATA2 0x7a2 +#define CSR_TDATA3 0x7a3 +#define CSR_TINFO 0x7a4 +#define CSR_TCONTROL 0x7a5 +#define CSR_MCONTEXT 0x7a8 +#define CSR_MSCONTEXT 0x7aa +#define CSR_DCSR 0x7b0 +#define CSR_DPC 0x7b1 +#define CSR_DSCRATCH0 0x7b2 +#define CSR_DSCRATCH1 0x7b3 +#define CSR_MCYCLE 0xb00 +#define CSR_MINSTRET 0xb02 +#define CSR_MHPMCOUNTER3 0xb03 +#define CSR_MHPMCOUNTER4 0xb04 +#define CSR_MHPMCOUNTER5 0xb05 +#define CSR_MHPMCOUNTER6 0xb06 +#define CSR_MHPMCOUNTER7 0xb07 +#define CSR_MHPMCOUNTER8 0xb08 +#define CSR_MHPMCOUNTER9 0xb09 +#define CSR_MHPMCOUNTER10 0xb0a +#define CSR_MHPMCOUNTER11 0xb0b +#define CSR_MHPMCOUNTER12 0xb0c +#define CSR_MHPMCOUNTER13 0xb0d +#define CSR_MHPMCOUNTER14 0xb0e +#define CSR_MHPMCOUNTER15 0xb0f +#define CSR_MHPMCOUNTER16 0xb10 +#define CSR_MHPMCOUNTER17 0xb11 +#define CSR_MHPMCOUNTER18 0xb12 +#define CSR_MHPMCOUNTER19 0xb13 +#define CSR_MHPMCOUNTER20 0xb14 +#define CSR_MHPMCOUNTER21 0xb15 +#define CSR_MHPMCOUNTER22 0xb16 +#define CSR_MHPMCOUNTER23 0xb17 +#define CSR_MHPMCOUNTER24 0xb18 +#define CSR_MHPMCOUNTER25 0xb19 +#define CSR_MHPMCOUNTER26 0xb1a +#define CSR_MHPMCOUNTER27 0xb1b +#define CSR_MHPMCOUNTER28 0xb1c +#define CSR_MHPMCOUNTER29 0xb1d +#define CSR_MHPMCOUNTER30 0xb1e +#define CSR_MHPMCOUNTER31 0xb1f +#define CSR_MHPMEVENT3 0x323 +#define CSR_MHPMEVENT4 0x324 +#define CSR_MHPMEVENT5 0x325 +#define CSR_MHPMEVENT6 0x326 +#define CSR_MHPMEVENT7 0x327 +#define CSR_MHPMEVENT8 0x328 +#define CSR_MHPMEVENT9 0x329 +#define CSR_MHPMEVENT10 0x32a +#define CSR_MHPMEVENT11 0x32b +#define CSR_MHPMEVENT12 0x32c +#define CSR_MHPMEVENT13 0x32d +#define CSR_MHPMEVENT14 0x32e +#define CSR_MHPMEVENT15 0x32f +#define CSR_MHPMEVENT16 0x330 +#define CSR_MHPMEVENT17 0x331 +#define CSR_MHPMEVENT18 0x332 +#define CSR_MHPMEVENT19 0x333 +#define CSR_MHPMEVENT20 0x334 +#define CSR_MHPMEVENT21 0x335 +#define CSR_MHPMEVENT22 0x336 +#define CSR_MHPMEVENT23 0x337 +#define CSR_MHPMEVENT24 0x338 +#define CSR_MHPMEVENT25 0x339 +#define CSR_MHPMEVENT26 0x33a +#define CSR_MHPMEVENT27 0x33b +#define CSR_MHPMEVENT28 0x33c +#define CSR_MHPMEVENT29 0x33d +#define CSR_MHPMEVENT30 0x33e +#define CSR_MHPMEVENT31 0x33f +#define CSR_MVENDORID 0xf11 +#define CSR_MARCHID 0xf12 +#define CSR_MIMPID 0xf13 +#define CSR_MHARTID 0xf14 +#define CSR_MCONFIGPTR 0xf15 +#define CSR_STIMECMPH 0x15d +#define CSR_VSTIMECMPH 0x25d +#define CSR_HTIMEDELTAH 0x615 +#define CSR_HENVCFGH 0x61a +#define CSR_HSTATEEN0H 0x61c +#define CSR_HSTATEEN1H 0x61d +#define CSR_HSTATEEN2H 0x61e +#define CSR_HSTATEEN3H 0x61f +#define CSR_CYCLEH 0xc80 +#define CSR_TIMEH 0xc81 +#define CSR_INSTRETH 0xc82 +#define CSR_HPMCOUNTER3H 0xc83 +#define CSR_HPMCOUNTER4H 0xc84 +#define CSR_HPMCOUNTER5H 0xc85 +#define CSR_HPMCOUNTER6H 0xc86 +#define CSR_HPMCOUNTER7H 0xc87 +#define CSR_HPMCOUNTER8H 0xc88 +#define CSR_HPMCOUNTER9H 0xc89 +#define CSR_HPMCOUNTER10H 0xc8a +#define CSR_HPMCOUNTER11H 0xc8b +#define CSR_HPMCOUNTER12H 0xc8c +#define CSR_HPMCOUNTER13H 0xc8d +#define CSR_HPMCOUNTER14H 0xc8e +#define CSR_HPMCOUNTER15H 0xc8f +#define CSR_HPMCOUNTER16H 0xc90 +#define CSR_HPMCOUNTER17H 0xc91 +#define CSR_HPMCOUNTER18H 0xc92 +#define CSR_HPMCOUNTER19H 0xc93 +#define CSR_HPMCOUNTER20H 0xc94 +#define CSR_HPMCOUNTER21H 0xc95 +#define CSR_HPMCOUNTER22H 0xc96 +#define CSR_HPMCOUNTER23H 0xc97 +#define CSR_HPMCOUNTER24H 0xc98 +#define CSR_HPMCOUNTER25H 0xc99 +#define CSR_HPMCOUNTER26H 0xc9a +#define CSR_HPMCOUNTER27H 0xc9b +#define CSR_HPMCOUNTER28H 0xc9c +#define CSR_HPMCOUNTER29H 0xc9d +#define CSR_HPMCOUNTER30H 0xc9e +#define CSR_HPMCOUNTER31H 0xc9f +#define CSR_MSTATUSH 0x310 +#define CSR_MENVCFGH 0x31a +#define CSR_MSTATEEN0H 0x31c +#define CSR_MSTATEEN1H 0x31d +#define CSR_MSTATEEN2H 0x31e +#define CSR_MSTATEEN3H 0x31f +#define CSR_MHPMEVENT3H 0x723 +#define CSR_MHPMEVENT4H 0x724 +#define CSR_MHPMEVENT5H 0x725 +#define CSR_MHPMEVENT6H 0x726 +#define CSR_MHPMEVENT7H 0x727 +#define CSR_MHPMEVENT8H 0x728 +#define CSR_MHPMEVENT9H 0x729 +#define CSR_MHPMEVENT10H 0x72a +#define CSR_MHPMEVENT11H 0x72b +#define CSR_MHPMEVENT12H 0x72c +#define CSR_MHPMEVENT13H 0x72d +#define CSR_MHPMEVENT14H 0x72e +#define CSR_MHPMEVENT15H 0x72f +#define CSR_MHPMEVENT16H 0x730 +#define CSR_MHPMEVENT17H 0x731 +#define CSR_MHPMEVENT18H 0x732 +#define CSR_MHPMEVENT19H 0x733 +#define CSR_MHPMEVENT20H 0x734 +#define CSR_MHPMEVENT21H 0x735 +#define CSR_MHPMEVENT22H 0x736 +#define CSR_MHPMEVENT23H 0x737 +#define CSR_MHPMEVENT24H 0x738 +#define CSR_MHPMEVENT25H 0x739 +#define CSR_MHPMEVENT26H 0x73a +#define CSR_MHPMEVENT27H 0x73b +#define CSR_MHPMEVENT28H 0x73c +#define CSR_MHPMEVENT29H 0x73d +#define CSR_MHPMEVENT30H 0x73e +#define CSR_MHPMEVENT31H 0x73f +#define CSR_MSECCFGH 0x757 +#define CSR_MCYCLEH 0xb80 +#define CSR_MINSTRETH 0xb82 +#define CSR_MHPMCOUNTER3H 0xb83 +#define CSR_MHPMCOUNTER4H 0xb84 +#define CSR_MHPMCOUNTER5H 0xb85 +#define CSR_MHPMCOUNTER6H 0xb86 +#define CSR_MHPMCOUNTER7H 0xb87 +#define CSR_MHPMCOUNTER8H 0xb88 +#define CSR_MHPMCOUNTER9H 0xb89 +#define CSR_MHPMCOUNTER10H 0xb8a +#define CSR_MHPMCOUNTER11H 0xb8b +#define CSR_MHPMCOUNTER12H 0xb8c +#define CSR_MHPMCOUNTER13H 0xb8d +#define CSR_MHPMCOUNTER14H 0xb8e +#define CSR_MHPMCOUNTER15H 0xb8f +#define CSR_MHPMCOUNTER16H 0xb90 +#define CSR_MHPMCOUNTER17H 0xb91 +#define CSR_MHPMCOUNTER18H 0xb92 +#define CSR_MHPMCOUNTER19H 0xb93 +#define CSR_MHPMCOUNTER20H 0xb94 +#define CSR_MHPMCOUNTER21H 0xb95 +#define CSR_MHPMCOUNTER22H 0xb96 +#define CSR_MHPMCOUNTER23H 0xb97 +#define CSR_MHPMCOUNTER24H 0xb98 +#define CSR_MHPMCOUNTER25H 0xb99 +#define CSR_MHPMCOUNTER26H 0xb9a +#define CSR_MHPMCOUNTER27H 0xb9b +#define CSR_MHPMCOUNTER28H 0xb9c +#define CSR_MHPMCOUNTER29H 0xb9d +#define CSR_MHPMCOUNTER30H 0xb9e +#define CSR_MHPMCOUNTER31H 0xb9f + +/* === TEE CSR Registers === */ +#define CSR_SPMPCFG0 0x1A0 +#define CSR_SPMPCFG1 0x1A1 +#define CSR_SPMPCFG2 0x1A2 +#define CSR_SPMPCFG3 0x1A3 +#define CSR_SPMPADDR0 0x1B0 +#define CSR_SPMPADDR1 0x1B1 +#define CSR_SPMPADDR2 0x1B2 +#define CSR_SPMPADDR3 0x1B3 +#define CSR_SPMPADDR4 0x1B4 +#define CSR_SPMPADDR5 0x1B5 +#define CSR_SPMPADDR6 0x1B6 +#define CSR_SPMPADDR7 0x1B7 +#define CSR_SPMPADDR8 0x1B8 +#define CSR_SPMPADDR9 0x1B9 +#define CSR_SPMPADDR10 0x1BA +#define CSR_SPMPADDR11 0x1BB +#define CSR_SPMPADDR12 0x1BC +#define CSR_SPMPADDR13 0x1BD +#define CSR_SPMPADDR14 0x1BE +#define CSR_SPMPADDR15 0x1BF + +#define CSR_SMPUCFG0 0x1A0 +#define CSR_SMPUCFG1 0x1A1 +#define CSR_SMPUCFG2 0x1A2 +#define CSR_SMPUCFG3 0x1A3 +#define CSR_SMPUADDR0 0x1B0 +#define CSR_SMPUADDR1 0x1B1 +#define CSR_SMPUADDR2 0x1B2 +#define CSR_SMPUADDR3 0x1B3 +#define CSR_SMPUADDR4 0x1B4 +#define CSR_SMPUADDR5 0x1B5 +#define CSR_SMPUADDR6 0x1B6 +#define CSR_SMPUADDR7 0x1B7 +#define CSR_SMPUADDR8 0x1B8 +#define CSR_SMPUADDR9 0x1B9 +#define CSR_SMPUADDR10 0x1BA +#define CSR_SMPUADDR11 0x1BB +#define CSR_SMPUADDR12 0x1BC +#define CSR_SMPUADDR13 0x1BD +#define CSR_SMPUADDR14 0x1BE +#define CSR_SMPUADDR15 0x1BF + +#define CSR_SMPUSWITCH0 0x170 +#define CSR_SMPUSWITCH1 0x171 + +/* === CLIC CSR Registers === */ +#define CSR_MTVT 0x307 +#define CSR_MNXTI 0x345 +#define CSR_MINTSTATUS 0x346 +#define CSR_MSCRATCHCSW 0x348 +#define CSR_MSCRATCHCSWL 0x349 +#define CSR_MCLICBASE 0x350 + +/* === P-Extension Registers === */ +#define CSR_UCODE 0x801 + +/* === Nuclei custom CSR Registers === */ +//#define CSR_MCOUNTINHIBIT 0x320 +#define CSR_MILM_CTL 0x7C0 +#define CSR_MDLM_CTL 0x7C1 +#define CSR_MECC_CODE 0x7C2 +#define CSR_MNVEC 0x7C3 +#define CSR_MSUBM 0x7C4 +#define CSR_MDCAUSE 0x7C9 +#define CSR_MCACHE_CTL 0x7CA +#define CSR_MMISC_CTL 0x7D0 +#define CSR_MSAVESTATUS 0x7D6 +#define CSR_MSAVEEPC1 0x7D7 +#define CSR_MSAVECAUSE1 0x7D8 +#define CSR_MSAVEEPC2 0x7D9 +#define CSR_MSAVECAUSE2 0x7DA +#define CSR_MSAVEDCAUSE1 0x7DB +#define CSR_MSAVEDCAUSE2 0x7DC +#define CSR_MTLB_CTL 0x7DD +#define CSR_MECC_LOCK 0x7DE +#define CSR_MFP16MODE 0x7E2 +/* mfp16mode is renamed to mmisc_ctl1 */ +#define CSR_MMISC_CTL1 0x7E2 +#define CSR_LSTEPFORC 0x7E9 +#define CSR_PUSHMSUBM 0x7EB +#define CSR_MTVT2 0x7EC +#define CSR_JALMNXTI 0x7ED +#define CSR_PUSHMCAUSE 0x7EE +#define CSR_PUSHMEPC 0x7EF +#define CSR_MPPICFG_INFO 0x7F0 +#define CSR_MFIOCFG_INFO 0x7F1 + +/* === NCDEV === */ +#define CSR_MDEVB 0x7F3 +#define CSR_MDEVM 0x7F4 +#define CSR_MNOCB 0x7F5 +#define CSR_MNOCM 0x7F6 +#define CSR_MMACRO_DEV_EN 0xBC8 +#define CSR_MMACRO_NOC_EN 0xBC9 +#define CSR_MMACRO_CA_EN 0xBCA +#define CSR_MATTRI0_BASE 0x7F3 +#define CSR_MATTRI0_MASK 0x7F4 +#define CSR_MATTRI1_BASE 0x7F5 +#define CSR_MATTRI1_MASK 0x7F6 +#define CSR_MATTRI2_BASE 0x7F9 +#define CSR_MATTRI2_MASK 0x7FA +#define CSR_MATTRI3_BASE 0x7FB +#define CSR_MATTRI3_MASK 0x7FC +#define CSR_MATTRI4_BASE 0x7FD +#define CSR_MATTRI4_MASK 0x7FE +#define CSR_MATTRI5_BASE 0xBE0 +#define CSR_MATTRI5_MASK 0xBE1 +#define CSR_MATTRI6_BASE 0xBE2 +#define CSR_MATTRI6_MASK 0xBE3 +#define CSR_MATTRI7_BASE 0xBE4 +#define CSR_MATTRI7_MASK 0xBE5 +#define CSR_SATTRI0_BASE 0x5F0 +#define CSR_SATTRI0_MASK 0x5F1 +#define CSR_SATTRI1_BASE 0x5F2 +#define CSR_SATTRI1_MASK 0x5F3 +#define CSR_SATTRI2_BASE 0x5F4 +#define CSR_SATTRI2_MASK 0x5F5 +#define CSR_SATTRI3_BASE 0x5F6 +#define CSR_SATTRI3_MASK 0x5F7 +#define CSR_SATTRI4_BASE 0x5F8 +#define CSR_SATTRI4_MASK 0x5F9 +#define CSR_SATTRI5_BASE 0x5FA +#define CSR_SATTRI5_MASK 0x5FB +#define CSR_SATTRI6_BASE 0x5FC +#define CSR_SATTRI6_MASK 0x5FD +#define CSR_SATTRI7_BASE 0x5FE +#define CSR_SATTRI7_MASK 0x5FF + +/* === IREGION === */ +#define CSR_MSMPCFG_INFO 0x7F7 +#define CSR_MIRGB_INFO 0x7F7 + +#define CSR_SLEEPVALUE 0x811 +#define CSR_TXEVT 0x812 +#define CSR_WFE 0x810 +#define CSR_JALSNXTI 0x947 +#define CSR_STVT2 0x948 +#define CSR_PUSHSCAUSE 0x949 +#define CSR_PUSHSEPC 0x94A +#define CSR_SDCAUSE 0x9C0 +#define CSR_MICFG_INFO 0xFC0 +#define CSR_MDCFG_INFO 0xFC1 +#define CSR_MCFG_INFO 0xFC2 +#define CSR_MTLBCFG_INFO 0xFC3 + +/* === ECC === */ +#define CSR_MECC_CTL 0xBC0 +#define CSR_MECC_STATUS 0xBC4 + +/* === STL === */ +#define CSR_SAFETY_CRC_CTL 0x813 +#define CSR_SAFETY_STL_STATUS 0x814 + +/* === Stack protect === */ +#define CSR_MSTACK_CTRL 0x7C6 +#define CSR_MSTACK_BOUND 0x7C7 +#define CSR_MSTACK_BASE 0x7C8 + +/* === Nuclei CCM Registers === */ +#define CSR_CCM_MBEGINADDR 0x7CB +#define CSR_CCM_MCOMMAND 0x7CC +#define CSR_CCM_MDATA 0x7CD +#define CSR_CCM_SUEN 0x7CE +#define CSR_CCM_SBEGINADDR 0x5CB +#define CSR_CCM_SCOMMAND 0x5CC +#define CSR_CCM_SDATA 0x5CD +#define CSR_CCM_UBEGINADDR 0x4CB +#define CSR_CCM_UCOMMAND 0x4CC +#define CSR_CCM_UDATA 0x4CD +#define CSR_CCM_FPIPE 0x4CF + +/** @} */ /** End of Doxygen Group NMSIS_Core_CSR_Registers **/ + +/* Exception Code in MCAUSE CSR */ +#define CAUSE_MISALIGNED_FETCH 0x0 +#define CAUSE_FAULT_FETCH 0x1 +#define CAUSE_ILLEGAL_INSTRUCTION 0x2 +#define CAUSE_BREAKPOINT 0x3 +#define CAUSE_MISALIGNED_LOAD 0x4 +#define CAUSE_FAULT_LOAD 0x5 +#define CAUSE_MISALIGNED_STORE 0x6 +#define CAUSE_FAULT_STORE 0x7 +#define CAUSE_USER_ECALL 0x8 +#define CAUSE_SUPERVISOR_ECALL 0x9 +#define CAUSE_HYPERVISOR_ECALL 0xa +#define CAUSE_MACHINE_ECALL 0xb +#define CAUSE_FETCH_PAGE_FAULT 0xc +#define CAUSE_LOAD_PAGE_FAULT 0xd +#define CAUSE_STORE_PAGE_FAULT 0xf + +/* Delegatable Exception Code Mask in MCAUSE CSR*/ +#define MISALIGNED_FETCH (1 << CAUSE_MISALIGNED_FETCH) +#define FAULT_FETCH (1 << CAUSE_FAULT_FETCH) +#define ILLEGAL_INSTRUCTION (1 << CAUSE_ILLEGAL_INSTRUCTION) +#define BREAKPOINT (1 << CAUSE_BREAKPOINT) +#define MISALIGNED_LOAD (1 << CAUSE_MISALIGNED_LOAD) +#define FAULT_LOAD (1 << CAUSE_FAULT_LOAD) +#define MISALIGNED_STORE (1 << CAUSE_MISALIGNED_STORE) +#define FAULT_STORE (1 << CAUSE_FAULT_STORE) +#define USER_ECALL (1 << CAUSE_USER_ECALL) +#define FETCH_PAGE_FAULT (1 << CAUSE_FETCH_PAGE_FAULT) +#define LOAD_PAGE_FAULT (1 << CAUSE_LOAD_PAGE_FAULT) +#define STORE_PAGE_FAULT (1 << CAUSE_STORE_PAGE_FAULT) + +/* Exception Subcode in MDCAUSE CSR */ +#define DCAUSE_FAULT_FETCH_PMP 0x1 +#define DCAUSE_FAULT_FETCH_INST 0x2 + +#define DCAUSE_FAULT_LOAD_PMP 0x1 +#define DCAUSE_FAULT_LOAD_INST 0x2 +#define DCAUSE_FAULT_LOAD_NICE 0x3 + +#define DCAUSE_FAULT_STORE_PMP 0x1 +#define DCAUSE_FAULT_STORE_INST 0x2 + +/** @} */ /** End of Doxygen Group NMSIS_Core_CSR_Encoding **/ + +#ifdef __cplusplus +} +#endif +#endif /* __RISCV_ENCODING_H__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/component.mk b/pec930_sdk-v1.0.1/Drivers/PEC930/component.mk new file mode 100644 index 0000000..f1aa5e1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/component.mk @@ -0,0 +1,92 @@ +# +# component Makefile +# + + +#======================================= +# Configurations +#======================================= + +# +# Drivers of MCU +# + +SOC_CPU_NAME = n203e + +#======================================= +# system +#======================================= +ifeq ("$(SOC)","pec930") + C_DEFS += -DCONFIG_USE_PEC930 +else +$(error "Unknown SoC !!!") +endif + +# +# cpu +# +C_DEFS += -DCONFIG_CPU_N203E -DCONFIG_HAS_BPU + +CPU_FLAGS = -mabi=ilp32e -mcmodel=medlow +CPU_FLAGS += -march=rv32emc_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + + +# +# Source +# +ASM_SOURCES := \ + $(srctree)/Drivers/PEC930/Device/src/Startup/startup.S \ + $(srctree)/Drivers/PEC930/Device/src/Startup/trap.S + +C_SOURCES += \ + $(srctree)/Drivers/PEC930/Device/src/interrupt.c \ + $(srctree)/Drivers/PEC930/Device/src/syscalls.c \ + $(srctree)/Drivers/PEC930/Device/src/system_dev.c + +C_INCLUDES += \ + -I$(srctree)/Drivers/PEC930/Device/inc \ + -I$(srctree)/Drivers/PEC930/NMSIS/Core/Include \ + -I$(srctree)/Drivers/PEC930/ + + + +#======================================= +# peripheral hal driver +#======================================= +C_SOURCES += \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_adc.c \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_amisc.c \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_comp.c \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_opamp.c \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_crc.c \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_dsp.c \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_flash.c \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_gpio.c \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_i2c.c \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_lptim.c \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_pwr.c \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_spi.c \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_syscfg.c \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_tim.c \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_uart.c \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_wdg.c \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_device.c + +C_INCLUDES += \ + -I$(srctree)/Drivers/PEC930/HAL_Lib/inc + +#======================================= +# BSP +#======================================= +C_SOURCES += $(srctree)/Drivers/PEC930/BSP/StarterKit/starterkit.c + +C_INCLUDES += \ + -I$(srctree)/Drivers/PEC930/BSP/StarterKit + +#======================================= +# Flags +#======================================= +CFLAGS += $(CPU_FLAGS) +CXXFLAGS += +LDFLAGS += $(CPU_FLAGS) +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/gcc_flashxip.ld b/pec930_sdk-v1.0.1/Drivers/PEC930/gcc_flashxip.ld new file mode 100644 index 0000000..5641231 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/gcc_flashxip.ld @@ -0,0 +1,267 @@ +/****************************************************************************** + * @file gcc_flashxip.ld + * @brief GNU Linker Script for RISC-V device in FlashXIP Download Mode + * @date 10. March 2022 + ******************************************************************************/ + +/*********** Use Configuration Wizard in Context Menu *************************/ + +OUTPUT_ARCH( "riscv" ) + +/********************* Stack / neap Configuration **************************** + * Stack / Heap Configuration + * Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> + * Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> + * + */ +__STACK_SIZE = 0x00000200; +__HEAP_SIZE = 0x00000000; +/**************************** end of configuration section ********************/ + +ENTRY(_start) + +/* Define base address and length of flash and sram */ +MEMORY +{ + flash (rxa!w) : ORIGIN = 0x00000000, LENGTH = 0x8000 + sram (wxa!r) : ORIGIN = 0x20000000, LENGTH = 0x1000 + ovly (wxa!r) : ORIGIN = 0x20000C00, LENGTH = 0x400 +} + +REGION_ALIAS("ROM", flash) +REGION_ALIAS("RAM", sram) + +SECTIONS +{ + /* To provide symbol __STACK_SIZE, __HEAP_SIZE */ + PROVIDE(__STACK_SIZE = 512); + PROVIDE(__HEAP_SIZE = 256); + __TOT_STACK_SIZE = __STACK_SIZE; + + .init : + { + __exec_base_start = .; + /* vector table locate at ROM */ + *(.text.vtable) + KEEP (*(SORT_NONE(.text.init))) + . = ALIGN(4); + } >flash AT>flash + + . = ALIGN(4); + __fastcode_lma_start = .; + + .fastcode : ALIGN(4) + { + /* fast code, execute code at SRAM */ + __fastcode_vma_start = ALIGN(4); + PROVIDE( __fastcode_start = . ); + + *(.fastcode) + + __fastcode_vma_end = .; + PROVIDE( __fastcode_end = . ); + } >sram AT>flash + + /* Code section located at flash */ + .text : + { + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + . = ALIGN(8); + PROVIDE( __jvt_base$ = . ); + *(.text.tbljal .text.tbljal.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + /* readonly data placed in flash */ + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + *(.rdata) + *(.rodata .rodata.*) + *(.gnu.linkonce.r.*) + /* below sections are used for rt-thread */ + . = ALIGN(4); + __rt_init_start = .; + KEEP(*(SORT(.rti_fn*))) + __rt_init_end = .; + . = ALIGN(4); + __fsymtab_start = .; + KEEP(*(FSymTab)) + __fsymtab_end = .; + . = ALIGN(4); + __vsymtab_start = .; + KEEP(*(VSymTab)) + __vsymtab_end = .; + } >flash AT>flash + + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } >flash AT>flash + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >flash AT>flash + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } >flash AT>flash + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >flash AT>flash + + .ctors : + { + /* gcc uses crtbegin.o to find the start of + * the constructors, so we make sure it is + * first. Because this is a wildcard, it + * doesn't matter if the user does not + * actually link against crtbegin.o; the + * linker won't look for a file to match a + * wildcard. The wildcard also means that it + * doesn't matter which directory crtbegin.o + * is in. + */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + * the crtend.o file until after the sorted ctors. + * The .ctor section from the crtend file contains the + * end of ctors marker and it must be last + */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >flash AT>flash + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >flash AT>flash + + PROVIDE( _text_lma = LOADADDR(.text) ); + PROVIDE( _text = ADDR(.text) ); + PROVIDE (_etext = .); + PROVIDE (__etext = .); + PROVIDE (etext = .); + + .data : ALIGN(8) + { + KEEP(*(.data.ctest*)) + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.* .sdata*) + *(.gnu.linkonce.s.*) + /* Fix undefined symbol: __eh_frame_start/__eh_frame_hdr_start/__eh_frame_end/__eh_frame_hdr_end */ + PROVIDE_HIDDEN (__eh_frame_hdr_start = .); + *(.eh_frame_hdr) + PROVIDE_HIDDEN (__eh_frame_hdr_end = .); + PROVIDE_HIDDEN (__eh_frame_start = .); + *(.eh_frame) + PROVIDE_HIDDEN (__eh_frame_end = .); + . = ALIGN(8); + + /* table real-usage */ + . = ALIGN(256); + KEEP (*(.mintvec)) + . = ALIGN(64); + KEEP (*(.mexcptrap)) + } >sram AT>flash + + .tdata : ALIGN(8) + { + PROVIDE( __tls_base = . ); + *(.tdata .tdata.* .gnu.linkonce.td.*) + } >sram AT>flash + + PROVIDE( _data_lma = LOADADDR(.data) ); + PROVIDE( _data = ADDR(.data) ); + PROVIDE( _edata = . ); + PROVIDE( edata = . ); + + PROVIDE( _fbss = . ); + PROVIDE( __bss_start = . ); + + __end_lma__ = LOADADDR(.tdata); + + .tbss (NOLOAD) : ALIGN(8) + { + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon) + PROVIDE( __tls_end = . ); + } >sram AT>sram + + .tbss_space (NOLOAD) : ALIGN(8) + { + . = . + SIZEOF(.tbss); + } >sram AT>sram + + .bss (NOLOAD) : ALIGN(8) + { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + } >sram AT>sram + + . = ALIGN(4); + __ovly_vma_start = ORIGIN(ovly); + OVERLAY : NOCROSSREFS + { + .ovly1 { *(.ovly1.text .ovly1.data) } + .ovly2 { *(.ovly2.text .ovly2.data) } + } >ovly AT>flash + + PROVIDE( _end = . ); + PROVIDE( end = . ); + + /** + * 1. heap need to be align at 16 bytes + * 2. __heap_start and __heap_end symbol need to be defined + * 3. reserved at least __HEAP_SIZE space for heap + */ + .heap (NOLOAD) : ALIGN(16) + { + . = ALIGN(16); + PROVIDE( __heap_start = . ); + . += __HEAP_SIZE; + . = ALIGN(16); + PROVIDE( __heap_limit = . ); + } >sram AT>sram + + .stack ORIGIN(sram) + LENGTH(sram) - __TOT_STACK_SIZE (NOLOAD) : + { + . = ALIGN(16); + PROVIDE( _heap_end = . ); + PROVIDE( __heap_end = . ); + PROVIDE( __StackLimit = . ); + PROVIDE( __StackBottom = . ); + . += __TOT_STACK_SIZE; + . = ALIGN(16); + PROVIDE( __StackTop = . ); + PROVIDE( _sp = . ); + } >sram AT>sram +} diff --git a/pec930_sdk-v1.0.1/Drivers/drivers.mk b/pec930_sdk-v1.0.1/Drivers/drivers.mk new file mode 100644 index 0000000..54e9be7 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/drivers.mk @@ -0,0 +1,22 @@ +# +# component Makefile +# + +ifeq (,$(filter $(MAKECMDGOALS),clean help)) + +ifeq ("$(SOC_DRIVER)","") +$(error "Unknown SoC !!!") +else + include $(srctree)/Drivers/$(SOC_DRIVER)/component.mk +endif + +C_INCLUDES += + + +endif # ifeq (,$(filter $(MAKECMDGOALS),clean help)) + + +CFLAGS += +CXXFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/.cproject b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/.project b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/Project.nuproject b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/component.mk b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/component.mk new file mode 100644 index 0000000..fde693b --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += -DCONFIG_HAS_SYSLOG_FLOAT +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/inc/isr.h b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/inc/main.h b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/readme.md b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/readme.md new file mode 100644 index 0000000..a8e8ab7 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/readme.md @@ -0,0 +1,374 @@ +adc_conv_mode +--- + +This is an example of ADC conversion mode. + ++ This ADC supports 4 modes + > + Single conversion mode + > + Continuous mode + > + Scan mode + > + Discontinuous mode + ++ The target ADC channels + + ``` + // in main.c + #define CONFIG_TARGET_1_ADC_CHANNEL ADC_Channel_03 + #define CONFIG_TARGET_ADC_MULTI_CHANNELS (ADC_Channel_02 | ADC_Channel_03 | ADC_Channel_09) + ``` + ++ User pull low of the specific key to trigger ADC work + + ``` + // in main.c + #define CONFIG_GPIO_INPUT_PORTx GPIOA + #define CONFIG_GPIO_INPUT_PINx GPIO_Pin_02 + ``` + +## Single conversion mode + +Software trigger ADC to sample a channel once +> The target ADC channel is defined at `CONFIG_TARGET_1_ADC_CHANNEL` + ++ Configure to single conversion mode + + ``` + // in main.c + #define CONFIG_TARGET_ADC_MODE_SIGNAL 1 + #define CONFIG_TARGET_ADC_MODE_CONTINOUS 0 + #define CONFIG_TARGET_ADC_MODE_SCAN 0 + #define CONFIG_TARGET_ADC_MODE_DISCONTINOUS 0 + ``` + ++ Operation flow + + - Step 1. Connect the AIN-Channel (`CONFIG_TARGET_1_ADC_CHANNEL`) with an external device (e.g. power support) which provide difference voltage + - Step 2. Set a specific voltage to external device (e.g. power support) + - Step 3. Press button to trigger ADC start + - Step 4. Get the ADC conversion value from log message + - Step 5. Calculate the measured voltage + + ``` + the measured voltage = ADC_Value * ((AVDD - AVSS) / 4095) + ``` + + - Step 6. repeat `Step 2 ~ Step 5` + +## Continuous mode + +In this mode, ADC will always sequentially sample the specific channels after a trigger-event + ++ Configure to continuous mode + + ``` + // in main.c + #define CONFIG_TARGET_ADC_MODE_SIGNAL 0 + #define CONFIG_TARGET_ADC_MODE_CONTINOUS 1 + #define CONFIG_TARGET_ADC_MODE_SCAN 0 + #define CONFIG_TARGET_ADC_MODE_DISCONTINOUS 0 + ``` + ++ Operation flow + + - Step 1. Connect the AIN-Channel (`CONFIG_TARGET_1_ADC_CHANNEL`) with an external device (e.g. power support) which provide difference voltage + - Step 2. Set a specific voltage to the external device (e.g. power support) + - Step 3. Press button to trigger ADC start + - Step 4. Run-time change voltage from the external device (e.g. power support) + - Step 5. Get the ADC conversion value from log message + > It will auto-log `CONFIG_REPEAT_TIMES` times with a trigger-event + > ``` + > // at main.c + > #define CONFIG_REPEAT_TIMES 10 + > ``` + +## Scan mode + +In Scan mode, ACD will sequentially sample the specific channels **once** after a trigger-event + ++ Configure to Scan mode + + ``` + // in main.c + #define CONFIG_TARGET_ADC_MODE_SIGNAL 0 + #define CONFIG_TARGET_ADC_MODE_CONTINOUS 0 + #define CONFIG_TARGET_ADC_MODE_SCAN 1 + #define CONFIG_TARGET_ADC_MODE_DISCONTINOUS 0 + ``` + ++ Operation flow + + - Step 1. Connect the AIN-Channels (`CONFIG_TARGET_ADC_MULTI_CHANNELS`) with an external device (e.g. power support) which provide difference voltages + - Step 2. Set specific voltages to the external device (e.g. power support) with multi-channels + - Step 3. Press button to trigger ADC start + - Step 4. Run-time change voltages of multi-channels of the external device (e.g. power support) + - Step 5. Get the ADC conversion values from log message + > It will auto-trigger the sample-event `CONFIG_REPEAT_TIMES` times + > ``` + > // at main.c + > #define CONFIG_REPEAT_TIMES 10 + > ``` + +## Discontinuous mode + +It will group the selected AIN-Channels and sequentially trigger a sub-group of the selected AIN-Channels with a trigger-event +> An example as below +> ``` +> Selected AIN 4,5,7,9 +> Sub-Group 1: AIN 4, 5, 7 +> Sub-Group 2: AIN 9 +> the 1st trigger-evern => Execute Sub-Group 1 +> the 2nd trigger-evern => Execute Sub-Group 2 +> ``` + + ++ Configure to Discontinuous mode + + ``` + // in main.c + #define CONFIG_TARGET_ADC_MODE_SIGNAL 0 + #define CONFIG_TARGET_ADC_MODE_CONTINOUS 0 + #define CONFIG_TARGET_ADC_MODE_SCAN 0 + #define CONFIG_TARGET_ADC_MODE_DISCONTINOUS 1 + ``` + ++ Operation flow + + - Step 1. Connect the AIN-Channels (`CONFIG_TARGET_ADC_MULTI_CHANNELS`) with an external device (e.g. power support) which provide difference voltages + - Step 2. Set specific voltages to the external device (e.g. power support) with multi-channels + - Step 3. Press button to trigger ADC start + - Step 4. Run-time change voltages of multi-channels of the external device (e.g. power support) + - Step 5. Get the ADC conversion values from log message + + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + ++ Single conversion mode + + ``` + Oct 2 2025 16:19:41 + ADC run Single conversion mode + Button = PA2 + wait key event (voltage level low)... + ADC Single Conversion + Trigger ADC + ch-03 ADC Value: 3395, voltage: 2.735898 + + ... + ``` + ++ Continuous mode + + ``` + Oct 2 2025 15:02:37 + ADC run Continuous conversion mode + Button = PA2 + wait key event (voltage level low)... + ADC Continuous mode + + Trigger ADC <--- trigger ADC + => Change External Voltage + ch-09 ADC Value: 2327, voltage: 1.875238 + ch-03 ADC Value: 3274, voltage: 2.638388 + ch-02 ADC Value: 1342, voltage: 1.081465 + => Change External Voltage + ch-09 ADC Value: 2331, voltage: 1.878461 + ch-03 ADC Value: 3276, voltage: 2.640000 + ch-02 ADC Value: 1349, voltage: 1.087106 + => Change External Voltage + ch-09 ADC Value: 2341, voltage: 1.886520 + ch-03 ADC Value: 3152, voltage: 2.540073 <--- change AIN3 voltage + ch-02 ADC Value: 1352, voltage: 1.089524 + => Change External Voltage + ch-09 ADC Value: 2336, voltage: 1.882491 + ch-03 ADC Value: 3159, voltage: 2.545714 + ch-02 ADC Value: 1351, voltage: 1.088718 + => Change External Voltage + ch-09 ADC Value: 2333, voltage: 1.880073 + ch-03 ADC Value: 3028, voltage: 2.440146 + ch-02 ADC Value: 1341, voltage: 1.080659 + => Change External Voltage + ch-09 ADC Value: 2336, voltage: 1.882491 + ch-03 ADC Value: 2906, voltage: 2.341831 <--- change AIN3 voltage + ch-02 ADC Value: 1343, voltage: 1.082271 + => Change External Voltage + ch-09 ADC Value: 2345, voltage: 1.889744 + ch-03 ADC Value: 2902, voltage: 2.338608 + ch-02 ADC Value: 1347, voltage: 1.085495 + => Change External Voltage + ch-09 ADC Value: 2332, voltage: 1.879267 + ch-03 ADC Value: 2904, voltage: 2.340220 + ch-02 ADC Value: 1717, voltage: 1.383663 <--- change AIN2 voltage + => Change External Voltage + ch-09 ADC Value: 2338, voltage: 1.884103 + ch-03 ADC Value: 2902, voltage: 2.338608 + ch-02 ADC Value: 2090, voltage: 1.684249 + => Change External Voltage + ch-09 ADC Value: 2340, voltage: 1.885714 + ch-03 ADC Value: 2910, voltage: 2.345055 + ch-02 ADC Value: 2575, voltage: 2.075092 <--- change AIN2 voltage + => Change External Voltage + ch-09 ADC Value: 2328, voltage: 1.876044 + ch-03 ADC Value: 2905, voltage: 2.341026 + ch-02 ADC Value: 2585, voltage: 2.083150 + => Change External Voltage + ch-09 ADC Value: 2082, voltage: 1.677802 <--- change AIN9 voltage + ch-03 ADC Value: 2907, voltage: 2.342637 + ch-02 ADC Value: 2582, voltage: 2.080733 + => Change External Voltage + ch-09 ADC Value: 1956, voltage: 1.576264 + ch-03 ADC Value: 2905, voltage: 2.341026 + ch-02 ADC Value: 2582, voltage: 2.080733 + => Change External Voltage + ch-09 ADC Value: 2457, voltage: 1.980000 + ch-03 ADC Value: 2905, voltage: 2.341026 + ch-02 ADC Value: 2583, voltage: 2.081538 + => Change External Voltage + ch-09 ADC Value: 2833, voltage: 2.283004 <--- change AIN9 voltage + ch-03 ADC Value: 2904, voltage: 2.340220 + ch-02 ADC Value: 2589, voltage: 2.086374 + ... + ``` + ++ Scan mode + + ``` + Oct 2 2025 15:44:15 + ADC run Scan conversion mode + Button = PA2 + wait key event (voltage level low)... + ADC Scan mode + + => Change External Voltage + Trigger ADC <--- trigger ADC + ch-09 ADC Value: 2215, voltage: 1.784982 + ch-03 ADC Value: 2902, voltage: 2.338608 + ch-02 ADC Value: 2581, voltage: 2.079927 + => Change External Voltage + Trigger ADC + ch-09 ADC Value: 2214, voltage: 1.784176 + ch-03 ADC Value: 2903, voltage: 2.339414 + ch-02 ADC Value: 2578, voltage: 2.077509 + => Change External Voltage + Trigger ADC + ch-09 ADC Value: 2081, voltage: 1.676996 + ch-03 ADC Value: 2902, voltage: 2.338608 + ch-02 ADC Value: 2587, voltage: 2.084762 + => Change External Voltage + Trigger ADC <--- trigger ADC + ch-09 ADC Value: 1961, voltage: 1.580293 <--- change AIN9 voltage + ch-03 ADC Value: 2906, voltage: 2.341831 + ch-02 ADC Value: 2581, voltage: 2.079927 + => Change External Voltage + Trigger ADC + ch-09 ADC Value: 1843, voltage: 1.485201 + ch-03 ADC Value: 2907, voltage: 2.342637 + ch-02 ADC Value: 2573, voltage: 2.073480 + => Change External Voltage + Trigger ADC <--- trigger ADC + ch-09 ADC Value: 1843, voltage: 1.485201 <--- change AIN9 voltage + ch-03 ADC Value: 2901, voltage: 2.337802 + ch-02 ADC Value: 2586, voltage: 2.083956 + => Change External Voltage + Trigger ADC <--- trigger ADC + ch-09 ADC Value: 1848, voltage: 1.489231 + ch-03 ADC Value: 2901, voltage: 2.337802 + ch-02 ADC Value: 2830, voltage: 2.280586 <--- change AIN2 voltage + => Change External Voltage + Trigger ADC + ch-09 ADC Value: 1852, voltage: 1.492454 + ch-03 ADC Value: 2906, voltage: 2.341831 + ch-02 ADC Value: 2697, voltage: 2.173407 + => Change External Voltage + Trigger ADC <--- trigger ADC + ch-09 ADC Value: 1847, voltage: 1.488425 + ch-03 ADC Value: 2902, voltage: 2.338608 + ch-02 ADC Value: 2453, voltage: 1.976776 <--- change AIN2 voltage + => Change External Voltage + Trigger ADC <--- trigger ADC + ch-09 ADC Value: 1846, voltage: 1.487619 + ch-03 ADC Value: 2903, voltage: 2.339414 + ch-02 ADC Value: 2344, voltage: 1.888938 <--- change AIN2 voltage + => Change External Voltage + Trigger ADC <--- trigger ADC + ch-09 ADC Value: 1851, voltage: 1.491648 + ch-03 ADC Value: 2905, voltage: 2.341026 + ch-02 ADC Value: 2459, voltage: 1.981612 <--- change AIN2 voltage + => Change External Voltage + Trigger ADC + ch-09 ADC Value: 1854, voltage: 1.494066 + ch-03 ADC Value: 2893, voltage: 2.331355 + ch-02 ADC Value: 2466, voltage: 1.987253 + => Change External Voltage + Trigger ADC <--- trigger ADC + ch-09 ADC Value: 1848, voltage: 1.489231 + ch-03 ADC Value: 3148, voltage: 2.536850 <--- change AIN3 voltage + ch-02 ADC Value: 2464, voltage: 1.985641 + => Change External Voltage + Trigger ADC + ch-09 ADC Value: 1849, voltage: 1.490037 + ch-03 ADC Value: 2782, voltage: 2.241905 + ch-02 ADC Value: 2460, voltage: 1.982418 + => Change External Voltage + Trigger ADC <--- trigger ADC + ch-09 ADC Value: 1850, voltage: 1.490842 + ch-03 ADC Value: 2413, voltage: 1.944542 <--- change AIN3 voltage + ch-02 ADC Value: 2458, voltage: 1.980806 + => Change External Voltage + Trigger ADC + ch-09 ADC Value: 1848, voltage: 1.489231 + ch-03 ADC Value: 2412, voltage: 1.943736 + ch-02 ADC Value: 2458, voltage: 1.980806 + => Change External Voltage + Trigger ADC <--- trigger ADC + ch-09 ADC Value: 1850, voltage: 1.490842 + ch-03 ADC Value: 2679, voltage: 2.158901 <--- change AIN3 voltage + ch-02 ADC Value: 2466, voltage: 1.987253 + => Change External Voltage + Trigger ADC + ch-09 ADC Value: 1850, voltage: 1.490842 + ch-03 ADC Value: 3023, voltage: 2.436117 + ch-02 ADC Value: 2460, voltage: 1.982418 + => Change External Voltage + Trigger ADC <--- trigger ADC + ch-09 ADC Value: 1854, voltage: 1.494066 + ch-03 ADC Value: 3397, voltage: 2.737509 <--- change AIN3 voltage + ch-02 ADC Value: 2464, voltage: 1.985641 + + ... + ``` + ++ Discontinuous mode + > Sub-Group 1: AIN 2
+ > Sub-Group 2: AIN 3
+ > Sub-Group 3: AIN 9
+ + ``` + Oct 2 2025 16:13:42 + ADC run Discontinuous conversion mode + Button = PA2 + wait key event (voltage level low)... + ADC Discontinuous mode + => Change External Voltage + + ## trigger 00-th + Trigger ADC <--- trigger ADC Sub-Group 1 (AIN 2) + ch-09 ADC Value: 0, voltage: 0.000000 + ch-03 ADC Value: 0, voltage: 0.000000 + ch-02 ADC Value: 2453, voltage: 1.976776 + + ## trigger 01-th + Trigger ADC <--- trigger ADC Sub-Group 2 (AIN 3) + ch-09 ADC Value: 0, voltage: 0.000000 + ch-03 ADC Value: 3399, voltage: 2.739121 + ch-02 ADC Value: 2453, voltage: 1.976776 + + ## trigger 02-th + Trigger ADC <--- trigger ADC Sub-Group 3 (AIN 9) + ch-09 ADC Value: 1843, voltage: 1.485201 + ch-03 ADC Value: 3399, voltage: 2.739121 + ch-02 ADC Value: 2453, voltage: 1.976776 + + ... + ``` diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/src/isr.c b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/src/main.c b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/src/main.c new file mode 100644 index 0000000..731c5a4 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/src/main.c @@ -0,0 +1,356 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_TARGET_ADC_MODE_SIGNAL 0 +#define CONFIG_TARGET_ADC_MODE_CONTINOUS 1 +#define CONFIG_TARGET_ADC_MODE_SCAN 0 +#define CONFIG_TARGET_ADC_MODE_DISCONTINOUS 0 + +#define CONFIG_REPEAT_TIMES 10 + +/* Input Key I/O definitions */ +#define CONFIG_GPIO_INPUT_PORTx GPIOA +#define CONFIG_GPIO_INPUT_PINx GPIO_Pin_02 +#define CONFIG_GPIO_IRQ GPIOA_IRQn // GPIOB_IRQn + +#define CONFIG_TARGET_1_ADC_CHANNEL ADC_Channel_03 // ADC_Channel_AVSS +#define CONFIG_TARGET_ADC_MULTI_CHANNELS (ADC_Channel_02 | ADC_Channel_03 | ADC_Channel_09) // (ADC_Channel_AVSS | ADC_Channel_AMISC) +#define CONFIG_TARGET_ADC_SUB_CHANNEL ADC_SubChannel_VBuf_1_5 +//============================================================================= +// Macro Definition +//============================================================================= +#define _ADC_Convert_Voltage(__ADC_12b_value__) \ + ((__ADC_12b_value__) * 3.3f / 4095.0f) +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static bool g_hasPullLow = false; +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void GPIOx_Handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); + + if( GPIO_GetITFlag(CONFIG_GPIO_INPUT_PORTx, CONFIG_GPIO_INPUT_PINx) ) + { + GPIO_ClearITFlag(CONFIG_GPIO_INPUT_PORTx, CONFIG_GPIO_INPUT_PINx); + + g_hasPullLow = true; + } + + RESTORE_IRQ_CSR_CONTEXT(); + return; +} + +__INTERRUPT void ADC0_Handler(void) +{ + return; +} + +__USED static int +_ADC_Conv_Single(ADC_ChannelsTypeDef channel) +{ + int rval = 0; + uint16_t value = 0; + ADC_InitTypeDef init = {0}; + int index = 31ul - HAL_CLZ(channel); + + log_color(SLOG_CYAN, "ADC Single Conversion\n"); + + /* Configure ADC */ + ADC_StructInit(&init); + + init.SelChannels = channel; + init.IsSoftTrig = true; + ADC_Init(ADC0, &init); + + /* Start ADC conversion */ + msg("Trigger ADC\n"); + ADC_Start(ADC0); + + /* Wait ADC idle */ + while( ADC_IsIdle(ADC0) == 0 ); + + /* Get ADC conversion value */ + value = ADC_GetChannelConvValue(ADC0, channel); + msg(" ch-%02d ADC Value: %d, voltage: %f\n", + index, value, _ADC_Convert_Voltage(value)); + + ADC_DeInit(ADC0); + return rval; +} + +__USED static int +_ADC_Conv_Continuous(ADC_ChannelsTypeDef channels) +{ + int rval = 0; + uint16_t value = 0; + ADC_InitTypeDef init = {0}; + + log_color(SLOG_CYAN, "ADC Continuous mode\n"); + + /* Configure ADC */ + ADC_StructInit(&init); + + init.SelChannels = channels; + init.Mode = ADC_Mode_Continuous; + init.IsSoftTrig = true; + ADC_Init(ADC0, &init); + + /* Start ADC conversion once */ + msg("Trigger ADC \n"); + ADC_Start(ADC0); + sys_delay(3); + + for(int i = 0; i < CONFIG_REPEAT_TIMES; i++) + { + uint32_t chnnls_set = 0; + + /** + * User modify the AIN channel voltage + */ + log_color(SLOG_GREEN, "=> Change External Voltage\n"); + sys_delay(1000); + + chnnls_set = (uint32_t)channels; + + while( chnnls_set ) + { + int index = 31ul - HAL_CLZ(chnnls_set); + + chnnls_set &= ~(0x1ul << index); + + /* Get ADC conversion value */ + value = ADC_GetChannelConvValue(ADC0, 0x1ul << index); + msg(" ch-%02d ADC Value: %d, voltage: %f\n", + index, value, _ADC_Convert_Voltage(value)); + } + + } + + ADC_DeInit(ADC0); + return rval; +} + +__USED static int +_ADC_Conv_Scan(ADC_ChannelsTypeDef channels) +{ + int rval = 0; + uint32_t chnnls_set = 0; + ADC_InitTypeDef init = {0}; + + log_color(SLOG_CYAN, "ADC Scan mode\n"); + + /* Configure ADC */ + ADC_StructInit(&init); + + init.SelChannels = channels; + init.Mode = ADC_Mode_Scan; + init.IsSoftTrig = true; + ADC_Init(ADC0, &init); + + for(int i = 0; i < CONFIG_REPEAT_TIMES; i++) + { + /** + * User modify the AIN channel voltage + */ + log_color(SLOG_GREEN, "=> Change External Voltage\n"); + sys_delay(1000); + + /* Start ADC conversion every time */ + msg("Trigger ADC \n"); + ADC_Start(ADC0); + + + /* Wait ADC idle */ + while( ADC_IsIdle(ADC0) == 0 ); + + chnnls_set = (uint32_t)channels; + + while( chnnls_set ) + { + uint16_t value = 0; + int index = 31ul - HAL_CLZ(chnnls_set); + + chnnls_set &= ~(0x1ul << index); + + /* Get ADC conversion value */ + value = ADC_ITGetConvValue(ADC0, 0x1ul << index); + msg(" ch-%02d ADC Value: %d, voltage: %f\n", + index, value, _ADC_Convert_Voltage(value)); + } + } + + ADC_DeInit(ADC0); + return rval; +} + +__USED static int +_ADC_Conv_Discontinuous(ADC_ChannelsTypeDef channels) +{ + int rval = 0; + int chnnl_num = 0; + uint32_t chnnls_set = 0; + int subset_ch_cnt = 1; + int trigger_cnt = 0; + ADC_InitTypeDef init = {0}; + + log_color(SLOG_CYAN, "ADC Discontinuous mode\n"); + + chnnl_num = HAL_PopCount((uint32_t)channels); + + /* Configure ADC */ + ADC_StructInit(&init); + + init.SelChannels = channels; + init.Mode = ADC_Mode_Discontinuous; + init.IsSoftTrig = true; + ADC_Init(ADC0, &init); + + /* Set the subset channel number */ + ADC_DiscMode_SetGroupSubsetNum(ADC0, subset_ch_cnt); + + trigger_cnt = (chnnl_num + (subset_ch_cnt - 1)) / subset_ch_cnt; + + for(int i = 0; i < CONFIG_REPEAT_TIMES; i++) + { + /** + * User modify the AIN channel voltage + */ + log_color(SLOG_GREEN, "=> Change External Voltage\n"); + sys_delay(1000); + + for(int j = 0; j < trigger_cnt; j++) + { + msg("\n ## trigger %02d-th\n", j); + + /* Start ADC conversion */ + msg(" Trigger ADC \n"); + ADC_Start(ADC0); + + /* Wait ADC idle */ + while( ADC_IsIdle(ADC0) == 0 ); + + chnnls_set = (uint32_t)channels; + + while( chnnls_set ) + { + uint16_t value = 0; + int index = 31ul - HAL_CLZ(chnnls_set); + + chnnls_set &= ~(0x1ul << index); + + /* Get ADC conversion value */ + value = ADC_ITGetConvValue(ADC0, 0x1ul << index); + msg(" ch-%02d ADC Value: %d, voltage: %f\n", + index, value, _ADC_Convert_Voltage(value)); + } + } + } + + ADC_DeInit(ADC0); + return rval; +} +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + int rval = 0; + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s %s\nADC run %s conversion mode\n", __DATE__, __TIME__, + #if (CONFIG_TARGET_ADC_MODE_CONTINOUS) + "Continuous" + #elif (CONFIG_TARGET_ADC_MODE_SCAN) + "Scan" + #elif (CONFIG_TARGET_ADC_MODE_DISCONTINOUS) + "Discontinuous" + #else + "Single" + #endif + ); + + msg(" Button = P%s%d\n", + (CONFIG_GPIO_INPUT_PORTx == GPIOA) ? "A" : "B", + 31ul - HAL_CLZ(CONFIG_GPIO_INPUT_PINx)); + + do { + GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.GPIO_Pin = CONFIG_GPIO_INPUT_PINx; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN ; + GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_InitStruct.GPIO_ITInit.GPIO_Trigger = GPIO_Trigger_Level; + GPIO_InitStruct.GPIO_ITInit.GPIO_Polarity = GPIO_Polarity_Low_Fall; + GPIO_Init(CONFIG_GPIO_INPUT_PORTx , &GPIO_InitStruct); + + GPIO_ITEnable(CONFIG_GPIO_INPUT_PORTx, CONFIG_GPIO_INPUT_PINx); + } while(0); + + sys_register_IRQ(CONFIG_GPIO_IRQ, GPIOx_Handler, &irq_attr); + sys_register_IRQ(ADC0_IRQn, ADC0_Handler, &irq_attr); + + msg("wait key event (voltage level low)...\n"); + + while(1) + { + if( g_hasPullLow == true ) + { + g_hasPullLow = false; + + #if (CONFIG_TARGET_ADC_MODE_CONTINOUS) + rval = _ADC_Conv_Continuous(CONFIG_TARGET_ADC_MULTI_CHANNELS); + if( rval ) break; + + #elif (CONFIG_TARGET_ADC_MODE_SCAN) + rval = _ADC_Conv_Scan(CONFIG_TARGET_ADC_MULTI_CHANNELS); + if( rval ) break; + + #elif (CONFIG_TARGET_ADC_MODE_DISCONTINOUS) + rval = _ADC_Conv_Discontinuous(CONFIG_TARGET_ADC_MULTI_CHANNELS); + if( rval ) break; + + #else + rval = _ADC_Conv_Single(CONFIG_TARGET_1_ADC_CHANNEL); + if( rval ) break; + #endif + + msg("wait key event (voltage level low)...\n"); + } + + sys_delay(500); + } + + if( rval ) err("Fail ! (err_code= %d)\n"); + + while(1); + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/.cproject b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/.project b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/Project.nuproject b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/component.mk b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/inc/isr.h b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/inc/main.h b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/readme.md b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/readme.md new file mode 100644 index 0000000..b69ffcd --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/readme.md @@ -0,0 +1,78 @@ +adc_single_conv_interrupt +--- + +This example is a single channel conversion of ADC with interrupt + ++ Configure the target ADC channel (AINx) + + ``` + // in main.c + #if 1 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_08 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_02 + #elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_09 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_03 + #elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_10 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_04 + #elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_11 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_05 + #elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_12 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_06 + #elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_13 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_07 + #elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_06 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_08 + #elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_07 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_09 + #elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_14 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_10 + #elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_15 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_11 + #elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOB + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_00 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_12 + #elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOB + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_01 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_13 + #elif 0 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_14 + #else + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_15 + #endif + ``` + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + +``` +Sep 30 2025 10:02:19 +ADC single channel (AIN-2) conversion with interrupt + 1-th ADC Single Conv Value = 0x920 (2336) + 2-th ADC Single Conv Value = 0x9F7 (2551) + 3-th ADC Single Conv Value = 0xB49 (2889) + 4-th ADC Single Conv Value = 0xB2F (2863) + 5-th ADC Single Conv Value = 0xB62 (2914) + ... +``` \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/src/isr.c b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/src/main.c b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/src/main.c new file mode 100644 index 0000000..a7a3a7c --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/src/main.c @@ -0,0 +1,240 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= + +#define CONFIG_USE_ADC_INTERRUPT 1 + +#if 1 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_08 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_02 +#elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_09 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_03 +#elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_10 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_04 +#elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_11 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_05 +#elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_12 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_06 +#elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_13 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_07 +#elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_06 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_08 +#elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_07 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_09 +#elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_14 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_10 +#elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_15 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_11 +#elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOB + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_00 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_12 +#elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOB + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_01 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_13 +#elif 0 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_14 +#else + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_15 +#endif + + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static uint16_t g_ConvValue = 0; +static bool g_IsDone = false; +static ADC_SubChannelTypeDef g_a15_sub_chnnl = ADC_SubChannel_NONE; + +static ADC_SubChannelTypeDef g_sub_channels[] = +{ + ADC_SubChannel_TEMP, + ADC_SubChannel_DAC0, + ADC_SubChannel_DAC1, + ADC_SubChannel_VBuf_1_5, + ADC_SubChannel_VDDL, + ADC_SubChannel_VSS, + ADC_SubChannel_VDD, +}; +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void ADC0_Handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); + + g_ConvValue = ADC_ITGetConvValue(ADC0, CONFIG_TARGGET_ADC_CHANNEL); + + g_IsDone = true; + + RESTORE_IRQ_CSR_CONTEXT(); + return; +} + +#if defined(CONFIG_ADC_IO_SRC_PORT) && defined(CONFIG_ADC_IO_SRC_PIN) +static void _Config_AIN_IO(void) +{ + GPIO_InitTypeDef gpio_init = {0}; + + if( CONFIG_TARGGET_ADC_CHANNEL == ADC_Channel_13 ) + { + SYSCFG_SetRstPin2NormalIO(true); + } + + gpio_init.GPIO_Pin = CONFIG_ADC_IO_SRC_PIN; + gpio_init.GPIO_Mode = GPIO_Mode_ANAL; + GPIO_Init(CONFIG_ADC_IO_SRC_PORT, &gpio_init); + return; +} +#else + #define _Config_AIN_IO() +#endif /* CONFIG_ADC_IO_SRC_PORT */ +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + { /* Configure system clock */ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + #if 1 + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + #else + SysClkInit.ClkSource = SYSCFG_ClkSrc_FreqDiv; + SysClkInit.SysClk_Div = SYSCFG_SysClkDiv4; + #endif + SYSCFG_SysClkConfig(&SysClkInit); + } + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s %s\nADC single channel (AIN-%d) conversion with interrupt\n", + __DATE__, __TIME__, (31ul - HAL_CLZ(CONFIG_TARGGET_ADC_CHANNEL))); + + _Config_AIN_IO(); + + { /* Configure ADC */ + ADC_InitTypeDef init = {0}; + + ADC_StructInit(&init); + + if( init.SelChannels == ADC_Channel_15 ) + { + ADC_SelSubChannel(g_a15_sub_chnnl); + + init.ClkPrescaler = ADC_ClkDiv_32; + } + + init.SelChannels = CONFIG_TARGGET_ADC_CHANNEL; + init.IsSoftTrig = true; + ADC_Init(ADC0, &init); + + if( init.SelChannels == ADC_Channel_15 ) + { + ADC_SetSampleCycles(ADC0, 0x1F); + } + + #if defined(CONFIG_USE_ADC_INTERRUPT) && (CONFIG_USE_ADC_INTERRUPT) + { + sys_irq_attr_t irq_attr = { .disable_vector = false, }; + + irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL; + irq_attr.level = SYS_IRQ_LEVEL_L; + irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN; + sys_register_IRQ(ADC0_IRQn, ADC0_Handler, &irq_attr); + ADC_ITConfig(ADC0, ADC_IT_CONV_DONE); + } + #endif + } + + g_IsDone = false; + ADC_Start(ADC0); + + sys_delay(100); + + while(1) + { + static int cnt = 0; + + #if defined(CONFIG_USE_ADC_INTERRUPT) && (CONFIG_USE_ADC_INTERRUPT) + if( g_IsDone == false ) + continue; + + g_IsDone = false; + #else /* CONFIG_USE_ADC_INTERRUPT */ + g_ConvValue = ADC_GetChannelConvValue(ADC0, CONFIG_TARGGET_ADC_CHANNEL); + #endif /* CONFIG_USE_ADC_INTERRUPT */ + + cnt++; + + msg(" %d-th ADC Single Conv Value(12-bits) = 0x%02X (%d)\n", + cnt, g_ConvValue, g_ConvValue); + + if( CONFIG_TARGGET_ADC_CHANNEL == ADC_Channel_15 ) + { + log_color(SLOG_GREEN, "\n\nSet internal signal: %s\n", + (g_a15_sub_chnnl == ADC_SubChannel_TEMP ) ? "Temperature" : + (g_a15_sub_chnnl == ADC_SubChannel_DAC0 ) ? "DAC 0" : + (g_a15_sub_chnnl == ADC_SubChannel_DAC1 ) ? "DAC 1" : + (g_a15_sub_chnnl == ADC_SubChannel_VBuf_1_5 ) ? "V1.5" : + (g_a15_sub_chnnl == ADC_SubChannel_VDDL ) ? "VDDL" : + (g_a15_sub_chnnl == ADC_SubChannel_VSS ) ? "VSS" : + (g_a15_sub_chnnl == ADC_SubChannel_VDD ) ? "VDD" : + "None"); + + ADC_SelSubChannel(g_a15_sub_chnnl); + + g_a15_sub_chnnl = g_sub_channels[cnt % (sizeof(g_sub_channels)/sizeof(g_sub_channels[0]))]; + } + + ADC_Start(ADC0); + sys_delay(1000); + } + + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/.cproject b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/.project b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/Project.nuproject b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/component.mk b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/inc/isr.h b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/inc/main.h b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/readme.md b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/readme.md new file mode 100644 index 0000000..2d9b6bd --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/readme.md @@ -0,0 +1,108 @@ +adc_trigger_src_io +--- + +This is an example to select the source (I/O) to trigger ADC start +> It uses the specific pin to trigge ADC + ++ Select the ADC converison channel + + ``` + // in main.c + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_09 + #define CONFIG_TARGGET_ADC_1_CHANNEL ADC_Channel_03 + ``` + ++ Select the specific pin to trigger ADC + > It supports PB1 (nRST) or PB2 (JTCK) + >> PB1/PB2 MUST be changed to normal I/O mode + + ``` + // in main.c + #define CONFIG_ADC_EXT_TRIG_SRC ADC_ExtTrigSource_PB1 + ``` + ++ Select the trigger mode of the specific pin + > It supports rising or falling trigger mode + + ``` + // in main.c + #define CONFIG_ADC_EXT_TRIG_MODE ADC_ExtTrigMode_PinRising + ``` + + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + ++ Link PB1 to button + + - Trigger ADC when free button + + ``` + Oct 7 2025 15:46:32 + ADC Trigger single conversion (AIN-3) from external source (Pin: PB1 Rising) + Button = PA2 + Press Button to setup I/O trigger ... + PB1 (nRST) => I/O + 1-th ADC Single Conv Value = 0x77C (1916) <--- Trigger ADC when free button + 2-th ADC Single Conv Value = 0x778 (1912) + 3-th ADC Single Conv Value = 0x77A (1914) + 4-th ADC Single Conv Value = 0x77E (1918) + 5-th ADC Single Conv Value = 0x77F (1919) + ``` + + - Trigger ADC when press button + + ``` + Oct 7 2025 15:59:09 + ADC Trigger single conversion (AIN-3) from external source (Pin: PB1 Falling) + Button = PA2 + Press Button to setup I/O trigger ... + PB1 (nRST) => I/O + 1-th ADC Single Conv Value = 0x775 (1909) <--- Trigger ADC when press button + 2-th ADC Single Conv Value = 0x789 (1929) + 3-th ADC Single Conv Value = 0x78A (1930) + 4-th ADC Single Conv Value = 0x777 (1911) + ``` + ++ Link PB2 to button + + - Trigger ADC when free button + + ``` + Oct 7 2025 16:18:35 + ADC Trigger single conversion (AIN-3) from external source (Pin: PB2 Rising) + Button = PA2 + Press Button to setup I/O trigger ... + 1-th ADC Single Conv Value = 0x7DF (2015) <--- Link ICE handshaking + 2-th ADC Single Conv Value = 0x722 (1826) + 3-th ADC Single Conv Value = 0x6E8 (1768) + 4-th ADC Single Conv Value = 0x752 (1874) + 5-th ADC Single Conv Value = 0x748 (1864) + 6-th ADC Single Conv Value = 0x675 (1653) + PB2 (JTCK) => I/O <--- disable ICE + 7-th ADC Single Conv Value = 0x789 (1929) <--- free button + 8-th ADC Single Conv Value = 0x7E5 (2021) + ... + ``` + + - Trigger ADC when press button + + ``` + Oct 3 2025 16:22:41 + ADC Trigger single conversion (AIN-3) from external source (Pin: PB2 Falling) + Button = PA2 + Press Button to setup I/O trigger ... + ... + 31-th ADC Single Conv Value = 0x78A (1930) <--- Link ICE handshaking + 32-th ADC Single Conv Value = 0x77B (1915) + 33-th ADC Single Conv Value = 0x7A8 (1960) + 34-th ADC Single Conv Value = 0x792 (1938) + 35-th ADC Single Conv Value = 0x777 (1911) <--- Link ICE handshaking + PB2 (JTCK) => I/O <--- disable ICE + 36-th ADC Single Conv Value = 0x7EC (2028) <--- press button + 37-th ADC Single Conv Value = 0x777 (1911) + 38-th ADC Single Conv Value = 0x78E (1934) + 39-th ADC Single Conv Value = 0x792 (1938) + ``` diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/src/isr.c b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/src/main.c b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/src/main.c new file mode 100644 index 0000000..3389d1d --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/src/main.c @@ -0,0 +1,223 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= + +#define CONFIG_ADC_IO_SRC_PORT GPIOA +#define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_09 +#define CONFIG_TARGGET_ADC_1_CHANNEL ADC_Channel_03 + +/** + * I/O triggr is PB1 or PB2 + * + ADC_ExtTrigSource_PB1 + * + ADC_ExtTrigSource_PB2 + */ +#define CONFIG_ADC_EXT_TRIG_SRC ADC_ExtTrigSource_PB1 + +/** + * Trigger edge + * + ADC_ExtTrigMode_PinRising + * + ADC_ExtTrigMode_PinFaling + */ +#define CONFIG_ADC_EXT_TRIG_MODE ADC_ExtTrigMode_PinFaling + +/* Input Key I/O definitions */ +#define CONFIG_GPIO_INPUT_PORTx GPIOA +#define CONFIG_GPIO_INPUT_PINx GPIO_Pin_02 +#define CONFIG_GPIO_IRQ GPIOA_IRQn // GPIOB_IRQn +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static uint16_t g_ConvValue = 0; +static bool g_IsDone = false; +static bool g_hasPullLow = false; +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void GPIOx_Handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); + + if( GPIO_GetITFlag(CONFIG_GPIO_INPUT_PORTx, CONFIG_GPIO_INPUT_PINx) ) + { + GPIO_ClearITFlag(CONFIG_GPIO_INPUT_PORTx, CONFIG_GPIO_INPUT_PINx); + + g_hasPullLow = true; + } + + RESTORE_IRQ_CSR_CONTEXT(); + return; +} + +__INTERRUPT void ADC0_Handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); + + g_ConvValue = ADC_ITGetConvValue(ADC0, CONFIG_TARGGET_ADC_1_CHANNEL); + + g_IsDone = true; + + RESTORE_IRQ_CSR_CONTEXT(); + return; +} + +static void _Config_ButtonIO(void) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + msg(" Button = P%s%d\n", + (CONFIG_GPIO_INPUT_PORTx == GPIOA) ? "A" : "B", + 31ul - HAL_CLZ(CONFIG_GPIO_INPUT_PINx)); + + GPIO_InitStruct.GPIO_Pin = CONFIG_GPIO_INPUT_PINx; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN ; + GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_InitStruct.GPIO_ITInit.GPIO_Trigger = GPIO_Trigger_Level; + GPIO_InitStruct.GPIO_ITInit.GPIO_Polarity = GPIO_Polarity_Low_Fall; + GPIO_Init(CONFIG_GPIO_INPUT_PORTx , &GPIO_InitStruct); + + GPIO_ITEnable(CONFIG_GPIO_INPUT_PORTx, CONFIG_GPIO_INPUT_PINx); + return; +} + +static void _Config_AIN_IO(void) +{ + GPIO_InitTypeDef gpio_init = {0}; + + gpio_init.GPIO_Pin = CONFIG_ADC_IO_SRC_PIN; + gpio_init.GPIO_Mode = GPIO_Mode_ANAL; + GPIO_Init(CONFIG_ADC_IO_SRC_PORT, &gpio_init); + return; +} +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + REG_WRITE(SYSCFG->PRSTEN1, 0xFFFFFFFFul); + REG_WRITE(SYSCFG->PRSTEN, 0xFFFFFFFFul); + REG_WRITE(SYSCFG->PRSTEN1, 0x0ul); + REG_WRITE(SYSCFG->PRSTEN, 0x0ul); + + { /* Configure system clock */ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + } + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s %s\nADC Trigger single conversion (AIN-%d) from external source (Pin: %s %s)\n", + __DATE__, __TIME__, + (31ul - HAL_CLZ(CONFIG_TARGGET_ADC_1_CHANNEL)), + (CONFIG_ADC_EXT_TRIG_SRC == ADC_ExtTrigSource_PB1) ? "PB1" : + (CONFIG_ADC_EXT_TRIG_SRC == ADC_ExtTrigSource_PB2) ? "PB2" : + "N/A", + (CONFIG_ADC_EXT_TRIG_MODE == ADC_ExtTrigMode_PinRising) ? "Rising" : "Falling" + ); + + _Config_ButtonIO(); + _Config_AIN_IO(); + + g_hasPullLow = false; + + { /* Configure ADC */ + ADC_InitTypeDef init = {0}; + sys_irq_attr_t irq_attr = { .disable_vector = false, }; + + irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL; + irq_attr.level = SYS_IRQ_LEVEL_L; + irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN; + sys_register_IRQ(ADC0_IRQn, ADC0_Handler, &irq_attr); + sys_register_IRQ(CONFIG_GPIO_IRQ, GPIOx_Handler, &irq_attr); + + ADC_StructInit(&init); + + init.SelChannels = CONFIG_TARGGET_ADC_1_CHANNEL; + init.IsSoftTrig = false; + ADC_Init(ADC0, &init); + + ADC_ExtTrigConfig(ADC0, CONFIG_ADC_EXT_TRIG_SRC, CONFIG_ADC_EXT_TRIG_MODE); + ADC_ITConfig(ADC0, ADC_IT_CONV_DONE); + } + + g_IsDone = false; + + /* User makes External-Pin Rising/Falling to trigger ADC start */ + msg("Press Button to setup I/O trigger ...\n"); + + while(1) + { + static int cnt = 0; + + if( g_hasPullLow == true ) + { + static int is_io_mode = false; + GPIO_InitTypeDef gpio_init = {0}; + + g_hasPullLow = false; + + if( CONFIG_ADC_EXT_TRIG_SRC == ADC_ExtTrigSource_PB1 ) + { + SYSCFG_SetRstPin2NormalIO(true); + + gpio_init.GPIO_Pin = GPIO_Pin_01; + msg(" PB1 (nRST) => I/O\n"); + } + else if( CONFIG_ADC_EXT_TRIG_SRC == ADC_ExtTrigSource_PB2 ) + { + SYSCFG_SetICEPin2NormalIO(true); + + gpio_init.GPIO_Pin = GPIO_Pin_02; + msg(" PB2 (JTCK) => I/O\n"); + } + + if( is_io_mode == false ) + { + gpio_init.GPIO_Mode = GPIO_Mode_IN; + gpio_init.GPIO_PuPd = GPIO_PuPd_UP; + gpio_init.GPIO_OType = GPIO_OType_PP; + GPIO_Init(GPIOB , &gpio_init); + + is_io_mode = true; + } + } + + if( g_IsDone == false ) + continue; + + cnt++; + + msg(" %d-th ADC Single Conv Value = 0x%02X (%d)\n", + cnt, g_ConvValue, g_ConvValue); + + g_IsDone = false; + } + + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/.cproject b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/.project b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/Project.nuproject b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/component.mk b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/inc/isr.h b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/inc/main.h b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/readme.md b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/readme.md new file mode 100644 index 0000000..e9ae499 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/readme.md @@ -0,0 +1,174 @@ +comp_src_io +--- + +This example is used to run comparator with sources from I/O + ++ VinP (Input-plus type of the Comparator) support 4 I/O sources + > I/O 0 ~ 4 type + + - PEC930 + > + I/O 0: PA8 + > + I/O 1: PA11 + > + I/O 2: PA14 + > + I/O 3: PA15 + ++ VinM (Input-minus type of the Comparator) only support 1 I/O source + > + COMP_0: PA6 + > + COMP_1: PA12 + +### Use interrupt/polling mode + +```c +// at main.c +/** + * + Use polling mode when CONIFG_USE_COMP_INTERRUPT = 0 + * + Use interrupt mode when CONIFG_USE_COMP_INTERRUPT = 1 + */ +#define CONIFG_USE_COMP_INTERRUPT 0 +``` + +### Select the target COMP module + +```c +// at main.c +/** + * Use COMP0 or COMP1 + * ps. Use the COMP0 when unmark + * Use the COMP1 when mark + */ +#define CONFIG_USE_COMP0 +``` + +### Select the target I/O type of VinP + +```c +// at main.c +/** + * Select the target I/O type of VinP + * + Use I/O 0 as VinP if CONIFG_TERGET_COMP_VinP_IO_IDX is 0 + * + Use I/O 1 as VinP if CONIFG_TERGET_COMP_VinP_IO_IDX is 1 + * + Use I/O 2 as VinP if CONIFG_TERGET_COMP_VinP_IO_IDX is 2 + * + Use I/O 3 as VinP if CONIFG_TERGET_COMP_VinP_IO_IDX is 3 + */ +#define CONIFG_TERGET_COMP_VinP_IO_IDX 0 +``` + +### Select the interrupt types + +> + COMP triggers the rising event when `VinP > VinM` +> + COMP triggers the falling event when `VinP < VinM` + +``` +// at main.c +/** + * Configure status flags of COMP + * + COMP_IE_Falling + * + COMP_IE_Rising + */ +#define CONFIG_COMP_WATCH_STATE (COMP_IE_Rising | COMP_IE_Falling) +``` + + +## Operation flow + ++ Step 1. Connect the I/O of VinP (`CONIFG_TERGET_COMP_VinP_IO_IDX`) and VinM with an external device (e.g. power support) which provide difference voltage ++ Step 2. Respectively, set the specific voltage to external device (e.g. power support) to link the I/O of VinP and VinM ++ Step 3. Modify the VinP voltage of external device (e.g. power support) ++ Step 4. Observe the message has match the relation of VinP and VinM or not + + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + ++ Polling mode + > modify VinP voltage with external device + + ``` + Dec 19 2025 16:19:55 + COMP0 compares the voltage from I/O + COMP Vin+ = PA8 + COMP Vin- = PA6 + The target status (Rising/Falling) of COMP + + @COMP Event + Get (Rising edge) Vin+ > Vin- + + @COMP Event + Get (Falling edge) Vin+ < Vin- + + @COMP Event + Get (Rising edge) Vin+ > Vin- + + @COMP Event + Get (Falling edge) Vin+ < Vin- + + @COMP Event + Get (Rising edge) Vin+ > Vin- + ``` + ++ Interrupt mode + > modify VinP voltage with external device + + - Rising and Falling events + + ``` + Dec 19 2025 15:27:53 + COMP0 compares the voltage from I/O + COMP Vin+ = PA8 + COMP Vin- = PA6 + The target status (Rising/Falling) of COMP + + @COMP Event + Get (Rising edge) Vin+ > Vin- + + @COMP Event + Get (Falling edge) Vin+ < Vin- + + @COMP Event + Get (Rising edge) Vin+ > Vin- + + @COMP Event + Get (Falling edge) Vin+ < Vin- + + @COMP Event + Get (Rising edge) Vin+ > Vin- + ``` + + - Rising event + + ``` + Dec 19 2025 16:16:33 + COMP0 compares the voltage from I/O + COMP Vin+ = PA8 + COMP Vin- = PA6 + The target status (Rising/-) of COMP + + @COMP Event + Get (Rising edge) Vin+ > Vin- + + @COMP Event + Get (Rising edge) Vin+ > Vin- + + @COMP Event + Get (Rising edge) Vin+ > Vin- + ``` + + - Falling event + + ``` + Dec 19 2025 16:18:40 + COMP0 compares the voltage from I/O + COMP Vin+ = PA8 + COMP Vin- = PA6 + The target status (-/Falling) of COMP + + @COMP Event + Get (Falling edge) Vin+ < Vin- + + @COMP Event + Get (Falling edge) Vin+ < Vin- + + @COMP Event + Get (Falling edge) Vin+ < Vin- + ``` \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/src/isr.c b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/src/main.c b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/src/main.c new file mode 100644 index 0000000..89fc825 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/src/main.c @@ -0,0 +1,251 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +/** + * + Use polling mode when CONIFG_USE_COMP_INTERRUPT = 0 + * + Use interrupt mode when CONIFG_USE_COMP_INTERRUPT = 1 + */ +#define CONIFG_USE_COMP_INTERRUPT 0 + +/** + * Use COMP0 or COMP1 + * ps. Use the COMP0 when unmark + * Use the COMP1 when mark + */ +#define CONFIG_USE_COMP0 + +/** + * Select the target I/O type of VinP + * + Use I/O 0 as VinP if CONIFG_TERGET_COMP_VinP_IO_IDX is 0 + * + Use I/O 1 as VinP if CONIFG_TERGET_COMP_VinP_IO_IDX is 1 + * + Use I/O 2 as VinP if CONIFG_TERGET_COMP_VinP_IO_IDX is 2 + * + Use I/O 3 as VinP if CONIFG_TERGET_COMP_VinP_IO_IDX is 3 + */ +#define CONIFG_TERGET_COMP_VinP_IO_IDX 0 + + +#if defined(CONFIG_USE_COMP0) + #define COMPx COMP0 + #define COMPx_IRQn COMP0_IRQn + + #define CONFIG_COMP_VinM_PORTx GPIOA + #define CONFIG_COMP_VinM_PINx GPIO_Pin_06 + +#else + #define COMPx COMP1 + #define COMPx_IRQn COMP1_IRQn + + #define CONFIG_COMP_VinM_PORTx GPIOA + #define CONFIG_COMP_VinM_PINx GPIO_Pin_12 + +#endif + +#if (CONIFG_TERGET_COMP_VinP_IO_IDX == 0) + #define CONFIG_COMP_VinP_IO_PORTx GPIOA + #define CONFIG_COMP_VinP_IO_PINx GPIO_Pin_08 +#elif (CONIFG_TERGET_COMP_VinP_IO_IDX == 1) + #define CONFIG_COMP_VinP_IO_PORTx GPIOA + #define CONFIG_COMP_VinP_IO_PINx GPIO_Pin_11 +#elif (CONIFG_TERGET_COMP_VinP_IO_IDX == 2) + #define CONFIG_COMP_VinP_IO_PORTx GPIOA + #define CONFIG_COMP_VinP_IO_PINx GPIO_Pin_14 +#elif (CONIFG_TERGET_COMP_VinP_IO_IDX == 3) + #define CONFIG_COMP_VinP_IO_PORTx GPIOA + #define CONFIG_COMP_VinP_IO_PINx GPIO_Pin_15 +#else + #error "Wrong VinP I/O index !" +#endif + +#if defined(CONIFG_USE_COMP_INTERRUPT) && (CONIFG_USE_COMP_INTERRUPT) + /** + * Configure status flags of COMP + * + COMP_IE_Falling + * + COMP_IE_Rising + */ + #define CONFIG_COMP_WATCH_STATE (COMP_IE_Rising | COMP_IE_Falling) +#endif + +typedef enum comp_event +{ + COMP_EVENT_NONE = 0, + COMP_EVENT_VinP_GT_VinM = (0x1ul << 0), + COMP_EVENT_VinP_LT_VinM = (0x1ul << 1), + COMP_EVENT_BOTH = (COMP_EVENT_VinP_GT_VinM | COMP_EVENT_VinP_LT_VinM), +} comp_event_t; +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static comp_event_t g_comp_event = COMP_EVENT_NONE; +static int g_prev_state = 0; +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void COMPx_Handler(void) +{ + uint32_t flags = 0; + uint32_t it_en_flags = 0; + + SAVE_IRQ_CSR_CONTEXT(); + + it_en_flags = COMP_GetITFlags(COMPx); + flags = COMP_GetFlagStatus(COMPx, COMP_IE_ALL); + + COMP_ClearFlag(COMPx, flags); + + if( (flags & COMP_IE_Rising) & it_en_flags ) + g_comp_event |= COMP_EVENT_VinP_GT_VinM; + + if( (flags & COMP_IE_Falling) & it_en_flags ) + g_comp_event |= COMP_EVENT_VinP_LT_VinM; + + RESTORE_IRQ_CSR_CONTEXT(); + return; +} + + +static void _Config_IO(void) +{ + GPIO_InitTypeDef gpio_init = {0}; + + msg(" COMP Vin+ = P%s%d\n", + (CONFIG_COMP_VinP_IO_PORTx == GPIOA) ? "A" : "B", + 31ul - HAL_CLZ(CONFIG_COMP_VinP_IO_PINx)); + + msg(" COMP Vin- = P%s%d\n", + (CONFIG_COMP_VinM_PORTx == GPIOA) ? "A" : "B", + 31ul - HAL_CLZ(CONFIG_COMP_VinM_PINx)); + + // Vin- + gpio_init.GPIO_Pin = CONFIG_COMP_VinM_PINx; + gpio_init.GPIO_Mode = GPIO_Mode_ANAL; + GPIO_Init(CONFIG_COMP_VinM_PORTx, &gpio_init); + + // Vin+ + gpio_init.GPIO_Pin = CONFIG_COMP_VinP_IO_PINx; + GPIO_Init(CONFIG_COMP_VinP_IO_PORTx, &gpio_init); + + return; +} +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + { /* Configure system clock */ + SYSCFG_ClkInitTypeDef SysClkInit = { .ClkSource = SYSCFG_ClkSrc_HSI, }; + + #if 0 + SysClkInit.ClkSource = SYSCFG_ClkSrc_FreqDiv; + SysClkInit.SysClk_Div = SYSCFG_SysClkDiv2; + #endif + + SYSCFG_SysClkConfig(&SysClkInit); + } + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s %s\nCOMP%d compares the voltage from I/O\n", + __DATE__, __TIME__, + (COMPx == COMP0) ? 0 : 1); + + g_comp_event = COMP_EVENT_NONE; + + _Config_IO(); + + { /* Initialize COMP */ + COMP_InitTypeDef init = {0}; + + COMP_StructInit(&init); + + init.InputPlus = (CONIFG_TERGET_COMP_VinP_IO_IDX == 0) ? COMP_VinP_IO0 : + (CONIFG_TERGET_COMP_VinP_IO_IDX == 1) ? COMP_VinP_IO1 : + (CONIFG_TERGET_COMP_VinP_IO_IDX == 2) ? COMP_VinP_IO2 : + COMP_VinP_IO3; + init.InputMinus = COMP_VinM_IO; + init.InputHysteresis = COMP_Hysteresis_Enable; + init.FilterFreq = COMP_Filter_Sample_4; + init.OutputPolarity = COMP_OutPolarity_Normal; + init.OutputSel = COMP_Vout_IO; // COMP_Vout_None; + COMP_Init(COMPx, &init); + } + +#if defined(CONIFG_USE_COMP_INTERRUPT) && (CONIFG_USE_COMP_INTERRUPT) + { /* Configure Interrupt */ + COMP_IETypeDef flags = 0; + sys_irq_attr_t irq_attr = { .disable_vector = false, }; + + irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL; + irq_attr.level = SYS_IRQ_LEVEL_L; + irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN; + sys_register_IRQ(COMPx_IRQn, COMPx_Handler, &irq_attr); + + flags = CONFIG_COMP_WATCH_STATE; + msg(" The target status (%s/%s) of COMP\n", + (flags & COMP_IE_Rising) ? "Rising" : "-", + (flags & COMP_IE_Falling) ? "Falling" : "-"); + + COMP_ITConfig(COMPx, flags); + } +#endif + + COMP_Enable(COMPx); + COMP_ClearFlag(COMPx, COMP_IE_ALL); + + while(1) + { + #if defined(CONIFG_USE_COMP_INTERRUPT) && (CONIFG_USE_COMP_INTERRUPT) + if( g_comp_event == COMP_EVENT_NONE ) + continue; + + msg("\n @COMP Event\n"); + if( g_comp_event & COMP_EVENT_VinP_GT_VinM ) + { + HAL_ClearBits(g_comp_event, COMP_EVENT_VinP_GT_VinM); + msg(" Get (Rising edge) Vin+ > Vin- \n"); + } + + if( g_comp_event & COMP_EVENT_VinP_LT_VinM ) + { + HAL_ClearBits(g_comp_event, COMP_EVENT_VinP_LT_VinM); + msg(" Get (Falling edge) Vin+ < Vin- \n"); + } + #else + int rt_state = 0; + + rt_state = COMP_GetOutputLevel(COMPx); + + if( rt_state == g_prev_state ) + continue; + + g_prev_state = rt_state; + msg(" COMP Vin+ %s Vin- \n", rt_state ? ">" : "<"); + #endif + + sys_delay(1000); + } +} diff --git a/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/.cproject b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/.project b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/Project.nuproject b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/component.mk b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/inc/isr.h b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/inc/main.h b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/readme.md b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/readme.md new file mode 100644 index 0000000..ceabdac --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/readme.md @@ -0,0 +1,89 @@ +crc_calculate +--- + +This example is used to calculate CRC 16/32. + ++ Use CRC16 + + ```c + // at main.c + #define CONFIG_USE_CRC16 1 + ``` + ++ Use CRC32 + + ```c + // at main.c + #define CONFIG_USE_CRC16 0 + ``` + +# Log + +Use serial port with baudrate 115200 8bit, no parity check.
+User can receive log infomation from `PA00(Uart TXD)` of DUT. + ++ CRC16 + + ``` + 11:50:46 + This example to calculates CRC16. + + data:200001C8 | A1 98 EE 82 A5 4B 5D 90 - 11 30 AC F5 2F 54 EB 64 + data:200001D8 | 02 CC 74 C5 85 14 E8 FA - B3 66 8D CB 9E 16 6C 0A + data:200001E8 | FB 03 7B 69 BC 8E 36 D3 - 32 F5 3A D5 D1 7D 05 20 + data:200001F8 | 29 8D 79 F9 65 18 06 B4 - 99 79 47 73 90 AD 16 B4 + data:20000208 | E0 70 C9 A7 7B 69 5B 46 - 12 E2 56 B1 62 2D 1A 52 + data:20000218 | 4C 3C 14 95 82 0E 16 E5 - 98 E3 87 0F 55 61 A5 80 + data:20000228 | 56 77 D1 30 B4 CD BB A0 - 33 FD BD B1 DD 7F 04 9A + data:20000238 | 41 0E 03 CA FA 31 C7 E9 - 9D B1 41 0C 00 CD B6 14 + + Expected CRC16: 0x00006679 + + data-stream: + crc= 0x00006679 + CRC verify OK~~ + + byte by byte: + crc= 0x00006679 + CRC verify OK~~ + + two-part accumulation: + crc= 0x00004546 (addr: 0x200001C8 ~ 0x20000207) + crc= 0x00006679 (accumulate to 0x20000247) + CRC verify OK~~ + + CRC done~~ + ``` + ++ CRC32 + + ``` + 11:52:08 + This example to calculates CRC32. + + data:200001C8 | A6 98 9F 82 5A 48 5A AF - 6F BE B1 0A CB 54 63 64 + data:200001D8 | 92 C0 54 1A C5 54 6E 77 - D0 A1 72 37 9E 2D 6C CA + data:200001E8 | FA 8E 65 AA 67 38 31 D1 - 43 DE C5 3D D7 2D 6C 80 + data:200001F8 | 6A CE C0 4B 80 50 96 A8 - BD 86 46 73 8D A2 F1 57 + data:20000208 | 57 80 D0 47 D9 A9 38 CB - E5 2A C6 A2 43 39 42 3F + data:20000218 | 72 3F 8C AA 3B 8C F5 CF - 60 1F F1 3A D3 51 CE EA + data:20000228 | 36 0E 17 58 56 9D 5B 0F - F8 51 92 23 7E 74 77 34 + data:20000238 | 9C BB 68 FE 93 15 89 E9 - E3 B1 59 0F B9 F5 54 E6 + + Expected CRC32: 0xAF32ACDE + + data-stream: + crc= 0xAF32ACDE + CRC verify OK~~ + + byte by byte: + crc= 0xAF32ACDE + CRC verify OK~~ + + two-part accumulation: + crc= 0x55325724 (addr: 0x200001C8 ~ 0x20000207) + crc= 0xAF32ACDE (accumulate to 0x20000247) + CRC verify OK~~ + + CRC done~~ + ``` \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/src/isr.c b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/src/main.c b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/src/main.c new file mode 100644 index 0000000..5bfd00b --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/src/main.c @@ -0,0 +1,194 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author CT + * @version 0.1 + * @date 2024/10/28 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +#include + +#include +#include + +/* #include "gdb_peri.h" */ + +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_USE_CRC16 1 + +#if (CONFIG_USE_CRC16) + #define CONFIG_USE_CRC_WIDTH CRC_Width_CRC16 +#else + #define CONFIG_USE_CRC_WIDTH CRC_Width_CRC32 +#endif + +#define CONFIG_DATA_SIZE 128 +#define CONFIG_HALF_PART_SIZE (CONFIG_DATA_SIZE >> 1) + +/** + * Data offset for word/hword/byte align + * + '0': word + * + '2': half-word + * + '1': byte + */ +#define CONFIG_DATA_OFFSET 0 + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static uint8_t g_data[CONFIG_DATA_SIZE] = {0}; +//============================================================================= +// Private Function Definition +//============================================================================= +static __used uint16_t _Calc_crc16(uint8_t *c, int n, uint16_t crc16) +{ +#define CRC16POLY1 0x1021U +#define CRC16POLY2 0x8408U /* left-right reversal */ + + for(int i = 0; i < n; i++) + { + crc16 ^= c[i]; + for(int j = 0; j < 8; j++) + { + if (crc16 & 0x1) + crc16 = (crc16 >> 1) ^ CRC16POLY2; + else + crc16 >>= 1; + } + } + return crc16 ^ 0xFFFFU; +} + +static __used uint32_t _Calc_crc32(uint8_t *c, int n, uint32_t crc32) +{ +#define CRC32POLY1 0x04C11DB7U +#define CRC32POLY2 0xEDB88320U /* left-right reversal */ + + for(int i = 0; i < n; i++) + { + crc32 ^= c[i]; + for(int j = 0; j < 8; j++) + { + if (crc32 & 0x1) + crc32 = (crc32 >> 1) ^ CRC32POLY2; + else + crc32 >>= 1; + } + } + return crc32 ^ 0xFFFFFFFFU; +} +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + uint32_t expected_crc_value = 0; + uint32_t crc_value = 0; + + { + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + } + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s\nThis example to calculates %s.\n", + __TIME__, + #if (CONFIG_USE_CRC16) + "CRC16" + #else + "CRC32" + #endif + ); + + /** + * Prepare the data stream + */ + /* HAL_SRand(sys_get_tick()); */ + for(int i = 0; i < sizeof(g_data); i++) + { + g_data[i] = HAL_Rand() & 0xFF; + } + + syslog_dump_mem("data:", (uint32_t*)&g_data, sizeof(g_data), false); + +#if (CONFIG_USE_CRC16) + expected_crc_value = _Calc_crc16((uint8_t*)&g_data[CONFIG_DATA_OFFSET], + sizeof(g_data) - CONFIG_DATA_OFFSET, (uint16_t)CRC_START_CODE); + msg("Expected CRC16: 0x%08X\n", (int)expected_crc_value); +#else + expected_crc_value = _Calc_crc32((uint8_t*)&g_data[CONFIG_DATA_OFFSET], + sizeof(g_data) - CONFIG_DATA_OFFSET, (uint32_t)CRC_START_CODE); + msg("Expected CRC32: 0x%08X\n", (int)expected_crc_value); +#endif + + CRC_Init(); + + msg("\n data-stream:\n"); + crc_value = CRC_CalcBlockCRC((uint8_t*)&g_data[CONFIG_DATA_OFFSET], + sizeof(g_data) - CONFIG_DATA_OFFSET, CONFIG_USE_CRC_WIDTH); + msg(" crc= 0x%08X\n", (int)crc_value); + if( CRC_VerifyFlag(expected_crc_value) == 0 ) + err(" CRC verify fail !\n"); + else + msg(" CRC verify OK~~\n"); + + + msg("\n byte by byte:\n"); + CRC_Init(); + + for(int i = CONFIG_DATA_OFFSET; i < sizeof(g_data); i++) + CRC_CalcCRC((uint8_t*)&g_data[i], CONFIG_USE_CRC_WIDTH); + + msg(" crc= 0x%08X\n", (int)CRC_GetCRC()); + if( CRC_VerifyFlag(expected_crc_value) == 0 ) + err(" CRC verify fail !\n"); + else + msg(" CRC verify OK~~\n"); + + + msg("\n two-part accumulation:\n"); + CRC_Init(); + + crc_value = CRC_CalcBlockCRC((uint8_t*)&g_data[CONFIG_DATA_OFFSET], + CONFIG_HALF_PART_SIZE - CONFIG_DATA_OFFSET, CONFIG_USE_CRC_WIDTH); + msg(" crc= 0x%08X (addr: 0x%08X ~ 0x%08X)\n", + (int)crc_value, (int)&g_data[CONFIG_DATA_OFFSET], (int)&g_data[CONFIG_HALF_PART_SIZE-1]); + + crc_value = CRC_CalcBlockCRC((uint8_t*)&g_data[CONFIG_HALF_PART_SIZE], CONFIG_HALF_PART_SIZE, CONFIG_USE_CRC_WIDTH); + msg(" crc= 0x%08X (accumulate to 0x%08X)\n", (int)crc_value, (int)&g_data[CONFIG_DATA_SIZE] - 1); + if( CRC_VerifyFlag(expected_crc_value) == 0 ) + err(" CRC verify fail !\n"); + else + msg(" CRC verify OK~~\n"); + + msg("\nCRC done~~\n"); + + while(1) + { + __NOP(); + } + + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/dac/dac_base/.cproject b/pec930_sdk-v1.0.1/Examples/dac/dac_base/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dac/dac_base/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/dac/dac_base/.project b/pec930_sdk-v1.0.1/Examples/dac/dac_base/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dac/dac_base/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/dac/dac_base/Project.nuproject b/pec930_sdk-v1.0.1/Examples/dac/dac_base/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dac/dac_base/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/dac/dac_base/component.mk b/pec930_sdk-v1.0.1/Examples/dac/dac_base/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dac/dac_base/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/dac/dac_base/inc/isr.h b/pec930_sdk-v1.0.1/Examples/dac/dac_base/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dac/dac_base/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/dac/dac_base/inc/main.h b/pec930_sdk-v1.0.1/Examples/dac/dac_base/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dac/dac_base/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/dac/dac_base/readme.md b/pec930_sdk-v1.0.1/Examples/dac/dac_base/readme.md new file mode 100644 index 0000000..39f4b87 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dac/dac_base/readme.md @@ -0,0 +1,62 @@ +dac_base +--- + +This example is used to demo the usage of DAC +> It is a `10-bits DAC` + + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + ++ DAC0 + - Measure DAC outupt (PA8) + > + `step= 0`, PA8 Output= 1 mV + > + `step= 128`, PA8 Output= 407 mV + > + `step= 256`, PA8 Output= 815 mV + > + `step= 384`, PA8 Output= 1219 mV + > + `step= 512`, PA8 Output= 1627 mV + > + `step= 640`, PA8 Output= 2017 mV + > + `step= 768`, PA8 Output= 2413 mV + > + `step= 896`, PA8 Output= 2825 mV + > + `step= 1023`, PA8 Output= 3231 mV + + ``` + Oct 1 2025 16:42:52 + Run DAC-0 and output to PA8 <--- If VDD = 3300 + DAC step= 0, Expect Output= 0 mV + DAC step= 128, Expect Output= 412 mV + DAC step= 256, Expect Output= 825 mV + DAC step= 384, Expect Output= 1237 mV + DAC step= 512, Expect Output= 1650 mV + DAC step= 640, Expect Output= 2062 mV + DAC step= 768, Expect Output= 2475 mV + DAC step= 896, Expect Output= 2887 mV + DAC step= 1023, Expect Output= 3296 mV + ``` + ++ DAC1 + - Measure DAC outupt (PA8) + > + `step= 0`, PA8 Output= 1 mV + > + `step= 128`, PA8 Output= 408 mV + > + `step= 256`, PA8 Output= 815 mV + > + `step= 384`, PA8 Output= 1218 mV + > + `step= 512`, PA8 Output= 1628 mV + > + `step= 640`, PA8 Output= 2018 mV + > + `step= 768`, PA8 Output= 2413 mV + > + `step= 896`, PA8 Output= 2825 mV + > + `step= 1023`, PA8 Output= 3231 mV + + ``` + Oct 1 2025 16:50:50 + Run DAC-1 and output to PA8 <--- If VDD = 3300 + DAC step= 0, Expect Output= 0 mV + DAC step= 128, Expect Output= 412 mV + DAC step= 256, Expect Output= 825 mV + DAC step= 384, Expect Output= 1237 mV + DAC step= 512, Expect Output= 1650 mV + DAC step= 640, Expect Output= 2062 mV + DAC step= 768, Expect Output= 2475 mV + DAC step= 896, Expect Output= 2887 mV + DAC step= 1023, Expect Output= 3296 mV + ``` \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/dac/dac_base/src/isr.c b/pec930_sdk-v1.0.1/Examples/dac/dac_base/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dac/dac_base/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/dac/dac_base/src/main.c b/pec930_sdk-v1.0.1/Examples/dac/dac_base/src/main.c new file mode 100644 index 0000000..00b66d1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dac/dac_base/src/main.c @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_USE_DAC0 0 + +/** + * The reference mVoltage of ADC on board + */ +#define CONFIG_ADC_REF_mVOLTAGE 3300 // 5000 +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + #if 1 + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + #else + SysClkInit.ClkSource = SYSCFG_ClkSrc_FreqDiv; + SysClkInit.SysClk_Div = SYSCFG_SysClkDiv2; + #endif + + SYSCFG_SysClkConfig(&SysClkInit); + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s %s\nRun DAC-%d and output to PA8\n", + __DATE__, __TIME__, (CONFIG_USE_DAC0) ? 0 : 1); + + AMISC_Init(); + + for(int dac_step = 0; dac_step <= (0x1ul << 10); dac_step += ((0x1ul << 10) >> 3)) + { + dac_step = (dac_step == (0x1ul << 10)) ? (0x1ul << 10) -1 : dac_step; + + #if defined(CONFIG_USE_DAC0) && (CONFIG_USE_DAC0) + AMISC_OutInternalSignalToIO(AMISC_InternalSrc_DAC0, true); + + AMISC_DAC0_Config(dac_step); + AMISC_DAC0_Enable(); + #else + AMISC_OutInternalSignalToIO(AMISC_InternalSrc_DAC1, true); + + AMISC_DAC1_Config(dac_step); + AMISC_DAC1_Enable(); + #endif + + msg(" DAC step= %d, Expect Output= %d mV\n", + dac_step, (dac_step * CONFIG_ADC_REF_mVOLTAGE) >> 10); + + sys_delay(1000); + } + + while(1) + { + __NOP(); + } + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/.cproject b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/.project b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/Project.nuproject b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/component.mk b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/inc/isr.h b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/inc/main.h b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/readme.md b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/readme.md new file mode 100644 index 0000000..dc80123 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/readme.md @@ -0,0 +1,81 @@ +dsp_divide +--- + +This example is a demo project to calculate divide with DSP +> Support `signed 32-bits` input + ++ the remainder + > + In math theory, the remainder should be `>= 0` + > + In computer implementation, the remainder may be sign + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + +``` +14:09:45 +This is a demo project to calculat divide with DSP +Calculate -696395606/254485144: + DSP: -2...187425318 + SW : -2...187425318 +Calculate 960610547/194190880: + DSP: 4...183847027 + SW : 4...183847027 +Calculate 53174450/-1858707637: + DSP: 0...53174450 + SW : 0...53174450 +Calculate -2037599628/552396449: + DSP: -3...380410281 + SW : -3...380410281 +Calculate 1207792136/-457186971: + DSP: -2...293418194 + SW : -2...293418194 +Calculate -624636222/1570295625: + DSP: 0...624636222 + SW : 0...624636222 +Calculate -1198278299/-885072939: + DSP: 1...313205360 + SW : 1...313205360 +Calculate 407759637/1611478605: + DSP: 0...407759637 + SW : 0...407759637 +Calculate 967964410/-1150596243: + DSP: 0...967964410 + SW : 0...967964410 +Calculate -674502209/610867640: + DSP: -1...63634569 + SW : -1...63634569 +Calculate -388411390/-1696873075: + DSP: 0...388411390 + SW : 0...388411390 +Calculate 261576971/-1546613682: + DSP: 0...261576971 + SW : 0...261576971 +Calculate -2004069415/1563427714: + DSP: -1...440641701 + SW : -1...440641701 +Calculate -439982405/-2110095024: + DSP: 0...439982405 + SW : 0...439982405 +Calculate 576556116/-1770983411: + DSP: 0...576556116 + SW : 0...576556116 +Calculate -1910913220/-453320577: + DSP: 4...97630912 + SW : 4...97630912 +Calculate 1229840007/2045052399: + DSP: 0...1229840007 + SW : 0...1229840007 +Calculate 227256829/1222470193: + DSP: 0...227256829 + SW : 0...227256829 +Calculate 600388003/1510945259: + DSP: 0...600388003 + SW : 0...600388003 +Calculate -839901652/-1917673492: + DSP: 0...839901652 + SW : 0...839901652 +done~~~ + +``` + diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/src/isr.c b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/src/main.c b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/src/main.c new file mode 100644 index 0000000..27cc276 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/src/main.c @@ -0,0 +1,80 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +#include +#include +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + { + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + } + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s\nThis is a demo project to calculat divide with DSP\n", __TIME__); + + __HAL_SYSCFG_DSP_CLK_ENABLE(); + + for(int cnt = 0; cnt < 20; cnt++) + { + int numerator = 0, denominator = 0; + int Quotient = 0, Remainder = 0; + + numerator = HAL_Rand(); + denominator = HAL_Rand(); + + DSP_Div32(numerator, denominator, &Quotient, &Remainder); + + msg("Calculate %d/%d:\n", numerator, denominator); + msg(" DSP: %d...%d\n", Quotient, Remainder); + msg(" SW : %d...%d\n", (numerator/denominator), (numerator%denominator)); + } + + msg("done~~~\n"); + + while(1) + { + __NOP(); + } + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/.cproject b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/.project b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/Project.nuproject b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/component.mk b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/inc/isr.h b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/inc/main.h b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/readme.md b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/readme.md new file mode 100644 index 0000000..52e734b --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/readme.md @@ -0,0 +1,77 @@ +dsp_sqrt +--- + +This example is a demo project to calculate sqrt with DSP +> Support to input `unsigned 64-bits` values + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + +``` +13:49:12 +This is a demo project to calculat square root with DSP +square root of 1285064488: + DSP: 35847 + SW : 35847 +square root of 2029536100: + DSP: 45050 + SW : 45050 +square root of 3986797496: + DSP: 63141 + SW : 63141 +square root of 243657094: + DSP: 15609 + SW : 15609 +square root of 3954601218: + DSP: 62885 + SW : 62885 +square root of 3274404210: + DSP: 57222 + SW : 57222 +square root of 2272361996: + DSP: 47669 + SW : 47669 +square root of 1348358280: + DSP: 36719 + SW : 36719 +square root of 2143185402: + DSP: 46294 + SW : 46294 +square root of 1611702454: + DSP: 40146 + SW : 40146 +square root of 2651961574: + DSP: 51497 + SW : 51497 +square root of 2217312272: + DSP: 47088 + SW : 47088 +square root of 2377225393: + DSP: 48756 + SW : 48756 +square root of 3369961082: + DSP: 58051 + SW : 58051 +square root of 3553778770: + DSP: 59613 + SW : 59613 +square root of 3301112800: + DSP: 57455 + SW : 57455 +square root of 4229335839: + DSP: 65033 + SW : 65033 +square root of 2794502198: + DSP: 52863 + SW : 52863 +square root of 2327378881: + DSP: 48242 + SW : 48242 +square root of 584525248: + DSP: 24176 + SW : 24176 +done~~~ + + +``` \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/src/isr.c b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/src/main.c b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/src/main.c new file mode 100644 index 0000000..b841255 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/src/main.c @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +#include +#include +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + { + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + } + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s\nThis is a demo project to calculat square root with DSP\n", __TIME__); + + __HAL_SYSCFG_DSP_CLK_ENABLE(); + + for(int cnt = 0; cnt < 20; cnt++) + { + DSP_SqrtParamTypeDef param = {0}; + + param.value64 = HAL_Rand() * HAL_Rand(); + + msg("square root of %lu:\n", param.value64); + msg(" DSP: %u\n", DSP_Sqrt32(¶m)); + msg(" SW : %u\n", (uint32_t)sqrt((double)param.value64)); + } + + msg("done~~~\n"); + + while(1) + { + __NOP(); + } + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/.cproject b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/.project b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/Project.nuproject b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/component.mk b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/inc/isr.h b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/inc/main.h b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/inc/main.h new file mode 100644 index 0000000..bd118fa --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/inc/main.h @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= +/** + * + 10KB: 0x2800 + */ +#define FLASH_PROG_ADDR_START (13ul << 10) +#define FLASH_PROG_ADDR_END sizeof(EFLASH_MEM_Type) +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/readme.md b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/readme.md new file mode 100644 index 0000000..5ae68bd --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/readme.md @@ -0,0 +1,60 @@ +flash_prog_erase +--- + +This example is a demo project to P/E (Program/Erase) main-area of eFlash. +> The execute-bin will occupy front area of eFlash, + as the result P/E the other area of eFlash + +There are 3-case in this example +> + word data +> + half-word data +> + byte data + +The execute-flow of every case: + ++ Erase eFalsh (secotr by sector) and verify word-data is `0xFFFFFFFF` or not + > If the word-data is NOT `0xFFFFFFFF`, it will stop procedure and log error message + ++ Program **word/hword/byte-data** to eFlash and verify the result value of eFlash + > If the data is NOT match, it will stop procedure and log error message + +It also supports fix/random pattern + ++ Fix pattern is `0x5A5A5A5Aul` ++ Random pattern + > User should modify `CONFIG_USE_RAND_DATA` as below + > ``` + > // at main.c + > /** + > * Use random data as pattern + > */ + > #define CONFIG_USE_RAND_DATA 1 + > ``` + +If user wants to get more detail message, unmark `CONFIG_MORE_MESSAGE` definition + +```c +// at main.c +/** + * Get more log message + */ +#define CONFIG_MORE_MESSAGE +``` + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + +``` +Oct 13 2025 14:12:47 +This is eFlash Erase/Program/Read (0x00003400 ~ 0x00008000) example +## P/E with word value + done~ +## P/E with half-word value + done~ +## P/E with byte value + done~ +## P/E with data stream (32-bits valule and 4-aling length) + done~ +done ~~~~~~ +``` diff --git a/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/src/isr.c b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/src/main.c b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/src/main.c new file mode 100644 index 0000000..59db641 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/src/main.c @@ -0,0 +1,365 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#include +#include +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +/** + * Get more log message + */ +// #define CONFIG_MORE_MESSAGE + +/** + * Use random data as pattern + */ +#define CONFIG_USE_RAND_DATA 0 + +#define CONFIG_PATTERN_BYTE_1 0x5Au +#define CONFIG_PATTERN_BYTE_2 0xA5u +#define CONFIG_PATTERN_HWORD_1 0x5A5Au +#define CONFIG_PATTERN_HWORD_2 0xA5A5u +#define CONFIG_PATTERN_WORD_1 0x5A5A5A5Aul +#define CONFIG_PATTERN_WORD_2 0xA5A5A5A5ul +//============================================================================= +// Macro Definition +//============================================================================= +#if !defined(CONFIG_MORE_MESSAGE) +#undef dbg +#define dbg(str, ...) +#endif +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static uint32_t g_buf[512 >> 2] = {0}; +//============================================================================= +// Private Function Definition +//============================================================================= +static int +_Run_Flash_Erase(void) +{ + int rval = 0; + + for(uint32_t addr = FLASH_PROG_ADDR_START; + addr < FLASH_PROG_ADDR_END; + addr += FLASH_1_PAGE_SIZE) + { + uint32_t *pCur = 0; + + /* Erase eFlash (sector by sector) */ + rval = FLASH_ErasePage(addr); + if( rval ) break; + + /* Verify value after erase */ + pCur = (uint32_t*)addr; + + for(int i = 0; i < (FLASH_1_PAGE_SIZE >> 2); i++) + { + if( pCur[i] != 0xFFFFFFFFul ) + { + rval = -__LINE__; + err(" ! erase fail (addr: 0x%08X, data: 0x%08X)\n", &pCur[i], pCur[i]); + /* break; */ + } + + dbg("addr(x%08X)= x%08X, pattern= x%08X\n", &pCur[i], pCur[i], 0xFFFFFFFF); + } + } + + return rval; +} + +static int +_Run_Flash_ProgWord(uint32_t pattern) +{ + int rval = 0; + + do { + for(uint32_t addr = FLASH_PROG_ADDR_START; + addr < FLASH_PROG_ADDR_END; + addr += FLASH_1_PAGE_SIZE) + { + /* Program value to eFlash */ + for(int i = 0; i < FLASH_1_PAGE_SIZE; i += sizeof(uint32_t)) + { + rval = FLASH_ProgWord(addr + i, pattern); + if( rval ) break; + } + + if( rval ) break; + } + + if( rval ) break; + + for(uint32_t addr = FLASH_PROG_ADDR_START; + addr < FLASH_PROG_ADDR_END; + addr += FLASH_1_PAGE_SIZE) + { + /* Verify value after program */ + for(int i = 0; i < FLASH_1_PAGE_SIZE; i += sizeof(uint32_t)) + { + dbg("addr(x%08X)= x%08X, pattern= x%08X\n", addr + i, *(uint32_t*)(addr + i), pattern); + + if( *(uint32_t*)(addr + i) != pattern ) + { + rval = -__LINE__; + err(" ! prog fail (addr: 0x%08X, value: 0x%08X)\n", addr + i, *(uint32_t*)(addr + i)); + break; + } + } + + if( rval ) break; + } + } while(0); + + return rval; +} + + +static int +_Run_Flash_ProgHWord(uint16_t pattern) +{ + int rval = 0; + + do { + for(uint32_t addr = FLASH_PROG_ADDR_START; + addr < FLASH_PROG_ADDR_END; + addr += FLASH_1_PAGE_SIZE) + { + /* Program value to eFlash */ + for(int i = 0; i < FLASH_1_PAGE_SIZE; i += sizeof(uint16_t)) + { + rval = FLASH_ProgHWord(addr + i, pattern); + if( rval ) break; + } + + if( rval ) break; + } + + if( rval ) break; + + for(uint32_t addr = FLASH_PROG_ADDR_START; + addr < FLASH_PROG_ADDR_END; + addr += FLASH_1_PAGE_SIZE) + { + /* Verify value after program */ + for(int i = 0; i < FLASH_1_PAGE_SIZE; i += sizeof(uint16_t)) + { + dbg("addr(x%08X)= x%08X, pattern= x%08X\n", addr + i, *(uint16_t*)(addr + i), pattern); + + if( *(uint16_t*)(addr + i) != pattern ) + { + rval = -__LINE__; + err(" ! prog fail (addr: 0x%08X, value: 0x%04X)\n", addr + i, *(uint16_t*)(addr + i)); + break; + } + } + + if( rval ) break; + } + } while(0); + + return rval; +} + +static int +_Run_Flash_ProgByte(uint8_t pattern) +{ + int rval = 0; + + do { + for(uint32_t addr = FLASH_PROG_ADDR_START; + addr < FLASH_PROG_ADDR_END; + addr += FLASH_1_PAGE_SIZE) + { + /* Program value to eFlash */ + for(int i = 0; i < FLASH_1_PAGE_SIZE; i += sizeof(uint8_t)) + { + rval = FLASH_ProgByte(addr + i, pattern); + if( rval ) break; + } + + if( rval ) break; + } + + if( rval ) break; + + for(uint32_t addr = FLASH_PROG_ADDR_START; + addr < FLASH_PROG_ADDR_END; + addr += FLASH_1_PAGE_SIZE) + { + /* Verify value after program */ + for(int i = 0; i < FLASH_1_PAGE_SIZE; i += sizeof(uint8_t)) + { + dbg("addr(x%08X)= x%08X, pattern= x%08X\n", addr + i, *(uint8_t*)(addr + i), pattern); + + if( *(uint8_t*)(addr + i) != pattern ) + { + rval = -__LINE__; + err(" ! prog fail (addr: 0x%08X, value: 0x%02X)\n", addr + i, *(uint8_t*)(addr + i)); + break; + } + } + + if( rval ) break; + } + } while(0); + + return rval; +} + +static int +_Run_Flash_ProgData(uint32_t pattern) +{ + int rval = 0; + + do { + uint32_t patt_act = pattern; + + for(int j = 0; j < (sizeof(g_buf) >> 2); j++) + { + g_buf[j] = patt_act; + } + + for(uint32_t addr = FLASH_PROG_ADDR_START; + addr < FLASH_PROG_ADDR_END; + addr += FLASH_1_PAGE_SIZE) + { + /* Program value to eFlash */ + for(int i = 0; i < FLASH_1_PAGE_SIZE; i += sizeof(g_buf)) + { + rval = FLASH_ProgData(addr + i, (uint32_t*)&g_buf, sizeof(g_buf)); + if( rval ) break; + } + + if( rval ) break; + } + + if( rval ) break; + + + for(uint32_t addr = FLASH_PROG_ADDR_START; + addr < FLASH_PROG_ADDR_END; + addr += FLASH_1_PAGE_SIZE) + { + /* Verify value after program */ + for(int i = 0; i < FLASH_1_PAGE_SIZE; i += sizeof(g_buf)) + { + dbg("addr(x%08X)= x%08X, pattern= x%08X\n", addr + i, *(uint32_t*)(addr + i), patt_act); + + if( memcmp((void*)(addr + i), (void*)&g_buf, sizeof(g_buf)) ) + { + rval = -__LINE__; + err(" ! prog fail (addr: 0x%08X, value: 0x%08X)\n", addr + i, *(uint32_t*)(addr + i)); + break; + } + } + + if( rval ) break; + } + } while(0); + return rval; +} +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + int rval = 0; + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s %s\nThis is eFlash Erase/Program/Read (0x%08x ~ 0x%08x) example\n", + __DATE__, __TIME__, FLASH_PROG_ADDR_START, FLASH_PROG_ADDR_END); + + do { + uint32_t patt_value = 0; + + log_color(SLOG_GREEN, "## P/E with word value\n"); + + rval = _Run_Flash_Erase(); + if( rval ) break; + + patt_value = (CONFIG_USE_RAND_DATA) + ? (HAL_Rand() << 16 | HAL_Rand()) + : CONFIG_PATTERN_WORD_1; + + rval = _Run_Flash_ProgWord(patt_value); + if( rval ) break; + + msg(" done~\n"); + + log_color(SLOG_GREEN, "## P/E with half-word value\n"); + + rval = _Run_Flash_Erase(); + if( rval ) break; + + patt_value = (CONFIG_USE_RAND_DATA) + ? (HAL_Rand() & 0xFFFFul) + : CONFIG_PATTERN_HWORD_1; + + rval = _Run_Flash_ProgHWord(patt_value); + if( rval ) break; + + msg(" done~\n"); + + log_color(SLOG_GREEN, "## P/E with byte value\n"); + + rval = _Run_Flash_Erase(); + if( rval ) break; + + patt_value = (CONFIG_USE_RAND_DATA) + ? ((HAL_Rand() & 0xFF00ul) >> 8) + : CONFIG_PATTERN_BYTE_1; + + rval = _Run_Flash_ProgByte(patt_value); + if( rval ) break; + + msg(" done~\n"); + + log_color(SLOG_GREEN, "## P/E with data stream (32-bits valule and 4-aling length)\n"); + + rval = _Run_Flash_Erase(); + if( rval ) break; + + patt_value = (CONFIG_USE_RAND_DATA) + ? (HAL_Rand() << 16 | HAL_Rand()) + : CONFIG_PATTERN_WORD_1; + + rval = _Run_Flash_ProgData(patt_value); + if( rval ) break; + + msg(" done~\n"); + } while(0); + + if(rval) err("!!! fail %d\n", rval); + else msg("done ~~~~~~\n"); + + while(1) + { + __NOP(); + } + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/.cproject b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/.project b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/Project.nuproject b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/component.mk b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/inc/isr.h b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/inc/main.h b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/readme.md b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/readme.md new file mode 100644 index 0000000..5dd58ac --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/readme.md @@ -0,0 +1,54 @@ + +## GPIO Interrupt + +> This example is used to trig gpio interrupt. + ++ Select GPIO Port + + ``` + // in main.c + /** + * Select Interrupt pin + */ + #define GPIO_INPUT_PORTx GPIOB + #define GPIO_INPUT_PINx GPIO_Pin_00 + #define CONFIG_GPIO_IRQ GPIOB_IRQn + ``` + ++ Select GPIO interrupt trigger mode + + ``` + // in main.c + /** + * Select Interrupt source + */ + #define GPIO_INTERRUPT_TRIGGER GPIO_Trigger_Level + #define GPIO_INTERRUPT_POLARITY GPIO_Polarity_Low_Fall + ``` + + +## Note-Log + +Use serial port with baudrate 115200 8bit, no parity check. + ++ Select UART log pin + + ``` + // in syslog.c + #define CONFIG_LOG_DEVICE_TX_IO_PORTx GPIOA + #define CONFIG_LOG_DEVICE_TX_IO_PINx GPIO_Pin_15 + #define CONFIG_LOG_DEVICE_TX_IO_AF GPIO_AF_1 + ``` + ++ If you want to use `PB1` as an interrupt, set IO to normal IO.(RST pin by default) + + ``` + SYSCFG_SetRstPin2NormalIO(true); // set RST IO to normal IO + ``` + ++ If you want to use `PB[2:5]` as an interrupt, set IO to normal IO, and Restore IO to JTAG IO at the end.(JTAG pin by default) + + ``` + SYSCFG_SetICEPin2NormalIO(true); // set JTAG IO to normal IO + SYSCFG_SetICEPin2NormalIO(false); // set normal IO to JTAG IO + ``` diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/src/isr.c b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/src/main.c b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/src/main.c new file mode 100644 index 0000000..d304dd5 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/src/main.c @@ -0,0 +1,111 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +/** + * Select Interrupt pin + */ +#define GPIO_INPUT_PORTx GPIOB +#define GPIO_INPUT_PINx GPIO_Pin_00 +#define CONFIG_GPIO_IRQ GPIOB_IRQn + +/** + * Select Interrupt source + */ +#define GPIO_INTERRUPT_TRIGGER GPIO_Trigger_Level +#define GPIO_INTERRUPT_POLARITY GPIO_Polarity_Low_Fall +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static uint32_t g_interrupt_cnt = 0; +static bool g_hasPullLow = false; +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void GPIOx_Handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); // Save CSRs + + if( GPIO_GetITFlag(GPIO_INPUT_PORTx, GPIO_INPUT_PINx) ) + { + /* Enter interrupt trigger */ + GPIO_ClearITFlag(GPIO_INPUT_PORTx, GPIO_INPUT_PINx); + + g_hasPullLow = true; // Mark interrupt triggered + g_interrupt_cnt++; + } + + RESTORE_IRQ_CSR_CONTEXT(); // Restore CSRs + return; +} +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + /* Configure system clock */ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s %s\nThis is a demo project of GPIO interrput\n", __DATE__, __TIME__); + + /* Configure trig interrupt pin and set interrupt source */ + GPIO_InitTypeDef InitStruct = {0}; + InitStruct.GPIO_Pin = GPIO_INPUT_PINx; + InitStruct.GPIO_Mode = GPIO_Mode_IN ; + InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN; + InitStruct.GPIO_ITInit.GPIO_Trigger = GPIO_INTERRUPT_TRIGGER; + InitStruct.GPIO_ITInit.GPIO_Polarity = GPIO_INTERRUPT_POLARITY; + InitStruct.GPIO_PuPd = (InitStruct.GPIO_ITInit.GPIO_Polarity == GPIO_Polarity_High_Rise) + ? GPIO_PuPd_DOWN : GPIO_PuPd_UP; + GPIO_Init(GPIO_INPUT_PORTx , &InitStruct); + + { /* Configure the interrupt function of GPIO */ + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(CONFIG_GPIO_IRQ, GPIOx_Handler, &irq_attr); + + GPIO_ITConfig(GPIO_INPUT_PORTx, GPIO_INPUT_PINx, &InitStruct.GPIO_ITInit); + GPIO_ITEnable(GPIO_INPUT_PORTx, GPIO_INPUT_PINx); + } + + while(1) + { + /* Interrupt triggered behavior */ + if( g_hasPullLow == true ) + { + msg("Interrupt times is %d\n", g_interrupt_cnt); + g_hasPullLow = false; + } + + sys_delay(30); + } + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/.cproject b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/.project b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/Project.nuproject b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/component.mk b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/inc/isr.h b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/inc/main.h b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/readme.md b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/readme.md new file mode 100644 index 0000000..0df6687 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/readme.md @@ -0,0 +1,31 @@ + +## GPIO toggle + +The example is used to toggle gpio. + ++ Select GPIO Portx + + ``` + // at main.c + /** + * Select toggle pin + */ + #define GPIO_PORTx GPIOA + #define GPIO_Pinx GPIO_Pin_00 + ``` + +Note: +--- + ++ If you want to toggle `PB1`, set IO to normal IO.(RST pin by default) + + ``` + SYSCFG_SetRstPin2NormalIO(true); // set RST IO to normal IO + ``` + ++ If you want to toggle `PB[2:5]`, set IO to normal IO, and Restore IO to JTAG IO at the end.(JTAG pin by default) + + ``` + SYSCFG_SetICEPin2NormalIO(true); // set JTAG IO to normal IO + SYSCFG_SetICEPin2NormalIO(false); // set normal IO to JTAG IO + ``` diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/src/isr.c b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/src/main.c b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/src/main.c new file mode 100644 index 0000000..60d6691 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/src/main.c @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +#include +#include +//============================================================================= +// Constant Definition +//============================================================================= +/** + * Select toggle pin + */ +#define GPIO_PORTx GPIOA +#define GPIO_Pinx GPIO_Pin_00 +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + /* Configure system clock */ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s\nThis is a demo project to toggle gpio\n", __TIME__); + + /* Configure toggle pin */ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.GPIO_Pin = GPIO_Pinx; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; + GPIO_Init(GPIO_PORTx , &GPIO_InitStruct); + + while(1) + { + /* pin toggle */ + GPIO_TogglePin(GPIO_PORTx, GPIO_Pinx); + + /* delay 10ms */ + sys_delay(10); + } + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/.cproject b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/.project b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/Project.nuproject b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/component.mk b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/inc/isr.h b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/inc/main.h b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/readme.md b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/readme.md new file mode 100644 index 0000000..e1f8a63 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/readme.md @@ -0,0 +1,79 @@ + +## I2C_master_transceiver + +> This example is used to transceive data with STM32 I2C-Master + +### steps +> IIC master: `DUT` IIC slave: `STM32` +1. `DUT` ==> `STM32`(Transmit data action) +2. `STM32` save the data +3. `DUT` ==> `STM32`(Receive data action) +4. `STM32` send the saved data +5. `DUT` save the read data +6. `DUT` compare the Transmitted data with the Received data, + if consistent, proceed to the next loop, and inconsistent, enter `while(1)` loop + +### Configuration + ++ select transmit mode + + ``` + //in main.c + /** + * if defined, transfer data using interrupt mode + * if not, transfer data using polling mode + */ + #define CONFIG_USE_I2C_INTERRUPT + ``` + ++ Select IIC DIV Clock + + ``` + //in main.c + #define IIC_DIV_CLOCK I2C_CLK_Div60 // I2C clock division + ``` + ++ Select IIC pin + + ``` + //in main.c + /** + * Select I2C SCL and SDA pin + */ + #define IIC_SCL_PORT GPIOA + #define IIC_SCL_PIN GPIO_Pin_00 + #define IIC_SCL_AF GPIO_AF_4 + #define IIC_SDA_PORT GPIOA + #define IIC_SDA_PIN GPIO_Pin_01 + #define IIC_SDA_AF GPIO_AF_4 + ``` + + > SCL_PIN: `PA00` `PA01` `PB02` `PB01` `PB03` `PA15` + > + > SDA_PIN: `PA01` `PA00` `PB01` `PB02` `PB05` `PB00` + + +--- +Note: + ++ Select UART log pin + + ``` + // in syslog.c + #define CONFIG_LOG_DEVICE_TX_IO_PORTx GPIOA + #define CONFIG_LOG_DEVICE_TX_IO_PINx GPIO_Pin_15 + #define CONFIG_LOG_DEVICE_TX_IO_AF GPIO_AF_1 + ``` + ++ If you want to use `PB1` as an I2C pin, set IO to normal IO.(RST pin by default) + + ``` + SYSCFG_SetRstPin2NormalIO(true); // set RST IO to normal IO + ``` + ++ If you want to use `PB[2:5]` as an I2C pin, set IO to normal IO, and Restore IO to JTAG IO at the end.(JTAG pin by default) + + ``` + SYSCFG_SetICEPin2NormalIO(true); // set JTAG IO to normal IO + SYSCFG_SetICEPin2NormalIO(false); // set normal IO to JTAG IO + ``` diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/src/isr.c b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/src/main.c b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/src/main.c new file mode 100644 index 0000000..a0fa29d --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/src/main.c @@ -0,0 +1,219 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#include +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +/** + * if defined, transfer data using interrupt mode + * if not, transfer data using polling mode + */ +#define CONFIG_USE_I2C_INTERRUPT + +#define CONFIG_REMOTE_I2C_ADDR 0xB0 // slave address +#define CONFIG_DATA_BUF_LEN 64 // transmit data of length + +#define IIC_DIV_CLOCK I2C_CLK_Div60 // I2C clock division + +/** + * Select I2C SCL and SDA pin + */ +#define IIC_SCL_PORT GPIOA +#define IIC_SCL_PIN GPIO_Pin_00 +#define IIC_SCL_AF GPIO_AF_4 +#define IIC_SDA_PORT GPIOA +#define IIC_SDA_PIN GPIO_Pin_01 +#define IIC_SDA_AF GPIO_AF_4 + +#define I2Cx I2C0 +#define I2Cx_IRQn I2C0_IRQn + +#if defined(CONFIG_USE_I2C_INTERRUPT) + #define CONFIG_XFER_MODE "Interrupt" +#else + #define CONFIG_XFER_MODE "Polling" +#endif + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static uint8_t g_tx_buf[CONFIG_DATA_BUF_LEN] = {0}; +static uint8_t g_rx_buf[CONFIG_DATA_BUF_LEN] = {0}; + +static I2C_IT_HandleTypeDef g_hI2CIT = {0}; +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void I2Cx_Handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); + + I2C_Master_IRQHandler(&g_hI2CIT); + + RESTORE_IRQ_CSR_CONTEXT(); + + return; +} + +/** + * Configure the pin of I2C + */ +static void _Config_IO(void) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + GPIO_InitStruct.GPIO_Pin = IIC_SCL_PIN; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = IIC_SCL_AF; + GPIO_InitStruct.GPIO_OType = GPIO_OType_OD; + GPIO_Init(IIC_SCL_PORT, &GPIO_InitStruct); + + GPIO_InitStruct.GPIO_Pin = IIC_SDA_PIN; + GPIO_InitStruct.GPIO_AF_Mode = IIC_SDA_AF; + GPIO_Init(IIC_SDA_PORT, &GPIO_InitStruct); + + return; +} + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + I2C_ErrTypeDef rval = I2C_Err_OK; + int data_base = 0x50; + + { /* Configure system clock */ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SysClkInit.SysClk_Div = SYSCFG_SysClkDiv4; + SYSCFG_SysClkConfig(&SysClkInit); + } + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s %s\nI2C-Maseter (%s). The Target Slave-Address is 0x%02X\n", + __DATE__, __TIME__, CONFIG_XFER_MODE, (CONFIG_REMOTE_I2C_ADDR >> 1)); + + /* Configure the pin of I2C */ + _Config_IO(); + + { /* Configure the parameters of I2C */ + I2C_InitTypeDef init = {0}; + + I2C_StructInit(&init); + + init.Mode = I2C_Mode_MASTER; + init.ClockDiv = IIC_DIV_CLOCK; + init.BroadAck = I2C_BroadAck_Enable; + rval = I2C_Init(I2Cx, &init); + if( rval != I2C_Err_OK ) + { + err("I2C init fail !\n"); + } + } + +#if defined(CONFIG_USE_I2C_INTERRUPT) + { /* Setup Interrupt */ + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(I2Cx_IRQn, I2Cx_Handler, &irq_attr); + + g_hI2CIT.pHI2C = I2Cx; + } +#endif + + do { + sys_delay(500); + + /* prepare data */ + data_base++; + for(int i = 0; i < sizeof(g_tx_buf); i++) + { + g_tx_buf[i] = (data_base + i) & 0xFF; + } + + log_color(SLOG_GREEN, " @ Start Transmitting...\n"); + syslog_dump_mem("tx: ", (uint32_t*)&g_tx_buf, sizeof(g_tx_buf), 0); + + /* IIC Master transmit and receive data */ + #if defined(CONFIG_USE_I2C_INTERRUPT) + rval = I2C_Master_Transmit_IT(&g_hI2CIT, CONFIG_REMOTE_I2C_ADDR, (uint8_t*)&g_tx_buf, (uint16_t)sizeof(g_tx_buf)); + if( rval != I2C_Err_OK ) + { + err("I2C master TX fail !\n"); + break; + } + + while( g_hI2CIT.XferMode != I2C_XferMode_Idle ) + __NOP(); + + rval = I2C_Master_Receive_IT(&g_hI2CIT, CONFIG_REMOTE_I2C_ADDR, (uint8_t*)&g_rx_buf, (uint16_t)sizeof(g_rx_buf)); + if( rval != I2C_Err_OK ) + { + err("I2C master RX fail !\n"); + break; + } + + while( g_hI2CIT.XferMode != I2C_XferMode_Idle ) + __NOP(); + + #else + uint16_t length = 0; + + rval = I2C_Master_Transmit(I2Cx, CONFIG_REMOTE_I2C_ADDR, (uint8_t*)&g_tx_buf, (uint16_t)sizeof(g_tx_buf)); + if( rval != I2C_Err_OK ) + { + err("I2C master TX fail !\n"); + break; + } + + length = sizeof(g_rx_buf); + memset((void*)&g_rx_buf, 0xAA, sizeof(g_rx_buf)); + + rval = I2C_Master_Receive(I2Cx, CONFIG_REMOTE_I2C_ADDR, (uint8_t*)&g_rx_buf, &length, 1000); + if( rval != I2C_Err_OK ) + { + err("I2C master RX fail !\n"); + break; + } + #endif + + /* comparative data */ + syslog_dump_mem("rx: ", (uint32_t*)&g_rx_buf, sizeof(g_rx_buf), 0); + + if( !memcmp(g_tx_buf, g_rx_buf, sizeof(g_tx_buf)) ) + msg("done~~ \n\n"); + else + { + err("Data is NOT match !\n"); + break; + } + + } while(1); + + + while(1); + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/.cproject b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/.project b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/Project.nuproject b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/component.mk b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/inc/isr.h b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/inc/main.h b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/readme.md b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/readme.md new file mode 100644 index 0000000..543c13f --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/readme.md @@ -0,0 +1,67 @@ + +## i2c_slave_transceiver +> This example is used to transceive data with I2C-Slave + + +### steps +> IIC master: `STM32` IIC slave: `DUT` +1. `STM32` ==> `DUT`(Transmit data action) +2. `DUT` save the data +3. `STM32` ==> `DUT`(Receive data action) +4. `DUT` send data( is consistent with the transmitted data) +5. `DUT` compare the save send with the send data, if consistent, proceed to the next loop, and inconsistent, enter `while(1)` loop + +### Configuration + ++ select transmit mode + + ``` + //in main.c + /** + * if defined, transfer data using interrupt mode + * if not, transfer data using polling mode + */ + #define CONFIG_USE_I2C_INTERRUPT + ``` + ++ Select IIC pin + + ``` + //in main.c + /** + * Select I2C SCL and SDA pin + */ + #define IIC_SCL_PORT GPIOA + #define IIC_SCL_PIN GPIO_Pin_00 + #define IIC_SCL_AF GPIO_AF_4 + #define IIC_SDA_PORT GPIOA + #define IIC_SDA_PIN GPIO_Pin_01 + #define IIC_SDA_AF GPIO_AF_4 + ``` + + > SCL_PIN: `PA00` `PA01` `PB02` `PB01` `PB03` `PA15` + > + > SDA_PIN: `PA01` `PA00` `PB01` `PB02` `PB05` `PB00` + + ++ Select UART log pin + + ``` + // in syslog.c + #define CONFIG_LOG_DEVICE_TX_IO_PORTx GPIOA + #define CONFIG_LOG_DEVICE_TX_IO_PINx GPIO_Pin_15 + #define CONFIG_LOG_DEVICE_TX_IO_AF GPIO_AF_1 + ``` + ++ If you want to use `PB1` as an I2C pin, set IO to normal IO.(RST pin by default) + + ``` + SYSCFG_SetRstPin2NormalIO(true); // set RST IO to normal IO + ``` + ++ If you want to use `PB[2:5]` as an I2C pin, set IO to normal IO, and Restore IO to JTAG IO at the end. (JTAG pin by default) + + ``` + SYSCFG_SetICEPin2NormalIO(true); // set JTAG IO to normal IO + SYSCFG_SetICEPin2NormalIO(false); // set normal IO to JTAG IO + ``` diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/src/isr.c b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/src/main.c b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/src/main.c new file mode 100644 index 0000000..18ca019 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/src/main.c @@ -0,0 +1,211 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#include +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +/** + * if defined, transfer data using interrupt mode + * if not, transfer data using polling mode + */ +#define CONFIG_USE_I2C_INTERRUPT + +#define CONFIG_REMOTE_I2C_ADDR 0xAA // slave address +#define CONFIG_DATA_BUF_LEN 64 // transmit data of length + +/** + * Select I2C SCL and SDA pin + */ +#define IIC_SCL_PORT GPIOA +#define IIC_SCL_PIN GPIO_Pin_00 +#define IIC_SCL_AF GPIO_AF_4 +#define IIC_SDA_PORT GPIOA +#define IIC_SDA_PIN GPIO_Pin_01 +#define IIC_SDA_AF GPIO_AF_4 + +#define I2Cx I2C0 +#define I2Cx_IRQn I2C0_IRQn + +#if defined(CONFIG_USE_I2C_INTERRUPT) + #define CONFIG_XFER_MODE "Interrupt" +#else + #define CONFIG_XFER_MODE "Polling" +#endif +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static uint8_t g_tx_buf[CONFIG_DATA_BUF_LEN] = {0}; +static uint8_t g_rx_buf[CONFIG_DATA_BUF_LEN] = {0}; + +static I2C_IT_HandleTypeDef g_hI2CIT = {0}; +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void I2Cx_Handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); + + I2C_Slave_IRQHandler(&g_hI2CIT); + + RESTORE_IRQ_CSR_CONTEXT(); + return; +} + + +/** + * Configure the pin of I2C + */ +static void _Config_IO(void) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.GPIO_Pin = IIC_SCL_PIN; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = IIC_SCL_AF; + GPIO_InitStruct.GPIO_OType = GPIO_OType_OD; + GPIO_Init(IIC_SCL_PORT, &GPIO_InitStruct); + + GPIO_InitStruct.GPIO_Pin = IIC_SDA_PIN; + GPIO_InitStruct.GPIO_AF_Mode = IIC_SDA_AF; + GPIO_Init(IIC_SDA_PORT, &GPIO_InitStruct); + + return; +} + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + I2C_ErrTypeDef rval = I2C_Err_OK; + int data_base = 0x50; + + /* Configure system clock */ + SysClkInit.ClkSource = SYSCFG_ClkSrc_FreqDiv; + SysClkInit.SysClk_Div = SYSCFG_SysClkDiv8; + SYSCFG_SysClkConfig(&SysClkInit); + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s %s\nI2C-Slave (%s). The local Slave-Address is 0x%02X\n", + __DATE__, __TIME__, CONFIG_XFER_MODE, (CONFIG_REMOTE_I2C_ADDR >> 1)); + + /* Configure the pin of I2C */ + _Config_IO(); + + /* Configure the parameters of I2C */ + I2C_InitTypeDef init = {0}; + I2C_StructInit(&init); + init.Mode = I2C_Mode_SLAVE; + init.OwnAddress = CONFIG_REMOTE_I2C_ADDR >> 1; +// init.ClockDiv = I2C_CLK_Div960; + rval = I2C_Init(I2Cx, &init); + if( rval != I2C_Err_OK ) + { + err("I2C init fail !\n"); + } + + +#if defined(CONFIG_USE_I2C_INTERRUPT) + { /* Setup Interrupt */ + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(I2Cx_IRQn, I2Cx_Handler, &irq_attr); + + g_hI2CIT.pHI2C = I2Cx; + } +#endif + + do { + /* prepare data */ + data_base++; + for(int i = 0; i < sizeof(g_tx_buf); i++) + { + g_tx_buf[i] = (data_base + i) & 0xFF; + } + + log_color(SLOG_GREEN, " @ Start Transmitting...\n"); + syslog_dump_mem("tx: ", (uint32_t*)&g_tx_buf, sizeof(g_tx_buf), 0); + + /* IIC slave receive and transmit data */ + #if defined(CONFIG_USE_I2C_INTERRUPT) + rval = I2C_Slave_Receive_IT(&g_hI2CIT, (uint8_t*)&g_rx_buf, (uint16_t)sizeof(g_rx_buf)); + if( rval != I2C_Err_OK ) + { + err("I2C master TX fail !\n"); + break; + } + + while( g_hI2CIT.XferMode != I2C_XferMode_Idle ) + __NOP(); + + rval = I2C_Slave_Transmit_IT(&g_hI2CIT, (uint8_t*)&g_tx_buf, (uint16_t)sizeof(g_tx_buf)); + if( rval != I2C_Err_OK ) + { + err("I2C master RX fail !\n"); + break; + } + + while( g_hI2CIT.XferMode != I2C_XferMode_Idle ) + __NOP(); + + #else + uint16_t length = 0; + + length = sizeof(g_rx_buf); + + memset((void*)&g_rx_buf, 0xAA, sizeof(g_rx_buf)); + + rval = I2C_Slave_Receive(I2Cx, (uint8_t*)&g_rx_buf, &length, I2C_BLOCKING); + if( rval != I2C_Err_OK ) + { + err("I2C slave RX fail !\n"); + break; + } + + rval = I2C_Slave_Transmit(I2Cx, (uint8_t*)&g_tx_buf, (uint16_t)sizeof(g_tx_buf), I2C_BLOCKING); + if( rval != I2C_Err_OK ) + { + err("I2C slave TX fail !\n"); + break; + } + #endif + + /* comparative data */ + syslog_dump_mem("rx: ", (uint32_t*)&g_rx_buf, sizeof(g_rx_buf), 0); + + if( !memcmp(g_tx_buf, g_rx_buf, sizeof(g_tx_buf)) ) + msg("done~~ \n\n"); + else + { + err("Data is NOT match !\n"); + break; + } + + } while(1); + + + while(1); + return 0; + } diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/.cproject b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/.project b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/Project.nuproject b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/component.mk b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/inc/isr.h b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/inc/main.h b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/readme.md b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/readme.md new file mode 100644 index 0000000..7908a3b --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/readme.md @@ -0,0 +1,17 @@ +LPTIM count +--- + +This example is used to run LPTIM count function. + +## Hardware and Software environment + ++ This example runs on PEC930 devices. + +## How to use it ? + +### In order to make the program work, you must do the following: + ++ Open your preferred toolchain ++ Rebuild all files and load your image into target memory ++ Set the count value to your desired value. ++ Run the example \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/src/isr.c b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/src/main.c b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/src/main.c new file mode 100644 index 0000000..7c8e3dd --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/src/main.c @@ -0,0 +1,106 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= + +// #define CONFIG_USE_LPTIM +#define CONFIG_USE_TIM0 +// #define CONFIG_USE_TIM1 + +#if defined(CONFIG_USE_LPTIM) + #define LPTIMx LPTIM + #define CONFIG_PERI_NAME "LpTim" +#elif defined(CONFIG_USE_TIM0) + #define LPTIMx TIM0 + #define CONFIG_PERI_NAME "Tim0" +#elif defined(CONFIG_USE_TIM1) + #define LPTIMx TIM1 + #define CONFIG_PERI_NAME "Tim1" +#endif + +/* Use PA2 to toggle */ +#define CONFIG_TOGGLE_PORT GPIOA +#define CONFIG_TOGGLE_PIN GPIO_Pin_02 +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + uint32_t set_matchvalue = 0; + LPTIM_InitTypeDef Init = {0}; + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("This is a demo project to set %s count\n", + CONFIG_PERI_NAME); + + {// configure I/O to toggle + GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.GPIO_Pin = CONFIG_TOGGLE_PIN; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; + GPIO_Init(CONFIG_TOGGLE_PORT, &GPIO_InitStruct); + } + + set_matchvalue = 0xFFF0; + + Init.LPTIM_Prescaler = 0x3; + Init.LPTIM_ClockSource = LPTIM_CLK_Src_SysClk; + Init.LPTIM_MatchMode = LPTIM_MatchMode_Reset; + Init.LPTIM_MatchValue = set_matchvalue; + LPTIM_Init(LPTIMx, &Init); + + LPTIM_Enable(LPTIMx); + + while(1) + { + if( LPTIM_GetFlagStatus(LPTIMx, LPTIM_Flag_Match0) ) + { + LPTIM_ClearFlag(LPTIMx, LPTIM_Flag_Match0); + + msg("cnt= x%04X\n", LPTIM_GetCounter(LPTIMx)); + + GPIO_TogglePin(CONFIG_TOGGLE_PORT, CONFIG_TOGGLE_PIN); + } + + } + + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/.cproject b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/.project b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/Project.nuproject b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/component.mk b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/inc/isr.h b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/inc/main.h b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/readme.md b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/readme.md new file mode 100644 index 0000000..851ee0d --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/readme.md @@ -0,0 +1,17 @@ +LPTIM match and interrupt +--- + +This example is used to run LPTIM match and interrupt function. + +## Hardware and Software environment + ++ This example runs on PEC930 devices. + +## How to use it ? + +### In order to make the program work, you must do the following: + ++ Open your preferred toolchain ++ Rebuild all files and load your image into target memory ++ Set the match model and interrupt ++ Run the example \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/src/isr.c b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/src/main.c b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/src/main.c new file mode 100644 index 0000000..e6100f3 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/src/main.c @@ -0,0 +1,123 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= + +#define CONFIG_USE_LPTIM +// #define CONFIG_USE_TIM0 +// #define CONFIG_USE_TIM1 + +#if defined(CONFIG_USE_LPTIM) + #define LPTIMx LPTIM + #define CONFIG_IRQ_ID LPTIM_IRQn + #define CONFIG_PERI_NAME "LpTim" +#elif defined(CONFIG_USE_TIM0) + #define LPTIMx TIM0 + #define CONFIG_IRQ_ID TIM0_IRQn + #define CONFIG_PERI_NAME "Tim0" +#elif defined(CONFIG_USE_TIM1) + #define LPTIMx TIM1 + #define CONFIG_IRQ_ID TIM1_IRQn + #define CONFIG_PERI_NAME "Tim1" +#endif + +/* Use PA2 to toggle */ +#define CONFIG_TOGGLE_PORT GPIOA +#define CONFIG_TOGGLE_PIN GPIO_Pin_02 +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void LPTIMx_Handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); + + if( LPTIM_GetFlagStatus(LPTIMx, LPTIM_Flag_Match0) ) + { + LPTIM_ClearFlag(LPTIMx, LPTIM_Flag_Match0); + + GPIO_TogglePin(CONFIG_TOGGLE_PORT, CONFIG_TOGGLE_PIN); + } + + RESTORE_IRQ_CSR_CONTEXT(); + return; + +} +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + LPTIM_InitTypeDef Init = {0}; + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("This is a demo project to set %s match model and interrupt\n", + CONFIG_PERI_NAME); + + + {// configure I/O to toggle + GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.GPIO_Pin = CONFIG_TOGGLE_PIN; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; + GPIO_Init(CONFIG_TOGGLE_PORT, &GPIO_InitStruct); + } + + + Init.LPTIM_Prescaler = 0x0; + Init.LPTIM_ClockSource = LPTIM_CLK_Src_SysClk; + Init.LPTIM_MatchMode = LPTIM_MatchMode_IRQ | LPTIM_MatchMode_Reset; + Init.LPTIM_MatchValue = 2400; + LPTIM_Init(LPTIMx, &Init); + + /* Regiser ISR MUST be after init method */ + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(CONFIG_IRQ_ID, LPTIMx_Handler, &irq_attr); + sys_enable_girq(); + + LPTIM_ITConfig(LPTIMx, true); + + LPTIM_Enable(LPTIMx); + + + while(1) + { + __NOP(); + } + + + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/.cproject b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/.project b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/Project.nuproject b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/component.mk b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/inc/isr.h b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/inc/main.h b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/readme.md b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/readme.md new file mode 100644 index 0000000..e6ca230 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/readme.md @@ -0,0 +1,21 @@ +## LVD & LVR + +> This example is used to run lvd/lvr function. + ++ Select Test Items + ``` + // in main.c + /** + * Enable LVD and Select LVD Voltage + */ + #define LVD_TEST_EN + #define LVD_VOL_SET AMISC_LVDVoltage_4_3V + + /** + * Enable LVR and Select LVR Voltage + */ + //#define LVR_TEST_EN + //#define LVR_VOL_SET AMISC_LVRVoltage_3_7V + ``` + +> Run Code,and adjust VDD, then observe the waveform with an oscilloscope \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/src/isr.c b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/src/main.c b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/src/main.c new file mode 100644 index 0000000..c4d4011 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/src/main.c @@ -0,0 +1,105 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +/** + * Enable LVD and Select LVD Voltage + */ +#define LVD_TEST_EN +#define LVD_VOL_SET AMISC_LVDVoltage_4_3V + +/** + * Enable LVR and Select LVR Voltage + */ +//#define LVR_TEST_EN +//#define LVR_VOL_SET AMISC_LVRVoltage_3_7V +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + GPIO_InitTypeDef GPIO_InitStruct = {0}; + AMISC_LVDRInitTypeDef LVD_LVR_InitStruct = {0}; + + /* Configure system clock */ + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + /* Enable AMISC Module and enable vbuf */ + AMISC_Init(); + AMISC_Vbuf_Enable(); + + /* Enable and Configure the parameters of LVD/LVR */ +#if defined(LVD_TEST_EN) + AMISC_LVD_Enable(); + LVD_LVR_InitStruct.LVD_Voltage = LVD_VOL_SET; +#endif + +#if defined(LVR_TEST_EN) + AMISC_LVR_Enable(); + LVD_LVR_InitStruct.LVR_Voltage = LVR_VOL_SET; +#endif + + AMISC_LVD_LVR_Config(&LVD_LVR_InitStruct); + + info("%s %s\nThis is a demo project of LVD/LVR test\n", __DATE__, __TIME__); + + /* Configure GPIO, pin is used to display the status of LVD/LVR */ + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_00 | GPIO_Pin_03; + GPIO_InitStruct.GPIO_Pin = GPIO_PIN_All; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; + GPIO_Init(GPIOA , &GPIO_InitStruct); + + while(1) + { +#if defined(LVR_TEST_EN) + /* Observe LVR action through pin */ + GPIO_TogglePin(GPIOA, GPIO_Pin_00); +#endif + +#if defined(LVD_TEST_EN) + /* VDD < LVD: pin out low; VDD > LVD:pin out high */ + GPIO_WriteBit(GPIOA, GPIO_Pin_03, (AMISC_LVD_GetFlagStatus() ? GPIO_PIN_HIGH : GPIO_PIN_LOW)); +#endif + sys_delay(1); + + } + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/.cproject b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/.project b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/Project.nuproject b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/component.mk b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/inc/isr.h b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/inc/main.h b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/readme.md b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/readme.md new file mode 100644 index 0000000..060fc01 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/readme.md @@ -0,0 +1,114 @@ +pga_src_internal +--- + +This example is used to demo the PGA module which uses internal signals as input/output +> Only PGA0 supports internal source + ++ Configure the amplifier gain + + ```c + // at main.c + /** + * The amplify gain, @ref OPAMP_PGAGainTypeDef + * ps. OPAMP_PGAGain_1 ~ OPAMP_PGAGain_16 + */ + #define CONFIG_AMP_GAIN OPAMP_PGAGain_1 + ``` + ++ Configure the reference mVoltage of ADC to convert the sampled value to mVoltage + + ```c + // at main.c + /** + * The reference mVoltage of ADC on board + */ + #define CONFIG_ADC_REF_mVOLTAGE 3300 + ``` + + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + ++ Internal signal + > + Temperature: Analog signal output to PA8 (0.686 V) + > + DAC0 : Analog signal output to PA8 (1.627 V) + > + DAC1 : Analog signal output to PA8 (1.659 V) + > + VBuf 1.5v : Analog signal output to PA8 (1.511 V) + > + VDDL : Analog signal output to PA8 (1.521 V) + > + VSS : Analog signal output to PA8 (0.002 V) + > + VDD : Analog signal output to PA8 (3.288 V) + + ``` + Oct 1 2025 15:48:50 + Run PGA-0 (Programmable Gain Amplifier) internal source + The gain 1 + VinP= Internal signal + VinM= GND + Vout= ADC AIN0 + + Set internal signal: Temperature + ADC samples the PGA Vout= 0x00000353 (685 mV) + + Set internal signal: DAC 0 + ADC samples the PGA Vout= 0x000007D7 (1616 mV) + + Set internal signal: DAC 1 + ADC samples the PGA Vout= 0x000007F0 (1637 mV) + + Set internal signal: VBuf 1.5 + ADC samples the PGA Vout= 0x0000074C (1504 mV) + + Set internal signal: VDDL + ADC samples the PGA Vout= 0x00000757 (1513 mV) + + Set internal signal: VSS + ADC samples the PGA Vout= 0x00000006 (4 mV) + + Set internal signal: VDD + ADC samples the PGA Vout= 0x00000FEF (3286 mV) + + Set internal signal: Temperature + ADC samples the PGA Vout= 0x0000034F (682 mV) + + Set internal signal: DAC 0 + ADC samples the PGA Vout= 0x000007CE (1609 mV) + + Set internal signal: DAC 1 + ADC samples the PGA Vout= 0x00000822 (1677 mV) + + Set internal signal: VBuf 1.5 + ADC samples the PGA Vout= 0x0000074F (1507 mV) + + Set internal signal: VDDL + ADC samples the PGA Vout= 0x0000074C (1504 mV) + + Set internal signal: VSS + ADC samples the PGA Vout= 0x00000004 (3 mV) + + Set internal signal: VDD + ADC samples the PGA Vout= 0x00000FED (3284 mV) + + Set internal signal: Temperature + ADC samples the PGA Vout= 0x0000034F (682 mV) + + Set internal signal: DAC 0 + ADC samples the PGA Vout= 0x000007E2 (1625 mV) + + Set internal signal: DAC 1 + ADC samples the PGA Vout= 0x000007F2 (1638 mV) + + Set internal signal: VBuf 1.5 + ADC samples the PGA Vout= 0x00000747 (1500 mV) + + Set internal signal: VDDL + ADC samples the PGA Vout= 0x00000755 (1512 mV) + + Set internal signal: VSS + ADC samples the PGA Vout= 0x00000008 (6 mV) + + Set internal signal: VDD + ADC samples the PGA Vout= 0x00000FF6 (3291 mV) + + ... + ``` diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/src/isr.c b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/src/main.c b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/src/main.c new file mode 100644 index 0000000..0026678 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/src/main.c @@ -0,0 +1,188 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +/** + * The reference mVoltage of ADC on board + */ +#define CONFIG_ADC_REF_mVOLTAGE 3300 // 5000 + +/** + * The amplify gain, @ref OPAMP_PGAGainTypeDef + * ps. OPAMP_PGAGain_1 ~ OPAMP_PGAGain_16 + */ +#define CONFIG_AMP_GAIN OPAMP_PGAGain_1 + + +#define OPAMPx OPAMP0 +#define CONFIG_ADC_TARGET_CHANNEL ADC_Channel_OPA0_O + + +typedef enum internal_src +{ + INTERNAL_SRC_TEMPERATURE, + INTERNAL_SRC_DAC0, + INTERNAL_SRC_DAC1, + INTERNAL_SRC_VBUF_1P5V, + INTERNAL_SRC_VDDL, + INTERNAL_SRC_VSS, + INTERNAL_SRC_VDD, + +} internal_src_t; +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +static AMISC_InternalSrcTypeDef g_VinP_Src = AMISC_InternalSrc_NONE; +static AMISC_InternalSrcTypeDef g_InternalSrc[] = +{ + AMISC_InternalSrc_TEMP, + AMISC_InternalSrc_DAC0, + AMISC_InternalSrc_DAC1, + AMISC_InternalSrc_VBuf_1P5V, + AMISC_InternalSrc_VDDL, + AMISC_InternalSrc_VSS, + AMISC_InternalSrc_VDD, +}; + + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + { /* Configure system clock */ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + } + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s %s\nRun PGA-%d (Programmable Gain Amplifier) internal source\n", + __DATE__, __TIME__, (OPAMPx == OPAMP0) ? 0 : 1); + + msg(" The gain %d\n", + (CONFIG_AMP_GAIN == OPAMP_PGAGain_2 ) ? 2 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_3 ) ? 3 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_4 ) ? 4 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_5 ) ? 5 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_6 ) ? 6 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_7 ) ? 7 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_8 ) ? 8 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_9 ) ? 9 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_10) ? 10 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_11) ? 11 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_12) ? 12 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_13) ? 13 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_14) ? 14 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_15) ? 15 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_16) ? 16 : + 1); + + msg(" VinP= Internal signal\n"); + msg(" VinM= GND\n"); + msg(" Vout= ADC AIN%d\n", 31ul - HAL_CLZ(CONFIG_ADC_TARGET_CHANNEL)); + + { /* Configure ADC */ + ADC_InitTypeDef init = {0}; + + ADC_StructInit(&init); + + init.SelChannels = CONFIG_ADC_TARGET_CHANNEL; + init.IsSoftTrig = true; + ADC_Init(ADC0, &init); + } + + while(1) + { + static int cnt = 0; + OPAMP_InitTypeDef init = {0}; + uint32_t ConvValue = 0; + + /* Configure OPAMP module */ + init.OPAMP_VinP = OPAMP_VinP_Internal; + init.OPAMP_VinM = OPAMP_VinM_GND; + init.OPAMP_Vout = OPAMP_Vout_None; + init.OPAMP_Gain = CONFIG_AMP_GAIN; + + if( init.OPAMP_VinP == OPAMP_VinP_Internal ) + { + uint16_t dac_step = 512; // 0 ~ 1023 (10-bits) + + g_VinP_Src = g_InternalSrc[cnt % (sizeof(g_InternalSrc)/sizeof(g_InternalSrc[0]))]; + + log_color(SLOG_GREEN, "\nSet internal signal: %s\n", + (g_VinP_Src == AMISC_InternalSrc_TEMP ) ? "Temperature" : + (g_VinP_Src == AMISC_InternalSrc_DAC0 ) ? "DAC 0" : + (g_VinP_Src == AMISC_InternalSrc_DAC1 ) ? "DAC 1" : + (g_VinP_Src == AMISC_InternalSrc_VBuf_1P5V) ? "VBuf 1.5" : + (g_VinP_Src == AMISC_InternalSrc_VDDL ) ? "VDDL" : + (g_VinP_Src == AMISC_InternalSrc_VSS ) ? "VSS" : + (g_VinP_Src == AMISC_InternalSrc_VDD ) ? "VDD" : + "None"); + + /* Select internal source as VinP */ + AMISC_Sel_PGA_VinP_Src(g_VinP_Src); + AMISC_OutInternalSignalToIO(g_VinP_Src, true); + + if( g_VinP_Src == AMISC_InternalSrc_DAC0 ) + { + AMISC_DAC0_Config(dac_step); + AMISC_DAC0_Enable(); + } + else if( g_VinP_Src == AMISC_InternalSrc_DAC1 ) + { + AMISC_DAC1_Config(dac_step + 10); + AMISC_DAC1_Enable(); + } + } + + OPAMP_Init(OPAMPx, &init); + + OPAMP_Enable(OPAMPx); + + sys_busy_wait(60*1000); + + ADC_Start(ADC0); + + ConvValue = ADC_GetChannelConvValue(ADC0, CONFIG_ADC_TARGET_CHANNEL); + + msg(" ADC samples the PGA Vout= 0x%08X (%d mV)\n", + ConvValue, ((ConvValue * CONFIG_ADC_REF_mVOLTAGE) >> 12)); + + cnt++; + + sys_delay(1000); + } + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/.cproject b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/.project b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/Project.nuproject b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/component.mk b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/inc/isr.h b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/inc/main.h b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/readme.md b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/readme.md new file mode 100644 index 0000000..fb8e142 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/readme.md @@ -0,0 +1,108 @@ +pga_src_io +--- + +This example is used to demo the PGA module which uses GPIO Pins as input/output + ++ Select PGA0 or PGA1 + + ```c + // at main.c + /** + * Select the terget OPAMP module + * + unmark CONFIG_USE_OPAMP_0 => OPAMP0 + * + mark CONFIG_USE_OPAMP_0 => OPAMP1 + */ + #define CONFIG_USE_OPAMP_0 + ``` + ++ Configure the amplifier gain + + ```c + // at main.c + /** + * The amplify gain, @ref OPAMP_PGAGainTypeDef + * ps. OPAMP_PGAGain_1 ~ OPAMP_PGAGain_16 + */ + #define CONFIG_AMP_GAIN OPAMP_PGAGain_1 + ``` + ++ Configure the reference mVoltage of ADC to convert the sampled value to mVoltage + + ```c + // at main.c + /** + * The reference mVoltage of ADC on board + */ + #define CONFIG_ADC_REF_mVOLTAGE 3300 + ``` + ++ Configure VinM to use internal ground + + ``` + // at main.c + #define CONFIG_SET_OPAMP_VINM_GND 1 + ``` + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + ++ Use OPAmp0 and PA8 links to VDD/VSS + + ``` + Oct 1 2025 14:25:16 + Run PGA-0 (Programmable Gain Amplifier) + The gain 1 + VinP= PA8 + VinM= GND + Vout= ADC AIN0 <--- Vout directly links to AIN0 + ADC samples the PGA Vout= 0x08E6 (1835 mV) + ADC samples the PGA Vout= 0x080D (1660 mV) + ADC samples the PGA Vout= 0x061F (1262 mV) + ADC samples the PGA Vout= 0x0590 (1147 mV) + ADC samples the PGA Vout= 0x0E02 (2889 mV) + ADC samples the PGA Vout= 0x0FFB (3295 mV) <--- link VinP to VDD + ADC samples the PGA Vout= 0x0FFB (3295 mV) + ADC samples the PGA Vout= 0x0FFB (3295 mV) + ADC samples the PGA Vout= 0x0FFA (3295 mV) + ADC samples the PGA Vout= 0x0BB2 (2412 mV) + ADC samples the PGA Vout= 0x0003 (2 mV) <--- link VinP to VSS + ADC samples the PGA Vout= 0x0001 (0 mV) + ADC samples the PGA Vout= 0x0002 (1 mV) + ADC samples the PGA Vout= 0x0003 (2 mV) + ``` + ++ Use OPAmp0 and PA8 links to VDD/VSS + > ADC samples AIN9 (PA7) + >> There is an impedance between Vout and AIN9(PA7). + As this result, the ADC sample value is difference with `Vout = AIN0` case + + ``` + Oct 1 2025 14:30:09 + Run PGA-0 (Programmable Gain Amplifier) + The gain 1 + VinP= PA8 + VinM= GND + Vout= PA7 <--- Vout to PA7 + ADC samples the PGA Vout= 0x0110 (219 mV) + ADC samples the PGA Vout= 0x0056 (69 mV) <--- link VinP to VSS + ADC samples the PGA Vout= 0x0058 (70 mV) + ADC samples the PGA Vout= 0x0059 (71 mV) + ADC samples the PGA Vout= 0x0062 (78 mV) + ADC samples the PGA Vout= 0x002B (34 mV) + ADC samples the PGA Vout= 0x0038 (45 mV) + ADC samples the PGA Vout= 0x0057 (70 mV) + ADC samples the PGA Vout= 0x0064 (80 mV) + ADC samples the PGA Vout= 0x0029 (33 mV) + ADC samples the PGA Vout= 0x0031 (39 mV) + ADC samples the PGA Vout= 0x0590 (1147 mV) + ADC samples the PGA Vout= 0x0ADB (2238 mV) + ADC samples the PGA Vout= 0x0B38 (2313 mV) + ADC samples the PGA Vout= 0x0ECA (3050 mV) + ADC samples the PGA Vout= 0x0F2F (3131 mV) <--- link VinP to VDD + ADC samples the PGA Vout= 0x0F58 (3164 mV) + ADC samples the PGA Vout= 0x0F68 (3177 mV) + ADC samples the PGA Vout= 0x0F43 (3147 mV) + ADC samples the PGA Vout= 0x0F35 (3136 mV) + ... + ``` \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/src/isr.c b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/src/main.c b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/src/main.c new file mode 100644 index 0000000..563a752 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/src/main.c @@ -0,0 +1,220 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_SET_OPAMP_VINM_GND 1 + +/** + * The reference mVoltage of ADC on board + */ +#define CONFIG_ADC_REF_mVOLTAGE 3300 // 5000 + +/** + * Select the terget OPAMP module + * + unmark CONFIG_USE_OPAMP_0 => OPAMP0 + * + mark CONFIG_USE_OPAMP_0 => OPAMP1 + */ +#define CONFIG_USE_OPAMP_0 + +/** + * The amplify gain, @ref OPAMP_PGAGainTypeDef + * ps. OPAMP_PGAGain_1 ~ OPAMP_PGAGain_16 + */ +#define CONFIG_AMP_GAIN OPAMP_PGAGain_1 + + +#if defined(CONFIG_USE_OPAMP_0) + #define OPAMPx OPAMP0 + + #define CONFIG_OPAMPx_VinP_IO_PORT GPIOA + #define CONFIG_OPAMPx_VinP_IO_PIN GPIO_Pin_08 + + #define CONFIG_OPAMPx_VinM_IO_PORT GPIOA + #define CONFIG_OPAMPx_VinM_IO_PIN GPIO_Pin_09 + + #define CONFIG_OPAMPx_Vout_IO_PORT GPIOA + #define CONFIG_OPAMPx_Vout_IO_PIN GPIO_Pin_07 + + #define CONFIG_ADC_TARGET_CHANNEL ADC_Channel_OPA0_O + // #define CONFIG_ADC_TARGET_CHANNEL ADC_Channel_09 +#else + #define OPAMPx OPAMP1 + + #define CONFIG_OPAMPx_VinP_IO_PORT GPIOA + #define CONFIG_OPAMPx_VinP_IO_PIN GPIO_Pin_11 + + #define CONFIG_OPAMPx_VinM_IO_PORT GPIOA + #define CONFIG_OPAMPx_VinM_IO_PIN GPIO_Pin_10 + + #define CONFIG_OPAMPx_Vout_IO_PORT GPIOA + #define CONFIG_OPAMPx_Vout_IO_PIN GPIO_Pin_13 + + #define CONFIG_ADC_TARGET_CHANNEL ADC_Channel_OPA1_O + // #define CONFIG_ADC_TARGET_CHANNEL ADC_Channel_07 +#endif +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= +static void +_Log_IO_Msg(char *pPrefix, GPIO_Type *pHGpio, GPIO_PinTypeDef pin) +{ + int pin_idx = 0; + + pin_idx = 31 - HAL_CLZ(pin); + msg("%s P%s%d\n", pPrefix, + (pHGpio == GPIOB) ? "B" : "A", + pin_idx); + return; +} + +static int +_Config_PGA_IO(void) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + // VinP + GPIO_InitStruct.GPIO_Pin = CONFIG_OPAMPx_VinP_IO_PIN; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_ANAL; + GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_Init(CONFIG_OPAMPx_VinP_IO_PORT , &GPIO_InitStruct); + + // VinM + GPIO_InitStruct.GPIO_Pin = CONFIG_OPAMPx_VinM_IO_PIN; + GPIO_Init(CONFIG_OPAMPx_VinM_IO_PORT , &GPIO_InitStruct); + + // Vout + if( CONFIG_ADC_TARGET_CHANNEL != ADC_Channel_OPA0_O && + CONFIG_ADC_TARGET_CHANNEL != ADC_Channel_OPA1_O ) + { + GPIO_InitStruct.GPIO_Pin = CONFIG_OPAMPx_Vout_IO_PIN; + GPIO_Init(CONFIG_OPAMPx_Vout_IO_PORT , &GPIO_InitStruct); + } + return 0; +} +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + { /* Configure system clock */ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + } + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s %s\nRun PGA-%d (Programmable Gain Amplifier)\n", + __DATE__, __TIME__, (OPAMPx == OPAMP0) ? 0 : 1); + + msg(" The gain %d\n", + (CONFIG_AMP_GAIN == OPAMP_PGAGain_2 ) ? 2 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_3 ) ? 3 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_4 ) ? 4 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_5 ) ? 5 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_6 ) ? 6 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_7 ) ? 7 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_8 ) ? 8 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_9 ) ? 9 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_10) ? 10 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_11) ? 11 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_12) ? 12 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_13) ? 13 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_14) ? 14 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_15) ? 15 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_16) ? 16 : + 1); + + _Log_IO_Msg(" VinP=", CONFIG_OPAMPx_VinP_IO_PORT, CONFIG_OPAMPx_VinP_IO_PIN); + + #if defined(CONFIG_SET_OPAMP_VINM_GND) && (CONFIG_SET_OPAMP_VINM_GND) + msg(" VinM= GND\n"); + #else + _Log_IO_Msg(" VinM=", CONFIG_OPAMPx_VinM_IO_PORT, CONFIG_OPAMPx_VinM_IO_PIN); + #endif + + if( CONFIG_ADC_TARGET_CHANNEL == ADC_Channel_OPA0_O || + CONFIG_ADC_TARGET_CHANNEL == ADC_Channel_OPA1_O ) + msg(" Vout= ADC AIN%d\n", 31ul - HAL_CLZ(CONFIG_ADC_TARGET_CHANNEL)); + else + _Log_IO_Msg(" Vout=", CONFIG_OPAMPx_Vout_IO_PORT, CONFIG_OPAMPx_Vout_IO_PIN); + + _Config_PGA_IO(); + + { /* Configure ADC */ + ADC_InitTypeDef init = {0}; + + ADC_StructInit(&init); + + init.SelChannels = CONFIG_ADC_TARGET_CHANNEL; + init.IsSoftTrig = true; + ADC_Init(ADC0, &init); + } + + { /* Configure OPAMP module */ + OPAMP_InitTypeDef init = {0}; + + init.OPAMP_Gain = CONFIG_AMP_GAIN; + init.OPAMP_VinP = OPAMP_VinP_IO; + + #if defined(CONFIG_SET_OPAMP_VINM_GND) && (CONFIG_SET_OPAMP_VINM_GND) + init.OPAMP_VinM = OPAMP_VinM_GND; + #else + init.OPAMP_VinM = OPAMP_VinM_IO; + #endif + + if( CONFIG_ADC_TARGET_CHANNEL == ADC_Channel_OPA0_O || + CONFIG_ADC_TARGET_CHANNEL == ADC_Channel_OPA1_O ) + init.OPAMP_Vout = OPAMP_Vout_None; + else + init.OPAMP_Vout = OPAMP_Vout_IO; + + OPAMP_Init(OPAMPx, &init); + + OPAMP_Enable(OPAMPx); + } + + while(1) + { + uint32_t ConvValue = 0ul; + + ADC_Start(ADC0); + + ConvValue = ADC_GetChannelConvValue(ADC0, CONFIG_ADC_TARGET_CHANNEL); + + msg("ADC samples the PGA Vout= 0x%04X (%d mV)\n", + ConvValue, ((ConvValue * CONFIG_ADC_REF_mVOLTAGE) >> 12)); + + sys_delay(1000); + } + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/.cproject b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/.project b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/Project.nuproject b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/component.mk b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/inc/isr.h b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/inc/main.h b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/readme.md b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/readme.md new file mode 100644 index 0000000..8379eee --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/readme.md @@ -0,0 +1,210 @@ +pwr_sleep_mode +--- + +This example is used to enter power mode and wake-up system +> + In normal mode, it will toggle I/O to notify user +> + Use Button to enter/leave power-mode function + +When measure the electric current, user should remove all external device links +> External device e.g. ICE, log message device (UART), LA (Logic Analyzer), ...etc. + ++ Sleep/Deepsleep mode + + - Sleep mode + + ``` + // at main.c (Use sleep mode) + #define CONFIG_USE_SLEEP_MODE 1 + ``` + - Deep-Sleep mode + + ``` + // at main.c (Use deep-sleep mode) + #define CONFIG_USE_SLEEP_MODE 0 + ``` + ++ The I/O selection of Button + + ```c + // at main.c + /* Input Key I/O definitions */ + #define CONFIG_GPIO_INPUT_PORTx GPIOA + #define CONFIG_GPIO_INPUT_PINx GPIO_Pin_03 + #define CONFIG_GPIO_INPUT_IRQ GPIOA_IRQn + ``` + ++ The toggled I/O selection + + ```c + // at main.c + /* Toggle I/O when normal App executing */ + #define CONFIG_IO_TOGGLE_PORTx GPIOA + #define CONFIG_IO_TOGGLE_PINx GPIO_Pin_02 + ``` + ++ Wake-up modules selection + > + The I/O wake-up case will provide the `minimum current` when deep-sleep mode + > + The LpTIM/WDG cases will provide the `lower current` when deep-sleep mode + + > In `void (*CallbaskPreSleepTypeDef)(PWR_ModeTypeDef, PWR_WakeupTypeDef*)` + >> User uses `PWR_WakeupTypeDef` to focus on the selected wake-up type (The un-selected types will be disable) + >> ```c + >> // at _Pre_Proc() + >> ... + >> *pWakeup_type = PWR_Wakeup_IO_PORT_A | PWR_Wakeup_IO_PORT_B; + >> or + >> *pWakeup_type = PWR_Wakeup_LpTIM; + >> or + >> *pWakeup_type = PWR_Wakeup_WDG; + >> ... + >> ``` + + - I/O wake-up + + ``` + // at main.c + /** + * The target module to wake-up system + * + I/O wake-up case is ultra-low power in DeepSleep mode + * + LpTIM/WDG wake-up cases are low power in DeepSleep mode + */ + #define CONFIG_USE_IO_WAKEUP 1 + #define CONFIG_USE_LPTIN_WAKEUP 0 + #define CONFIG_USE_WDG_WAKEUP 0 + ``` + + - LpTIM wake-up + + ``` + // at main.c + /** + * The target module to wake-up system + * + I/O wake-up case is ultra-low power in DeepSleep mode + * + LpTIM/WDG wake-up cases are low power in DeepSleep mode + */ + #define CONFIG_USE_IO_WAKEUP 0 + #define CONFIG_USE_LPTIN_WAKEUP 1 + #define CONFIG_USE_WDG_WAKEUP 0 + ``` + + - WDG wake-up + + ``` + // at main.c + /** + * The target module to wake-up system + * + I/O wake-up case is ultra-low power in DeepSleep mode + * + LpTIM/WDG wake-up cases are low power in DeepSleep mode + */ + #define CONFIG_USE_IO_WAKEUP 0 + #define CONFIG_USE_LPTIN_WAKEUP 0 + #define CONFIG_USE_WDG_WAKEUP 1 + ``` + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + ++ Sleep mode + + - I/O wake-up + + ``` + [2025-11-21 16:54:01.215] Nov 19 2025 16:53:58 + [2025-11-21 16:54:01.215] This is an example of Power-Mode (Sleep) and wake-up with I/O + [2025-11-21 16:54:01.220] Button = PA3 + [2025-11-21 16:54:01.224] Output I/O = PA2 + [2025-11-21 16:54:05.020] -> enter sleep + [2025-11-21 16:54:05.020] _Pre_Proc <--- manually trigger to enter sleep mode + [2025-11-21 16:54:06.462] Output I/O = PA2 <--- manually trigger to leave sleep mode + [2025-11-21 16:54:06.462] _Post_Proc + [2025-11-21 16:54:06.464] @ Entered None ISR <--- Never enter ISR + [2025-11-21 16:54:06.464] <- wake-up + [2025-11-21 16:54:06.466] + ``` + + - LpTIM wake-up + > Configure 5 sec wake-up with LpTIM + + ``` + [2026-01-13 16:47:15.315] Nov 19 2025 16:47:12 + [2026-01-13 16:47:15.315] This is an example of Power-Mode (Sleep) and wake-up with LpTIM + [2026-01-13 16:47:15.321] Button = PA3 + [2026-01-13 16:47:15.324] Output I/O = PA2 + [2026-01-13 16:47:19.546] -> enter sleep + [2026-01-13 16:47:19.546] _Pre_Proc <--- enter sleep mode + [2026-01-13 16:48:26.635] Output I/O = PA2 <--- wake-up with LpTIM (duration 67 sec !!!) + [2026-01-13 16:48:26.635] _Post_Proc + [2026-01-13 16:48:26.637] @ Entered None ISR <--- Never enter ISR + [2026-01-13 16:48:26.637] <- wake-up + [2026-01-13 16:48:26.639] + ``` + + - WDG wake-up + > Configure 1 sec wake-up with WatchDog + + ``` + [2025-11-21 16:36:30.876] Nov 19 2025 16:35:58 + [2025-11-21 16:36:30.876] This is an example of Power-Mode (Sleep) and wake-up with WatchDog + [2025-11-21 16:36:30.881] Button = PA3 + [2025-11-21 16:36:30.881] Output I/O = PA2 + [2025-11-21 16:36:34.050] -> enter sleep + [2025-11-21 16:36:34.050] _Pre_Proc <--- enter sleep mode + [2025-11-21 16:36:35.098] Output I/O = PA2 <--- wake-up with WDG (duration 1 sec) + [2025-11-21 16:36:35.098] _Post_Proc + [2025-11-21 16:36:35.101] @ Entered None ISR <--- Never enter ISR + [2025-11-21 16:36:35.101] <- wake-up + [2025-11-21 16:36:35.102] + ``` + ++ Deepsleep + + - I/O wake-up + + ``` + [2025-11-21 16:44:10.823] Nov 19 2025 16:44:07 + [2025-11-21 16:44:10.823] This is an example of Power-Mode (DeepSleep) and wake-up with I/O + [2025-11-21 16:44:10.828] Button = PA3 + [2025-11-21 16:44:10.838] Output I/O = PA2 + [2025-11-21 16:44:13.727] -> enter deepsleep + [2025-11-21 16:44:13.727] _Pre_Proc <--- manually trigger to enter deepsleep mode + [2025-11-21 16:44:16.085] Output I/O = PA2 <--- manually trigger to leave deepsleep mode + [2025-11-21 16:44:16.085] _Post_Proc + [2025-11-21 16:44:16.085] @ Entered None ISR <--- Never enter ISR + [2025-11-21 16:44:16.085] <- wake-up + [2025-11-21 16:44:16.085] + ``` + + - LpTIM wake-up + > Configure 5 sec wake-up with LpTIM + + ``` + [2026-01-13 16:40:38.170] Nov 19 2025 16:40:34 + [2026-01-13 16:40:38.170] This is an example of Power-Mode (DeepSleep) and wake-up with LpTIM + [2026-01-13 16:40:38.179] Button = PA3 + [2026-01-13 16:40:38.179] Output I/O = PA2 + [2026-01-13 16:40:41.607] -> enter deepsleep + [2026-01-13 16:40:41.607] _Pre_Proc <--- enter deepsleep mode + [2026-01-13 16:40:46.789] Output I/O = PA2 <--- wake-up with LpTIM (duration 5 sec) + [2026-01-13 16:40:46.789] _Post_Proc + [2026-01-13 16:40:46.791] @ Entered None ISR <--- Never enter ISR + [2026-01-13 16:40:46.792] <- wake-up + [2026-01-13 16:40:46.793] + ``` + + - WDG wake-up + > Configure 1 sec wake-up with WatchDog + + ``` + [2025-11-21 16:38:56.627] Nov 19 2025 16:38:53 + [2025-11-21 16:38:56.627] This is an example of Power-Mode (DeepSleep) and wake-up with WatchDog + [2025-11-21 16:38:56.635] Button = PA3 + [2025-11-21 16:38:56.635] Output I/O = PA2 + [2025-11-21 16:38:59.874] -> enter deepsleep + [2025-11-21 16:38:59.874] _Pre_Proc <--- enter deepsleep mode + [2025-11-21 16:39:00.911] Output I/O = PA2 <--- wake-up with WDG (duration 1 sec) + [2025-11-21 16:39:00.911] _Post_Proc + [2025-11-21 16:39:00.914] @ Entered None ISR <--- Never enter ISR + [2025-11-21 16:39:00.914] <- wake-up + [2025-11-21 16:39:00.914] + ``` diff --git a/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/src/isr.c b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/src/main.c b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/src/main.c new file mode 100644 index 0000000..e34e703 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/src/main.c @@ -0,0 +1,310 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_USE_SLEEP_MODE 0 + +/** + * The target module to wake-up system + * + I/O wake-up case is ultra-low power in DeepSleep mode + * + LpTIM/WDG wake-up cases are low power in DeepSleep mode + */ +#define CONFIG_USE_IO_WAKEUP 1 +#define CONFIG_USE_LPTIM_WAKEUP 0 +#define CONFIG_USE_WDG_WAKEUP 0 + +/* Toggle I/O when normal App executing */ +#define CONFIG_IO_TOGGLE_PORTx GPIOA +#define CONFIG_IO_TOGGLE_PINx GPIO_Pin_02 + +/* Input Key I/O definitions (Wake-up Key when I/O wakup case) */ +#define CONFIG_GPIO_INPUT_PORTx GPIOA +#define CONFIG_GPIO_INPUT_PINx GPIO_Pin_03 +#define CONFIG_GPIO_INPUT_IRQn GPIOA_IRQn + + +typedef enum isr_tag +{ + ISR_TAG_NONE = 0, + ISR_TAG_LPTIM = 0x123, + ISR_TAG_WDG = 0x456, + ISR_TAG_IO = 0x789, +} isr_tag_t; +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static bool g_has_key_event = false; +static isr_tag_t g_enter_isr_tag = ISR_TAG_NONE; +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void GPIOx_Handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); + + if( GPIO_GetITFlag(CONFIG_GPIO_INPUT_PORTx, CONFIG_GPIO_INPUT_PINx) ) + { + GPIO_ClearITFlag(CONFIG_GPIO_INPUT_PORTx, CONFIG_GPIO_INPUT_PINx); + + g_has_key_event = true; + } + + g_enter_isr_tag = ISR_TAG_IO; + RESTORE_IRQ_CSR_CONTEXT(); + return; +} + +static void _Config_ButtonIO(bool has_log) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + if( has_log ) + { + msg(" Button = P%s%d\n", + (CONFIG_GPIO_INPUT_PORTx == GPIOA) ? "A" : "B", + 31ul - HAL_CLZ(CONFIG_GPIO_INPUT_PINx)); + } + + GPIO_InitStruct.GPIO_Pin = CONFIG_GPIO_INPUT_PINx; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN ; + GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_InitStruct.GPIO_ITInit.GPIO_Trigger = GPIO_Trigger_Level; + GPIO_InitStruct.GPIO_ITInit.GPIO_Polarity = GPIO_Polarity_Low_Fall; + GPIO_Init(CONFIG_GPIO_INPUT_PORTx , &GPIO_InitStruct); + + GPIO_ITEnable(CONFIG_GPIO_INPUT_PORTx, CONFIG_GPIO_INPUT_PINx); + + sys_irq_attr_t irq_attr = { .disable_vector = false, }; + + irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL; + irq_attr.level = SYS_IRQ_LEVEL_L; + irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN; + sys_register_IRQ(CONFIG_GPIO_INPUT_IRQn, GPIOx_Handler, &irq_attr); + return; +} + +static void _Config_ToggleOutput(void) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + msg(" Output I/O = P%s%d\n", + (CONFIG_IO_TOGGLE_PORTx == GPIOA) ? "A" : "B", + 31ul - HAL_CLZ(CONFIG_IO_TOGGLE_PINx)); + + GPIO_InitStruct.GPIO_Pin = CONFIG_IO_TOGGLE_PINx; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN; + GPIO_Init(CONFIG_IO_TOGGLE_PORTx, &GPIO_InitStruct); + return; +} + +static void +_Pre_Proc(PWR_ModeTypeDef pwr_mode, PWR_WakeupTypeDef *pWakeup_type) +{ + msg(" %s\n", __func__); + + { /* User terminates proprietary modules */ + sys_disable_systick(); + syslog_deinit(); + } + + { /* Configure wake-up module */ + #if (CONFIG_USE_IO_WAKEUP) + *pWakeup_type = (CONFIG_GPIO_INPUT_PORTx == GPIOA) + ? PWR_Wakeup_IO_PORT_A : PWR_Wakeup_IO_PORT_B; + + #elif (CONFIG_USE_LPTIM_WAKEUP) + + // Configure LpTim to wake-up system + LPTIM_InitTypeDef InitStruct = {0}; + int g_wakeup_sec = 5; + + SYSCFG_SetLSIAlwaysOn(true); + + *pWakeup_type = PWR_Wakeup_LpTIM; + + InitStruct.LPTIM_Prescaler = 32 - 1; + InitStruct.LPTIM_ClockSource = LPTIM_CLK_Src_LSI; + InitStruct.LPTIM_MatchMode = LPTIM_MatchMode_IRQ; + InitStruct.LPTIM_MatchValue = (g_wakeup_sec * SYS_LIRC_VALUE) / (InitStruct.LPTIM_Prescaler + 1); + LPTIM_Init(LPTIM, &InitStruct); + LPTIM_Enable(LPTIM); + + #elif (CONFIG_USE_WDG_WAKEUP) + + // Configure WDG to wake-up system + WDG_InitTypeDef init = {0}; + uint32_t g_wakeup_msec = 5000; + + SYSCFG_SetLSIAlwaysOn(true); + + *pWakeup_type = PWR_Wakeup_WDG; + + init.Counter = WDG_MSec2Counter(g_wakeup_msec); + init.ResetMode = WDG_Reset_Disable; + WDG_Init(&init); + + WDG_Enable(); + + #else + #error "No wake-up configuration !" + #endif + } + + g_enter_isr_tag = ISR_TAG_NONE; + + /* Reset Pin Configuration if necessary */ + + /* Disable ICE I/O */ + SYSCFG_SetICEPin2NormalIO(true); + + { /* Configure I/O for Power-Saving mode */ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_PWR_Saving; + GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; + GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN; + + GPIO_InitStruct.GPIO_Pin = GPIO_PIN_All; + if( GPIOA == CONFIG_GPIO_INPUT_PORTx ) + { + HAL_ClearBits(GPIO_InitStruct.GPIO_Pin, CONFIG_GPIO_INPUT_PINx); + } + + GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.GPIO_Pin = GPIO_PIN_All; + if( GPIOB == CONFIG_GPIO_INPUT_PORTx ) + { + HAL_ClearBits(GPIO_InitStruct.GPIO_Pin, CONFIG_GPIO_INPUT_PINx); + } + GPIO_Init(GPIOB, &GPIO_InitStruct); + } + + return; +} + +static void +_Post_Proc(PWR_ModeTypeDef pwr_mode) +{ + { /* Recover wake-up module */ + SYSCFG_SetLSIAlwaysOn(false); + + __HAL_SYSCFG_RESET_GPIOA(); + __HAL_SYSCFG_RESET_GPIOB(); + + #if (CONFIG_USE_LPTIM_WAKEUP) + LPTIM_DeInit(LPTIM); + #elif (CONFIG_USE_WDG_WAKEUP) + WDG_DeInit(); + #endif + } + + /* Enable ICE I/O */ + SYSCFG_SetICEPin2NormalIO(false); + + { /* User re-initializes proprietary modules */ + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + msg(" %s\n", __func__); + msg(" @ Entered %s ISR\n", + (g_enter_isr_tag == ISR_TAG_WDG) ? "WDG" : + (g_enter_isr_tag == ISR_TAG_LPTIM) ? "LpTim" : + (g_enter_isr_tag == ISR_TAG_IO) ? "I/O" : + "None"); + + _Config_ButtonIO(false); + _Config_ToggleOutput(); + + g_has_key_event = false; + } + + return; +} + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + HAL_DeviceInit(); + + { /* Configure system clock */ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + } + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s %s\nThis is an example of Power-Mode (%s) and wake-up with %s\n", + __DATE__, __TIME__, + #if (CONFIG_USE_SLEEP_MODE) + "Sleep", + #else + "DeepSleep", + #endif + #if (CONFIG_USE_IO_WAKEUP) + "I/O" + #elif (CONFIG_USE_LPTIM_WAKEUP) + "LpTIM" + #elif (CONFIG_USE_WDG_WAKEUP) + "WatchDog" + #endif + ); + + _Config_ButtonIO(true); + _Config_ToggleOutput(); + + g_has_key_event = false; + + while(1) + { + if( g_has_key_event == true ) + { + g_has_key_event = false; + + #if (CONFIG_USE_SLEEP_MODE) + msg("-> enter sleep\n"); + PWR_EnterSleepMode(_Pre_Proc, _Post_Proc); + #else + msg("-> enter deepsleep\n"); + PWR_EnterDeepSleepMode(_Pre_Proc, _Post_Proc); + #endif + + msg("<- wake-up \n\n"); + } + + GPIO_TogglePin(CONFIG_IO_TOGGLE_PORTx, CONFIG_IO_TOGGLE_PINx); + + sys_busy_wait(100); + } + + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master/.cproject b/pec930_sdk-v1.0.1/Examples/spi/spi_master/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master/.project b/pec930_sdk-v1.0.1/Examples/spi/spi_master/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master/Project.nuproject b/pec930_sdk-v1.0.1/Examples/spi/spi_master/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master/component.mk b/pec930_sdk-v1.0.1/Examples/spi/spi_master/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master/inc/isr.h b/pec930_sdk-v1.0.1/Examples/spi/spi_master/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master/inc/main.h b/pec930_sdk-v1.0.1/Examples/spi/spi_master/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master/readme.md b/pec930_sdk-v1.0.1/Examples/spi/spi_master/readme.md new file mode 100644 index 0000000..c3f0f1b --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master/readme.md @@ -0,0 +1,22 @@ +spi send and receive data +--- + +This example is used to run spi send and receive function. + +## Hardware and Software environment + ++ This example runs on PEC930 devices. + +## How to use it ? + +### In order to make the program work, you must do the following: + ++ Open your preferred toolchain ++ Rebuild all files and load your image into target memory ++ Sets the data to be transferred ++ Run the example + +* spi_clk -- p02 +* spi_do -- p03 +* spi_di -- p04 +* spi_cs -- p05 \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master/src/isr.c b/pec930_sdk-v1.0.1/Examples/spi/spi_master/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master/src/main.c b/pec930_sdk-v1.0.1/Examples/spi/spi_master/src/main.c new file mode 100644 index 0000000..372bdc8 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master/src/main.c @@ -0,0 +1,107 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= +void SPI_PinConfg(SPI_Type *spi, uint32_t io_sel) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(io_sel == 0) + { + /*----------------------------------- + * spi_clk -- p02 + * spi_do -- p03 + * spi_di -- p04 + * spi_cs -- p05 + * ---------------------------------*/ + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_02 | GPIO_Pin_03 |GPIO_Pin_04|GPIO_Pin_05; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_1; + GPIO_Init(GPIOA, &GPIO_InitStruct); + + } + +} +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + uint32_t tx_data[10] = {0}; + uint32_t rx_data[10] = {0}; + + SPI_InitTypeDef SPI_InitStruct = {0}; + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + /* Configure system clock */ + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + sys_config_systick(SYS_TICK_1_MS); + + /* set tx data */ + for(int i=0; i<10; i++) + { + tx_data[i] = 0xA1A2A3A4; + } + + /* configure GPIO Pin mux of SPI */ + SPI_PinConfg(SPI0, 0); + + /* configure SPI */ + SPI_DeInit(SPI0); + SPI_InitStruct.SPI_Mode = SPI_Mode_Master; + SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low; + SPI_InitStruct.SPI_CPHA = SPI_CPHA_Effective; + SPI_InitStruct.SPI_TxDataSize = SPI_TxDataSize_8b; + SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudratePrescaler_256; + SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB; + SPI_Init(SPI0, &SPI_InitStruct); + + /* Enable SPI */ + SPI_Enable(SPI0); + + /* SPI Master Send data */ + for(int i=0; i<10; i++) + { + SPI_SendData(SPI0, tx_data[i]); + while(SPI_GetFlagStatus(SPI0, SPI_RXNEP_Flag) == 0); + rx_data[i] = SPI_ReceiveData(SPI0); + } + + while(1) + { + __NOP(); + } + + + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/.cproject b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/.project b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/Project.nuproject b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/component.mk b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/inc/isr.h b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/inc/main.h b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/readme.md b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/readme.md new file mode 100644 index 0000000..90b1f7e --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/readme.md @@ -0,0 +1,33 @@ +spi send and receive data by interrupt +--- + +This example is used to run spi send and receive function by interrupt. + +## Hardware and Software environment + ++ This example runs on PEC930 devices. + +## How to use it ? + +### In order to make the program work, you must do the following: + ++ Open your preferred toolchain ++ Rebuild all files and load your image into target memory ++ Sets the data to be transferred ++ Run the example + +* spi_clk -- p02 +* spi_do -- p03 +* spi_di -- p04 +* spi_cs -- p05 + ++ select transmit mode + + ``` + //in main.c + /** + * Select only send Data, and send/receive Data + */ + #define TRANSMISSION_METHOD_TRANSMIT // only send data + //#define TRANSMISSION_METHOD_RECEIVE // send and receive data + ``` \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/src/isr.c b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/src/main.c b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/src/main.c new file mode 100644 index 0000000..c37db7a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/src/main.c @@ -0,0 +1,177 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= +#define TRANSMISSION_METHOD_TRANSMIT // send data +//#define TRANSMISSION_METHOD_RECEIVE // receive data +#define FRAME_LENGTH 64 // Length of one frame of data +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static uint32_t g_tx_buf[FRAME_LENGTH] = {0}; +static uint32_t g_rx_buf[FRAME_LENGTH] = {0}; +uint16_t tx_cnt = 0; +uint16_t rx_cnt = 0; +uint16_t data_base = 0; +bool frame_flag = 0; +//============================================================================= +// Private Function Definition +//============================================================================= +void SPI_PinConfg(SPI_Type *spi, uint32_t io_sel) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(io_sel == 0) + { + /*----------------------------------- + * spi_clk -- p02 + * spi_do -- p03 + * spi_di -- p04 + * spi_cs -- p05 + * ---------------------------------*/ + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_02 | GPIO_Pin_03 |GPIO_Pin_04|GPIO_Pin_05; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_1; + GPIO_Init(GPIOA, &GPIO_InitStruct); + + } + +} + +void SPI_Master_IRQHandler(void) +{ +#if defined(TRANSMISSION_METHOD_TRANSMIT) + // send data and interrupt handler + if(SPI_GetFlagStatus(SPI0,SPI_TXNFUL_Flag) == 1 && frame_flag == 0) + { + // send data + SPI_SendData(SPI0, g_tx_buf[tx_cnt++]); + if(tx_cnt >= FRAME_LENGTH) + { + // Data transmission completed, and close SPI + tx_cnt = 0; + SPI_SetInterruptDisable(SPI0, SPI_STA_TXNFUL_Msk); + SPI_Disable(SPI0); + frame_flag = 1; + } + } + +#elif defined(TRANSMISSION_METHOD_RECEIVE) + + // receive data and interrupt handler + if(SPI_GetFlagStatus(SPI0,SPI_TXNFUL_Flag) == 1 && frame_flag == 0) + { + // Send data and read data + SPI_SendData(SPI0, g_tx_buf[tx_cnt++]); + while(SPI_GetFlagStatus(SPI0, SPI_RXNEP_Flag) == 0); + // The selected transmission word size is 8 bits + // and the received data requires forced conversion (uint8_t) + g_rx_buf[rx_cnt++] = (uint8_t)SPI_ReceiveData(SPI0); // need + if(tx_cnt >= FRAME_LENGTH) + { + // Data received completed, and close SPI + tx_cnt = 0; + rx_cnt = 0; + SPI_SetInterruptDisable(SPI0, SPI_STA_TXNFUL_Msk); + SPI_Disable(SPI0); + frame_flag = 1; + } + } +#endif +} + +__INTERRUPT void SPIx_Handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); // Save CSRs + + SPI_Master_IRQHandler(); + + RESTORE_IRQ_CSR_CONTEXT(); // Restore CSRs + return; +} +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + SPI_InitTypeDef SPI_InitStruct = {0}; + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + /* Configure system clock */ + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + sys_config_systick(SYS_TICK_1_MS); + + /* configure GPIO Pin mux of SPI */ + SPI_PinConfg(SPI0, 0); + + /* configure SPI */ + SPI_DeInit(SPI0); + SPI_InitStruct.SPI_Mode = SPI_Mode_Master; + SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low; + SPI_InitStruct.SPI_CPHA = SPI_CPHA_Effective; + SPI_InitStruct.SPI_TxDataSize = SPI_TxDataSize_8b; + SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudratePrescaler_256; + SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB; + SPI_Init(SPI0, &SPI_InitStruct); + + /* Enable SPI */ + SPI_Enable(SPI0); + + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(SPI0_IRQn, SPIx_Handler, &irq_attr); + sys_enable_girq(); + + /* initial data */ + data_base++; + for(uint32_t i = 0; i < FRAME_LENGTH; i++) + { + g_tx_buf[i] = data_base+i; + g_rx_buf[i] = 0xA55A; + } + + // enable Interrupt TXNFUL + SPI_SetInterrupt(SPI0, SPI_STA_TXNFUL_Msk); + + while(1) + { + // a frame data send finished + if(frame_flag == 1) + { + data_base++; + // and initial array + for(uint32_t i = 0; i < FRAME_LENGTH; i++) + { + g_tx_buf[i] = data_base+i; + g_rx_buf[i] = 0xA55A; + } + // enter the next data transmission + frame_flag = 0; + SPI_Enable(SPI0); + SPI_SetInterrupt(SPI0, SPI_STA_TXNFUL_Msk); + } + } + + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave/.cproject b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave/.project b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave/Project.nuproject b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave/component.mk b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave/inc/isr.h b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave/inc/main.h b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave/readme.md b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/readme.md new file mode 100644 index 0000000..45c2ffb --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/readme.md @@ -0,0 +1,21 @@ +spi slave mode +--- + +This example is used to run the function of spi to transmit data in slave mode. + +## Hardware and Software environment + ++ This example runs on PEC930 devices. + +## How to use it ? + +### In order to make the program work, you must do the following: + ++ Open your preferred toolchain ++ Rebuild all files and load your image into target memory ++ Run the example + + * spi_clk -- p02 + * spi_do -- p03 + * spi_di -- p04 + * spi_cs -- p05 \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave/src/isr.c b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave/src/main.c b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/src/main.c new file mode 100644 index 0000000..dde6401 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/src/main.c @@ -0,0 +1,103 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= +void SPI_PinConfg(SPI_Type *spi, uint32_t io_sel) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + if(io_sel == 0) + { + /*----------------------------------- + * spi_clk -- p02 + * spi_do -- p03 + * spi_di -- p04 + * spi_cs -- p05 + * ---------------------------------*/ + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_02 | GPIO_Pin_03 |GPIO_Pin_04|GPIO_Pin_05; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_1; + GPIO_Init(GPIOA, &GPIO_InitStruct); + } + +} +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + uint32_t tx_data[10] = {0}; + uint32_t rx_data[10] = {0}; + + SPI_InitTypeDef SPI_InitStruct = {0}; + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + /* Configure system clock */ + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + /* set tx data */ + for(int i=0; i<10; i++) + { + tx_data[i] = 0xB1A1 + i*0x101; + } + + /* configure GPIO Pin mux of SPI */ + SPI_PinConfg(SPI0, 0); + + /* configure SPI */ + SPI_DeInit(SPI0); + SPI_InitStruct.SPI_Mode = SPI_Mode_Slave; + SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low; + SPI_InitStruct.SPI_CPHA = SPI_CPHA_Effective; + SPI_InitStruct.SPI_TxDataSize = SPI_TxDataSize_16b; + SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudratePrescaler_4; + SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB; + SPI_Init(SPI0, &SPI_InitStruct); + + /* Enable SPI */ + SPI_Enable(SPI0); + + while(1) + { + for(int i=0; i<10; i++) + { + /* SPI Slave Send data */ + SPI_SendData(SPI0, tx_data[i]); + while(SPI_GetFlagStatus(SPI0, SPI_STA_RXNEP_Msk) == 0); + rx_data[i] = SPI_ReceiveData(SPI0); + } + } + + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/.cproject b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/.project b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/Project.nuproject b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/component.mk b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/inc/isr.h b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/inc/main.h b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/readme.md b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/readme.md new file mode 100644 index 0000000..6f742ea --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/readme.md @@ -0,0 +1,21 @@ +spi slave Interrupt mode +--- + +This example is used to run the function of spi to transmit data in slave mode from interrupt. + +## Hardware and Software environment + ++ This example runs on PEC930 devices. + +## How to use it ? + +### In order to make the program work, you must do the following: + ++ Open your preferred toolchain ++ Rebuild all files and load your image into target memory ++ Run the example + + * spi_clk -- p02 + * spi_do -- p03 + * spi_di -- p04 + * spi_cs -- p05 \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/src/isr.c b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/src/main.c b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/src/main.c new file mode 100644 index 0000000..9dc3128 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/src/main.c @@ -0,0 +1,162 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= +#define FRAME_LENGTH 64 // Length of one frame of data +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static uint32_t g_tx_buf[FRAME_LENGTH] = {0}; +static uint32_t g_rx_buf[FRAME_LENGTH] = {0}; +uint16_t tx_cnt = 0; +uint16_t rx_cnt = 0; +uint16_t data_base = 0; +bool frame_flag = 0; +//============================================================================= +// Private Function Definition +//============================================================================= +void SPI_PinConfg(SPI_Type *spi, uint32_t io_sel) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + if(io_sel == 0) + { + /*----------------------------------- + * spi_clk -- p02 + * spi_do -- p03 + * spi_di -- p04 + * spi_cs -- p05 + * ---------------------------------*/ + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_02 | GPIO_Pin_03 |GPIO_Pin_04|GPIO_Pin_05; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_1; + GPIO_Init(GPIOA, &GPIO_InitStruct); + } + +} + +void SPI_Slave_IRQHandler(void) +{ + // send data and interrupt handler + if(SPI_GetFlagStatus(SPI0,SPI_STA_RXNEP_Msk) == 1 && frame_flag == 0) + { + // send data + SPI_SendData(SPI0, g_tx_buf[tx_cnt++]); + // The selected transmission word size is 8 bits + // and the received data requires forced conversion (uint8_t) + g_rx_buf[rx_cnt++] = (uint8_t)SPI_ReceiveData(SPI0); + if(tx_cnt >= FRAME_LENGTH) + { + // Read the last data + while(SPI_GetFlagStatus(SPI0, SPI_RXNEP_Flag) == 0); + g_rx_buf[rx_cnt++] = (uint8_t)SPI_ReceiveData(SPI0); + tx_cnt = 0; + rx_cnt = 0; + // Data transmission completed, and close SPI + SPI_SetInterruptDisable(SPI0, SPI_STA_RXNEP_Msk); + SPI_Disable(SPI0); + frame_flag = 1; + } + } + +} + +__INTERRUPT void SPIx_Handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); + + SPI_Slave_IRQHandler(); + + RESTORE_IRQ_CSR_CONTEXT(); + return; +} + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + SPI_InitTypeDef SPI_InitStruct = {0}; + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + /* Configure system clock */ + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + /* configure GPIO Pin mux of SPI */ + SPI_PinConfg(SPI0, 0); + + /* configure SPI */ + SPI_DeInit(SPI0); + SPI_InitStruct.SPI_Mode = SPI_Mode_Slave; + SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low; + SPI_InitStruct.SPI_CPHA = SPI_CPHA_Effective; + SPI_InitStruct.SPI_TxDataSize = SPI_TxDataSize_8b; + SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudratePrescaler_4; + SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB; + SPI_Init(SPI0, &SPI_InitStruct); + + /* Enable SPI */ + SPI_Enable(SPI0); + + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(SPI0_IRQn, SPIx_Handler, &irq_attr); + sys_enable_girq(); + + /* initial data */ + data_base++; + for(uint32_t i = 0; i < FRAME_LENGTH; i++) + { + g_tx_buf[i] = data_base+i; + g_rx_buf[i] = 0xA55A; + } + + SPI_SendData(SPI0, g_tx_buf[tx_cnt++]); + + SPI_SetInterrupt(SPI0, SPI_STA_RXNEP_Msk); // enable Interrupt TXNFUL + + while(1) + { + // a frame data send finished + if(frame_flag == 1) + { + data_base++; + // and initial array + for(uint32_t i = 0; i < FRAME_LENGTH; i++) + { + g_tx_buf[i] = data_base+i; + g_rx_buf[i] = 0xA55A; + } + // enter the next data transmission + frame_flag = 0; + SPI_Enable(SPI0); + SPI_SendData(SPI0, g_tx_buf[tx_cnt++]); + SPI_SetInterrupt(SPI0, SPI_STA_RXNEP_Msk); + } + } + + + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/.cproject b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/.project b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/Project.nuproject b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/component.mk b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/component.mk new file mode 100644 index 0000000..e5e2310 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/component.mk @@ -0,0 +1,17 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + +LIBS += -L$(srctree)/Drivers/PEC930 -lSysDev_PEC930 + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/image/pec930_SW_unlock_ICE_time_slot_resp.jpg b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/image/pec930_SW_unlock_ICE_time_slot_resp.jpg new file mode 100644 index 0000000..1ec58cd Binary files /dev/null and b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/image/pec930_SW_unlock_ICE_time_slot_resp.jpg differ diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/image/pec930_unlock_ice_dut_resp.png b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/image/pec930_unlock_ice_dut_resp.png new file mode 100644 index 0000000..ee5d0a3 Binary files /dev/null and b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/image/pec930_unlock_ice_dut_resp.png differ diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/image/pec930_unlock_ice_waveform.jpg b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/image/pec930_unlock_ice_waveform.jpg new file mode 100644 index 0000000..d103c84 Binary files /dev/null and b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/image/pec930_unlock_ice_waveform.jpg differ diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/image/pec930_unlock_ice_waveform_1xxKHz.png b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/image/pec930_unlock_ice_waveform_1xxKHz.png new file mode 100644 index 0000000..7a8882d Binary files /dev/null and b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/image/pec930_unlock_ice_waveform_1xxKHz.png differ diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/image/pec930_unlock_ice_waveform_with_resp.png b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/image/pec930_unlock_ice_waveform_with_resp.png new file mode 100644 index 0000000..a38efb2 Binary files /dev/null and b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/image/pec930_unlock_ice_waveform_with_resp.png differ diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/image/pec930_unlock_ice_working_time.png b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/image/pec930_unlock_ice_working_time.png new file mode 100644 index 0000000..7e8bcb1 Binary files /dev/null and b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/image/pec930_unlock_ice_working_time.png differ diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/inc/ice_unlock.h b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/inc/ice_unlock.h new file mode 100644 index 0000000..ad69063 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/inc/ice_unlock.h @@ -0,0 +1,67 @@ +/** + * Copyright (c) 2025 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file ice_unlock.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2026/01/12 + * @license + * @description + */ + +#ifndef __ice_unlock_H_wHRIfKCc_lrgE_Hco5_sCMI_uyqVOtiS2itE__ +#define __ice_unlock_H_wHRIfKCc_lrgE_Hco5_sCMI_uyqVOtiS2itE__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "hal_device.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +/** + * \brief Detect the authentic key in ISR + * The authentic key are made up of the specific 2-PINs of GPIO module + * \return + * error code + */ +void ICP_ITDetectAuthKey(GPIO_Type *pDat_port, GPIO_PinTypeDef dat_pin); + +/** + * \brief The authentication procedure which enable debug mode or not + * + * \return + * error code + */ +void ICP_AuthDProcedure(void); + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/inc/isr.h b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/inc/main.h b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/inc/main.h new file mode 100644 index 0000000..abc0093 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/inc/main.h @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= +/** + * + NVR area + */ +#define FLASH_PROG_NVR_ADDR_START NVR_MEM_BASE + +// ignore the last sector (record flash paraments) of NVR +#define FLASH_PROG_NVR_ADDR_END (NVR_MEM_BASE + sizeof(NVR_MEM_Type) - FLASH_1_SECTOR_SIZE) +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/readme.md b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/readme.md new file mode 100644 index 0000000..bd49385 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/readme.md @@ -0,0 +1,132 @@ +sys_ice_unlock_lib +--- + +This project is used to implement `Unlock-ICE` mechanism with the specific external device +> The system clock of the DUT is `60 MHz` + +## Behavior of this example + ++ Select the target I/O Pins + + - Use the ICE I/O Pins + + ```c + // at main.c + #define CONIFG_USE_ICE_IO 1 + ``` + + - Use the customization I/O Pins + + ```c + // at main.c + #define CONIFG_USE_ICE_IO 0 + ... + // the target pin definitions + #define CONFIG_TCLK_PORT GPIOA + #define CONFIG_TCLK_PIN GPIO_Pin_00 + #define CONFIG_TCLK_IRQ GPIOA_IRQn + #define CONFIG_TMSC_PORT GPIOA + #define CONFIG_TMSC_PIN GPIO_Pin_01 + ``` + ++ Select an I/O pin (as Key event) to trigger Core-Procedure + > This key event will disable ICE I/O run-time and then ICE will disconnect with Host + >> User should be carefully + + ```c + /* Input Key I/O definitions (Wake-up Key when I/O wakup case) */ + #define CONFIG_GPIO_INPUT_PORTx GPIOA + #define CONFIG_GPIO_INPUT_PINx GPIO_Pin_03 + #define CONFIG_GPIO_INPUT_IRQn GPIOA_IRQn + ``` + ++ Log + + ``` + Jan 23 2026 10:57:17 + Demo to Unlcok-ICE + Button = PA3 + Wait event to unlock ICE ... <--- trigger key event and wait to receive signal + ``` + +## Conidtion + ++ Disable the ICE function with software detection + + - User should open the code section with compile option + + ``` + // at pec930_sdk/Drivers/PEC930/Device/src/Startup/startup.S + #if 1 + /* Disable/Enable ICE I/O */ + ... + + #endif + ``` + + - User modifies the `ICE_PIN_DIS tag (32-bits value and address: 0x00201C28)` of the SysInfo sector of NVR + > + when the value of **ICE_PIN_DIS tag (Address:0x0020-1C28)** is `0x00000000`, DUT will `LOCK ICE` function + > + when the value of **ICE_PIN_DIS tag (Address:0x0020-1C28)** is `0xFFFFFFFF`, DUT will `Un-LOCK ICE` function + ++ It uses the specific 2-PINs (`TCK/TMS Pins of cJTag`) to dedicatedly receive signals + > The specific 2-PINs `CAN NOT` be used as other usage + ++ User MUST add the specific APIs to their APP by self + > + `ICP_ITDetectAuthKey()` to detect the signals of `2-PINs` + > + `ICP_AuthDProcedure()` to handle the procedure of Unlock-ICE + + ++ Resource + - It uses code size about `514-Bytes` + > + `ICP_ITDetectAuthKey()` + > + `ICP_AuthDProcedure()` + + - Some variables (on SRAM) are about `60-Bytes` + +## Flow + ++ DUT uses input interrupt of a GPIO module to run-time receive signals + - Run-time check the signals are proprietary protocol or not (in ISR) + - DUT (receiver) latches the data signal when the `Falling-edge` of the clock signal + > The transmitter prepares data when `Rising-edge` of the clock signal + + - The transmitter should support programmable frequency (**20 ~ 200 KHz**) of output clock signal + > The DUT receiving performance is dependent on the complexity of user's appliecation + ++ When the external signals fit the specific waveform, DUT enters the `Unlock-ICE` process + + - The specific waveform + > Transmitter keeps clock/data signals **high** after the specific waveform + + ![unlock_ice_waveform](./image/pec930_unlock_ice_waveform.jpg) + + 1. An example of the transmitter outputs clock signal at `170 KHz` + > + The green line is clock signal + > + The orange line is data signal + + ![pec930_unlock_ice_waveform_1xxKHz](./image/pec930_unlock_ice_waveform_1xxKHz.png) + + - DUT modifies the sysinfo to `Unlock-ICE` + > It should reserve `512-Bytes` buffer to keep the original data of sysinfo + + - DUT destroys the main-erea of eFlash + + - DUT call the specific reset (e.g. reboot-latch) or be re-powered on by the external device + + ++ The DUT (receiver) responds the specific signal through TMS pin (**16-times Falling-edge**) to transmitter after `Unlock-ICE` process is done + > The frequency of response signal is about `25 KHz` (when the DUT system clock is `60 MHz`) + > ![pec930_unlock_ice_dut_resp](./image/pec930_unlock_ice_dut_resp.png) + + - Transmitter MUST change the I/O direction of the data signal to receive the response of the DUT (receiver) + > The sequence diagram is as below + > ![pec930_SW_unlock_ICE_time_slot_resp](./image/pec930_SW_unlock_ICE_time_slot_resp.jpg) + + - The duration of DUT (receiver) Unlock-ICE process will be less then `100 msec` (when the DUT system clock is `60 MHz`) + > As below: `35128/1M => 36 msec` + + ![pec930_unlock_ice_waveform_with_resp](./image/pec930_unlock_ice_waveform_with_resp.png) + + 1. The unlock-ICE-process spent about `35 msec` + + ![pec930_unlock_ice_working_time](./image/pec930_unlock_ice_working_time.png) diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/src/isr.c b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/src/main.c b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/src/main.c new file mode 100644 index 0000000..53c1f4b --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/src/main.c @@ -0,0 +1,174 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include +#include +#include "main.h" +#include "isr.h" + +#include "ice_unlock.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define CONIFG_USE_ICE_IO 0 + +#if defined(CONIFG_USE_ICE_IO) && (CONIFG_USE_ICE_IO) + #define CONFIG_TCLK_PORT GPIOB + #define CONFIG_TCLK_PIN GPIO_Pin_02 + #define CONFIG_TCLK_IRQ GPIOB_IRQn + #define CONFIG_TMSC_PORT GPIOB + #define CONFIG_TMSC_PIN GPIO_Pin_04 +#else + #define CONFIG_TCLK_PORT GPIOA + #define CONFIG_TCLK_PIN GPIO_Pin_00 + #define CONFIG_TCLK_IRQ GPIOA_IRQn + #define CONFIG_TMSC_PORT GPIOA + #define CONFIG_TMSC_PIN GPIO_Pin_01 +#endif + + +/* Input Key I/O definitions (Wake-up Key when I/O wakup case) */ +#define CONFIG_GPIO_INPUT_PORTx GPIOA +#define CONFIG_GPIO_INPUT_PINx GPIO_Pin_03 +#define CONFIG_GPIO_INPUT_IRQn GPIOA_IRQn + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static bool g_has_key_event = false; +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void GPIOx_Handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); + + // Button Pin + if( GPIO_GetITFlag(CONFIG_GPIO_INPUT_PORTx, CONFIG_GPIO_INPUT_PINx) ) + { + GPIO_ClearITFlag(CONFIG_GPIO_INPUT_PORTx, CONFIG_GPIO_INPUT_PINx); + + g_has_key_event = true; + } + + // ICE-CLK Pin + if( GPIO_GetITFlag(CONFIG_TCLK_PORT, CONFIG_TCLK_PIN) ) + { + GPIO_ClearITFlag(CONFIG_TCLK_PORT, CONFIG_TCLK_PIN); + + // ICE-Data Pin + ICP_ITDetectAuthKey(CONFIG_TMSC_PORT, CONFIG_TMSC_PIN); + } + + RESTORE_IRQ_CSR_CONTEXT(); + return; +} + +static void _Config_ButtonIO(void) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + msg(" Button = P%s%d\n", + (CONFIG_GPIO_INPUT_PORTx == GPIOA) ? "A" : "B", + 31ul - HAL_CLZ(CONFIG_GPIO_INPUT_PINx)); + + GPIO_InitStruct.GPIO_Pin = CONFIG_GPIO_INPUT_PINx; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN ; + GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_InitStruct.GPIO_ITInit.GPIO_Trigger = GPIO_Trigger_Level; + GPIO_InitStruct.GPIO_ITInit.GPIO_Polarity = GPIO_Polarity_Low_Fall; + GPIO_Init(CONFIG_GPIO_INPUT_PORTx, &GPIO_InitStruct); + + GPIO_ITEnable(CONFIG_GPIO_INPUT_PORTx, CONFIG_GPIO_INPUT_PINx); + + sys_irq_attr_t irq_attr = { .disable_vector = false, }; + + irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL; + irq_attr.level = SYS_IRQ_LEVEL_L; + irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN; + sys_register_IRQ(CONFIG_GPIO_INPUT_IRQn, GPIOx_Handler, &irq_attr); + return; +} + +static int _Config_ICE_IO(void) +{ + GPIO_InitTypeDef Init = {0}; + +#if defined(CONIFG_USE_ICE_IO) && (CONIFG_USE_ICE_IO) + SYSCFG_SetICEPin2NormalIO(true); +#endif + + Init.GPIO_Pin = CONFIG_TMSC_PIN; + Init.GPIO_Mode = GPIO_Mode_IN ; + Init.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_Init(CONFIG_TMSC_PORT , &Init); + + Init.GPIO_Pin = CONFIG_TCLK_PIN; + Init.GPIO_ITInit.GPIO_Trigger = GPIO_Trigger_Edge; + Init.GPIO_ITInit.GPIO_Polarity = GPIO_Polarity_Low_Fall; + GPIO_Init(CONFIG_TCLK_PORT , &Init); + + GPIO_ITEnable(CONFIG_TCLK_PORT, CONFIG_TCLK_PIN); + + sys_irq_attr_t irq_attr = { .disable_vector = false, }; + + irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL; + irq_attr.level = SYS_IRQ_LEVEL_M; + irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN; + sys_register_IRQ(CONFIG_TCLK_IRQ, GPIOx_Handler, &irq_attr); + + return 0; +} + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s %s\nDemo to Unlcok-ICE\n", __DATE__, __TIME__); + + _Config_ButtonIO(); + + g_has_key_event = false; + + while(1) + { + ICP_AuthDProcedure(); + + if( g_has_key_event == true ) + { + msg(" Wait event to unlock ICE ...\n"); + g_has_key_event = false; + _Config_ICE_IO(); + } + } + + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_mco/.cproject b/pec930_sdk-v1.0.1/Examples/system/sys_mco/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_mco/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_mco/.project b/pec930_sdk-v1.0.1/Examples/system/sys_mco/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_mco/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_mco/Project.nuproject b/pec930_sdk-v1.0.1/Examples/system/sys_mco/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_mco/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_mco/component.mk b/pec930_sdk-v1.0.1/Examples/system/sys_mco/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_mco/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_mco/inc/isr.h b/pec930_sdk-v1.0.1/Examples/system/sys_mco/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_mco/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_mco/inc/main.h b/pec930_sdk-v1.0.1/Examples/system/sys_mco/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_mco/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_mco/readme.md b/pec930_sdk-v1.0.1/Examples/system/sys_mco/readme.md new file mode 100644 index 0000000..f1f8d1e --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_mco/readme.md @@ -0,0 +1,33 @@ +system mco +--- + +This example is used to run system mco function. + +## Hardware and Software environment + ++ This example runs on PEC930 devices. + +## How to use it ? + +### In order to make the program work, you must do the following: + ++ Open your preferred toolchain ++ Rebuild all files and load your image into target memory ++ Run the example ++ GPIO Pin pa2 selection mco output mode ++ GPIO Pin pa14 selection mco output + +## Log +Use serial port(pa15) with baudrate 115200, 8bit, no parity check. + +``` +Sep 30 2025 09:28:41 +This is a demo to output MCO signal (SysCLK= 60000000) + Press bottun to change output type (PA2) + No Output + MCO output HSI + MCO output LSI + MCO output HSI-DIV + No Output + +``` \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_mco/src/isr.c b/pec930_sdk-v1.0.1/Examples/system/sys_mco/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_mco/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_mco/src/main.c b/pec930_sdk-v1.0.1/Examples/system/sys_mco/src/main.c new file mode 100644 index 0000000..a2ed8d6 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_mco/src/main.c @@ -0,0 +1,184 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_BUTTON_PORT GPIOA +#define CONFIG_BUTTON_PIN GPIO_Pin_02 +#define CONFIG_BUTTON_IRQ GPIOA_IRQn + + +#define CONFIG_MCO_PORT GPIOA +#define CONFIG_MCO_PIN GPIO_Pin_14 +#define CONFIG_MCO_AF GPIO_AF_6 + +typedef enum mco_out +{ + MCO_OUT_NONE = SYSCFG_MCOCR_MCOSEL_GND << SYSCFG_MCOCR_MCOSEL_Pos, + MCO_OUT_HSI = SYSCFG_MCOCR_MCOSEL_HSI << SYSCFG_MCOCR_MCOSEL_Pos, + MCO_OUT_HSE = SYSCFG_MCOCR_MCOSEL_HSE << SYSCFG_MCOCR_MCOSEL_Pos, + MCO_OUT_HSI_DIV = SYSCFG_MCOCR_MCOSEL_CLKDIV << SYSCFG_MCOCR_MCOSEL_Pos, + MCO_OUT_LSI = SYSCFG_MCOCR_MCOSEL_LSI << SYSCFG_MCOCR_MCOSEL_Pos, +} mco_out_t; + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= +typedef struct mco_attr +{ + mco_out_t out_type; + char description[64]; +} mco_attr_t; + + +static mco_attr_t g_mco_attr[] = +{ + { .out_type = MCO_OUT_NONE, .description = "No Output" }, + { .out_type = MCO_OUT_HSI, .description = "MCO output HSI" }, + { .out_type = MCO_OUT_LSI, .description = "MCO output LSI" }, + { .out_type = MCO_OUT_HSI_DIV, .description = "MCO output HSI-DIV" }, + +#if 0 + { .out_type = MCO_OUT_HSE, .description = "MCO output HSE" }, +#endif +}; +//============================================================================= +// Global Data Definition +//============================================================================= +static bool g_IsButtonPress = false; +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void GPIOx_Handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); + + if( GPIO_GetITFlag(CONFIG_BUTTON_PORT, CONFIG_BUTTON_PIN) ) + { + GPIO_ClearITFlag(CONFIG_BUTTON_PORT, CONFIG_BUTTON_PIN); + + g_IsButtonPress = true; + } + + RESTORE_IRQ_CSR_CONTEXT(); + return; +} + +static void _Config_Button(void) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.GPIO_Pin = CONFIG_BUTTON_PIN; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN ; + GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_InitStruct.GPIO_ITInit.GPIO_Trigger = GPIO_Trigger_Level; + GPIO_InitStruct.GPIO_ITInit.GPIO_Polarity = GPIO_Polarity_Low_Fall; + GPIO_Init(CONFIG_MCO_PORT , &GPIO_InitStruct); + + do { + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(CONFIG_BUTTON_IRQ, GPIOx_Handler, &irq_attr); + } while(0); + + /* Enable GPIO interrupt */ + GPIO_ITConfig(CONFIG_MCO_PORT, CONFIG_BUTTON_PIN, &GPIO_InitStruct.GPIO_ITInit); + GPIO_ITEnable(CONFIG_MCO_PORT, CONFIG_BUTTON_PIN); + + + return; +} + +static void _Config_MCO_IO(void) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.GPIO_Pin = CONFIG_MCO_PIN; + GPIO_InitStruct.GPIO_AF_Mode = CONFIG_MCO_AF; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + + GPIO_Init(CONFIG_MCO_PORT, &GPIO_InitStruct); + return; +} + + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + do{ /* Configure system clock */ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + #if 1 + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + #else + SysClkInit.ClkSource = SYSCFG_ClkSrc_FreqDiv; + SysClkInit.SysClk_Div = SYSCFG_SysClkDiv2; + #endif + SYSCFG_SysClkConfig(&SysClkInit); + } while(0); + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s %s\nThis is a demo to output MCO signal (SysCLK= %d)\n", + __DATE__, __TIME__, (int)sys_get_cpu_freq()); + + msg(" Press bottun to change output type (P%s%d)\n", + (CONFIG_BUTTON_PORT == GPIOA) ? "A" : "B", + (31 - HAL_CLZ(CONFIG_BUTTON_PIN))); + + g_IsButtonPress = false; + + SYSCFG->MCOCR_b.MCOSEL = SYSCFG_MCOCR_MCOSEL_GND; + SYSCFG->MCOCR_b.DivEn = 0; + SYSCFG->MCOCR_b.DivSel = 0; + SYSCFG->MCOCR_b.Divider = 1; + + _Config_Button(); + + _Config_MCO_IO(); + + while(1) + { + static int mco_index = 0; + + if( g_IsButtonPress == false ) + { + __NOP(); + continue; + } + + g_IsButtonPress = false; + + mco_index = (mco_index == (sizeof(g_mco_attr)/sizeof(g_mco_attr[0]))) + ? 0 : mco_index; + + SYSCFG->MCOCR_b.MCOSEL = (g_mco_attr[mco_index].out_type == MCO_OUT_HSI) ? SYSCFG_MCOCR_MCOSEL_HSI : + (g_mco_attr[mco_index].out_type == MCO_OUT_LSI) ? SYSCFG_MCOCR_MCOSEL_LSI : + (g_mco_attr[mco_index].out_type == MCO_OUT_HSI_DIV) ? SYSCFG_MCOCR_MCOSEL_CLKDIV : + SYSCFG_MCOCR_MCOSEL_GND; + + msg(" %s\n", g_mco_attr[mco_index].description); + + mco_index++; + } + + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/.cproject b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/.project b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/Project.nuproject b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/component.mk b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/inc/isr.h b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/inc/main.h b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/readme.md b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/readme.md new file mode 100644 index 0000000..6af3cb8 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/readme.md @@ -0,0 +1,210 @@ +sys_tick_swi +--- + +This example is used to configure ECLIC module +> + Support to register the proprietary ISR for specific requirement. +> + Support programmable IRQ-Level +>> reference `sys_irq_level_t` + +> + Support programmable IRQ-Priority +>> reference `sys_irq_priority_t` + + ++ Configure SWI (Software Interupt) level + > The default level of system timer is `SYS_IRQ_LEVEL_L` + + ```c + // at main.c + /** + * The defualt level of system timer is SYS_IRQ_LEVEL_L + * ps. SYS_IRQ_LEVEL_LL/ SYS_IRQ_LEVEL_L/ SYS_IRQ_LEVEL_M + */ + #define CONFIG_IRQ_SWI_LEVEL SYS_IRQ_LEVEL_L + ``` + + - Use `sys_register_IRQ()` to re-configure attributes of an interrupt + + ```c + sys_irq_attr_t irq_attr = { .disable_vector = false, }; + + irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL; + irq_attr.level = SYS_IRQ_LEVEL_L; + irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN; + sys_register_IRQ(SysTimer_IRQn, _mtim_handler, &irq_attr); + ``` + ++ This example use message (in ISR) to figure out the relation of Level/Priority of ECLIC + > Logging message in ISR is misbehavior + + - For logging message, the period of system tick MUST be more then `1-msec` + + ``` + // at main.c, + /* The period MUST be more then 1 msec */ + sys_config_systick(SYS_TICK_10_MS); + ``` + + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + ++ If SWI level is equal to system timer + >```c + > // at main.c + > #define CONFIG_IRQ_SWI_LEVEL SYS_IRQ_LEVEL_L + > + > #define CONFIG_IRQ_SWI_PRIORITY SYS_IRQ_PRIORITY_MIDDEN + > ``` + + - Priority is the same + + ``` + Feb 20 2025 12:42:39 + This is a demo projec to configure ECLIC (IRQ Level: SWI == SysTim, Priority: SWI == SysTim) + -> _mtim_handler 0-th <--- enter ISR of system timer + <- _mtim_handler <--- leave system timer + => _mswi_handler 1-th <--- enter ISR of SWI (wait for system timer finish) + <= _mswi_handler <--- leave SWI + -> _mtim_handler 1-th + <- _mtim_handler + => _mswi_handler 2-th + <= _mswi_handler + -> _mtim_handler 2-th + <- _mtim_handler + => _mswi_handler 3-th + <= _mswi_handler + -> _mtim_handler 3-th + <- _mtim_handler + => _mswi_handler 4-th + <= _mswi_handler + -> _mtim_handler 4-th + <- _mtim_handler + => _mswi_handler 5-th + <= _mswi_handler + done~~~ + ``` + + - If SWI priority is greater then system timer + + ``` + Feb 20 2025 12:40:04 + This is a demo projec to configure ECLIC (IRQ Level: SWI == SysTim, Priority: SWI > SysTim) + -> _mtim_handler 0-th <--- enter ISR of system timer + <- _mtim_handler <--- leave system timer + => _mswi_handler 1-th <--- enter ISR of SWI (wait for system timer finish) + <= _mswi_handler <--- leave SWI + -> _mtim_handler 1-th + <- _mtim_handler + => _mswi_handler 2-th + <= _mswi_handler + -> _mtim_handler 2-th + <- _mtim_handler + => _mswi_handler 3-th + <= _mswi_handler + -> _mtim_handler 3-th + <- _mtim_handler + => _mswi_handler 4-th + <= _mswi_handler + -> _mtim_handler 4-th + <- _mtim_handler + => _mswi_handler 5-th + <= _mswi_handler + done~~~ + ``` + + - If SWI priority is lower then system timer + + ``` + Feb 20 2025 12:44:14 + This is a demo projec to configure ECLIC (IRQ Level: SWI == SysTim, Priority: SWI < SysTim) + -> _mtim_handler 0-th <--- enter ISR of system timer + <- _mtim_handler <--- leave system timer + => _mswi_handler 1-th <--- enter ISR of SWI (wait for system timer finish) + <= _mswi_handler <--- leave SWI + -> _mtim_handler 1-th + <- _mtim_handler + => _mswi_handler 2-th + <= _mswi_handler + -> _mtim_handler 2-th + <- _mtim_handler + => _mswi_handler 3-th + <= _mswi_handler + -> _mtim_handler 3-th + <- _mtim_handler + => _mswi_handler 4-th + <= _mswi_handler + -> _mtim_handler 4-th + <- _mtim_handler + => _mswi_handler 5-th + <= _mswi_handler + done~~~ + ``` + ++ If SWI level is greater than system timer + >```c + > // at main.c + > #define CONFIG_IRQ_SWI_LEVEL SYS_IRQ_LEVEL_M + > + > #define CONFIG_IRQ_SWI_PRIORITY SYS_IRQ_PRIORITY_MIDDEN + > ``` + + ``` + Feb 20 2025 12:45:53 + This is a demo projec to configure ECLIC (IRQ Level: SWI > SysTim, Priority: SWI == SysTim) + -> _mtim_handler 0-th <--- enter ISR of system timer + => _mswi_handler 1-th <--- Nested interrupt by SWI + <= _mswi_handler <--- leave SWI + <- _mtim_handler <--- leave system timer + -> _mtim_handler 1-th + => _mswi_handler 2-th + <= _mswi_handler + <- _mtim_handler + -> _mtim_handler 2-th + => _mswi_handler 3-th + <= _mswi_handler + <- _mtim_handler + -> _mtim_handler 3-th + => _mswi_handler 4-th + <= _mswi_handler + <- _mtim_handler + -> _mtim_handler 4-th + => _mswi_handler 5-th + <= _mswi_handler + <- _mtim_handler + done~~~ + ``` + ++ If SWI level is lower then system timer + >```c + > // at main.c + > #define CONFIG_IRQ_SWI_LEVEL SYS_IRQ_LEVEL_LL + > + > #define CONFIG_IRQ_SWI_PRIORITY SYS_IRQ_PRIORITY_MIDDEN + > ``` + + ``` + Feb 20 2025 12:47:11 + This is a demo projec to configure ECLIC (IRQ Level: SWI < SysTim, Priority: SWI == SysTim) + -> _mtim_handler 0-th <--- enter ISR of system timer + <- _mtim_handler <--- leave system timer + => _mswi_handler 1-th <--- enter ISR of SWI (wait for system timer finish) + <= _mswi_handler <--- leave SWI + -> _mtim_handler 1-th + <- _mtim_handler + => _mswi_handler 2-th + <= _mswi_handler + -> _mtim_handler 2-th + <- _mtim_handler + => _mswi_handler 3-th + <= _mswi_handler + -> _mtim_handler 3-th + <- _mtim_handler + => _mswi_handler 4-th + <= _mswi_handler + -> _mtim_handler 4-th + <- _mtim_handler + => _mswi_handler 5-th + <= _mswi_handler + done~~~ + ``` diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/src/isr.c b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/src/main.c b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/src/main.c new file mode 100644 index 0000000..64bd704 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/src/main.c @@ -0,0 +1,142 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +/** + * The defualt level of system timer is SYS_IRQ_LEVEL_L + * + SYS_IRQ_LEVEL_LL + * + SYS_IRQ_LEVEL_L + * + SYS_IRQ_LEVEL_M + * + SYS_IRQ_LEVEL_H + * + SYS_IRQ_LEVEL_HH + */ +#define CONFIG_IRQ_SWI_LEVEL SYS_IRQ_LEVEL_L +#define CONFIG_LOOP_MAX 5 + +/** + * The default priority of system time is SYS_IRQ_PRIORITY_MIDDEN + * + SYS_IRQ_PRIORITY_LOW + * + SYS_IRQ_PRIORITY_MIDDEN + * + SYS_IRQ_PRIORITY_HIGH + */ +#define CONFIG_IRQ_SWI_PRIORITY SYS_IRQ_PRIORITY_HIGH + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static uint8_t g_irq_swi_level = CONFIG_IRQ_SWI_LEVEL; +static uint8_t g_irq_swi_priority = CONFIG_IRQ_SWI_PRIORITY; +static uint32_t g_mtim_cnt = 0; +static uint32_t g_swi_cnt = 0; +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void _mtim_handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); + + msg("-> %s %u-th\n", __func__, g_mtim_cnt); + + g_mtim_cnt++; + + sys_launch_swi(); + + // Reload Timer Interrupt + SysTick_Reload(g_SysTickPeriod); + + msg("<- %s\n", __func__); + + RESTORE_IRQ_CSR_CONTEXT(); + return; +} + +__INTERRUPT void _mswi_handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); + + g_swi_cnt++; + msg(" => %s %u-th\n", __func__, g_swi_cnt); + + sys_clear_swi(); + + msg(" <= %s\n", __func__); + + RESTORE_IRQ_CSR_CONTEXT(); + return; +} +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + sys_config_systick(SYS_TICK_10_MS); + + syslog_init(); + + info("%s %s\nThis is a demo projec to configure ECLIC " + "(IRQ Level: SWI %s SysTim, Priority: SWI %s SysTim)\n", + __DATE__, __TIME__, + (g_irq_swi_level < SYS_IRQ_LEVEL_L) ? "<" : + (g_irq_swi_level > SYS_IRQ_LEVEL_L) ? ">" : + "==", + (g_irq_swi_priority < SYS_IRQ_PRIORITY_MIDDEN) ? "<" : + (g_irq_swi_priority > SYS_IRQ_PRIORITY_MIDDEN) ? ">" : + "=="); + + do { /* Configure ECLIC interrupts */ + sys_irq_attr_t irq_attr = { .disable_vector = false, }; + + sys_disable_systick(); + + irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL; + irq_attr.level = SYS_IRQ_LEVEL_L; + irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN; + sys_register_IRQ(SysTimer_IRQn, _mtim_handler, &irq_attr); + + irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL; + irq_attr.level = g_irq_swi_level; + irq_attr.priority = g_irq_swi_priority; + sys_register_IRQ(SysSW_IRQn, _mswi_handler, &irq_attr); + + sys_enable_systick(); + } while(0); + + while( g_swi_cnt < CONFIG_LOOP_MAX ); + + sys_disable_systick(); + + msg("done~~~\n"); + + while(1) + { + __NOP(); + } + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_01/.cproject b/pec930_sdk-v1.0.1/Examples/template/JF_01/.cproject new file mode 100644 index 0000000..1a0019e --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_01/.cproject @@ -0,0 +1,294 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_01/.project b/pec930_sdk-v1.0.1/Examples/template/JF_01/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_01/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_01/Project.nuproject b/pec930_sdk-v1.0.1/Examples/template/JF_01/Project.nuproject new file mode 100644 index 0000000..0072223 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_01/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_01/component.mk b/pec930_sdk-v1.0.1/Examples/template/JF_01/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_01/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_01/inc/init.h b/pec930_sdk-v1.0.1/Examples/template/JF_01/inc/init.h new file mode 100644 index 0000000..6cf4d9f --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_01/inc/init.h @@ -0,0 +1,22 @@ +/* + * init.h + * + * Created on: 2025å¹´10月9æ—¥ + * Author: jim_liao + */ + +#ifndef INC_INIT_H_ +#define INC_INIT_H_ + +void SYS_Config(); +void gpio_config(); +void opa_config(); +void adc_config(); +void pwm_config(); +void pwm_set_duty(uint16_t ch1_val, uint16_t ch2_val, uint16_t ch3_val); +void pwm_enable(); +void pwm_disable(); +void pwm_brake(); +void uart_config(); +void UART_Send_Wait(UART_Type *pHUart, uint16_t value); +#endif /* INC_INIT_H_ */ diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_01/inc/isr.h b/pec930_sdk-v1.0.1/Examples/template/JF_01/inc/isr.h new file mode 100644 index 0000000..3c103a3 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_01/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +void isr_epwm_handle(void); +void isr_adc_handle(void); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_01/inc/main.h b/pec930_sdk-v1.0.1/Examples/template/JF_01/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_01/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_01/readme.md b/pec930_sdk-v1.0.1/Examples/template/JF_01/readme.md new file mode 100644 index 0000000..a718da5 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_01/readme.md @@ -0,0 +1,8 @@ +demo_project +--- + +This example is a demo project to descript `how to log message` + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_01/src/init.c b/pec930_sdk-v1.0.1/Examples/template/JF_01/src/init.c new file mode 100644 index 0000000..6d643e7 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_01/src/init.c @@ -0,0 +1,232 @@ +/* + * init.c + * + * Created on: 2025å¹´8月18æ—¥ + * Author: jim_liao + */ + +#include "main.h" +#include "isr.h" +#include "init.h" +#include "hal_device.h" + +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_OPA_PGA_GAIN OPAMP_PGAGain_5 + +unsigned long ADC0Sum = 0; +unsigned char k; + +#define HIRC_Freq 60000000 //Hz +#define CurrentLoopIsrFreq 100000 //Hz +#define PWM_PERIOD HIRC_Freq/CurrentLoopIsrFreq/2 +#define DEAD_TIME 200 //ns +#define DEAD_TIME_VALUE DEAD_TIME*0.06 +//============================================================================= +// Public Function Definition +//============================================================================= +void SYS_Config() +{ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + gpio_config(); + opa_config(); + adc_config(); + pwm_config(); + +} + +void gpio_config() +{ +//-----------------// +// PWM +//-----------------// + GPIO_InitTypeDef GPIO_InitStruct; + + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_00 | GPIO_Pin_01 | GPIO_Pin_02 | \ + GPIO_Pin_03 | GPIO_Pin_04 | GPIO_Pin_05; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_6; + GPIO_Init(GPIOA, &GPIO_InitStruct); +//-----------------// +// UART +// PA15:TX PB0:RX +//-----------------// + GPIO_InitTypeDef GPIOA_InitUart; + GPIOA_InitUart.GPIO_Pin = GPIO_Pin_15; + GPIOA_InitUart.GPIO_Mode = GPIO_Mode_AF; + GPIOA_InitUart.GPIO_AF_Mode = GPIO_AF_1; + GPIO_Init(GPIOA, &GPIOA_InitUart); + + GPIO_InitTypeDef GPIOB_InitUart; + GPIOB_InitUart.GPIO_Pin = GPIO_Pin_00; + GPIOB_InitUart.GPIO_Mode = GPIO_Mode_AF; + GPIOB_InitUart.GPIO_AF_Mode = GPIO_AF_1; + GPIO_Init(GPIOB, &GPIOB_InitUart); +//-----------------// +// ADC +// PA12/13/14:OVP/OTP/CMD +//-----------------// + GPIO_InitTypeDef GPIO_InitADC; + GPIO_InitADC.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12 | GPIO_Pin_13; + GPIO_InitADC.GPIO_Mode = GPIO_Mode_ANAL; + GPIO_Init(GPIOA, &GPIO_InitADC); +#if 1 +//-----------------// +// test +//-----------------// +// GPIO_InitStruct.GPIO_Pin = GPIO_Pin_06 | GPIO_Pin_07; + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_06; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; + GPIO_Init(GPIOA, &GPIO_InitStruct); +#endif +} + +void opa_config(void) +{ + OPAMP_InitTypeDef opa_init = {0}; + + opa_init.OPAMP_VinP = OPAMP_VinP_IO; + opa_init.OPAMP_VinM = OPAMP_VinM_GND; + opa_init.OPAMP_Gain = CONFIG_OPA_PGA_GAIN; + + OPAMP_Init(OPAMP0, &opa_init); +// OPAMP_Init(OPAMP1, &opa_init); + + OPAMP_Enable(OPAMP0); +// OPAMP_Enable(OPAMP1); +} + + + +void adc_config(void) +{ + + ADC_InitTypeDef init = {0}; + ADC_StructInit(&init); + +//-----------------// +// set +//-----------------// + ADC_InitTypeDef init1 = {0}; + ADC_StructInit(&init1); + init1.SelChannels = ADC_Channel_00 | ADC_Channel_04 | ADC_Channel_05 |ADC_Channel_06 |ADC_Channel_07; + init1.ClkPrescaler = ADC_ClkDiv_4; + init1.DataAlign = ADC_DataAlign_Right; + init1.Mode = ADC_Mode_Scan; + ADC_Init(ADC0, &init1); + + ADC_ExtTrigConfig(ADC0,ADC_ExtTrigSource_EPWM_CH2R,ADC_ExtTrigMode_Enable); + + +#if 0 + { /* Configure TIM interrupts */ + sys_irq_attr_t irq_attr = { .disable_vector = false, }; + + irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL; + irq_attr.level = SYS_IRQ_LEVEL_H; + irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN; + sys_register_IRQ(ADC0_IRQn, isr_adc_handle, &irq_attr); + ADC0->CON0_b.INT_EN = 1; + } +#endif +} + + +void pwm_config() +{ + TIM_OCInitTypeDef TIM_OCInitStruct; + TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; + + { /* Configure TIM interrupts */ + sys_irq_attr_t irq_attr = { .disable_vector = false, }; + + irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL; + irq_attr.level = SYS_IRQ_LEVEL_H; + irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN; + sys_register_IRQ(EPWM_IRQn, isr_epwm_handle, &irq_attr); + } + + TIM_DeInit(EPWM); + + TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct); + TIM_TimeBaseInitStruct.TIM_Prescaler = 0; + TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_CenterAligned1; + TIM_TimeBaseInitStruct.TIM_Period = PWM_PERIOD-1; + TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_Div1; + TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; + TIM_TimeBaseInit(EPWM, &TIM_TimeBaseInitStruct); + + TIM_ARRPreloadConfig(EPWM,ENABLE); + + TIM_OCStructInit(&TIM_OCInitStruct); + TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; + TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Disable; + TIM_OCInitStruct.TIM_Pulse = 0; + TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; + TIM_OCInitStruct.TIM_OCIdleState = TIM_OCIdleState_Reset; + TIM_OCInitStruct.TIM_Pulse = 1; + + TIM_OCInitStruct.TIM_OutputNState = TIM_OutputNState_Disable; + TIM_OCInitStruct.TIM_OCNPolarity = TIM_OCPolarity_High; + TIM_OC1Init(EPWM, &TIM_OCInitStruct); + + TIM_OCInitStruct.TIM_Pulse = 1; + TIM_OC2Init(EPWM, &TIM_OCInitStruct); + + + + { /* Automatic Output enable, Break, dead time and lock configuration */ + TIM_BDTRInitTypeDef bdtr_init = {0}; + bdtr_init.TIM_LOCKLevel = TIM_LockLevel_OFF; + bdtr_init.TIM_DeadTime = DEAD_TIME_VALUE; + + TIM_BDTRConfig(EPWM, &bdtr_init); + } + + EPWM->DIER |= 0x1000; //under flow + __enable_irq(); + TIM_Cmd(EPWM, ENABLE); + TIM_CtrlPWMOutputs(EPWM,ENABLE); + +} + +void pwm_set_duty(uint16_t ch1_val, uint16_t ch2_val, uint16_t ch3_val) +{ + EPWM->CCR1 = ch1_val; + EPWM->CCR2 = ch2_val; + EPWM->CCR3 = ch3_val; + return; +} +void pwm_enable() +{ + REG_SET_BITS(EPWM->CCER, TIM_CCER_CC1E_Msk | TIM_CCER_CC1NE_Msk | \ + TIM_CCER_CC2E_Msk) ; +// | TIM_CCER_CC2NE_Msk | \ +// TIM_CCER_CC3E_Msk | TIM_CCER_CC3NE_Msk); + return; +} + + + +void uart_config() +{ + UART_InitTypeDef uart_init = {0}; + uart_init.BaudRate = 115200; + uart_init.WordLength = UART_WordLength_8b; + uart_init.StopBits = UART_StopBits_1; + uart_init.Parity = UART_Parity_No; + uart_init.Mode = UART_Mode_TxRx; + UART_Init(UART0, &uart_init); + UART_Start(UART0); +} + +void UART_Send_Wait(UART_Type *pHUart, uint16_t value) +{ + UART_SendData(pHUart,value); + UART_WaitTxFifoEmpty(pHUart); +} diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_01/src/isr.c b/pec930_sdk-v1.0.1/Examples/template/JF_01/src/isr.c new file mode 100644 index 0000000..c5ea2bc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_01/src/isr.c @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#include "main.h" +#include "isr.h" +#include "init.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +long ADC_DATA[10]; +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +__INTERRUPT void isr_epwm_handle(void) +{ + + if((EPWM->SR&0x20000) ==0x20000) + { + TIM_ClearITPendingBit(EPWM, 0x20000); + ADC_DATA[0] = ADC0->DAT4_b.DATA; + ADC_DATA[1] = ADC0->DAT5_b.DATA; + ADC_DATA[2] = ADC0->DAT6_b.DATA; + ADC_DATA[3] = ADC0->DAT7_b.DATA; + pwm_enable(); + pwm_set_duty(100,200,0); + GPIO_TogglePin(GPIOA, GPIO_Pin_06); + + } + +} + + + diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_01/src/main.c b/pec930_sdk-v1.0.1/Examples/template/JF_01/src/main.c new file mode 100644 index 0000000..9dba9ba --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_01/src/main.c @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +#include "init.h" +#include "hal_tim.h" +#include "hal_gpio.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + + SYS_Config(); + + while(1) + { + + } +} + + diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02/.cproject b/pec930_sdk-v1.0.1/Examples/template/JF_02/.cproject new file mode 100644 index 0000000..1a0019e --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02/.cproject @@ -0,0 +1,294 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02/.project b/pec930_sdk-v1.0.1/Examples/template/JF_02/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02/Project.nuproject b/pec930_sdk-v1.0.1/Examples/template/JF_02/Project.nuproject new file mode 100644 index 0000000..0072223 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02/component.mk b/pec930_sdk-v1.0.1/Examples/template/JF_02/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02/inc/init.h b/pec930_sdk-v1.0.1/Examples/template/JF_02/inc/init.h new file mode 100644 index 0000000..6cf4d9f --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02/inc/init.h @@ -0,0 +1,22 @@ +/* + * init.h + * + * Created on: 2025å¹´10月9æ—¥ + * Author: jim_liao + */ + +#ifndef INC_INIT_H_ +#define INC_INIT_H_ + +void SYS_Config(); +void gpio_config(); +void opa_config(); +void adc_config(); +void pwm_config(); +void pwm_set_duty(uint16_t ch1_val, uint16_t ch2_val, uint16_t ch3_val); +void pwm_enable(); +void pwm_disable(); +void pwm_brake(); +void uart_config(); +void UART_Send_Wait(UART_Type *pHUart, uint16_t value); +#endif /* INC_INIT_H_ */ diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02/inc/isr.h b/pec930_sdk-v1.0.1/Examples/template/JF_02/inc/isr.h new file mode 100644 index 0000000..3c103a3 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +void isr_epwm_handle(void); +void isr_adc_handle(void); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02/inc/main.h b/pec930_sdk-v1.0.1/Examples/template/JF_02/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02/readme.md b/pec930_sdk-v1.0.1/Examples/template/JF_02/readme.md new file mode 100644 index 0000000..a718da5 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02/readme.md @@ -0,0 +1,8 @@ +demo_project +--- + +This example is a demo project to descript `how to log message` + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02/src/init.c b/pec930_sdk-v1.0.1/Examples/template/JF_02/src/init.c new file mode 100644 index 0000000..4c12025 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02/src/init.c @@ -0,0 +1,234 @@ +/* + * init.c + * + * Created on: 2025å¹´8月18æ—¥ + * Author: jim_liao + */ + +#include "main.h" +#include "isr.h" +#include "init.h" +#include "hal_device.h" + +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_OPA_PGA_GAIN OPAMP_PGAGain_5 + +unsigned long ADC0Sum = 0; +unsigned char k; + +#define HIRC_Freq 60000000 //Hz +#define CurrentLoopIsrFreq 24000 //Hz +#define PWM_PERIOD HIRC_Freq/CurrentLoopIsrFreq/2 +#define DEAD_TIME 200 //ns +#define DEAD_TIME_VALUE DEAD_TIME*0.06 +//============================================================================= +// Public Function Definition +//============================================================================= +void SYS_Config() +{ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + sys_config_systick(SYS_TICK_1_MS); + + gpio_config(); + opa_config(); + adc_config(); + pwm_config(); + uart_config(); + +} + +void gpio_config() +{ +//-----------------// +// PWM +//-----------------// + GPIO_InitTypeDef GPIO_InitStruct; + + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_00 | GPIO_Pin_01 | GPIO_Pin_02 | \ + GPIO_Pin_03 | GPIO_Pin_04 | GPIO_Pin_05; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_6; + GPIO_Init(GPIOA, &GPIO_InitStruct); +//-----------------// +// UART +// PA15:TX PB0:RX +//-----------------// + GPIO_InitTypeDef GPIOA_InitUart; + GPIOA_InitUart.GPIO_Pin = GPIO_Pin_15; + GPIOA_InitUart.GPIO_Mode = GPIO_Mode_AF; + GPIOA_InitUart.GPIO_AF_Mode = GPIO_AF_1; + GPIO_Init(GPIOA, &GPIOA_InitUart); + + GPIO_InitTypeDef GPIOB_InitUart; + GPIOB_InitUart.GPIO_Pin = GPIO_Pin_00; + GPIOB_InitUart.GPIO_Mode = GPIO_Mode_AF; + GPIOB_InitUart.GPIO_AF_Mode = GPIO_AF_1; + GPIO_Init(GPIOB, &GPIOB_InitUart); +//-----------------// +// ADC +// PA12/13/14:OVP/OTP/CMD +//-----------------// + GPIO_InitTypeDef GPIO_InitADC; + GPIO_InitADC.GPIO_Pin = GPIO_Pin_06 | GPIO_Pin_12; + GPIO_InitADC.GPIO_Mode = GPIO_Mode_ANAL; + GPIO_Init(GPIOA, &GPIO_InitADC); +#if 0 +//-----------------// +// test +//-----------------// +// GPIO_InitStruct.GPIO_Pin = GPIO_Pin_06 | GPIO_Pin_07; + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_06; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; + GPIO_Init(GPIOA, &GPIO_InitStruct); +#endif +} + +void opa_config(void) +{ + OPAMP_InitTypeDef opa_init = {0}; + + opa_init.OPAMP_VinP = OPAMP_VinP_IO; + opa_init.OPAMP_VinM = OPAMP_VinM_GND; + opa_init.OPAMP_Gain = CONFIG_OPA_PGA_GAIN; + + OPAMP_Init(OPAMP0, &opa_init); + OPAMP_Init(OPAMP1, &opa_init); + + OPAMP_Enable(OPAMP0); + OPAMP_Enable(OPAMP1); +} + + + +void adc_config(void) +{ + + ADC_InitTypeDef init = {0}; + ADC_StructInit(&init); + +//-----------------// +// set +//-----------------// + ADC_InitTypeDef init1 = {0}; + ADC_StructInit(&init1); + init1.SelChannels = ADC_Channel_06 |ADC_Channel_08; + init1.ClkPrescaler = ADC_ClkDiv_4; + init1.DataAlign = ADC_DataAlign_Right; + init1.Mode = ADC_Mode_Scan; + ADC_Init(ADC0, &init1); + + ADC_ExtTrigConfig(ADC0,ADC_ExtTrigSource_EPWM_CCR4_UP,ADC_ExtTrigMode_Enable); + ADC_ExtTrigConfig(ADC0,ADC_ExtTrigSource_EPWM_CCDR4_UP,ADC_ExtTrigMode_Enable); + + +#if 0 + { /* Configure TIM interrupts */ + sys_irq_attr_t irq_attr = { .disable_vector = false, }; + + irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL; + irq_attr.level = SYS_IRQ_LEVEL_H; + irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN; + sys_register_IRQ(ADC0_IRQn, isr_adc_handle, &irq_attr); + ADC0->CON0_b.INT_EN = 1; + } +#endif +} + + +void pwm_config() +{ + TIM_OCInitTypeDef TIM_OCInitStruct; + TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; + + { /* Configure TIM interrupts */ + sys_irq_attr_t irq_attr = { .disable_vector = false, }; + + irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL; + irq_attr.level = SYS_IRQ_LEVEL_H; + irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN; + sys_register_IRQ(EPWM_IRQn, isr_epwm_handle, &irq_attr); + } + + TIM_DeInit(EPWM); + + TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct); + TIM_TimeBaseInitStruct.TIM_Prescaler = 0; + TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_CenterAligned1; + TIM_TimeBaseInitStruct.TIM_Period = PWM_PERIOD-1; + TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_Div1; + TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; + TIM_TimeBaseInit(EPWM, &TIM_TimeBaseInitStruct); + + TIM_ARRPreloadConfig(EPWM,ENABLE); + + TIM_OCStructInit(&TIM_OCInitStruct); + TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; + TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Disable; + TIM_OCInitStruct.TIM_Pulse = 0; + TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; + TIM_OCInitStruct.TIM_OCIdleState = TIM_OCIdleState_Reset; + TIM_OCInitStruct.TIM_Pulse = 1; + + TIM_OCInitStruct.TIM_OutputNState = TIM_OutputNState_Disable; + TIM_OCInitStruct.TIM_OCNPolarity = TIM_OCPolarity_High; + TIM_OC1Init(EPWM, &TIM_OCInitStruct); + + TIM_OCInitStruct.TIM_Pulse = 1; + TIM_OC2Init(EPWM, &TIM_OCInitStruct); + + TIM_OCInitStruct.TIM_Pulse = 1; + TIM_OC3Init(EPWM, &TIM_OCInitStruct); + + { /* Automatic Output enable, Break, dead time and lock configuration */ + TIM_BDTRInitTypeDef bdtr_init = {0}; + bdtr_init.TIM_LOCKLevel = TIM_LockLevel_OFF; + bdtr_init.TIM_DeadTime = DEAD_TIME_VALUE; + + TIM_BDTRConfig(EPWM, &bdtr_init); + } + + EPWM->DIER |= 0x1000; //under flow + __enable_irq(); + TIM_Cmd(EPWM, ENABLE); + TIM_CtrlPWMOutputs(EPWM,ENABLE); + +} + +void pwm_set_duty(uint16_t ch1_val, uint16_t ch2_val, uint16_t ch3_val) +{ + EPWM->CCR1 = ch1_val; + EPWM->CCR2 = ch2_val; + EPWM->CCR3 = ch3_val; + return; +} +void pwm_enable() +{ + REG_SET_BITS(EPWM->CCER, TIM_CCER_CC1E_Msk | TIM_CCER_CC1NE_Msk | \ + TIM_CCER_CC2E_Msk | TIM_CCER_CC2NE_Msk | \ + TIM_CCER_CC3E_Msk | TIM_CCER_CC3NE_Msk); + return; +} + + + +void uart_config() +{ + UART_InitTypeDef uart_init = {0}; + uart_init.BaudRate = 115200; + uart_init.WordLength = UART_WordLength_8b; + uart_init.StopBits = UART_StopBits_1; + uart_init.Parity = UART_Parity_No; + uart_init.Mode = UART_Mode_TxRx; + UART_Init(UART0, &uart_init); + UART_Start(UART0); +} + +void UART_Send_Wait(UART_Type *pHUart, uint16_t value) +{ + UART_SendData(pHUart,value); + UART_WaitTxFifoEmpty(pHUart); +} diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02/src/isr.c b/pec930_sdk-v1.0.1/Examples/template/JF_02/src/isr.c new file mode 100644 index 0000000..bc566c4 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02/src/isr.c @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#include "main.h" +#include "isr.h" +#include "init.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +long ADC_DATA[10]; +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +__INTERRUPT void isr_epwm_handle(void) +{ + + if((EPWM->SR&0x20000) ==0x20000) + { + TIM_ClearITPendingBit(EPWM, 0x20000); + EPWM->CCR4 = 200; + EPWM->CCDR4 = 100; + ADC_DATA[0] = ADC0->DAT6_b.DATA; + ADC_DATA[1] = ADC0->DAT8_b.DATA; + + pwm_enable(); + +// GPIO_TogglePin(GPIOA, GPIO_Pin_06); + + } + +} + + + diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02/src/main.c b/pec930_sdk-v1.0.1/Examples/template/JF_02/src/main.c new file mode 100644 index 0000000..5ffb956 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02/src/main.c @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +#include "init.h" +#include "hal_tim.h" +#include "hal_gpio.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + + SYS_Config(); + + info("This is a demo project: JF_02\n"); + + uint32_t timer = sys_get_tick(); + + while(1) + { + if (sys_get_tick() - timer >= 1000) + { + msg("%d tick\n", sys_get_tick()); + timer = sys_get_tick(); + } + + pwm_set_duty(100,200,500); + } + +} + + diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/.clang-format b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/.clang-format new file mode 100644 index 0000000..2e9eca0 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/.clang-format @@ -0,0 +1,52 @@ +#Generated from Visual Studio settings +--- +BasedOnStyle: webkit +BraceWrapping: + BeforeCatch: true + BeforeElse: true + AfterClass: true + AfterFunction: true + AfterControlStatement: true + AfterEnum: true + AfterNamespace: true + AfterObjCDeclaration: true + AfterStruct: true + AfterUnion: true + AfterExternBlock: true +ColumnLimit: 80 +BreakBeforeBraces: Custom +NamespaceIndentation: All +TabWidth: 4 +IndentCaseLabels: true +AlignAfterOpenBracket: Align +PointerAlignment: Right +AlignOperands: true +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortLoopsOnASingleLine: true +AllowShortIfStatementsOnASingleLine: true +BinPackArguments: true +BinPackParameters: true +BreakBeforeBinaryOperators: All +BreakBeforeTernaryOperators: false +BreakAfterJavaFieldAnnotations: true +AlignTrailingComments: true +BreakConstructorInitializers: AfterColon +AlignConsecutiveMacros: + Enabled: true + AcrossEmptyLines: true + AcrossComments: true +AlignArrayOfStructures: Right +AlignConsecutiveAssignments: + Enabled: true + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: true + PadOperators: true +AlignConsecutiveBitFields: + Enabled: true + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: true + PadOperators: true +AlignEscapedNewlines: Right +... diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/.cproject b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/.cproject new file mode 100644 index 0000000..1a0019e --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/.cproject @@ -0,0 +1,294 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/.project b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/Project.nuproject b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/Project.nuproject new file mode 100644 index 0000000..0072223 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/component.mk b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/inc/init.h b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/inc/init.h new file mode 100644 index 0000000..7a1cae3 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/inc/init.h @@ -0,0 +1,24 @@ +/* + * init.h + * + * Created on: 2025å¹´10月9æ—¥ + * Author: jim_liao + */ + +#ifndef INC_INIT_H_ +#define INC_INIT_H_ + +#include "main.h" + +void SYS_Config(); +void gpio_config(); +void opa_config(); +void adc_config(); +void pwm_config(); +void pwm_set_duty(uint16_t ch1_val, uint16_t ch2_val, uint16_t ch3_val); +void pwm_enable(); +void pwm_disable(); +void pwm_brake(); +void uart_config(); +void UART_Send_Wait(UART_Type *pHUart, uint16_t value); +#endif /* INC_INIT_H_ */ diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/inc/isr.h b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/inc/isr.h new file mode 100644 index 0000000..8effcac --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/inc/isr.h @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "main.h" + //============================================================================= + // Constant Definition + //============================================================================= + + //============================================================================= + // Macro Definition + //============================================================================= + + //============================================================================= + // Structure Definition + //============================================================================= + + //============================================================================= + // Global Data Definition + //============================================================================= + extern volatile bool flag_24Khz_timer; + extern volatile bool stringComplete; + extern volatile char rxBuffer[128]; + //============================================================================= + // Private Function Definition + //============================================================================= + + //============================================================================= + // Public Function Definition + //============================================================================= + void isr_epwm_handle(void); + void isr_adc_handle(void); + void isr_uart0_handle(void); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/inc/main.h b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/inc/main.h new file mode 100644 index 0000000..f49530e --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "hal_device.h" +#include "syslog.h" + //============================================================================= + // Constant Definition + //============================================================================= + + //============================================================================= + // Macro Definition + //============================================================================= + + //============================================================================= + // Structure Definition + //============================================================================= + + //============================================================================= + // Global Data Definition + //============================================================================= + + //============================================================================= + // Private Function Definition + //============================================================================= + + //============================================================================= + // Public Function Definition + //============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/readme.md b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/readme.md new file mode 100644 index 0000000..a718da5 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/readme.md @@ -0,0 +1,8 @@ +demo_project +--- + +This example is a demo project to descript `how to log message` + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/src/init.c b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/src/init.c new file mode 100644 index 0000000..b46e367 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/src/init.c @@ -0,0 +1,258 @@ +/* + * init.c + * + * Created on: 2025å¹´8月18æ—¥ + * Author: jim_liao + */ +#include "init.h" +#include "hal_device.h" +#include "isr.h" +#include "main.h" + + +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_OPA_PGA_GAIN OPAMP_PGAGain_5 + +unsigned long ADC0Sum = 0; +unsigned char k; + +#define HIRC_Freq 60000000 // Hz +#define CurrentLoopIsrFreq 24000 // Hz +#define PWM_PERIOD HIRC_Freq / CurrentLoopIsrFreq +#define DEAD_TIME 200 // ns +#define DEAD_TIME_VALUE DEAD_TIME * 0.06 +//============================================================================= +// Public Function Definition +//============================================================================= +void SYS_Config() +{ + SYSCFG_ClkInitTypeDef SysClkInit = { 0 }; + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + sys_config_systick(SYS_TICK_1_MS); + + gpio_config(); + opa_config(); + adc_config(); + pwm_config(); + uart_config(); + + __enable_irq(); +} + +void gpio_config() +{ + //-----------------// + // PWM + //-----------------// + GPIO_InitTypeDef GPIO_InitStruct; + + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_00 | GPIO_Pin_01 | GPIO_Pin_02 + | GPIO_Pin_03 | GPIO_Pin_04 | GPIO_Pin_05; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_6; + GPIO_Init(GPIOA, &GPIO_InitStruct); + //-----------------// + // UART + // PB3:TX PB5:RX + //-----------------// + GPIO_InitTypeDef GPIOA_InitUart; + GPIOA_InitUart.GPIO_Pin = GPIO_Pin_03; + GPIOA_InitUart.GPIO_Mode = GPIO_Mode_AF; + GPIOA_InitUart.GPIO_AF_Mode = GPIO_AF_1; + GPIO_Init(GPIOB, &GPIOA_InitUart); + + GPIO_InitTypeDef GPIOB_InitUart; + GPIOB_InitUart.GPIO_Pin = GPIO_Pin_05; + GPIOB_InitUart.GPIO_Mode = GPIO_Mode_AF; + GPIOB_InitUart.GPIO_AF_Mode = GPIO_AF_1; + GPIO_Init(GPIOB, &GPIOB_InitUart); + //-----------------// + // ADC + // PA12/13/14:OVP/OTP/CMD + //-----------------// + GPIO_InitTypeDef GPIO_InitADC; + GPIO_InitADC.GPIO_Pin = GPIO_Pin_06 | GPIO_Pin_12; + GPIO_InitADC.GPIO_Mode = GPIO_Mode_ANAL; + GPIO_Init(GPIOA, &GPIO_InitADC); +#if 1 + //-----------------// + // test + //-----------------// + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; + GPIO_Init(GPIOA, &GPIO_InitStruct); +#endif +} + +void opa_config(void) +{ + OPAMP_InitTypeDef opa_init = { 0 }; + + opa_init.OPAMP_VinP = OPAMP_VinP_IO; + opa_init.OPAMP_VinM = OPAMP_VinM_GND; + opa_init.OPAMP_Gain = CONFIG_OPA_PGA_GAIN; + + OPAMP_Init(OPAMP0, &opa_init); + OPAMP_Init(OPAMP1, &opa_init); + + OPAMP_Enable(OPAMP0); + OPAMP_Enable(OPAMP1); +} + +void adc_config(void) +{ + + ADC_InitTypeDef init = { 0 }; + ADC_StructInit(&init); + + //-----------------// + // set + //-----------------// + ADC_InitTypeDef init1 = { 0 }; + ADC_StructInit(&init1); + init1.SelChannels = ADC_Channel_06 | ADC_Channel_08; + init1.ClkPrescaler = ADC_ClkDiv_4; + init1.DataAlign = ADC_DataAlign_Right; + init1.Mode = ADC_Mode_Scan; + ADC_Init(ADC0, &init1); + + ADC_ExtTrigConfig(ADC0, ADC_ExtTrigSource_EPWM_CCR4_UP, + ADC_ExtTrigMode_Enable); + ADC_ExtTrigConfig(ADC0, ADC_ExtTrigSource_EPWM_CCDR4_UP, + ADC_ExtTrigMode_Enable); + +#if 0 + { /* Configure TIM interrupts */ + sys_irq_attr_t irq_attr = { .disable_vector = false, }; + + irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL; + irq_attr.level = SYS_IRQ_LEVEL_H; + irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN; + sys_register_IRQ(ADC0_IRQn, isr_adc_handle, &irq_attr); + ADC0->CON0_b.INT_EN = 1; + } +#endif +} + +void pwm_config() +{ + TIM_OCInitTypeDef TIM_OCInitStruct; + TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; + + { /* Configure TIM interrupts */ + sys_irq_attr_t irq_attr = { + .disable_vector = false, + }; + + irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL; + irq_attr.level = SYS_IRQ_LEVEL_H; + irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN; + sys_register_IRQ(EPWM_IRQn, isr_epwm_handle, &irq_attr); + } + + TIM_DeInit(EPWM); + + TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct); + TIM_TimeBaseInitStruct.TIM_Prescaler = 0; + TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; + TIM_TimeBaseInitStruct.TIM_Period = PWM_PERIOD - 1; + TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_Div1; + TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; + TIM_TimeBaseInit(EPWM, &TIM_TimeBaseInitStruct); + + TIM_ARRPreloadConfig(EPWM, ENABLE); + + TIM_OCStructInit(&TIM_OCInitStruct); + TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; + TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Disable; + TIM_OCInitStruct.TIM_Pulse = 0; + TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; + TIM_OCInitStruct.TIM_OCIdleState = TIM_OCIdleState_Reset; + TIM_OCInitStruct.TIM_Pulse = 1; + + TIM_OCInitStruct.TIM_OutputNState = TIM_OutputNState_Disable; + TIM_OCInitStruct.TIM_OCNPolarity = TIM_OCPolarity_High; + TIM_OC1Init(EPWM, &TIM_OCInitStruct); + + TIM_OCInitStruct.TIM_Pulse = 1; + TIM_OC2Init(EPWM, &TIM_OCInitStruct); + + TIM_OCInitStruct.TIM_Pulse = 1; + TIM_OC3Init(EPWM, &TIM_OCInitStruct); + + { /* Automatic Output enable, Break, dead time and lock configuration */ + TIM_BDTRInitTypeDef bdtr_init = { 0 }; + bdtr_init.TIM_LOCKLevel = TIM_LockLevel_OFF; + bdtr_init.TIM_DeadTime = DEAD_TIME_VALUE; + + TIM_BDTRConfig(EPWM, &bdtr_init); + } + + EPWM->DIER |= 0x0800; // over flow + + // enable preload for CCR1, CCR2 and CCR3 + EPWM->CCMR1_OUTPUT_b.OC1PE = 1; + EPWM->CCMR1_OUTPUT_b.OC2PE = 1; + EPWM->CCMR2_OUTPUT_b.OC3PE = 1; + + TIM_Cmd(EPWM, ENABLE); + TIM_CtrlPWMOutputs(EPWM, ENABLE); +} + +void pwm_set_duty(uint16_t ch1_val, uint16_t ch2_val, uint16_t ch3_val) +{ + EPWM->CCR1 = ch1_val; + EPWM->CCR2 = ch2_val; + EPWM->CCR3 = ch3_val; + return; +} +void pwm_enable() +{ + REG_SET_BITS(EPWM->CCER, TIM_CCER_CC1E_Msk | TIM_CCER_CC1NE_Msk + | TIM_CCER_CC2E_Msk | TIM_CCER_CC2NE_Msk + | TIM_CCER_CC3E_Msk | TIM_CCER_CC3NE_Msk); + return; +} + +void pwm_disable() +{ + REG_CLR_BITS(EPWM->CCER, TIM_CCER_CC1E_Msk | TIM_CCER_CC1NE_Msk + | TIM_CCER_CC2E_Msk | TIM_CCER_CC2NE_Msk + | TIM_CCER_CC3E_Msk | TIM_CCER_CC3NE_Msk); + return; +} + +void uart_config() +{ + UART_InitTypeDef uart_init = { 0 }; + uart_init.BaudRate = 115200; + uart_init.WordLength = UART_WordLength_8b; + uart_init.StopBits = UART_StopBits_1; + uart_init.Parity = UART_Parity_No; + uart_init.Mode = UART_Mode_TxRx; + UART_Init(UART0, &uart_init); + UART_Start(UART0); + + UART_ITConfig(UART0, UART_FLAG_RXNE, ENABLE); + { /* Configure TIM interrupts */ + sys_irq_attr_t irq_attr = { + .disable_vector = false, + }; + + irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL; + irq_attr.level = SYS_IRQ_LEVEL_H; + irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN; + sys_register_IRQ(UART0_IRQn, isr_uart0_handle, &irq_attr); + } +} + +void UART_Send_Wait(UART_Type *pHUart, uint16_t value) +{ + UART_SendData(pHUart, value); + UART_WaitTxFifoEmpty(pHUart); +} diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/src/isr.c b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/src/isr.c new file mode 100644 index 0000000..21747e0 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/src/isr.c @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#include "isr.h" +#include "init.h" +#include "main.h" + + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= +#define RX_BUFFER_SIZE 128 +//============================================================================= +// Global Data Definition +//============================================================================= +long ADC_DATA[10]; +volatile bool flag_24Khz_timer = false; + +volatile char rxBuffer[RX_BUFFER_SIZE]; +volatile bool stringComplete = false; +volatile uint16_t rxIndex = 0; +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +__INTERRUPT void isr_epwm_handle(void) +{ + + if ((EPWM->SR & 0x10000) == 0x10000) + { + flag_24Khz_timer = true; + ADC_DATA[0] = ADC0->DAT6_b.DATA; + ADC_DATA[1] = ADC0->DAT8_b.DATA; + TIM_ClearITPendingBit(EPWM, 0x10000); // clear OVIF + } +} + +__INTERRUPT void isr_uart0_handle(void) +{ + if (UART_GetITStatus(UART0, UART_FLAG_RXNE) == 1) + { + char receivedChar = (char)UART_ReceiveData(UART0); + + if (receivedChar == '\n' || receivedChar == '\r') + { + if (rxIndex > 0) + { + rxBuffer[rxIndex] = '\0'; + stringComplete = true; + rxIndex = 0; + msg("Received: %s\n", rxBuffer); + } + } + else if (rxIndex < RX_BUFFER_SIZE - 1) + { + rxBuffer[rxIndex++] = receivedChar; + } + } +} diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/src/main.c b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/src/main.c new file mode 100644 index 0000000..75feb30 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/src/main.c @@ -0,0 +1,127 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ +#include + +#include "hal_gpio.h" +#include "hal_tim.h" +#include "init.h" +#include "isr.h" +#include "main.h" + + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= +#define PWM_TABLE_SIZE 64 +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +const uint16_t pwm_table[PWM_TABLE_SIZE] + = { 1250, 1372, 1493, 1612, 1728, 1839, 1944, 2042, 2133, 2216, 2289, + 2352, 2404, 2446, 2475, 2493, 2499, 2493, 2475, 2446, 2404, 2352, + 2289, 2216, 2133, 2042, 1944, 1839, 1728, 1612, 1493, 1372, 1250, + 1127, 1006, 887, 771, 660, 555, 457, 366, 283, 210, 147, + 95, 53, 24, 6, 0, 6, 24, 53, 95, 147, 210, + 283, 366, 457, 555, 660, 771, 887, 1006, 1127 }; +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +void uvw_set_duty(uint16_t base_idx) +{ + uint16_t iA = base_idx; + uint16_t iB = (base_idx + PWM_TABLE_SIZE / 3) % PWM_TABLE_SIZE; + uint16_t iC = (base_idx + 2 * PWM_TABLE_SIZE / 3) % PWM_TABLE_SIZE; + + EPWM->CCR1 = pwm_table[iA]; + EPWM->CCR2 = pwm_table[iB]; + EPWM->CCR3 = pwm_table[iC]; +} + +static void cmd_parser(char *data, uint32_t len) +{ + char cmd_reply[64] = { 0 }; + + // echo back received command + sprintf(cmd_reply, "Received command: %s\r\n", data); + msg("%s", cmd_reply); + + // parse commands + if (strncmp(data, "help", 4) == 0) + { + msg("Available commands:\r\n"); + msg(" help - Show this help message\r\n"); + msg(" fw_ver - Show firmware version\r\n"); + } + else if (strncmp(data, "fw_ver", 6) == 0) + { + msg("FW_VER_1.0.0_20260320\r\n"); + } + else if (strncmp(data, "pwm_enable", 10) == 0) + { + pwm_enable(); + msg("PWM enabled.\r\n"); + } + else if (strncmp(data, "pwm_disable", 11) == 0) + { + pwm_disable(); + msg("PWM disabled.\r\n"); + } + else + { + msg("Unknown command. Type 'help' for available commands.\r\n"); + } +} + +int main(void) +{ + uint16_t base_idx = 0; + uint32_t timer = sys_get_tick(); + + SYS_Config(); + info("This is a demo project: JF_02\n"); + uvw_set_duty(base_idx); + pwm_enable(); + + while (1) + { + if (stringComplete) + { + cmd_parser((char *)rxBuffer, strlen((char *)rxBuffer)); + stringComplete = false; + } + + if (sys_get_tick() - timer >= 1) + { + msg("%d tick\n", sys_get_tick()); + timer = sys_get_tick(); + } + + if (flag_24Khz_timer) + { + base_idx = (base_idx + 1) % PWM_TABLE_SIZE; + uvw_set_duty(base_idx); + flag_24Khz_timer = false; + } + } +} diff --git a/pec930_sdk-v1.0.1/Examples/template/demo_project/.cproject b/pec930_sdk-v1.0.1/Examples/template/demo_project/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/demo_project/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/template/demo_project/.project b/pec930_sdk-v1.0.1/Examples/template/demo_project/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/demo_project/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/template/demo_project/Project.nuproject b/pec930_sdk-v1.0.1/Examples/template/demo_project/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/demo_project/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/template/demo_project/component.mk b/pec930_sdk-v1.0.1/Examples/template/demo_project/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/demo_project/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/template/demo_project/inc/isr.h b/pec930_sdk-v1.0.1/Examples/template/demo_project/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/demo_project/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/template/demo_project/inc/main.h b/pec930_sdk-v1.0.1/Examples/template/demo_project/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/demo_project/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/template/demo_project/readme.md b/pec930_sdk-v1.0.1/Examples/template/demo_project/readme.md new file mode 100644 index 0000000..d4feae0 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/demo_project/readme.md @@ -0,0 +1,8 @@ +demo_project +--- + +This example is a demo project to descript `how to log message` + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. diff --git a/pec930_sdk-v1.0.1/Examples/template/demo_project/src/isr.c b/pec930_sdk-v1.0.1/Examples/template/demo_project/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/demo_project/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/template/demo_project/src/main.c b/pec930_sdk-v1.0.1/Examples/template/demo_project/src/main.c new file mode 100644 index 0000000..fc5e7da --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/demo_project/src/main.c @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= +uint32_t __FASTCODE fastcode_proc(void) +{ + log_color(SLOG_CYAN, "run at fast area: $pc= x%08X\n", (uint32_t)&fastcode_proc); + return 0; +} + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + SYSCFG_ClkInitTypeDef SysClkInit = { .ClkSource = SYSCFG_ClkSrc_HSI, }; + + #if 0 + SysClkInit.ClkSource = SYSCFG_ClkSrc_FreqDiv; + SysClkInit.SysClk_Div = SYSCFG_SysClkDiv2; + #endif + SYSCFG_SysClkConfig(&SysClkInit); + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("This is a demo project\n"); + msg("log debug message: $pc= x%08X\n", __get_pc()); + log_color(SLOG_GREEN, "color green\n"); + log_color(SLOG_YELLOW, "color yellow\n"); + + fastcode_proc(); + + while(1) + { + __NOP(); + } + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/.cproject b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/.project b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/Project.nuproject b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/component.mk b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/inc/isr.h b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/inc/main.h b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/readme.md b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/readme.md new file mode 100644 index 0000000..f654b30 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/readme.md @@ -0,0 +1,16 @@ +TIM_6StepOutput_project +--- + +This example is a demo project to TIM 6StepOutput + +## Hardware and Software environment + ++ This example runs on PEC930 devices. + +## Log + ++ PA0,PA1,PA2,PA3,PA4,PA5 output pwm ++ if Enable CCPC,Need to use COM to update CCER ++ if Disable CCPC,Can use software to update CCER + + diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/src/isr.c b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/src/main.c b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/src/main.c new file mode 100644 index 0000000..884edcd --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/src/main.c @@ -0,0 +1,233 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define COMPARE_PRELOAD 1 +#define TIMx EPWM +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= +void EPWM_6StepOutput_Sample(TIM_Type *tim,uint16_t Period,uint16_t Prescaler,uint8_t DeadTime); +void TIM1_PWM_6StepOutput_DeadTime_Break_Sample(void); +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + TIM1_PWM_6StepOutput_DeadTime_Break_Sample(); + while(1) + { + + } +} + +void EPWM_6StepOutput_Sample(TIM_Type *tim,uint16_t Period,uint16_t Prescaler,uint8_t DeadTime) +{ + GPIO_InitTypeDef GPIO_InitStruct; + TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; + TIM_OCInitTypeDef TIM_OCInitStructure; + TIM_BDTRInitTypeDef TIM_BDTRInitStructure; + + /* ToDo: configure GPIO Pin mux of EPWM */ + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_00 | GPIO_Pin_01 | GPIO_Pin_02 | GPIO_Pin_03 | GPIO_Pin_04 | GPIO_Pin_05; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_6; + GPIO_Init(GPIOA, &GPIO_InitStruct); + + TIM_DeInit(tim); + /* Time Base configuration */ + TIM_TimeBaseStructure.TIM_Prescaler = Prescaler; + TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1; + TIM_TimeBaseStructure.TIM_Period = Period; + TIM_TimeBaseStructure.TIM_ClockDivision = 0; + TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; + + TIM_TimeBaseInit(tim, &TIM_TimeBaseStructure); + + /* Channel 1, 2,3 and 4 Configuration in PWM mode */ + TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; + TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; + TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; + TIM_OCInitStructure.TIM_Pulse = 8000; + TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; + TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; + TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; + TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set; + + TIM_OC1Init(tim, &TIM_OCInitStructure); + + TIM_OCInitStructure.TIM_Pulse = 6000; + TIM_OC2Init(tim, &TIM_OCInitStructure); + + TIM_OCInitStructure.TIM_Pulse = 3000; + TIM_OC3Init(tim, &TIM_OCInitStructure); + + TIM_OC1PreloadConfig(tim, ENABLE); + TIM_OC2PreloadConfig(tim, ENABLE); + TIM_OC3PreloadConfig(tim, ENABLE); + + /* Automatic Output enable, Break, dead time and lock configuration*/ + TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; + TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; + TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LockLevel_OFF; + TIM_BDTRInitStructure.TIM_DeadTime = DeadTime; + TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable; + TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; + TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; + + TIM_BDTRConfig(tim, &TIM_BDTRInitStructure); + +#if (COMPARE_PRELOAD == 1) + TIM_CCPreloadControl(EPWM, ENABLE); +#endif + + /* TIM1 counter enable */ + TIM_Cmd(tim, ENABLE); + + /* Main Output Enable */ + TIM_CtrlPWMOutputs(tim, ENABLE); +} + +void TIM1_PWM_6StepOutput_DeadTime_Break_Sample(void) +{ + uint8_t Index = 0; + + uint8_t Step[6] = { + 6, 2, 3, 1, 5, 4 + }; + + uint32_t delay = 0; + + EPWM_6StepOutput_Sample(TIMx,10000 - 1, 24- 1 ,64); + + TIM_CCxCmd(TIMx, TIM_Channel_1, TIM_CCx_Disable); + TIM_CCxNCmd(TIMx, TIM_Channel_1, TIM_CCxN_Disable); + + TIM_CCxCmd(TIMx, TIM_Channel_2, TIM_CCx_Disable); + TIM_CCxNCmd(TIMx, TIM_Channel_2, TIM_CCxN_Disable); + + TIM_CCxCmd(TIMx, TIM_Channel_3, TIM_CCx_Disable); + TIM_CCxNCmd(TIMx, TIM_Channel_3, TIM_CCxN_Disable); + + while (1) + { + switch (Step[Index]) + { + case 6: + TIM_CCxCmd(TIMx, TIM_Channel_1, TIM_CCx_Disable); + TIM_CCxNCmd(TIMx, TIM_Channel_1, TIM_CCx_Disable); + + TIM_SetCompare2(TIMx, 5000 - 1); + TIM_CCxCmd(TIMx, TIM_Channel_2, TIM_CCx_Enable); + + TIM_SetCompare3(TIMx, 5000 - 1); + TIM_CCxNCmd(TIMx, TIM_Channel_3, TIM_CCxN_Enable); + break; + + case 2: + TIM_CCxCmd(TIMx, TIM_Channel_3, TIM_CCx_Disable); + TIM_CCxNCmd(TIMx, TIM_Channel_3, TIM_CCxN_Disable); + + TIM_SetCompare1(TIMx, 5000 - 1); + TIM_CCxNCmd(TIMx, TIM_Channel_1, TIM_CCxN_Enable); + + TIM_SetCompare2(TIMx, 5000 - 1); + TIM_CCxCmd(TIMx, TIM_Channel_2, TIM_CCx_Enable); + break; + + case 3: + TIM_CCxCmd(TIMx, TIM_Channel_2, TIM_CCx_Disable); + TIM_CCxNCmd(TIMx, TIM_Channel_2, TIM_CCxN_Disable); + + TIM_SetCompare1(TIMx, 5000 - 1); + TIM_CCxNCmd(TIMx, TIM_Channel_1, TIM_CCxN_Enable); + + TIM_SetCompare3(TIMx, 5000 - 1); + TIM_CCxCmd(TIMx, TIM_Channel_3, TIM_CCx_Enable); + break; + + case 1: + TIM_CCxCmd(TIMx, TIM_Channel_1, TIM_CCx_Disable); + TIM_CCxNCmd(TIMx, TIM_Channel_1, TIM_CCxN_Disable); + + TIM_SetCompare2(TIMx, 5000 - 1); + TIM_CCxNCmd(TIMx, TIM_Channel_2, TIM_CCxN_Enable); + + TIM_SetCompare3(TIMx, 5000 - 1); + TIM_CCxCmd(TIMx, TIM_Channel_3, TIM_CCx_Enable); + break; + + case 5: + TIM_CCxCmd(TIMx, TIM_Channel_3, TIM_CCx_Disable); + TIM_CCxNCmd(TIMx, TIM_Channel_3, TIM_CCxN_Disable); + + TIM_SetCompare1(TIMx, 5000 - 1); + TIM_CCxCmd(TIMx, TIM_Channel_1, TIM_CCx_Enable); + + TIM_SetCompare2(TIMx, 5000 - 1); + TIM_CCxNCmd(TIMx, TIM_Channel_2, TIM_CCxN_Enable); + break; + + case 4: + TIM_CCxCmd(TIMx, TIM_Channel_2, TIM_CCx_Disable); + TIM_CCxNCmd(TIMx, TIM_Channel_2, TIM_CCxN_Disable); + + TIM_SetCompare1(TIMx, 5000 - 1); + TIM_CCxCmd(TIMx, TIM_Channel_1, TIM_CCx_Enable); + + TIM_SetCompare3(TIMx, 5000 - 1); + TIM_CCxNCmd(TIMx, TIM_Channel_3, TIM_CCxN_Enable); + break; + + default: + TIM_CCxCmd(TIMx, TIM_Channel_1, TIM_CCx_Disable); + TIM_CCxNCmd(TIMx, TIM_Channel_1, TIM_CCxN_Disable); + + TIM_CCxCmd(TIMx, TIM_Channel_2, TIM_CCx_Disable); + TIM_CCxNCmd(TIMx, TIM_Channel_2, TIM_CCxN_Disable); + + TIM_CCxCmd(TIMx, TIM_Channel_3, TIM_CCx_Disable); + TIM_CCxNCmd(TIMx, TIM_Channel_3, TIM_CCxN_Disable); + break; + } + +#if (COMPARE_PRELOAD == 1) + TIM_GenerateEvent(TIMx,TIM_EventSource_COM); +#endif + + Index = (Index + 1) % 6; + + for(delay = 0; delay < 0x50000 ; delay++); + } +} diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/.cproject b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/.project b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/Project.nuproject b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/component.mk b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/inc/isr.h b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/inc/main.h b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/readme.md b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/readme.md new file mode 100644 index 0000000..dac906e --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/readme.md @@ -0,0 +1,14 @@ +TIM_inputCapture_project +--- + +This example is a demo project to TIM inputCapture + +## Hardware and Software environment + ++ This example runs on PEC930 devices. + +## Log + ++ Use channel 2 as the input capture channel ++ Obtain the count value in the interrupt and clear the flag bit + diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/src/isr.c b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/src/main.c b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/src/main.c new file mode 100644 index 0000000..22953e1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/src/main.c @@ -0,0 +1,139 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +#include "hal_tim.h" + +//============================================================================= +// Constant Definition +//============================================================================= +//#define CONFIG_USE_TIM2 +#define CONFIG_USE_EPWM + +#if defined(CONFIG_USE_TIM2) + #define TIMx TIM2 + #define CONFIG_IRQ_ID TIM2_IRQn +#elif defined(CONFIG_USE_EPWM) + #define TIMx EPWM + #define CONFIG_IRQ_ID EPWM_IRQn +#endif +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +uint16_t IC2ReadValue1 = 0, IC2ReadValue2 = 0; +uint16_t CaptureNumber = 0; +uint32_t Capture = 0; +uint32_t TIMFreq = 0; +uint32_t SystemClock = 48000000; +//============================================================================= +// Private Function Definition +//============================================================================= + +void TIMx_handler(void); + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure = {0}; + TIM_ICInitTypeDef TIM_ICInitStruct; + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + /* Configure system clock */ + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + /* configure GPIO Pin mux of TIM capture */ +#if defined(CONFIG_USE_TIM2) + /* SET TCAP1 -> PA15*/ + GPIO_PeriAFConfig(GPIOA,GPIO_Peri_TCAP1,GPIO_PeriAF_2); +#elif defined(CONFIG_USE_EPWM) + /* SET ECAP1 -> PA15*/ + GPIO_PeriAFConfig(GPIOA,GPIO_Peri_ECAP1,GPIO_PeriAF_2); +#endif + + /* configure TIM */ + TIM_DeInit(TIMx); + TIM_TimeBaseInit(TIMx,&TIM_TimeBaseStructure); + + TIM_ICInitStruct.TIM_Channel = TIM_Channel_2; + TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising; + TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI; + TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_Div1; + TIM_ICInitStruct.TIM_ICFilter = 0x3; + TIM_ICInit(TIMx, &TIM_ICInitStruct); + + /* Enable the CC2 Interrupt Request */ + TIM_ITConfig(TIMx, TIM_IT_CC2, ENABLE); + + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(CONFIG_IRQ_ID, TIMx_handler, &irq_attr); + sys_enable_girq(); + + /* Sets the tim Counter Register value */ + TIM_SetAutoreload(TIMx,0xFFFF); + + /* TIM enable counter */ + TIM_Cmd(TIMx, ENABLE); + while(1) + { + __NOP(); + } + return 0; +} + +__INTERRUPT void TIMx_handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); // Save CSRs + + if(TIM_GetITStatus(TIMx, TIM_IT_CC2) == SET) + { + /* Clear TIM3 Capture compare interrupt pending bit */ + TIM_ClearITPendingBit(TIMx, TIM_IT_CC2); + if(CaptureNumber == 0) + { + /* Get the Input Capture value */ + IC2ReadValue1 = TIM_GetCapture2(TIMx); + CaptureNumber = 1; + } + else if(CaptureNumber == 1) + { + IC2ReadValue2 = TIM_GetCapture2(TIMx); + + if (IC2ReadValue2 > IC2ReadValue1) + { + Capture = (IC2ReadValue2 - IC2ReadValue1); + } + else + { + Capture = ((0xFFFF - IC2ReadValue1) + IC2ReadValue2); + } + /* get frequency */ + TIMFreq = (uint32_t) SystemClock / Capture; + CaptureNumber = 0; + } + } + + RESTORE_IRQ_CSR_CONTEXT(); // Restore CSRs + return; +} diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/.cproject b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/.project b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/Project.nuproject b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/component.mk b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/inc/isr.h b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/inc/main.h b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/readme.md b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/readme.md new file mode 100644 index 0000000..137f044 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/readme.md @@ -0,0 +1,15 @@ +TIM_forceOutput_project +--- + +This example is a demo project to TIM forceOutput + +## Hardware and Software environment + ++ This example runs on PEC930 devices. + +## Log + ++ Enable force output and delay ++ Disable force output and delay ++ You can see PWM for SET GPIO(EPWM -> PA0 ,TIM2 -> PA2) + diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/src/isr.c b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/src/main.c b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/src/main.c new file mode 100644 index 0000000..a288985 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/src/main.c @@ -0,0 +1,92 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_USE_TIM2 +//#define CONFIG_USE_EPWM + +#if defined(CONFIG_USE_TIM2) + #define TIMx TIM2 + #define CONFIG_IRQ_ID TIM2_IRQn +#elif defined(CONFIG_USE_EPWM) + #define TIMx EPWM + #define CONFIG_IRQ_ID EPWM_IRQn +#endif +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +uint16_t delayCounter = 0; +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + /* Configure system clock */ + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + +#if defined(CONFIG_USE_TIM2) + GPIO_InitTypeDef GPIO_InitStruct; + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_02 ; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_5; + GPIO_Init(GPIOA, &GPIO_InitStruct); +#elif defined(CONFIG_USE_EPWM) + GPIO_InitTypeDef GPIO_InitStruct; + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_00 ; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_6; + GPIO_Init(GPIOA, &GPIO_InitStruct); +#endif + /* Resets the TIMx */ + TIM_DeInit(TIMx); + + TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure = {0}; + TIM_TimeBaseInit(TIMx,&TIM_TimeBaseStructure); + + /* TIM1 counter enable */ + TIM_Cmd(TIMx, ENABLE); + + /* Main Output Enable */ + TIM_CtrlPWMOutputs(TIMx, ENABLE); + while(1) + { + /* TIM_ForcedAction_Inactive*/ + for(delayCounter = 0; delayCounter < 0x1000;delayCounter++); + TIM_SelectOCxM(TIMx,TIM_Channel_1,TIM_ForcedAction_Inactive); + TIM_CCxCmd(TIMx,TIM_Channel_1,TIM_CCx_Enable); + + /* TIM_ForcedAction_Active*/ + for(delayCounter = 0; delayCounter < 0x1000;delayCounter++); + TIM_SelectOCxM(TIMx,TIM_Channel_1,TIM_ForcedAction_Active); + TIM_CCxCmd(TIMx,TIM_Channel_1,TIM_CCx_Enable); + } +} diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/.cproject b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/.project b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/Project.nuproject b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/component.mk b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/inc/isr.h b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/inc/main.h b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/readme.md b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/readme.md new file mode 100644 index 0000000..b450060 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/readme.md @@ -0,0 +1,17 @@ +tim_outputCompare_project +--- + +This example is a demo project to Compare output + +## Hardware and Software environment + ++ This example runs on PEC930 devices. + +## Log + ++ The output mode of channel 1 comparison is Active ++ The output mode of channel 1 comparison is Inactive ++ The output mode of channel 1 comparison is Toggle ++ PA6 indicates the start of counting ++ PA7 indicates the position of channel 2 marker + diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/src/isr.c b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/src/main.c b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/src/main.c new file mode 100644 index 0000000..43bc439 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/src/main.c @@ -0,0 +1,136 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_USE_TIM2 +//#define CONFIG_USE_EPWM + +#if defined(CONFIG_USE_TIM2) + #define TIMx TIM2 + #define CONFIG_IRQ_ID TIM2_IRQn +#elif defined(CONFIG_USE_EPWM) + #define TIMx EPWM + #define CONFIG_IRQ_ID EPWM_IRQn +#endif +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= +void TIMx_handler(void); +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + /* Configure system clock */ + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + /* configure GPIO Pin mux of PWM */ +#if defined(CONFIG_USE_TIM2) + GPIO_InitTypeDef GPIO_InitStruct; + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_02 | GPIO_Pin_03 | GPIO_Pin_04 | GPIO_Pin_05; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_5; + GPIO_Init(GPIOA, &GPIO_InitStruct); +#elif defined(CONFIG_USE_EPWM) + GPIO_InitTypeDef GPIO_InitStruct; + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_00 | GPIO_Pin_02 | GPIO_Pin_04; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_6; + GPIO_Init(GPIOA, &GPIO_InitStruct); +#endif + + /* configure GPIO Pin OUT of test flag */ + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_06 | GPIO_Pin_07; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; + GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* Resets the TIMx */ + TIM_DeInit(TIMx); + + /* Time Base configuration */ + TIM_TimeBaseStructure.TIM_Prescaler = 60 - 1; + TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; + TIM_TimeBaseStructure.TIM_Period = 1000 - 1; + TIM_TimeBaseStructure.TIM_ClockDivision = 0; + TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; + TIM_TimeBaseInit(TIMx, &TIM_TimeBaseStructure); + + TIM_SetCompare1(TIMx,800);//CH1 DUTY:80% + TIM_SelectOCxM(TIMx,TIM_Channel_1,TIM_OCMode_Active); + TIM_CCxCmd(TIMx,TIM_Channel_1,TIM_CCx_Enable); + + TIM_SetCompare2(TIMx,400);//CH2 DUTY:40% + TIM_SelectOCxM(TIMx,TIM_Channel_2,TIM_OCMode_Inactive); + TIM_CCxCmd(TIMx,TIM_Channel_2,TIM_CCx_Enable); + + TIM_SetCompare3(TIMx,250);//CH3 DUTY:25% + TIM_SelectOCxM(TIMx,TIM_Channel_3,TIM_OCMode_Toggle); + TIM_CCxCmd(TIMx,TIM_Channel_3,TIM_CCx_Enable); + + /* Enable the CC2 Interrupt Request */ + TIM_ITConfig(TIMx, TIM_IT_CC2, ENABLE); + + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(CONFIG_IRQ_ID, TIMx_handler, &irq_attr); + sys_enable_girq(); + + /* TIM ENABLE Flag */ + GPIO_SetBits(GPIOA,GPIO_Pin_06); + + /* TIM1 counter enable */ + TIM_Cmd(TIMx, ENABLE); + + /* Main Output Enable */ + TIM_CtrlPWMOutputs(TIMx, ENABLE); + + while(1) + { + + } + +} + +__INTERRUPT void TIMx_handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); // Save CSRs + + if(TIM_GetITStatus(TIMx, TIM_IT_CC2) == SET) + { + TIM_ClearITPendingBit(TIMx, TIM_IT_CC2); + /* TIM Interrupt Flag */ + GPIO_SetBits(GPIOA, GPIO_Pin_07); + } + + RESTORE_IRQ_CSR_CONTEXT(); // Restore CSRs + return; +} diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/.cproject b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/.project b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/Project.nuproject b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/component.mk b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/inc/isr.h b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/inc/main.h b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/readme.md b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/readme.md new file mode 100644 index 0000000..a04b548 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/readme.md @@ -0,0 +1,24 @@ +PWM_OUT +--- +This example is used to pwm output function. + +## Hardware and Software environment + ++ This example runs on PEC930 devices. + +> + How to log message + +## Log + +TIM2:T2CH1 -> PA2 + T2CH2 -> PA3 + T2CH3 -> PA4 + T2CH4 -> PA5 + +EPWM:EPWMCH0P -> PA0 + EPWMCH0N -> PA1 + EPWMCH1P -> PA2 + EPWMCH1N -> PA3 + EPWMCH2P -> PA4 + EPWMCH2N -> PA5 + diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/src/isr.c b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/src/main.c b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/src/main.c new file mode 100644 index 0000000..39355da --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/src/main.c @@ -0,0 +1,133 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +#include "hal_tim.h" +#include "hal_gpio.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_USE_TIM2 +//#define CONFIG_USE_EPWM + +#if defined(CONFIG_USE_TIM2) + #define TIMx TIM2 + #define CONFIG_IRQ_ID TIM2_IRQn +#elif defined(CONFIG_USE_EPWM) + #define TIMx EPWM + #define CONFIG_IRQ_ID EPWM_IRQn +#endif +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +void TIM_PWM_OUTPUT_Sample(TIM_Type *tim,uint16_t Period,uint16_t Prescaler ,uint16_t CounterMode); +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + /* Configure system clock */ + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + /* Configure PWM OUT */ + TIM_PWM_OUTPUT_Sample(TIMx, 100 - 1, 48 - 1, TIM_CounterMode_Up);//pwm:10K + + /* Set PWM DUTY */ + TIM_SetCompare1(TIMx, 80);//CH1 DUTY:80% + TIM_SetCompare2(TIMx, 40);//CH2 DUTY:40% + TIM_SetCompare3(TIMx, 25);//CH3 DUTY:25% + TIM_SetCompare4(TIMx, 10);//CH4 DUTY:25% + + while(1) + { + + } +} + +void TIM_PWM_OUTPUT_Sample(TIM_Type *tim,uint16_t Period,uint16_t Prescaler ,uint16_t CounterMode) +{ + GPIO_InitTypeDef GPIO_InitStruct; + TIM_OCInitTypeDef TIM_OCInitStruct; + TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; + + TIM_DeInit(tim); + + TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct); + TIM_TimeBaseInitStruct.TIM_Prescaler = Prescaler; + TIM_TimeBaseInitStruct.TIM_CounterMode = CounterMode; + TIM_TimeBaseInitStruct.TIM_Period = Period; + TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_Div1; + TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; + TIM_TimeBaseInit(tim, &TIM_TimeBaseInitStruct); + TIM_ARRPreloadConfig(tim,ENABLE); + + TIM_OCStructInit(&TIM_OCInitStruct); + TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; + TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable; + TIM_OCInitStruct.TIM_Pulse = 0; + TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; + TIM_OCInitStruct.TIM_OCIdleState = TIM_OCIdleState_Reset; + TIM_OCInitStruct.TIM_Pulse = 1; + TIM_OC1Init(tim, &TIM_OCInitStruct); + + TIM_OCInitStruct.TIM_Pulse = 1; + TIM_OC2Init(tim, &TIM_OCInitStruct); + + TIM_OCInitStruct.TIM_Pulse = 1; + TIM_OC3Init(tim, &TIM_OCInitStruct); + + TIM_OCInitStruct.TIM_Pulse = 1; + TIM_OC4Init(tim, &TIM_OCInitStruct); + + +#if defined(CONFIG_USE_TIM2) + /* configure GPIO Pin mux of TIM2 PWM */ + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_02 | GPIO_Pin_03 | GPIO_Pin_04| GPIO_Pin_05; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_5; + GPIO_Init(GPIOA, &GPIO_InitStruct); +#elif defined(CONFIG_USE_EPWM) + /* configure GPIO Pin mux of EPWM PWM */ + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_00 | GPIO_Pin_02 | GPIO_Pin_04; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_6; + GPIO_Init(GPIOA, &GPIO_InitStruct); +#endif + /* configure GPIO Pin OUT */ + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_06 ; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; + GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* Enable EPWM */ + TIM_Cmd(tim, ENABLE); + + /* Enable PWM OUT */ + TIM_CtrlPWMOutputs(tim,ENABLE); +} diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/.cproject b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/.project b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/Project.nuproject b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/component.mk b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/inc/isr.h b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/inc/isr.h new file mode 100644 index 0000000..964e1e9 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/inc/isr.h @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +/** + * ISRs of Internal Interrupt of IRQC + */ +void irqc_mtip_handler(void); +void irqc_msip_handler(void); + +/** + * ISRs of External Interrupt of IRQC + */ +void irqc_uart_handler(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/inc/main.h b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/readme.md b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/readme.md new file mode 100644 index 0000000..b647971 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/readme.md @@ -0,0 +1,44 @@ +uart_Interrput +--- + +This is an example of UART Interrput + ++ Select the UART TX/RX pins + + ``` + // in main.c + #define CONFIG_UART_IO_TX_PORT GPIOA + #define CONFIG_UART_IO_TX_PIN GPIO_Pin_01 + #define CONFIG_UART_IO_TX_AF_MODE GPIO_AF_1 + #define CONFIG_UART_IO_RX_PORT GPIOA + #define CONFIG_UART_IO_RX_PIN GPIO_Pin_00 + #define CONFIG_UART_IO_RX_AF_MODE GPIO_AF_1 + ``` + ++ Configure the parameters related to UART + + ``` + // in main.c + #define CONFIG_BAUD_RATE_VALUE 38400 + UART_WordLength_8b //Data bit 8 + UART_StopBits_1 //Stop bit 1 + UART_Parity_No //No check bit + UART_Mode_TxRx //Transmit-Receive Mode + ``` + ++ Select the UART interrupt mode ++ It can be modified according to the requirements + + ``` + // in main.c + UART_ITConfig(UART0, UART_IE_RXNEE_Msk, ENABLE); + ``` + + +## Log + +Use serial port with baudrate 38400, 8bit, no parity check + ++ SET different uart flag bits to enable interrupts ++ Send the corresponding success log in the interrupt function + diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/src/isr.c b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/src/isr.c new file mode 100644 index 0000000..5e8b24a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/src/main.c b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/src/main.c new file mode 100644 index 0000000..22ef8eb --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/src/main.c @@ -0,0 +1,110 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +/* UART0-TX GPIO pins are PA1 PA15 PB3 PB4 + * GPIO reuse are GPIO_AF_1 + * GPIO pins are PA0 PB0 PB5 + * GPIO reuse are GPIO_AF_2 + * UART0-RX GPIO pins are PA0 PB0 PB5 + * GPIO reuse are GPIO_AF_1 + * GPIO pins are PA1 PA15 PB4 + * GPIO reuse are GPIO_AF_2 + */ +/* adjustment Instructions for the GPIOs */ +#define CONFIG_UART_IO_TX_PORT GPIOA +#define CONFIG_UART_IO_TX_PIN GPIO_Pin_01 +#define CONFIG_UART_IO_TX_AF_MODE GPIO_AF_1 +#define CONFIG_UART_IO_RX_PORT GPIOA +#define CONFIG_UART_IO_RX_PIN GPIO_Pin_00 +#define CONFIG_UART_IO_RX_AF_MODE GPIO_AF_1 + +/* Use Baud Rate */ +#define CONFIG_BAUD_RATE_VALUE 38400 + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void UART0_Handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); //Save CSRs + + if(UART_GetITStatus(UART0, UART_IE_RXNEE_Msk)) + { + printf("UART0 RXNE Interrupt successful\r\n"); + UART_ITConfig(UART0, UART_IE_RXNEE_Msk, DISABLE); + } + + RESTORE_IRQ_CSR_CONTEXT(); //Restore CSRs + return; +} + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + /* Configure the system clock */ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + /* Configure GPIO Pin mux of UART */ + GPIO_InitTypeDef GpioInit = {0}; + GpioInit.GPIO_Pin = CONFIG_UART_IO_TX_PIN; //UART0-TX + GpioInit.GPIO_Mode = GPIO_Mode_AF; + GpioInit.GPIO_AF_Mode = CONFIG_UART_IO_TX_AF_MODE; + GPIO_Init(CONFIG_UART_IO_TX_PORT, &GpioInit); + GpioInit.GPIO_Pin = CONFIG_UART_IO_RX_PIN; //UART0-RX + GpioInit.GPIO_AF_Mode = CONFIG_UART_IO_RX_AF_MODE; + GPIO_Init(CONFIG_UART_IO_RX_PORT, &GpioInit); + + /* Configure the parameters of UART */ + UART_InitTypeDef UartInit = {0}; + UartInit.BaudRate = CONFIG_BAUD_RATE_VALUE; + UartInit.WordLength = UART_WordLength_8b; + UartInit.StopBits = UART_StopBits_1; + UartInit.Parity = UART_Parity_No; + UartInit.Mode = UART_Mode_TxRx; + UART_Init(UART0, &UartInit); + + /* Configure the interrupt function of UART */ + UART_ITConfig(UART0, UART_IE_RXNEE_Msk, ENABLE); + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(UART0_IRQn, UART0_Handler, &irq_attr); + sys_enable_girq(); + + /* UART enable */ + UART_Start(UART0); + + while(1) + { + + } +} diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_polling/.cproject b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_polling/.project b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_polling/Project.nuproject b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_polling/component.mk b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_polling/inc/isr.h b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/inc/isr.h new file mode 100644 index 0000000..964e1e9 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/inc/isr.h @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +/** + * ISRs of Internal Interrupt of IRQC + */ +void irqc_mtip_handler(void); +void irqc_msip_handler(void); + +/** + * ISRs of External Interrupt of IRQC + */ +void irqc_uart_handler(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_polling/inc/main.h b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_polling/readme.md b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/readme.md new file mode 100644 index 0000000..f591d26 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/readme.md @@ -0,0 +1,37 @@ +uart_polling +--- + +This is an example of UART polling + ++ Select the UART TX/RX pins + + ``` + // in main.c + #define CONFIG_UART_IO_TX_PORT GPIOA + #define CONFIG_UART_IO_TX_PIN GPIO_Pin_01 + #define CONFIG_UART_IO_TX_AF_MODE GPIO_AF_1 + #define CONFIG_UART_IO_RX_PORT GPIOA + #define CONFIG_UART_IO_RX_PIN GPIO_Pin_00 + #define CONFIG_UART_IO_RX_AF_MODE GPIO_AF_1 + ``` + ++ Configure the parameters related to UART ++ It can be modified according to the requirements + + ``` + // in main.c + #define CONFIG_BAUD_RATE_VALUE 38400 + UART_WordLength_8b //Data bit 8 + UART_StopBits_1 //Stop bit 1 + UART_Parity_No //No check bit + UART_Mode_TxRx //Transmit-Receive Mode + ``` + + +## Log + +Use serial port with baudrate 38400, 8bit, no parity check + ++ PC sends 1~255 to PEC930 ++ PEC930 receives and sends back data + diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_polling/src/isr.c b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_polling/src/main.c b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/src/main.c new file mode 100644 index 0000000..cbcb197 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/src/main.c @@ -0,0 +1,111 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +uint16_t rxDataBuffer[256]; +uint16_t rxCounter = 0; +uint16_t rxData = 0; +uint16_t errCounter = 0; +uint16_t rightCounter = 0; + +/* UART0-TX GPIO pins are PA1 PA15 PB3 PB4 + * GPIO reuse are GPIO_AF_1 + * GPIO pins are PA0 PB0 PB5 + * GPIO reuse are GPIO_AF_2 + * UART0-RX GPIO pins are PA0 PB0 PB5 + * GPIO reuse are GPIO_AF_1 + * GPIO pins are PA1 PA15 PB4 + * GPIO reuse are GPIO_AF_2 + */ +/* adjustment Instructions for the GPIOs */ +#define CONFIG_UART_IO_TX_PORT GPIOA +#define CONFIG_UART_IO_TX_PIN GPIO_Pin_01 +#define CONFIG_UART_IO_TX_AF_MODE GPIO_AF_1 +#define CONFIG_UART_IO_RX_PORT GPIOA +#define CONFIG_UART_IO_RX_PIN GPIO_Pin_00 +#define CONFIG_UART_IO_RX_AF_MODE GPIO_AF_1 + +/* Use Baud Rate */ +#define CONFIG_BAUD_RATE_VALUE 38400 + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + /* Configure the system clock */ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + /* Configure GPIO Pin mux of UART */ + GPIO_InitTypeDef GpioInit = {0}; + GpioInit.GPIO_Pin = CONFIG_UART_IO_TX_PIN; //UART0-TX + GpioInit.GPIO_Mode = GPIO_Mode_AF; + GpioInit.GPIO_AF_Mode = CONFIG_UART_IO_TX_AF_MODE; + GPIO_Init(CONFIG_UART_IO_TX_PORT, &GpioInit); + GpioInit.GPIO_Pin = CONFIG_UART_IO_RX_PIN; //UART0-RX + GpioInit.GPIO_AF_Mode = CONFIG_UART_IO_RX_AF_MODE; + GPIO_Init(CONFIG_UART_IO_RX_PORT, &GpioInit); + + /* Configure the parameters of UART */ + UART_InitTypeDef UartInit = {0}; + UartInit.BaudRate = CONFIG_BAUD_RATE_VALUE; + UartInit.WordLength = UART_WordLength_8b; + UartInit.StopBits = UART_StopBits_1; + UartInit.Parity = UART_Parity_No; + UartInit.Mode = UART_Mode_TxRx; + UART_Init(UART0, &UartInit); + /* UART enable */ + UART_Start(UART0); + + for(rxCounter = 0; rxCounter < 256; rxCounter ++) + rxDataBuffer[rxCounter] = rxCounter; + + while(1) + { + if(UART_GetFlagStatus(UART0, UART_FLAG_RXNE) == 1) + { + rxData = UART_ReceiveData(UART0); + UART_ResetRxFIFO(UART0); + if(rxData != rxDataBuffer[rxData]) + errCounter++; + else + { + UART_SendData(UART0, rxData); + UART_WaitTxFifoEmpty(UART0); + rightCounter++; + } + } + } +} diff --git a/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/.cproject b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/.project b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/Project.nuproject b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/component.mk b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/inc/isr.h b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/inc/main.h b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/readme.md b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/readme.md new file mode 100644 index 0000000..e29b3e7 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/readme.md @@ -0,0 +1,105 @@ +wdg_count +--- + +This example is used to demo the confguration of the WatchDog + ++ Use interrut or polling mode + + - Use interrupt function + + ```c + // at mian.c + #define CONFIG_USE_WDG_INTERRUPT 1 + ``` + + - Use polling function + + ```c + // at mian.c + #define CONFIG_USE_WDG_INTERRUPT 0 + ``` + ++ Calculate timeout of the WatchDog + > It supports the API to convert milli-seconds to counter value of the WatchDog + + ``` + uint32_t WDG_MSec2Counter(uint32_t msec); + ``` + ++ Trigger system reset when WatchDog timeout + > Too small counter value of the WatchDog will lead to ICE disconnect + + ```c + // at main.c + init.ResetMode = WDG_Reset_Enable; + ``` + ++ Provid the API to extend the timeout of the WatchDog module + + ``` + void WDG_Kick(void); + ``` + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + ++ Use interrupt function + > Set 3 seconds timeout + + ``` + [15:19:48.430] 15:19:43 + [15:19:48.430] Watch-Dog demo + [15:19:51.495] Get the new counter= 95999 + [15:19:54.554] Get the new counter= 95999 + [15:19:57.612] Get the new counter= 95999 + [15:20:00.671] Get the new counter= 95999 + [15:20:03.729] Get the new counter= 95999 + ... + ``` + ++ Use polling function + > Set 3 seconds timeout and polling the counter value + + ``` + 15:21:25 + Watch-Dog demo + Get the counter= 95999 + Get the counter= 95933 + Get the counter= 95864 + ... + Get the counter= 536 + Get the counter= 473 + Get the counter= 409 + Get the counter= 345 + Get the counter= 282 + Get the counter= 218 + Get the counter= 154 + Get the counter= 91 + Get the counter= 30 + --- timeout + Get the counter= 95969 + Get the counter= 95900 + Get the counter= 95831 + ... + ``` + ++ Use system reset when timeou + > Set 3 seconds timeout + + ``` + [15:26:16.696] 15:26:13 <--- reboot + [15:26:16.696] Watch-Dog demo + [15:26:22.824] 15:26:13 <--- reboot + [15:26:22.824] Watch-Dog demo + [15:26:25.888] 15:26:13 <--- reboot + [15:26:25.888] Watch-Dog demo + [15:26:28.952] 15:26:13 <--- reboot + [15:26:28.952] Watch-Dog demo + [15:26:32.016] 15:26:13 <--- reboot + [15:26:32.017] Watch-Dog demo + [15:26:35.080] 15:26:13 + [15:26:35.081] Watch-Dog demo + [15:26:38.145] 15:26:13 + [15:26:38.145] Watch-Dog demo + ``` diff --git a/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/src/isr.c b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/src/main.c b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/src/main.c new file mode 100644 index 0000000..cc690eb --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/src/main.c @@ -0,0 +1,121 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_USE_WDG_INTERRUPT 1 + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static bool g_has_enter_isr = false; +static uint32_t g_counter = 0; +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void WDG_Handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); + + g_has_enter_isr = true; + g_counter = WDG_GetCounter(); + + WDG_ClearITFlag(); + + RESTORE_IRQ_CSR_CONTEXT(); + return; +} + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + SYSCFG_ClkInitTypeDef SysClkInit = {.ClkSource = SYSCFG_ClkSrc_HSI,}; + + #if 0 + SysClkInit.ClkSource = SYSCFG_ClkSrc_FreqDiv; + SysClkInit.SysClk_Div = SYSCFG_SysClkDiv2; + #endif + + SYSCFG_SysClkConfig(&SysClkInit); + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s %s\nWatch-Dog demo\n", __DATE__, __TIME__); + + { /* Configure WDG */ + + WDG_InitTypeDef init = {0}; + + init.Counter = WDG_MSec2Counter(3000); + init.ResetMode = WDG_Reset_Disable; // WDG_Reset_Enable; + WDG_Init(&init); + } + + WDG_Unlock(); + +#if defined(CONFIG_USE_WDG_INTERRUPT) && (CONFIG_USE_WDG_INTERRUPT) + { /* Configure the interrupt function of WDG and it MUST be after init method */ + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(WDG_IRQn, WDG_Handler, &irq_attr); + + WDG_ITEnable(); + } +#else + WDG_ITDisable(); +#endif /* CONFIG_USE_WDG_INTERRUPT */ + + WDG_Enable(); + + WDG_Lock(); + + g_has_enter_isr = false; + g_counter = 0; + + while(1) + { +#if defined(CONFIG_USE_WDG_INTERRUPT) && (CONFIG_USE_WDG_INTERRUPT) + + if( g_has_enter_isr == false ) + continue; + + msg(" Get the new counter= %d\n", g_counter); + + g_has_enter_isr = false; + g_counter = 0; +#else + // WDG_Kick(); + + msg(" Get the counter= %d\n", WDG_GetCounter()); + if( WDG_GetStatusFlag() ) + { + WDG_ClearITFlag(); + msg("--- timeout\n"); + } +#endif + } +} diff --git a/pec930_sdk-v1.0.1/Makefile b/pec930_sdk-v1.0.1/Makefile new file mode 100644 index 0000000..25f962a --- /dev/null +++ b/pec930_sdk-v1.0.1/Makefile @@ -0,0 +1,333 @@ +# ------------------------------------------------ +# Generic Makefile (based on gcc) +# Copyright (c) 2022, All Rights Reserved. +# @file Makefile +# @author Wei-Lun Hsu +# @version 1.0 +# ------------------------------------------------ + +RED="\033[0;31m" +GREEN="\033[0;32m" +LIGHT_GREEN="\033[1;32m" +YELLOW="\033[0;33m" +LIGHT_YELLOW="\033[1;33m" +GREY="\033[0;37m" +BWHITE="\033[1;37m" +MAGENTA="\033[1;35m" +CYAN="\033[1;36m" +NC="\033[0m" + + +PHONY := all flash flash_nvr clean help +PHONY += gdb +PHONY += tags TAGS cscope gtags +PHONY += upload +###################################### +# target +###################################### +ifeq ("$(TARGET)","") +TARGET = Project +endif + +SOC ?= pec930 + +ifeq (,$(filter $(MAKECMDGOALS),clean help)) + +ifeq ("$(SOC)","pec930") + SOC_DRIVER = PEC930 +else +$(error "Unknown SoC, User MUST define 'SOC' name !") +endif + +endif + +srctree=$(shell pwd) + +export SOC_CPU_NAME TARGET srctree SOC_DRIVER + + +###################################### +# building variables +###################################### +# debug build? +DEBUG = y +OPT = +ifeq ("$(D)","0") + DEBUG = n + OPT = -O2 +endif + +V ?= $(VERBOSE) +ifeq ("$(V)","1") + Q = +else + Q = @ +endif + +PLATFORM = $(shell uname -o) +ifeq ("$(findstring Linux, $(PLATFORM))","Linux") + ECHO = echo + TUI = -tui +else + ECHO = echo -e + TUI = +endif + +PYTHON := python3 +PYTHON_VER := $(wordlist 2,4,$(subst ., ,$(shell $(PYTHON) --version 2>&1))) +PYTHON_VER := $(word 1,${PYTHON_VER})$(word 2,${PYTHON_VER}) + +export PLATFORM ECHO Q PYTHON PYTHON_VER TUI DEBUG OPT +####################################### +# paths +####################################### +ifeq ("$(O)","") + OUT = out +else + OUT = $(O) +endif + +ifeq ("$(P)","") + PROJ = Examples/template/demo_project +else + PROJ = $(P) +endif + +$(info Active SoC=$(SOC) @$(PROJ)) + +export OUT PROJ LIBBIN +####################################### +# binaries +####################################### +PREFIX = riscv64-unknown-elf- + +ifdef GCC_PATH +CC = $(GCC_PATH)/$(PREFIX)gcc +AS = $(GCC_PATH)/$(PREFIX)gcc -x assembler-with-cpp +SZ = $(GCC_PATH)/$(PREFIX)size +GDB= $(GCC_PATH)/$(PREFIX)gdb +OBJCOPY = $(GCC_PATH)/$(PREFIX)objcopy +OBJDUMP = $(GCC_PATH)/$(PREFIX)objdump +else +CC = $(PREFIX)gcc +AS = $(PREFIX)gcc -x assembler-with-cpp +SZ = $(PREFIX)size +GDB= $(PREFIX)gdb +OBJCOPY = $(PREFIX)objcopy +OBJDUMP = $(PREFIX)objdump +endif + +HEX = $(OBJCOPY) -O ihex +BIN = $(OBJCOPY) -O binary -S + +ifeq ("$(findstring Linux, $(PLATFORM))","Linux") + OPENOCD = openocd +else + OPENOCD = openocd.exe +endif + +OPENOCDCFG := $(srctree)/Tools/openocd/scripts/target/$(SOC) +####################################### +# CFLAGS +####################################### +# mcu +MCU = + +# AS defines +AS_DEFS = + +# C defines +C_DEFS = + +# AS includes +AS_INCLUDES = + +# C includes +C_INCLUDES = + +ifeq ("$(DEBUG)","y") + OPT += -g3 -ggdb -gdwarf-2 -O0 +else + CFLAGS += -DNDEBUG +endif + +ASFLAGS = $(MCU) $(OPT) -Wall -fdata-sections -ffunction-sections -fno-common +CFLAGS = $(MCU) $(OPT) -Wall -fdata-sections -ffunction-sections -fno-common + +CFLAGS += -std=gnu99 + + +CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)" + +export CFLAGS ASFLAGS C_INCLUDES AS_INCLUDES C_DEFS +####################################### +# LDFLAGS +####################################### +# link script +ifeq ("$(L)","") + LDSCRIPT = $(srctree)/Drivers/$(SOC_DRIVER)/gcc_flashxip.ld +else + LDSCRIPT = $(L) +endif + +# libraries +LIBS = +LIBDIR = + +LDFLAGS = $(MCU) -nodefaultlibs -nostartfiles -Wl,--cref \ + $(LIBDIR) \ + -Wl,-T$(LDSCRIPT) \ + -Wl,-Map=$(OUT)/$(TARGET).map + +export LDFLAGS LDSCRIPT LIBS +###################################### +# source +###################################### +# C sources +C_SOURCES := + +# ASM sources +ASM_SOURCES := + +include $(srctree)/Drivers/drivers.mk + +include $(srctree)/Common/common.mk + +ifeq ("$(PROJ)","") + $(error "Unknown project !!!") +else + include $(srctree)/$(PROJ)/component.mk +endif + + +OBJECTS = $(addprefix $(OUT)/,$(notdir $(C_SOURCES:.c=.o))) +vpath %.c $(sort $(dir $(C_SOURCES))) + +OBJECTS += $(addprefix $(OUT)/,$(notdir $(ASM_SOURCES:.S=.o))) +vpath %.S $(sort $(dir $(ASM_SOURCES))) + +RELT_SOURCES = $(foreach srcpath,$(C_SOURCES),$(subst $(srctree), ,$(srcpath))) +RELT_SOURCES += $(foreach srcpath,$(ASM_SOURCES),$(subst $(srctree),,$(srcpath))) +RELT_INCLUDES = $(foreach incpath,$(C_INCLUDES),$(subst $(srctree),,$(incpath))) + + +TARGET_GDB_SCRIPT := +####################################### +# build the application +####################################### +ASFLAGS += $(AS_DEFS) $(AS_INCLUDES) +CFLAGS += $(C_DEFS) $(C_INCLUDES) + +LDFLAGS += \ + -Wl,-gc-sections \ + -Wl,--check-sections \ + -Wl,--start-group \ + -lc_nano -lgcc -lm \ + -Wl,--end-group + +LDFLAGS += \ + -Wl,--no-warn-rwx-segments + +# default action: build all +all: $(OUT) $(OUT)/$(TARGET).elf $(OUT)/$(TARGET).hex $(OUT)/$(TARGET).bin + +$(OUT)/%.o: %.c Makefile | $(OUT) + @$(ECHO) " CC $@" + $(Q)$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(OUT)/$(notdir $(<:.c=.lst)) $< -o $@ + +$(OUT)/%.o: %.S Makefile | $(OUT) + @$(ECHO) " CC $@" + $(Q)$(AS) -c $(ASFLAGS) $(CFLAGS) $< -o $@ + +$(OUT)/$(TARGET).elf: $(OBJECTS) Makefile + $(Q)$(CC) -Wl,--whole-archive $(OBJECTS) $(LIBS) -Wl,--no-whole-archive $(LDFLAGS) -o $@ + $(Q)$(OBJDUMP) -Sx $(OUT)/$(TARGET).elf > $(OUT)/$(TARGET).disa + @$(ECHO) $(GREEN)"\nSize $(OUT)/$(TARGET).elf" $(NC) + $(Q)$(SZ) $@ + +$(OUT)/%.hex: $(OUT)/%.elf | $(OUT) + @$(ECHO) $(YELLOW) "Generate $(OUT)/$(TARGET).hex" $(NC) + $(Q)$(HEX) $< $@ + +$(OUT)/%.bin: $(OUT)/%.elf | $(OUT) + @$(ECHO) $(YELLOW) "Generate $(OUT)/$(TARGET).bin" $(NC) + $(Q)$(BIN) $< $@ + $(Q)od -A n -t x4 --width=4 -v $@ > $(OUT)/$(TARGET).txt + $(Q)$(ECHO) $(CYAN) "Project SoC=$(SOC) @$(PROJ)" $(NC) + +$(OUT): + @mkdir -p $@ + +flash: $(OUT)/$(TARGET).bin + @$(ECHO) $(YELLOW) "Program $(OUT)/$(TARGET).elf to flash of DUT" $(NC) + @$(OPENOCD) -s Tools/openocd/scripts -f Tools/openocd/scripts/target/$(SOC).cfg \ + -c "program $(OUT)/$(TARGET).bin verify 0; exit" 2>&1 | tee openocd.log + + +gdb: $(OUT)/$(TARGET).elf +ifeq ("$(DEBUG)","y") + @$(ECHO) $(YELLOW) "Download and Run GDB" $(NC) + @$(ECHO) " load $(OUT)/$(TARGET).elf" + @$(GDB) $< $(TUI) --command=$(TARGET_GDB_SCRIPT) \ + -ex "set remotetimeout 240" \ + -ex "monitor reset halt resume" \ + -ex "set mem inaccessible-by-default off" \ + -ex "target remote | $(OPENOCD) -c \"gdb_port pipe; log_output openocd.log\" \ + -s Tools/openocd/scripts \ + -f Tools/openocd/scripts/target/$(SOC).cfg" \ + -ex "j _start" +else + @$(ECHO) $(RED) "It MUST be compiled with debug mode !" $(NC) +endif + + +upload: $(OUT)/$(TARGET).bin + @$(ECHO) $(YELLOW) "Download $(OUT)/$(TARGET).elf to flash of DUT and Run" $(NC) + @$(OPENOCD) -s Tools/openocd/scripts -f Tools/openocd/scripts/target/$(SOC).cfg \ + -c "program $(OUT)/$(TARGET).elf verify reset exit" 2>&1 | tee openocd.log + +clean: + @$(ECHO) $(YELLOW) "Clean target" $(NC) + @$(ECHO) " Remove $(OUT)" + @rm -fR $(OUT) + @$(ECHO) " Done\n" + +tags TAGS cscope gtags: $(OUT) + @rm -f GPATH GRTAGS GTAGS + @$(srctree)/Tools/scripts/tags.sh $@ + + +help: + @$(ECHO) "----------------------------------------------------------------------" + @$(ECHO) "Useful make targets:" + @$(ECHO) "" + @$(ECHO) "Options:" + @$(ECHO) " SOC: $(SOC)" + @$(ECHO) " P: project path (root: $(srctree))" + @$(ECHO) " D: debug mode (0: release, default: 1)" + @$(ECHO) " O: output path (default: out)" + @$(ECHO) " L: link-script path (default: gcc_flashxip.ld in Drivers)" + @$(ECHO) "" + @$(ECHO) "e.g. make P=Examples/template/demo_project" + @$(ECHO) "" + @$(ECHO) " make clean - Remove most generated files" + @$(ECHO) "" + @$(ECHO) " make flash - Program ELF file to flash of DUT" + @$(ECHO) "" + @$(ECHO) " make upload - Program ELF file to flash of DUT and free-run" + @$(ECHO) "" + @$(ECHO) " make gdb - Download elf to flash and run GDB for development" + @$(ECHO) "" + @$(ECHO) " make tags/TAGS - Generate tags file for editors" + @$(ECHO) " make cscope - Generate cscope index" + @$(ECHO) "" + @$(ECHO) " make V=0|1 [targets] 0 => quiet build (default), 1 => verbose build" + @$(ECHO) "----------------------------------------------------------------------" + +####################################### +# dependencies +####################################### + +-include $(wildcard $(OUT)/*.d) + +.PHONY: $(PHONY) diff --git a/pec930_sdk-v1.0.1/README.md b/pec930_sdk-v1.0.1/README.md new file mode 100644 index 0000000..b224e3f --- /dev/null +++ b/pec930_sdk-v1.0.1/README.md @@ -0,0 +1,58 @@ +# pec930_sdk + +PEC930_SDK (RISC-V 32-bits) +> `Tools/markdown/MarkdownEditor.exe` is a markdown viewer +and it assists user to view markdown file friendly (e.g. readme.md) + + +## Naming directory and file + ++ only use ASCII `a-z`, `A-Z`, `0-9`, and `_` (DONOT use white-space) + +## Development + +### Linux platform + +SDK uses Makefile to compile in Ubuntu and type `make help` to get message + +### Windows 10/11 platform + +[Nuclei-Studio IDE 2024.06](https://www.nucleisys.com/download.php#tools) is used to compile SDK in Windows 10/11. +> User opens `Project.nuproject` file of exmples with Nuclei-Studio + ++ Build with IDE + + ![ICE_normal_view](./Docs/image/ICE_normal_view.jpg) + ++ Debug with IDE + + ![IDE_debug_view](./Docs/image/IDE_debug_view.jpg) + ++ Delete the recent project before open the other project (Recommend) + > Avoid IDE automatically appends suffix serial number + + + - Close project + + ![IDE_close_proj](./Docs/image/IDE_close_proj.jpg) + + - Delete the recent project of IDE + + ![IDE_delet_recent_proj](./Docs/image/IDE_delet_recent_proj.jpg) + +### Log message + +For code size, default only support 32-bits integer. + +User should enable the other features manually + +``` +// at Common/printf.c + +/* mark to enable feature */ +#define PRINTF_DISABLE_SUPPORT_FLOAT +#define PRINTF_DISABLE_SUPPORT_EXPONENTIAL +#define PRINTF_DISABLE_SUPPORT_LONG_LONG +#define PRINTF_DISABLE_SUPPORT_PTRDIFF_T + +``` diff --git a/pec930_sdk-v1.0.1/Tools/.DS_Store b/pec930_sdk-v1.0.1/Tools/.DS_Store new file mode 100644 index 0000000..b272a73 Binary files /dev/null and b/pec930_sdk-v1.0.1/Tools/.DS_Store differ diff --git a/pec930_sdk-v1.0.1/Tools/openocd/.DS_Store b/pec930_sdk-v1.0.1/Tools/openocd/.DS_Store new file mode 100644 index 0000000..b2a6b3e Binary files /dev/null and b/pec930_sdk-v1.0.1/Tools/openocd/.DS_Store differ diff --git a/pec930_sdk-v1.0.1/Tools/openocd/README.md b/pec930_sdk-v1.0.1/Tools/openocd/README.md new file mode 100644 index 0000000..ede5dda --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/openocd/README.md @@ -0,0 +1,85 @@ +# Nuclei OpenOCD Distribution + +For **Nuclei OpenOCD documentation**, please check https://doc.nucleisys.com/nuclei_tools/openocd/intro.html + +If the tool version and documentation version not match, please take care. + +**Below is the changelog for Nuclei OpenOCD.** + +## 2024.06 + +* Add and update nuclei custom CSR +* Fix `nuclei cpuinfo` command implementation +* Add debug map feature for Nuclei CPU with new `nuclei expose_cpu_core` and `nuclei examine_cpu_core` commands +* changes are based on [riscv/riscv-openocd](https://github.com/riscv/riscv-openocd/commit/52177592) +* Fix hbird/hbirdv2 flash programming, and re-route fespi to nuspi flash loader for hbird/hbirdv2 processor + +## 2024.02 + +> **Still in development, not official release.** + +* Add Nuclei N100 CSR support +* Nuclei etrace support multicore trace +* Fix riscv debug 0.11 call riscv_run_algorithm error such as hbird/hbirdv2 processor +* Update and fix openocd documentation +* changes are based on [riscv/riscv-openocd](https://github.com/riscv/riscv-openocd/commit/52177592) + +## 2023.10 + +* Add nuclei command group to contains all nuclei customized commands +* Add `nuclei cpuinfo` dump support +* Add more spiflash devices according to customer request +* Fix gdb flash program error on address size > 32bit on windows +* Update nuclei custom csr +* Add `ftdi nscan1_mode` to support 2-wire cjtag for Nuclei CPU, which is replacement for `ftdi oscan1_mode` +* Add nuclei custom command in openocd documentation +* **Experimental and may change**: Add nuclei etrace command to support nuclei etrace hardware feature +* changes are based on [riscv/riscv-openocd](https://github.com/riscv/riscv-openocd/commit/52177592) + +## 2022.12 + +This is release 2022.12 of openocd. + +* nor/spi:add w25q512jv +* add 'init resethalt' command +* feature:auto search custom flashloader path +* fix riscv-debug v0.11 call riscv_run_algorithm error. + + +## 2022.08 + +This is release 2022.08 of openocd. + +* spi_nor:add xt25f256b mac25l1633e gd25q80b gd25le32e en25s40a by25q32al fm25q128 gd25B512me. +* merge upstream https://github.com/riscv/riscv-openocd commit id 52177592f9d3afc6a008f8e1b321cf74e823018f. +* custom flashloader don't rely on 'src/flash/nor/spi.c', fix memory leaks bug. + + +## 2022.04 + +This is release 2022.04 of openocd. + +* add DSP ucode csr register +* Adjustment simulation timeout param +* Fix after write_bank/write_image command read date error bug +* Add custom flash loader in openocd, please refer wiki for how to use it +* Custom flash loader: add 'simulation' parameter for simulation test. + + +## 2022.01 + +This is release 2022.01 of openocd. + +* optimize cjtag support for nuclei cjtag +* spi_nor: add BoHong bh25d80a bh25d40a bh25d20a +* spi_nor: Add Micron MT25QU512 +* flash:"flash bank" command add simulation param +* add nuclei all custom csr +* spi_nor: Add MXIC MX25U51245G +* transport/ftdi: Update to new standard cJTAG sequence +* flash: add XinSheng RISC-V MCU CM32M4xxR flash program driver +* Add nuspi loader support. +* Add nuspi SPI flash driver support. +* Enable multi-core debug. +* Previous fespi loader will be rerouted to nuspi loader. +* Changes are based on [openocd for riscv 0.11.0](https://github.com/riscv/riscv-openocd/commit/6edf98db7f98c5e24bc51cf98419bdf5bbc530e6) diff --git a/pec930_sdk-v1.0.1/Tools/openocd/scripts/bitsbytes.tcl b/pec930_sdk-v1.0.1/Tools/openocd/scripts/bitsbytes.tcl new file mode 100644 index 0000000..6f7d423 --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/openocd/scripts/bitsbytes.tcl @@ -0,0 +1,59 @@ +#---------------------------------------- +# Purpose - Create some $BIT variables +# Create $K and $M variables +# and some bit field extraction variables. +# Create helper variables ... +# BIT0.. BIT31 + +for { set x 0 } { $x < 32 } { set x [expr {$x + 1}]} { + set vn [format "BIT%d" $x] + global $vn + set $vn [expr {1 << $x}] +} + +# Create K bytes values +# __1K ... to __2048K +for { set x 1 } { $x < 2048 } { set x [expr {$x * 2}]} { + set vn [format "__%dK" $x] + global $vn + set $vn [expr {1024 * $x}] +} + +# Create M bytes values +# __1M ... to __2048K +for { set x 1 } { $x < 2048 } { set x [expr {$x * 2}]} { + set vn [format "__%dM" $x] + global $vn + set $vn [expr {1024 * 1024 * $x}] +} + +proc create_mask { MSB LSB } { + return [expr {((1 << ($MSB - $LSB + 1))-1) << $LSB}] +} + +# Cut Bits $MSB to $LSB out of this value. +# Example: % format "0x%08x" [extract_bitfield 0x12345678 27 16] +# Result: 0x02340000 + +proc extract_bitfield { VALUE MSB LSB } { + return [expr {[create_mask $MSB $LSB] & $VALUE}] +} + + +# Cut bits $MSB to $LSB out of this value +# and shift (normalize) them down to bit 0. +# +# Example: % format "0x%08x" [normalize_bitfield 0x12345678 27 16] +# Result: 0x00000234 +# +proc normalize_bitfield { VALUE MSB LSB } { + return [expr {[extract_bitfield $VALUE $MSB $LSB ] >> $LSB}] +} + +proc show_normalize_bitfield { VALUE MSB LSB } { + set m [create_mask $MSB $LSB] + set mr [expr {$VALUE & $m}] + set sr [expr {$mr >> $LSB}] + echo [format "((0x%08x & 0x%08x) -> 0x%08x) >> %2d => (0x%x) %5d " $VALUE $m $mr $LSB $sr $sr] + return $sr +} diff --git a/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/dummy.cfg b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/dummy.cfg new file mode 100644 index 0000000..8cbb5e0 --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/dummy.cfg @@ -0,0 +1,5 @@ +# +# Dummy interface (for testing purposes) +# + +adapter driver dummy diff --git a/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/flashlink.cfg b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/flashlink.cfg new file mode 100644 index 0000000..465a03e --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/flashlink.cfg @@ -0,0 +1,16 @@ +# +# ST FlashLINK JTAG parallel cable +# +# http://www.st.com/internet/evalboard/product/94023.jsp +# http://www.st.com/stonline/products/literature/um/7889.pdf +# + +if { [info exists PARPORTADDR] } { + set _PARPORTADDR $PARPORTADDR +} else { + set _PARPORTADDR 0 +} + +adapter driver parport +parport port $_PARPORTADDR +parport cable flashlink diff --git a/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/ft232r.cfg b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/ft232r.cfg new file mode 100644 index 0000000..9dd00c6 --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/ft232r.cfg @@ -0,0 +1,2 @@ +adapter driver ft232r +adapter speed 1000 diff --git a/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/jlink.cfg b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/jlink.cfg new file mode 100644 index 0000000..1aa211f --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/jlink.cfg @@ -0,0 +1,14 @@ +# +# SEGGER J-Link +# +# http://www.segger.com/jlink.html +# + +adapter driver jlink + +# The serial number can be used to select a specific device in case more than +# one is connected to the host. +# +# Example: Select J-Link with serial number 123456789 +# +# adapter serial 123456789 diff --git a/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/jtag_dpi.cfg b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/jtag_dpi.cfg new file mode 100644 index 0000000..283c413 --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/jtag_dpi.cfg @@ -0,0 +1,38 @@ +# +# Provide support for the Cadence JTAG BFM +# +# Copyright (c) 2020, Ampere Computing LLC +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; +# +# + +adapter driver jtag_dpi + +# Set the DPI JTAG server port +if { [info exists DPI_PORT] } { + set _DPI_PORT $DPI_PORT +} else { + set _DPI_PORT 5555 +} + +# Set the DPI JTAG server address +if { [info exists DPI_ADDRESS] } { + set _DPI_ADDRESS $DPI_ADDRESS +} else { + set _DPI_ADDRESS "127.0.0.1" +} + +jtag_dpi set_port $_DPI_PORT +jtag_dpi set_address $_DPI_ADDRESS diff --git a/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/jtag_hat_rpi2.cfg b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/jtag_hat_rpi2.cfg new file mode 100644 index 0000000..e564199 --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/jtag_hat_rpi2.cfg @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Blinkinlabs JTAG_Hat +# +# https://github.com/blinkinlabs/jtag_hat +# + +adapter driver bcm2835gpio + +bcm2835gpio_peripheral_base 0x3F000000 + +# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET +# These depend on system clock, calibrated for stock 700MHz +# bcm2835gpio_speed SPEED_COEFF SPEED_OFFSET +bcm2835gpio_speed_coeffs 146203 36 + +# Each of the JTAG lines need a gpio number set: tck tms tdi tdo +# Header pin numbers: 23 22 19 21 +bcm2835gpio_jtag_nums 11 25 10 9 + +# Each of the SWD lines need a gpio number set: swclk swdio +# Header pin numbers: 23 22 +bcm2835gpio_swd_nums 11 25 + +# Direction pin for SWDIO level shifting buffer +bcm2835gpio_swdio_dir_num 6 + +# If you define trst or srst, use appropriate reset_config +# Header pin numbers: TRST - 26, SRST - 18 + +bcm2835gpio_trst_num 7 +#reset_config trst_only + +bcm2835gpio_srst_num 24 +#reset_config srst_only + +# or if you have both connected +#reset_config trst_and_srst diff --git a/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/jtag_vpi.cfg b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/jtag_vpi.cfg new file mode 100644 index 0000000..0dbd1be --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/jtag_vpi.cfg @@ -0,0 +1,18 @@ +adapter driver jtag_vpi + +# Set the VPI JTAG server port +if { [info exists VPI_PORT] } { + set _VPI_PORT $VPI_PORT +} else { + set _VPI_PORT 5555 +} + +# Set the VPI JTAG server address +if { [info exists VPI_ADDRESS] } { + set _VPI_ADDRESS $VPI_ADDRESS +} else { + set _VPI_ADDRESS "127.0.0.1" +} + +jtag_vpi set_port $_VPI_PORT +jtag_vpi set_address $_VPI_ADDRESS diff --git a/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/openjtag.cfg b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/openjtag.cfg new file mode 100644 index 0000000..662ceba --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/openjtag.cfg @@ -0,0 +1,8 @@ +# +# OpenJTAG +# +# www.openjtag.org +# + +adapter driver openjtag +openjtag device_desc "Open JTAG Project" diff --git a/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/usb-jtag.cfg b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/usb-jtag.cfg new file mode 100644 index 0000000..65d45e7 --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/usb-jtag.cfg @@ -0,0 +1,37 @@ +# ixo-usb-jtag - Emulation of a Altera Bus Blaster I on a Cypress FX2 IC. +# +# The ixo-usb-jtag firmware can be loaded onto a bunch of different hardware +# including; +# * Xilinx USB Platform Cable +# * Many Digilent boards such as the Nexys, Nexys 2 and Atlys boards +# * Many fpga4fun.com boards from such as the Saxo and Xylo boards +# * The Numato Opsis +# +# Original version - http://www.ixo.de/info/usb_jtag/ +# Updated version - http://ixo-jtag.sourceforge.net/ +# Newest version - http://github.com/mithro/ixo-usb-jtag +# +# Procedure for using is; +# * Get the ixo-usb-jtag firmware for your hardware (or build it yourself). +# * Load the firmware using the fxload tool. +# * Use openocd. +# +# Unless you burn the firmware into the EEPROM on your device, power cycling +# will require you to reload the firmware using the fxload tool. This can be +# automated by using udev rules (which can be found in the firmware +# repository). +# +# Ubuntu packages built from mithro's version (with prebuilt firmware and udev +# rules) can be found at +# https://launchpad.net/~timvideos/+archive/ubuntu/fpga-support +# +# TODO: Refactor the usb_blaster driver to allow loading firmware using any low +# level driver. Loading firmware is currently only supported on the ublast2 +# driver but ixo-usb-jtag requires the ftdi driver. + +adapter driver usb_blaster +usb_blaster vid_pid 0x16C0 0x06AD +usb_blaster device_desc "Van Ooijen Technische Informatica" +# ixo-usb-jtag is only compatible with the ublast1 protocol implemented via the +# ftdi modes, using ublast2 will cause openocd to hang. +usb_blaster lowlevel_driver ftdi diff --git a/pec930_sdk-v1.0.1/Tools/openocd/scripts/mem_helper.tcl b/pec930_sdk-v1.0.1/Tools/openocd/scripts/mem_helper.tcl new file mode 100644 index 0000000..7cd370e --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/openocd/scripts/mem_helper.tcl @@ -0,0 +1,36 @@ +# Helper for common memory read/modify/write procedures + +# mrw: "memory read word", returns value of $reg +proc mrw {reg} { + return [read_memory $reg 32 1] +} + +add_usage_text mrw "address" +add_help_text mrw "Returns value of word in memory." + +# mrh: "memory read halfword", returns value of $reg +proc mrh {reg} { + return [read_memory $reg 16 1] +} + +add_usage_text mrh "address" +add_help_text mrh "Returns value of halfword in memory." + +# mrb: "memory read byte", returns value of $reg +proc mrb {reg} { + return [read_memory $reg 8 1] +} + +add_usage_text mrb "address" +add_help_text mrb "Returns value of byte in memory." + +# mmw: "memory modify word", updates value of $reg +# $reg <== ((value & ~$clearbits) | $setbits) +proc mmw {reg setbits clearbits} { + set old [mrw $reg] + set new [expr {($old & ~$clearbits) | $setbits}] + mww $reg $new +} + +add_usage_text mmw "address setbits clearbits" +add_help_text mmw "Modify word in memory. new_val = (old_val & ~clearbits) | setbits;" diff --git a/pec930_sdk-v1.0.1/Tools/openocd/scripts/memory.tcl b/pec930_sdk-v1.0.1/Tools/openocd/scripts/memory.tcl new file mode 100644 index 0000000..ecd1a25 --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/openocd/scripts/memory.tcl @@ -0,0 +1,175 @@ +# MEMORY +# +# All Memory regions have two components. +# (1) A count of regions, in the form N_NAME +# (2) An array within info about each region. +# +# The ARRAY +# +# ( RegionNumber , ATTRIBUTE ) +# +# Where is one of: +# +# N_FLASH & FLASH (internal memory) +# N_RAM & RAM (internal memory) +# N_MMREGS & MMREGS (for memory mapped registers) +# N_XMEM & XMEM (off chip memory, ie: flash on cs0, sdram on cs2) +# or N_UNKNOWN & UNKNOWN for things that do not exist. +# +# We have 1 unknown region. +set N_UNKNOWN 1 +# All MEMORY regions must have these attributes +# CS - chip select (if internal, use -1) +set UNKNOWN(0,CHIPSELECT) -1 +# BASE - base address in memory +set UNKNOWN(0,BASE) 0 +# LEN - length in bytes +set UNKNOWN(0,LEN) $CPU_MAX_ADDRESS +# HUMAN - human name of the region +set UNKNOWN(0,HUMAN) "unknown" +# TYPE - one of: +# flash, ram, mmr, unknown +# For harvard arch: +# iflash, dflash, iram, dram +set UNKNOWN(0,TYPE) "unknown" +# RWX - access ablity +# unix style chmod bits +# 0 - no access +# 1 - execute +# 2 - write +# 4 - read +# hence: 7 - readwrite execute +set RWX_NO_ACCESS 0 +set RWX_X_ONLY $BIT0 +set RWX_W_ONLY $BIT1 +set RWX_R_ONLY $BIT2 +set RWX_RW [expr {$RWX_R_ONLY + $RWX_W_ONLY}] +set RWX_R_X [expr {$RWX_R_ONLY + $RWX_X_ONLY}] +set RWX_RWX [expr {$RWX_R_ONLY + $RWX_W_ONLY + $RWX_X_ONLY}] +set UNKNOWN(0,RWX) $RWX_NO_ACCESS + +# WIDTH - access width +# 8,16,32 [0 means ANY] +set ACCESS_WIDTH_NONE 0 +set ACCESS_WIDTH_8 $BIT0 +set ACCESS_WIDTH_16 $BIT1 +set ACCESS_WIDTH_32 $BIT2 +set ACCESS_WIDTH_ANY [expr {$ACCESS_WIDTH_8 + $ACCESS_WIDTH_16 + $ACCESS_WIDTH_32}] +set UNKNOWN(0,ACCESS_WIDTH) $ACCESS_WIDTH_NONE + +proc iswithin { ADDRESS BASE LEN } { + return [expr {(($ADDRESS - $BASE) >= 0) && (($BASE + $LEN - $ADDRESS) > 0)}] +} + +proc address_info { ADDRESS } { + + foreach WHERE { FLASH RAM MMREGS XMEM UNKNOWN } { + if { info exists $WHERE } { + set lmt [set N_[set WHERE]] + for { set region 0 } { $region < $lmt } { incr region } { + if { iswithin $ADDRESS $WHERE($region,BASE) $WHERE($region,LEN) } { + return "$WHERE $region"; + } + } + } + } + + # Return the 'unknown' + return "UNKNOWN 0" +} + +proc memread32 {ADDR} { + if ![ catch { set foo [read_memory $ADDR 32 1] } msg ] { + return $foo + } else { + error "memread32: $msg" + } +} + +proc memread16 {ADDR} { + if ![ catch { set foo [read_memory $ADDR 16 1] } msg ] { + return $foo + } else { + error "memread16: $msg" + } +} + +proc memread8 {ADDR} { + if ![ catch { set foo [read_memory $ADDR 8 1] } msg ] { + return $foo + } else { + error "memread8: $msg" + } +} + +proc memwrite32 {ADDR DATA} { + if ![ catch { write_memory $ADDR 32 $DATA } msg ] { + return $DATA + } else { + error "memwrite32: $msg" + } +} + +proc memwrite16 {ADDR DATA} { + if ![ catch { write_memory $ADDR 16 $DATA } msg ] { + return $DATA + } else { + error "memwrite16: $msg" + } +} + +proc memwrite8 {ADDR DATA} { + if ![ catch { write_memory $ADDR 8 $DATA } msg ] { + return $DATA + } else { + error "memwrite8: $msg" + } +} + +proc memread32_phys {ADDR} { + if ![ catch { set foo [read_memory $ADDR 32 1 phys] } msg ] { + return $foo + } else { + error "memread32: $msg" + } +} + +proc memread16_phys {ADDR} { + if ![ catch { set foo [read_memory $ADDR 16 1 phys] } msg ] { + return $foo + } else { + error "memread16: $msg" + } +} + +proc memread8_phys {ADDR} { + if ![ catch { set foo [read_memory $ADDR 8 1 phys] } msg ] { + return $foo + } else { + error "memread8: $msg" + } +} + +proc memwrite32_phys {ADDR DATA} { + if ![ catch { write_memory $ADDR 32 $DATA phys } msg ] { + return $DATA + } else { + error "memwrite32: $msg" + } +} + +proc memwrite16_phys {ADDR DATA} { + if ![ catch { write_memory $ADDR 16 $DATA phys } msg ] { + return $DATA + } else { + error "memwrite16: $msg" + } +} + +proc memwrite8_phys {ADDR DATA} { + if ![ catch { write_memory $ADDR 8 $DATA phys } msg ] { + return $DATA + } else { + error "memwrite8: $msg" + } +} diff --git a/pec930_sdk-v1.0.1/Tools/openocd/scripts/mmr_helpers.tcl b/pec930_sdk-v1.0.1/Tools/openocd/scripts/mmr_helpers.tcl new file mode 100644 index 0000000..d03c8da --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/openocd/scripts/mmr_helpers.tcl @@ -0,0 +1,72 @@ + +proc proc_exists { NAME } { + set n [info commands $NAME] + set l [string length $n] + return [expr {$l != 0}] +} + +# Give: REGISTER name - must be a global variable. +proc show_mmr32_reg { NAME } { + + global $NAME + # we want $($NAME) + set a [set [set NAME]] + + if ![catch { set v [memread32 $a] } msg ] { + echo [format "%15s: (0x%08x): 0x%08x" $NAME $a $v] + + # Was a helper defined? + set fn show_${NAME}_helper + if [ proc_exists $fn ] { + # Then call it + $fn $NAME $a $v + } + return $v; + } else { + error [format "%s (%s)" $msg $NAME ] + } +} + + +# Give: NAMES - an array of names accessible +# in the callers symbol-scope. +# VAL - the bits to display. + +proc show_mmr32_bits { NAMES VAL } { + + upvar $NAMES MYNAMES + + set w 5 + foreach {IDX N} $MYNAMES { + set l [string length $N] + if { $l > $w } { set w $l } + } + + for { set x 24 } { $x >= 0 } { incr x -8 } { + echo -n " " + for { set y 7 } { $y >= 0 } { incr y -1 } { + set s $MYNAMES([expr {$x + $y}]) + echo -n [format "%2d: %-*s | " [expr {$x + $y}] $w $s ] + } + echo "" + + echo -n " " + for { set y 7 } { $y >= 0 } { incr y -1 } { + echo -n [format " %d%*s | " [expr {!!($VAL & (1 << ($x + $y)))}] [expr {$w -1}] ""] + } + echo "" + } +} + + +proc show_mmr_bitfield { MSB LSB VAL FIELDNAME FIELDVALUES } { + set width [expr {(($MSB - $LSB + 1) + 7) / 4}] + set nval [show_normalize_bitfield $VAL $MSB $LSB ] + set name0 [lindex $FIELDVALUES 0 ] + if [ string compare $name0 _NUMBER_ ] { + set sval [lindex $FIELDVALUES $nval] + } else { + set sval "" + } + echo [format "%-15s: %d (0x%0*x) %s" $FIELDNAME $nval $width $nval $sval ] +} diff --git a/pec930_sdk-v1.0.1/Tools/openocd/scripts/target/pec930.cfg b/pec930_sdk-v1.0.1/Tools/openocd/scripts/target/pec930.cfg new file mode 100644 index 0000000..57762d4 --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/openocd/scripts/target/pec930.cfg @@ -0,0 +1,129 @@ + +adapter speed 5000 +reset_config srst_only +adapter srst pulse_width 100 + +adapter driver ftdi +ftdi vid_pid 0x0403 0x6010 + +proc _get_loader {patt} { + set _patt_loader $patt + set _loader_bin 0 + set _level 0 + + while {1} { + if {[file exists $_patt_loader]} { + set _loader_bin [pwd] + append _loader_bin "/" $patt + break + } + + cd .. + incr _level 1 + if {$_level > 20} { + set _loader_bin "" + break + } + } + return $_loader_bin +} + +set _2WIRE_ICE 1 +if { $_2WIRE_ICE == 0 } { + # jTag 4-wire + echo "=> Use 4-wires jTag..." + ftdi nscan1_mode off +} else { + # cJtag 2-wire + echo "=> Use 2-wires cJTag..." + ftdi nscan1_mode on +} + +#/* +# * bindto 0.0.0.0 can be used to cover all available interfaces. +# * Uncomment bindto line to enable remote machine debug +# */ +# bindto 0.0.0.0 + +#/* +# * If ftdi device_desc not specified, the device description is ignored during device selection. +# * So if you want to specify a dedicated FTDI device, you can select following device description: +# * "Dual RS232-HS" is for Nuclei HummingBird Debugger V1 +# * "USB <-> JTAG-DEBUGGER" is for Nuclei HummingBird Debugger V2 +# * Uncomment one which match your device description +# */ +# ftdi device_desc "Dual RS232-HS" +# ftdi device_desc "USB <-> JTAG-DEBUGGER" +#/* you can also specify adapter serial to select a ftdi chip */ +# adapter serial "FT6S9RD6" + +# Bind JTAG with specified serial number passed by JTAGSN +if { [ info exists JTAGSN ] } { + puts "Bind JTAG with serial number $JTAGSN" + adapter serial $JTAGSN +} + +ftdi layout_init 0x0008 0x001b +ftdi layout_signal nSRST -oe 0x0020 -data 0x0020 +#/* These signals are used for cJTAG escape sequence on initialization only */ +ftdi layout_signal TCK -data 0x0001 +ftdi layout_signal TDI -data 0x0002 +ftdi layout_signal TDO -input 0x0004 +ftdi layout_signal TMS -data 0x0008 +ftdi layout_signal JTAG_SEL -data 0x0100 -oe 0x0100 +transport select jtag + +set _CHIPNAME riscv +jtag newtap $_CHIPNAME cpu -irlen 5 + +#/* Work-area is a space in RAM used for flash programming */ +if { [info exists WORKAREASIZE] } { + set _WORKAREA_SIZE $WORKAREASIZE +} else { + set _WORKAREA_SIZE 0x600 +} + +set _WORKAREA_BASE 0x20000A00 + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME riscv -chain-position $_TARGETNAME +$_TARGETNAME configure -work-area-phys $_WORKAREA_BASE -work-area-size $_WORKAREA_SIZE -work-area-backup 0 + +set _FLASHNAME $_CHIPNAME.flash + + + +#/* +# * Use external flash-loader 'loader.bin' +# */ + +set _BURN_DEV_BASE 0x0 +set _BURN_DEV_SIZE 0x8000 + +# eflash +echo "=> Burn Data to eFlash ..." +set _LOADER_BIN [_get_loader Drivers/PEC930/Flash/loader.bin] +flash bank $_FLASHNAME custom $_BURN_DEV_BASE $_BURN_DEV_SIZE 0 0 $_TARGETNAME 0x4000F800 $_LOADER_BIN sectorsize=512 + + + +#/* +# * Expose Nuclei self-defined CSRS range +# * See https://github.com/riscv/riscv-gnu-toolchain/issues/319#issuecomment-358397306 +# * Then user can view the csr register value in gdb using: info reg csr775 for CSR MTVT(0x307) +# * no need to expose since Nuclei OpenOCD 2022 +# */ +#riscv expose_csrs 770-800,835-850,1984-2032,2064-2070 + +#/* expose N100 customized csr 0xbd0 -> 0xbdc, mainly irqc and timer csrs */ +# riscv expose_csrs 3024-3036 + +riscv set_reset_timeout_sec 1 + +init + +halt + +flash protect 0 0 last off + +arm semihosting enable diff --git a/pec930_sdk-v1.0.1/Tools/scripts/.DS_Store b/pec930_sdk-v1.0.1/Tools/scripts/.DS_Store new file mode 100644 index 0000000..0005c61 Binary files /dev/null and b/pec930_sdk-v1.0.1/Tools/scripts/.DS_Store differ diff --git a/pec930_sdk-v1.0.1/Tools/scripts/Profiles/Project_Debug_OpenOCD.launch b/pec930_sdk-v1.0.1/Tools/scripts/Profiles/Project_Debug_OpenOCD.launch new file mode 100644 index 0000000..922e717 --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/scripts/Profiles/Project_Debug_OpenOCD.launch @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pec930_sdk-v1.0.1/Tools/scripts/tags.sh b/pec930_sdk-v1.0.1/Tools/scripts/tags.sh new file mode 100644 index 0000000..725f5ed --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/scripts/tags.sh @@ -0,0 +1,349 @@ +#!/bin/sh +# Generate tags or cscope files +# Usage tags.sh +# +# mode may be any of: tags, TAGS, cscope +# +# Uses the following environment variables: +# ARCH, SUBARCH, SRCARCH, srctree, src, obj + +# +# e.g. +# $ make tags ARCH=arm +# $ make gtags ARCH=arm +# $ make cscope ARCH=arm +# + +if [ "$KBUILD_VERBOSE" = "1" ]; then + set -x +fi + +# RCS_FIND_IGNORE has escaped ()s -- remove them. +ignore="$(echo "$RCS_FIND_IGNORE" | sed 's|\\||g' )" +# tags and cscope files should also ignore MODVERSION *.mod.c files +ignore="$ignore ( -name *.mod.c ) -prune -o" + +# Do not use full path if we do not use O=.. builds +# Use make O=. {tags|cscope} +# to force full paths for a non-O= build +if [ "${KBUILD_SRC}" = "" ]; then + tree=./ +else + tree=${srctree}/ +fi + +# ignore userspace tools +ignore="$ignore ( -path ${tree}tools ) -prune -o" +ignore="$ignore ( -path ${tree}out/syntax ) -prune -o" +ignore="$ignore ( -path ${tree}out/uncrustify ) -prune -o" + +# Find all available archs +find_all_archs() +{ + ALLSOURCE_ARCHS="" + for arch in `ls ${tree}arch`; do + ALLSOURCE_ARCHS="${ALLSOURCE_ARCHS} "${arch##\/} + done +} + +# Detect if ALLSOURCE_ARCHS is set. If not, we assume SRCARCH +if [ "${ALLSOURCE_ARCHS}" = "" ]; then + ALLSOURCE_ARCHS=${SRCARCH} +elif [ "${ALLSOURCE_ARCHS}" = "all" ]; then + find_all_archs +fi + +# find sources in arch/$ARCH +find_arch_sources() +{ + for i in $archincludedir; do + prune="$prune -wholename $i -prune -o" + done + find ${tree}arch/$1 $ignore $subarchprune $prune -name "$2" \ + -not -type l -print; +} + +# find sources in arch/$1/include +find_arch_include_sources() +{ + include=$(find ${tree}arch/$1/ $subarchprune \ + -name include -type d -print); + if [ -n "$include" ]; then + archincludedir="$archincludedir $include" + find $include $ignore -name "$2" -not -type l -print; + fi +} + +# find sources in include/ +find_include_sources() +{ + find ${tree} $ignore -name config -prune -o -name "$1" \ + -not -type l -print; +} + +# find sources in rest of tree +# we could benefit from a list of dirs to search in here +find_other_sources() +{ + find ${tree}* $ignore \ + \( -name include -o -name arch -o -name '.tmp_*' \) -prune -o \ + -name "$1" -not -type l -print; +} + +find_sources() +{ + find_arch_sources $1 "$2" +} + +all_sources() +{ + # find_arch_include_sources ${SRCARCH} '*.[chS]' + # if [ ! -z "$archinclude" ]; then + # find_arch_include_sources $archinclude '*.[chS]' + # fi + find_include_sources '*.[chS]' + # for arch in $ALLSOURCE_ARCHS + # do + # find_sources $arch '*.[chS]' + # done + # find_other_sources '*.[chS]' +} + +all_compiled_sources() +{ + for i in $(all_sources); do + case "$i" in + *.[cS]) + j=${i/\.[cS]/\.o} + if [ -e $j ]; then + echo $i + fi + ;; + *) + echo $i + ;; + esac + done +} + +all_target_sources() +{ + if [ -n "$COMPILED_SOURCE" ]; then + all_compiled_sources + else + all_sources + fi +} + +all_kconfigs() +{ + for arch in $ALLSOURCE_ARCHS; do + find_sources $arch 'Kconfig*' + done + find_other_sources 'Kconfig*' +} + +all_defconfigs() +{ + find_sources $ALLSOURCE_ARCHS "defconfig" +} + +docscope() +{ + (echo \-k; echo \-q; all_target_sources) > cscope.files + cscope -b -f cscope.out +} + +dogtags() +{ + (all_target_sources) > cscope.files + all_target_sources | gtags -i -f - +} + +exuberant() +{ + all_target_sources | xargs $1 -a \ + -I __initdata,__exitdata,__initconst, \ + -I __cpuinitdata,__initdata_memblock \ + -I __refdata,__attribute,__maybe_unused,__always_unused \ + -I __acquires,__releases,__deprecated \ + -I __read_mostly,__aligned,____cacheline_aligned \ + -I ____cacheline_aligned_in_smp \ + -I __cacheline_aligned,__cacheline_aligned_in_smp \ + -I ____cacheline_internodealigned_in_smp \ + -I __used,__packed,__packed2__,__must_check,__must_hold \ + -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL,ACPI_EXPORT_SYMBOL \ + -I DEFINE_TRACE,EXPORT_TRACEPOINT_SYMBOL,EXPORT_TRACEPOINT_SYMBOL_GPL \ + -I static,const \ + --extra=+f --c-kinds=+px \ + --regex-asm='/^(ENTRY|_GLOBAL)\(([^)]*)\).*/\2/' \ + --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' \ + --regex-c++='/^TRACE_EVENT\(([^,)]*).*/trace_\1/' \ + --regex-c++='/^DEFINE_EVENT\([^,)]*, *([^,)]*).*/trace_\1/' \ + --regex-c++='/PAGEFLAG\(([^,)]*).*/Page\1/' \ + --regex-c++='/PAGEFLAG\(([^,)]*).*/SetPage\1/' \ + --regex-c++='/PAGEFLAG\(([^,)]*).*/ClearPage\1/' \ + --regex-c++='/TESTSETFLAG\(([^,)]*).*/TestSetPage\1/' \ + --regex-c++='/TESTPAGEFLAG\(([^,)]*).*/Page\1/' \ + --regex-c++='/SETPAGEFLAG\(([^,)]*).*/SetPage\1/' \ + --regex-c++='/__SETPAGEFLAG\(([^,)]*).*/__SetPage\1/' \ + --regex-c++='/TESTCLEARFLAG\(([^,)]*).*/TestClearPage\1/' \ + --regex-c++='/__TESTCLEARFLAG\(([^,)]*).*/TestClearPage\1/' \ + --regex-c++='/CLEARPAGEFLAG\(([^,)]*).*/ClearPage\1/' \ + --regex-c++='/__CLEARPAGEFLAG\(([^,)]*).*/__ClearPage\1/' \ + --regex-c++='/__PAGEFLAG\(([^,)]*).*/__SetPage\1/' \ + --regex-c++='/__PAGEFLAG\(([^,)]*).*/__ClearPage\1/' \ + --regex-c++='/PAGEFLAG_FALSE\(([^,)]*).*/Page\1/' \ + --regex-c++='/TESTSCFLAG\(([^,)]*).*/TestSetPage\1/' \ + --regex-c++='/TESTSCFLAG\(([^,)]*).*/TestClearPage\1/' \ + --regex-c++='/SETPAGEFLAG_NOOP\(([^,)]*).*/SetPage\1/' \ + --regex-c++='/CLEARPAGEFLAG_NOOP\(([^,)]*).*/ClearPage\1/' \ + --regex-c++='/__CLEARPAGEFLAG_NOOP\(([^,)]*).*/__ClearPage\1/' \ + --regex-c++='/TESTCLEARFLAG_FALSE\(([^,)]*).*/TestClearPage\1/' \ + --regex-c++='/__TESTCLEARFLAG_FALSE\(([^,)]*).*/__TestClearPage\1/' \ + --regex-c++='/_PE\(([^,)]*).*/PEVENT_ERRNO__\1/' \ + --regex-c++='/TESTPCGFLAG\(([^,)]*).*/PageCgroup\1/' \ + --regex-c++='/SETPCGFLAG\(([^,)]*).*/SetPageCgroup\1/' \ + --regex-c++='/CLEARPCGFLAG\(([^,)]*).*/ClearPageCgroup\1/' \ + --regex-c++='/TESTCLEARPCGFLAG\(([^,)]*).*/TestClearPageCgroup\1/' \ + --regex-c='/PCI_OP_READ\((\w*).*[1-4]\)/pci_bus_read_config_\1/' \ + --regex-c='/PCI_OP_WRITE\((\w*).*[1-4]\)/pci_bus_write_config_\1/' \ + --regex-c='/DEFINE_(MUTEX|SEMAPHORE|SPINLOCK)\((\w*)/\2/v/' \ + --regex-c='/DEFINE_(RAW_SPINLOCK|RWLOCK|SEQLOCK)\((\w*)/\2/v/' \ + --regex-c='/DECLARE_(RWSEM|COMPLETION)\((\w*)/\2/v/' \ + --regex-c='/DECLARE_BITMAP\((\w*)/\1/v/' \ + --regex-c='/(^|\s)(|L|H)LIST_HEAD\((\w*)/\3/v/' \ + --regex-c='/(^|\s)RADIX_TREE\((\w*)/\2/v/' \ + --regex-c='/DEFINE_PER_CPU\(([^,]*,\s*)(\w*).*\)/\2/v/' \ + --regex-c='/DEFINE_PER_CPU_SHARED_ALIGNED\(([^,]*,\s*)(\w*).*\)/\2/v/' \ + --regex-c='/DECLARE_WAIT_QUEUE_HEAD\((\w*)/\1/v/' \ + --regex-c='/DECLARE_(TASKLET|WORK|DELAYED_WORK)\((\w*)/\2/v/' \ + --regex-c='/DEFINE_PCI_DEVICE_TABLE\((\w*)/\1/v/' \ + --regex-c='/(^\s)OFFSET\((\w*)/\2/v/' \ + --regex-c='/(^\s)DEFINE\((\w*)/\2/v/' \ + --regex-c='/DEFINE_HASHTABLE\((\w*)/\1/v/' + + all_kconfigs | xargs $1 -a \ + --langdef=kconfig --language-force=kconfig \ + --regex-kconfig='/^[[:blank:]]*(menu|)config[[:blank:]]+([[:alnum:]_]+)/\2/' + + all_kconfigs | xargs $1 -a \ + --langdef=kconfig --language-force=kconfig \ + --regex-kconfig='/^[[:blank:]]*(menu|)config[[:blank:]]+([[:alnum:]_]+)/CONFIG_\2/' + + all_defconfigs | xargs -r $1 -a \ + --langdef=dotconfig --language-force=dotconfig \ + --regex-dotconfig='/^#?[[:blank:]]*(CONFIG_[[:alnum:]_]+)/\1/' +} + +emacs() +{ + all_target_sources | xargs $1 -a \ + --regex='/^\(ENTRY\|_GLOBAL\)(\([^)]*\)).*/\2/' \ + --regex='/^SYSCALL_DEFINE[0-9]?(\([^,)]*\).*/sys_\1/' \ + --regex='/^TRACE_EVENT(\([^,)]*\).*/trace_\1/' \ + --regex='/^DEFINE_EVENT([^,)]*, *\([^,)]*\).*/trace_\1/' \ + --regex='/PAGEFLAG(\([^,)]*\).*/Page\1/' \ + --regex='/PAGEFLAG(\([^,)]*\).*/SetPage\1/' \ + --regex='/PAGEFLAG(\([^,)]*\).*/ClearPage\1/' \ + --regex='/TESTSETFLAG(\([^,)]*\).*/TestSetPage\1/' \ + --regex='/TESTPAGEFLAG(\([^,)]*\).*/Page\1/' \ + --regex='/SETPAGEFLAG(\([^,)]*\).*/SetPage\1/' \ + --regex='/__SETPAGEFLAG(\([^,)]*\).*/__SetPage\1/' \ + --regex='/TESTCLEARFLAG(\([^,)]*\).*/TestClearPage\1/' \ + --regex='/__TESTCLEARFLAG(\([^,)]*\).*/TestClearPage\1/' \ + --regex='/CLEARPAGEFLAG(\([^,)]*\).*/ClearPage\1/' \ + --regex='/__CLEARPAGEFLAG(\([^,)]*\).*/__ClearPage\1/' \ + --regex='/__PAGEFLAG(\([^,)]*\).*/__SetPage\1/' \ + --regex='/__PAGEFLAG(\([^,)]*\).*/__ClearPage\1/' \ + --regex='/PAGEFLAG_FALSE(\([^,)]*\).*/Page\1/' \ + --regex='/TESTSCFLAG(\([^,)]*\).*/TestSetPage\1/' \ + --regex='/TESTSCFLAG(\([^,)]*\).*/TestClearPage\1/' \ + --regex='/SETPAGEFLAG_NOOP(\([^,)]*\).*/SetPage\1/' \ + --regex='/CLEARPAGEFLAG_NOOP(\([^,)]*\).*/ClearPage\1/' \ + --regex='/__CLEARPAGEFLAG_NOOP(\([^,)]*\).*/__ClearPage\1/' \ + --regex='/TESTCLEARFLAG_FALSE(\([^,)]*\).*/TestClearPage\1/' \ + --regex='/__TESTCLEARFLAG_FALSE(\([^,)]*\).*/__TestClearPage\1/' \ + --regex='/TESTPCGFLAG\(([^,)]*).*/PageCgroup\1/' \ + --regex='/SETPCGFLAG\(([^,)]*).*/SetPageCgroup\1/' \ + --regex='/CLEARPCGFLAG\(([^,)]*).*/ClearPageCgroup\1/' \ + --regex='/TESTCLEARPCGFLAG\(([^,)]*).*/TestClearPageCgroup\1/' \ + --regex='/_PE(\([^,)]*\).*/PEVENT_ERRNO__\1/' \ + --regex='/PCI_OP_READ(\([a-z]*[a-z]\).*[1-4])/pci_bus_read_config_\1/' \ + --regex='/PCI_OP_WRITE(\([a-z]*[a-z]\).*[1-4])/pci_bus_write_config_\1/'\ + --regex='/DEFINE_HASHTABLE\((\w*)/\1/v/' + + all_kconfigs | xargs $1 -a \ + --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/\3/' + + all_kconfigs | xargs $1 -a \ + --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/CONFIG_\3/' + + all_defconfigs | xargs -r $1 -a \ + --regex='/^#?[ \t]?\(CONFIG_[a-zA-Z0-9_]+\)/\1/' +} + +xtags() +{ + if $1 --version 2>&1 | grep -iq exuberant; then + exuberant $1 + elif $1 --version 2>&1 | grep -iq emacs; then + emacs $1 + else + all_target_sources | xargs $1 -a + fi +} + +# # Support um (which uses SUBARCH) +# if [ "${ARCH}" = "um" ]; then +# if [ "$SUBARCH" = "i386" ]; then +# archinclude=x86 +# elif [ "$SUBARCH" = "x86_64" ]; then +# archinclude=x86 +# else +# archinclude=${SUBARCH} +# fi +# elif [ "${SRCARCH}" = "arm" -a "${SUBARCH}" != "" ]; then +# subarchdir=$(find ${tree}arch/$SRCARCH/ -name "mach-*" -type d -o \ +# -name "plat-*" -type d); +# for i in $subarchdir; do +# case "$i" in +# *"mach-"${SUBARCH}) +# ;; +# *"plat-"${SUBARCH}) +# ;; +# *) +# subarchprune="$subarchprune \ +# -wholename $i -prune -o" +# ;; +# esac +# done +# fi + +remove_structs= +case "$1" in + "cscope") + docscope + ;; + + "gtags") + dogtags + ;; + + "tags") + rm -f tags + xtags ctags + remove_structs=y + ;; + + "TAGS") + rm -f TAGS + xtags etags + remove_structs=y + ;; +esac + +# Remove structure forward declarations. +if [ -n "$remove_structs" ]; then + LANG=C sed -i -e '/^\([a-zA-Z_][a-zA-Z0-9_]*\)\t.*\t\/\^struct \1;.*\$\/;"\tx$/d' $1 +fi