diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2218d20 --- /dev/null +++ b/.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/.gitmodules b/.gitmodules new file mode 100644 index 0000000..b1fecda --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "BitFiles"] + path = BitFiles + url = https://60.248.80.176:28080/wlhsu/fpga_bit_file.git diff --git a/Apps/demo_project/.cproject b/Apps/demo_project/.cproject new file mode 100644 index 0000000..d9ac06f --- /dev/null +++ b/Apps/demo_project/.cproject @@ -0,0 +1,294 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Apps/demo_project/.project b/Apps/demo_project/.project new file mode 100644 index 0000000..83b30c3 --- /dev/null +++ b/Apps/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 + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/Apps/demo_project/Project.nuproject b/Apps/demo_project/Project.nuproject new file mode 100644 index 0000000..0072223 --- /dev/null +++ b/Apps/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/Apps/demo_project/component.mk b/Apps/demo_project/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Apps/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/Apps/demo_project/inc/isr.h b/Apps/demo_project/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/Apps/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/Apps/demo_project/inc/main.h b/Apps/demo_project/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Apps/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/Apps/demo_project/readme.md b/Apps/demo_project/readme.md new file mode 100644 index 0000000..b4f1dcd --- /dev/null +++ b/Apps/demo_project/readme.md @@ -0,0 +1,10 @@ +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/Apps/demo_project/src/isr.c b/Apps/demo_project/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/Apps/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/Apps/demo_project/src/main.c b/Apps/demo_project/src/main.c new file mode 100644 index 0000000..d84273f --- /dev/null +++ b/Apps/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 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/Common/common.mk b/Common/common.mk new file mode 100644 index 0000000..d2d10d3 --- /dev/null +++ b/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/Common/hal_conf.h b/Common/hal_conf.h new file mode 100644 index 0000000..13805e7 --- /dev/null +++ b/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/Common/printf.c b/Common/printf.c new file mode 100644 index 0000000..fbc88e7 --- /dev/null +++ b/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/Common/printf.h b/Common/printf.h new file mode 100644 index 0000000..c45eb26 --- /dev/null +++ b/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/Common/syslog.c b/Common/syslog.c new file mode 100644 index 0000000..e93c49a --- /dev/null +++ b/Common/syslog.c @@ -0,0 +1,115 @@ +/** + * 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 +//============================================================================= +// 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 through PA15) */ + gpio_init.GPIO_Pin = GPIO_Pin_15; + gpio_init.GPIO_Mode = GPIO_Mode_AF; + gpio_init.GPIO_AF_Mode = GPIO_AF_1; + GPIO_Init(GPIOA, &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_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/Common/syslog.h b/Common/syslog.h new file mode 100644 index 0000000..e292755 --- /dev/null +++ b/Common/syslog.h @@ -0,0 +1,107 @@ +/** + * 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); + +/** + * \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/Docs/Schematic/DAC_ADC_Simple_BOARD_010(20250730)_2.pdf b/Docs/Schematic/DAC_ADC_Simple_BOARD_010(20250730)_2.pdf new file mode 100644 index 0000000..c306ba8 Binary files /dev/null and b/Docs/Schematic/DAC_ADC_Simple_BOARD_010(20250730)_2.pdf differ diff --git a/Docs/Schematic/PB5700_EV_BOARD_SOP24(010)_20250305_M.pdf b/Docs/Schematic/PB5700_EV_BOARD_SOP24(010)_20250305_M.pdf new file mode 100644 index 0000000..70fc485 Binary files /dev/null and b/Docs/Schematic/PB5700_EV_BOARD_SOP24(010)_20250305_M.pdf differ diff --git a/Docs/Schematic/PB5700_EV_BOARD_SSOP24(010)_20250327.pdf b/Docs/Schematic/PB5700_EV_BOARD_SSOP24(010)_20250327.pdf new file mode 100644 index 0000000..69b3716 Binary files /dev/null and b/Docs/Schematic/PB5700_EV_BOARD_SSOP24(010)_20250327.pdf differ diff --git a/Docs/commit_rule.md b/Docs/commit_rule.md new file mode 100644 index 0000000..0bef65f --- /dev/null +++ b/Docs/commit_rule.md @@ -0,0 +1,161 @@ +# Commit Rule +--- + +當共同合作開發時, 能藉由瀏覽 Commit Message 內容快速進入狀況, 瞭解程式異動的原因, 如此也利於後續的維護. + +良好的 Commit Message 在 release 時, 可大幅減少整理 Change Log 的時間. + ++ 何謂好的 Commit Message ? + > 一個好的 Commit Message 必須兼具 What & Why & How, 能幫助開發者瞭解這個提交版本: + + - 這個提交版本做了什麼事情(What) + > 這個版本修正了什麼 bug, 新增了什麼 feature, 或是優化了什麼效能, 也可能只是簡單的文字修正. + 這是一個 GCM 最重要的一部分, 必須要簡潔明瞭地告訴開發者這個提交版本的目的 + + - 為什麼要做這件事情(Why) + > 說明更動的`動機`與`原因`是什麼, 並補充說明 `What` 所描述的項目 + + - 用什麼方法做到的(How) + > 用什麼方法做到提交版本的目的.
+ 在大部分簡單的提交版本中, 是不需要特別詳註的. + > 建議是有需要特別補充的才紀錄在訊息中, 並且應該是提供 High-level 的方法與概念的敘述, 例如用了什麼演算法, 設計模式等, 而不是方法的實際細節. + >> 方法細節應當透過更動的程式碼本身, 以及程式碼註解來自行解釋. + + +# 設定 Git + + +``` +$ git config --global user.name "your-name" +$ git config --global user.email "your-email" +``` + ++ Name + > 在公司中使用的名字 (不要用暱稱, 要明確知道是誰) + ++ E-mail + > 限制使用公司的 e-mail + +# Message Format + + +一個 Commit Message 主要由 `Header (what)` + `Body(why)` + `Footer` 組成 +> 各部分以空行區隔, 為了讓 `git log` 顯示乾淨 + +``` +Message Header + ---> 空行 +Message Body + ---> 空行 +Message Footer +``` + +### Message Header + +``` +(scope): +``` + ++ type(必要): commit 的類別 + > 用來告訴進行 Code Review 的人應該以什麼態度來檢視 Commit 內容. + > 利用不同的 Type 來決定進行 Code Review 檢視的角度, 可以提升 Code Review 的速度 + > + 看到 Type 為 `fix`, 進行 Code Review 的人就可以用**觀察 Commit 如何解決錯誤**的角度來閱讀程式碼 + > + 若是 `refactor`, 則可以放輕鬆閱讀程式碼如何被重構, 因為重構的本質是不會影響既有的功能 + + - `feat`: 新功能、新特性 + - `fix`: 修改 bug + > 如果修復的這個BUG只影響當前修改的文件, 可不加範圍. + 如果影響的範圍比較大, 要加上範圍描述. + 例如這次 BUG 修復影響到全局, 可以加個 global. 如果影響的是某個目錄或某個功能, 可以加上該目錄的路徑, 或者對應的功能名稱. + + ```js + fix(global): 修復checkbox不能復選的問題 + ``` + + ``` + # 下面圓括號裡的 common 為通用管理的名稱 + fix(common): 修復字體過小的BUG, 將通用管理下所有頁面的默認字體大小修改為 14px + ``` + + ``` + fix: value.length -> values.length + ``` + + - `perf`: 更改代碼, 以提高性能(在不影響代碼內部行為的前提下, 對程序性能進行優化) + - `refactor`: 代碼重構 (重構, 在不影響代碼內部行為, 功能下的代碼修改) + - `docs`: 文檔修改 + - `style`: 代碼格式修改 (例如分號修改) + - `test`: 測試用例新增, 修改 + - `build`: 影響項目構建或依賴項修改 + - `revert`: 恢復上一次提交 + - `ci`: 持續集成相關文件修改 + - `chore`: 其他修改(不在上述類型中的修改) + > chore 的中文翻譯為日常事務、例行工作, 顧名思義, 即不在其他 commit 類型中的修改, 都可以用 chore 表示. + - `release`: 發佈新版本 + ++ Chip ID(必要) + > 註明 target ID, e.g. `F103`, `F100/F103`, `All` + ++ Module + > 註明目標的 module, e.g. peripheral name (I2C, Uart), Tool, ...等 + ++ subject(必要): commit 的簡短描述 + + - **不超過 50 個字元** + > describe issue + - 結尾不加句號 + - 儘量讓 Commit 單一化, 一次只更動一個主題 + +### Message Body + ++ 對本次 Commit 的詳細描述 ++ 可以分成多行, **每一行不超過 72 個字元** + > display issue ++ 說明程式碼變動的項目與原因, 必要時與先前行為做對比 + +### Message Footer + +如果有 Bug tracer, 紀錄 Issue ID + + +### Example + +``` +fix: [F103][I2C] Fix an error handling path in mtk_i2c_probe() + +The clsk are prepared, enabled, then disabled. So if an error occurs after +the disable step, they are still prepared. + +Add an error handling path to unprepare the clks in such a case, as already +done in the .remove function. + +bug1234 +``` + +## Change Log + ++ [Basic example](https://github.com/Mokkapps/changelog-generator-demo/blob/master/CHANGELOG.md) + ++ [Angular- CHANGELOG](https://github.com/angular/angular/blob/22b96b96902e1a42ee8c5e807720424abad3082a/CHANGELOG.md) + + +## Reference ++ [約定式提交](https://www.conventionalcommits.org/zh-hans/v1.0.0-beta.4/) + + +# Setup environment +--- + ++ Install [Official Git](https://git-scm.com/downloads) + ++ Verify git configuration + + - [Right key] -> [Git Bash Here] + > System MUST be installed official git tool. + + - Execute `z_git_config.sh` + > verify git configuration + + ```bash + $ z_git_config.sh + ``` diff --git a/Docs/image/ICE_normal_view.jpg b/Docs/image/ICE_normal_view.jpg new file mode 100644 index 0000000..18df783 Binary files /dev/null and b/Docs/image/ICE_normal_view.jpg differ diff --git a/Docs/image/IDE_debug_view.jpg b/Docs/image/IDE_debug_view.jpg new file mode 100644 index 0000000..4f9927e Binary files /dev/null and b/Docs/image/IDE_debug_view.jpg differ diff --git a/Docs/image/TortoiseGit_clone.jpg b/Docs/image/TortoiseGit_clone.jpg new file mode 100644 index 0000000..c550936 Binary files /dev/null and b/Docs/image/TortoiseGit_clone.jpg differ diff --git a/Docs/image/gitlab_login.jpg b/Docs/image/gitlab_login.jpg new file mode 100644 index 0000000..d2449ab Binary files /dev/null and b/Docs/image/gitlab_login.jpg differ diff --git a/Drivers/PB5700/BSP/StarterKit/starterkit.c b/Drivers/PB5700/BSP/StarterKit/starterkit.c new file mode 100644 index 0000000..a83c4d7 --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/BSP/StarterKit/starterkit.h b/Drivers/PB5700/BSP/StarterKit/starterkit.h new file mode 100644 index 0000000..6d711a4 --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/Device/inc/SVD/PB5700.svd b/Drivers/PB5700/Device/inc/SVD/PB5700.svd new file mode 100644 index 0000000..7d8d6ac --- /dev/null +++ b/Drivers/PB5700/Device/inc/SVD/PB5700.svd @@ -0,0 +1,10164 @@ + + + Padauk-tech + PB5700 + 1.0 + PB5700 uses 32-bits RISC-V 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 + 0x00201EB0 + + 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 + + + SR + Sample Rate + 16 + 2 + 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 + + + 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 + + + + + + + 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 + + + + + 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 + + + + + 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 + + + CCR1 + Down Capture/Compare 1 value + 0 + 20 + + + + + CCDR2 + CR2 down capture or compare value + 0X54 + 32 + 0x0 + 0xFFFFFFFF + + + CCR2 + Down Capture/Compare 2 value + 0 + 20 + + + + + CCDR3 + CR3 down capture or compare value + 0X58 + 32 + 0x0 + 0xFFFFFFFF + + + CCR3 + Down Capture/Compare 3 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/Drivers/PB5700/Device/inc/pb5700.h b/Drivers/PB5700/Device/inc/pb5700.h new file mode 100644 index 0000000..efe341a --- /dev/null +++ b/Drivers/PB5700/Device/inc/pb5700.h @@ -0,0 +1,5904 @@ +/* + * Copyright (c) 2009-2019 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 PB5700.h + * @brief CMSIS HeaderFile + * @version 1.0 + * @date 23. September 2025 + * @note Generated by SVDConv V3.3.38 on Tuesday, 23.09.2025 12:30:25 + * from File './PB5700.svd', + * last modified on Tuesday, 23.09.2025 04:19:56 + */ + + + +/** @addtogroup Padauk-tech + * @{ + */ + + +/** @addtogroup PB5700 + * @{ + */ + + +#ifndef PB5700_H +#define PB5700_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @addtogroup Configuration_of_CMSIS + * @{ + */ + + + +/* =========================================================================================================================== */ +/* ================ Interrupt Number Definition ================ */ +/* =========================================================================================================================== */ + +typedef enum { +/* =========================================== PB5700 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 { /*!< (@ 0x00201EB0) 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 */ + __IOM uint32_t SR : 2; /*!< [17..16] Sample Rate */ + uint32_t : 14; + } 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 { + uint32_t : 24; + __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) */ + + + +/* =========================================================================================================================== */ +/* ================ 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 */ + uint32_t : 24; + } 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 */ + uint32_t : 19; + } 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 CCR1 : 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 CCR2 : 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 CCR3 : 20; /*!< [19..0] Down Capture/Compare 3 value */ + uint32_t : 12; + } CCDR3_b; + } ; +} TIM_Type; /*!< Size = 92 (0x5c) */ + + + +/* =========================================================================================================================== */ +/* ================ 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 0x00201EB0UL +#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 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 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) */ +#define UART_BR_SR_Pos (16UL) /*!< SR (Bit 16) */ +#define UART_BR_SR_Msk (0x30000UL) /*!< SR (Bitfield-Mask: 0x03) */ +/* ========================================================== 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_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) */ + + +/* =========================================================================================================================== */ +/* ================ 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) */ +/* ========================================================== 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) */ +/* ========================================================== 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_CCR1_Pos (0UL) /*!< CCR1 (Bit 0) */ +#define TIM_CCDR1_CCR1_Msk (0xfffffUL) /*!< CCR1 (Bitfield-Mask: 0xfffff) */ +/* ========================================================= CCDR2 ========================================================= */ +#define TIM_CCDR2_CCR2_Pos (0UL) /*!< CCR2 (Bit 0) */ +#define TIM_CCDR2_CCR2_Msk (0xfffffUL) /*!< CCR2 (Bitfield-Mask: 0xfffff) */ +/* ========================================================= CCDR3 ========================================================= */ +#define TIM_CCDR3_CCR3_Pos (0UL) /*!< CCR3 (Bit 0) */ +#define TIM_CCDR3_CCR3_Msk (0xfffffUL) /*!< CCR3 (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 ========================================================= */ +/* ======================================================== LSI_CR ========================================================= */ +/* ====================================================== ADC_AIN_CR ======================================================= */ + + +/* =========================================================================================================================== */ +/* ================ 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 ========================================================= */ + + +/* =========================================================================================================================== */ +/* ================ 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 /* PB5700_H */ + + +/** @} */ /* End of group PB5700 */ + +/** @} */ /* End of group Padauk-tech */ diff --git a/Drivers/PB5700/Device/inc/pb57xx.h b/Drivers/PB5700/Device/inc/pb57xx.h new file mode 100644 index 0000000..d8a65a3 --- /dev/null +++ b/Drivers/PB5700/Device/inc/pb57xx.h @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file pb57xx.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __pb57xx_H_wqIH3HdS_l3C8_Hgh6_syur_ubmEVDiPX8aR__ +#define __pb57xx_H_wqIH3HdS_l3C8_Hgh6_syur_ubmEVDiPX8aR__ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(CONFIG_USE_PB5700) + #include "pb5700.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/Drivers/PB5700/Device/inc/system_dev.h b/Drivers/PB5700/Device/inc/system_dev.h new file mode 100644 index 0000000..4ad3baf --- /dev/null +++ b/Drivers/PB5700/Device/inc/system_dev.h @@ -0,0 +1,390 @@ +/** + * 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 */ +#ifndef __riscv_32e + uint32_t a6; /* a6: x16, function argument 6 */ + uint32_t a7; /* a7: x17, function argument 7 */ + uint32_t t3; /* t3: x28, temporary register 3 */ + uint32_t t4; /* t4: x29, temporary register 4 */ + uint32_t t5; /* t5: x30, temporary register 5 */ + uint32_t t6; /* t6: x31, temporary register 6 */ +#endif +} 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); + 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/Drivers/PB5700/Device/src/Startup/startup.S b/Drivers/PB5700/Device/src/Startup/startup.S new file mode 100644 index 0000000..1d59b32 --- /dev/null +++ b/Drivers/PB5700/Device/src/Startup/startup.S @@ -0,0 +1,158 @@ +/* + * 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 + 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 + + /** + * Set the the NMI base mnvec to share + * with mtvec by setting CSR_MMISC_CTL + * bit 9 NMI_CAUSE_FFF to 1 + */ + 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/Drivers/PB5700/Device/src/Startup/trap.S b/Drivers/PB5700/Device/src/Startup/trap.S new file mode 100644 index 0000000..1fa05d0 --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/Device/src/interrupt.c b/Drivers/PB5700/Device/src/interrupt.c new file mode 100644 index 0000000..af9297e --- /dev/null +++ b/Drivers/PB5700/Device/src/interrupt.c @@ -0,0 +1,137 @@ +/** + * 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 "pb57xx.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 */ +#if 0 + default_handler, /* 34: ext_irq Reserved */ + default_handler, /* 35: ext_irq Reserved */ + default_handler, /* 36: ext_irq Reserved */ + default_handler, /* 37: ext_irq Reserved */ + default_handler, /* 38: ext_irq Reserved */ + default_handler, /* 39: ext_irq Reserved */ + default_handler, /* 40: ext_irq Reserved */ + default_handler, /* 41: ext_irq Reserved */ + default_handler, /* 42: ext_irq Reserved */ + default_handler, /* 43: ext_irq Reserved */ + default_handler, /* 44: ext_irq Reserved */ + default_handler, /* 45: ext_irq Reserved */ + default_handler, /* 46: ext_irq Reserved */ + default_handler, /* 47: ext_irq Reserved */ + default_handler, /* 48: ext_irq Reserved */ + default_handler, /* 49: ext_irq Reserved */ +#endif +}; diff --git a/Drivers/PB5700/Device/src/syscalls.c b/Drivers/PB5700/Device/src/syscalls.c new file mode 100644 index 0000000..92edc9f --- /dev/null +++ b/Drivers/PB5700/Device/src/syscalls.c @@ -0,0 +1,214 @@ +/** + * 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) +{ +#if 0 + extern char _end[]; + extern char _heap_end[]; + static char *curbrk = _end; + + if ((curbrk + incr < _end) || (curbrk + incr > _heap_end)) { + return (void *)(-1); + } + + curbrk += incr; + return (void *)(curbrk - incr); +#else + return 0; +#endif +} diff --git a/Drivers/PB5700/Device/src/system_dev.c b/Drivers/PB5700/Device/src/system_dev.c new file mode 100644 index 0000000..caae90c --- /dev/null +++ b/Drivers/PB5700/Device/src/system_dev.c @@ -0,0 +1,418 @@ +/** + * 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 "pb57xx.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); + + 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/Drivers/PB5700/Flash/readme.md b/Drivers/PB5700/Flash/readme.md new file mode 100644 index 0000000..e473025 --- /dev/null +++ b/Drivers/PB5700/Flash/readme.md @@ -0,0 +1,10 @@ +flash-loader +--- + +## flash-loader for eFlash + +`loader.bin` is used to download data (on Host) to DUT eFlash +> OpenOCD should use `pb5700.cfg` to setup environment + ++ flash-loader will be put at `0x2000_0A00` of DUT + > It uses 1.5KB (?) as executing area diff --git a/Drivers/PB5700/HAL_Lib/inc/hal_adc.h b/Drivers/PB5700/HAL_Lib/inc/hal_adc.h new file mode 100644 index 0000000..c9a6953 --- /dev/null +++ b/Drivers/PB5700/HAL_Lib/inc/hal_adc.h @@ -0,0 +1,502 @@ +/** + * 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, + ADC_SubChannel_TEMP = AMISC_VBUF_CR_ANA_SEL_TEMP, + ADC_SubChannel_DAC0 = AMISC_VBUF_CR_ANA_SEL_DAC0, + ADC_SubChannel_DAC1 = AMISC_VBUF_CR_ANA_SEL_DAC1, + ADC_SubChannel_VBuf_1_5 = AMISC_VBUF_CR_ANA_SEL_VBuf_1p5v, + ADC_SubChannel_VDDL = AMISC_VBUF_CR_ANA_SEL_VDDL, + ADC_SubChannel_VSS = AMISC_VBUF_CR_ANA_SEL_VSS, + ADC_SubChannel_VDD = AMISC_VBUF_CR_ANA_SEL_VDD, +} 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_64 = (ADC_CON0_CLK_Div64 << 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_07, /*!< ADC external source trigger from COMP1 Rising */ + ADC_ExtTrigSource_COMP0_Fall = ADC_ExtTrigSource_08, /*!< 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_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->CON0, 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); + 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 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 + */ +__STATIC_FORCEINLINE void ADC_SelSubChannel(ADC_SubChannelTypeDef subchannel) +{ + REG_WRITE_MASK(AMISC->VBUF_CR, AMISC_VBUF_CR_ANA_SEL_Msk, subchannel); + 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); +} + +//============================================================================= +// 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 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/Drivers/PB5700/HAL_Lib/inc/hal_amisc.h b/Drivers/PB5700/HAL_Lib/inc/hal_amisc.h new file mode 100644 index 0000000..ac68d1b --- /dev/null +++ b/Drivers/PB5700/HAL_Lib/inc/hal_amisc.h @@ -0,0 +1,387 @@ +/** + * 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_Ana2IO_Disable = 0x0, //AMISC_Ana2IO_En + AMISC_Ana2IO_En = AMISC_VBUF_CR_ANA2IO_EN_Msk, + +} AMISC_Ana2IOTypeDef; + +typedef enum +{ + AMISC_Ana2PGA_Disable = 0x0, // AMISC_Ana2PGA_En + AMISC_Ana2PGA_Ene = AMISC_VBUF_CR_ANA2PGA_EN_Msk , + +} AMISC_Ana2PGATypeDef ; + +typedef enum +{ + AMISC_AnaSel_temp = 0x1 << AMISC_VBUF_CR_ANA_SEL_Pos, + AMISC_AnaSel_dac0 = 0x2 << AMISC_VBUF_CR_ANA_SEL_Pos, + AMISC_AnaSel_dac1 = 0x4 << AMISC_VBUF_CR_ANA_SEL_Pos, + AMISC_AnaSel_1p5v = 0x8 << AMISC_VBUF_CR_ANA_SEL_Pos, + AMISC_AnaSel_vddl = 0x10 << AMISC_VBUF_CR_ANA_SEL_Pos, + AMISC_AnaSel_vss = 0x20 << AMISC_VBUF_CR_ANA_SEL_Pos, + AMISC_AnaSel_v = 0x40 << AMISC_VBUF_CR_ANA_SEL_Pos, + +} AMISC_AnaSelTypeDef ; + + +//============================================================================= +// 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 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; +} + + + + + +//============================================================================= +// Structure Definition +//============================================================================= +typedef struct +{ + AMISC_LVDVoltageTypeDef LVD_Voltage; + AMISC_LVRVoltageTypeDef LVR_Voltage; + AMISC_LVDFuncTypeDef LVD_FuncModes; + +} AMISC_LVDRInitTypeDef; + +typedef struct +{ + AMISC_Ana2IOTypeDef Ana2IOT; + AMISC_Ana2PGATypeDef Ana2PGA; + AMISC_AnaSelTypeDef AnaSel; + +} AMISC_VBUFConfigTypeDef; + + +//============================================================================= +// 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); + + +void AMISC_VBUF_Config(AMISC_VBUFConfigTypeDef *pInit); + + + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Drivers/PB5700/HAL_Lib/inc/hal_comp.h b/Drivers/PB5700/HAL_Lib/inc/hal_comp.h new file mode 100644 index 0000000..6d04df2 --- /dev/null +++ b/Drivers/PB5700/HAL_Lib/inc/hal_comp.h @@ -0,0 +1,204 @@ +/** + * 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 +//============================================================================= +/** + * the voltige input_n of Comparer + */ +typedef enum COMP_Vin +{ + COMP_Vin_IO = (COMP_CTRL_VIN_SEL_IO << COMP_CTRL_VIN_SEL_Pos), + COMP_Vin_DAC = (COMP_CTRL_VIN_SEL_DAC << COMP_CTRL_VIN_SEL_Pos), + +} COMP_VinTypeDef; + +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; + +/** + * the voltige input_p of Comparer + */ +typedef enum COMP_Vip +{ + COMP_Vip_PGA = (COMP_VIPSEL_VIP_SEL_PGA << COMP_VIPSEL_VIP_SEL_Pos), + COMP_Vip_IO0 = (COMP_VIPSEL_VIP_SEL_IO0 << COMP_VIPSEL_VIP_SEL_Pos), + COMP_Vip_IO1 = (COMP_VIPSEL_VIP_SEL_IO1 << COMP_VIPSEL_VIP_SEL_Pos), + COMP_Vip_IO2 = (COMP_VIPSEL_VIP_SEL_IO2 << COMP_VIPSEL_VIP_SEL_Pos), + COMP_Vip_IO3 = (COMP_VIPSEL_VIP_SEL_IO3 << COMP_VIPSEL_VIP_SEL_Pos), + +} COMP_VipTypeDef; + + +typedef enum COMP_Polarity +{ + COMP_Polarity_Normal = (COMP_CTRL_POL_SEL_NORMAL << COMP_CTRL_POL_SEL_Pos), + COMP_Polarity_Invert = (COMP_CTRL_POL_SEL_INVERT << COMP_CTRL_POL_SEL_Pos), + +} COMP_PolarityTypeDef; + +/** + * Interrupt type of Comparer + */ +typedef enum COMP_IE +{ + 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; + +/** + * Out type of Comparer + */ + +typedef enum COMP_Out +{ + COMP_Out_Disable = 0x0, + COMP_Out_Enable = COMP_CTRL_OUT_EN_Msk, + +} COMP_OutTypeDef; + +typedef enum COMP_Hsy +{ + COMP_Hsy_Disable = 0x0, + COMP_Hsy_Enable = COMP_CTRL_HYS_EN_Msk, + +} COMP_HsyTypeDef; + + +//============================================================================= +// 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); +} + + +//============================================================================= +// Structure Definition +//============================================================================= + +typedef struct +{ + COMP_VinTypeDef COMP_NegativeSel; /*!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); +} +//============================================================================= +// 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/Drivers/PB5700/HAL_Lib/inc/hal_dsp.h b/Drivers/PB5700/HAL_Lib/inc/hal_dsp.h new file mode 100644 index 0000000..0903011 --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/HAL_Lib/inc/hal_flash.h b/Drivers/PB5700/HAL_Lib/inc/hal_flash.h new file mode 100644 index 0000000..8d80be5 --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/HAL_Lib/inc/hal_gpio.h b/Drivers/PB5700/HAL_Lib/inc/hal_gpio.h new file mode 100644 index 0000000..6934ae0 --- /dev/null +++ b/Drivers/PB5700/HAL_Lib/inc/hal_gpio.h @@ -0,0 +1,408 @@ +/** + * 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_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->IES, 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 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/Drivers/PB5700/HAL_Lib/inc/hal_i2c.h b/Drivers/PB5700/HAL_Lib/inc/hal_i2c.h new file mode 100644 index 0000000..05cd0b3 --- /dev/null +++ b/Drivers/PB5700/HAL_Lib/inc/hal_i2c.h @@ -0,0 +1,152 @@ +/** + * 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 +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +/************************************************************************************************************* +* STAT_I2C_STAT) : I2C Status Register (bit[7:3]total 26 flags), 26 states can generate interrupt requests. +**************************************************************************************************************/ +#define I2C_MASTER_START_ACK (0x01ul) +#define I2C_MASTER_RPTSTART_ACK (0x02ul) +#define I2C_MASTER_WRDEVADREND_ACK (0x03ul) +#define I2C_MASTER_WRDEVADREND_NACK (0x04ul) +#define I2C_MASTER_WRDATEND_ACK (0x05ul) +#define I2C_MASTER_WRDATEND_NACK (0x06ul) +#define I2C_MASTER_WR_BUSLOST (0x07ul) +#define I2C_MASTER_WRADR_RDCMD_ACK (0x08ul) +#define I2C_MASTER_WRADR_RDCMD_NACK (0x09ul) +#define I2C_RXDAT_TXACK (0x0Aul) +#define I2C_RXDAT_TXNACK (0x0Bul) +#define I2C_SLAVE_WRCMD_ACK (0x0Cul) +#define I2C_SLAVE_RXADR_WRCMD_ACK (0x0Dul) +#define I2C_RX_BROADCASTADR_ACK (0x0Eul) +#define I2C_SLAVE_RXBROADCASTADR_ACK (0x0Ful) +#define I2C_SLAVE_RXNEXTDAT_ACK (0x10ul) +#define I2C_SLAVE_RXNEXTDAT_NACK (0x11ul) +#define I2C_BROADCAST_RXNEXTDAT_ACK (0x12ul) +#define I2C_BROADCAST_RXNEXTDAT_NACK (0x13ul) +#define I2C_SLAVE_RXSTOP_OR_RPTSTAT (0x14ul) +#define I2C_SLAVE_RXADR_RXCMD_ACK (0x15ul) +#define I2C_BUSLOST_SLAVE_RXADR_RXCMD_ACK (0x16ul) +#define I2C_SLAVE_TXDAT_ACK (0x17ul) +#define I2C_SLAVE_TXDAT_NACK (0x18ul) +#define I2C_SLAVE_TXLASTDAT_ACK (0x19ul) +#define I2C_BUS_FREE (0x1Ful) + +/** + * @brief I2C mode definition + */ +#define I2C_Own_Address 0x55 + +#define I2C_Mode_Master 0x01 +#define I2C_Mode_Slave 0x00 + +typedef enum I2C_Clk_Div +{ + I2C_CLK_Div60 = 0, + I2C_CLK_Div120, + I2C_CLK_Div160, + I2C_CLK_Div192, + I2C_CLK_Div244, + I2C_CLK_Div256, + I2C_CLK_Div960 + +} I2C_Clk_DivTypeDef; + +typedef enum +{ + I2C_STA_RESET = 0, + I2C_STA_SET + +} I2C_StartFlagTypeDef; + +typedef enum +{ + I2C_STO_RESET = 0, + I2C_STO_SET +} I2C_StopStaTypeDef; + +typedef enum +{ + I2C_SI_RESET = 0, + I2C_SI_SET +} I2C_SiStaTypeDef; + +typedef enum +{ + I2C_AA_RESET = 0, + I2C_AA_SET +} I2C_AckStaTypeDef; + +typedef struct +{ + uint16_t I2C_Mode; /*!< Specifies the I2C mode. This parameter can be a value of I2C_mode. */ + uint16_t I2C_OwnAddress; /*!< Specifies the first device own address. This parameter can be a 7-bit or 10-bit address. */ + I2C_Clk_DivTypeDef I2C_ClockDiv; +} I2C_InitTypeDef; + +void I2C_DeInit(I2C_Type *i2c); +void I2C_Cmd(I2C_Type *i2c, FunctionalState state); +void I2C_Init(I2C_Type *i2c, I2C_InitTypeDef *init_struct); +void I2C_StructInit(I2C_InitTypeDef *init_struct); +void I2C_ClkDivConfig(I2C_Type *i2c, uint32_t I2C_ClockDivCr0,uint32_t I2C_ClockDivCr1,uint32_t I2C_ClockDivCr2); +void I2C_GenerateSTART(I2C_Type *i2c, FunctionalState state); +void I2C_GenerateSTOP(I2C_Type *i2c, FunctionalState state); +void I2C_TargetAddressConfig(I2C_Type *i2c, uint8_t addr); +void I2C_GeneralCallCmd(I2C_Type *i2c, FunctionalState state); +void I2C_ITConfig(I2C_Type *i2c, FunctionalState state); +void I2C_SendData(I2C_Type *i2c, uint8_t dat); +void I2C_ReadCmd(I2C_Type *i2c); +void I2C_StaFlagConfig(I2C_Type *i2c, I2C_StartFlagTypeDef sta,I2C_StopStaTypeDef sto,I2C_SiStaTypeDef si,I2C_AckStaTypeDef aa); +void I2C_GenerateRESTART(I2C_Type *i2c, FunctionalState state); +uint8_t I2C_ReceiveData(I2C_Type *i2c); +uint32_t I2C_GetLastEvent(I2C_Type *i2c); +ErrorStatus I2C_CheckEvent(I2C_Type *i2c, uint32_t event); +FlagStatus I2C_GetFlagStatus(I2C_Type *i2c, uint32_t flag); +uint32_t I2C_GetSlaveReceivedAddr(I2C_Type *i2c); +ITStatus I2C_GetITStatus(I2C_Type *i2c, uint32_t it); +uint32_t I2C_GetSta(I2C_Type *i2c); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Drivers/PB5700/HAL_Lib/inc/hal_lptim.h b/Drivers/PB5700/HAL_Lib/inc/hal_lptim.h new file mode 100644 index 0000000..e72cffa --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/HAL_Lib/inc/hal_opamp.h b/Drivers/PB5700/HAL_Lib/inc/hal_opamp.h new file mode 100644 index 0000000..efa35b0 --- /dev/null +++ b/Drivers/PB5700/HAL_Lib/inc/hal_opamp.h @@ -0,0 +1,184 @@ +/** + * 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_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/Drivers/PB5700/HAL_Lib/inc/hal_pwr.h b/Drivers/PB5700/HAL_Lib/inc/hal_pwr.h new file mode 100644 index 0000000..a48e263 --- /dev/null +++ b/Drivers/PB5700/HAL_Lib/inc/hal_pwr.h @@ -0,0 +1,100 @@ +/** + * 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 +//============================================================================= +typedef enum PWR_Mode +{ + PWR_Mode_Sleep = 0, + PWR_Mode_DeepSleep, + +} PWR_ModeTypeDef; + + +/** + * \brief Set a peripheral before entering deep-sleep + * + */ +typedef void (*CallbaskPreDeepsleepTypeDef)(void); + +/** + * \brief Set a peripheral after deep-sleep wake-up + * ps. This callback function ONLY supports to set ONE peripheral + */ +typedef void (*CallbaskPostDeepsleepTypeDef)(void); + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +/** + * @brief Set duration of auto wake-up + * + * @param [in] msec the duration of auto wakeup from sleep/deepsleep mode + * @return + * None + */ +void PWR_SetAutoWakeUp(uint32_t msec); + +/** + * \brief Enters 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_EnterSleepMode(CallbaskPreDeepsleepTypeDef cb_pre_set, + CallbaskPostDeepsleepTypeDef 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(CallbaskPreDeepsleepTypeDef cb_pre_set, + CallbaskPostDeepsleepTypeDef cb_post_set); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Drivers/PB5700/HAL_Lib/inc/hal_spi.h b/Drivers/PB5700/HAL_Lib/inc/hal_spi.h new file mode 100644 index 0000000..98f9777 --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/HAL_Lib/inc/hal_syscfg.h b/Drivers/PB5700/HAL_Lib/inc/hal_syscfg.h new file mode 100644 index 0000000..539f293 --- /dev/null +++ b/Drivers/PB5700/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 the Alternate Function mode of Reset-Pin + * + * \param [in] has_rst_pin Enable Reset-Pin function or not + * \return + * None + */ +__STATIC_FORCEINLINE void SYSCFG_SetRstPinAF(int has_rst_pin) +{ + (has_rst_pin) + ? REG_WRITE_MASK(SYSCFG->RSTPINCR, SYSCFG_RSTPINCR_RSTPINAF_Msk, SYSCFG_RSTPINCR_RSTPINAF_ON << SYSCFG_RSTPINCR_RSTPINAF_Pos) + : REG_WRITE_MASK(SYSCFG->RSTPINCR, SYSCFG_RSTPINCR_RSTPINAF_Msk, SYSCFG_RSTPINCR_RSTPINAF_OFF << 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/Drivers/PB5700/HAL_Lib/inc/hal_tim.h b/Drivers/PB5700/HAL_Lib/inc/hal_tim.h new file mode 100644 index 0000000..5204c8e --- /dev/null +++ b/Drivers/PB5700/HAL_Lib/inc/hal_tim.h @@ -0,0 +1,538 @@ +/** + * 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. */ +} 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 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 */ + + +/** + * @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 (0x01U << 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 (0x01U << 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 ((uint16_t)0x0000) +#define TIM_ExtTRGPSC_DIV2 ((uint16_t)0x1000) +#define TIM_ExtTRGPSC_DIV4 ((uint16_t)0x2000) +#define TIM_ExtTRGPSC_DIV8 ((uint16_t)0x3000) + +/** @defgroup TIM_External_Trigger_Polarity + * @{ + */ +#define TIM_ExtTRGPolarity_Inverted ((uint16_t)0x8000) +#define TIM_ExtTRGPolarity_NonInverted ((uint16_t)0x0000) + +//============================================================================= +// 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_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_OC5PreloadConfig(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_SetCompare5(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_GetCapture5(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); +void TIM_SetCCR5FALL(TIM_Type *tim, uint32_t shift); +FlagStatus TIM_GetCountDirection(TIM_Type *tim); + +uint32_t TIM_GetTIMxClock(TIM_Type *tim); + +void TIM_ETRClockMode2Config(TIM_Type* TIMx, uint16_t TIM_ExtTRGPrescaler,uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Drivers/PB5700/HAL_Lib/inc/hal_uart.h b/Drivers/PB5700/HAL_Lib/inc/hal_uart.h new file mode 100644 index 0000000..c329035 --- /dev/null +++ b/Drivers/PB5700/HAL_Lib/inc/hal_uart.h @@ -0,0 +1,301 @@ +/** + * 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, 0x5700); + 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, 0x5700); + 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); + + +/** + * @brief UART_Interrupt_definition + */ +#define UART_IT_RXNE (0x01U << UART_IE_RXNEE_Pos) /*!< RXNE interrupt enable */ +#define UART_IT_TXE (0x01U << UART_IE_TXEE_Pos) /*!< TXE interrupt enable */ +#define UART_IT_TXHE (0x01U << UART_IE_TXHEE_Pos) /*!< TXHE interrupt enable */ +#define UART_IT_PERR (0x01U << UART_IE_PERRE_Pos) /*!< PERR interrupt enable */ +#define UART_IT_FERR (0x01U << UART_IE_FERRE_Pos) /*!< FERR interrupt enable */ +#define UART_IT_OVERR (0x01U << UART_IE_OVERRE_Pos) /*!< OVERR interrupt enable */ +#define UART_IT_TONE (0x01U << UART_IE_TONEE_Pos) /*!< TONE Interrupt enable */ +#define UART_IT_TOIDLE (0x01U << UART_IE_TOIDLEE_Pos) /*!< TOIDLE interrupt enable */ +#define UART_IT_RXHF (0x01U << UART_IE_RXHFE_Pos) /*!< RXHF interrupt enable */ +#define UART_IT_RXF (0x01U << UART_IE_RXFE_Pos) /*!< RXF interrupt enable */ +#define UART_IT_TXEND (0x01U << UART_IE_TXENDE_Pos) /*!< TXEND interrupt enable */ +#define UART_IT_TXF (0x01U << UART_IE_TXFE_Pos) /*!< TXF interrupt enable */ + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Drivers/PB5700/HAL_Lib/inc/hal_wdg.h b/Drivers/PB5700/HAL_Lib/inc/hal_wdg.h new file mode 100644 index 0000000..44bbe12 --- /dev/null +++ b/Drivers/PB5700/HAL_Lib/inc/hal_wdg.h @@ -0,0 +1,89 @@ +/** + * 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 +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +typedef struct +{ + uint32_t Relaod; + uint32_t Reset; + uint32_t Debug; +} WDG_BaseInitTypeDef; + + +#define WDG_Reset_En (0x1U << WDG_CR_RSTE_Pos) +#define WDG_Reset_Dis (0x0U << WDG_CR_RSTE_Pos) + +#define WDG_Debug_En (0x1U << WDG_CR_DBGE_Pos) +#define WDG_Debug_Dis (0x0U << WDG_CR_DBGE_Pos) + + + +void WDG_BaseStructInit(WDG_BaseInitTypeDef *init_struct); +void WDG_BaseInit( WDG_BaseInitTypeDef *init_struct); +void WDG_SetReload(uint32_t reload); +void WDG_Enable(void); +void WDG_Disable(void); +uint32_t WDG_GetCountValue(void); +void WDG_ClearITFlag(void); +void WDG_Clear(void); +void WDG_Unlock(void); +void WDG_Lock(void); +uint32_t WDG_GetLockStatus(void); +uint32_t WDG_GetRIF(uint32_t rif_bit_mask); +uint32_t WDG_GetMIF(uint32_t mif_bit_mask); + + + + + + + + + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Drivers/PB5700/HAL_Lib/src/hal_adc.c b/Drivers/PB5700/HAL_Lib/src/hal_adc.c new file mode 100644 index 0000000..fcbf644 --- /dev/null +++ b/Drivers/PB5700/HAL_Lib/src/hal_adc.c @@ -0,0 +1,278 @@ +/** + * 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 1000 + +#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); + 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_15; + 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; +} + +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)); + +#if 0 + 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; + } +#endif + + 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/Drivers/PB5700/HAL_Lib/src/hal_amisc.c b/Drivers/PB5700/HAL_Lib/src/hal_amisc.c new file mode 100644 index 0000000..9db059a --- /dev/null +++ b/Drivers/PB5700/HAL_Lib/src/hal_amisc.c @@ -0,0 +1,129 @@ +/** + * 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(); + 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(); + 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_VBUF_Config(AMISC_VBUFConfigTypeDef *pInit) +{ + REG_WRITE_MASK(AMISC->VBUF_CR, + AMISC_VBUF_CR_ANA2IO_EN_Msk | AMISC_VBUF_CR_ANA2PGA_EN_Msk | \ + AMISC_VBUF_CR_ANA_SEL_Msk , + pInit->Ana2IOT | pInit->Ana2PGA | pInit->AnaSel); +} + +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; +} + + + +#endif /* CONFIG_ENABLE_HAL_AMISC */ diff --git a/Drivers/PB5700/HAL_Lib/src/hal_comp.c b/Drivers/PB5700/HAL_Lib/src/hal_comp.c new file mode 100644 index 0000000..f9bb482 --- /dev/null +++ b/Drivers/PB5700/HAL_Lib/src/hal_comp.c @@ -0,0 +1,86 @@ +/** + * 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_Init(COMP_Type *pHComp, COMP_InitTypeDef *pInit) +{ + if( pHComp == COMP0 ) + { + __HAL_SYSCFG_COMP0_CLK_ENABLE(); + __HAL_SYSCFG_RESET_COMP0(); + } + else if( pHComp == COMP1 ) + { + __HAL_SYSCFG_COMP1_CLK_ENABLE(); + __HAL_SYSCFG_RESET_COMP1(); + } + + 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->COMP_NegativeSel | pInit->COMP_Filter | pInit->COMP_Polarity | + pInit->COMP_Out | pInit->COMP_Hsy); + + REG_WRITE_MASK(pHComp->VIPSEL, COMP_VIPSEL_VIP_SEL_Msk, pInit->COMP_PositiveSel); + + REG_WRITE_MASK(pHComp->IR, + COMP_IR_RIE_Msk | COMP_IR_FIE_Msk, + pInit->COMP_Interrupt); + + REG_WRITE_MASK(pHComp->INITCNT, + COMP_INITCNT_INIT_DELAY_Msk, + pInit->COMP_InitDelay); + + return; +} + +void COMP_DeInit(COMP_Type *pHComp) +{ + if( pHComp == COMP0 ) + { + __HAL_SYSCFG_COMP0_CLK_DISABLE(); + } + else if( pHComp == COMP1 ) + { + __HAL_SYSCFG_COMP1_CLK_DISABLE(); + } + return; +} + +#endif /* CONFIG_ENABLE_HAL_VCMP */ diff --git a/Drivers/PB5700/HAL_Lib/src/hal_crc.c b/Drivers/PB5700/HAL_Lib/src/hal_crc.c new file mode 100644 index 0000000..e0a4620 --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/HAL_Lib/src/hal_device.c b/Drivers/PB5700/HAL_Lib/src/hal_device.c new file mode 100644 index 0000000..3ca803a --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/HAL_Lib/src/hal_dsp.c b/Drivers/PB5700/HAL_Lib/src/hal_dsp.c new file mode 100644 index 0000000..8a0660c --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/HAL_Lib/src/hal_flash.c b/Drivers/PB5700/HAL_Lib/src/hal_flash.c new file mode 100644 index 0000000..a7a53df --- /dev/null +++ b/Drivers/PB5700/HAL_Lib/src/hal_flash.c @@ -0,0 +1,266 @@ +/** + * 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 +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// 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; + + REG_WRITE(FLASH->DIV, SYS_HIRC_MHZ | (0x1ul << 8)); // move to system init ??? + + 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; + } + + 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; + } + + 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; + + 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; + } + + 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/Drivers/PB5700/HAL_Lib/src/hal_gpio.c b/Drivers/PB5700/HAL_Lib/src/hal_gpio.c new file mode 100644 index 0000000..d1fdb99 --- /dev/null +++ b/Drivers/PB5700/HAL_Lib/src/hal_gpio.c @@ -0,0 +1,209 @@ +/** + * 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_CLR_BITS(pHGpio->CTC, pin_cur); + REG_SET_BITS(pHGpio->CTS, 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); + (pInit->GPIO_OType == GPIO_OType_OD) + ? REG_SET_BITS(pHGpio->ODS, pin_cur) + : REG_SET_BITS(pHGpio->ODC, 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); + } + + break; + + case GPIO_Mode_ANAL: /* Analog mode */ + REG_SET_BITS(pHGpio->INEC, pin_cur); + + // disable Schmitt-Trigger + REG_CLR_BITS(pHGpio->CTS, pin_cur); + REG_SET_BITS(pHGpio->CTC, 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_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); // any trigger + } + else if( pInit->GPIO_Trigger == GPIO_Trigger_Edge ) + { + REG_SET_BITS(pHGpio->ITS0, pins); // Edge trigger + } + else + { + 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/Drivers/PB5700/HAL_Lib/src/hal_i2c.c b/Drivers/PB5700/HAL_Lib/src/hal_i2c.c new file mode 100644 index 0000000..b67d1d9 --- /dev/null +++ b/Drivers/PB5700/HAL_Lib/src/hal_i2c.c @@ -0,0 +1,288 @@ +/** + * 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 +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +/** + * @brief Deinitializes the i2c peripheral registers to their default + * reset values. + * @param i2c1. + * @retval None. + */ +void I2C_DeInit(I2C_Type *i2c) +{ + __HAL_SYSCFG_RESET_I2C(); +} + +/** + * @brief Initializes the i2c peripheral according to the specified + * parameters in the init_struct. + * @param i2c: select the I2C peripheral. + * @param init_struct: pointer to a I2C_InitTypeDef structure that + * contains the configuration information for the specified + * I2C peripheral. + * @retval None. + */ +void I2C_Init(I2C_Type *i2c, I2C_InitTypeDef *init_struct) +{ + __HAL_SYSCFG_I2C_CLK_ENABLE() ; + REG_WRITE_MASK(i2c->ADDR, I2C_ADDR_ADDR_Msk, init_struct->I2C_OwnAddress); + switch(init_struct->I2C_ClockDiv) + { + case (I2C_CLK_Div60): + I2C_ClkDivConfig(i2c,0,1,1); + break; + case (I2C_CLK_Div120): + I2C_ClkDivConfig(i2c,1,0,1); + break; + case (I2C_CLK_Div160): + I2C_ClkDivConfig(i2c,1,1,0); + break; + case (I2C_CLK_Div192): + I2C_ClkDivConfig(i2c,0,1,0); + break; + case (I2C_CLK_Div244): + I2C_ClkDivConfig(i2c,1,0,0); + break; + case (I2C_CLK_Div256): + I2C_ClkDivConfig(i2c,0,0,0); + break; + case (I2C_CLK_Div960): + I2C_ClkDivConfig(i2c,0,0,1); + break; + default: + break; + } + +} +void I2C_ClkDivConfig(I2C_Type *i2c, uint32_t I2C_ClockDivCr0,uint32_t I2C_ClockDivCr1,uint32_t I2C_ClockDivCr2) +{ + (I2C_ClockDivCr0) ? \ + (REG_WRITE_MASK(i2c->CTLSET, I2C_CTLSET_CR0_Msk, 1 << I2C_CTLSET_CR0_Pos)) : \ + (REG_WRITE_MASK(i2c->CTLCLR, I2C_CTLCLR_CR0_Msk, 1 << I2C_CTLCLR_CR0_Pos)); + (I2C_ClockDivCr1) ? \ + (REG_WRITE_MASK(i2c->CTLSET, I2C_CTLSET_CR1_Msk, 1 << I2C_CTLSET_CR1_Pos)) : \ + (REG_WRITE_MASK(i2c->CTLCLR, I2C_CTLCLR_CR1_Msk, 1 << I2C_CTLCLR_CR1_Pos)); + (I2C_ClockDivCr2) ? \ + (REG_WRITE_MASK(i2c->CTLSET, I2C_CTLSET_CR2_Msk, 1 << I2C_CTLSET_CR2_Pos)) : \ + (REG_WRITE_MASK(i2c->CTLCLR, I2C_CTLCLR_CR2_Msk, 1 << I2C_CTLCLR_CR2_Pos)); +} +/** + * @brief Fills each init_struct member with its default value. + * @param init_struct: pointer to an I2C_InitTypeDef structure + * which will be initialized. + * @retval None. + */ +void I2C_StructInit(I2C_InitTypeDef *init_struct) +{ + init_struct->I2C_Mode = I2C_Mode_Master; + init_struct->I2C_OwnAddress = I2C_Own_Address; + init_struct->I2C_ClockDiv = I2C_CLK_Div256; +} + +/** + * @brief Enables or disables the specified I2C peripheral. + * @param i2c: select the I2C peripheral. + * @param state: new state of the i2c peripheral. This parameter + * can be: ENABLE or DISABLE. + * @retval None. + */ +void I2C_Cmd(I2C_Type *i2c, FunctionalState state) +{ + (state) ? \ + (i2c->CTLSET |= (0x01U << I2C_CTLSET_EN_Pos)) : \ + (i2c->CTLCLR |= (0x01U << I2C_CTLCLR_EN_Pos)) ; +} + +/** + * @brief Generates i2c communication START condition. + * @param i2c: select the I2C peripheral. + * @param state: new state of the I2C START condition generation. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void I2C_GenerateSTART(I2C_Type *i2c, FunctionalState state) +{ + (state) ? \ + (i2c->CTLSET |= (0x01U << I2C_CTLSET_STA_Pos)) : \ + (i2c->CTLCLR |= (0x01U << I2C_CTLCLR_STA_Pos)); +} + +void I2C_GenerateRESTART(I2C_Type *i2c, FunctionalState state) +{ + (state) ? \ + (i2c->CTLSET |= (0x01U << I2C_CTLSET_STA_Pos)) : \ + (i2c->CTLCLR |= (0x01U << I2C_CTLCLR_STA_Pos)); +} +/** + * @brief Generates i2c communication STOP condition. + * @param i2c: select the I2C peripheral. + * @param state: new state of the I2C STOP condition generation. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void I2C_GenerateSTOP(I2C_Type *i2c, FunctionalState state) +{ + (state) ? \ + (i2c->CTLSET |= (0x01U << I2C_CTLSET_STO_Pos)) : \ + (i2c->CTLCLR |= (0x01U << I2C_CTLCLR_STO_Pos)); +} + +/** + * @brief Configures the specified I2C Target Address. + * @param i2c: select the I2C peripheral. + * @param addr: specifies the 7bit I2C Target Address. + * @retval None. + */ +void I2C_TargetAddressConfig(I2C_Type *i2c, uint8_t addr) +{ + REG_WRITE_MASK(i2c->ADDR, I2C_ADDR_ADDR_Msk, addr << 1); +} + + +/** + * @brief Enables or disables the specified I2C interrupts. + * @param i2c: select the I2C peripheral. + * @param it: specifies the I2C interrupts sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg : + * @param state: new state of the specified I2C interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void I2C_ITConfig(I2C_Type *i2c, FunctionalState state) +{ + (state) ? \ + (i2c->CTLSET |= (0x01U << I2C_CTLSET_SI_Pos)) : \ + (i2c->CTLCLR |= (0x01U << I2C_CTLCLR_SI_Pos)); +} + +/** + * @brief Sends a data byte through the i2c peripheral. + * @param i2c: select the I2C peripheral. + * @param dat: Byte to be transmitted.. + * @retval None. + */ +void I2C_SendData(I2C_Type *i2c, uint8_t dat) +{ + i2c->DATA_b.DATA = dat; +} + + +/** + * @brief Returns the most recent received data by the i2c peripheral. + * @param i2c: select the I2C peripheral. + * @retval The value of the received data. + */ +uint8_t I2C_ReceiveData(I2C_Type *i2c) +{ + return ((uint8_t)i2c->DATA_b.DATA ); +} + +/** + * @brief Checks whether the specified I2C flag is set or not. + * @param i2c: select the I2C peripheral. + * @param flag: specifies the flag to check. + * This parameter can be one of the following values: + * @arg : + * @retval The new state of I2C_FLAG (SET or RESET). + */ +FlagStatus I2C_GetFlagStatus(I2C_Type *i2c, uint32_t flag) +{ + return ((i2c->STAT_b.STAT == flag) ? SET : RESET); +} + +/** + * @brief Clears the i2c's pending flags. + * @param i2c: select the I2C peripheral. + * @param flag: specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg I2C_START_RESET : Rx Buffer is empty flag + * @arg I2C_START_SET : RX Buffer Overrun flag + * @arg I2C_STO_RESET : Rx buffer full flag + * @arg I2C_STO_SET : TX Buffer Overrun flag + * @arg I2C_SI_RESET : TX_FIFO empty flag + * @arg I2C_SI_SET : I2C work as slave or master flag + * @arg I2C_AA_RESET : TX error flag(Master mode) + * @arg I2C_AA_SET : Master not ack flag(slave mode) + * @retval None. + */ +void I2C_ClearFlag(I2C_Type *i2c, uint32_t flag) +{ + +} +/** + * @brief Config the i2c's flags. + * @param i2c: select the I2C peripheral. + * @param flag: specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg : + * @retval None. + */ +void I2C_StaFlagConfig(I2C_Type *i2c, I2C_StartFlagTypeDef sta,I2C_StopStaTypeDef sto,I2C_SiStaTypeDef si,I2C_AckStaTypeDef aa) +{ + (sta) ? \ + (REG_WRITE_MASK(i2c->CTLSET, I2C_CTLSET_STA_Msk, 1 << I2C_CTLSET_STA_Pos)) : \ + (REG_WRITE_MASK(i2c->CTLCLR, I2C_CTLCLR_STA_Msk, 1 << I2C_CTLCLR_STA_Pos)); + (sto) ? \ + (REG_WRITE_MASK(i2c->CTLSET, I2C_CTLSET_STO_Msk, 1 << I2C_CTLSET_STO_Pos)) : \ + (REG_WRITE_MASK(i2c->CTLCLR, I2C_CTLCLR_STO_Msk, 1 << I2C_CTLCLR_STO_Pos)); + (aa) ? \ + (REG_WRITE_MASK(i2c->CTLSET, I2C_CTLSET_AA_Msk, 1 << I2C_CTLSET_AA_Pos)) : \ + (REG_WRITE_MASK(i2c->CTLCLR, I2C_CTLCLR_AA_Msk, 1 << I2C_CTLCLR_AA_Pos)); + (si) ? \ + (REG_WRITE_MASK(i2c->CTLSET, I2C_CTLSET_SI_Msk, 1 << I2C_CTLSET_SI_Pos)) : \ + (REG_WRITE_MASK(i2c->CTLCLR, I2C_CTLCLR_SI_Msk, 1 << I2C_CTLCLR_SI_Pos)); +} + +/** + * @brief Returns the last i2c Event. + * @param i2c: select the I2C peripheral. + * @retval The last event + */ +uint32_t I2C_GetSlaveReceivedAddr(I2C_Type *i2c) +{ + return ((uint32_t)i2c->ADDR); +} + +uint32_t I2C_GetSta(I2C_Type *i2c) +{ + return ((uint32_t)i2c->STAT_b.STAT); +} + +#endif /* CONFIG_ENABLE_HAL_I2C */ diff --git a/Drivers/PB5700/HAL_Lib/src/hal_lptim.c b/Drivers/PB5700/HAL_Lib/src/hal_lptim.c new file mode 100644 index 0000000..a8a626d --- /dev/null +++ b/Drivers/PB5700/HAL_Lib/src/hal_lptim.c @@ -0,0 +1,124 @@ +/** + * 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 ) + { + // ToDo: reset module + __HAL_SYSCFG_LPTIM_CLK_ENABLE(); + REG_WRITE_MASK(pHLpTim->TCR, LPTIM_TCR_CLKS_Msk, pInit->LPTIM_ClockSource); + } + else if( pHLpTim == TIM0 ) + { + // ToDo: reset module + __HAL_SYSCFG_TIM0_CLK_ENABLE(); + } + else if( pHLpTim == TIM1 ) + { + // ToDo: reset module + __HAL_SYSCFG_TIM1_CLK_ENABLE(); + } + + pHLpTim->PR = pInit->LPTIM_Prescaler; + pHLpTim->MCR = pInit->LPTIM_MatchMode; + pHLpTim->MR0 = pInit->LPTIM_MatchValue; + + return; +} + + +void LPTIM_DeInit(LPTIM_Type *pHLpTim) +{ + if( pHLpTim == LPTIM ) + { + __HAL_SYSCFG_LPTIM_CLK_DISABLE(); + } + else if( pHLpTim == TIM0 ) + { + __HAL_SYSCFG_TIM1_CLK_DISABLE(); + } + else if( pHLpTim == TIM1 ) + { + __HAL_SYSCFG_TIM1_CLK_DISABLE(); + } + + 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/Drivers/PB5700/HAL_Lib/src/hal_opamp.c b/Drivers/PB5700/HAL_Lib/src/hal_opamp.c new file mode 100644 index 0000000..491308d --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/HAL_Lib/src/hal_pwr.c b/Drivers/PB5700/HAL_Lib/src/hal_pwr.c new file mode 100644 index 0000000..e104a8d --- /dev/null +++ b/Drivers/PB5700/HAL_Lib/src/hal_pwr.c @@ -0,0 +1,99 @@ +/** + * 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 +//============================================================================= +#define __PWR_WAIT_RECHARGE() do{ __NOP(); __NOP(); __NOP(); __NOP(); \ + }while(0) +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +void PWR_SetAutoWakeUp(uint32_t msec) +{ + sys_config_systick(msec * SYS_TICK_1_MS); + return; +} + +void PWR_EnterSleepMode(CallbaskPreDeepsleepTypeDef cb_pre_set, + CallbaskPostDeepsleepTypeDef cb_post_set) +{ + sys_disable_girq(); + + if( cb_pre_set ) + cb_pre_set(); + + __set_wfi_sleepmode(WFI_SHALLOW_SLEEP); + + SYSCFG_SetLowPower(true); + + __WFI(); + __PWR_WAIT_RECHARGE(); + + if( cb_post_set ) + cb_post_set(); + + SYSCFG_SetLowPower(false); + + sys_enable_girq(); + + return; +} + + +void PWR_EnterDeepSleepMode(CallbaskPreDeepsleepTypeDef cb_pre_set, + CallbaskPostDeepsleepTypeDef cb_post_set) +{ + sys_disable_girq(); + + if( cb_pre_set ) + cb_pre_set(); + + __set_wfi_sleepmode(WFI_DEEP_SLEEP); + + SYSCFG_SetLowPower(true); + + __WFI(); + __PWR_WAIT_RECHARGE(); + + if( cb_post_set ) + cb_post_set(); + + SYSCFG_SetLowPower(false); + + sys_enable_girq(); + + return; +} + +#endif /* CONFIG_ENABLE_HAL_PMU */ diff --git a/Drivers/PB5700/HAL_Lib/src/hal_spi.c b/Drivers/PB5700/HAL_Lib/src/hal_spi.c new file mode 100644 index 0000000..94745e3 --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/HAL_Lib/src/hal_syscfg.c b/Drivers/PB5700/HAL_Lib/src/hal_syscfg.c new file mode 100644 index 0000000..dee473c --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/HAL_Lib/src/hal_tim.c b/Drivers/PB5700/HAL_Lib/src/hal_tim.c new file mode 100644 index 0000000..cf57036 --- /dev/null +++ b/Drivers/PB5700/HAL_Lib/src/hal_tim.c @@ -0,0 +1,1557 @@ +/** + * 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 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; +} + +#if 0 +/** + * @brief Configures the TIMx Trigger as External Clock + * @param TIMx: where x can be 1, 2, 3, 4, 5, 9, 12 or 15 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 Mode1 + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 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 *TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, + uint16_t ExtTRGFilter) +{ + uint16_t tmpsmcr = 0; + /* Configure the ETR Clock source */ + TIM_ETRConfig(TIMx, TIM_ExtTRGPrescaler, TIM_ExtTRGPolarity, ExtTRGFilter); + + /* Get the TIMx SMCR register value */ + tmpsmcr = TIMx->SMCR; + /* Reset the SMS Bits */ + tmpsmcr &= (uint16_t)(~((uint16_t)TIM_SMCR_SMS_Msk)); + /* Select the External clock mode1 */ + tmpsmcr |= TIM_SlaveMode_External1; + /* Select the Trigger selection : ETRF */ + tmpsmcr &= (uint16_t)(~((uint16_t)TIM_SMCR_TS_Msk)); + tmpsmcr |= TIM_TS_ETRF; + /* Write to TIMx SMCR */ + TIMx->SMCR = tmpsmcr; +} + +/** + * @brief Configures the External clock Mode2 + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 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 *TIMx, uint16_t TIM_ExtTRGPrescaler, + uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter) +{ + /* Configure the ETR Clock source */ + TIM_ETRConfig(TIMx, TIM_ExtTRGPrescaler, TIM_ExtTRGPolarity, ExtTRGFilter); + /* Enable the External clock mode2 */ + TIMx->SMCR |= TIM_SMCR_ECE_Msk; +} + +/** + * @brief Configures the TIMx External Trigger (ETR). + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 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 *TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, + uint16_t ExtTRGFilter) +{ + uint16_t tmpsmcr = 0; + tmpsmcr = TIMx->SMCR; + /* Reset the ETR Bits */ + tmpsmcr &= SMCR_ETR_Mask; + /* Set the Prescaler, the Filter value and the Polarity */ + tmpsmcr |= (uint16_t)(TIM_ExtTRGPrescaler | (uint16_t)(TIM_ExtTRGPolarity | (uint16_t)(ExtTRGFilter << (uint16_t)8))); + /* Write to TIMx SMCR */ + TIMx->SMCR = tmpsmcr; +} +#endif + +/** + * @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 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); +} + +#endif /* CONFIG_ENABLE_HAL_TIM2 || CONFIG_ENABLE_HAL_EPWM */ diff --git a/Drivers/PB5700/HAL_Lib/src/hal_uart.c b/Drivers/PB5700/HAL_Lib/src/hal_uart.c new file mode 100644 index 0000000..874f2f2 --- /dev/null +++ b/Drivers/PB5700/HAL_Lib/src/hal_uart.c @@ -0,0 +1,101 @@ +/** + * 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); + + /** + * Set Uart->BR_b.SR = 0 + * ToDo: 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/Drivers/PB5700/HAL_Lib/src/hal_wdg.c b/Drivers/PB5700/HAL_Lib/src/hal_wdg.c new file mode 100644 index 0000000..4fe5a86 --- /dev/null +++ b/Drivers/PB5700/HAL_Lib/src/hal_wdg.c @@ -0,0 +1,190 @@ +/** + * 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 +//============================================================================= + +/** + * @brief Fills each init_struct member with its default value. + * @param init_struct : pointer to a WDG_BaseInitTypeDef + * structure which will be initialized. + * @retval None. + */ +void WDG_BaseStructInit(WDG_BaseInitTypeDef *init_struct) +{ + init_struct->Relaod = 0xFFFFFFFF; + init_struct->Reset = WDG_Reset_Dis; + init_struct->Debug = WDG_Debug_Dis; +} + +/** + * @brief Initializes the WDG Base Unit peripheral according to + * the specified parameters in the init_struct. + * @param init_struct: pointer to a WDG_BaseInitTypeDef + * structure that contains the configuration information for the + * specified WDG peripheral. + * @retval None. + */ +void WDG_BaseInit( WDG_BaseInitTypeDef *init_struct) +{ + __HAL_SYSCFG_WDG_CLK_ENABLE(); + + WDG_Unlock(); + + WDG->LOAD = init_struct->Relaod; + REG_WRITE_MASK(WDG->CR, WDG_CR_RSTE_Msk, init_struct->Reset); + REG_WRITE_MASK(WDG->CR, WDG_CR_DBGE_Msk, init_struct->Debug); + + WDG_Clear(); + +} + + +/** + * @brief Set WDG reload value. + * @param reload: specifies the WDG reload value. + * This parameter must be a number between 0 and 0xFFFFFFFF. + * @retval None. + */ +void WDG_SetReload(uint32_t reload) +{ + WDG->LOAD = reload; +} + + +/** + * @brief WDG peripheral Enable. + * @param None. + * @retval None. + */ +void WDG_Enable(void) +{ + REG_SET_BITS(WDG->CR, WDG_CR_INTE_Msk); +} + +/** + * @brief WDG peripheral Disables. + * @param None. + * @retval None. + */ +void WDG_Disable(void) +{ + REG_CLR_BITS(WDG->CR, WDG_CR_INTE_Msk); +} + +/** + * @brief Get wdg current count value + * @param None. + * @retval None. + */ +uint32_t WDG_GetCountValue(void) +{ + return(WDG->VALUE); +} + +/** + * @brief Clear interrupt flag + * @param None. + * @retval None. + */ +void WDG_ClearITFlag(void) +{ + WDG->INTCLR = 1; +} +/** + * @brief Clear wdg count + * @param None. + * @retval None. + */ +void WDG_Clear(void) +{ + WDG->INTCLR = 1; +} +/** + * @brief Get wdg original interrupt flag + * @param None. + * @retval None. + */ +uint32_t WDG_GetRIF(uint32_t rif_bit_mask) +{ + return(WDG->RIS & rif_bit_mask); +} +/** + * @brief Get wdg Mask interrupt flag + * @param None. + * @retval None. + */ +uint32_t WDG_GetMIF(uint32_t mif_bit_mask) +{ + return(WDG->MIS & mif_bit_mask); +} + +/** + * @brief Unlocks wdg so that it can be overwritten + * @param None + * @retval IWDG CNT value + */ +void WDG_Unlock(void) +{ + WDG->LOCK = 0x1ACCE551; +} +/** + * @brief Lock the WDG so thatit cannot be overwritten + * @param None + * @retval IWDG CNT value + */ +void WDG_Lock(void) +{ + WDG->LOCK = 0; +} +/** + * @brief Get WDG lock status. This Value is only read. + * @param None + * @retval WDG lock status + */ +uint32_t WDG_GetLockStatus(void) +{ + return (WDG->LOCK); +} + + + + + + +#endif /* CONFIG_ENABLE_HAL_WDG */ diff --git a/Drivers/PB5700/NMSIS/Core/Include/core_compatiable.h b/Drivers/PB5700/NMSIS/Core/Include/core_compatiable.h new file mode 100644 index 0000000..a0636e7 --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/NMSIS/Core/Include/core_feature_base.h b/Drivers/PB5700/NMSIS/Core/Include/core_feature_base.h new file mode 100644 index 0000000..a1a639b --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/NMSIS/Core/Include/core_feature_bitmanip.h b/Drivers/PB5700/NMSIS/Core/Include/core_feature_bitmanip.h new file mode 100644 index 0000000..f0d7c9b --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/NMSIS/Core/Include/core_feature_cache.h b/Drivers/PB5700/NMSIS/Core/Include/core_feature_cache.h new file mode 100644 index 0000000..04aefb9 --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/NMSIS/Core/Include/core_feature_cidu.h b/Drivers/PB5700/NMSIS/Core/Include/core_feature_cidu.h new file mode 100644 index 0000000..26efde2 --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/NMSIS/Core/Include/core_feature_dsp.h b/Drivers/PB5700/NMSIS/Core/Include/core_feature_dsp.h new file mode 100644 index 0000000..6a7e5a1 --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/NMSIS/Core/Include/core_feature_eclic.h b/Drivers/PB5700/NMSIS/Core/Include/core_feature_eclic.h new file mode 100644 index 0000000..67617df --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/NMSIS/Core/Include/core_feature_fpu.h b/Drivers/PB5700/NMSIS/Core/Include/core_feature_fpu.h new file mode 100644 index 0000000..3d97a5b --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/NMSIS/Core/Include/core_feature_plic.h b/Drivers/PB5700/NMSIS/Core/Include/core_feature_plic.h new file mode 100644 index 0000000..4a1c78b --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/NMSIS/Core/Include/core_feature_pmp.h b/Drivers/PB5700/NMSIS/Core/Include/core_feature_pmp.h new file mode 100644 index 0000000..e989a68 --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/NMSIS/Core/Include/core_feature_spmp.h b/Drivers/PB5700/NMSIS/Core/Include/core_feature_spmp.h new file mode 100644 index 0000000..f83f1ec --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/NMSIS/Core/Include/core_feature_timer.h b/Drivers/PB5700/NMSIS/Core/Include/core_feature_timer.h new file mode 100644 index 0000000..a8f9cf5 --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/NMSIS/Core/Include/core_feature_vector.h b/Drivers/PB5700/NMSIS/Core/Include/core_feature_vector.h new file mode 100644 index 0000000..061dcd7 --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/NMSIS/Core/Include/nmsis_bench.h b/Drivers/PB5700/NMSIS/Core/Include/nmsis_bench.h new file mode 100644 index 0000000..d8d6592 --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/NMSIS/Core/Include/nmsis_compiler.h b/Drivers/PB5700/NMSIS/Core/Include/nmsis_compiler.h new file mode 100644 index 0000000..869d753 --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/NMSIS/Core/Include/nmsis_core.h b/Drivers/PB5700/NMSIS/Core/Include/nmsis_core.h new file mode 100644 index 0000000..16ed438 --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/NMSIS/Core/Include/nmsis_gcc.h b/Drivers/PB5700/NMSIS/Core/Include/nmsis_gcc.h new file mode 100644 index 0000000..b53775d --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/NMSIS/Core/Include/nmsis_iar.h b/Drivers/PB5700/NMSIS/Core/Include/nmsis_iar.h new file mode 100644 index 0000000..4d95a69 --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/NMSIS/Core/Include/nmsis_version.h b/Drivers/PB5700/NMSIS/Core/Include/nmsis_version.h new file mode 100644 index 0000000..ebc26fa --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/NMSIS/Core/Include/riscv_bits.h b/Drivers/PB5700/NMSIS/Core/Include/riscv_bits.h new file mode 100644 index 0000000..78687da --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/NMSIS/Core/Include/riscv_encoding.h b/Drivers/PB5700/NMSIS/Core/Include/riscv_encoding.h new file mode 100644 index 0000000..7ebab68 --- /dev/null +++ b/Drivers/PB5700/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/Drivers/PB5700/component.mk b/Drivers/PB5700/component.mk new file mode 100644 index 0000000..252384c --- /dev/null +++ b/Drivers/PB5700/component.mk @@ -0,0 +1,92 @@ +# +# component Makefile +# + + +#======================================= +# Configurations +#======================================= + +# +# Drivers of MCU +# + +SOC_CPU_NAME = n203e + +#======================================= +# system +#======================================= +ifeq ("$(SOC)","pb5700") + C_DEFS += -DCONFIG_USE_PB5700 +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/PB5700/Device/src/Startup/startup.S \ + $(srctree)/Drivers/PB5700/Device/src/Startup/trap.S + +C_SOURCES += \ + $(srctree)/Drivers/PB5700/Device/src/interrupt.c \ + $(srctree)/Drivers/PB5700/Device/src/syscalls.c \ + $(srctree)/Drivers/PB5700/Device/src/system_dev.c + +C_INCLUDES += \ + -I$(srctree)/Drivers/PB5700/Device/inc \ + -I$(srctree)/Drivers/PB5700/NMSIS/Core/Include \ + -I$(srctree)/Drivers/PB5700/ + + + +#======================================= +# peripheral hal driver +#======================================= +C_SOURCES += \ + $(srctree)/Drivers/PB5700/HAL_Lib/src/hal_adc.c \ + $(srctree)/Drivers/PB5700/HAL_Lib/src/hal_amisc.c \ + $(srctree)/Drivers/PB5700/HAL_Lib/src/hal_comp.c \ + $(srctree)/Drivers/PB5700/HAL_Lib/src/hal_opamp.c \ + $(srctree)/Drivers/PB5700/HAL_Lib/src/hal_crc.c \ + $(srctree)/Drivers/PB5700/HAL_Lib/src/hal_dsp.c \ + $(srctree)/Drivers/PB5700/HAL_Lib/src/hal_flash.c \ + $(srctree)/Drivers/PB5700/HAL_Lib/src/hal_gpio.c \ + $(srctree)/Drivers/PB5700/HAL_Lib/src/hal_i2c.c \ + $(srctree)/Drivers/PB5700/HAL_Lib/src/hal_lptim.c \ + $(srctree)/Drivers/PB5700/HAL_Lib/src/hal_pwr.c \ + $(srctree)/Drivers/PB5700/HAL_Lib/src/hal_spi.c \ + $(srctree)/Drivers/PB5700/HAL_Lib/src/hal_syscfg.c \ + $(srctree)/Drivers/PB5700/HAL_Lib/src/hal_tim.c \ + $(srctree)/Drivers/PB5700/HAL_Lib/src/hal_uart.c \ + $(srctree)/Drivers/PB5700/HAL_Lib/src/hal_wdg.c \ + $(srctree)/Drivers/PB5700/HAL_Lib/src/hal_device.c + +C_INCLUDES += \ + -I$(srctree)/Drivers/PB5700/HAL_Lib/inc + +#======================================= +# BSP +#======================================= +C_SOURCES += $(srctree)/Drivers/PB5700/BSP/StarterKit/starterkit.c + +C_INCLUDES += \ + -I$(srctree)/Drivers/PB5700/BSP/StarterKit + +#======================================= +# Flags +#======================================= +CFLAGS += $(CPU_FLAGS) +CXXFLAGS += +LDFLAGS += $(CPU_FLAGS) +LIBDIR += diff --git a/Drivers/PB5700/gcc_flashxip.ld b/Drivers/PB5700/gcc_flashxip.ld new file mode 100644 index 0000000..ce6f60d --- /dev/null +++ b/Drivers/PB5700/gcc_flashxip.ld @@ -0,0 +1,258 @@ +/****************************************************************************** + * @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 +} + +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 + + 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/Drivers/drivers.mk b/Drivers/drivers.mk new file mode 100644 index 0000000..b43215e --- /dev/null +++ b/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/Examples/I2C/I2C_Master_EEPROM/.cproject b/Examples/I2C/I2C_Master_EEPROM/.cproject new file mode 100644 index 0000000..d9ac06f --- /dev/null +++ b/Examples/I2C/I2C_Master_EEPROM/.cproject @@ -0,0 +1,294 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/I2C/I2C_Master_EEPROM/.project b/Examples/I2C/I2C_Master_EEPROM/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/Examples/I2C/I2C_Master_EEPROM/.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/Examples/I2C/I2C_Master_EEPROM/Project.nuproject b/Examples/I2C/I2C_Master_EEPROM/Project.nuproject new file mode 100644 index 0000000..0072223 --- /dev/null +++ b/Examples/I2C/I2C_Master_EEPROM/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/Examples/I2C/I2C_Master_EEPROM/component.mk b/Examples/I2C/I2C_Master_EEPROM/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Examples/I2C/I2C_Master_EEPROM/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/Examples/I2C/I2C_Master_EEPROM/inc/isr.h b/Examples/I2C/I2C_Master_EEPROM/inc/isr.h new file mode 100644 index 0000000..b1ab850 --- /dev/null +++ b/Examples/I2C/I2C_Master_EEPROM/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/Examples/I2C/I2C_Master_EEPROM/inc/main.h b/Examples/I2C/I2C_Master_EEPROM/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Examples/I2C/I2C_Master_EEPROM/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/Examples/I2C/I2C_Master_EEPROM/readme.md b/Examples/I2C/I2C_Master_EEPROM/readme.md new file mode 100644 index 0000000..b4f1dcd --- /dev/null +++ b/Examples/I2C/I2C_Master_EEPROM/readme.md @@ -0,0 +1,10 @@ +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/Examples/I2C/I2C_Master_EEPROM/src/isr.c b/Examples/I2C/I2C_Master_EEPROM/src/isr.c new file mode 100644 index 0000000..4cd5b57 --- /dev/null +++ b/Examples/I2C/I2C_Master_EEPROM/src/isr.c @@ -0,0 +1,50 @@ +/** + * 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 +//============================================================================= +/** + * \brief System Software ISR + * + * \return None + */ +__INTERRUPT void irqc_msip_handler(void) +{ + sys_clear_swi(); + return; +} + diff --git a/Examples/I2C/I2C_Master_EEPROM/src/main.c b/Examples/I2C/I2C_Master_EEPROM/src/main.c new file mode 100644 index 0000000..0f04546 --- /dev/null +++ b/Examples/I2C/I2C_Master_EEPROM/src/main.c @@ -0,0 +1,401 @@ +/** + * 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 ENABLE_IIC_INT +//============================================================================= +// Macro Definition +//============================================================================= +#define EEPROM_I2C_ADDRESS 0xA0 +uint32_t testFlasg = 0; +uint32_t errCounter = 0; +uint32_t delay = 0; +uint8_t i = 0; +uint8_t ReadBuffer[20], WriteBuffer[20]; +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= +void I2C_Configure(void); +void I2C_Handler(void); +void I2C_TxData_Polling(uint8_t *Buffer, uint8_t Length); +void EEPROM_WriteData(uint8_t Address, uint8_t *Buffer, uint8_t Length); +void EEPROM_WritePage(uint8_t Address, uint8_t *Buffer, uint8_t Length); +void I2C_RxData_Polling(uint8_t *Buffer, uint16_t Length); +void EEPROM_ReadData(uint8_t Address, uint8_t *Buffer, uint8_t Length); +void I2C_Send_WriteAddr(I2C_Type *i2c,uint8_t address); +void I2C_Send_ReadAddr(I2C_Type *i2c,uint8_t address); + +void EEPROM_GenerateSTART(I2C_Type *i2c, FunctionalState state); +void EEPROM_GenerateRESTART(I2C_Type *i2c, FunctionalState state); +void EEPROM_Send_WriteAddr(I2C_Type *i2c, uint8_t address); +void I2C_Send_ReadAddr(I2C_Type *i2c,uint8_t address); +void EEPROM_Send_Data(I2C_Type *i2c, uint8_t data); +void EEPROM_GenerateSTOP(I2C_Type *i2c, FunctionalState state); + + +void I2C_Master_EEPROM_Polling_Sample(void); +//============================================================================= +// 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); + + I2C_Master_EEPROM_Polling_Sample(); + + while(1) + { + + } + +} + +void I2C_Master_EEPROM_Polling_Sample(void) +{ + I2C_Configure(); + + for (i = 0; i < 20; i++) + { + ReadBuffer[i] = 0; + WriteBuffer[i] = i + 0x10; + } + + EEPROM_GenerateSTART(I2C,ENABLE); + EEPROM_Send_WriteAddr(I2C,0xA0); + EEPROM_Send_Data(I2C,0x00); + EEPROM_Send_Data(I2C,0x00); + + I2C_TxData_Polling((uint8_t *)WriteBuffer, 20); + EEPROM_GenerateSTOP(I2C,ENABLE); + + for(delay = 0;delay <0x1000; delay ++); + + EEPROM_GenerateSTART(I2C,ENABLE); + EEPROM_Send_WriteAddr(I2C,0xA0); + EEPROM_Send_Data(I2C,0x00); + EEPROM_Send_Data(I2C,0x00); + + EEPROM_GenerateRESTART(I2C,ENABLE); + I2C_Send_ReadAddr(I2C,0xA1); + + I2C_RxData_Polling((uint8_t *)ReadBuffer, 20); + EEPROM_GenerateSTOP(I2C,ENABLE); + + for (i = 0; i < 20; i++) + { + if(WriteBuffer[i] != ReadBuffer[i]) + { + errCounter ++; + } + } +} + +void I2C_Configure(void) +{ + GPIO_InitTypeDef GPIO_InitStruct; + I2C_InitTypeDef I2C_InitStruct; + + I2C_StructInit(&I2C_InitStruct); + I2C_InitStruct.I2C_Mode = I2C_Mode_Master; + I2C_InitStruct.I2C_OwnAddress = 0x00; + I2C_InitStruct.I2C_ClockDiv = I2C_CLK_Div960; + I2C_Init(I2C,&I2C_InitStruct); + + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_00 | GPIO_Pin_01; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_3; + GPIO_Init(GPIOA, &GPIO_InitStruct); + + I2C_TargetAddressConfig(I2C,EEPROM_I2C_ADDRESS); +#ifdef ENABLE_IIC_INT + I2C_ITConfig(I2C, ENABLE); + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(I2C0_IRQn, I2C_Handler, &irq_attr); + __enable_irq(); +# endif + I2C_Cmd(I2C, ENABLE); +} + +void EEPROM_WriteData(uint8_t Address, uint8_t *Buffer, uint8_t Length) +{ + /****************SEND_START****************/ + I2C_GenerateSTART(I2C,ENABLE); + while (RESET == I2C_GetFlagStatus(I2C, I2C_MASTER_START_ACK)) + { + + } + EEPROM_WritePage(Address, Buffer, EEPROM_PAGE_SIZE); +} + +void EEPROM_WritePage(uint8_t Address, uint8_t *Buffer, uint8_t Length) +{ + I2C_Send_WriteAddr(I2C,Address); + + I2C_TxData_Polling((uint8_t *)Buffer, Length); + + I2C_GenerateSTOP(I2C, ENABLE); + I2C_ITConfig(I2C, DISABLE); + while (!I2C_GetFlagStatus(I2C, I2C_BUS_FREE)) + { + } +} + +void I2C_TxData_Polling(uint8_t *Buffer, uint8_t Length) +{ + uint8_t i = 0; + + for (i = 0; i < Length; i++) + { + I2C_SendData(I2C, Buffer[i]); + I2C_StaFlagConfig(I2C,I2C_STA_RESET,I2C_STO_RESET,I2C_SI_RESET,I2C_AA_RESET); + while (RESET == I2C_GetFlagStatus(I2C, I2C_MASTER_WRDATEND_ACK)); + { + + } + } +} + +void I2C_Send_WriteAddr(I2C_Type *i2c,uint8_t address) +{ + I2C_SendData(i2c, address); + REG_WRITE_MASK(i2c->CTLCLR, I2C_CTLCLR_SI_Msk, 1 << I2C_CTLCLR_SI_Pos); + while (RESET == I2C_GetFlagStatus(i2c, I2C_MASTER_WRDEVADREND_ACK)); + { + + } +} + +void EEPROM_ReadData(uint8_t Address, uint8_t *Buffer, uint8_t Length) +{ + + + + I2C_GenerateSTART(I2C,ENABLE); + I2C_ITConfig(I2C, DISABLE); +// I2C_StaFlagConfig(I2C,I2C_STA_SET,I2C_STO_RESET,I2C_SI_RESET,I2C_AA_RESET); + while (RESET == I2C_GetFlagStatus(I2C, I2C_MASTER_RPTSTART_ACK)) + { + + } + I2C_Send_ReadAddr(I2C,0xA1); + + I2C_RxData_Polling((uint8_t *)Buffer, Length); + + I2C_GenerateSTOP(I2C, ENABLE); + + while (!I2C_GetITStatus(I2C, I2C_BUS_FREE)) + { + } +} + +void I2C_RxData_Polling(uint8_t *Buffer, uint16_t Length) +{ + uint8_t i = 0; + I2C_StaFlagConfig(I2C,I2C_STA_RESET,I2C_STO_RESET,I2C_SI_RESET,I2C_AA_SET); + for (i = 0; i < Length; i++) + { + REG_WRITE_MASK(I2C->CTLCLR, I2C_CTLCLR_SI_Msk, 1 << I2C_CTLCLR_SI_Pos); + while (RESET == I2C_GetFlagStatus(I2C, I2C_RXDAT_TXACK)); + { + + } + Buffer[i] = I2C_ReceiveData(I2C); + } +} + +void EEPROM_GenerateSTART(I2C_Type *i2c, FunctionalState state) +{ + I2C_GenerateSTART(I2C,ENABLE); + while (RESET == I2C_GetFlagStatus(I2C, I2C_MASTER_START_ACK)) + { + + } +} + +void EEPROM_GenerateRESTART(I2C_Type *i2c, FunctionalState state) +{ + I2C_GenerateSTART(I2C,ENABLE); + I2C_ITConfig(I2C,DISABLE ); + while (RESET == I2C_GetFlagStatus(I2C, I2C_MASTER_RPTSTART_ACK)) + { + + } +} + +void EEPROM_Send_WriteAddr(I2C_Type *i2c, uint8_t address) +{ + I2C_Send_WriteAddr(i2c,address); + + I2C_SendData(I2C, 0x00); + I2C_StaFlagConfig(I2C,I2C_STA_RESET,I2C_STO_RESET,I2C_SI_RESET,I2C_AA_RESET); + while (RESET == I2C_GetFlagStatus(I2C, I2C_MASTER_WRDATEND_ACK)); + { + + } +} + + +void EEPROM_Send_Data(I2C_Type *i2c, uint8_t data) +{ + I2C_SendData(i2c, data); + I2C_StaFlagConfig(I2C,I2C_STA_RESET,I2C_STO_RESET,I2C_SI_RESET,I2C_AA_RESET); + while (RESET == I2C_GetFlagStatus(I2C, I2C_MASTER_WRDATEND_ACK)); + { + + } +} +void I2C_Send_ReadAddr(I2C_Type *i2c,uint8_t address) +{ + I2C_SendData(i2c, address); + REG_WRITE_MASK(i2c->CTLCLR, I2C_CTLCLR_SI_Msk, 1 << I2C_CTLCLR_SI_Pos); + while (RESET == I2C_GetFlagStatus(i2c, I2C_MASTER_WRADR_RDCMD_ACK)); + { + + } +} + +void EEPROM_GenerateSTOP(I2C_Type *i2c, FunctionalState state) +{ + I2C_GenerateSTOP(i2c,ENABLE); + I2C_ITConfig(i2c, DISABLE); + while (RESET == I2C_GetFlagStatus(I2C, I2C_BUS_FREE)) + { + + } + +} +/**********IRQ Number 17**********/ +__INTERRUPT void I2C_Handler(void) +{ + if(I2C_GetFlagStatus(I2C, I2C_MASTER_START_ACK) == 1) + { + printf("I2C_STAT = 0x01,I2C_MASTER_START_ACK Interrupt Successful!/r/n"); + } + if(I2C_GetFlagStatus(I2C, I2C_MASTER_RPTSTART_ACK) == 1) + { + printf("I2C_STAT = 0x02,I2C_MASTER_RPTSTART_ACK Interrupt Successful!/r/n"); + } + if(I2C_GetFlagStatus(I2C, I2C_MASTER_WRDEVADREND_ACK) == 1) + { + printf("I2C_STAT = 0x02,I2C_MASTER_WRDEVADREND_ACK Interrupt Successful!/r/n"); + } + if(I2C_GetFlagStatus(I2C, I2C_MASTER_WRDEVADREND_NACK) == 1) + { + printf("I2C_STAT = 0x02,I2C_MASTER_WRDEVADREND_NACK Interrupt Successful!/r/n"); + } + if(I2C_GetFlagStatus(I2C, I2C_MASTER_WRDATEND_ACK) == 1) + { + printf("I2C_STAT = 0x02,I2C_MASTER_WRDATEND_ACK Interrupt Successful!/r/n"); + } + if(I2C_GetFlagStatus(I2C, I2C_MASTER_START_ACK) == 1) + { + printf("I2C_STAT = 0x02,I2C_MASTER_START_ACK Interrupt Successful!/r/n"); + } + if(I2C_GetFlagStatus(I2C, I2C_MASTER_START_ACK) == 1) + { + printf("I2C_STAT = 0x02,I2C_MASTER_START_ACK Interrupt Successful!/r/n"); + } + if(I2C_GetFlagStatus(I2C, I2C_MASTER_START_ACK) == 1) + { + printf("I2C_STAT = 0x02,I2C_MASTER_START_ACK Interrupt Successful!/r/n"); + } + if(I2C_GetFlagStatus(I2C, I2C_MASTER_START_ACK) == 1) + { + printf("I2C_STAT = 0x02,I2C_MASTER_START_ACK Interrupt Successful!/r/n"); + } + if(I2C_GetFlagStatus(I2C, I2C_MASTER_START_ACK) == 1) + { + printf("I2C_STAT = 0x02,I2C_MASTER_START_ACK Interrupt Successful!/r/n"); + } + if(I2C_GetFlagStatus(I2C, I2C_MASTER_START_ACK) == 1) + { + printf("I2C_STAT = 0x02,I2C_MASTER_START_ACK Interrupt Successful!/r/n"); + } + if(I2C_GetFlagStatus(I2C, I2C_MASTER_START_ACK) == 1) + { + printf("I2C_STAT = 0x02,I2C_MASTER_START_ACK Interrupt Successful!/r/n"); + } + if(I2C_GetFlagStatus(I2C, I2C_MASTER_START_ACK) == 1) + { + printf("I2C_STAT = 0x02,I2C_MASTER_START_ACK Interrupt Successful!/r/n"); + } + if(I2C_GetFlagStatus(I2C, I2C_MASTER_START_ACK) == 1) + { + printf("I2C_STAT = 0x02,I2C_MASTER_START_ACK Interrupt Successful!/r/n"); + } + if(I2C_GetFlagStatus(I2C, I2C_MASTER_START_ACK) == 1) + { + printf("I2C_STAT = 0x02,I2C_MASTER_START_ACK Interrupt Successful!/r/n"); + } + if(I2C_GetFlagStatus(I2C, I2C_MASTER_START_ACK) == 1) + { + printf("I2C_STAT = 0x02,I2C_MASTER_START_ACK Interrupt Successful!/r/n"); + } + if(I2C_GetFlagStatus(I2C, I2C_MASTER_START_ACK) == 1) + { + printf("I2C_STAT = 0x02,I2C_MASTER_START_ACK Interrupt Successful!/r/n"); + } + if(I2C_GetFlagStatus(I2C, I2C_MASTER_START_ACK) == 1) + { + printf("I2C_STAT = 0x02,I2C_MASTER_START_ACK Interrupt Successful!/r/n"); + } + if(I2C_GetFlagStatus(I2C, I2C_MASTER_START_ACK) == 1) + { + printf("I2C_STAT = 0x02,I2C_MASTER_START_ACK Interrupt Successful!/r/n"); + } + if(I2C_GetFlagStatus(I2C, I2C_MASTER_START_ACK) == 1) + { + printf("I2C_STAT = 0x02,I2C_MASTER_START_ACK Interrupt Successful!/r/n"); + } + if(I2C_GetFlagStatus(I2C, I2C_MASTER_START_ACK) == 1) + { + printf("I2C_STAT = 0x02,I2C_MASTER_START_ACK Interrupt Successful!/r/n"); + } + if(I2C_GetFlagStatus(I2C, I2C_MASTER_START_ACK) == 1) + { + printf("I2C_STAT = 0x02,I2C_MASTER_START_ACK Interrupt Successful!/r/n"); + } + if(I2C_GetFlagStatus(I2C, I2C_MASTER_START_ACK) == 1) + { + printf("I2C_STAT = 0x02,I2C_MASTER_START_ACK Interrupt Successful!/r/n"); + } + if(I2C_GetFlagStatus(I2C, I2C_MASTER_START_ACK) == 1) + { + printf("I2C_STAT = 0x02,I2C_MASTER_START_ACK Interrupt Successful!/r/n"); + } + if(I2C_GetFlagStatus(I2C, I2C_MASTER_START_ACK) == 1) + { + printf("I2C_STAT = 0x02,I2C_MASTER_START_ACK Interrupt Successful!/r/n"); + } + if(I2C_GetFlagStatus(I2C, I2C_MASTER_START_ACK) == 1) + { + printf("I2C_STAT = 0x02,I2C_MASTER_START_ACK Interrupt Successful!/r/n"); + } +} diff --git a/Examples/I2C/I2C_Slave_STM32/.cproject b/Examples/I2C/I2C_Slave_STM32/.cproject new file mode 100644 index 0000000..d9ac06f --- /dev/null +++ b/Examples/I2C/I2C_Slave_STM32/.cproject @@ -0,0 +1,294 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/I2C/I2C_Slave_STM32/.project b/Examples/I2C/I2C_Slave_STM32/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/Examples/I2C/I2C_Slave_STM32/.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/Examples/I2C/I2C_Slave_STM32/Project.nuproject b/Examples/I2C/I2C_Slave_STM32/Project.nuproject new file mode 100644 index 0000000..0072223 --- /dev/null +++ b/Examples/I2C/I2C_Slave_STM32/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/Examples/I2C/I2C_Slave_STM32/component.mk b/Examples/I2C/I2C_Slave_STM32/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Examples/I2C/I2C_Slave_STM32/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/Examples/I2C/I2C_Slave_STM32/inc/isr.h b/Examples/I2C/I2C_Slave_STM32/inc/isr.h new file mode 100644 index 0000000..b1ab850 --- /dev/null +++ b/Examples/I2C/I2C_Slave_STM32/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/Examples/I2C/I2C_Slave_STM32/inc/main.h b/Examples/I2C/I2C_Slave_STM32/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Examples/I2C/I2C_Slave_STM32/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/Examples/I2C/I2C_Slave_STM32/readme.md b/Examples/I2C/I2C_Slave_STM32/readme.md new file mode 100644 index 0000000..04dfe58 --- /dev/null +++ b/Examples/I2C/I2C_Slave_STM32/readme.md @@ -0,0 +1,13 @@ +IIC_SlaveMode_project +--- + +This example is a demo project to IIC onePulseOutput + +## Hardware and Software environment + ++ This example runs on PB5700 devices. + +## Log + ++ STM32 as the Master and PB5700 as the slave for communication + diff --git a/Examples/I2C/I2C_Slave_STM32/src/isr.c b/Examples/I2C/I2C_Slave_STM32/src/isr.c new file mode 100644 index 0000000..4cd5b57 --- /dev/null +++ b/Examples/I2C/I2C_Slave_STM32/src/isr.c @@ -0,0 +1,50 @@ +/** + * 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 +//============================================================================= +/** + * \brief System Software ISR + * + * \return None + */ +__INTERRUPT void irqc_msip_handler(void) +{ + sys_clear_swi(); + return; +} + diff --git a/Examples/I2C/I2C_Slave_STM32/src/main.c b/Examples/I2C/I2C_Slave_STM32/src/main.c new file mode 100644 index 0000000..196696b --- /dev/null +++ b/Examples/I2C/I2C_Slave_STM32/src/main.c @@ -0,0 +1,176 @@ +/** + * 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 I2C_SLAVE_ADDRESS 0x50 +uint8_t i = 0; +uint8_t ReadBuffer[100], WriteBuffer[20]; +uint8_t readCounter = 0; +uint8_t writeCounter = 0; +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= +void I2C_Handler(void); +void I2C_Slave_Configure(void); +//============================================================================= +// 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); + + I2C_Slave_Configure(); + + + while(1) + { + + } + +} + +void I2C_Slave_Configure(void) +{ + GPIO_InitTypeDef GPIO_InitStruct; + I2C_InitTypeDef I2C_InitStruct; + + I2C_StructInit(&I2C_InitStruct); + I2C_InitStruct.I2C_Mode = I2C_Mode_Master; + I2C_InitStruct.I2C_OwnAddress = 0x00; + I2C_InitStruct.I2C_ClockDiv = I2C_CLK_Div960; + I2C_Init(I2C,&I2C_InitStruct); + + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_00 | GPIO_Pin_01; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_3; + GPIO_Init(GPIOA, &GPIO_InitStruct); + I2C_StaFlagConfig(I2C,I2C_STA_RESET,I2C_STO_RESET,I2C_SI_RESET,I2C_AA_SET); + I2C_TargetAddressConfig(I2C,I2C_SLAVE_ADDRESS); + I2C_ITConfig(I2C, ENABLE); + for (i = 0; i < 20; i++) + { + ReadBuffer[i] = 0; + WriteBuffer[i] = i + 0x10; + } + + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(I2C0_IRQn, I2C_Handler, &irq_attr); + __enable_irq(); + I2C_Cmd(I2C, ENABLE); +} + +/**********IRQ Number 17**********/ +__INTERRUPT void I2C_Handler(void) +{ + switch(I2C_GetSta(I2C)) + { + case (I2C_SLAVE_WRCMD_ACK): + I2C_StaFlagConfig(I2C,I2C_STA_RESET,I2C_STO_RESET,I2C_SI_RESET,I2C_AA_SET); + + break; + + case (I2C_SLAVE_RXADR_WRCMD_ACK): + + break; + + case (I2C_RX_BROADCASTADR_ACK): + + break; + + case (I2C_SLAVE_RXBROADCASTADR_ACK): + + break; + + case (I2C_SLAVE_RXNEXTDAT_ACK): + I2C_StaFlagConfig(I2C,I2C_STA_RESET,I2C_STO_RESET,I2C_SI_RESET,I2C_AA_SET); + ReadBuffer[readCounter] = I2C_ReceiveData(I2C); + readCounter++; + + + break; + + case (I2C_SLAVE_RXNEXTDAT_NACK): + + break; + + case (I2C_BROADCAST_RXNEXTDAT_ACK): + + break; + + case (I2C_BROADCAST_RXNEXTDAT_NACK): + + break; + + case (I2C_SLAVE_RXSTOP_OR_RPTSTAT): + I2C_StaFlagConfig(I2C,I2C_STA_RESET,I2C_STO_RESET,I2C_SI_RESET,I2C_AA_SET); + + break; + + case (I2C_SLAVE_RXADR_RXCMD_ACK): + I2C_SendData(I2C,WriteBuffer[writeCounter]); + I2C_StaFlagConfig(I2C,I2C_STA_RESET,I2C_STO_RESET,I2C_SI_RESET,I2C_AA_SET); + writeCounter ++; + + break; + + case (I2C_BUSLOST_SLAVE_RXADR_RXCMD_ACK): + I2C_StaFlagConfig(I2C,I2C_STA_RESET,I2C_STO_RESET,I2C_SI_RESET,I2C_AA_SET); + + break; + + case (I2C_SLAVE_TXDAT_ACK): + I2C_SendData(I2C,WriteBuffer[writeCounter]); + I2C_StaFlagConfig(I2C,I2C_STA_RESET,I2C_STO_RESET,I2C_SI_RESET,I2C_AA_SET); + writeCounter ++; + + break; + + case (I2C_SLAVE_TXDAT_NACK): + I2C_StaFlagConfig(I2C,I2C_STA_RESET,I2C_STO_RESET,I2C_SI_RESET,I2C_AA_SET); + + break; + + case (I2C_SLAVE_TXLASTDAT_ACK): +// I2C_SendData(I2C,WriteBuffer[writeCounter]); + I2C_StaFlagConfig(I2C,I2C_STA_RESET,I2C_STO_RESET,I2C_SI_RESET,I2C_AA_SET); +// writeCounter ++; + + break; + + case (I2C_BUS_FREE): + break; + default: + break; + } +} diff --git a/Examples/adc/adc_conv_mode/.cproject b/Examples/adc/adc_conv_mode/.cproject new file mode 100644 index 0000000..2f90cfe --- /dev/null +++ b/Examples/adc/adc_conv_mode/.cproject @@ -0,0 +1,294 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/adc/adc_conv_mode/.project b/Examples/adc/adc_conv_mode/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/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/Examples/adc/adc_conv_mode/Project.nuproject b/Examples/adc/adc_conv_mode/Project.nuproject new file mode 100644 index 0000000..b783ad6 --- /dev/null +++ b/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: rv32emac_zba_zbb_zbs + 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/Examples/adc/adc_conv_mode/component.mk b/Examples/adc/adc_conv_mode/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/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 += +LDFLAGS += +LIBDIR += diff --git a/Examples/adc/adc_conv_mode/inc/isr.h b/Examples/adc/adc_conv_mode/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/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/Examples/adc/adc_conv_mode/inc/main.h b/Examples/adc/adc_conv_mode/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/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/Examples/adc/adc_conv_mode/readme.md b/Examples/adc/adc_conv_mode/readme.md new file mode 100644 index 0000000..0852e4a --- /dev/null +++ b/Examples/adc/adc_conv_mode/readme.md @@ -0,0 +1,78 @@ +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_AVSS + #define CONFIG_TARGET_ADC_MULTI_CHANNELS (ADC_Channel_AVSS | ADC_Channel_AMISC) + ``` + ++ 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_05 + ``` + +## 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 +``` + +## 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 +``` + +## 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 +``` + +## 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 1 +#define CONFIG_TARGET_ADC_MODE_DISCONTINOUS 0 +``` + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + ++ Single conversion mode + ++ Continuous mode + ++ Scan mode + ++ Discontinuous mode diff --git a/Examples/adc/adc_conv_mode/src/isr.c b/Examples/adc/adc_conv_mode/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/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/Examples/adc/adc_conv_mode/src/main.c b/Examples/adc/adc_conv_mode/src/main.c new file mode 100644 index 0000000..ddfd69c --- /dev/null +++ b/Examples/adc/adc_conv_mode/src/main.c @@ -0,0 +1,331 @@ +/** + * 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 0 +#define CONFIG_TARGET_ADC_MODE_SCAN 0 +#define CONFIG_TARGET_ADC_MODE_DISCONTINOUS 1 + +#define CONFIG_REPEAT_TIMES 10 + +/* Input Key I/O definitions */ +#define CONFIG_GPIO_INPUT_PORTx GPIOA +#define CONFIG_GPIO_INPUT_PINx GPIO_Pin_05 +#define CONFIG_GPIO_IRQ GPIOA_IRQn // GPIOB_IRQn + +#define CONFIG_TARGET_1_ADC_CHANNEL ADC_Channel_AVSS +#define CONFIG_TARGET_ADC_MULTI_CHANNELS (ADC_Channel_AVSS | ADC_Channel_AMISC) +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static bool g_hasPullLow = false; +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void GPIOx_Handler(void) +{ + if( GPIO_GetITFlag(CONFIG_GPIO_INPUT_PORTx, CONFIG_GPIO_INPUT_PINx) ) + { + GPIO_ClearITFlag(CONFIG_GPIO_INPUT_PORTx, CONFIG_GPIO_INPUT_PINx); + + g_hasPullLow = true; + } + + 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}; + + 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 */ + ADC_Start(ADC0); + + /* Wait ADC idle */ + while( ADC_IsIdle(ADC0) == 0 ); + + /* Get ADC conversion value */ + value = ADC_GetChannelConvValue(ADC0, channel); + msg(" ADC Value: %d\n", 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 */ + ADC_Start(ADC0); + sys_delay(3); + + for(int i = 0; i < CONFIG_REPEAT_TIMES; i++) + { + uint32_t chnnls_set = 0; + + /** + * ToDo: User modify the AIN channel voltage + */ + + 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\n", index, 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++) + { + /** + * ToDo: User modify the AIN channel voltage + */ + + /* Start ADC conversion */ + 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_GetChannelConvValue(ADC0, 0x1ul << index); + msg(" ch-%02d ADC Value: %d\n", index, 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++) + { + for(int j = 0; j < trigger_cnt; j++) + { + msg(" ## trigger %02d-th\n", j); + + /* Start ADC conversion */ + 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_GetChannelConvValue(ADC0, 0x1ul << index); + msg(" ch-%02d ADC Value: %d\n", index, 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(" key = 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_1_ADC_CHANNEL); + 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/Examples/adc/adc_for_TI/.cproject b/Examples/adc/adc_for_TI/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/adc/adc_for_TI/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/adc/adc_for_TI/.project b/Examples/adc/adc_for_TI/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/Examples/adc/adc_for_TI/.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/Examples/adc/adc_for_TI/Project.nuproject b/Examples/adc/adc_for_TI/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/Examples/adc/adc_for_TI/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/adc/adc_for_TI/component.mk b/Examples/adc/adc_for_TI/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Examples/adc/adc_for_TI/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/Examples/adc/adc_for_TI/inc/isr.h b/Examples/adc/adc_for_TI/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/Examples/adc/adc_for_TI/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/Examples/adc/adc_for_TI/inc/main.h b/Examples/adc/adc_for_TI/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Examples/adc/adc_for_TI/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/Examples/adc/adc_for_TI/readme.md b/Examples/adc/adc_for_TI/readme.md new file mode 100644 index 0000000..cdbc22b --- /dev/null +++ b/Examples/adc/adc_for_TI/readme.md @@ -0,0 +1,17 @@ +ADC test +--- + +This example is used to run compare test function. + +## Hardware and Software environment + ++ This example runs on PB5700 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 ++ READ AIN2 ADC DATA \ No newline at end of file diff --git a/Examples/adc/adc_for_TI/src/isr.c b/Examples/adc/adc_for_TI/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/Examples/adc/adc_for_TI/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/Examples/adc/adc_for_TI/src/main.c b/Examples/adc/adc_for_TI/src/main.c new file mode 100644 index 0000000..4d15b57 --- /dev/null +++ b/Examples/adc/adc_for_TI/src/main.c @@ -0,0 +1,77 @@ +/** + * 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 +//============================================================================= +// Constant Definition +//============================================================================= +#define GPIO_PORTx GPIOA + +//============================================================================= +// 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 adc Conversion TriggerSW\n", __TIME__); + + __HAL_SYSCFG_ADC_CLK_ENABLE(); + + REG_WRITE_MASK(ADC0->CON0, ADC_CON0_M_Msk, ADC_Channel_02); // Selection AIN2 (@ref ADC_ChannelsTypeDef) + + /* ADC Enable */ + REG_SET_BITS(ADC0->CON0, ADC_CON0_EN_Msk); + + while( 1 ) + { + uint16_t adcValue = 0; + + ADC->CON0 |= ADC_CON0_START_Msk; + while( (ADC->STAT & ADC_STAT_DONE_Msk) == 0 ); + + adcValue = REG_READ_MASK(ADC->DAT2, 0xFFF); // Read AIN2 DATA DAT2 + + msg("ACD sample value = x%08X\n", adcValue); + + REG_CLR_BITS(ADC->STAT, ADC_STAT_DONE_Msk); + } + +} diff --git a/Examples/adc/adc_single_conv_interrupt/.cproject b/Examples/adc/adc_single_conv_interrupt/.cproject new file mode 100644 index 0000000..2f90cfe --- /dev/null +++ b/Examples/adc/adc_single_conv_interrupt/.cproject @@ -0,0 +1,294 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/adc/adc_single_conv_interrupt/.project b/Examples/adc/adc_single_conv_interrupt/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/Examples/adc/adc_single_conv_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/Examples/adc/adc_single_conv_interrupt/Project.nuproject b/Examples/adc/adc_single_conv_interrupt/Project.nuproject new file mode 100644 index 0000000..b783ad6 --- /dev/null +++ b/Examples/adc/adc_single_conv_interrupt/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + 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/Examples/adc/adc_single_conv_interrupt/component.mk b/Examples/adc/adc_single_conv_interrupt/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Examples/adc/adc_single_conv_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/Examples/adc/adc_single_conv_interrupt/inc/isr.h b/Examples/adc/adc_single_conv_interrupt/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/Examples/adc/adc_single_conv_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/Examples/adc/adc_single_conv_interrupt/inc/main.h b/Examples/adc/adc_single_conv_interrupt/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Examples/adc/adc_single_conv_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/Examples/adc/adc_single_conv_interrupt/readme.md b/Examples/adc/adc_single_conv_interrupt/readme.md new file mode 100644 index 0000000..0d7c791 --- /dev/null +++ b/Examples/adc/adc_single_conv_interrupt/readme.md @@ -0,0 +1,52 @@ +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 + #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/Examples/adc/adc_single_conv_interrupt/src/isr.c b/Examples/adc/adc_single_conv_interrupt/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/Examples/adc/adc_single_conv_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/Examples/adc/adc_single_conv_interrupt/src/main.c b/Examples/adc/adc_single_conv_interrupt/src/main.c new file mode 100644 index 0000000..984772e --- /dev/null +++ b/Examples/adc/adc_single_conv_interrupt/src/main.c @@ -0,0 +1,154 @@ +/** + * 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 +//============================================================================= + +#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 +#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; +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void ADC0_Handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); + + g_ConvValue = ADC_ITGetConvValue(ADC0, CONFIG_TARGGET_ADC_CHANNEL); + + ADC_ClearITFlag(ADC0); + + 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}; + + 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}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + 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}; + 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_StructInit(&init); + + init.SelChannels = CONFIG_TARGGET_ADC_CHANNEL; + init.IsSoftTrig = true; + ADC_Init(ADC0, &init); + + ADC_ITConfig(ADC0, ADC_IT_CONV_DONE); + } + + g_IsDone = false; + ADC_Start(ADC0); + + while(1) + { + static int cnt = 0; + + 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; + + sys_delay(1000); + + ADC_Start(ADC0); + } + + return 0; +} diff --git a/Examples/adc/adc_trigger_src/.cproject b/Examples/adc/adc_trigger_src/.cproject new file mode 100644 index 0000000..2f90cfe --- /dev/null +++ b/Examples/adc/adc_trigger_src/.cproject @@ -0,0 +1,294 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/adc/adc_trigger_src/.project b/Examples/adc/adc_trigger_src/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/Examples/adc/adc_trigger_src/.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/Examples/adc/adc_trigger_src/Project.nuproject b/Examples/adc/adc_trigger_src/Project.nuproject new file mode 100644 index 0000000..b783ad6 --- /dev/null +++ b/Examples/adc/adc_trigger_src/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + 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/Examples/adc/adc_trigger_src/component.mk b/Examples/adc/adc_trigger_src/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Examples/adc/adc_trigger_src/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/Examples/adc/adc_trigger_src/inc/isr.h b/Examples/adc/adc_trigger_src/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/Examples/adc/adc_trigger_src/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/Examples/adc/adc_trigger_src/inc/main.h b/Examples/adc/adc_trigger_src/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Examples/adc/adc_trigger_src/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/Examples/adc/adc_trigger_src/readme.md b/Examples/adc/adc_trigger_src/readme.md new file mode 100644 index 0000000..0d42102 --- /dev/null +++ b/Examples/adc/adc_trigger_src/readme.md @@ -0,0 +1,34 @@ +adc_trigger_src +--- + +This is an example to select the source to trigger ADC start +> It uses the specific pin to trigge ADC + ++ Select the ADC converison channel + + ``` + // in main.c + #define CONFIG_TARGGET_ADC_1_CHANNEL ADC_Channel_15 + ``` + ++ Select the specific pin to trigger ADC + > It supports PB1 or PB2 + + ``` + // 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. + diff --git a/Examples/adc/adc_trigger_src/src/isr.c b/Examples/adc/adc_trigger_src/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/Examples/adc/adc_trigger_src/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/Examples/adc/adc_trigger_src/src/main.c b/Examples/adc/adc_trigger_src/src/main.c new file mode 100644 index 0000000..7316960 --- /dev/null +++ b/Examples/adc/adc_trigger_src/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 +//============================================================================= +#define CONFIG_TARGGET_ADC_1_CHANNEL ADC_Channel_15 +#define CONFIG_ADC_EXT_TRIG_SRC ADC_ExtTrigSource_PB1 // ADC_ExtTrigSource_PB2 +#define CONFIG_ADC_EXT_TRIG_MODE ADC_ExtTrigMode_PinRising // ADC_ExtTrigMode_PinFaling +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static uint16_t g_ConvValue = 0; +static bool g_IsDone = false; +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void ADC0_Handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); + + ADC_ClearITFlag(ADC0); + + g_ConvValue = ADC_GetChannelConvValue(ADC0, CONFIG_TARGGET_ADC_1_CHANNEL); + + g_IsDone = true; + + RESTORE_IRQ_CSR_CONTEXT(); + 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\nADC Trigger single conversion (AIN-%d) from external source (Pin: %s)\n", + __DATE__, __TIME__, + (31ul - HAL_CLZ(CONFIG_TARGGET_ADC_1_CHANNEL)), + (CONFIG_ADC_EXT_TRIG_SRC == ADC_ExtTrigSource_PB1) ? "PB1" : "PB2"); + + { /* 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); + + 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 */ + + while(1) + { + static int cnt = 0; + + 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/Examples/adc/adc_verify_wr_rd_reg/.cproject b/Examples/adc/adc_verify_wr_rd_reg/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/adc/adc_verify_wr_rd_reg/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/adc/adc_verify_wr_rd_reg/.project b/Examples/adc/adc_verify_wr_rd_reg/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/Examples/adc/adc_verify_wr_rd_reg/.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/Examples/adc/adc_verify_wr_rd_reg/Project.nuproject b/Examples/adc/adc_verify_wr_rd_reg/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/Examples/adc/adc_verify_wr_rd_reg/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/adc/adc_verify_wr_rd_reg/component.mk b/Examples/adc/adc_verify_wr_rd_reg/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Examples/adc/adc_verify_wr_rd_reg/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/Examples/adc/adc_verify_wr_rd_reg/inc/isr.h b/Examples/adc/adc_verify_wr_rd_reg/inc/isr.h new file mode 100644 index 0000000..b1ab850 --- /dev/null +++ b/Examples/adc/adc_verify_wr_rd_reg/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/Examples/adc/adc_verify_wr_rd_reg/inc/main.h b/Examples/adc/adc_verify_wr_rd_reg/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Examples/adc/adc_verify_wr_rd_reg/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/Examples/adc/adc_verify_wr_rd_reg/readme.md b/Examples/adc/adc_verify_wr_rd_reg/readme.md new file mode 100644 index 0000000..00aa3ff --- /dev/null +++ b/Examples/adc/adc_verify_wr_rd_reg/readme.md @@ -0,0 +1,284 @@ +adc read/write_registers +--- + +This example is used to read/write_registers + +# Log + +Use serial port with baudrate 115200 8bit, no parity check.
+User can receive log infomation on `PA00->TXD` of DUT. + +16:43:25 +This is a demo project to adc Read Write register + +CON0: Register Default: 0XC0400000, Register Read: 0XC0400000 +Match + +CON0: Register Write: 0XFFFFFFFF, Register result value: 0XCF7F3F2F, Register Read: 0XCF7F3F2F +Match + +CON0: Register Write: 0X0, Register result value: 0X0, Register Read: 0X0 +Match + +CON0: Register Write: 0X5A5A5A5A, Register result value: 0X4A5A1A0A, Register Read: 0X4A5A1A0A +Match + +CON0: Register Write: 0XA5A5A5A5, Register result value: 0X85252525, Register Read: 0X85252525 +Match + +STAT: Register Default: 0X30040, Register Read: 0X30040 +Match + +STAT: Register Write: 0XFFFFFFFF, Register result value: 0XFF01C0, Register Read: 0XFF01C0 +Match + +STAT: Register Write: 0X0, Register result value: 0X30000, Register Read: 0X30000 +Match + +STAT: Register Write: 0X5A5A5A5A, Register result value: 0X5A0040, Register Read: 0X5A0040 +Match + +STAT: Register Write: 0XA5A5A5A5, Register result value: 0XA50180, Register Read: 0XA50180 +Match + +DATA0: Register Default: 0X0, Register Read: 0X0 +Match + +DATA1: Register Default: 0X0, Register Read: 0X0 +Match + +DATA2: Register Default: 0X0, Register Read: 0X0 +Match + +DATA3: Register Default: 0X0, Register Read: 0X0 +Match + +DATA4: Register Default: 0X0, Register Read: 0X0 +Match + +DATA5: Register Default: 0X0, Register Read: 0X0 +Match + +DATA6: Register Default: 0X0, Register Read: 0X0 +Match + +DATA7: Register Default: 0X0, Register Read: 0X0 +Match + +DATA8: Register Default: 0X0, Register Read: 0X0 +Match + +DATA9: Register Default: 0X0, Register Read: 0X0 +Match + +DATA10: Register Default: 0X0, Register Read: 0X0 +Match + +DATA11: Register Default: 0X0, Register Read: 0X0 +Match + +DATA12: Register Default: 0X0, Register Read: 0X0 +Match + +DATA13: Register Default: 0X0, Register Read: 0X0 +Match + +DATA14: Register Default: 0X0, Register Read: 0X0 +Match + +DATA15: Register Default: 0X0, Register Read: 0X0 +Match + +DATA0: Register Write: 0XFFFFFFFF, Register result value: 0XFFF0000, Register Read: 0XFFF0000 +Match + +DATA1: Register Write: 0XFFFFFFFF, Register result value: 0XFFF0000, Register Read: 0XFFF0000 +Match + +DATA2: Register Write: 0XFFFFFFFF, Register result value: 0XFFF0000, Register Read: 0XFFF0000 +Match + +DATA3: Register Write: 0XFFFFFFFF, Register result value: 0XFFF0000, Register Read: 0XFFF0000 +Match + +DATA4: Register Write: 0XFFFFFFFF, Register result value: 0XFFF0000, Register Read: 0XFFF0000 +Match + +DATA5: Register Write: 0XFFFFFFFF, Register result value: 0XFFF0000, Register Read: 0XFFF0000 +Match + +DATA6: Register Write: 0XFFFFFFFF, Register result value: 0XFFF0000, Register Read: 0XFFF0000 +Match + +DATA7: Register Write: 0XFFFFFFFF, Register result value: 0XFFF0000, Register Read: 0XFFF0000 +Match + +DATA8: Register Write: 0XFFFFFFFF, Register result value: 0XFFF0000, Register Read: 0XFFF0000 +Match + +DATA9: Register Write: 0XFFFFFFFF, Register result value: 0XFFF0000, Register Read: 0XFFF0000 +Match + +DATA10: Register Write: 0XFFFFFFFF, Register result value: 0XFFF0000, Register Read: 0XFFF0000 +Match + +DATA11: Register Write: 0XFFFFFFFF, Register result value: 0XFFF0000, Register Read: 0XFFF0000 +Match + +DATA12: Register Write: 0XFFFFFFFF, Register result value: 0XFFF0000, Register Read: 0XFFF0000 +Match + +DATA13: Register Write: 0XFFFFFFFF, Register result value: 0XFFF0000, Register Read: 0XFFF0000 +Match + +DATA14: Register Write: 0XFFFFFFFF, Register result value: 0XFFF0000, Register Read: 0XFFF0000 +Match + +DATA15: Register Write: 0XFFFFFFFF, Register result value: 0XFFF0000, Register Read: 0XFFF0000 +Match + +DATA0: Register Write: 0X0, Register result value: 0X0, Register Read: 0X0 +Match + +DATA1: Register Write: 0X0, Register result value: 0X0, Register Read: 0X0 +Match + +DATA2: Register Write: 0X0, Register result value: 0X0, Register Read: 0X0 +Match + +DATA3: Register Write: 0X0, Register result value: 0X0, Register Read: 0X0 +Match + +DATA4: Register Write: 0X0, Register result value: 0X0, Register Read: 0X0 +Match + +DATA5: Register Write: 0X0, Register result value: 0X0, Register Read: 0X0 +Match + +DATA6: Register Write: 0X0, Register result value: 0X0, Register Read: 0X0 +Match + +DATA7: Register Write: 0X0, Register result value: 0X0, Register Read: 0X0 +Match + +DATA8: Register Write: 0X0, Register result value: 0X0, Register Read: 0X0 +Match + +DATA9: Register Write: 0X0, Register result value: 0X0, Register Read: 0X0 +Match + +DATA10: Register Write: 0X0, Register result value: 0X0, Register Read: 0X0 +Match + +DATA11: Register Write: 0X0, Register result value: 0X0, Register Read: 0X0 +Match + +DATA12: Register Write: 0X0, Register result value: 0X0, Register Read: 0X0 +Match + +DATA13: Register Write: 0X0, Register result value: 0X0, Register Read: 0X0 +Match + +DATA14: Register Write: 0X0, Register result value: 0X0, Register Read: 0X0 +Match + +DATA15: Register Write: 0X0, Register result value: 0X0, Register Read: 0X0 +Match + +DATA0: Register Write: 0X5A5A5A5A, Register result value: 0XA5A0000, Register Read: 0XA5A0000 +Match + +DATA1: Register Write: 0X5A5A5A5A, Register result value: 0XA5A0000, Register Read: 0XA5A0000 +Match + +DATA2: Register Write: 0X5A5A5A5A, Register result value: 0XA5A0000, Register Read: 0XA5A0000 +Match + +DATA3: Register Write: 0X5A5A5A5A, Register result value: 0XA5A0000, Register Read: 0XA5A0000 +Match + +DATA4: Register Write: 0X5A5A5A5A, Register result value: 0XA5A0000, Register Read: 0XA5A0000 +Match + +DATA5: Register Write: 0X5A5A5A5A, Register result value: 0XA5A0000, Register Read: 0XA5A0000 +Match + +DATA6: Register Write: 0X5A5A5A5A, Register result value: 0XA5A0000, Register Read: 0XA5A0000 +Match + +DATA7: Register Write: 0X5A5A5A5A, Register result value: 0XA5A0000, Register Read: 0XA5A0000 +Match + +DATA8: Register Write: 0X5A5A5A5A, Register result value: 0XA5A0000, Register Read: 0XA5A0000 +Match + +DATA9: Register Write: 0X5A5A5A5A, Register result value: 0XA5A0000, Register Read: 0XA5A0000 +Match + +DATA10: Register Write: 0X5A5A5A5A, Register result value: 0XA5A0000, Register Read: 0XA5A0000 +Match + +DATA11: Register Write: 0X5A5A5A5A, Register result value: 0XA5A0000, Register Read: 0XA5A0000 +Match + +DATA12: Register Write: 0X5A5A5A5A, Register result value: 0XA5A0000, Register Read: 0XA5A0000 +Match + +DATA13: Register Write: 0X5A5A5A5A, Register result value: 0XA5A0000, Register Read: 0XA5A0000 +Match + +DATA14: Register Write: 0X5A5A5A5A, Register result value: 0XA5A0000, Register Read: 0XA5A0000 +Match + +DATA15: Register Write: 0X5A5A5A5A, Register result value: 0XA5A0000, Register Read: 0XA5A0000 +Match + +DATA0: Register Write: 0XA5A5A5A5, Register result value: 0X5A50000, Register Read: 0X5A50000 +Match + +DATA1: Register Write: 0XA5A5A5A5, Register result value: 0X5A50000, Register Read: 0X5A50000 +Match + +DATA2: Register Write: 0XA5A5A5A5, Register result value: 0X5A50000, Register Read: 0X5A50000 +Match + +DATA3: Register Write: 0XA5A5A5A5, Register result value: 0X5A50000, Register Read: 0X5A50000 +Match + +DATA4: Register Write: 0XA5A5A5A5, Register result value: 0X5A50000, Register Read: 0X5A50000 +Match + +DATA5: Register Write: 0XA5A5A5A5, Register result value: 0X5A50000, Register Read: 0X5A50000 +Match + +DATA6: Register Write: 0XA5A5A5A5, Register result value: 0X5A50000, Register Read: 0X5A50000 +Match + +DATA7: Register Write: 0XA5A5A5A5, Register result value: 0X5A50000, Register Read: 0X5A50000 +Match + +DATA8: Register Write: 0XA5A5A5A5, Register result value: 0X5A50000, Register Read: 0X5A50000 +Match + +DATA9: Register Write: 0XA5A5A5A5, Register result value: 0X5A50000, Register Read: 0X5A50000 +Match + +DATA10: Register Write: 0XA5A5A5A5, Register result value: 0X5A50000, Register Read: 0X5A50000 +Match + +DATA11: Register Write: 0XA5A5A5A5, Register result value: 0X5A50000, Register Read: 0X5A50000 +Match + +DATA12: Register Write: 0XA5A5A5A5, Register result value: 0X5A50000, Register Read: 0X5A50000 +Match + +DATA13: Register Write: 0XA5A5A5A5, Register result value: 0X5A50000, Register Read: 0X5A50000 +Match + +DATA14: Register Write: 0XA5A5A5A5, Register result value: 0X5A50000, Register Read: 0X5A50000 +Match + +DATA15: Register Write: 0XA5A5A5A5, Register result value: 0X5A50000, Register Read: 0X5A50000 +Match + +done~~~ \ No newline at end of file diff --git a/Examples/adc/adc_verify_wr_rd_reg/src/isr.c b/Examples/adc/adc_verify_wr_rd_reg/src/isr.c new file mode 100644 index 0000000..af63b27 --- /dev/null +++ b/Examples/adc/adc_verify_wr_rd_reg/src/isr.c @@ -0,0 +1,51 @@ +/** + * 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 +//============================================================================= +/** + * \brief System Software ISR + * + * \return None + */ +__INTERRUPT void irqc_msip_handler(void) +{ + sys_clear_swi(); + + return; +} + diff --git a/Examples/adc/adc_verify_wr_rd_reg/src/main.c b/Examples/adc/adc_verify_wr_rd_reg/src/main.c new file mode 100644 index 0000000..3f937a3 --- /dev/null +++ b/Examples/adc/adc_verify_wr_rd_reg/src/main.c @@ -0,0 +1,209 @@ +/** + * 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 +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + + uint32_t read_value; + uint32_t write_value; + uint32_t result_value; + + { + 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 adc Read Write register\n", __TIME__); + + __HAL_SYSCFG_ADC_CLK_ENABLE(); + __HAL_SYSCFG_RESET_ADC(); + //-------------------ADCON0 ------------------// + + volatile uint32_t *registers_CON0[] = {&ADC->CON0 }; + uint32_t CON0_default_value = 0xC0400000; + uint32_t CON0_write_values[] = {0xFFFFFFFF, 0x00000000, 0x5A5A5A5A, 0xA5A5A5A5}; + + for (int i = 0; i < 1; i++) // READ CHECK REG + { + read_value = REG_READ(*registers_CON0[i]); + printf("\nCON%d: Register Default: 0X%X, Register Read: 0X%X\n", i, CON0_default_value, read_value); + if (CON0_default_value == read_value) + { + printf("Match\n"); + } + else + { + err("No Match\n"); + } + } + + for (int j = 0; j < 4; j++) // WRITE & CHECK REG + { + for (int i = 0; i < 1; i++) + { + write_value = CON0_write_values[j]; + result_value = (write_value & 0xCF7F3F2F); //cs 0xCF7F3FAF + REG_WRITE(*registers_CON0[i], write_value); + sys_delay(1); //cs + + read_value = REG_READ(*registers_CON0[i]); + printf("\nCON%d: Register Write: 0X%X, Register result value: 0X%X, Register Read: 0X%X\n", i, write_value, result_value, read_value); + if (result_value == read_value) + { + printf("Match\n"); + } + else + { + err("No Match\n"); + } + } + } + + + //-------------------ADCSTAT ------------------// + + volatile uint32_t *registers_STAT[]= {&ADC->STAT }; + uint32_t STAT_default_value = 0x00030040; //CS 0x0003E440 + uint32_t STAT_write_values[] = {0XFFFFFFFF,0X00000000,0x5A5A5A5A, 0xA5A5A5A5}; + + __HAL_SYSCFG_RESET_ADC(); + + for (int i = 0; i < 1; i++) // READ CHECK REG + { + read_value =REG_READ(*registers_STAT[i]); + printf("\nSTAT: Register Default: 0X%X, Register Read: 0X%X\n", STAT_default_value, read_value); + if (STAT_default_value == read_value) + { + printf("Match\n"); + } + else + { + err("No Match\n"); + } + } + + for (int j = 0; j < 4; j++) // WRITE & CHECK REG + { + + for (int i = 0; i < 1; i++) + { + write_value = STAT_write_values[j]; + + if(write_value==0) + { + result_value = (write_value & 0x00FF01C0)| 0x00030000; + } + else + { + result_value = (write_value & 0x00FF01C0); //CS 0x00FF01C0 b'00000000111111110000000111000000' + } + + REG_WRITE(*registers_STAT[i], write_value); + read_value = REG_READ(*registers_STAT[i]); + printf("\nSTAT: Register Write: 0X%X, Register result value: 0X%X, Register Read: 0X%X\n", write_value, result_value, read_value); + if (result_value == read_value) + { + printf("Match\n"); + } + else + { + err("No Match\n"); + } + } + } + + //-------------------ADCDATA ------------------// + + volatile uint32_t *registers[]= {&ADC->DAT0, &ADC->DAT1, &ADC->DAT2, &ADC->DAT3, &ADC->DAT4, &ADC->DAT5, \ + &ADC->DAT6, &ADC->DAT7, &ADC->DAT8, &ADC->DAT9, &ADC->DAT10, &ADC->DAT11, \ + &ADC->DAT12, &ADC->DAT13, &ADC->DAT14, &ADC->DAT15 + }; + uint32_t default_values = 0X0; + uint32_t write_values[] = {0xFFFFFFFF, 0x00000000, 0x5A5A5A5A, 0xA5A5A5A5}; + + __HAL_SYSCFG_RESET_ADC(); + + for (int i = 0; i < 16; i++) // READ CHECK REG + { + read_value =REG_READ(*registers[i]); + printf("\nDATA%d: Register Default: 0X%X, Register Read: 0X%X\n", i, default_values, read_value); + if (default_values == read_value) + { + printf("Match\n"); + } + else + { + err("No Match\n"); + } + } + + for (int j = 0; j < 4; j++) // WRITE & CHECK REG + { + + for (int i = 0; i < 16; i++) + { + write_value = write_values[j]; + result_value = (write_value & 0x0FFF0000); + REG_WRITE(*registers[i], write_value); + read_value = REG_READ(*registers[i]); + printf("\nDATA%d: Register Write: 0X%X, Register result value: 0X%X, Register Read: 0X%X\n", i, write_value, result_value, read_value); + if (result_value == read_value) + { + printf("Match\n"); + } + else + { + err("No Match\n"); + } + } + } + + msg("\ndone~~~\n"); + + while(1) + { + __NOP(); + } +} diff --git a/Examples/amisc/dac_test/.cproject b/Examples/amisc/dac_test/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/amisc/dac_test/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/amisc/dac_test/.project b/Examples/amisc/dac_test/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/Examples/amisc/dac_test/.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/Examples/amisc/dac_test/Project.nuproject b/Examples/amisc/dac_test/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/Examples/amisc/dac_test/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/amisc/dac_test/component.mk b/Examples/amisc/dac_test/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Examples/amisc/dac_test/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/Examples/amisc/dac_test/inc/isr.h b/Examples/amisc/dac_test/inc/isr.h new file mode 100644 index 0000000..b77f364 --- /dev/null +++ b/Examples/amisc/dac_test/inc/isr.h @@ -0,0 +1,51 @@ +/** + * 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/Examples/amisc/dac_test/inc/main.h b/Examples/amisc/dac_test/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Examples/amisc/dac_test/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/Examples/amisc/dac_test/src/isr.c b/Examples/amisc/dac_test/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/Examples/amisc/dac_test/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/Examples/amisc/dac_test/src/main.c b/Examples/amisc/dac_test/src/main.c new file mode 100644 index 0000000..541fdd6 --- /dev/null +++ b/Examples/amisc/dac_test/src/main.c @@ -0,0 +1,149 @@ +/** + * 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 GPIO_PORTx GPIOA + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + GPIO_InitTypeDef Init_GPIO = {0}; + AMISC_VBUFConfigTypeDef VBUFConfig = {0}; + + + { + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + } + + sys_config_systick(SYS_TICK_10_MS); + + syslog_init(); + + info("%s\nThis is a demo project to dac0_1 \n", __TIME__); + + AMISC_Init(); + + VBUFConfig.Ana2IOT = AMISC_Ana2IO_En; // dac0_1 out=pa8 + VBUFConfig.Ana2PGA = AMISC_Ana2PGA_Disable; + VBUFConfig.Ana2PGA = AMISC_AnaSel_dac0; //AMISC_AnaSel_dac0 AMISC_AnaSel_dac1 + + AMISC_VBUF_Config(&VBUFConfig); + AMISC_Vbuf_Enable(); + + AMISC_DAC0_Config(0x10); // test_dac0 + AMISC_DAC0_Enable(); + + //AMISC_DAC1_Config(0x10); // test_dac1 + // AMISC_DAC1_Enable(); + + //uint32_t sel = (GPIO_ReadOutputData(GPIOA) >> 0) & 0x0F; // pa3:pa2:pa1:pa0 + + while(1) + { + uint32_t sel = (GPIO_ReadOutputData(GPIOA) >> 0) & 0x0F; // pa3:pa2:pa1:pa0 + switch( sel ) + { + + default: + case 0x00: + AMISC_DAC0_Config(0x00); //0mV for 3.3V + AMISC_DAC1_Config(0x00); + break; + + case 0x01: + AMISC_DAC0_Config(0x02); //6.44mV + AMISC_DAC1_Config(0x02); + break; + + case 0x02: + AMISC_DAC0_Config(0x04); //12.88mV + AMISC_DAC1_Config(0x04); + break; + + case 0x03: + AMISC_DAC0_Config(0x08); //25.76mV + AMISC_DAC1_Config(0x08); + break; + + case 0x04: + AMISC_DAC0_Config(0x10); //51.52mV + AMISC_DAC1_Config(0x10); + break; + + case 0x05: + AMISC_DAC0_Config(0x20); //103.04mV + AMISC_DAC1_Config(0x20); + break; + + case 0x06: + AMISC_DAC0_Config(0x40); //206.8mV + AMISC_DAC1_Config(0x40); + break; + + case 0x07: + AMISC_DAC0_Config(0x80); //412.16mV + AMISC_DAC1_Config(0x80); + break; + + case 0x08: + AMISC_DAC0_Config(0x100); //824.32mV + AMISC_DAC1_Config(0x100); + break; + + case 0x09: + AMISC_DAC0_Config(0x200); //1648.64mV + AMISC_DAC1_Config(0x200); + break; + + case 0x0A: + AMISC_DAC0_Config(0x300); //2472.96mV + AMISC_DAC1_Config(0x300); + break; + + case 0x0B: + AMISC_DAC0_Config(0x3FF); //3.297.28mV + AMISC_DAC1_Config(0x3FF); + break; + + } + + __asm("nop"); + __asm("nop"); + + } +} diff --git a/Examples/comp/Compare_GpioVsVref/.cproject b/Examples/comp/Compare_GpioVsVref/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/comp/Compare_GpioVsVref/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/comp/Compare_GpioVsVref/.project b/Examples/comp/Compare_GpioVsVref/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/Examples/comp/Compare_GpioVsVref/.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/Examples/comp/Compare_GpioVsVref/Project.nuproject b/Examples/comp/Compare_GpioVsVref/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/Examples/comp/Compare_GpioVsVref/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/comp/Compare_GpioVsVref/component.mk b/Examples/comp/Compare_GpioVsVref/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Examples/comp/Compare_GpioVsVref/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/Examples/comp/Compare_GpioVsVref/inc/isr.h b/Examples/comp/Compare_GpioVsVref/inc/isr.h new file mode 100644 index 0000000..b77f364 --- /dev/null +++ b/Examples/comp/Compare_GpioVsVref/inc/isr.h @@ -0,0 +1,51 @@ +/** + * 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/Examples/comp/Compare_GpioVsVref/inc/main.h b/Examples/comp/Compare_GpioVsVref/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Examples/comp/Compare_GpioVsVref/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/Examples/comp/Compare_GpioVsVref/readme.md b/Examples/comp/Compare_GpioVsVref/readme.md new file mode 100644 index 0000000..74954ad --- /dev/null +++ b/Examples/comp/Compare_GpioVsVref/readme.md @@ -0,0 +1,17 @@ +compare test +--- + +This example is used to run compare test function. + +## Hardware and Software environment + ++ This example runs on PB5700 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 ++ compare0 & 1 Negative(PA6 PA12) & Positive(PA8 PA11) Output results in COUT(PA7 PA13) \ No newline at end of file diff --git a/Examples/comp/Compare_GpioVsVref/src/isr.c b/Examples/comp/Compare_GpioVsVref/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/Examples/comp/Compare_GpioVsVref/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/Examples/comp/Compare_GpioVsVref/src/main.c b/Examples/comp/Compare_GpioVsVref/src/main.c new file mode 100644 index 0000000..7692127 --- /dev/null +++ b/Examples/comp/Compare_GpioVsVref/src/main.c @@ -0,0 +1,113 @@ +/** + * 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 GPIO_PORTx GPIOA + +/** + * Use COMP0 or COMP1 + */ +#define CONFIG_USE_COMP0 +// #define CONFIG_USE_COMP1 + +#if defined(CONFIG_USE_COMP0) + #define COMPx COMP0 +#elif defined(CONFIG_USE_COMP1) + #define COMPx COMP1 +#endif + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + GPIO_InitTypeDef Init_GPIO = {0}; + COMP_InitTypeDef Init_Comp = {0}; + + { + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + } + + sys_config_systick(SYS_TICK_10_MS); + + syslog_init(); + + info("%s\nThis is a demo project to compare gpio vs Vreflnt\n", __TIME__); + + Init_Comp.COMP_NegativeSel = COMP_Vin_IO; // vin io comp0=pa6 comp1=pa12 + Init_Comp.COMP_Filter = COMP_Filter_Bypass; + Init_Comp.COMP_Polarity = COMP_Polarity_Normal; + Init_Comp.COMP_PositiveSel = COMP_Vip_IO3; // vip comp0_1 pga io0=pa8 io1=pa11 io2=pa14 io3=pa15 + Init_Comp.COMP_Interrupt = 0x0; // disable interrupt; + Init_Comp.COMP_InitDelay = 0x3C; + Init_Comp.COMP_Out = COMP_Out_Disable; //Out_Enable COMP0 --->PA7 COMP1 --->PA13 + Init_Comp.COMP_Hsy = COMP_Hsy_Enable; + + COMP_Init(COMP0, &Init_Comp); + + COMP_Init(COMP1, &Init_Comp); + + COMP_Enable(COMP0); + COMP_Enable(COMP1); + + Init_GPIO.GPIO_Pin = GPIO_Pin_03|GPIO_Pin_04; + Init_GPIO.GPIO_Mode = GPIO_Mode_OUT; + Init_GPIO.GPIO_PuPd = GPIO_PuPd_NOPULL; + Init_GPIO.GPIO_OType = GPIO_OType_PP; + GPIO_Init(GPIO_PORTx , &Init_GPIO); + + while(1) + { + if( COMP_GetOutputLevel(COMP0) == 0 ) + { + GPIO_ResetBits(GPIO_PORTx, GPIO_Pin_03); + } + else + { + GPIO_SetBits(GPIO_PORTx, GPIO_Pin_03); + } + + if( COMP_GetOutputLevel(COMP1) == 0 ) + { + GPIO_WriteBit(GPIO_PORTx, GPIO_Pin_04, GPIO_PIN_LOW); + } + else + { + GPIO_WriteBit(GPIO_PORTx, GPIO_Pin_04, GPIO_PIN_HIGH); + } + + } +} diff --git a/Examples/comp/Compare_for_TI/.cproject b/Examples/comp/Compare_for_TI/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/comp/Compare_for_TI/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/comp/Compare_for_TI/.project b/Examples/comp/Compare_for_TI/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/Examples/comp/Compare_for_TI/.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/Examples/comp/Compare_for_TI/Project.nuproject b/Examples/comp/Compare_for_TI/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/Examples/comp/Compare_for_TI/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/comp/Compare_for_TI/component.mk b/Examples/comp/Compare_for_TI/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Examples/comp/Compare_for_TI/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/Examples/comp/Compare_for_TI/inc/isr.h b/Examples/comp/Compare_for_TI/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/Examples/comp/Compare_for_TI/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/Examples/comp/Compare_for_TI/inc/main.h b/Examples/comp/Compare_for_TI/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Examples/comp/Compare_for_TI/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/Examples/comp/Compare_for_TI/readme.md b/Examples/comp/Compare_for_TI/readme.md new file mode 100644 index 0000000..16e618a --- /dev/null +++ b/Examples/comp/Compare_for_TI/readme.md @@ -0,0 +1,17 @@ +compare test +--- + +This example is used to run compare test function. + +## Hardware and Software environment + ++ This example runs on PB5700 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 ++ compare0 & 1 Output results in COUT \ No newline at end of file diff --git a/Examples/comp/Compare_for_TI/src/isr.c b/Examples/comp/Compare_for_TI/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/Examples/comp/Compare_for_TI/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/Examples/comp/Compare_for_TI/src/main.c b/Examples/comp/Compare_for_TI/src/main.c new file mode 100644 index 0000000..c99d24c --- /dev/null +++ b/Examples/comp/Compare_for_TI/src/main.c @@ -0,0 +1,109 @@ +/** + * 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 GPIO_PORTx GPIOA + +/** + * Use COMP0 or COMP1 + */ +#define CONFIG_USE_COMP0 +// #define CONFIG_USE_COMP1 + +#if defined(CONFIG_USE_COMP0) + #define COMPx COMP0 +#elif defined(CONFIG_USE_COMP1) + #define COMPx COMP1 +#endif + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + GPIO_InitTypeDef Init_GPIO = {0}; + COMP_InitTypeDef Init_Comp = {0}; + + { + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + } + + sys_config_systick(SYS_TICK_10_MS); + + syslog_init(); + + info("%s\nThis is a demo project to compare gpio vs Vreflnt\n", __TIME__); + + __HAL_SYSCFG_COMP0_CLK_ENABLE(); + + REG_WRITE_MASK(COMP0->CTRL, COMP_CTRL_VIN_SEL_Msk , COMP_Vin_IO ); // COMP0 selection Negative(IO) @ref COMP_Vin + + COMP_Enable(COMP0); + + __HAL_SYSCFG_COMP1_CLK_ENABLE(); + + REG_WRITE_MASK(COMP1->CTRL, COMP_CTRL_VIN_SEL_Msk , COMP_Vin_IO ); // COMP1 selection Negative(IO) @ref COMP_Vin + + COMP_Enable(COMP1); + + Init_GPIO.GPIO_Pin = GPIO_Pin_03|GPIO_Pin_04; + Init_GPIO.GPIO_Mode = GPIO_Mode_OUT; + Init_GPIO.GPIO_PuPd = GPIO_PuPd_NOPULL; + Init_GPIO.GPIO_OType = GPIO_OType_PP; + GPIO_Init(GPIO_PORTx , &Init_GPIO); + + while(1) + { + if( COMP_GetOutputLevel(COMP0) == 0 ) + { + GPIO_ResetBits(GPIO_PORTx, GPIO_Pin_03); + } + else + { + GPIO_SetBits(GPIO_PORTx, GPIO_Pin_03); + } + + if( COMP_GetOutputLevel(COMP1) == 0 ) + { + GPIO_WriteBit(GPIO_PORTx, GPIO_Pin_04, GPIO_PIN_LOW); + } + else + { + GPIO_WriteBit(GPIO_PORTx, GPIO_Pin_04, GPIO_PIN_HIGH); + } + + } +} diff --git a/Examples/comp/comp_test/.cproject b/Examples/comp/comp_test/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/comp/comp_test/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/comp/comp_test/.project b/Examples/comp/comp_test/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/Examples/comp/comp_test/.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/Examples/comp/comp_test/Project.nuproject b/Examples/comp/comp_test/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/Examples/comp/comp_test/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/comp/comp_test/component.mk b/Examples/comp/comp_test/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Examples/comp/comp_test/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/Examples/comp/comp_test/inc/isr.h b/Examples/comp/comp_test/inc/isr.h new file mode 100644 index 0000000..b77f364 --- /dev/null +++ b/Examples/comp/comp_test/inc/isr.h @@ -0,0 +1,51 @@ +/** + * 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/Examples/comp/comp_test/inc/main.h b/Examples/comp/comp_test/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Examples/comp/comp_test/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/Examples/comp/comp_test/src/isr.c b/Examples/comp/comp_test/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/Examples/comp/comp_test/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/Examples/comp/comp_test/src/main.c b/Examples/comp/comp_test/src/main.c new file mode 100644 index 0000000..e69a65d --- /dev/null +++ b/Examples/comp/comp_test/src/main.c @@ -0,0 +1,125 @@ +/** + * 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 GPIO_PORTx GPIOA + +/** + * Use COMP0 or COMP1 + */ +#define CONFIG_USE_COMP0 +// #define CONFIG_USE_COMP1 + +#if defined(CONFIG_USE_COMP0) + #define COMPx COMP0 +#elif defined(CONFIG_USE_COMP1) + #define COMPx COMP1 +#endif + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + GPIO_InitTypeDef Init_GPIO = {0}; + COMP_InitTypeDef Init_Comp = {0}; + + { + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + } + + sys_config_systick(SYS_TICK_10_MS); + + // syslog_init(); + + // info("%s\nThis is a demo project to compare gpio vs Vreflnt\n", __TIME__); + + Init_Comp.COMP_NegativeSel = COMP_Vin_IO; //vin comp0=pa6 comp1=pa12 + Init_Comp.COMP_Filter = COMP_Filter_Sample_2; //COMP_Filter_Bypass + Init_Comp.COMP_Polarity = COMP_Polarity_Normal; + Init_Comp.COMP_PositiveSel = COMP_Vip_IO3; // vip comp0_1 pga io0=pa8 io1=pa11 io2=pa14 io3=pa15 + Init_Comp.COMP_Interrupt = 0x0; // disable interrupt; + Init_Comp.COMP_InitDelay = 0x3C; + Init_Comp.COMP_Out = COMP_Out_Enable; //Out_Enable COMP0 --->PA7 COMP1 --->PA13 + Init_Comp.COMP_Hsy = COMP_Hsy_Enable; // COMP_Hsy_Enable + COMP_Init(COMP0, &Init_Comp); + + Init_Comp.COMP_PositiveSel = COMP_Vip_IO2; // vip comp0_1 pga io0=pa8 io1=pa11 io2=pa14 io3=pa15 + COMP_Init(COMP1, &Init_Comp); + + COMP_Enable(COMP0); + COMP_Enable(COMP1); + + /* Init_GPIO.GPIO_Pin = GPIO_Pin_03|GPIO_Pin_04; + Init_GPIO.GPIO_Mode = GPIO_Mode_OUT; + Init_GPIO.GPIO_PuPd = GPIO_PuPd_NOPULL; + Init_GPIO.GPIO_OType = GPIO_OType_PP; + GPIO_Init(GPIO_PORTx , &Init_GPIO); */ + + COMP_VipTypeDef val=0x00 ; + while(1) + { + uint32_t sel = (GPIO_ReadOutputData(GPIOA) >> 0) & 0x03; // pa1:pa0 + // COMP_VipTypeDef val=0x00 ; + switch( sel ) + { + + default: + case 0x00: + val = COMP_Vip_IO0; + break; + + case 0x01: + val = COMP_Vip_IO1; + break; + + case 0x02: + val = COMP_Vip_IO2; + break; + + case 0x03: + val = COMP_Vip_IO3; + break; + + } + + REG_WRITE_MASK(COMP0->VIPSEL ,COMP_VIPSEL_VIP_SEL_Msk, val ); + REG_WRITE_MASK(COMP1->VIPSEL ,COMP_VIPSEL_VIP_SEL_Msk, val ); + __asm("nop"); + } + + return 0; +} diff --git a/Examples/crc/crc_calculate/.cproject b/Examples/crc/crc_calculate/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/crc/crc_calculate/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/crc/crc_calculate/.project b/Examples/crc/crc_calculate/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/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/Examples/crc/crc_calculate/Project.nuproject b/Examples/crc/crc_calculate/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/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: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/crc/crc_calculate/component.mk b/Examples/crc/crc_calculate/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/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/Examples/crc/crc_calculate/inc/isr.h b/Examples/crc/crc_calculate/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/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/Examples/crc/crc_calculate/inc/main.h b/Examples/crc/crc_calculate/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/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/Examples/crc/crc_calculate/readme.md b/Examples/crc/crc_calculate/readme.md new file mode 100644 index 0000000..32dc761 --- /dev/null +++ b/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/Examples/crc/crc_calculate/src/isr.c b/Examples/crc/crc_calculate/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/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/Examples/crc/crc_calculate/src/main.c b/Examples/crc/crc_calculate/src/main.c new file mode 100644 index 0000000..fc290c2 --- /dev/null +++ b/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/Examples/dsp/dsp_divide/.cproject b/Examples/dsp/dsp_divide/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/dsp/dsp_divide/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/dsp/dsp_divide/.project b/Examples/dsp/dsp_divide/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/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/Examples/dsp/dsp_divide/Project.nuproject b/Examples/dsp/dsp_divide/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/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: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/dsp/dsp_divide/component.mk b/Examples/dsp/dsp_divide/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/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/Examples/dsp/dsp_divide/inc/isr.h b/Examples/dsp/dsp_divide/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/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/Examples/dsp/dsp_divide/inc/main.h b/Examples/dsp/dsp_divide/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/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/Examples/dsp/dsp_divide/readme.md b/Examples/dsp/dsp_divide/readme.md new file mode 100644 index 0000000..977c064 --- /dev/null +++ b/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/Examples/dsp/dsp_divide/src/isr.c b/Examples/dsp/dsp_divide/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/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/Examples/dsp/dsp_divide/src/main.c b/Examples/dsp/dsp_divide/src/main.c new file mode 100644 index 0000000..26d1de4 --- /dev/null +++ b/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/Examples/dsp/dsp_sqrt/.cproject b/Examples/dsp/dsp_sqrt/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/dsp/dsp_sqrt/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/dsp/dsp_sqrt/.project b/Examples/dsp/dsp_sqrt/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/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/Examples/dsp/dsp_sqrt/Project.nuproject b/Examples/dsp/dsp_sqrt/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/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: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/dsp/dsp_sqrt/component.mk b/Examples/dsp/dsp_sqrt/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/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/Examples/dsp/dsp_sqrt/inc/isr.h b/Examples/dsp/dsp_sqrt/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/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/Examples/dsp/dsp_sqrt/inc/main.h b/Examples/dsp/dsp_sqrt/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/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/Examples/dsp/dsp_sqrt/readme.md b/Examples/dsp/dsp_sqrt/readme.md new file mode 100644 index 0000000..7a697d6 --- /dev/null +++ b/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/Examples/dsp/dsp_sqrt/src/isr.c b/Examples/dsp/dsp_sqrt/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/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/Examples/dsp/dsp_sqrt/src/main.c b/Examples/dsp/dsp_sqrt/src/main.c new file mode 100644 index 0000000..6222e3d --- /dev/null +++ b/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/Examples/flash/flash_prog_erase/.cproject b/Examples/flash/flash_prog_erase/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/flash/flash_prog_erase/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/flash/flash_prog_erase/.project b/Examples/flash/flash_prog_erase/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/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/Examples/flash/flash_prog_erase/Project.nuproject b/Examples/flash/flash_prog_erase/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/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: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/flash/flash_prog_erase/component.mk b/Examples/flash/flash_prog_erase/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/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/Examples/flash/flash_prog_erase/inc/isr.h b/Examples/flash/flash_prog_erase/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/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/Examples/flash/flash_prog_erase/inc/main.h b/Examples/flash/flash_prog_erase/inc/main.h new file mode 100644 index 0000000..4905c06 --- /dev/null +++ b/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 (32ul << 10) +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Examples/flash/flash_prog_erase/readme.md b/Examples/flash/flash_prog_erase/readme.md new file mode 100644 index 0000000..a1e5753 --- /dev/null +++ b/Examples/flash/flash_prog_erase/readme.md @@ -0,0 +1,44 @@ +flash_prog_erase +--- + +This example is a demo project to P/E (Program/Erase) 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 in every case: + ++ Erase eFalsh and verify data is `0xFF` or not ++ Program **word/hword/byte data** to eFlash and verify the result value of eFlash + +It also supports fix/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 +> ``` + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + +``` +This is a 13:28:12 +This is eFlash Erase/Program/Read (0x00002800 ~ 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/Examples/flash/flash_prog_erase/src/isr.c b/Examples/flash/flash_prog_erase/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/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/Examples/flash/flash_prog_erase/src/main.c b/Examples/flash/flash_prog_erase/src/main.c new file mode 100644 index 0000000..4379189 --- /dev/null +++ b/Examples/flash/flash_prog_erase/src/main.c @@ -0,0 +1,398 @@ +/** + * 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 +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static uint32_t g_buf[512 >> 2] = {0}; +//============================================================================= +// Private Function Definition +//============================================================================= +static uint32_t __rand(void) +{ + static uint32_t z1 = 0, z2 = 0, z3 = 0, z4 = 0 ; + + if( z1 == 0 && z2 == 0 ) + { + char *str = __TIME__; + uint16_t *pCur = (uint16_t*)str; + z1 = pCur[0]; + z2 = pCur[1]; + z3 = pCur[2]; + z4 = pCur[3]; + } + + uint32_t b; + b = ((z1 << 6) ^ z1) >> 13; + z1 = ((z1 & 0xFFFFFFFEU) << 18) ^ b; + b = ((z2 << 2) ^ z2) >> 27; + z2 = ((z2 & 0xFFFFFFF8U) << 2) ^ b; + b = ((z3 << 13) ^ z3) >> 21; + z3 = ((z3 & 0xFFFFFFF0U) << 7) ^ b; + b = ((z4 << 3) ^ z4) >> 12; + z4 = ((z4 & 0xFFFFFF80U) << 13) ^ b; + return (z1 ^ z2 ^ z3 ^ z4); +} + +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; */ + } + + #if defined(CONFIG_MORE_MESSAGE) + msg("addr(x%08X)= x%08X, pattern= x%08X\n", &pCur[i], pCur[i], 0xFFFFFFFF); + #endif + } + } + + 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)) + { + #if defined(CONFIG_MORE_MESSAGE) + msg("addr(x%08X)= x%08X, pattern= x%08X\n", addr + i, *(uint32_t*)(addr + i), pattern); + #endif + + 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)) + { + #if defined(CONFIG_MORE_MESSAGE) + msg("addr(x%08X)= x%08X, pattern= x%08X\n", addr + i, *(uint16_t*)(addr + i), pattern); + #endif + + 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)) + { + #if defined(CONFIG_MORE_MESSAGE) + msg("addr(x%08X)= x%08X, pattern= x%08X\n", addr + i, *(uint8_t*)(addr + i), pattern); + #endif + + 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)) + { + #if defined(CONFIG_MORE_MESSAGE) + msg("addr(x%08X)= x%08X, pattern= x%08X\n", addr + i, *(uint32_t*)(addr + i), patt_act); + #endif + + 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\nThis is eFlash Erase/Program/Read (0x%08x ~ 0x%08x) example\n", + __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) + ? (__rand() << 16 | __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) + ? (__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) + ? ((__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) + ? (__rand() << 16 | __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/Examples/flash/flash_prog_erase_nvr/component.mk b/Examples/flash/flash_prog_erase_nvr/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Examples/flash/flash_prog_erase_nvr/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/Examples/flash/flash_prog_erase_nvr/inc/isr.h b/Examples/flash/flash_prog_erase_nvr/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/Examples/flash/flash_prog_erase_nvr/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/Examples/flash/flash_prog_erase_nvr/inc/main.h b/Examples/flash/flash_prog_erase_nvr/inc/main.h new file mode 100644 index 0000000..7b07a4c --- /dev/null +++ b/Examples/flash/flash_prog_erase_nvr/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/Examples/flash/flash_prog_erase_nvr/readme.md b/Examples/flash/flash_prog_erase_nvr/readme.md new file mode 100644 index 0000000..a94016e --- /dev/null +++ b/Examples/flash/flash_prog_erase_nvr/readme.md @@ -0,0 +1,126 @@ +flash_prog_erase_nvr +--- + +This example is a demo project to P/E (Program/Erase) NVR area of DUT (execute at main-flash) +> This example is only for `internal` verification. + We do NOT expect user to modify data of NVR + + ++ There are 8-KBytes (sector 0 ~ 15) in NVR area + > A sector size is 512 bytes + + - The 15-th sector is recorded the paraments of embedded flash + - The 14-th sector is recorded the trim-values + ++ It supports 3 type (read 8/16/32 bits) to verify data + + ```c + // at main.c + #define CONFIG_USE_READ_WORD + /* #define CONFIG_USE_READ_HWORD */ + /* #define CONFIG_USE_READ_BYTE */ + ``` + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + +``` +14:12:31 +This is NVR Erase/Program/Read (0x00200000 ~ 0x00201e00) example +## P/E with word value, read 32-bits to verify +sector-addr: x00200000 + erase this sector + verify data + prog data to this sector + verify data + done~ +sector-addr: x00200200 + erase this sector + verify data + prog data to this sector + verify data + done~ +sector-addr: x00200400 + erase this sector + verify data + prog data to this sector + verify data + done~ +sector-addr: x00200600 + erase this sector + verify data + prog data to this sector + verify data + done~ +sector-addr: x00200800 + erase this sector + verify data + prog data to this sector + verify data + done~ +sector-addr: x00200A00 + erase this sector + verify data + prog data to this sector + verify data + done~ +sector-addr: x00200C00 + erase this sector + verify data + prog data to this sector + verify data + done~ +sector-addr: x00200E00 + erase this sector + verify data + prog data to this sector + verify data + done~ +sector-addr: x00201000 + erase this sector + verify data + prog data to this sector + verify data + done~ +sector-addr: x00201200 + erase this sector + verify data + prog data to this sector + verify data + done~ +sector-addr: x00201400 + erase this sector + verify data + prog data to this sector + verify data + done~ +sector-addr: x00201600 + erase this sector + verify data + prog data to this sector + verify data + done~ +sector-addr: x00201800 + erase this sector + verify data + prog data to this sector + verify data + done~ +sector-addr: x00201A00 + erase this sector + verify data + prog data to this sector + verify data + done~ +sector-addr: x00201C00 + erase this sector + verify data + prog data to this sector + verify data + done~ +Fully verify data + done~ +done ~~~~~~ + +``` diff --git a/Examples/flash/flash_prog_erase_nvr/src/isr.c b/Examples/flash/flash_prog_erase_nvr/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/Examples/flash/flash_prog_erase_nvr/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/Examples/flash/flash_prog_erase_nvr/src/main.c b/Examples/flash/flash_prog_erase_nvr/src/main.c new file mode 100644 index 0000000..0df6cc9 --- /dev/null +++ b/Examples/flash/flash_prog_erase_nvr/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 +#include +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_USE_READ_WORD +/* #define CONFIG_USE_READ_HWORD */ +/* #define CONFIG_USE_READ_BYTE */ + +#define CONFIG_NVR_SECTOR_NUM ((FLASH_PROG_NVR_ADDR_END - FLASH_PROG_NVR_ADDR_START) >> 9) + +#define CONFIG_PATTERN_WORD_1 0x5A5A5A5Aul +#define CONFIG_PATTERN_WORD_2 0xA5A5A5A5ul + +#define __SYSINFO_UNLOCK() REG_WRITE(*(volatile uint32_t*)0x4000F82C, 0x5A5A005A) +#define __SYSINFO_LOCK() REG_WRITE(*(volatile uint32_t*)0x4000F82C, 0x5A5A0000) +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= +flash_state_t +_FLASH_EraseNVRSector(uint32_t nvr_addr) +{ + flash_state_t rval = FLASH_STATE_OK; + + if( nvr_addr < (uint32_t)&NVR_MEM->DATA0 || + nvr_addr > (uint32_t)&NVR_MEM->DATA_END ) + { + return FLASH_STATE_FAIL_ADDR; + } + + REG_WRITE(FLASH->SR, 0xFFFFFFFFul); // clean status flags + + REG_WRITE(FLASH->DIV, SYS_HIRC_MHZ); + + FLASH->AR = nvr_addr & ~(FLASH_1_SECTOR_SIZE - 1); + + if( nvr_addr >= 0x00201C00 && nvr_addr <= 0x00201E00 ) + { + __SYSINFO_UNLOCK(); + } + + REG_WRITE_MASK(FLASH->CMD, + (FLASH_CMD_KEY_Msk | FLASH_CMD_START_Msk | + FLASH_CMD_UNLOCK_Msk | + FLASH_CMD_CMD_Msk), + (0xA5EC0000ul | FLASH_CMD_START_Msk | \ + (0x1ul << FLASH_CMD_UNLOCK_Pos) | \ + (FLASH_CMD_CMD_ERASE_SECTOR << FLASH_CMD_CMD_Pos))); + + /* lock P/E operations */ + REG_WRITE_MASK(FLASH->CMD, + (FLASH_CMD_KEY_Msk | FLASH_CMD_UNLOCK_Msk), + FLASH_AUTH_KEY); + + __SYSINFO_LOCK(); + return rval; +} + +flash_state_t +_FLASH_ProgNVRWord(uint32_t addr, uint32_t value) +{ + flash_state_t rval = FLASH_STATE_OK; + + if( addr < (uint32_t)&NVR_MEM->DATA0 || + addr > (uint32_t)&NVR_MEM->DATA_END || + (addr & 0x3ul) ) + { + return FLASH_STATE_FAIL_ADDR; + } + + REG_WRITE(FLASH->SR, 0xFFFFFFFFul); // clean status flags + + REG_WRITE(FLASH->DIV, SYS_HIRC_MHZ); + + FLASH->AR = addr; + FLASH->DR = value; + + if( addr >= 0x00201C00 && addr <= 0x00201E00 ) + { + __SYSINFO_UNLOCK(); + } + + REG_WRITE_MASK(FLASH->CMD, + (FLASH_CMD_KEY_Msk | + FLASH_CMD_UNLOCK_Msk | + FLASH_CMD_CMD_Msk | FLASH_CMD_START_Msk), + (0xA5EC0000ul | \ + (0x1ul << FLASH_CMD_UNLOCK_Pos) | \ + (FLASH_CMD_CMD_PROG << FLASH_CMD_CMD_Pos) | FLASH_CMD_START_Msk)); + + /* lock P/E operations */ + REG_WRITE_MASK(FLASH->CMD, + (FLASH_CMD_KEY_Msk | FLASH_CMD_UNLOCK_Msk), + FLASH_AUTH_KEY); + + __SYSINFO_LOCK(); + return rval; +} + +flash_state_t +_FLASH_ProgNVRData(uint32_t addr, uint32_t *pData, int length) +{ + flash_state_t rval = FLASH_STATE_OK; + + if( addr < (uint32_t)&NVR_MEM->DATA0 || + addr > (uint32_t)&NVR_MEM->DATA_END || + addr & 0x3 || length & 0x3 ) + { + return FLASH_STATE_FAIL_ADDR; + } + + REG_WRITE(FLASH->SR, 0xFFFFFFFFul); // clean status flags + + REG_WRITE(FLASH->DIV, SYS_HIRC_MHZ); + + FLASH->AR = addr; + + do { + FLASH->AR = addr; + FLASH->DR = *pData++; + + if( addr >= 0x00201C00 && addr <= 0x00201E00 ) + { + __SYSINFO_UNLOCK(); + } + + REG_WRITE_MASK(FLASH->CMD, + (FLASH_CMD_KEY_Msk | + FLASH_CMD_UNLOCK_Msk | + FLASH_CMD_CMD_Msk | FLASH_CMD_START_Msk), + (0xA5EC0000ul | \ + (0x1ul << FLASH_CMD_UNLOCK_Pos) | \ + (FLASH_CMD_CMD_PROG << FLASH_CMD_CMD_Pos) | FLASH_CMD_START_Msk)); + + 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); + + __SYSINFO_LOCK(); + return rval; +} + +static int +_Flash_VerifyData(uint32_t addr_start, uint32_t addr_end, uint32_t patt_value) +{ + int rval = 0; + union { + uint32_t *pWCur; + uint16_t *pHWCur; + uint8_t *pBCur; + } u; + + /* uint32_t *pCur = (uint32_t*)addr_start; */ + + u.pWCur = (uint32_t*)addr_start; + + while( (uint32_t)u.pWCur < addr_end ) + { + #if defined(CONFIG_USE_READ_WORD) + if( *u.pWCur++ == patt_value ) + continue; + #elif defined(CONFIG_USE_READ_HWORD) + if( *u.pHWCur++ == (patt_value & 0xFFFFul) && + *u.pHWCur++ == ((patt_value >> 16) & 0xFFFFul) ) + continue; + #else + if( *u.pBCur++ == (patt_value & 0xFFul) && + *u.pBCur++ == ((patt_value >> 8) & 0xFFul) && + *u.pBCur++ == ((patt_value >> 16) & 0xFFul) && + *u.pBCur++ == ((patt_value >> 24) & 0xFFul) ) + continue; + #endif + + err("x%08X: x%08X != x%08X\n", + (uint32_t)(u.pWCur - 1), + *(u.pWCur - 1), patt_value); + + rval = -1; + } + 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\nThis is NVR Erase/Program/Read (0x%08x ~ 0x%08x) example\n", + __TIME__, FLASH_PROG_NVR_ADDR_START, FLASH_PROG_NVR_ADDR_END); + + + do { + uint32_t patt_value = CONFIG_PATTERN_WORD_1; + + log_color(SLOG_GREEN, "## P/E with word value, read %s to verify\n", + #if defined(CONFIG_USE_READ_WORD) + "32-bits" + #elif defined(CONFIG_USE_READ_HWORD) + "16-bits" + #else + "8-bits" + #endif + ); + + + for(uint32_t addr_sector = FLASH_PROG_NVR_ADDR_START; + addr_sector < FLASH_PROG_NVR_ADDR_END; + addr_sector += FLASH_1_SECTOR_SIZE) + { + msg("sector-addr: x%08X\n", addr_sector); + + msg(" erase this sector\n"); + /* Erase a sector */ + rval = (int)_FLASH_EraseNVRSector(addr_sector); + if( rval ) break; + + msg(" verify data\n"); + /* Verify data in the sector */ + rval = _Flash_VerifyData(addr_sector, addr_sector + FLASH_1_SECTOR_SIZE, 0xFFFFFFFFul); + if( rval ) + { + rval = -__LINE__; + break; + } + + /* Program data to this sector */ + msg(" prog data to this sector\n"); + for(uint32_t addr_word = addr_sector; + addr_word < addr_sector + FLASH_1_SECTOR_SIZE; + addr_word += 4) + { + rval = (int)_FLASH_ProgNVRWord(addr_word, patt_value); + if( rval ) break; + } + + msg(" verify data\n"); + /* Verify data in the sector */ + rval = _Flash_VerifyData(addr_sector, addr_sector + FLASH_1_SECTOR_SIZE, patt_value); + if( rval ) + { + rval = -__LINE__; + break; + } + + msg(" done~\n"); + } + + if( rval ) break; + + msg("Fully verify data\n"); + /* Verify data in the sector */ + rval = _Flash_VerifyData(FLASH_PROG_NVR_ADDR_START, FLASH_PROG_NVR_ADDR_END, patt_value); + if( rval ) + { + rval = -__LINE__; + 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/Examples/flash/flash_set_latency/.cproject b/Examples/flash/flash_set_latency/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/flash/flash_set_latency/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/flash/flash_set_latency/.project b/Examples/flash/flash_set_latency/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/Examples/flash/flash_set_latency/.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/Examples/flash/flash_set_latency/Project.nuproject b/Examples/flash/flash_set_latency/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/Examples/flash/flash_set_latency/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/flash/flash_set_latency/component.mk b/Examples/flash/flash_set_latency/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Examples/flash/flash_set_latency/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/Examples/flash/flash_set_latency/inc/isr.h b/Examples/flash/flash_set_latency/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/Examples/flash/flash_set_latency/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/Examples/flash/flash_set_latency/inc/main.h b/Examples/flash/flash_set_latency/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Examples/flash/flash_set_latency/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/Examples/flash/flash_set_latency/readme.md b/Examples/flash/flash_set_latency/readme.md new file mode 100644 index 0000000..08f1e7a --- /dev/null +++ b/Examples/flash/flash_set_latency/readme.md @@ -0,0 +1,36 @@ +flash_set_latency +--- + +This example is a demo project to rendom switch latency of eFlash +> It will set new latency value to FMC and read back the latency value of FMC + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + +``` +15:18:36 +This is example of switching flash latency + + Set latency= 2 + Get latency= 2 + + Set latency= 3 + Get latency= 3 + + Set latency= 1 + Get latency= 1 + + Set latency= 3 + Get latency= 3 + + Set latency= 3 + Get latency= 3 + + Set latency= 1 + Get latency= 1 + + Set latency= 2 + Get latency= 2 + ... +``` diff --git a/Examples/flash/flash_set_latency/src/isr.c b/Examples/flash/flash_set_latency/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/Examples/flash/flash_set_latency/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/Examples/flash/flash_set_latency/src/main.c b/Examples/flash/flash_set_latency/src/main.c new file mode 100644 index 0000000..a36023c --- /dev/null +++ b/Examples/flash/flash_set_latency/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 +#include +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= +static uint32_t __rand(void) +{ + static uint32_t z1 = 0, z2 = 0, z3 = 0, z4 = 0 ; + + if( z1 == 0 && z2 == 0 ) + { + char *str = __TIME__; + uint16_t *pCur = (uint16_t*)str; + z1 = pCur[0]; + z2 = pCur[1]; + z3 = pCur[2]; + z4 = pCur[3]; + } + + uint32_t b; + b = ((z1 << 6) ^ z1) >> 13; + z1 = ((z1 & 0xFFFFFFFEU) << 18) ^ b; + b = ((z2 << 2) ^ z2) >> 27; + z2 = ((z2 & 0xFFFFFFF8U) << 2) ^ b; + b = ((z3 << 13) ^ z3) >> 21; + z3 = ((z3 & 0xFFFFFFF0U) << 7) ^ b; + b = ((z4 << 3) ^ z4) >> 12; + z4 = ((z4 & 0xFFFFFF80U) << 13) ^ b; + return (z1 ^ z2 ^ z3 ^ z4); +} +//============================================================================= +// 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\nThis is example of switching flash latency\n", + __TIME__); + + while(1) + { + flash_latency_t wait_cycles = FLASH_LATENCY_1; + + rval = __rand() & 0x3ul; + + wait_cycles = (rval == 0) ? FLASH_LATENCY_3 : + (rval == 1) ? FLASH_LATENCY_2 : + FLASH_LATENCY_1; + + msg("\n Set latency= %d\n", (wait_cycles == FLASH_LATENCY_2) ? 2 : + (wait_cycles == FLASH_LATENCY_3) ? 3 : + 1); + + FLASH_SetLatency(wait_cycles); + + __NOP(); + __NOP(); + __NOP(); + + wait_cycles = FLASH_GetLatency(); + + msg(" Get latency= %d\n", (wait_cycles == FLASH_LATENCY_2) ? 2 : + (wait_cycles == FLASH_LATENCY_3) ? 3 : + 1); + + #if 0 + { /* do flash P/E operation */ + } + #endif + } + return 0; +} diff --git a/Examples/flash/flash_sram_run/.cproject b/Examples/flash/flash_sram_run/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/flash/flash_sram_run/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/flash/flash_sram_run/.project b/Examples/flash/flash_sram_run/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/Examples/flash/flash_sram_run/.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/Examples/flash/flash_sram_run/Project.nuproject b/Examples/flash/flash_sram_run/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/Examples/flash/flash_sram_run/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/flash/flash_sram_run/component.mk b/Examples/flash/flash_sram_run/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Examples/flash/flash_sram_run/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/Examples/flash/flash_sram_run/inc/isr.h b/Examples/flash/flash_sram_run/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/Examples/flash/flash_sram_run/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/Examples/flash/flash_sram_run/inc/main.h b/Examples/flash/flash_sram_run/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Examples/flash/flash_sram_run/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/Examples/flash/flash_sram_run/readme.md b/Examples/flash/flash_sram_run/readme.md new file mode 100644 index 0000000..d140e94 --- /dev/null +++ b/Examples/flash/flash_sram_run/readme.md @@ -0,0 +1,48 @@ +flash_sram_run +--- + +This example is a demo project to execute bin between eFlash and SRAM. +> It will log the Program-Counter of CORE to address the memory type +> + eFlash is addressed from `0x0` +> + SRAM is addressed from `0x2000_0000` + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + +``` +15:52:35 +Run program between Flash and SRAM + + +run main() $pc@00000944 + + +run sram0_func() $pc@20000000 <--- run at SRAM + +SRAM-0: 20000254 | 00 01 02 03 04 05 06 07 - 08 09 0A 0B 0C 0D 0E 0F +SRAM-0: 20000264 | 10 11 12 13 14 15 16 17 - 18 19 1A 1B 1C 1D 1E 1F + + + +run eflash_func() $pc@000008A6 <--- run at eFlash + +SRAM: 20000234 | 00 01 02 03 04 05 06 07 - 08 09 0A 0B 0C 0D 0E 0F +SRAM: 20000244 | 10 11 12 13 14 15 16 17 - 18 19 1A 1B 1C 1D 1E 1F + + + +run sram0_func() $pc@20000000 + +SRAM-0: 20000254 | 00 01 02 03 04 05 06 07 - 08 09 0A 0B 0C 0D 0E 0F +SRAM-0: 20000264 | 10 11 12 13 14 15 16 17 - 18 19 1A 1B 1C 1D 1E 1F + + + +run eflash_func() $pc@000008A6 + +SRAM: 20000234 | 00 01 02 03 04 05 06 07 - 08 09 0A 0B 0C 0D 0E 0F +SRAM: 20000244 | 10 11 12 13 14 15 16 17 - 18 19 1A 1B 1C 1D 1E 1F + +... +``` diff --git a/Examples/flash/flash_sram_run/src/isr.c b/Examples/flash/flash_sram_run/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/Examples/flash/flash_sram_run/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/Examples/flash/flash_sram_run/src/main.c b/Examples/flash/flash_sram_run/src/main.c new file mode 100644 index 0000000..2f3f670 --- /dev/null +++ b/Examples/flash/flash_sram_run/src/main.c @@ -0,0 +1,104 @@ +/** + * 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 +//============================================================================= +#define CONFIG_BUF_SIZE 32 +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +const uint8_t g_src_buf_flash[CONFIG_BUF_SIZE] = +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, +}; + +uint32_t g_dst_buf1[CONFIG_BUF_SIZE >> 2]; +uint32_t g_dst_buf1_sram0[CONFIG_BUF_SIZE >> 2]; + + +//============================================================================= +// Private Function Definition +//============================================================================= +void __FASTCODE sram0_func(void) +{ + uint8_t *pCur = (uint8_t*)g_dst_buf1_sram0; + + memset(g_dst_buf1_sram0, 0xAA, sizeof(g_dst_buf1_sram0)); + for(int i = 0; i < sizeof(g_src_buf_flash); i++) + pCur[i] = g_src_buf_flash[i]; + + if( memcmp(g_dst_buf1_sram0, g_src_buf_flash, sizeof(g_src_buf_flash)) ) + err("Run fail ! ...\n"); + + syslog_dump_mem("SRAM-0: ", (uint32_t*)&g_dst_buf1_sram0, sizeof(g_dst_buf1_sram0), false); + return; +} + +void eflash_func(void) +{ + uint8_t *pCur = (uint8_t*)g_dst_buf1; + + memset(g_dst_buf1, 0xAA, sizeof(g_dst_buf1)); + for(int i = 0; i < sizeof(g_src_buf_flash); i++) + pCur[i] = g_src_buf_flash[i]; + + if( memcmp(g_dst_buf1, g_src_buf_flash, sizeof(g_src_buf_flash)) ) + err("Run fail ! ...\n"); + + syslog_dump_mem("SRAM: ", (uint32_t*)&g_dst_buf1, sizeof(g_dst_buf1), false); + return; +} + +//============================================================================= +// 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\nRun program between Flash and SRAM\n", + __TIME__); + + log_color(SLOG_YELLOW, "\n\nrun main() $pc@%p\n", &main); + + while(1) + { + log_color(SLOG_YELLOW, "\n\nrun sram0_func() $pc@%p\n", &sram0_func); + sram0_func(); + + log_color(SLOG_YELLOW, "\n\nrun eflash_func() $pc@%p\n", &eflash_func); + eflash_func(); + } + + return 0; +} diff --git a/Examples/flash/flash_status_flags/.cproject b/Examples/flash/flash_status_flags/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/flash/flash_status_flags/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/flash/flash_status_flags/.project b/Examples/flash/flash_status_flags/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/Examples/flash/flash_status_flags/.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/Examples/flash/flash_status_flags/Project.nuproject b/Examples/flash/flash_status_flags/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/Examples/flash/flash_status_flags/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/flash/flash_status_flags/component.mk b/Examples/flash/flash_status_flags/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Examples/flash/flash_status_flags/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/Examples/flash/flash_status_flags/inc/isr.h b/Examples/flash/flash_status_flags/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/Examples/flash/flash_status_flags/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/Examples/flash/flash_status_flags/inc/main.h b/Examples/flash/flash_status_flags/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Examples/flash/flash_status_flags/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/Examples/flash/flash_status_flags/readme.md b/Examples/flash/flash_status_flags/readme.md new file mode 100644 index 0000000..6506f2a --- /dev/null +++ b/Examples/flash/flash_status_flags/readme.md @@ -0,0 +1,107 @@ +flash_status_flags +--- + +This example is used to observe the staust register of FMC +> For generating the wrong behavior, directly control the registers of FMC + +It observes 4-cases +> + Normal case with CMD end +> + Wrong address (over range of device) +> + Miss unlock sector of flash +> + Use wrong auth-key to operate flash + + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + +``` +16:17:42 +Observe the error status of FMC with wrong behavior + +## Case: CMD end flag + +@ target address: x00004000 + ======= FMC Regs ==== + FLASH->CMD = xA5A50123 + FLASH->ISR = x00000000 + FLASH->AR = x00004000 + FLASH->DR = xFFFFFFFF + FLASH->ACM = x00000000 + FLASH->DIV = x00000030 + --- After FMC idle ---- + FLASH->ISR: 0x00000001, CMD_END= 1, KEY_ERR= 0, ACC_ERR=0, ADDR_ERR= 0 + +@ target address: x00200800 + ======= FMC Regs ==== + FLASH->CMD = xA5EC0123 + FLASH->ISR = x00000000 + FLASH->AR = x00200800 + FLASH->DR = x11223344 + FLASH->ACM = x00000000 + FLASH->DIV = x00000030 + --- After FMC idle ---- + FLASH->ISR: 0x00000001, CMD_END= 1, KEY_ERR= 0, ACC_ERR=0, ADDR_ERR= 0 + +## Case: Address error flag + +@ target address: x00008200 + ======= FMC Regs ==== + FLASH->CMD = xA5A50123 + FLASH->ISR = x00000008 + FLASH->AR = x00000200 + FLASH->DR = x11223344 + FLASH->ACM = x00000000 + FLASH->DIV = x00000030 + --- After FMC idle ---- + FLASH->ISR: 0x00000008, CMD_END= 0, KEY_ERR= 0, ACC_ERR=0, ADDR_ERR= 1 + +@ target address: x00202200 + ======= FMC Regs ==== + FLASH->CMD = xA5EC0123 + FLASH->ISR = x00000008 + FLASH->AR = x00202200 + FLASH->DR = x11223344 + FLASH->ACM = x00000000 + FLASH->DIV = x00000030 + --- After FMC idle ---- + FLASH->ISR: 0x00000008, CMD_END= 0, KEY_ERR= 0, ACC_ERR=0, ADDR_ERR= 1 + +## Case: Access error flag + +@ target address: x00004000 + ======= FMC Regs ==== + FLASH->CMD = xA5A50023 + FLASH->ISR = x00000000 + FLASH->AR = x00004000 + FLASH->DR = x11223344 + FLASH->ACM = x00000000 + FLASH->DIV = x00000030 + --- After FMC idle ---- + FLASH->ISR: 0x00000004, CMD_END= 0, KEY_ERR= 0, ACC_ERR=1, ADDR_ERR= 0 + +## Case: Key error flag + +@ target address: x00004000 + ======= FMC Regs ==== + FLASH->CMD = xA5EC0123 + FLASH->ISR = x00000000 + FLASH->AR = x00004000 + FLASH->DR = x11223344 + FLASH->ACM = x00000000 + FLASH->DIV = x00000030 + --- After FMC idle ---- + FLASH->ISR: 0x00000002, CMD_END= 0, KEY_ERR= 1, ACC_ERR=0, ADDR_ERR= 0 + +@ target address: x00200800 + ======= FMC Regs ==== + FLASH->CMD = xA5A50123 + FLASH->ISR = x00000000 + FLASH->AR = x00200800 + FLASH->DR = x11223344 + FLASH->ACM = x00000000 + FLASH->DIV = x00000030 + --- After FMC idle ---- + FLASH->ISR: 0x00000002, CMD_END= 0, KEY_ERR= 1, ACC_ERR=0, ADDR_ERR= 0 + +``` diff --git a/Examples/flash/flash_status_flags/src/isr.c b/Examples/flash/flash_status_flags/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/Examples/flash/flash_status_flags/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/Examples/flash/flash_status_flags/src/main.c b/Examples/flash/flash_status_flags/src/main.c new file mode 100644 index 0000000..c37d1ae --- /dev/null +++ b/Examples/flash/flash_status_flags/src/main.c @@ -0,0 +1,236 @@ +/** + * 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 +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= +static void +_Flash_DumpReg(uint32_t reg_cmd) +{ + msg(" ======= FMC Regs ====\n"); + msg(" FLASH->CMD = x%08X\n", reg_cmd ); + msg(" FLASH->SR = x%08X\n", FLASH->SR ); + msg(" FLASH->AR = x%08X\n", FLASH->AR ); + msg(" FLASH->DR = x%08X\n", FLASH->DR ); + msg(" FLASH->ACM = x%08X\n", FLASH->ACM ); + msg(" FLASH->DIV = x%08X\n", FLASH->DIV ); + return; +} +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + uint32_t 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\nObserve the error status of FMC with wrong behavior\n", + __TIME__); + + do { /* Case 1: Normal behavior */ + uint32_t addr_act = 0; + + log_color(SLOG_CYAN, "\n## Case: CMD end flag\n"); + + /* Main-Flash address */ + addr_act = EFLASH_MEM_BASE + (sizeof(EFLASH_MEM_Type) >> 1); + msg("\n@ target address: x%08X\n", addr_act); + + FLASH->SR = 0xFFFFFFFFul; + FLASH->AR = addr_act; + value = 0xA5A50020ul | FLASH_CMD_UNLOCK_Msk | + (FLASH_CMD_CMD_ERASE_SECTOR << FLASH_CMD_CMD_Pos) | + FLASH_CMD_START_Msk; + _Flash_DumpReg(value); + + FLASH->CMD = value; + + msg(" --- After FMC idle ----\n"); + msg(" FLASH->SR: 0x%08X, CMD_END= %d, KEY_ERR= %d, ACC_ERR=%d, ADDR_ERR= %d\n", + FLASH->SR, + FLASH->SR_b.CMD_END, FLASH->SR_b.KEY_ERR, + FLASH->SR_b.ACC_ERR, FLASH->SR_b.ADDR_ERR); + + /* NVR address */ + addr_act = NVR_MEM_BASE + (2ul << 10);// (sizeof(NVR_MEM_Type) >> 1); + msg("\n@ target address: x%08X\n", addr_act); + + FLASH->SR = 0xFFFFFFFFul; + FLASH->AR = addr_act; + FLASH->DR = 0x11223344; + value = 0xA5EC0020ul | FLASH_CMD_UNLOCK_Msk | + (FLASH_CMD_CMD_ERASE_SECTOR << FLASH_CMD_CMD_Pos) | + FLASH_CMD_START_Msk; + _Flash_DumpReg(value); + + FLASH->CMD = value; + + msg(" --- After FMC idle ----\n"); + msg(" FLASH->SR: 0x%08X, CMD_END= %d, KEY_ERR= %d, ACC_ERR=%d, ADDR_ERR= %d\n", + FLASH->SR, + FLASH->SR_b.CMD_END, FLASH->SR_b.KEY_ERR, + FLASH->SR_b.ACC_ERR, FLASH->SR_b.ADDR_ERR); + } while(0); + + do { /* Case 2: Wrong address behavior */ + uint32_t addr_act = 0; + + log_color(SLOG_CYAN, "\n## Case: Address error flag\n"); + + /* Over Main-flash address */ + addr_act = EFLASH_MEM_BASE + sizeof(EFLASH_MEM_Type) + 0x200; + msg("\n@ target address: x%08X\n", addr_act); + + FLASH->SR = 0xFFFFFFFFul; + FLASH->AR = addr_act; + FLASH->DR = 0x11223344; + value = 0xA5A50020ul | FLASH_CMD_UNLOCK_Msk | + (FLASH_CMD_CMD_ERASE_SECTOR << FLASH_CMD_CMD_Pos) | + FLASH_CMD_START_Msk; + _Flash_DumpReg(value); + + FLASH->CMD = value; + + msg(" --- After FMC idle ----\n"); + msg(" FLASH->SR: 0x%08X, CMD_END= %d, KEY_ERR= %d, ACC_ERR=%d, ADDR_ERR= %d\n", + FLASH->SR, + FLASH->SR_b.CMD_END, FLASH->SR_b.KEY_ERR, + FLASH->SR_b.ACC_ERR, FLASH->SR_b.ADDR_ERR); + + /* Over NVR address */ + addr_act = NVR_MEM_BASE + sizeof(NVR_MEM_Type) + 0x200; + msg("\n@ target address: x%08X\n", addr_act); + + FLASH->SR = 0xFFFFFFFFul; + FLASH->AR = addr_act; + FLASH->DR = 0x11223344; + value = 0xA5EC0020ul | FLASH_CMD_UNLOCK_Msk | + (FLASH_CMD_CMD_ERASE_SECTOR << FLASH_CMD_CMD_Pos) | + FLASH_CMD_START_Msk; + _Flash_DumpReg(value); + + FLASH->CMD = value; + + msg(" --- After FMC idle ----\n"); + msg(" FLASH->SR: 0x%08X, CMD_END= %d, KEY_ERR= %d, ACC_ERR=%d, ADDR_ERR= %d\n", + FLASH->SR, + FLASH->SR_b.CMD_END, FLASH->SR_b.KEY_ERR, + FLASH->SR_b.ACC_ERR, FLASH->SR_b.ADDR_ERR); + } while(0); + + do { /* Case 3: No unlock sectors behavior */ + uint32_t addr_act = 0; + + log_color(SLOG_CYAN, "\n## Case: Access error flag\n"); + + addr_act = EFLASH_MEM_BASE + (sizeof(EFLASH_MEM_Type) >> 1); + msg("\n@ target address: x%08X\n", addr_act); + + FLASH->SR = 0xFFFFFFFFul; + FLASH->AR = addr_act; + FLASH->DR = 0x11223344; + value = 0xA5A50020ul | + (FLASH_CMD_CMD_ERASE_SECTOR << FLASH_CMD_CMD_Pos) | + FLASH_CMD_START_Msk; + _Flash_DumpReg(value); + + FLASH->CMD = value; + msg(" --- After FMC idle ----\n"); + msg(" FLASH->SR: 0x%08X, CMD_END= %d, KEY_ERR= %d, ACC_ERR=%d, ADDR_ERR= %d\n", + FLASH->SR, + FLASH->SR_b.CMD_END, FLASH->SR_b.KEY_ERR, + FLASH->SR_b.ACC_ERR, FLASH->SR_b.ADDR_ERR); + } while(0); + + do { /* Case 4: Wrong key behavior */ + uint32_t addr_act = 0; + + log_color(SLOG_CYAN, "\n## Case: Key error flag\n"); + + /* Wrong Main-flash auth-key */ + addr_act = EFLASH_MEM_BASE + (sizeof(EFLASH_MEM_Type) >> 1); + msg("\n@ target address: x%08X\n", addr_act); + + FLASH->SR = 0xFFFFFFFFul; + FLASH->AR = addr_act; + FLASH->DR = 0x11223344; + value = 0xA5EC0020ul | FLASH_CMD_UNLOCK_Msk | + (FLASH_CMD_CMD_ERASE_SECTOR << FLASH_CMD_CMD_Pos) | + FLASH_CMD_START_Msk; + _Flash_DumpReg(value); + + FLASH->CMD = value; + + msg(" --- After FMC idle ----\n"); + msg(" FLASH->SR: 0x%08X, CMD_END= %d, KEY_ERR= %d, ACC_ERR=%d, ADDR_ERR= %d\n", + FLASH->SR, + FLASH->SR_b.CMD_END, FLASH->SR_b.KEY_ERR, + FLASH->SR_b.ACC_ERR, FLASH->SR_b.ADDR_ERR); + + /* Wrong NVR auth-key */ + addr_act = NVR_MEM_BASE + (2ul << 10); // (sizeof(NVR_MEM_Type) >> 1); + msg("\n@ target address: x%08X\n", addr_act); + + FLASH->SR = 0xFFFFFFFFul; + FLASH->AR = addr_act; + FLASH->DR = 0x11223344; + value = 0xA5A50020ul | FLASH_CMD_UNLOCK_Msk | + (FLASH_CMD_CMD_ERASE_SECTOR << FLASH_CMD_CMD_Pos) | + FLASH_CMD_START_Msk; + _Flash_DumpReg(value); + + FLASH->CMD = value; + + msg(" --- After FMC idle ----\n"); + msg(" FLASH->SR: 0x%08X, CMD_END= %d, KEY_ERR= %d, ACC_ERR=%d, ADDR_ERR= %d\n", + FLASH->SR, + FLASH->SR_b.CMD_END, FLASH->SR_b.KEY_ERR, + FLASH->SR_b.ACC_ERR, FLASH->SR_b.ADDR_ERR); + } while(0); + + + while(1) + { + __NOP(); + } + return 0; +} diff --git a/Examples/gpio/gpio_interrupt/.cproject b/Examples/gpio/gpio_interrupt/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/gpio/gpio_interrupt/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/gpio/gpio_interrupt/.project b/Examples/gpio/gpio_interrupt/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/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/Examples/gpio/gpio_interrupt/Project.nuproject b/Examples/gpio/gpio_interrupt/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/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: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/gpio/gpio_interrupt/component.mk b/Examples/gpio/gpio_interrupt/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/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/Examples/gpio/gpio_interrupt/inc/isr.h b/Examples/gpio/gpio_interrupt/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/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/Examples/gpio/gpio_interrupt/inc/main.h b/Examples/gpio/gpio_interrupt/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/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/Examples/gpio/gpio_interrupt/readme.md b/Examples/gpio/gpio_interrupt/readme.md new file mode 100644 index 0000000..3bcd4b5 --- /dev/null +++ b/Examples/gpio/gpio_interrupt/readme.md @@ -0,0 +1,35 @@ +gpio_interrupt +--- + +This example is used to run gpio interrupt function. + +## Hardware and Software environment + ++ This example runs on PB5700 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 ++ set PA5 for interrupt + +# Log +Use serial port with baudrate 115200 8bit, no parity check. +User can receive log infomation on `PA00->TXD` of DUT. + +11:12:58 +This is a demo project to interrput gpio +11:12:58 +Interupt even +11:12:58 +Interupt even +GPIO Interrupt times is 2 +11:12:58 +Interupt even +GPIO Interrupt times is 1 +11:12:58 +Interupt even +GPIO Interrupt times is 1 diff --git a/Examples/gpio/gpio_interrupt/src/isr.c b/Examples/gpio/gpio_interrupt/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/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/Examples/gpio/gpio_interrupt/src/main.c b/Examples/gpio/gpio_interrupt/src/main.c new file mode 100644 index 0000000..e37bccd --- /dev/null +++ b/Examples/gpio/gpio_interrupt/src/main.c @@ -0,0 +1,97 @@ +/** + * 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 GPIO_INPUT_PORTx GPIOA +#define GPIO_INPUT_PINx GPIO_Pin_05 +#define CONFIG_GPIO_IRQ GPIOA_IRQn // GPIOB_IRQn + +//============================================================================= +// 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) +{ + if( GPIO_GetITFlag(GPIO_INPUT_PORTx, GPIO_INPUT_PINx) ) + { + GPIO_ClearITFlag(GPIO_INPUT_PORTx, GPIO_INPUT_PINx); + + g_hasPullLow = true; + g_interrupt_cnt++; + } + + return; +} +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + GPIO_InitTypeDef GPIO_InitStruct = {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 a demo project of GPIO interrput\n", __DATE__, __TIME__); + + GPIO_InitStruct.GPIO_Pin = 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(GPIO_INPUT_PORTx , &GPIO_InitStruct); + + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(CONFIG_GPIO_IRQ, GPIOx_Handler, &irq_attr); + + /* Configure interrupt type of GPIO */ + GPIO_InitStruct.GPIO_ITInit.GPIO_Trigger = GPIO_Trigger_Level; + GPIO_InitStruct.GPIO_ITInit.GPIO_Polarity = GPIO_Polarity_Low_Fall; + GPIO_ITConfig(GPIO_INPUT_PORTx, GPIO_INPUT_PINx, &GPIO_InitStruct.GPIO_ITInit); + + /* Enable GPIO interrupt */ + GPIO_ITEnable(GPIO_INPUT_PORTx, GPIO_INPUT_PINx); + + while(1) + { + if( g_hasPullLow == true ) + { + msg("GPIO Interrupt times is %d\n", g_interrupt_cnt); + g_hasPullLow = false; + } + + sys_delay(30); + } + return 0; +} diff --git a/Examples/gpio/gpio_toggle/.cproject b/Examples/gpio/gpio_toggle/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/gpio/gpio_toggle/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/gpio/gpio_toggle/.project b/Examples/gpio/gpio_toggle/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/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/Examples/gpio/gpio_toggle/Project.nuproject b/Examples/gpio/gpio_toggle/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/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: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/gpio/gpio_toggle/component.mk b/Examples/gpio/gpio_toggle/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/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/Examples/gpio/gpio_toggle/inc/isr.h b/Examples/gpio/gpio_toggle/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/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/Examples/gpio/gpio_toggle/inc/main.h b/Examples/gpio/gpio_toggle/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/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/Examples/gpio/gpio_toggle/readme.md b/Examples/gpio/gpio_toggle/readme.md new file mode 100644 index 0000000..d672a91 --- /dev/null +++ b/Examples/gpio/gpio_toggle/readme.md @@ -0,0 +1,17 @@ +gpio_toggle +--- + +This example is used to run gpio toggle function. + +## Hardware and Software environment + ++ This example runs on PB5700 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 will toggle \ No newline at end of file diff --git a/Examples/gpio/gpio_toggle/src/isr.c b/Examples/gpio/gpio_toggle/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/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/Examples/gpio/gpio_toggle/src/main.c b/Examples/gpio/gpio_toggle/src/main.c new file mode 100644 index 0000000..d20649f --- /dev/null +++ b/Examples/gpio/gpio_toggle/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" +#include +#include +//============================================================================= +// Constant Definition +//============================================================================= +#define GPIO_PORTx GPIOA +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + GPIO_InitTypeDef GPIO_InitStruct = {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 is a demo project to toggle gpio\n", __TIME__); + + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_03 | GPIO_Pin_04; + 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) + { + GPIO_TogglePin(GPIO_PORTx, GPIO_Pin_03); + + GPIO_TogglePin(GPIO_PORTx, GPIO_Pin_04); + + //__NOP(); + } + return 0; +} diff --git a/Examples/lptim/lptim_count/.cproject b/Examples/lptim/lptim_count/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/lptim/lptim_count/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/lptim/lptim_count/.project b/Examples/lptim/lptim_count/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/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/Examples/lptim/lptim_count/Project.nuproject b/Examples/lptim/lptim_count/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/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: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/lptim/lptim_count/component.mk b/Examples/lptim/lptim_count/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/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/Examples/lptim/lptim_count/inc/isr.h b/Examples/lptim/lptim_count/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/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/Examples/lptim/lptim_count/inc/main.h b/Examples/lptim/lptim_count/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/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/Examples/lptim/lptim_count/readme.md b/Examples/lptim/lptim_count/readme.md new file mode 100644 index 0000000..d8a0c2c --- /dev/null +++ b/Examples/lptim/lptim_count/readme.md @@ -0,0 +1,17 @@ +tim count +--- + +This example is used to run tim count function. + +## Hardware and Software environment + ++ This example runs on PB5700 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/Examples/lptim/lptim_count/src/isr.c b/Examples/lptim/lptim_count/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/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/Examples/lptim/lptim_count/src/main.c b/Examples/lptim/lptim_count/src/main.c new file mode 100644 index 0000000..9b78d87 --- /dev/null +++ b/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/Examples/lptim/lptim_match_Interrupt/.cproject b/Examples/lptim/lptim_match_Interrupt/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/lptim/lptim_match_Interrupt/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/lptim/lptim_match_Interrupt/.project b/Examples/lptim/lptim_match_Interrupt/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/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/Examples/lptim/lptim_match_Interrupt/Project.nuproject b/Examples/lptim/lptim_match_Interrupt/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/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: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/lptim/lptim_match_Interrupt/component.mk b/Examples/lptim/lptim_match_Interrupt/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/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/Examples/lptim/lptim_match_Interrupt/inc/isr.h b/Examples/lptim/lptim_match_Interrupt/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/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/Examples/lptim/lptim_match_Interrupt/inc/main.h b/Examples/lptim/lptim_match_Interrupt/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/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/Examples/lptim/lptim_match_Interrupt/readme.md b/Examples/lptim/lptim_match_Interrupt/readme.md new file mode 100644 index 0000000..d6a2794 --- /dev/null +++ b/Examples/lptim/lptim_match_Interrupt/readme.md @@ -0,0 +1,17 @@ +tim match and interrupt +--- + +This example is used to run tim match and interrupt function. + +## Hardware and Software environment + ++ This example runs on PB5700 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/Examples/lptim/lptim_match_Interrupt/src/isr.c b/Examples/lptim/lptim_match_Interrupt/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/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/Examples/lptim/lptim_match_Interrupt/src/main.c b/Examples/lptim/lptim_match_Interrupt/src/main.c new file mode 100644 index 0000000..6812df2 --- /dev/null +++ b/Examples/lptim/lptim_match_Interrupt/src/main.c @@ -0,0 +1,118 @@ +/** + * 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) +{ + if( LPTIM_GetFlagStatus(LPTIMx, LPTIM_Flag_Match0) ) + { + LPTIM_ClearFlag(LPTIMx, LPTIM_Flag_Match0); + + GPIO_TogglePin(CONFIG_TOGGLE_PORT, CONFIG_TOGGLE_PIN); + } + 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); + + 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/Examples/lptim/lptim_prescaler/.cproject b/Examples/lptim/lptim_prescaler/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/lptim/lptim_prescaler/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/lptim/lptim_prescaler/.project b/Examples/lptim/lptim_prescaler/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/Examples/lptim/lptim_prescaler/.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/Examples/lptim/lptim_prescaler/Project.nuproject b/Examples/lptim/lptim_prescaler/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/Examples/lptim/lptim_prescaler/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/lptim/lptim_prescaler/component.mk b/Examples/lptim/lptim_prescaler/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Examples/lptim/lptim_prescaler/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/Examples/lptim/lptim_prescaler/inc/isr.h b/Examples/lptim/lptim_prescaler/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/Examples/lptim/lptim_prescaler/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/Examples/lptim/lptim_prescaler/inc/main.h b/Examples/lptim/lptim_prescaler/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Examples/lptim/lptim_prescaler/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/Examples/lptim/lptim_prescaler/readme.md b/Examples/lptim/lptim_prescaler/readme.md new file mode 100644 index 0000000..0fc3b97 --- /dev/null +++ b/Examples/lptim/lptim_prescaler/readme.md @@ -0,0 +1,17 @@ +tim prescaler +--- + +This example is used to run tim prescaler function. + +## Hardware and Software environment + ++ This example runs on PB5700 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 ++ Adjust the prescaler value to your desired value. ++ Run the example \ No newline at end of file diff --git a/Examples/lptim/lptim_prescaler/src/isr.c b/Examples/lptim/lptim_prescaler/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/Examples/lptim/lptim_prescaler/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/Examples/lptim/lptim_prescaler/src/main.c b/Examples/lptim/lptim_prescaler/src/main.c new file mode 100644 index 0000000..344d077 --- /dev/null +++ b/Examples/lptim/lptim_prescaler/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_prescaler = 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 prescaler\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_prescaler = 3;//23; //ftim = fsys/(pr+1) + + Init.LPTIM_Prescaler = set_prescaler; + Init.LPTIM_ClockSource = LPTIM_CLK_Src_SysClk; + Init.LPTIM_MatchMode = LPTIM_MatchMode_Normal; + Init.LPTIM_MatchValue = 2000; + + LPTIM_Init(LPTIMx, &Init); + + LPTIM_Enable(LPTIMx); + + while(1) + { + if( LPTIM_GetFlagStatus(LPTIMx, LPTIM_Flag_Match0) ) + { + LPTIM_ClearFlag(LPTIMx, LPTIM_Flag_Match0); + + GPIO_TogglePin(CONFIG_TOGGLE_PORT, CONFIG_TOGGLE_PIN); + } + } + + + return 0; +} diff --git a/Examples/pga/pga_test/.cproject b/Examples/pga/pga_test/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/pga/pga_test/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/pga/pga_test/.project b/Examples/pga/pga_test/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/Examples/pga/pga_test/.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/Examples/pga/pga_test/Project.nuproject b/Examples/pga/pga_test/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/Examples/pga/pga_test/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/pga/pga_test/component.mk b/Examples/pga/pga_test/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Examples/pga/pga_test/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/Examples/pga/pga_test/inc/isr.h b/Examples/pga/pga_test/inc/isr.h new file mode 100644 index 0000000..b77f364 --- /dev/null +++ b/Examples/pga/pga_test/inc/isr.h @@ -0,0 +1,51 @@ +/** + * 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/Examples/pga/pga_test/inc/main.h b/Examples/pga/pga_test/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Examples/pga/pga_test/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/Examples/pga/pga_test/src/isr.c b/Examples/pga/pga_test/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/Examples/pga/pga_test/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/Examples/pga/pga_test/src/main.c b/Examples/pga/pga_test/src/main.c new file mode 100644 index 0000000..f727777 --- /dev/null +++ b/Examples/pga/pga_test/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 GPIO_PORTx GPIOA + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + GPIO_InitTypeDef Init_GPIO = {0}; + OPAMP_InitTypeDef Init_Pga = {0}; + + + { + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + } + + sys_config_systick(SYS_TICK_10_MS); + + syslog_init(); + + info("%s\nThis is a demo project to pga0_1 gain\n", __TIME__); + + uint32_t sel = (GPIO_ReadOutputData(GPIOA) >> 0) & 0x07; // pa2:pa1:pa0 + + Init_Pga.OPAMP_VinP = OPAMP_VinP_IO; // pga0_vip=pa8 + Init_Pga.OPAMP_VinM = OPAMP_VinM_GND; // internal gain + Init_Pga.OPAMP_Gain = OPAMP_PGAGain_5; + Init_Pga.OPAMP_Vout = OPAMP_Vout_IO ; // pga_out=pa7 + OPAMP_Init(OPAMP0 ,&Init_Pga); + + // uint32_t ana2io_en = (0x01 << 4); // pga0_vip=pa8 out enable + // uint32_t pga_val = ana2io_en; + // AMISC->VBUF_CR= pga_val; + + OPAMP_Enable(OPAMP0); + + + Init_Pga.OPAMP_VinP = OPAMP_VinP_IO; // pga0_vip=pa11 + Init_Pga.OPAMP_VinM = OPAMP_VinM_GND; // internal gain + Init_Pga.OPAMP_Gain = OPAMP_PGAGain_5; + Init_Pga.OPAMP_Vout = OPAMP_Vout_IO ; // pga_out=pa13 + OPAMP_Init(OPAMP1 ,&Init_Pga); + + OPAMP_Enable(OPAMP1); + + + + while(1) + { + uint32_t sel = (GPIO_ReadOutputData(GPIOA) >> 0) & 0x07; // pa2:pa1:pa0 + switch( sel ) + { + + default: + case 0x00: + Init_Pga.OPAMP_Gain = OPAMP_PGAGain_1; + break; + + case 0x01: + Init_Pga.OPAMP_Gain = OPAMP_PGAGain_2; + break; + + case 0x02: + Init_Pga.OPAMP_Gain = OPAMP_PGAGain_4; + break; + + case 0x03: + Init_Pga.OPAMP_Gain = OPAMP_PGAGain_8; + break; + + case 0x04: + Init_Pga.OPAMP_Gain = OPAMP_PGAGain_16; + break; + + } + + REG_WRITE_MASK(OPAMP0->PGA_CR, OPAMP_PGA_CR_PGA_GAIN_Msk, Init_Pga.OPAMP_Gain); + REG_WRITE_MASK(OPAMP1->PGA_CR, OPAMP_PGA_CR_PGA_GAIN_Msk, Init_Pga.OPAMP_Gain); + + __asm("nop"); + __asm("nop"); + + } +} diff --git a/Examples/pga/pga_verify_wr_rd_reg/.cproject b/Examples/pga/pga_verify_wr_rd_reg/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/pga/pga_verify_wr_rd_reg/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/pga/pga_verify_wr_rd_reg/.project b/Examples/pga/pga_verify_wr_rd_reg/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/Examples/pga/pga_verify_wr_rd_reg/.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/Examples/pga/pga_verify_wr_rd_reg/Project.nuproject b/Examples/pga/pga_verify_wr_rd_reg/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/Examples/pga/pga_verify_wr_rd_reg/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/pga/pga_verify_wr_rd_reg/inc/isr.h b/Examples/pga/pga_verify_wr_rd_reg/inc/isr.h new file mode 100644 index 0000000..b1ab850 --- /dev/null +++ b/Examples/pga/pga_verify_wr_rd_reg/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/Examples/pga/pga_verify_wr_rd_reg/inc/main.h b/Examples/pga/pga_verify_wr_rd_reg/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Examples/pga/pga_verify_wr_rd_reg/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/Examples/pga/pga_verify_wr_rd_reg/readme.md b/Examples/pga/pga_verify_wr_rd_reg/readme.md new file mode 100644 index 0000000..0603180 --- /dev/null +++ b/Examples/pga/pga_verify_wr_rd_reg/readme.md @@ -0,0 +1,44 @@ +PGA read/write_registers +--- + +This example is used to read/write_registers + +# Log + +Use serial port with baudrate 115200 8bit, no parity check.
+User can receive log infomation on `PA00->TXD` of DUT. + +10:30:37 +This is a demo project to PGA Read Write registers + +PGA0_CR: Register Default: 0X0, Register Read: 0X0 +Match + +PGA1_CR: Register Default: 0X0, Register Read: 0X0 +Match + +PGA0_CR: Register Write: 0XFFFFFFFF, Register result value: 0XCFF, Register Read: 0XCFF +Match + +PGA1_CR: Register Write: 0XFFFFFFFF, Register result value: 0XCFF, Register Read: 0XCFF +Match + +PGA0_CR: Register Write: 0X0, Register result value: 0X0, Register Read: 0X0 +Match + +PGA1_CR: Register Write: 0X0, Register result value: 0X0, Register Read: 0X0 +Match + +PGA0_CR: Register Write: 0X5A5A5A5A, Register result value: 0X85A, Register Read: 0X85A +Match + +PGA1_CR: Register Write: 0X5A5A5A5A, Register result value: 0X85A, Register Read: 0X85A +Match + +PGA0_CR: Register Write: 0XA5A5A5A5, Register result value: 0X4A5, Register Read: 0X4A5 +Match + +PGA1_CR: Register Write: 0XA5A5A5A5, Register result value: 0X4A5, Register Read: 0X4A5 +Match + +done~~~ \ No newline at end of file diff --git a/Examples/pga/pga_verify_wr_rd_reg/src/isr.c b/Examples/pga/pga_verify_wr_rd_reg/src/isr.c new file mode 100644 index 0000000..af63b27 --- /dev/null +++ b/Examples/pga/pga_verify_wr_rd_reg/src/isr.c @@ -0,0 +1,51 @@ +/** + * 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 +//============================================================================= +/** + * \brief System Software ISR + * + * \return None + */ +__INTERRUPT void irqc_msip_handler(void) +{ + sys_clear_swi(); + + return; +} + diff --git a/Examples/pga/pga_verify_wr_rd_reg/src/main.c b/Examples/pga/pga_verify_wr_rd_reg/src/main.c new file mode 100644 index 0000000..e1da4da --- /dev/null +++ b/Examples/pga/pga_verify_wr_rd_reg/src/main.c @@ -0,0 +1,112 @@ +/** + * 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 +//============================================================================= +// Constant Definition +//============================================================================= +#define GPIO_PORTx GPIOA + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + + uint32_t read_value; + uint32_t write_value; + uint32_t result_value; + + { + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + } + + sys_config_systick(SYS_TICK_10_MS); + + syslog_init(); + + info("%s\nThis is a demo project to PGA Read Write registers\n", __TIME__); + +//-------------------PGA ------------------// +volatile uint32_t *registers_PGA_CR[]= {&OPAMP0->PGA_CR ,&OPAMP1->PGA_CR}; +uint32_t PGA_CR_default_value = 0x0; +uint32_t PGA_CR_write_values[] = {0xFFFFFFFF, 0x00000000, 0x5A5A5A5A, 0xA5A5A5A5}; + + REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PCLKEN_AMISC_Msk); + REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PCLKEN_AMISC_Msk); + + __HAL_SYSCFG_AMISC_CLK_ENABLE(); + + for (int i = 0; i < 2; i++) // READ CHECK REG + { + read_value =REG_READ(*registers_PGA_CR[i]); + printf("\nPGA%d_CR: Register Default: 0X%X, Register Read: 0X%X\n", i, PGA_CR_default_value, read_value); + if (PGA_CR_default_value == read_value) + { + printf("Match\n"); + } else + { + err("No Match\n"); + } + } + + for (int j = 0; j < 4; j++) // WRITE & CHECK REG + { + for (int i = 0; i < 2; i++) + { + write_value = PGA_CR_write_values[j]; + result_value = (write_value & 0x00000CFF); + REG_WRITE(*registers_PGA_CR[i], write_value); + read_value = REG_READ(*registers_PGA_CR[i]); + printf("\nPGA%d_CR: Register Write: 0X%X, Register result value: 0X%X, Register Read: 0X%X\n", i, write_value, result_value, read_value); + if (result_value == read_value) + { + printf("Match\n"); + } else + { + err("No Match\n"); + } + } + } + + msg("\ndone~~~\n"); + + + while(1) + { + + __NOP(); + + } +} diff --git a/Examples/pwr/pwr_sleep_mode/.cproject b/Examples/pwr/pwr_sleep_mode/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/pwr/pwr_sleep_mode/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/pwr/pwr_sleep_mode/.project b/Examples/pwr/pwr_sleep_mode/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/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/Examples/pwr/pwr_sleep_mode/Project.nuproject b/Examples/pwr/pwr_sleep_mode/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/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: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/pwr/pwr_sleep_mode/component.mk b/Examples/pwr/pwr_sleep_mode/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/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/Examples/pwr/pwr_sleep_mode/inc/isr.h b/Examples/pwr/pwr_sleep_mode/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/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/Examples/pwr/pwr_sleep_mode/inc/main.h b/Examples/pwr/pwr_sleep_mode/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/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/Examples/pwr/pwr_sleep_mode/readme.md b/Examples/pwr/pwr_sleep_mode/readme.md new file mode 100644 index 0000000..1e5ce62 --- /dev/null +++ b/Examples/pwr/pwr_sleep_mode/readme.md @@ -0,0 +1,54 @@ +pwr_sleep_mode +--- + +This example is used to enter power mode + ++ Sleep mode + + ``` + // at main.c + #define CONFIG_USE_SLEEP_MODE 1 + ``` + ++ Deepsleep mode + + ``` + // at main.c + #define CONFIG_USE_SLEEP_MODE 0 + ``` + ++ Set duration of auto-wakeup + + ``` + // Set 1000-msec in main.c + PWR_SetAutoWakeUp(1000); + ``` + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + ++ Sleep mode + + ``` + Jan 3 2025,17:06:27 + This is an example of Deepsleep of Power-Mode + wait 1-second + -> enter sleep + _Pre_Proc + _Post_Proc + <- wake-up + + -> enter sleep + _Pre_Proc + _Post_Proc + <- wake-up + + -> enter sleep + _Pre_Proc + _Post_Proc + <- wake-up + ... + ``` + ++ Deepsleep diff --git a/Examples/pwr/pwr_sleep_mode/src/isr.c b/Examples/pwr/pwr_sleep_mode/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/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/Examples/pwr/pwr_sleep_mode/src/main.c b/Examples/pwr/pwr_sleep_mode/src/main.c new file mode 100644 index 0000000..ba131c3 --- /dev/null +++ b/Examples/pwr/pwr_sleep_mode/src/main.c @@ -0,0 +1,97 @@ +/** + * 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 1 +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +static void +_Pre_Proc(void) +{ +#if 0 + /** + * If user has other ideas to wakeup system, + * please un-mark this API + */ + sys_disable_systick(); +#endif + + msg(" %s\n", __func__); + // ToDo: close peripheral clocks + return; +} + +static void +_Post_Proc(void) +{ + /* Enable peripheral clocks and re-configure peripheral if it is necessary */ + msg(" %s\n", __func__); + return; +} + +//============================================================================= +// 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\nThis is an example of Power-Mode\n", + __DATE__, __TIME__); + + msg(" wait 1-second\n"); + sys_delay(1000); + + while(1) + { + PWR_SetAutoWakeUp(1000); + + #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"); + sys_busy_wait(100); + } + + return 0; +} diff --git a/Examples/spi/spi_fifo/.cproject b/Examples/spi/spi_fifo/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/spi/spi_fifo/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/spi/spi_fifo/.project b/Examples/spi/spi_fifo/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/Examples/spi/spi_fifo/.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/Examples/spi/spi_fifo/Project.nuproject b/Examples/spi/spi_fifo/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/Examples/spi/spi_fifo/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/spi/spi_fifo/component.mk b/Examples/spi/spi_fifo/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Examples/spi/spi_fifo/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/Examples/spi/spi_fifo/inc/isr.h b/Examples/spi/spi_fifo/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/Examples/spi/spi_fifo/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/Examples/spi/spi_fifo/inc/main.h b/Examples/spi/spi_fifo/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Examples/spi/spi_fifo/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/Examples/spi/spi_fifo/readme.md b/Examples/spi/spi_fifo/readme.md new file mode 100644 index 0000000..86388fd --- /dev/null +++ b/Examples/spi/spi_fifo/readme.md @@ -0,0 +1,18 @@ +spi tx fifo and rx fifo +--- + +This example is used to run spi fifo function. + +## Hardware and Software environment + ++ This example runs on PB5700 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 + +The tx fifo and rx fifo of spi are 8 \ No newline at end of file diff --git a/Examples/spi/spi_fifo/src/isr.c b/Examples/spi/spi_fifo/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/Examples/spi/spi_fifo/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/Examples/spi/spi_fifo/src/main.c b/Examples/spi/spi_fifo/src/main.c new file mode 100644 index 0000000..d3f1385 --- /dev/null +++ b/Examples/spi/spi_fifo/src/main.c @@ -0,0 +1,141 @@ +/** + * 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 PA2 to toggle */ +#define CONFIG_TOGGLE_PORT GPIOA +#define CONFIG_TOGGLE_PIN GPIO_Pin_01 +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void SPIx_Handler(void) +{ + + return; + +} + +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) +{ + SPI_InitTypeDef SPI_InitStruct = {0}; + + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + uint32_t cnt_tx_fifo = 0; + uint32_t cnt_rx_fifo = 0; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + SPI_PinConfg(SPI0, 0); + SPI_DeInit(SPI0); + + {// 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); + } + + 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); + + SPI_Enable(SPI0); + for(int delay=0; delay<10000; delay++); + + for(int i=1; ; i++) + { + SPI_SendData(SPI0, i); + if(SPI_GetFlagStatus(SPI0, SPI_STA_TXFUL_Msk) == 1) + { + cnt_tx_fifo = i; + break; + } + } + + + SPI_Enable(SPI0); + for(int delay=0; delay<10000; delay++); + + uint32_t rec_dat = 0; + for(int i=1; i<10; i++) + { + rec_dat = SPI_ReceiveData(SPI0); + + } + + for(int i=1; ; i++) + { + SPI_SendData(SPI0, i); + for(int delay=0; delay<1000; delay++); + + if(SPI_GetFlagStatus(SPI0, SPI_STA_RXFUL_Msk) == 1) + { + cnt_rx_fifo = i; + break; + } + } + + while(1) + { + __NOP(); + } + + + return 0; +} diff --git a/Examples/spi/spi_interrupt/.cproject b/Examples/spi/spi_interrupt/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/spi/spi_interrupt/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/spi/spi_interrupt/.project b/Examples/spi/spi_interrupt/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/Examples/spi/spi_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/Examples/spi/spi_interrupt/Project.nuproject b/Examples/spi/spi_interrupt/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/Examples/spi/spi_interrupt/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/spi/spi_interrupt/component.mk b/Examples/spi/spi_interrupt/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Examples/spi/spi_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/Examples/spi/spi_interrupt/inc/isr.h b/Examples/spi/spi_interrupt/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/Examples/spi/spi_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/Examples/spi/spi_interrupt/inc/main.h b/Examples/spi/spi_interrupt/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Examples/spi/spi_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/Examples/spi/spi_interrupt/readme.md b/Examples/spi/spi_interrupt/readme.md new file mode 100644 index 0000000..69a7d9d --- /dev/null +++ b/Examples/spi/spi_interrupt/readme.md @@ -0,0 +1,17 @@ +spi interrupt +--- + +This example is used to run spi interrupt function. + +## Hardware and Software environment + ++ This example runs on PB5700 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 ++ Select the spi interrupt ++ Run the example \ No newline at end of file diff --git a/Examples/spi/spi_interrupt/src/isr.c b/Examples/spi/spi_interrupt/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/Examples/spi/spi_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/Examples/spi/spi_interrupt/src/main.c b/Examples/spi/spi_interrupt/src/main.c new file mode 100644 index 0000000..fbfb844 --- /dev/null +++ b/Examples/spi/spi_interrupt/src/main.c @@ -0,0 +1,358 @@ +/** + * 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 +//============================================================================= +uint32_t spi_flag = 0; +uint32_t it_flag = 0; +uint32_t spi_clear_flag =0; +uint32_t spi_tx = 0; +uint32_t spi_rx = 0; +uint32_t test_case = 0; +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void SPIx_Handler(void) +{ + switch(test_case) + { + case 0: + if(SPI_GetFlagStatus(SPI0, SPI_STA_RECVOV_Msk) == 1) //check flag + { + spi_flag |= it_flag; + + GPIO_TogglePin(GPIOA, GPIO_Pin_07); + + for(uint32_t i=0; i<10; i++) + { + spi_rx = SPI_ReceiveData(SPI0); + } + SPI_ClearFlagStatus(SPI0, SPI_STA_RECVOV_Msk); //check clear flag + + if(SPI_GetFlagStatus(SPI0, SPI_STA_RECVOV_Msk) != 1) + { + spi_clear_flag |= it_flag; + + GPIO_TogglePin(GPIOA, GPIO_Pin_07); + } + } + break; + case 1: + if(SPI_GetFlagStatus(SPI0, SPI_STA_MDF_Msk) == 1) + { + spi_flag |= it_flag; + + GPIO_TogglePin(GPIOA, GPIO_Pin_08); + + SPI_ClearFlagStatus(SPI0, SPI_STA_MDF_Msk); + if(SPI_GetFlagStatus(SPI0, SPI_STA_MDF_Msk) != 1) + { + spi_clear_flag |= it_flag; + + GPIO_TogglePin(GPIOA, GPIO_Pin_08); + } + } + break; + case 2: + if(SPI_GetFlagStatus(SPI0, SPI_STA_TXNFUL_Msk) == 1) + { + spi_flag |= it_flag; + + GPIO_TogglePin(GPIOA, GPIO_Pin_09); + + for(uint32_t i=0; i<4; i++) + { + SPI_SendData(SPI0, 0xAA); + } + if(SPI_GetFlagStatus(SPI0, SPI_STA_TXNFUL_Msk) != 1) + { + spi_clear_flag |= it_flag; + + GPIO_TogglePin(GPIOA, GPIO_Pin_09); + } + } + break; + case 3: + if(SPI_GetFlagStatus(SPI0, SPI_STA_TXFUL_Msk) == 1) + { + spi_flag |= it_flag; + + GPIO_TogglePin(GPIOA, GPIO_Pin_10); + + SPI_Enable(SPI0); + for(int i=0; i<100; i++); + if(SPI_GetFlagStatus(SPI0, SPI_STA_TXFUL_Msk) != 1) + { + spi_clear_flag |= it_flag; + + GPIO_TogglePin(GPIOA, GPIO_Pin_10); + } + } + break; + case 4: + if(SPI_GetFlagStatus(SPI0, SPI_STA_RXNEP_Msk) == 1) + { + spi_flag |= it_flag; + + GPIO_TogglePin(GPIOA, GPIO_Pin_11); + + spi_rx = SPI_ReceiveData(SPI0); + if(SPI_GetFlagStatus(SPI0, SPI_STA_RXNEP_Msk) != 1) + { + spi_clear_flag |= it_flag; + + GPIO_TogglePin(GPIOA, GPIO_Pin_11); + } + } + break; + case 5: + if(SPI_GetFlagStatus(SPI0, SPI_STA_RXFUL_Msk) == 1) + { + spi_flag |= it_flag; + + GPIO_TogglePin(GPIOA, GPIO_Pin_12); + + spi_rx = SPI_ReceiveData(SPI0); + if(SPI_GetFlagStatus(SPI0, SPI_STA_RXFUL_Msk) != 1) + { + spi_clear_flag |= it_flag; + + GPIO_TogglePin(GPIOA, GPIO_Pin_12); + } + } + break; + case 6: + if(SPI_GetFlagStatus(SPI0, SPI_STA_TXUFL_Msk) == 1) + { + spi_flag |= it_flag; + + GPIO_TogglePin(GPIOA, GPIO_Pin_13); + + SPI_ClearFlagStatus(SPI0, SPI_STA_TXUFL_Msk); + if(SPI_GetFlagStatus(SPI0, SPI_STA_TXUFL_Msk) != 1) + { + spi_clear_flag |= it_flag; + + GPIO_TogglePin(GPIOA, GPIO_Pin_13); + } + + } + break; + default : + + break; + + } + + return; + +} + + +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) +{ + SPI_InitTypeDef SPI_InitStruct = {0}; + + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + uint32_t tx_data[10] = {0}; + uint32_t rx_data[10] = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + {// configure I/O to toggle + GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_07|GPIO_Pin_08|GPIO_Pin_09|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13; + 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); + } + + for(uint32_t i=0; i<10; i++) + { + tx_data[i] = 0xA1A2A3A4; + } + + SPI_PinConfg(SPI0, 0); + SPI_DeInit(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(); + + SPI_InitStruct.SPI_Mode = SPI_Mode_Master;//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); + + SPI_SetTXTH(SPI0, 4); + SPI_SetRXTH(SPI0, 4); + + spi_flag = 0; + spi_clear_flag = 0; + + test_case = 5; + switch(test_case) + { + case 0: + + it_flag = SPI_STA_RECVOV_Msk; + SPI_SetInterrupt(SPI0, it_flag); + + SPI_Enable(SPI0); + for(uint32_t i=1; i<10; i++) + { + SPI_SendData(SPI0, 0xAA); + } + + break; + + case 1: + + it_flag = SPI_STA_MDF_Msk; + SPI_SetInterrupt(SPI0, it_flag); + + SPI_SlaveEnable(SPI0); + SPI_Enable(SPI0); + for(uint32_t i=1; ; i++) //slave -mdf + { + if(SPI_GetFlagStatus(SPI0, SPI_STA_TXNFUL_Msk) == 1) + { + SPI_SendData(SPI0, i); + } + if(SPI_GetFlagStatus(SPI0, SPI_STA_RXNEP_Msk) == 1) + { + rx_data[0] = SPI_ReceiveData(SPI0); + } + + } + + break; + + case 2: + + it_flag = SPI_STA_TXNFUL_Msk; + SPI_SetInterrupt(SPI0, it_flag); + + break; + + case 3: + + it_flag = SPI_STA_TXFUL_Msk; + SPI_SetInterrupt(SPI0, it_flag); + + for(uint32_t i=0; i<100; i++) + { + SPI_SendData(SPI0, i); + } + + break; + + case 4: + + it_flag = SPI_STA_RXNEP_Msk; + SPI_SetInterrupt(SPI0, it_flag); + + SPI_Enable(SPI0); + for(uint32_t i=0; i<4; i++) + { + SPI_SendData(SPI0, i); + } + + break; + + case 5: + + it_flag = SPI_STA_RXFUL_Msk; + SPI_SetInterrupt(SPI0, it_flag); + + SPI_Enable(SPI0); + for(uint32_t i=0; i<8; i++) + { + SPI_SendData(SPI0, i); + } + + break; + + case 6: + + it_flag = SPI_STA_TXUFL_Msk; + SPI_SetInterrupt(SPI0, it_flag); + + SPI_SlaveEnable(SPI0); + SPI_Enable(SPI0); + for(uint32_t i=1; ; i++) //slave - txuf + { + while(SPI_GetFlagStatus(SPI0, SPI_STA_RXNEP_Msk) == 0); + rx_data[0] = SPI_ReceiveData(SPI0); + } + + break; + + + default : + break; + + + } + + while(1) + { + __NOP(); + } + + + return 0; +} diff --git a/Examples/spi/spi_io_af/.cproject b/Examples/spi/spi_io_af/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/spi/spi_io_af/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/spi/spi_io_af/.project b/Examples/spi/spi_io_af/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/Examples/spi/spi_io_af/.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/Examples/spi/spi_io_af/Project.nuproject b/Examples/spi/spi_io_af/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/Examples/spi/spi_io_af/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/spi/spi_io_af/component.mk b/Examples/spi/spi_io_af/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Examples/spi/spi_io_af/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/Examples/spi/spi_io_af/inc/isr.h b/Examples/spi/spi_io_af/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/Examples/spi/spi_io_af/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/Examples/spi/spi_io_af/inc/main.h b/Examples/spi/spi_io_af/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Examples/spi/spi_io_af/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/Examples/spi/spi_io_af/readme.md b/Examples/spi/spi_io_af/readme.md new file mode 100644 index 0000000..b90e554 --- /dev/null +++ b/Examples/spi/spi_io_af/readme.md @@ -0,0 +1,36 @@ +SPI io alternate function +--- + +This example is used to run spi io alternate function. + +## Hardware and Software environment + ++ This example runs on PB5700 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 spi io alternate pin ++ select whether to switch DI DO ++ Run the example + +select 0: + * spi_clk -- p02 + * spi_do -- p03 + * spi_di -- p04 + * spi_cs -- p05 + +select 1: + * spi_clk -- pa14 + * spi_do -- pa15 + * spi_di -- pb00 + * spi_cs -- pb01 + +select 2: + * spi_clk -- pb02 + * spi_do -- pb03 + * spi_di -- pb04 + * spi_cs -- pb05 \ No newline at end of file diff --git a/Examples/spi/spi_io_af/src/isr.c b/Examples/spi/spi_io_af/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/Examples/spi/spi_io_af/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/Examples/spi/spi_io_af/src/main.c b/Examples/spi/spi_io_af/src/main.c new file mode 100644 index 0000000..9fc0b1a --- /dev/null +++ b/Examples/spi/spi_io_af/src/main.c @@ -0,0 +1,168 @@ +/** + * 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 spi_io_af 1 +//#define SPI_DIDO_SWITCH //SPI_DO and SPI_DI pin switch +//============================================================================= +// 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); + +#ifdef SPI_DIDO_SWITCH + + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_03 |GPIO_Pin_04; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_2; + GPIO_Init(GPIOA, &GPIO_InitStruct); +#endif + + } + + if(io_sel == 1) + { + /*----------------------------------- + * spi_clk -- pa14 + * spi_do -- pa15 + * spi_di -- pb00 + * spi_cs -- pb01 + * ---------------------------------*/ + SYSCFG->RSTPINCR = 0; + + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14 | GPIO_Pin_15 ; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_3; + GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_00 | GPIO_Pin_01; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_3; + GPIO_Init(GPIOB, &GPIO_InitStruct); + +#ifdef SPI_DIDO_SWITCH + + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_15; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_4; + GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_00; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_4; + GPIO_Init(GPIOB, &GPIO_InitStruct); +#endif + + } + + if(io_sel == 2) + { + /*----------------------------------- + * spi_clk -- pb02 + * spi_do -- pb03 + * spi_di -- pb04 + * spi_cs -- pb05 + * ---------------------------------*/ + SYSCFG_SetICEPin2NormalIO(true); + + 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_3; + GPIO_Init(GPIOB, &GPIO_InitStruct); + +#ifdef SPI_DIDO_SWITCH + + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_03 |GPIO_Pin_04; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_4; + GPIO_Init(GPIOB, &GPIO_InitStruct); +#endif + + } + +} +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + SPI_InitTypeDef SPI_InitStruct = {0}; + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + uint32_t tx_data[10] = {0}; + uint32_t rx_data[10] = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + for(int i=0; i<10; i++) + { + tx_data[i] = 0xA1A2A3A4 + i; + } + SPI_PinConfg(SPI0, spi_io_af); + 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); + + SPI_Enable(SPI0); + for(int i=0; i<10; i++) + { + SPI_SendData(SPI0, tx_data[i]); + while(SPI_GetFlagStatus(SPI0, SPI_STA_RXNEP_Msk) == 0); + rx_data[i] = SPI_ReceiveData(SPI0); + } + + while(1) + { + __NOP(); + } + + + return 0; +} diff --git a/Examples/spi/spi_manual/.cproject b/Examples/spi/spi_manual/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/spi/spi_manual/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/spi/spi_manual/.project b/Examples/spi/spi_manual/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/Examples/spi/spi_manual/.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/Examples/spi/spi_manual/Project.nuproject b/Examples/spi/spi_manual/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/Examples/spi/spi_manual/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/spi/spi_manual/component.mk b/Examples/spi/spi_manual/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Examples/spi/spi_manual/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/Examples/spi/spi_manual/inc/isr.h b/Examples/spi/spi_manual/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/Examples/spi/spi_manual/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/Examples/spi/spi_manual/inc/main.h b/Examples/spi/spi_manual/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Examples/spi/spi_manual/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/Examples/spi/spi_manual/readme.md b/Examples/spi/spi_manual/readme.md new file mode 100644 index 0000000..db9a958 --- /dev/null +++ b/Examples/spi/spi_manual/readme.md @@ -0,0 +1,22 @@ +spi manual mode +--- + +This example is used to run spi manual mode function. + +## Hardware and Software environment + ++ This example runs on PB5700 devices. + +## How to use it ? + +### In order to make the program work, you must do the following: + ++ Open your preferred toolchain ++ Set the send manual mode and cs manual ++ 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/Examples/spi/spi_manual/src/isr.c b/Examples/spi/spi_manual/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/Examples/spi/spi_manual/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/Examples/spi/spi_manual/src/main.c b/Examples/spi/spi_manual/src/main.c new file mode 100644 index 0000000..84727bb --- /dev/null +++ b/Examples/spi/spi_manual/src/main.c @@ -0,0 +1,129 @@ +/** + * 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 PA2 to toggle */ +#define CONFIG_TOGGLE_PORT GPIOA +#define CONFIG_TOGGLE_PIN GPIO_Pin_01 + +#define SPI_CS_MANUAL +//============================================================================= +// 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) +{ + SPI_InitTypeDef SPI_InitStruct = {0}; + + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + uint32_t tx_data[10] = {0}; + uint32_t rx_data[10] = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + for(int i=0; i<10; i++) + { + tx_data[i] = 0xA1A2A3A4; + } + + SPI_PinConfg(SPI0, 0); + SPI_DeInit(SPI0); + + {// 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); + } + + 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_4; + SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB; + SPI_Init(SPI0, &SPI_InitStruct); + + SPI_SetManualMode(SPI0, 1); + +#ifdef SPI_CS_MANUAL + SPI_SetManualChipSelect(SPI0, 1); +#endif + + SPI_Enable(SPI0); + + for(int i=0; i<10; i++) + { + +#ifdef SPI_CS_MANUAL + + SPI_SetSSOUT(SPI0, 0); + SPI_ManualSendData(SPI0, tx_data[i]); + SPI_SetSSOUT(SPI0, 1); +#else + SPI_ManualSendData(SPI0, tx_data[i]); +#endif + + while(SPI_GetFlagStatus(SPI0, SPI_STA_RXNEP_Msk) == 0); + rx_data[i] = SPI_ReceiveData(SPI0); + } + + while(1) + { + __NOP(); + } + + + return 0; +} diff --git a/Examples/spi/spi_send/.cproject b/Examples/spi/spi_send/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/spi/spi_send/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/spi/spi_send/.project b/Examples/spi/spi_send/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/Examples/spi/spi_send/.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/Examples/spi/spi_send/Project.nuproject b/Examples/spi/spi_send/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/Examples/spi/spi_send/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/spi/spi_send/component.mk b/Examples/spi/spi_send/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Examples/spi/spi_send/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/Examples/spi/spi_send/inc/isr.h b/Examples/spi/spi_send/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/Examples/spi/spi_send/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/Examples/spi/spi_send/inc/main.h b/Examples/spi/spi_send/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Examples/spi/spi_send/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/Examples/spi/spi_send/readme.md b/Examples/spi/spi_send/readme.md new file mode 100644 index 0000000..1ce1adb --- /dev/null +++ b/Examples/spi/spi_send/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 PB5700 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/Examples/spi/spi_send/src/isr.c b/Examples/spi/spi_send/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/Examples/spi/spi_send/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/Examples/spi/spi_send/src/main.c b/Examples/spi/spi_send/src/main.c new file mode 100644 index 0000000..fd653c5 --- /dev/null +++ b/Examples/spi/spi_send/src/main.c @@ -0,0 +1,113 @@ +/** + * 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 PA2 to toggle */ +#define CONFIG_TOGGLE_PORT GPIOA +#define CONFIG_TOGGLE_PIN GPIO_Pin_01 +//============================================================================= +// 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) +{ + SPI_InitTypeDef SPI_InitStruct = {0}; + + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + uint32_t tx_data[10] = {0}; + uint32_t rx_data[10] = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + sys_config_systick(SYS_TICK_1_MS); + + for(int i=0; i<10; i++) + { + tx_data[i] = 0xA1A2A3A4; + } + + SPI_PinConfg(SPI0, 0); + SPI_DeInit(SPI0); + + {// 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); + } + + 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); + + SPI_Enable(SPI0); + 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/Examples/spi/spi_slave/.cproject b/Examples/spi/spi_slave/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/spi/spi_slave/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/spi/spi_slave/.project b/Examples/spi/spi_slave/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/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/Examples/spi/spi_slave/Project.nuproject b/Examples/spi/spi_slave/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/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: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/spi/spi_slave/component.mk b/Examples/spi/spi_slave/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/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/Examples/spi/spi_slave/inc/isr.h b/Examples/spi/spi_slave/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/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/Examples/spi/spi_slave/inc/main.h b/Examples/spi/spi_slave/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/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/Examples/spi/spi_slave/readme.md b/Examples/spi/spi_slave/readme.md new file mode 100644 index 0000000..462faa3 --- /dev/null +++ b/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 PB5700 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/Examples/spi/spi_slave/src/isr.c b/Examples/spi/spi_slave/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/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/Examples/spi/spi_slave/src/main.c b/Examples/spi/spi_slave/src/main.c new file mode 100644 index 0000000..f3f62bb --- /dev/null +++ b/Examples/spi/spi_slave/src/main.c @@ -0,0 +1,108 @@ +/** + * 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 PA2 to toggle */ +#define CONFIG_TOGGLE_PORT GPIOA +#define CONFIG_TOGGLE_PIN GPIO_Pin_01 +//============================================================================= +// 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) +{ + SPI_InitTypeDef SPI_InitStruct = {0}; + + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + uint32_t tx_data[10] = {0}; + uint32_t rx_data[10] = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + for(int i=0; i<10; i++) + { + tx_data[i] = 0xB1A1 + i*0X101; + } + + SPI_PinConfg(SPI0, 0); + SPI_DeInit(SPI0); + + {// 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); + } + + 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_TxDataSize_8b; + SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudratePrescaler_4; + SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB; + SPI_Init(SPI0, &SPI_InitStruct); + + SPI_Enable(SPI0); + while(1) + { + for(int i=0; i<10; i++) + { + 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/Examples/system/sys_exception/.cproject b/Examples/system/sys_exception/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/system/sys_exception/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/system/sys_exception/.project b/Examples/system/sys_exception/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/Examples/system/sys_exception/.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/Examples/system/sys_exception/Project.nuproject b/Examples/system/sys_exception/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/Examples/system/sys_exception/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/system/sys_exception/component.mk b/Examples/system/sys_exception/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Examples/system/sys_exception/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/Examples/system/sys_exception/inc/isr.h b/Examples/system/sys_exception/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/Examples/system/sys_exception/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/Examples/system/sys_exception/inc/main.h b/Examples/system/sys_exception/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Examples/system/sys_exception/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/Examples/system/sys_exception/readme.md b/Examples/system/sys_exception/readme.md new file mode 100644 index 0000000..e55a346 --- /dev/null +++ b/Examples/system/sys_exception/readme.md @@ -0,0 +1,26 @@ +sys_exception +--- + +This example is a demo project to trigger exception event with software + ++ It will register the exception handlers (ecall) from App layer + ++ Trigger exception event with instructions (ecall) + + ```c + // at main.c + __ECALL(); + ``` + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + ++ `ecall` + + ``` + Jul 17 2025 10:05:43 + Software triggers exception event + => enter ecall handler (cause= 11) + + ``` diff --git a/Examples/system/sys_exception/src/isr.c b/Examples/system/sys_exception/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/Examples/system/sys_exception/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/Examples/system/sys_exception/src/main.c b/Examples/system/sys_exception/src/main.c new file mode 100644 index 0000000..75c03a7 --- /dev/null +++ b/Examples/system/sys_exception/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" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +static void _excp_break(uint32_t cause, uint32_t sp) +{ + msg(" => enter ebreak handler (cause= %d)\n", cause); + return; +} + +static void _excp_ecall(uint32_t cause, uint32_t sp) +{ + excp_frame_t *pFrame = (excp_frame_t*)sp; + pFrame->epc += 4; + + msg(" => enter ecall handler (cause= %d)\n", cause); + return; +} +//============================================================================= +// 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\nSoftware triggers exception event\n", __DATE__, __TIME__); + + sys_excp_register_handler(EXCPn_Break, (uint32_t)&_excp_break); + sys_excp_register_handler(EXCPn_MmodeEcall, (uint32_t)&_excp_ecall); + +#if 1 + __ECALL(); +#else + __EBREAK(); +#endif + + while(1) + { + __NOP(); + } + return 0; +} diff --git a/Examples/system/sys_mco/.cproject b/Examples/system/sys_mco/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/system/sys_mco/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/system/sys_mco/.project b/Examples/system/sys_mco/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/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/Examples/system/sys_mco/Project.nuproject b/Examples/system/sys_mco/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/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: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/system/sys_mco/component.mk b/Examples/system/sys_mco/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/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/Examples/system/sys_mco/inc/isr.h b/Examples/system/sys_mco/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/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/Examples/system/sys_mco/inc/main.h b/Examples/system/sys_mco/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/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/Examples/system/sys_mco/readme.md b/Examples/system/sys_mco/readme.md new file mode 100644 index 0000000..abb049a --- /dev/null +++ b/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 PB5700 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/Examples/system/sys_mco/src/isr.c b/Examples/system/sys_mco/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/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/Examples/system/sys_mco/src/main.c b/Examples/system/sys_mco/src/main.c new file mode 100644 index 0000000..5101a80 --- /dev/null +++ b/Examples/system/sys_mco/src/main.c @@ -0,0 +1,182 @@ +/** + * 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) +{ + if( GPIO_GetITFlag(CONFIG_BUTTON_PORT, CONFIG_BUTTON_PIN) ) + { + GPIO_ClearITFlag(CONFIG_BUTTON_PORT, CONFIG_BUTTON_PIN); + + g_IsButtonPress = true; + } + + 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/Examples/system/sys_tick_src/component.mk b/Examples/system/sys_tick_src/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Examples/system/sys_tick_src/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/Examples/system/sys_tick_src/inc/isr.h b/Examples/system/sys_tick_src/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/Examples/system/sys_tick_src/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/Examples/system/sys_tick_src/inc/main.h b/Examples/system/sys_tick_src/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Examples/system/sys_tick_src/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/Examples/system/sys_tick_src/readme.md b/Examples/system/sys_tick_src/readme.md new file mode 100644 index 0000000..b20b22c --- /dev/null +++ b/Examples/system/sys_tick_src/readme.md @@ -0,0 +1,54 @@ +sys_tick_src +--- + +This example is used to configure the clock source of systick +> clock source of systick +> + LSI +> + HSI with divider 2/4/8 + + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + +``` +Sep 25 2025 13:23:03 +This is a demo projec to configure source of systick + current tick source: LSI +SYSCFG->SYSCLKCR_b.SYSTICKCR= 0 +delay 1 sec + current tick source: HSI/2 +SYSCFG->SYSCLKCR_b.SYSTICKCR= 1 +delay 1 sec + current tick source: HSI/4 +SYSCFG->SYSCLKCR_b.SYSTICKCR= 2 +delay 1 sec + current tick source: HSI/8 +SYSCFG->SYSCLKCR_b.SYSTICKCR= 3 +delay 1 sec + current tick source: LSI +SYSCFG->SYSCLKCR_b.SYSTICKCR= 0 +delay 1 sec + current tick source: HSI/2 +SYSCFG->SYSCLKCR_b.SYSTICKCR= 1 +delay 1 sec + current tick source: HSI/4 +SYSCFG->SYSCLKCR_b.SYSTICKCR= 2 +delay 1 sec + current tick source: HSI/8 +SYSCFG->SYSCLKCR_b.SYSTICKCR= 3 +delay 1 sec + current tick source: LSI +SYSCFG->SYSCLKCR_b.SYSTICKCR= 0 +delay 1 sec + current tick source: HSI/2 +SYSCFG->SYSCLKCR_b.SYSTICKCR= 1 +delay 1 sec + current tick source: HSI/4 +SYSCFG->SYSCLKCR_b.SYSTICKCR= 2 +delay 1 sec + current tick source: HSI/8 +SYSCFG->SYSCLKCR_b.SYSTICKCR= 3 +delay 1 sec + ... +``` \ No newline at end of file diff --git a/Examples/system/sys_tick_src/src/isr.c b/Examples/system/sys_tick_src/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/Examples/system/sys_tick_src/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/Examples/system/sys_tick_src/src/main.c b/Examples/system/sys_tick_src/src/main.c new file mode 100644 index 0000000..cb88ce9 --- /dev/null +++ b/Examples/system/sys_tick_src/src/main.c @@ -0,0 +1,126 @@ +/** + * 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_TOGGLE_IO_PORT GPIOA +#define CONFIG_TOGGLE_IO_PIN GPIO_Pin_00 + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +static void _Config_IO(void) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.GPIO_Pin = CONFIG_TOGGLE_IO_PIN; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN; + GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; + GPIO_Init(CONFIG_TOGGLE_IO_PORT, &GPIO_InitStruct); + return; +} + +__INTERRUPT void _mtim_handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); + + GPIO_TogglePin(CONFIG_TOGGLE_IO_PORT, CONFIG_TOGGLE_IO_PIN); + + // Reload Timer Interrupt + SysTick_Reload(g_SysTickPeriod); + + RESTORE_IRQ_CSR_CONTEXT(); + return; +} +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + int cnt = 0; + 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\nThis is a demo projec to configure source of systick\n", + __DATE__, __TIME__); + + while(1) + { + SYSCFG_SysTickSrcTypeDef tick_src = SYSCFG_SysTickSrc_LSI; + + sys_disable_systick(); + + switch( cnt & 0x3 ) + { + default: + case 0: + SYSCFG_SetSysTickSrc(SYSCFG_SysTickSrc_LSI); + break; + case 1: + SYSCFG_SetSysTickSrc(SYSCFG_SysTickSrc_HSI_Div2); + break; + case 2: + SYSCFG_SetSysTickSrc(SYSCFG_SysTickSrc_HSI_Div4); + break; + case 3: + SYSCFG_SetSysTickSrc(SYSCFG_SysTickSrc_HSI_Div8); + break; + } + + cnt++; + + sys_config_systick(SYS_TICK_1_MS); + + tick_src = SYSCFG_GetSysTickSrc(); + + msg(" current tick source: %s\n", + (tick_src == SYSCFG_SysTickSrc_HSI_Div2) ? "HSI/2" : + (tick_src == SYSCFG_SysTickSrc_HSI_Div4) ? "HSI/4" : + (tick_src == SYSCFG_SysTickSrc_HSI_Div8) ? "HSI/8" : + "LSI"); + + msg("SYSCFG->SYSCLKCR_b.SYSTICKCR= %d\n", SYSCFG->SYSCLKCR_b.SYSTICKCR); + + msg("delay 1 sec\n"); + sys_delay(1000); + } + return 0; +} diff --git a/Examples/system/sys_tick_swi/component.mk b/Examples/system/sys_tick_swi/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/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/Examples/system/sys_tick_swi/inc/isr.h b/Examples/system/sys_tick_swi/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/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/Examples/system/sys_tick_swi/inc/main.h b/Examples/system/sys_tick_swi/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/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/Examples/system/sys_tick_swi/readme.md b/Examples/system/sys_tick_swi/readme.md new file mode 100644 index 0000000..2a3c26c --- /dev/null +++ b/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/Examples/system/sys_tick_swi/src/isr.c b/Examples/system/sys_tick_swi/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/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/Examples/system/sys_tick_swi/src/main.c b/Examples/system/sys_tick_swi/src/main.c new file mode 100644 index 0000000..55be770 --- /dev/null +++ b/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/Examples/systick/systick_count/.cproject b/Examples/systick/systick_count/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/systick/systick_count/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/systick/systick_count/.project b/Examples/systick/systick_count/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/Examples/systick/systick_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/Examples/systick/systick_count/Project.nuproject b/Examples/systick/systick_count/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/Examples/systick/systick_count/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/systick/systick_count/component.mk b/Examples/systick/systick_count/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Examples/systick/systick_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/Examples/systick/systick_count/inc/isr.h b/Examples/systick/systick_count/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/Examples/systick/systick_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/Examples/systick/systick_count/inc/main.h b/Examples/systick/systick_count/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Examples/systick/systick_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/Examples/systick/systick_count/readme.md b/Examples/systick/systick_count/readme.md new file mode 100644 index 0000000..b87d917 --- /dev/null +++ b/Examples/systick/systick_count/readme.md @@ -0,0 +1,17 @@ +systick count and relaod +--- + +This example is used to run systick count function. + +## Hardware and Software environment + ++ This example runs on PB5700 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 compare value to reload ++ Run the example \ No newline at end of file diff --git a/Examples/systick/systick_count/src/isr.c b/Examples/systick/systick_count/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/Examples/systick/systick_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/Examples/systick/systick_count/src/main.c b/Examples/systick/systick_count/src/main.c new file mode 100644 index 0000000..6653d6c --- /dev/null +++ b/Examples/systick/systick_count/src/main.c @@ -0,0 +1,82 @@ +/** + * 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 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_cmpvalue = 0; + uint32_t ir_flag = 0; + + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + syslog_init(); + + {// 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_cmpvalue = 48000; + ir_flag = 0; + + SysTimer_SetCompareValue(set_cmpvalue); + SysTimer_SetLoadValue(0); + SysTimer_Start(); + + while(1) + { + ir_flag = sys_get_IRQPending(SysTimer_IRQn); + if( ir_flag ) + { + ir_flag = 0; + SysTimer_SetLoadValue(0); + GPIO_TogglePin(CONFIG_TOGGLE_PORT, CONFIG_TOGGLE_PIN); + } + } + + + return 0; +} diff --git a/Examples/systick/systick_interrupt/.cproject b/Examples/systick/systick_interrupt/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/systick/systick_interrupt/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/systick/systick_interrupt/.project b/Examples/systick/systick_interrupt/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/Examples/systick/systick_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/Examples/systick/systick_interrupt/Project.nuproject b/Examples/systick/systick_interrupt/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/Examples/systick/systick_interrupt/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/systick/systick_interrupt/component.mk b/Examples/systick/systick_interrupt/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Examples/systick/systick_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/Examples/systick/systick_interrupt/inc/isr.h b/Examples/systick/systick_interrupt/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/Examples/systick/systick_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/Examples/systick/systick_interrupt/inc/main.h b/Examples/systick/systick_interrupt/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Examples/systick/systick_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/Examples/systick/systick_interrupt/readme.md b/Examples/systick/systick_interrupt/readme.md new file mode 100644 index 0000000..dba7b0f --- /dev/null +++ b/Examples/systick/systick_interrupt/readme.md @@ -0,0 +1,20 @@ +systick interrupt and stop +--- + +This example is used to run tim match and interrupt function. + +## Hardware and Software environment + ++ This example runs on PB5700 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 ++ Select the interrupt mode or count stop mode ++ Run the example + +in interrupt mode :will cause interrupt +in count stop mode :will stop when count is set to number of times \ No newline at end of file diff --git a/Examples/systick/systick_interrupt/src/isr.c b/Examples/systick/systick_interrupt/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/Examples/systick/systick_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/Examples/systick/systick_interrupt/src/main.c b/Examples/systick/systick_interrupt/src/main.c new file mode 100644 index 0000000..142fd8c --- /dev/null +++ b/Examples/systick/systick_interrupt/src/main.c @@ -0,0 +1,124 @@ +/** + * 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 PA2 to toggle */ +#define CONFIG_TOGGLE_PORT GPIOA +#define CONFIG_TOGGLE_PIN GPIO_Pin_02 + + +#define SYSTICK_INT_EN //systick will be able to generate interrupts +//#define SYSTICK_COUNT //SYSTICK will stop when the set number of cycles is reached +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void SYSTICK_Handler(void) +{ + SysTimer_SetLoadValue(0); + GPIO_TogglePin(CONFIG_TOGGLE_PORT, CONFIG_TOGGLE_PIN); + + return; + +} + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + uint32_t set_cmpvalue = 0; + uint32_t ir_flag = 0; + uint32_t cnt_time = 0; + + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + syslog_init(); + + + {// 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); + } + +#ifdef SYSTICK_INT_EN + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(SysTimer_IRQn, SYSTICK_Handler, &irq_attr); + sys_enable_girq(); +#endif + + + set_cmpvalue = 48000; + ir_flag = 0; + cnt_time = 15; + + SysTimer_SetCompareValue(set_cmpvalue); + SysTimer_SetLoadValue(0); + SysTimer_Start(); + + while(1) + { + +#ifndef SYSTICK_INT_EN + ir_flag = IRQC_GetPendingIRQ(SysTimer_IRQn); + if(ir_flag == 1) + { + ir_flag = 0; + SysTimer_SetLoadValue(0); + GPIO_TogglePin(CONFIG_TOGGLE_PORT, CONFIG_TOGGLE_PIN); + +#ifdef SYSTICK_COUNT + + cnt_time--; + if(cnt_time == 0) + { + SysTimer_Stop(); + + cnt_time = 0; + } +#endif + + } + + + +#endif + + __NOP(); + } + + + return 0; +} diff --git a/Examples/systick/systick_soft_interrupt/.cproject b/Examples/systick/systick_soft_interrupt/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/systick/systick_soft_interrupt/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/systick/systick_soft_interrupt/.project b/Examples/systick/systick_soft_interrupt/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/Examples/systick/systick_soft_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/Examples/systick/systick_soft_interrupt/Project.nuproject b/Examples/systick/systick_soft_interrupt/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/Examples/systick/systick_soft_interrupt/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/systick/systick_soft_interrupt/component.mk b/Examples/systick/systick_soft_interrupt/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Examples/systick/systick_soft_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/Examples/systick/systick_soft_interrupt/inc/isr.h b/Examples/systick/systick_soft_interrupt/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/Examples/systick/systick_soft_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/Examples/systick/systick_soft_interrupt/inc/main.h b/Examples/systick/systick_soft_interrupt/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Examples/systick/systick_soft_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/Examples/systick/systick_soft_interrupt/readme.md b/Examples/systick/systick_soft_interrupt/readme.md new file mode 100644 index 0000000..6033511 --- /dev/null +++ b/Examples/systick/systick_soft_interrupt/readme.md @@ -0,0 +1,16 @@ +systick Software interrupt +--- + +This example is used to run interrupt function. + +## Hardware and Software environment + ++ This example runs on PB5700 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 \ No newline at end of file diff --git a/Examples/systick/systick_soft_interrupt/src/isr.c b/Examples/systick/systick_soft_interrupt/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/Examples/systick/systick_soft_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/Examples/systick/systick_soft_interrupt/src/main.c b/Examples/systick/systick_soft_interrupt/src/main.c new file mode 100644 index 0000000..f6aabb8 --- /dev/null +++ b/Examples/systick/systick_soft_interrupt/src/main.c @@ -0,0 +1,87 @@ +/** + * 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 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 MSIP_Handler(void) +{ + SysTimer_ClearSWIRQ(); + GPIO_TogglePin(CONFIG_TOGGLE_PORT, CONFIG_TOGGLE_PIN); + + return; + +} + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + uint32_t cnt_time = 48000; + + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + syslog_init(); + + + {// 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); + } + + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(SysSW_IRQn, MSIP_Handler, &irq_attr); + sys_enable_girq(); + + + //SysTimer_SetSWIRQ(); + + while(1) + { + while(cnt_time--); + cnt_time = 48000; + SysTimer_SetSWIRQ(); + } + + + return 0; +} diff --git a/Examples/template/demo_project/.cproject b/Examples/template/demo_project/.cproject new file mode 100644 index 0000000..d9ac06f --- /dev/null +++ b/Examples/template/demo_project/.cproject @@ -0,0 +1,294 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/template/demo_project/.project b/Examples/template/demo_project/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/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/Examples/template/demo_project/Project.nuproject b/Examples/template/demo_project/Project.nuproject new file mode 100644 index 0000000..0072223 --- /dev/null +++ b/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/Examples/template/demo_project/component.mk b/Examples/template/demo_project/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/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/Examples/template/demo_project/inc/isr.h b/Examples/template/demo_project/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/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/Examples/template/demo_project/inc/main.h b/Examples/template/demo_project/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/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/Examples/template/demo_project/readme.md b/Examples/template/demo_project/readme.md new file mode 100644 index 0000000..b4f1dcd --- /dev/null +++ b/Examples/template/demo_project/readme.md @@ -0,0 +1,10 @@ +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/Examples/template/demo_project/src/isr.c b/Examples/template/demo_project/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/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/Examples/template/demo_project/src/main.c b/Examples/template/demo_project/src/main.c new file mode 100644 index 0000000..d84273f --- /dev/null +++ b/Examples/template/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 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/Examples/tim/tim_6StepOutput/.cproject b/Examples/tim/tim_6StepOutput/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/tim/tim_6StepOutput/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/tim/tim_6StepOutput/.project b/Examples/tim/tim_6StepOutput/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/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/Examples/tim/tim_6StepOutput/Project.nuproject b/Examples/tim/tim_6StepOutput/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/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: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/tim/tim_6StepOutput/component.mk b/Examples/tim/tim_6StepOutput/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/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/Examples/tim/tim_6StepOutput/inc/isr.h b/Examples/tim/tim_6StepOutput/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/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/Examples/tim/tim_6StepOutput/inc/main.h b/Examples/tim/tim_6StepOutput/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/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/Examples/tim/tim_6StepOutput/readme.md b/Examples/tim/tim_6StepOutput/readme.md new file mode 100644 index 0000000..29cf801 --- /dev/null +++ b/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 PB5700 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/Examples/tim/tim_6StepOutput/src/isr.c b/Examples/tim/tim_6StepOutput/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/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/Examples/tim/tim_6StepOutput/src/main.c b/Examples/tim/tim_6StepOutput/src/main.c new file mode 100644 index 0000000..4f2e9c4 --- /dev/null +++ b/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/Examples/tim/tim_ETRFClearOCxREF/.cproject b/Examples/tim/tim_ETRFClearOCxREF/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/tim/tim_ETRFClearOCxREF/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/tim/tim_ETRFClearOCxREF/.project b/Examples/tim/tim_ETRFClearOCxREF/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/Examples/tim/tim_ETRFClearOCxREF/.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/Examples/tim/tim_ETRFClearOCxREF/Project.nuproject b/Examples/tim/tim_ETRFClearOCxREF/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/Examples/tim/tim_ETRFClearOCxREF/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/tim/tim_ETRFClearOCxREF/component.mk b/Examples/tim/tim_ETRFClearOCxREF/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Examples/tim/tim_ETRFClearOCxREF/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/Examples/tim/tim_ETRFClearOCxREF/inc/isr.h b/Examples/tim/tim_ETRFClearOCxREF/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/Examples/tim/tim_ETRFClearOCxREF/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/Examples/tim/tim_ETRFClearOCxREF/inc/main.h b/Examples/tim/tim_ETRFClearOCxREF/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Examples/tim/tim_ETRFClearOCxREF/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/Examples/tim/tim_ETRFClearOCxREF/readme.md b/Examples/tim/tim_ETRFClearOCxREF/readme.md new file mode 100644 index 0000000..aeea203 --- /dev/null +++ b/Examples/tim/tim_ETRFClearOCxREF/readme.md @@ -0,0 +1,14 @@ +TIM_ETRFClearOCxREF_project +--- + +This example is a demo project to TIM ETRFClearOCxREF + +## Hardware and Software environment + ++ This example runs on PB5700 devices. + +## Log + ++ Enable OC1CE ++ ETRF input high level ,set OC1REF = 0 + diff --git a/Examples/tim/tim_ETRFClearOCxREF/src/isr.c b/Examples/tim/tim_ETRFClearOCxREF/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/Examples/tim/tim_ETRFClearOCxREF/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/Examples/tim/tim_ETRFClearOCxREF/src/main.c b/Examples/tim/tim_ETRFClearOCxREF/src/main.c new file mode 100644 index 0000000..d3f3599 --- /dev/null +++ b/Examples/tim/tim_ETRFClearOCxREF/src/main.c @@ -0,0 +1,113 @@ +/** + * 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 +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + 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_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); + /*TIM2_ETR -> PA15*/ + GPIO_PeriAFConfig(GPIOA,GPIO_Peri_T2ETR,GPIO_PeriAF_2); +#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); + /*EPWM_ETR -> PA15*/ + GPIO_PeriAFConfig(GPIOA,GPIO_Peri_EPETR,GPIO_PeriAF_2); +#endif + + 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); + + TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; + /* Time Base configuration */ + TIM_TimeBaseStructure.TIM_Prescaler = 48 - 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_PWM1); + TIM_CCxCmd(TIMx,TIM_Channel_1,TIM_CCx_Enable); + + TIM_SetCompare2(TIMx,400);//CH2 DUTY:40% + TIM_SelectOCxM(TIMx,TIM_Channel_2,TIM_OCMode_PWM1); + TIM_CCxCmd(TIMx,TIM_Channel_2,TIM_CCx_Enable); + + TIM_SetCompare3(TIMx,250);//CH3 DUTY:25% + TIM_SelectOCxM(TIMx,TIM_Channel_3,TIM_OCMode_PWM1); + TIM_CCxCmd(TIMx,TIM_Channel_3,TIM_CCx_Enable); + + REG_WRITE_MASK(TIMx->CCMR1_OUTPUT, TIM_CCMR1_OUTPUT_OC1CE_Msk, 1 << TIM_CCMR1_OUTPUT_OC1CE_Pos); + /* TIM1 counter enable */ + TIM_Cmd(TIMx, ENABLE); + /* Main Output Enable */ + TIM_CtrlPWMOutputs(TIMx, ENABLE); + + while(1) + { + + } +} diff --git a/Examples/tim/tim_InputCapture/.cproject b/Examples/tim/tim_InputCapture/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/tim/tim_InputCapture/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/tim/tim_InputCapture/.project b/Examples/tim/tim_InputCapture/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/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/Examples/tim/tim_InputCapture/Project.nuproject b/Examples/tim/tim_InputCapture/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/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: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/tim/tim_InputCapture/component.mk b/Examples/tim/tim_InputCapture/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/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/Examples/tim/tim_InputCapture/inc/isr.h b/Examples/tim/tim_InputCapture/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/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/Examples/tim/tim_InputCapture/inc/main.h b/Examples/tim/tim_InputCapture/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/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/Examples/tim/tim_InputCapture/readme.md b/Examples/tim/tim_InputCapture/readme.md new file mode 100644 index 0000000..9aa9700 --- /dev/null +++ b/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 PB5700 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/Examples/tim/tim_InputCapture/src/isr.c b/Examples/tim/tim_InputCapture/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/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/Examples/tim/tim_InputCapture/src/main.c b/Examples/tim/tim_InputCapture/src/main.c new file mode 100644 index 0000000..12cd455 --- /dev/null +++ b/Examples/tim/tim_InputCapture/src/main.c @@ -0,0 +1,128 @@ +/** + * 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) +{ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); +#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 + + TIM_DeInit(TIMx); + + TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure = {0}; + TIM_TimeBaseInit(TIMx,&TIM_TimeBaseStructure); + + TIM_ICInitTypeDef TIM_ICInitStruct; + 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); + __enable_irq(); + + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(CONFIG_IRQ_ID, TIMx_handler, &irq_attr); + + TIM_SetAutoreload(TIMx,0xFFFF); + /* TIM enable counter */ + TIM_Cmd(TIMx, ENABLE); + while(1) + { + __NOP(); + } + return 0; +} + +__INTERRUPT void TIMx_handler(void) +{ + 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); + } + TIMFreq = (uint32_t) SystemClock / Capture; + CaptureNumber = 0; + } + } +} diff --git a/Examples/tim/tim_Synchro/.cproject b/Examples/tim/tim_Synchro/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/tim/tim_Synchro/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/tim/tim_Synchro/.project b/Examples/tim/tim_Synchro/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/Examples/tim/tim_Synchro/.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/Examples/tim/tim_Synchro/Project.nuproject b/Examples/tim/tim_Synchro/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/Examples/tim/tim_Synchro/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/tim/tim_Synchro/component.mk b/Examples/tim/tim_Synchro/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Examples/tim/tim_Synchro/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/Examples/tim/tim_Synchro/inc/isr.h b/Examples/tim/tim_Synchro/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/Examples/tim/tim_Synchro/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/Examples/tim/tim_Synchro/inc/main.h b/Examples/tim/tim_Synchro/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Examples/tim/tim_Synchro/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/Examples/tim/tim_Synchro/readme.md b/Examples/tim/tim_Synchro/readme.md new file mode 100644 index 0000000..b79032d --- /dev/null +++ b/Examples/tim/tim_Synchro/readme.md @@ -0,0 +1,19 @@ +TIM_Synchro_project +--- + +This example is a demo project to TIM Synchro + +## Hardware and Software environment + ++ This example runs on PB5700 devices. + +## Log + ++ TIM Synchronize with a trigger signal ++ CONFIG_SYNCHRO_EXT External pins ++ CONFIG_SYNCHRO_ITR1 TIM0 ++ Reset mode: After the rising edge, the counter will reset to zero and start counting again ++ Gate control mode: PWM has output at high level and no output at low level ++ Trigger mode: The counter only starts after the rising edge arrives + + diff --git a/Examples/tim/tim_Synchro/src/isr.c b/Examples/tim/tim_Synchro/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/Examples/tim/tim_Synchro/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/Examples/tim/tim_Synchro/src/main.c b/Examples/tim/tim_Synchro/src/main.c new file mode 100644 index 0000000..ac9e90e --- /dev/null +++ b/Examples/tim/tim_Synchro/src/main.c @@ -0,0 +1,137 @@ +/** + * 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 + +#define CONFIG_SYNCHRO_EXT +//#define CONFIG_SYNCHRO_ITR1 + + +#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 TIM0_Handler(void); +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + 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_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); + /*TIM2_ETR -> PA15*/ + GPIO_PeriAFConfig(GPIOA,GPIO_Peri_T2ETR,GPIO_PeriAF_2); +#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); + /*EPWM_ETR -> PA15*/ + GPIO_PeriAFConfig(GPIOA,GPIO_Peri_EPETR,GPIO_PeriAF_2); +#endif + + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_06 ; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; + GPIO_Init(GPIOA, &GPIO_InitStruct); + + TIM_DeInit(TIMx); + TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; + TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct); + TIM_TimeBaseInitStruct.TIM_Prescaler = 48 - 1; + TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; + TIM_TimeBaseInitStruct.TIM_Period = 1000 - 1;//1ms + TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_Div1; + TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; + TIM_TimeBaseInit(TIMx, &TIM_TimeBaseInitStruct); + TIM_SetCompare1(TIMx,800);//CH1 DUTY:40% + TIM_SelectOCxM(TIMx,TIM_Channel_1,TIM_OCMode_PWM1); + TIM_CCxCmd(TIMx,TIM_Channel_1,TIM_CCx_Enable); + + TIM_SetCompare3(TIMx,250);//CH3 DUTY:25% + TIM_SelectOCxM(TIMx,TIM_Channel_3,TIM_OCMode_PWM1); + TIM_CCxCmd(TIMx,TIM_Channel_3,TIM_CCx_Enable); + +#if defined(CONFIG_SYNCHRO_EXT) + TIM_ITRxExternalClockConfig(TIMx,TIM_TS_ETRF); +#elif defined(CONFIG_SYNCHRO_ITR1) + LPTIM_InitTypeDef Init = {0}; + Init.LPTIM_Prescaler = 48 - 1; + Init.LPTIM_ClockSource = LPTIM_CLK_Src_SysClk; + Init.LPTIM_MatchMode = LPTIM_MatchMode_IRQ | LPTIM_MatchMode_Reset; + Init.LPTIM_MatchValue = 1800 - 1; + LPTIM_Init(TIM0, &Init); + + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(TIM0_IRQn, TIM0_Handler, &irq_attr); + sys_enable_girq(); + LPTIM_ITConfig(TIM0, true); + LPTIM_Enable(TIM0); + TIM_ITRxExternalClockConfig(TIMx,TIM_TS_ITR1); +#endif + + /*set SLAVE MODE*/ + TIM_SelectSlaveMode(TIMx,TIM_SlaveMode_Reset); + + TIM_Cmd(TIMx, ENABLE); + TIM_CtrlPWMOutputs(TIMx,ENABLE); + + while(1) + { + + } +} + +__INTERRUPT void TIM0_Handler(void) +{ + if(LPTIM_GetFlagStatus(TIM0, LPTIM_Flag_Match0)) + { + /* Clear TIM0 Updata */ + LPTIM_ClearFlag(TIM0, LPTIM_Flag_Match0); + GPIO_TogglePin(GPIOA,GPIO_Pin_06); + } +} diff --git a/Examples/tim/tim_clk_sel/.cproject b/Examples/tim/tim_clk_sel/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/tim/tim_clk_sel/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/tim/tim_clk_sel/.project b/Examples/tim/tim_clk_sel/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/Examples/tim/tim_clk_sel/.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/Examples/tim/tim_clk_sel/Project.nuproject b/Examples/tim/tim_clk_sel/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/Examples/tim/tim_clk_sel/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/tim/tim_clk_sel/component.mk b/Examples/tim/tim_clk_sel/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Examples/tim/tim_clk_sel/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/Examples/tim/tim_clk_sel/inc/isr.h b/Examples/tim/tim_clk_sel/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/Examples/tim/tim_clk_sel/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/Examples/tim/tim_clk_sel/inc/main.h b/Examples/tim/tim_clk_sel/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Examples/tim/tim_clk_sel/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/Examples/tim/tim_clk_sel/readme.md b/Examples/tim/tim_clk_sel/readme.md new file mode 100644 index 0000000..2ae306b --- /dev/null +++ b/Examples/tim/tim_clk_sel/readme.md @@ -0,0 +1,16 @@ +TIMx_CLKSEL_project +--- + +This example is a demo project to TIMx_CLKSEL + +## Hardware and Software environment + ++ This example runs on PB5700 devices. + +## Log + ++ CONFIG_CKINT :System Clock ++ CONFIG_EXTMODE1_ETR :ETR pin input ++ CONFIG_EXTMODE2_ETR :ETR pin input ++ CONFIG_EXTMODE1_ITR1 :ITR1(ITR1 -> TIM0,Need to clear the flag bit) + diff --git a/Examples/tim/tim_clk_sel/src/isr.c b/Examples/tim/tim_clk_sel/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/Examples/tim/tim_clk_sel/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/Examples/tim/tim_clk_sel/src/main.c b/Examples/tim/tim_clk_sel/src/main.c new file mode 100644 index 0000000..9a78f06 --- /dev/null +++ b/Examples/tim/tim_clk_sel/src/main.c @@ -0,0 +1,146 @@ +/** + * 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 + +#define CONFIG_CKINT +//#define CONFIG_EXTMODE1_ETR +//#define CONFIG_EXTMODE2_ETR +//#define CONFIG_EXTMODE1_ITR1 + +#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 TIM0_Handler(void); + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + 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_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); + /*TIM2_ETR -> PA15*/ + GPIO_PeriAFConfig(GPIOA,GPIO_Peri_T2ETR,GPIO_PeriAF_2); +#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); + /*EPWM_ETR -> PA15*/ + GPIO_PeriAFConfig(GPIOA,GPIO_Peri_EPETR,GPIO_PeriAF_2); +#endif + + TIM_DeInit(TIMx); + + TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; + TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct); + TIM_TimeBaseInitStruct.TIM_Prescaler = 1 - 1; + TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; + TIM_TimeBaseInitStruct.TIM_Period = 1000-1;//1ms + TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_Div1; + TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; + TIM_TimeBaseInit(TIMx, &TIM_TimeBaseInitStruct); +#if defined(CONFIG_CKINT) + TIM_InternalClockConfig(TIMx); +#elif defined(CONFIG_EXTMODE1_ETR) + TIM_ETRClockMode1Config(TIMx,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0x0); +#elif defined(CONFIG_EXTMODE2_ETR) + TIM_ETRClockMode2Config(TIMx,TIM_ExtTRGPSC_DIV2,TIM_ExtTRGPolarity_NonInverted,0x0); +#elif defined(CONFIG_EXTMODE1_ITR1) + LPTIM_InitTypeDef Init = {0}; + Init.LPTIM_Prescaler = 0; + Init.LPTIM_ClockSource = LPTIM_CLK_Src_SysClk; + Init.LPTIM_MatchMode = LPTIM_MatchMode_IRQ | LPTIM_MatchMode_Reset; + Init.LPTIM_MatchValue = 48 - 1; + LPTIM_Init(TIM0, &Init); + + LPTIM_ITConfig(TIM0, true); + LPTIM_Enable(TIM0); + TIM_ITRxExternalClockConfig(TIMx,TIM_TS_ITR1); +#endif + + TIM_SetCompare1(TIMx,800);//CH1 DUTY:80% + TIM_SelectOCxM(TIMx,TIM_Channel_1,TIM_OCMode_PWM1); + TIM_CCxCmd(TIMx,TIM_Channel_1,TIM_CCx_Enable); + + TIM_SetCompare2(TIMx,400);//CH2 DUTY:40% + TIM_SelectOCxM(TIMx,TIM_Channel_2,TIM_OCMode_PWM1); + TIM_CCxCmd(TIMx,TIM_Channel_2,TIM_CCx_Enable); + + TIM_SetCompare3(TIMx,250);//CH3 DUTY:25% + TIM_SelectOCxM(TIMx,TIM_Channel_3,TIM_OCMode_PWM1); + TIM_CCxCmd(TIMx,TIM_Channel_3,TIM_CCx_Enable); + + TIM_SetCompare4(TIMx,100);//CH4 DUTY:10% + TIM_SelectOCxM(TIMx,TIM_Channel_4,TIM_OCMode_PWM1); + TIM_CCxCmd(TIMx,TIM_Channel_4,TIM_CCx_Enable); + + TIM_Cmd(TIMx, ENABLE); + TIM_CtrlPWMOutputs(TIMx,ENABLE); + /*ITR1/2/3 -> TIMx CLK,ITR1/2/3 Interrupt Enable must be after TIMx Enable*/ +#if defined(CONFIG_EXTMODE1_ITR1) + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(TIM0_IRQn, TIM0_Handler, &irq_attr); + sys_enable_girq(); +#endif + while(1) + { + + } +} + +__INTERRUPT void TIM0_Handler(void) +{ + if( LPTIM_GetFlagStatus(TIM0, LPTIM_Flag_Match0) ) + { + LPTIM_ClearFlag(TIM0, LPTIM_Flag_Match0); + } +} diff --git a/Examples/tim/tim_encoder/.cproject b/Examples/tim/tim_encoder/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/tim/tim_encoder/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/tim/tim_encoder/.project b/Examples/tim/tim_encoder/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/Examples/tim/tim_encoder/.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/Examples/tim/tim_encoder/Project.nuproject b/Examples/tim/tim_encoder/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/Examples/tim/tim_encoder/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/tim/tim_encoder/component.mk b/Examples/tim/tim_encoder/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Examples/tim/tim_encoder/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/Examples/tim/tim_encoder/inc/isr.h b/Examples/tim/tim_encoder/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/Examples/tim/tim_encoder/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/Examples/tim/tim_encoder/inc/main.h b/Examples/tim/tim_encoder/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Examples/tim/tim_encoder/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/Examples/tim/tim_encoder/readme.md b/Examples/tim/tim_encoder/readme.md new file mode 100644 index 0000000..7e7312d --- /dev/null +++ b/Examples/tim/tim_encoder/readme.md @@ -0,0 +1,19 @@ +TIM_encoder_project +--- + +This example is a demo project to TIM encoder + +## Hardware and Software environment + ++ This example runs on PB5700 devices. + +## Log + ++ CAP0(PA14)/CAP1(PA15)/CAP2(PB0),PA6,PA7,PA8 set output ++ PA6 connects PA14,PA7 connects PA15,PA8 connects PB0 ++ Set channel 1->T1, channel2 -> T2 , ARR to 65535 ++ Set the encoder mode ++ Use PA6 and PA7 to output 3000 pulses ++ Capture register values + + diff --git a/Examples/tim/tim_encoder/src/isr.c b/Examples/tim/tim_encoder/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/Examples/tim/tim_encoder/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/Examples/tim/tim_encoder/src/main.c b/Examples/tim/tim_encoder/src/main.c new file mode 100644 index 0000000..5651ea3 --- /dev/null +++ b/Examples/tim/tim_encoder/src/main.c @@ -0,0 +1,114 @@ +/** + * 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 +//============================================================================= +uint32_t delayCounter = 0; +uint32_t encoderCounter = 0; +//============================================================================= +// 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); + +#if defined(CONFIG_USE_TIM2) + /*TIM2 TCAP0 -> PA14,TCAP1 -> PA15, TCAP2 -> PB0*/ + GPIO_PeriAFConfig(GPIOA,GPIO_Peri_TCAP0,GPIO_PeriAF_1); + GPIO_PeriAFConfig(GPIOA,GPIO_Peri_TCAP1,GPIO_PeriAF_2); + GPIO_PeriAFConfig(GPIOA,GPIO_Peri_TCAP2,GPIO_PeriAF_3); +#elif defined(CONFIG_USE_EPWM) + /*EPWM ECAP0 -> PA14,ECAP1 -> PA15, ECAP2 -> PB0*/ + GPIO_PeriAFConfig(GPIOA,GPIO_Peri_ECAP0,GPIO_PeriAF_1); + GPIO_PeriAFConfig(GPIOA,GPIO_Peri_ECAP1,GPIO_PeriAF_2); + GPIO_PeriAFConfig(GPIOA,GPIO_Peri_ECAP2,GPIO_PeriAF_3); +#endif + GPIO_InitTypeDef GPIO_InitStruct; + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_06 | GPIO_Pin_07 | GPIO_Pin_08 ; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; + GPIO_Init(GPIOA, &GPIO_InitStruct); + + TIM_DeInit(TIMx); + TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; + TIM_TimeBaseInitStruct.TIM_Prescaler = 0; + TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; + TIM_TimeBaseInitStruct.TIM_Period = 65535; + TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_Div1; + TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; + TIM_TimeBaseInit(TIMx, &TIM_TimeBaseInitStruct); + + TIM_ICInitTypeDef TIM_ICInitStruct; + TIM_ICInitStruct.TIM_Channel = TIM_Channel_1; + TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising; + TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI; + TIM_ICInitStruct.TIM_ICFilter = 0xF; + TIM_ICInit(TIMx, &TIM_ICInitStruct); + + TIM_ICInitStruct.TIM_Channel = TIM_Channel_2; + TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising; + TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI; + TIM_ICInitStruct.TIM_ICFilter = 0xF; + TIM_ICInit(TIMx, &TIM_ICInitStruct); + + TIM_EncoderInterfaceConfig(TIMx,TIM_EncoderMode_TI1,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising); + TIM_Cmd(TIMx, ENABLE); + + /*GPIO output 3000 pulses,PA6 -> PA14(channel1 T1 ),PA7 -> PA15(channel2 T2)*/ + for(encoderCounter = 0;encoderCounter < 3000 ;encoderCounter ++) + { + GPIO_SetBits(GPIOA,GPIO_Pin_06); + for(delayCounter = 0;delayCounter < 200 ;delayCounter ++); + GPIO_SetBits(GPIOA,GPIO_Pin_07); + for(delayCounter = 0;delayCounter < 200 ;delayCounter ++); + GPIO_ResetBits(GPIOA,GPIO_Pin_06); + for(delayCounter = 0;delayCounter < 200 ;delayCounter ++); + GPIO_ResetBits(GPIOA,GPIO_Pin_07); + for(delayCounter = 0;delayCounter < 200 ;delayCounter ++); + } + while(1) + { + + } +} diff --git a/Examples/tim/tim_forceOutput/.cproject b/Examples/tim/tim_forceOutput/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/tim/tim_forceOutput/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/tim/tim_forceOutput/.project b/Examples/tim/tim_forceOutput/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/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/Examples/tim/tim_forceOutput/Project.nuproject b/Examples/tim/tim_forceOutput/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/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: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/tim/tim_forceOutput/component.mk b/Examples/tim/tim_forceOutput/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/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/Examples/tim/tim_forceOutput/inc/isr.h b/Examples/tim/tim_forceOutput/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/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/Examples/tim/tim_forceOutput/inc/main.h b/Examples/tim/tim_forceOutput/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/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/Examples/tim/tim_forceOutput/readme.md b/Examples/tim/tim_forceOutput/readme.md new file mode 100644 index 0000000..2ca819a --- /dev/null +++ b/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 PB5700 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/Examples/tim/tim_forceOutput/src/isr.c b/Examples/tim/tim_forceOutput/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/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/Examples/tim/tim_forceOutput/src/main.c b/Examples/tim/tim_forceOutput/src/main.c new file mode 100644 index 0000000..5f5a61a --- /dev/null +++ b/Examples/tim/tim_forceOutput/src/main.c @@ -0,0 +1,83 @@ +/** + * 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) +{ +#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/Examples/tim/tim_onePulseOutput/.cproject b/Examples/tim/tim_onePulseOutput/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/tim/tim_onePulseOutput/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/tim/tim_onePulseOutput/.project b/Examples/tim/tim_onePulseOutput/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/Examples/tim/tim_onePulseOutput/.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/Examples/tim/tim_onePulseOutput/Project.nuproject b/Examples/tim/tim_onePulseOutput/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/Examples/tim/tim_onePulseOutput/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/tim/tim_onePulseOutput/component.mk b/Examples/tim/tim_onePulseOutput/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Examples/tim/tim_onePulseOutput/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/Examples/tim/tim_onePulseOutput/inc/isr.h b/Examples/tim/tim_onePulseOutput/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/Examples/tim/tim_onePulseOutput/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/Examples/tim/tim_onePulseOutput/inc/main.h b/Examples/tim/tim_onePulseOutput/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Examples/tim/tim_onePulseOutput/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/Examples/tim/tim_onePulseOutput/readme.md b/Examples/tim/tim_onePulseOutput/readme.md new file mode 100644 index 0000000..6d8a036 --- /dev/null +++ b/Examples/tim/tim_onePulseOutput/readme.md @@ -0,0 +1,13 @@ +TIM_onePulseOutput_project +--- + +This example is a demo project to TIM onePulseOutput + +## Hardware and Software environment + ++ This example runs on PB5700 devices. + +## Log + ++ only out one Pulse + diff --git a/Examples/tim/tim_onePulseOutput/src/isr.c b/Examples/tim/tim_onePulseOutput/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/Examples/tim/tim_onePulseOutput/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/Examples/tim/tim_onePulseOutput/src/main.c b/Examples/tim/tim_onePulseOutput/src/main.c new file mode 100644 index 0000000..0256ecf --- /dev/null +++ b/Examples/tim/tim_onePulseOutput/src/main.c @@ -0,0 +1,99 @@ +/** + * 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 +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ +#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 + + /* Resets the TIMx */ + TIM_DeInit(TIMx); + + TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; + /* Time Base configuration */ + TIM_TimeBaseStructure.TIM_Prescaler = 48 - 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_PWM1); + TIM_CCxCmd(TIMx,TIM_Channel_1,TIM_CCx_Enable); + + TIM_SetCompare2(TIMx,400);//CH1 DUTY:40% + TIM_SelectOCxM(TIMx,TIM_Channel_2,TIM_OCMode_PWM1); + TIM_CCxCmd(TIMx,TIM_Channel_2,TIM_CCx_Enable); + + TIM_SetCompare3(TIMx,250);//CH1 DUTY:25% + TIM_SelectOCxM(TIMx,TIM_Channel_3,TIM_OCMode_PWM1); + TIM_CCxCmd(TIMx,TIM_Channel_3,TIM_CCx_Enable); + + TIM_SelectOnePulseMode(TIMx, TIM_OPMode_Single); + /* TIM1 counter enable */ + TIM_Cmd(TIMx, ENABLE); + /* Main Output Enable */ + TIM_CtrlPWMOutputs(TIMx, ENABLE); + + while(1) + { + + } + +} diff --git a/Examples/tim/tim_outputCompare/.cproject b/Examples/tim/tim_outputCompare/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/tim/tim_outputCompare/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/tim/tim_outputCompare/.project b/Examples/tim/tim_outputCompare/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/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/Examples/tim/tim_outputCompare/Project.nuproject b/Examples/tim/tim_outputCompare/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/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: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/tim/tim_outputCompare/component.mk b/Examples/tim/tim_outputCompare/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/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/Examples/tim/tim_outputCompare/inc/isr.h b/Examples/tim/tim_outputCompare/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/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/Examples/tim/tim_outputCompare/inc/main.h b/Examples/tim/tim_outputCompare/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/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/Examples/tim/tim_outputCompare/readme.md b/Examples/tim/tim_outputCompare/readme.md new file mode 100644 index 0000000..b96ec04 --- /dev/null +++ b/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 PB5700 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/Examples/tim/tim_outputCompare/src/isr.c b/Examples/tim/tim_outputCompare/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/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/Examples/tim/tim_outputCompare/src/main.c b/Examples/tim/tim_outputCompare/src/main.c new file mode 100644 index 0000000..aa38d4c --- /dev/null +++ b/Examples/tim/tim_outputCompare/src/main.c @@ -0,0 +1,124 @@ +/** + * 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) +{ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + 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_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 + + 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); + + TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; + /* Time Base configuration */ + TIM_TimeBaseStructure.TIM_Prescaler = 48 - 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); + __enable_irq(); + + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(CONFIG_IRQ_ID, TIMx_handler, &irq_attr); + + 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) +{ + if(TIM_GetITStatus(TIMx, TIM_IT_CC2) == SET) + { + TIM_ClearITPendingBit(TIMx, TIM_IT_CC2); + GPIO_SetBits(GPIOA, GPIO_Pin_07); + } +} diff --git a/Examples/tim/tim_pwm_output/.cproject b/Examples/tim/tim_pwm_output/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/tim/tim_pwm_output/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/tim/tim_pwm_output/.project b/Examples/tim/tim_pwm_output/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/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/Examples/tim/tim_pwm_output/Project.nuproject b/Examples/tim/tim_pwm_output/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/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: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/tim/tim_pwm_output/component.mk b/Examples/tim/tim_pwm_output/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/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/Examples/tim/tim_pwm_output/inc/isr.h b/Examples/tim/tim_pwm_output/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/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/Examples/tim/tim_pwm_output/inc/main.h b/Examples/tim/tim_pwm_output/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/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/Examples/tim/tim_pwm_output/readme.md b/Examples/tim/tim_pwm_output/readme.md new file mode 100644 index 0000000..8a8c3a3 --- /dev/null +++ b/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 PB5700 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/Examples/tim/tim_pwm_output/src/isr.c b/Examples/tim/tim_pwm_output/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/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/Examples/tim/tim_pwm_output/src/main.c b/Examples/tim/tim_pwm_output/src/main.c new file mode 100644 index 0000000..64ce6c5 --- /dev/null +++ b/Examples/tim/tim_pwm_output/src/main.c @@ -0,0 +1,129 @@ +/** + * 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) +{ + uint16_t prescalerCounter = 23; + uint16_t delay = 0; + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + TIM_PWM_OUTPUT_Sample(TIMx,100 - 1,48 - 1,TIM_CounterMode_Up);//pwm:10K + 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) + /* ToDo: 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) + /* ToDo: 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 + /* ToDo: configure GPIO Pin OUT */ + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_06 ; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; + GPIO_Init(GPIOA, &GPIO_InitStruct); + + TIM_Cmd(tim, ENABLE); + TIM_CtrlPWMOutputs(tim,ENABLE); +} diff --git a/Examples/tim/tim_xorInput/.cproject b/Examples/tim/tim_xorInput/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/tim/tim_xorInput/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/tim/tim_xorInput/.project b/Examples/tim/tim_xorInput/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/Examples/tim/tim_xorInput/.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/Examples/tim/tim_xorInput/Project.nuproject b/Examples/tim/tim_xorInput/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/Examples/tim/tim_xorInput/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/tim/tim_xorInput/component.mk b/Examples/tim/tim_xorInput/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Examples/tim/tim_xorInput/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/Examples/tim/tim_xorInput/inc/isr.h b/Examples/tim/tim_xorInput/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/Examples/tim/tim_xorInput/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/Examples/tim/tim_xorInput/inc/main.h b/Examples/tim/tim_xorInput/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Examples/tim/tim_xorInput/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/Examples/tim/tim_xorInput/readme.md b/Examples/tim/tim_xorInput/readme.md new file mode 100644 index 0000000..850305c --- /dev/null +++ b/Examples/tim/tim_xorInput/readme.md @@ -0,0 +1,19 @@ +TIM_xorInput_project +--- + +This example is a demo project to TIM xorInput + +## Hardware and Software environment + ++ This example runs on PB5700 devices. + +## Log + ++ CAP0(PA14)/CAP1(PA15)/CAP2(PB0),PA6,PA7,PA8 set output ++ PA6 connects PA14,PA7 connects PA15,PA8 connects PB0 ++ Set TIM output to 1KHz PWM ++ Set as trigger mode, trigger source is T1 ++ Set T1 as the XOR result of CAP0, CAP1, and CAP2 ++ Set PA6/7/8 voltage level ++ When PA6/7/8 changes from 0 to 1, PWM starts outputting + diff --git a/Examples/tim/tim_xorInput/src/isr.c b/Examples/tim/tim_xorInput/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/Examples/tim/tim_xorInput/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/Examples/tim/tim_xorInput/src/main.c b/Examples/tim/tim_xorInput/src/main.c new file mode 100644 index 0000000..85e967d --- /dev/null +++ b/Examples/tim/tim_xorInput/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_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 +//============================================================================= +uint32_t delayCounter = 0; +//============================================================================= +// 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); + +#if defined(CONFIG_USE_TIM2) + GPIO_InitTypeDef GPIO_InitStruct; + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_03 | GPIO_Pin_04; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_5; + GPIO_Init(GPIOA, &GPIO_InitStruct); + + /*TIM2 TCAP0 -> PA14,TCAP1 -> PA15, TCAP2 -> PB0*/ + GPIO_PeriAFConfig(GPIOA,GPIO_Peri_TCAP0,GPIO_PeriAF_1); + GPIO_PeriAFConfig(GPIOA,GPIO_Peri_TCAP1,GPIO_PeriAF_2); + GPIO_PeriAFConfig(GPIOA,GPIO_Peri_TCAP2,GPIO_PeriAF_3); +#elif defined(CONFIG_USE_EPWM) + GPIO_InitTypeDef GPIO_InitStruct; + GPIO_InitStruct.GPIO_Pin = 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); + + /*EPWM ECAP0 -> PA14,ECAP1 -> PA15, ECAP2 -> PB0*/ + GPIO_PeriAFConfig(GPIOA,GPIO_Peri_ECAP0,GPIO_PeriAF_1); + GPIO_PeriAFConfig(GPIOA,GPIO_Peri_ECAP1,GPIO_PeriAF_2); + GPIO_PeriAFConfig(GPIOA,GPIO_Peri_ECAP2,GPIO_PeriAF_3); +#endif + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_06 | GPIO_Pin_07 | GPIO_Pin_08 ; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; + GPIO_Init(GPIOA, &GPIO_InitStruct); + + TIM_DeInit(TIMx); + TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; + TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct); + TIM_TimeBaseInitStruct.TIM_Prescaler = 48 - 1; + TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; + TIM_TimeBaseInitStruct.TIM_Period = 1000 - 1;//1ms + TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_Div1; + TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; + TIM_TimeBaseInit(TIMx, &TIM_TimeBaseInitStruct); + + TIM_ICInitTypeDef TIM_ICInitStruct; + TIM_ICInitStruct.TIM_Channel = TIM_Channel_1; + 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 = 0x0; + TIM_ICInit(TIMx, &TIM_ICInitStruct); + + TIM_SetCompare2(TIMx,400);//CH2 DUTY:40% + TIM_SelectOCxM(TIMx,TIM_Channel_2,TIM_OCMode_PWM1); + TIM_CCxCmd(TIMx,TIM_Channel_2,TIM_CCx_Enable); + + TIM_SetCompare3(TIMx,250);//CH3 DUTY:25% + TIM_SelectOCxM(TIMx,TIM_Channel_3,TIM_OCMode_PWM1); + TIM_CCxCmd(TIMx,TIM_Channel_3,TIM_CCx_Enable); + + TIM_SelectInputTrigger(TIMx,TIM_TS_TI1F_ED); + TIM_SelectSlaveMode(TIMx,TIM_SlaveMode_Trigger); + TIM_SelectHallSensor(TIMx, ENABLE); + TIM_Cmd(TIMx, ENABLE); + TIM_CtrlPWMOutputs(TIMx, ENABLE); + for(delayCounter = 0;delayCounter < 20000 ;delayCounter ++); + GPIO_SetBits(GPIOA,GPIO_Pin_06 | GPIO_Pin_07 | GPIO_Pin_08); + + while(1) + { + + } +} diff --git a/Examples/uart/uart_Interrupt/.cproject b/Examples/uart/uart_Interrupt/.cproject new file mode 100644 index 0000000..19a602b --- /dev/null +++ b/Examples/uart/uart_Interrupt/.cproject @@ -0,0 +1,289 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/uart/uart_Interrupt/.project b/Examples/uart/uart_Interrupt/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/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/Examples/uart/uart_Interrupt/Project.nuproject b/Examples/uart/uart_Interrupt/Project.nuproject new file mode 100644 index 0000000..f71fbc6 --- /dev/null +++ b/Examples/uart/uart_Interrupt/Project.nuproject @@ -0,0 +1,27 @@ +SDK_CONFIG: + Debug: + core: N100E + download: LINK_FLASH + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ec + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N100E + download: LINK_FLASH + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ec + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/uart/uart_Interrupt/component.mk b/Examples/uart/uart_Interrupt/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/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/Examples/uart/uart_Interrupt/inc/isr.h b/Examples/uart/uart_Interrupt/inc/isr.h new file mode 100644 index 0000000..b1ab850 --- /dev/null +++ b/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/Examples/uart/uart_Interrupt/inc/main.h b/Examples/uart/uart_Interrupt/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/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/Examples/uart/uart_Interrupt/readme.md b/Examples/uart/uart_Interrupt/readme.md new file mode 100644 index 0000000..6a51646 --- /dev/null +++ b/Examples/uart/uart_Interrupt/readme.md @@ -0,0 +1,14 @@ +Uart_Interrput_project +--- + +This example is a demo project to UART Interrput + +## Hardware and Software environment + ++ This example runs on PB5700 devices. + +## Log + ++ SET different uart flag bits to enable interrupts ++ Send data in the corresponding interrupt + diff --git a/Examples/uart/uart_Interrupt/src/isr.c b/Examples/uart/uart_Interrupt/src/isr.c new file mode 100644 index 0000000..4cd5b57 --- /dev/null +++ b/Examples/uart/uart_Interrupt/src/isr.c @@ -0,0 +1,50 @@ +/** + * 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 +//============================================================================= +/** + * \brief System Software ISR + * + * \return None + */ +__INTERRUPT void irqc_msip_handler(void) +{ + sys_clear_swi(); + return; +} + diff --git a/Examples/uart/uart_Interrupt/src/main.c b/Examples/uart/uart_Interrupt/src/main.c new file mode 100644 index 0000000..f6c6b50 --- /dev/null +++ b/Examples/uart/uart_Interrupt/src/main.c @@ -0,0 +1,178 @@ +/** + * 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 +//============================================================================= +uint16_t rxDataBuffer[256]; +uint16_t rxCounter = 0; +uint16_t rxData = 0; +uint16_t txData = 0; +uint16_t errCounter = 0; +uint16_t rightCounter = 0; +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +void UART0_Handler(void); +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + GPIO_InitTypeDef gpio_init = {0}; + UART_InitTypeDef uart_init = {0}; + + /* ToDo: configure GPIO Pin mux of UART (Tx through PA0?) */ + gpio_init.GPIO_Pin = GPIO_Pin_00 | GPIO_Pin_01; + gpio_init.GPIO_Mode = GPIO_Mode_AF; + gpio_init.GPIO_AF_Mode = GPIO_AF_1; + GPIO_Init(GPIOA, &gpio_init); + + uart_init.BaudRate = SLOG_SERIAL_BPS; + uart_init.WordLength = UART_WordLength_8b1P; + uart_init.StopBits = UART_StopBits_1; + uart_init.Parity = UART_Parity_No; + uart_init.Mode = UART_Mode_TxRx; + UART_Init(UART0, &uart_init); + + UART_ITConfig(UART0, UART_IT_RXF, ENABLE); + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(I2C0_IRQn, UART0_Handler, &irq_attr); + __enable_irq(); + + UART_Start(UART0); + + while(1) + { + + + } +} + +__INTERRUPT void UART0_Handler(void) +{ + if(UART_GetITStatus(UART0, UART_IT_RXNE) == 1) + { + printf("UART0 RXNE Interrupt successful\r\n"); + UART_ITConfig(UART0, UART_IT_RXNE, DISABLE); + + } + if(UART_GetITStatus(UART0, UART_IT_TXE) == 1) + { + printf("UART0 TXE Interrupt successful\r\n"); + UART_ITConfig(UART0, UART_IT_TXE, DISABLE); + } + if(UART_GetITStatus(UART0, UART_IT_TXHE) == 1) + { + printf("UART0 TXHE Interrupt successful\r\n"); + UART_ITConfig(UART0, UART_IT_TXHE, DISABLE); + } + if(UART_GetITStatus(UART0, UART_IT_PERR) == 1) + { + + printf("UART0 PERR Interrupt successful"); + REG_SET_BITS(UART0->SR, UART_IT_PERR); + + if(UART_GetFlagStatus(UART0, UART_IT_PERR ) == 0) + { + printf("UART0 PERR Interrupt Flag clear successful\r\n"); + } + else + { + printf("UART0 PERR Interrupt Flag clear fail\r\n"); + } + + UART_ITConfig(UART0, UART_IT_PERR, DISABLE); + } + if(UART_GetITStatus(UART0, UART_IT_FERR) == 1) + { + printf("UART0 FERR Interrupt successful\r\n"); + REG_SET_BITS(UART0->SR, UART_IT_FERR); + if(UART_GetFlagStatus(UART0, UART_IT_RXNE ) == 0) + { + printf("UART0 OVERR Interrupt Flag clear successful\r\n"); + } + else + { + printf("UART0 OVERR Interrupt Flag clear fail\r\n"); + } + UART_ITConfig(UART0, UART_IT_FERR, DISABLE); + } + if(UART_GetITStatus(UART0, UART_IT_OVERR) == 1) + { + printf("UART0 OVERR Interrupt successful\r\n"); + UART_ResetRxFIFO(UART0); + REG_SET_BITS(UART0->SR, UART_IT_OVERR); + if(UART_GetFlagStatus(UART0, UART_IT_RXNE ) == 0) + { + printf("UART0 OVERR Interrupt Flag clear successful\r\n"); + } + else + { + printf("UART0 OVERR Interrupt Flag clear fail\r\n"); + } + UART_ITConfig(UART0, UART_IT_OVERR, DISABLE); + } + if(UART_GetITStatus(UART0, UART_IT_TONE) == 1) + { + printf("UART0 TONE Interrupt successful\r\n"); + UART_ITConfig(UART0, UART_IT_TONE, DISABLE); + } + if(UART_GetITStatus(UART0, UART_IT_TOIDLE) == 1) + { + printf("UART0 TOIDLE Interrupt successful\r\n"); + UART_ITConfig(UART0, UART_IT_TOIDLE, DISABLE); + } + if(UART_GetITStatus(UART0, UART_IT_RXHF) == 1) + { + printf("UART0 RXHF Interrupt successful\r\n"); + UART_ITConfig(UART0, UART_IT_RXHF, DISABLE); + } + if(UART_GetITStatus(UART0, UART_IT_RXF) == 1) + { + printf("UART0 RXF Interrupt successful\r\n"); + UART_ITConfig(UART0, UART_IT_RXF, DISABLE); + } + if(UART_GetITStatus(UART0, UART_IT_TX_DONE) == 1) + { + printf("UART0 TXEND Interrupt successful\r\n"); + UART_ITConfig(UART0, UART_IT_TX_DONE, DISABLE); + } + if(UART_GetITStatus(UART0, UART_IT_TXF) == 1) + { + UART_ResetTxFIFO(UART0); + UART_Start(UART0); + printf("UART0 TXF Interrupt successful\r\n"); + UART_ITConfig(UART0, UART_IT_TXF, DISABLE); + } +} diff --git a/Examples/uart/uart_polling/.cproject b/Examples/uart/uart_polling/.cproject new file mode 100644 index 0000000..d9ac06f --- /dev/null +++ b/Examples/uart/uart_polling/.cproject @@ -0,0 +1,294 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/uart/uart_polling/.project b/Examples/uart/uart_polling/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/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/Examples/uart/uart_polling/Project.nuproject b/Examples/uart/uart_polling/Project.nuproject new file mode 100644 index 0000000..0072223 --- /dev/null +++ b/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/Examples/uart/uart_polling/component.mk b/Examples/uart/uart_polling/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/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/Examples/uart/uart_polling/inc/isr.h b/Examples/uart/uart_polling/inc/isr.h new file mode 100644 index 0000000..b1ab850 --- /dev/null +++ b/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/Examples/uart/uart_polling/inc/main.h b/Examples/uart/uart_polling/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/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/Examples/uart/uart_polling/readme.md b/Examples/uart/uart_polling/readme.md new file mode 100644 index 0000000..2a6cf75 --- /dev/null +++ b/Examples/uart/uart_polling/readme.md @@ -0,0 +1,14 @@ +Uart_Polling_project +--- + +This example is a demo project to UART Polling + +## Hardware and Software environment + ++ This example runs on PB5700 devices. + +## Log + ++ PC sends 1~255 to PB5700 ++ PB5700 receives and sends back data + diff --git a/Examples/uart/uart_polling/src/isr.c b/Examples/uart/uart_polling/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/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/Examples/uart/uart_polling/src/main.c b/Examples/uart/uart_polling/src/main.c new file mode 100644 index 0000000..dad56e7 --- /dev/null +++ b/Examples/uart/uart_polling/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 +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= +uint16_t rxDataBuffer[256]; +uint16_t rxCounter = 0; +uint16_t rxData = 0; +uint16_t txData = 0; +uint16_t errCounter = 0; +uint16_t rightCounter = 0; +//============================================================================= +// 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); + + GPIO_InitTypeDef gpio_init = {0}; + UART_InitTypeDef uart_init = {0}; + + /* ToDo: configure GPIO Pin mux of UART (Tx through PA0?) */ + gpio_init.GPIO_Pin = GPIO_Pin_00 | GPIO_Pin_01 ; + gpio_init.GPIO_Mode = GPIO_Mode_AF; + gpio_init.GPIO_AF_Mode = GPIO_AF_1; + GPIO_Init(GPIOA, &gpio_init); + + 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); + + 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]) + { + printf("rx error"); + errCounter ++; + } + else + { + UART_SendData(UART0,rxData); + UART_WaitTxFifoEmpty(UART0); + rightCounter ++ ; + } + } + + } +} diff --git a/Examples/wdg/wdg_count/.cproject b/Examples/wdg/wdg_count/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/wdg/wdg_count/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/wdg/wdg_count/.project b/Examples/wdg/wdg_count/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/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/Examples/wdg/wdg_count/Project.nuproject b/Examples/wdg/wdg_count/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/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: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/wdg/wdg_count/component.mk b/Examples/wdg/wdg_count/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/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/Examples/wdg/wdg_count/inc/isr.h b/Examples/wdg/wdg_count/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/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/Examples/wdg/wdg_count/inc/main.h b/Examples/wdg/wdg_count/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/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/Examples/wdg/wdg_count/readme.md b/Examples/wdg/wdg_count/readme.md new file mode 100644 index 0000000..8f0b1b4 --- /dev/null +++ b/Examples/wdg/wdg_count/readme.md @@ -0,0 +1,20 @@ +wdg count and interrupt +--- + +This example is used to run wdg count and interrupt function. + +## Hardware and Software environment + ++ This example runs on PB5700 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 reload value ++ Run the example + ++ If you want to use the reset function, you can set the reset enable, + but you need to remove the clear watchdog in the interrupt. \ No newline at end of file diff --git a/Examples/wdg/wdg_count/src/isr.c b/Examples/wdg/wdg_count/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/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/Examples/wdg/wdg_count/src/main.c b/Examples/wdg/wdg_count/src/main.c new file mode 100644 index 0000000..f7d6d48 --- /dev/null +++ b/Examples/wdg/wdg_count/src/main.c @@ -0,0 +1,112 @@ +/** + * 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 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 WDG_Handler(void) +{ + WDG_Clear(); + GPIO_TogglePin(CONFIG_TOGGLE_PORT, CONFIG_TOGGLE_PIN); + return; + +} +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + WDG_BaseInitTypeDef WDG_InitStruct = {0}; + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + syslog_init(); + msg("The value of RST_INFO is %#0x\n", SYSCFG->SYSRSTSR); + SYSCFG->SYSRSTSR = 0XFF; + + printf("Program start \r\n"); + + { + // configure I/O to toggle + GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.GPIO_Pin = CONFIG_TOGGLE_PIN | GPIO_Pin_03; + 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); + } + + GPIO_TogglePin(CONFIG_TOGGLE_PORT, GPIO_Pin_03); + for(int i=0; i<1000; i++); + GPIO_TogglePin(CONFIG_TOGGLE_PORT, GPIO_Pin_03); + for(int i=0; i<1000; i++); + GPIO_TogglePin(CONFIG_TOGGLE_PORT, GPIO_Pin_03); + + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(WDG_IRQn, WDG_Handler, &irq_attr); + sys_enable_girq(); + + WDG_InitStruct.Relaod = 1000; //3200; + WDG_InitStruct.Reset = WDG_Reset_Dis; + WDG_InitStruct.Debug = WDG_Debug_Dis; + + WDG_BaseInit(&WDG_InitStruct); + + WDG_Enable(); + +// while(1) +// { +// __NOP(); +// } + + int i=0; + uint32_t cnt_value[2] = {0}; + while(1) + { + cnt_value[0] = 0; + cnt_value[1] = 0; + + cnt_value[0] = WDG_GetCountValue(); + for(i=0; i<2; ) + { + i = i+1; + } + cnt_value[1] = WDG_GetCountValue(); + i = 0; + } + + + return 0; +} diff --git a/Examples/wdg/wdg_lock/.cproject b/Examples/wdg/wdg_lock/.cproject new file mode 100644 index 0000000..21d0162 --- /dev/null +++ b/Examples/wdg/wdg_lock/.cproject @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/wdg/wdg_lock/.project b/Examples/wdg/wdg_lock/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/Examples/wdg/wdg_lock/.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/Examples/wdg/wdg_lock/Project.nuproject b/Examples/wdg/wdg_lock/Project.nuproject new file mode 100644 index 0000000..0743ed2 --- /dev/null +++ b/Examples/wdg/wdg_lock/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/Examples/wdg/wdg_lock/component.mk b/Examples/wdg/wdg_lock/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/Examples/wdg/wdg_lock/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/Examples/wdg/wdg_lock/inc/isr.h b/Examples/wdg/wdg_lock/inc/isr.h new file mode 100644 index 0000000..2f4d4da --- /dev/null +++ b/Examples/wdg/wdg_lock/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/Examples/wdg/wdg_lock/inc/main.h b/Examples/wdg/wdg_lock/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/Examples/wdg/wdg_lock/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/Examples/wdg/wdg_lock/readme.md b/Examples/wdg/wdg_lock/readme.md new file mode 100644 index 0000000..0a04e69 --- /dev/null +++ b/Examples/wdg/wdg_lock/readme.md @@ -0,0 +1,17 @@ +wdg lock +--- + +This example is used to run wdg lock function. + +## Hardware and Software environment + ++ This example runs on PB5700 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 lock to aviod overwriting or unlock so that overwriting can be done ++ Run the example \ No newline at end of file diff --git a/Examples/wdg/wdg_lock/src/isr.c b/Examples/wdg/wdg_lock/src/isr.c new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/Examples/wdg/wdg_lock/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/Examples/wdg/wdg_lock/src/main.c b/Examples/wdg/wdg_lock/src/main.c new file mode 100644 index 0000000..7303fe1 --- /dev/null +++ b/Examples/wdg/wdg_lock/src/main.c @@ -0,0 +1,114 @@ +/** + * 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 PA2 to toggle */ +#define CONFIG_TOGGLE_PORT GPIOA +#define CONFIG_TOGGLE_PIN GPIO_Pin_02 +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +uint32_t cnt_int_flag = 0; +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void WDG_Handler(void) +{ + WDG_Clear(); + GPIO_TogglePin(CONFIG_TOGGLE_PORT, CONFIG_TOGGLE_PIN); + + cnt_int_flag++; + return; + +} +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + WDG_BaseInitTypeDef WDG_InitStruct = {0}; + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + syslog_init(); + msg("The value of RST_INFO is %#0x\n", SYSCFG->SYSRSTSR); + SYSCFG->SYSRSTSR = 0XFF; + + printf("Program start \r\n"); + + { + // configure I/O to toggle + GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.GPIO_Pin = CONFIG_TOGGLE_PIN | GPIO_Pin_03; + 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); + } + + GPIO_TogglePin(CONFIG_TOGGLE_PORT, GPIO_Pin_03); + for(int i=0; i<1000; i++); + GPIO_TogglePin(CONFIG_TOGGLE_PORT, GPIO_Pin_03); + for(int i=0; i<1000; i++); + GPIO_TogglePin(CONFIG_TOGGLE_PORT, GPIO_Pin_03); + + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(WDG_IRQn, WDG_Handler, &irq_attr); + sys_enable_girq(); + + WDG_InitStruct.Relaod = 1000; //3200; + WDG_InitStruct.Reset = WDG_Reset_Dis; + WDG_InitStruct.Debug = WDG_Debug_Dis; + + WDG_BaseInit(&WDG_InitStruct); + + WDG_Enable(); + WDG_Lock(); + while(WDG_GetLockStatus() != 1); + GPIO_TogglePin(CONFIG_TOGGLE_PORT, GPIO_Pin_03); + cnt_int_flag = 0; + while(cnt_int_flag<10); + + + WDG_Unlock(); + while(WDG_GetLockStatus() != 0); + + WDG_SetReload(2000); + WDG_Clear(); + GPIO_TogglePin(CONFIG_TOGGLE_PORT, GPIO_Pin_03); + cnt_int_flag = 0; + while(cnt_int_flag<10); + + WDG_Disable(); + GPIO_TogglePin(CONFIG_TOGGLE_PORT, GPIO_Pin_03); + while(1) + { + __NOP(); + } + + return 0; +} diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ebdfdd9 --- /dev/null +++ b/Makefile @@ -0,0 +1,338 @@ +# ------------------------------------------------ +# 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_server gdb +PHONY += tags TAGS cscope gtags +PHONY += upload +###################################### +# target +###################################### +ifeq ("$(TARGET)","") +TARGET = Project +endif + +SOC ?= pb5700 + +ifeq (,$(filter $(MAKECMDGOALS),clean help)) + +ifeq ("$(SOC)","pb5700") + SOC_DRIVER = PB5700 +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 += -g -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_server: $(OUT)/$(TARGET).elf + @${OPENOCD} -s Tools/openocd/scripts -f Tools/openocd/scripts/target/$(SOC).cfg + + +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 0; reset run" 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_server - Start GDB server" + @$(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/README.md b/README.md index 3349616..add911b 100644 --- a/README.md +++ b/README.md @@ -1,93 +1,96 @@ -# pec930_peripheral +# pb5700_sdk + +PB5700_SDK (Nuclei-N203E) + +## Setup Editor + ++ Spaces to replace Tab + > `4-空白`做縮排 + ++ File uses `UTF-8` encoding + > 檔案使用 `utf-8` 編碼 + +## Naming directory and file + ++ only use ASCII `a-z`, `A-Z`, `0-9`, and `_` (DONOT use white-space) + > 在目錄或檔案命名上, 只允許使用**英文/數字**及**下底線**, 禁止使用空白字元 + +## Download SDK + ++ [Git-for-Windows](https://git-scm.com/) + + - Setup Git when first-time + + ``` + $ git config --global user.name "your name" + $ git config --global user.email your-mail + $ git config --global http.sslVerify false + $ git config --global core.ignorecase false + $ git config --global core.autocrlf input + ``` + + - Clone SDK + + ``` + $ git -c http.sslVerify=false clone --recurse-submodules https://60.248.80.176:28080/wlhsu/pb5700_sdk.git + ``` + + Sign-in with Username/Password
+ ![Gitlab-sign-in](./Docs/image/gitlab_login.jpg) + ++ [TortoiseGit](https://tortoisegit.org/) + + - Use `Git-for-Windows` to configure paraments + + ``` + $ git config --global user.name "your name" + $ git config --global user.email your-mail + $ git config --global http.sslVerify false + $ git config --global core.ignorecase false + $ git config --global core.autocrlf input + ``` + - Clone SDK + + ![TortoiseGit-clone](./Docs/image/TortoiseGit_clone.jpg) + + - 基本操作 + 1. [TortoiseGit使用 - 風御之舉 - 部落格園](https://www.cnblogs.com/agui125/p/15940508.html) + > + `三:TortoiseGit使用` + 1. [易學難精:Git 簡單的部分(一)](https://jonny-huang.github.io/projects/03_git_01/) + +## Development + +### Linux platform + +SDK uses Makefile to compile in Ubuntu and type `make help` to get message + +### Windows 10/11 platform + +[Nuclei-Studio IDE 20224.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 ICE + + ![ICE_normal_view](./Docs/image/ICE_normal_view.jpg) + ++ Debug with IDE + + ![IDE_debug_view](./Docs/image/IDE_debug_view.jpg) +### Log message -## Getting started +For code size, default only support 32-bits integer. -To make it easy for you to get started with GitLab, here's a list of recommended next steps. - -Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)! - -## Add your files - -* [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files -* [Add files using the command line](https://docs.gitlab.com/topics/git/add_files/#add-files-to-a-git-repository) or push an existing Git repository with the following command: +User should enable the other features manually ``` -cd existing_repo -git remote add origin https://gitlab.com/wisetop/microchip/application/pec930/pec930_peripheral.git -git branch -M main -git push -uf origin main +// 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 + ``` - -## Integrate with your tools - -* [Set up project integrations](https://gitlab.com/wisetop/microchip/application/pec930/pec930_peripheral/-/settings/integrations) - -## Collaborate with your team - -* [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/) -* [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html) -* [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically) -* [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/) -* [Set auto-merge](https://docs.gitlab.com/user/project/merge_requests/auto_merge/) - -## Test and Deploy - -Use the built-in continuous integration in GitLab. - -* [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/) -* [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/) -* [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html) -* [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/) -* [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html) - -*** - -# Editing this README - -When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template. - -## Suggestions for a good README - -Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information. - -## Name -Choose a self-explaining name for your project. - -## Description -Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors. - -## Badges -On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge. - -## Visuals -Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method. - -## Installation -Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection. - -## Usage -Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README. - -## Support -Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc. - -## Roadmap -If you have ideas for releases in the future, it is a good idea to list them in the README. - -## Contributing -State if you are open to contributions and what your requirements are for accepting them. - -For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self. - -You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser. - -## Authors and acknowledgment -Show your appreciation to those who have contributed to the project. - -## License -For open source projects, say how it is licensed. - -## Project status -If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers. diff --git a/Tools/openocd/README.md b/Tools/openocd/README.md new file mode 100644 index 0000000..f703a25 --- /dev/null +++ b/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/Tools/openocd/scripts/bitsbytes.tcl b/Tools/openocd/scripts/bitsbytes.tcl new file mode 100644 index 0000000..756c725 --- /dev/null +++ b/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/Tools/openocd/scripts/interface/dummy.cfg b/Tools/openocd/scripts/interface/dummy.cfg new file mode 100644 index 0000000..154c872 --- /dev/null +++ b/Tools/openocd/scripts/interface/dummy.cfg @@ -0,0 +1,5 @@ +# +# Dummy interface (for testing purposes) +# + +adapter driver dummy diff --git a/Tools/openocd/scripts/interface/flashlink.cfg b/Tools/openocd/scripts/interface/flashlink.cfg new file mode 100644 index 0000000..b7ec0bb --- /dev/null +++ b/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/Tools/openocd/scripts/interface/ft232r.cfg b/Tools/openocd/scripts/interface/ft232r.cfg new file mode 100644 index 0000000..2c705c3 --- /dev/null +++ b/Tools/openocd/scripts/interface/ft232r.cfg @@ -0,0 +1,2 @@ +adapter driver ft232r +adapter speed 1000 diff --git a/Tools/openocd/scripts/interface/jlink.cfg b/Tools/openocd/scripts/interface/jlink.cfg new file mode 100644 index 0000000..f9a18b0 --- /dev/null +++ b/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/Tools/openocd/scripts/interface/jtag_dpi.cfg b/Tools/openocd/scripts/interface/jtag_dpi.cfg new file mode 100644 index 0000000..a92e131 --- /dev/null +++ b/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/Tools/openocd/scripts/interface/jtag_hat_rpi2.cfg b/Tools/openocd/scripts/interface/jtag_hat_rpi2.cfg new file mode 100644 index 0000000..495ff0f --- /dev/null +++ b/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/Tools/openocd/scripts/interface/jtag_vpi.cfg b/Tools/openocd/scripts/interface/jtag_vpi.cfg new file mode 100644 index 0000000..f2f90f7 --- /dev/null +++ b/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/Tools/openocd/scripts/interface/openjtag.cfg b/Tools/openocd/scripts/interface/openjtag.cfg new file mode 100644 index 0000000..8d015b7 --- /dev/null +++ b/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/Tools/openocd/scripts/interface/usb-jtag.cfg b/Tools/openocd/scripts/interface/usb-jtag.cfg new file mode 100644 index 0000000..bbfb076 --- /dev/null +++ b/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/Tools/openocd/scripts/mem_helper.tcl b/Tools/openocd/scripts/mem_helper.tcl new file mode 100644 index 0000000..1c86011 --- /dev/null +++ b/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/Tools/openocd/scripts/memory.tcl b/Tools/openocd/scripts/memory.tcl new file mode 100644 index 0000000..ac27345 --- /dev/null +++ b/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/Tools/openocd/scripts/mmr_helpers.tcl b/Tools/openocd/scripts/mmr_helpers.tcl new file mode 100644 index 0000000..d9b6e63 --- /dev/null +++ b/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/Tools/openocd/scripts/target/pb5700.cfg b/Tools/openocd/scripts/target/pb5700.cfg new file mode 100644 index 0000000..9756fc2 --- /dev/null +++ b/Tools/openocd/scripts/target/pb5700.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/PB5700/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/Tools/scripts/Profiles/Project_Debug_OpenOCD.launch b/Tools/scripts/Profiles/Project_Debug_OpenOCD.launch new file mode 100644 index 0000000..499d283 --- /dev/null +++ b/Tools/scripts/Profiles/Project_Debug_OpenOCD.launch @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/scripts/Profiles/Project_Debug_jLink.launch b/Tools/scripts/Profiles/Project_Debug_jLink.launch new file mode 100644 index 0000000..659be1c --- /dev/null +++ b/Tools/scripts/Profiles/Project_Debug_jLink.launch @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/scripts/tags.sh b/Tools/scripts/tags.sh new file mode 100644 index 0000000..61d4269 --- /dev/null +++ b/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 diff --git a/pec930_peripheral.code-workspace b/pec930_peripheral.code-workspace new file mode 100644 index 0000000..362d7c2 --- /dev/null +++ b/pec930_peripheral.code-workspace @@ -0,0 +1,7 @@ +{ + "folders": [ + { + "path": "." + } + ] +} \ No newline at end of file