diff --git a/ports/xuantie/e906/gnu/CMakeLists.txt b/ports/xuantie/e906/gnu/CMakeLists.txt new file mode 100644 index 00000000..33a3a43a --- /dev/null +++ b/ports/xuantie/e906/gnu/CMakeLists.txt @@ -0,0 +1,17 @@ + +target_sources(${PROJECT_NAME} + PRIVATE + # {{BEGIN_TARGET_SOURCES}} + ${CMAKE_CURRENT_LIST_DIR}/src/tx_port.c + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_context.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_interrupt_control.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_schedule.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_system_return.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_interrupt.c + # {{END_TARGET_SOURCES}} +) + +target_include_directories(${PROJECT_NAME} + PUBLIC + ${CMAKE_CURRENT_LIST_DIR}/inc +) diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/CMakeLists.txt b/ports/xuantie/e906/gnu/example_build/smartl_fpga/CMakeLists.txt new file mode 100644 index 00000000..ed803a64 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/CMakeLists.txt @@ -0,0 +1,78 @@ +cmake_minimum_required(VERSION 3.15 FATAL_ERROR) + +project(demo_threadx + LANGUAGES C ASM +) + +set(SRCS + ${CMAKE_CURRENT_LIST_DIR}/demo_threadx.c + ${CMAKE_CURRENT_LIST_DIR}/pre_main.c + ${CMAKE_CURRENT_LIST_DIR}/boards/board_riscv_dummy/src/uart/board_uart.c + ${CMAKE_CURRENT_LIST_DIR}/boards/board_riscv_dummy/src/board_init.c + ${CMAKE_CURRENT_LIST_DIR}/components/csi/csi2/src/csi_misc.c + ${CMAKE_CURRENT_LIST_DIR}/components/csi/csi2/src/csi_ringbuf.c + ${CMAKE_CURRENT_LIST_DIR}/components/libc_threadx/mini_printf.c + ${CMAKE_CURRENT_LIST_DIR}/components/libc_threadx/newlib_stub.c + ${CMAKE_CURRENT_LIST_DIR}/components/chip_riscv_dummy/src/arch/e906fdp/startup.S + ${CMAKE_CURRENT_LIST_DIR}/components/chip_riscv_dummy/src/arch/e906fdp/vectors.S + ${CMAKE_CURRENT_LIST_DIR}/components/chip_riscv_dummy/src/arch/e906fdp/system.c + ${CMAKE_CURRENT_LIST_DIR}/components/chip_riscv_dummy/src/arch/e906fdp/trap_c.c + ${CMAKE_CURRENT_LIST_DIR}/components/chip_riscv_dummy/src/drivers/dw_uart_ll.c + ${CMAKE_CURRENT_LIST_DIR}/components/chip_riscv_dummy/src/drivers/uart.c + ${CMAKE_CURRENT_LIST_DIR}/components/chip_riscv_dummy/src/sys/devices.c + ${CMAKE_CURRENT_LIST_DIR}/components/chip_riscv_dummy/src/sys/feature.c + ${CMAKE_CURRENT_LIST_DIR}/components/chip_riscv_dummy/src/sys/irq_port.c + ${CMAKE_CURRENT_LIST_DIR}/components/chip_riscv_dummy/src/sys/irq.c + ${CMAKE_CURRENT_LIST_DIR}/components/chip_riscv_dummy/src/sys/pre_main.c + ${CMAKE_CURRENT_LIST_DIR}/components/chip_riscv_dummy/src/sys/sys_clk.c + ${CMAKE_CURRENT_LIST_DIR}/components/chip_riscv_dummy/src/sys/target_get.c + ${CMAKE_CURRENT_LIST_DIR}/components/chip_riscv_dummy/src/sys/tick.c + ${CMAKE_CURRENT_LIST_DIR}/components/chip_riscv_dummy/src/sys/weak.c +) + +include_directories( + ${CMAKE_CURRENT_LIST_DIR}/../../../../../../common/inc + ${CMAKE_CURRENT_LIST_DIR}/../../inc + ${CMAKE_CURRENT_LIST_DIR} + ${CMAKE_CURRENT_LIST_DIR}/boards/board_riscv_dummy/include + ${CMAKE_CURRENT_LIST_DIR}/components/csi/csi2/include + ${CMAKE_CURRENT_LIST_DIR}/components/libc_threadx/include + ${CMAKE_CURRENT_LIST_DIR}/components/libc_threadx/compilers/gcc + ${CMAKE_CURRENT_LIST_DIR}/components/chip_riscv_dummy/include + ${CMAKE_CURRENT_LIST_DIR}/components/chip_riscv_dummy/include/asm +) + +add_compile_options( + -Os -g -Wno-main + -Wpointer-arith -Wno-undef -ffunction-sections -fdata-sections -fno-inline-functions -fno-builtin -fno-strict-aliasing + -DCONFIG_SUPPORT_TSPEND=1 + -DCONFIG_ARCH_MAINSTACK=4096 + -DCONFIG_ARCH_INTERRUPTSTACK=4096 + -DCONFIG_SUPPORT_IRQ_NESTED=1 + -DCONFIG_INTC_CLIC=1 + -DCONFIG_INTC_CLINT=1 + -DCONFIG_XIP=1 + -DCONFIG_LIBC_MINI_PRINTF_SUPPORT=1 + -DCONFIG_SYSTICK_HZ=100 + -DCONFIG_BOARD_SMARTL_EVB=1 + -DCONFIG_CPU_XUANTIE_E906FDP=1 + -DCONFIG_KERNEL_THREADX=1 + -DTX_INCLUDE_USER_DEFINE_FILE +) + +add_link_options( + -nostartfiles -Wl,--gc-sections + -T${CMAKE_CURRENT_LIST_DIR}/components/chip_riscv_dummy/gcc_flash_smartl.ld + -Wl,-zmax-page-size=1024 + -Wl,-Map=${PROJECT_NAME}.map +) + +link_directories(${CMAKE_CURRENT_LIST_DIR}/../../../../../../build) +add_executable(${PROJECT_NAME} ${SRCS}) +set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "${PROJECT_NAME}.elf") +target_link_libraries(${PROJECT_NAME} PRIVATE threadx) + +add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${OBJDUMP} -d $ > ${PROJECT_NAME}.asm + COMMENT "Generating ASM disassembly files" +) \ No newline at end of file diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/boards/board_riscv_dummy/include/board.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/boards/board_riscv_dummy/include/board.h new file mode 100644 index 00000000..6d5b756c --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/boards/board_riscv_dummy/include/board.h @@ -0,0 +1,444 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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. + */ + +/* + This is an example board.h for Board Compment, New Board should flow the macro defines. +*/ + +#ifndef __BOARD_H__ +#define __BOARD_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Common Board Features Define + +/* + The Common BOARD_XXX Macro Defines Boards supported features which may reference by Solutions. + Common board macro include: + . BOARD_NAME + · UART + · GPIO + · PWM + · ADC + · BUTTON + · LED + · WIFI + · BT + · AUDIO + BOARD_XXX Macro descripted below should be defined if the board support. +*/ + +/****************************************************************************/ + +/* + This riscv dummy board include: + · UART x1 + · GPIO x2 + · PWM x2 + · ADC x1 + · BUTTON x2 + · LED x2 + · WIFI x0 + · BT x0 + · AUDIO x1 +*/ + +#ifndef CONFIG_BOARD_UART +#define CONFIG_BOARD_UART 1 +#endif + +#ifndef CONFIG_BOARD_GPIO +#define CONFIG_BOARD_GPIO 0 +#endif + +#ifndef CONFIG_BOARD_PWM +#define CONFIG_BOARD_PWM 0 +#endif + +#ifndef CONFIG_BOARD_ADC +#define CONFIG_BOARD_ADC 0 +#endif + +#ifndef CONFIG_BOARD_BUTTON +#define CONFIG_BOARD_BUTTON 0 +#endif + +#ifndef CONFIG_BOARD_LED +#define CONFIG_BOARD_LED 0 +#endif + +#ifndef CONFIG_BOARD_WIFI +#define CONFIG_BOARD_WIFI 0 +#endif + +#ifndef CONFIG_BOARD_BT +#define CONFIG_BOARD_BT 0 +#endif + +#ifndef CONFIG_BOARD_AUDIO +#define CONFIG_BOARD_AUDIO 0 +#endif + +#define BOARD_NAME "RISCV_DUMMY" + +/* the board pins, can be used as uart, gpio, pwd... */ +#define BOARD_PIN0 (0) +#define BOARD_PIN1 (1) +#define BOARD_PIN2 (2) +#define BOARD_PIN3 (3) +#define BOARD_PIN4 (4) +#define BOARD_PIN5 (5) +#define BOARD_PIN6 (6) +#define BOARD_PIN7 (7) +#define BOARD_PIN8 (8) +#define BOARD_PIN9 (9) +#define BOARD_PIN10 (10) +#define BOARD_PIN11 (11) +#define BOARD_PIN12 (12) +//... + +#if defined(CONFIG_BOARD_UART) && CONFIG_BOARD_UART +// UART + +/* + The total supported uart numbers on this board, 0 meas No uart support. + the BOARD_UART_XXX, x in rang of (0, BOARD_UART_NUM - 1) +*/ +#ifndef BOARD_UART_NUM +#define BOARD_UART_NUM (1) +#endif + +#if defined(BOARD_UART_NUM) && BOARD_UART_NUM > 0 +/* the board uart0 tx pin */ +#define BOARD_UART0_TX_PIN (BOARD_PIN0) +/* the borad uart0 rx pin */ +#define BOARD_UART0_RX_PIN (BOARD_PIN1) +/* The real UART port reference to board logic port 0 */ +#define BOARD_UART0_IDX (0) +/* The default baudrate for uart0 */ +#define BOARD_UART0_BAUD (115200) + +//#define BOARD_UART1_IDX (1) +//#define BOARD_UART1_BAUD (115200) +// ... +#endif // defined(BOARD_UART_NUM) && BOARD_UART_NUM > 0 + +#endif // defined(CONFIG_BOARD_UART) && CONFIG_BOARD_UART + +#if defined(CONFIG_BOARD_GPIO) && CONFIG_BOARD_GPIO +// GPIO +/* + The total supported GPIO Pin numbers on this board, 0 meas No uart support. + the BOARD_GPIO_PIN, x in rang of (0, BOARD_GPIO_PIN_NUM - 1) +*/ +#ifndef BOARD_GPIO_PIN_NUM +#define BOARD_GPIO_PIN_NUM (2) +#endif + +#if defined(BOARD_GPIO_PIN_NUM) && BOARD_GPIO_PIN_NUM > 0 +/* The real gpio reference to board logic gpio pin */ +#define BOARD_GPIO_PIN0 (BOARD_PIN2) +#define BOARD_GPIO_PIN1 (BOARD_PIN3) +//#define BOARD_GPIO_PIN2 (x) +//#define BOARD_GPIO_PIN3 (x) +#endif // defined(BOARD_GPIO_PIN_NUM) && BOARD_GPIO_PIN_NUM > 0 +#endif // defined(CONFIG_BOARD_GPIO) && CONFIG_BOARD_GPIO + +#if defined(CONFIG_BOARD_PWM) && CONFIG_BOARD_PWM +// PWM +/* the board supported pwm channels */ +#ifndef BOARD_PWM_NUM +#define BOARD_PWM_NUM (2) +#endif + +#if defined(BOARD_PWM_NUM) && BOARD_PWM_NUM > 0 +/* the board pwm pin */ +#define BOARD_PWM0_PIN (BOARD_PIN4) +/* The real pwm channel reference to board logic pwm channel */ +#define BOARD_PWM0_CH (0) + +#define BOARD_PWM1_PIN (BOARD_PIN5) +#define BOARD_PWM1_CH (1) +#endif // defined(BOARD_PWM_NUM) && BOARD_PWM_NUM > 0 +#endif // defined(CONFIG_BOARD_PWM) && CONFIG_BOARD_PWM + +#if defined(CONFIG_BOARD_ADC) && CONFIG_BOARD_ADC > 0 +// ADC +/* the board supported adc channels */ +#ifndef BOARD_ADC_NUM +#define BOARD_ADC_NUM (1) +#endif + +#if defined(BOARD_ADC_NUM) && BOARD_ADC_NUM > 0 +/* the board adc pin */ +#define BOARD_ADC0_PIN (BOARD_PIN6) +/* The real adc channel reference to board logic adc channel */ +#define BOARD_ADC0_CH (0) +#endif // defined(BOARD_ADC_NUM) && BOARD_ADC_NUM > 0 +#endif // defined(CONFIG_BOARD_ADC) && CONFIG_BOARD_ADC > 0 + +#if defined(CONFIG_BOARD_BUTTON) && CONFIG_BOARD_BUTTON > 0 +// BUTTON +#ifndef BOARD_BUTTON_NUM +/* + the board supported buttons, include gpio button and adc button, + BOARD_BUTTON_NUM = BOARD_BUTTON_GPIO_NUM + BOARD_BUTTON_ADC_NUM. + +*/ +#define BOARD_BUTTON_NUM (4) +#endif + +#if defined(BOARD_BUTTON_NUM) && BOARD_BUTTON_NUM > 0 + +#define BOARD_BUTTON0_PIN (BOARD_PIN7) +#define BOARD_BUTTON1_PIN (BOARD_PIN8) +#define BOARD_BUTTON2_PIN (BOARD_PIN9) +#define BOARD_BUTTON3_PIN (BOARD_PIN10) + +// GPIO BUTTON +/* the board supported GPIO Buttons */ +#ifndef BOARD_BUTTON_GPIO_NUM +#define BOARD_BUTTON_GPIO_NUM (2) +#endif + +#if defined(BOARD_BUTTON_GPIO_NUM) && BOARD_BUTTON_GPIO_NUM > 0 +/* the board logic button id, in range of (0, BOARD_BUTTON_GPIO_NUM - 1) */ +#define BOARD_BUTTON0 (0) +/* for gpio button, define the pin numner. if the gpio pin used as gpio button, it shoudn't reference as BOARD_GPIO_PINx + */ +#define BOARD_BUTTON0_GPIO_PIN (BOARD_BUTTON0_PIN) + +#define BOARD_BUTTON1 (1) +#define BOARD_BUTTON1_GPIO_PIN (BOARD_BUTTON1_PIN) +#endif // defined(BOARD_BUTTON_GPIO_NUM) && BOARD_BUTTON_GPIO_NUM > 0 + +// ADC BUTTON +/* the board supported adc Buttons */ +#ifndef BOARD_BUTTON_ADC_NUM +#define BOARD_BUTTON_ADC_NUM (2) +#endif + +#if defined(BOARD_BUTTON_ADC_NUM) && BOARD_BUTTON_ADC_NUM > 0 +/* the board logic adc button id, in range of (BOARD_BUTTON_GPIO_NUM, BOARD_BUTTON_NUM - 1), if not suuport GPIO Button, + * BOARD_BUTTON_GPIO_NUM should be 0 */ +#define BOARD_BUTTON2 (BOARD_BUTTON_GPIO_NUM + 0) +#define BOARD_BUTTON2_ADC_PIN (BOARD_BUTTON2_PIN) +/* the adc channel used for button2, if the adc channel used as adc button, it shoudn't reference as BOARD_ADCx_CH*/ +#define BOARD_BUTTON2_ADC_CH (1) +/* the adc device name */ +#define BOARD_BUTTON2_ADC_NAME "adc1" +/* adc voltage reference */ +#define BOARD_BUTTON2_ADC_REF (100) +/* adc voltage range */ +#define BOARD_BUTTON2_ADC_RANG (500) + +#define BOARD_BUTTON3 (BOARD_BUTTON_GPIO_NUM + 1) +#define BOARD_BUTTON3_ADC_PIN (BOARD_BUTTON3_PIN) +#define BOARD_BUTTON3_ADC_CH (1) +#define BOARD_BUTTON3_ADC_NAME "adc1" +#define BOARD_BUTTON3_ADC_REF (600) +#define BOARD_BUTTON3_ADC_RANG (500) + +//#define BOARD_ADC_BUTTON2 (2) +//#define BOARD_ADC_BUTTON2_CH (1) +//#define BOARD_ADC_BUTTON2_NAME "adc1" +//#define BOARD_ADC_BUTTON2_REF xxx +//#define BOARD_ADC_BUTTON2_RANG xxx +#endif // defined(BOARD_BUTTON_ADC_NUM) && BOARD_BUTTON_ADC_NUM > 0 + +#endif // defined(BOARD_BUTTON_NUM) && BOARD_BUTTON_NUM > 0 + +#endif // defined(BOARD_BUTTON_NUM) && BOARD_BUTTON_NUM > 0 + +#if defined(CONFIG_BOARD_LED) && CONFIG_BOARD_LED > 0 +// LED +/* the board supported leds */ +#ifndef BOARD_LED_NUM +#define BOARD_LED_NUM (2) +#endif + +#define BOARD_LED0_PIN BOARD_PIN11 +#define BOARD_LED1_PIN BOARD_PIN12 + +// PWM LED +/* the board supported pwm leds */ +#ifndef BOARD_LED_PWM_NUM +#define BOARD_LED_PWM_NUM (1) +#endif + +#if defined(BOARD_LED_PWM_NUM) && BOARD_LED_PWM_NUM > 0 +#define BOARD_LED0_PWM_PIN (BOARD_LED0_PIN) +/* the pwm channel used for led0, if the pwm channel used as led0, it shoudn't reference as BOARD_PWMx_CH */ +#define BOARD_LED0_PWM_CH (0) +#endif // defined(BOARD_LED_PWM_NUM) && BOARD_LED_PWM_NUM > 0 + +// GPIO LED +#ifndef BOARD_LED_GPIO_NUM +#define BOARD_LED_GPIO_NUM (1) +#endif + +#if defined(BOARD_LED_GPIO_NUM) && BOARD_LED_GPIO_NUM > 0 +/* the gpio pin used for led0, if the gpio pin used as led, it shoudn't reference as BOARD_GPIO_PINx */ +#define BOARD_LED1_GPIO_PIN (BOARD_LED1_PIN) +#endif // defined(BOARD_LED_GPIO_NUM) && BOARD_LED_GPIO_NUM > 0 +#endif // defined(CONFIG_BOARD_LED) && CONFIG_BOARD_LED > 0 + +#if defined(CONFIG_BOARD_BT) && CONFIG_BOARD_BT > 0 +// BT +/* the board support bluetooth */ +#ifndef BOARD_BT_SUPPORT +#define BOARD_BT_SUPPORT 1 +#endif +#endif // defined(CONFIG_BOARD_BT) && CONFIG_BOARD_BT > 0 + +#if defined(CONFIG_BOARD_WIFI) && CONFIG_BOARD_WIFI > 0 +// WIFI +/* the board support wifi */ +#ifndef BOARD_WIFI_SUPPORT +#define BOARD_WIFI_SUPPORT 1 +#endif +#endif // defined(CONFIG_BOARD_WIFI) && CONFIG_BOARD_WIFI > 0 + +#if defined(CONFIG_BOARD_AUDIO) && CONFIG_BOARD_AUDIO > 0 +// Audio +/* the board support audio */ +#ifndef BOARD_AUDIO_SUPPORT +#define BOARD_AUDIO_SUPPORT 1 +#endif +#endif // defined(CONFIG_BOARD_AUDIO) && CONFIG_BOARD_AUDIO > 0 + +/****************************************************************************/ +// Common solutions defines + +// Console config, Almost all solutions and demos use these. +#ifndef CONSOLE_UART_IDX +#define CONSOLE_UART_IDX (BOARD_UART0_IDX) +#endif + +#ifndef CONFIG_CLI_USART_BAUD +#define CONFIG_CLI_USART_BAUD (BOARD_UART0_BAUD) +#endif + +#ifndef CONFIG_CONSOLE_UART_BUFSIZE +#define CONFIG_CONSOLE_UART_BUFSIZE (128) +#endif + +/****************************************************************************/ +// Commom test demos defines + +// i2c +#define EXAMPLE_IIC_IDX 0 // 1 +#define EXAMPLE_PIN_IIC_SDA 0 // PC1 +#define EXAMPLE_PIN_IIC_SCL 0 // PC0 +#define EXAMPLE_PIN_IIC_SDA_FUNC 0 // PC1_I2C1_SDA +#define EXAMPLE_PIN_IIC_SCL_FUNC 0 // PC0_I2C1_SCL + +// adc +#define EXAMPLE_ADC_CH0 0 // PA8 +#define EXAMPLE_ADC_CH0_FUNC 0 // PA8_ADC_A0 +#define EXAMPLE_ADC_CH12 0 // PA26 +#define EXAMPLE_ADC_CH12_FUNC 0 // PA26_ADC_A12 + +#define EXAMPLE_TIMER_IDX 0 + +/****************************************************************************/ +// Vendor board defines + +/* other board specific defines */ +//#define CUSTOM_BOARD_xxx + +/****************************************************************************/ +/** + * @brief init the board for default: pin mux, etc. + * re-implement if need. + * @return + */ +void board_init(void); + +/** + * @brief init the board gpio pin for default: pin mux, etc. + * re-implement if need. + * @return + */ +void board_gpio_pin_init(void); + +/** + * @brief init the board uart for default: pin mux, etc. + * re-implement if need. + * @return + */ +void board_uart_init(void); + +/** + * @brief init the board pwm for default: pin mux, etc. + * re-implement if need. + * @return + */ +void board_pwm_init(void); + +/** + * @brief init the board adc for default: pin mux, etc. + * re-implement if need. + * @return + */ +void board_adc_init(void); + +/** + * @brief init the board button for default: pin mux, etc. + * re-implement if need. + * @return + */ +void board_button_init(void); + +/** + * @brief init the board led for default: pin mux, etc. + * re-implement if need. + * @return + */ +void board_led_init(void); + +/** + * @brief init the board wifi for default: pin mux, etc. + * re-implement if need. + * @return + */ +void board_wifi_init(void); + +/** + * @brief init the board bt for default: pin mux, etc. + * re-implement if need. + * @return + */ +void board_bt_init(void); + +/** + * @brief init the board audio for default: pin mux, etc. + * re-implement if need. + * @return + */ +void board_audio_init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __BOARD_H__ */ \ No newline at end of file diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/boards/board_riscv_dummy/include/csi_config.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/boards/board_riscv_dummy/include/csi_config.h new file mode 100644 index 00000000..8e1af58f --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/boards/board_riscv_dummy/include/csi_config.h @@ -0,0 +1,26 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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. + */ + +#ifndef __CSI_CONFIG_H__ +#define __CSI_CONFIG_H__ + + + + + +#endif /* __CSI_CONFIG_H__ */ \ No newline at end of file diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/boards/board_riscv_dummy/src/board_init.c b/ports/xuantie/e906/gnu/example_build/smartl_fpga/boards/board_riscv_dummy/src/board_init.c new file mode 100644 index 00000000..b994f6ce --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/boards/board_riscv_dummy/src/board_init.c @@ -0,0 +1,83 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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. + */ + +#include +#include +#include + +void board_init(void) +{ + /* some board preconfig */ + // board_xxx(); + +#if defined(BOARD_GPIO_PIN_NUM) && BOARD_GPIO_PIN_NUM > 0 + board_gpio_pin_init(); +#endif + +#if defined(BOARD_UART_NUM) && BOARD_UART_NUM > 0 +#if !defined(RT_DEBUG_INIT) || !RT_DEBUG_INIT + board_uart_init(); +#endif +#endif + +#if defined(BOARD_PWM_NUM) && BOARD_PWM_NUM > 0 + board_pwm_init(); +#endif + +#if defined(BOARD_ADC_NUM) && BOARD_ADC_NUM > 0 + board_adc_init(); +#endif + +#if defined(BOARD_BUTTON_NUM) && BOARD_BUTTON_NUM > 0 + board_button_init(); +#endif + +#if defined(BOARD_LED_NUM) && BOARD_LED_NUM > 0 + board_led_init(); +#endif + +#if defined(BOARD_WIFI_SUPPORT) && BOARD_WIFI_SUPPORT > 0 + board_wifi_init(); +#endif + +#if defined(BOARD_BT_SUPPORT) && BOARD_BT_SUPPORT > 0 + board_bt_init(); +#endif + +#if defined(BOARD_AUDIO_SUPPORT) && BOARD_AUDIO_SUPPORT > 0 + board_audio_init(); +#endif +} + +#ifdef CONFIG_KERNEL_THREADX +#include + +extern unsigned long g_heap_start; +extern unsigned long g_heap_end; + +TX_BYTE_POOL tx_byte_pool_0; +UCHAR *tx_memory_area; + +void tx_mem_pool_init(void) +{ + ULONG pool_size = g_heap_end - g_heap_start; + tx_memory_area = (UCHAR *)g_heap_start; + + tx_byte_pool_create(&tx_byte_pool_0, "byte pool sys 0", tx_memory_area, pool_size); +} +#endif diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/boards/board_riscv_dummy/src/uart/board_uart.c b/ports/xuantie/e906/gnu/example_build/smartl_fpga/boards/board_riscv_dummy/src/uart/board_uart.c new file mode 100644 index 00000000..315e3aed --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/boards/board_riscv_dummy/src/uart/board_uart.c @@ -0,0 +1,45 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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. + */ + +#include +#include +#include +#if CONFIG_DEVICES_RVM_HAL +#include +#else +#include +#endif + +#if CONFIG_DEVICES_RVM_HAL +void board_uart_init(void) +{ + rvm_uart_drv_register(0); +} +#else +__attribute__((weak)) csi_uart_t g_console_handle; + +void board_uart_init(void) +{ + /* init the console */ + csi_uart_init(&g_console_handle, CONSOLE_UART_IDX); + + /* config the UART */ + csi_uart_baud(&g_console_handle, CONFIG_CLI_USART_BAUD); + csi_uart_format(&g_console_handle, UART_DATA_BITS_8, UART_PARITY_NONE, UART_STOP_BITS_1); +} +#endif diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/build_libthreadx.sh b/ports/xuantie/e906/gnu/example_build/smartl_fpga/build_libthreadx.sh new file mode 100755 index 00000000..2f35e09e --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/build_libthreadx.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +pushd ../../../../../../ +rm -rf build +cmake -Bbuild -GNinja -DCMAKE_TOOLCHAIN_FILE=ports/xuantie/e906/gnu/example_build/smartl_fpga/xuantie_e906_gnu.cmake . +cmake --build ./build/ +popd diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/build_threadx_sample.sh b/ports/xuantie/e906/gnu/example_build/smartl_fpga/build_threadx_sample.sh new file mode 100755 index 00000000..ec91e36a --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/build_threadx_sample.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +bash build_libthreadx.sh + +rm -rf build +cmake -Bbuild -GNinja -DCMAKE_TOOLCHAIN_FILE=xuantie_e906_gnu.cmake . +cmake --build ./build/ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/gcc_flash_smartl.ld b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/gcc_flash_smartl.ld new file mode 100644 index 00000000..3cfad67d --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/gcc_flash_smartl.ld @@ -0,0 +1,177 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 gcc_csky.ld + * @brief csky linker file + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +MEMORY +{ + ISRAM : ORIGIN = 0x00000000 , LENGTH = 0x30000 /* ISRAM 192KB*/ + DSRAM : ORIGIN = 0x20000000 , LENGTH = 0xC0000 /* DSRAM 768KB*/ + SRAM : ORIGIN = 0x60000000 , LENGTH = 0x20000 /* SRAM 128KB, no cacheable*/ +} + +__min_heap_size = 0x200; +PROVIDE (__ram_end = 0x200C0000); +PROVIDE (__heap_end = __ram_end); + +REGION_ALIAS("REGION_TEXT", ISRAM); +REGION_ALIAS("REGION_RODATA", ISRAM); +REGION_ALIAS("REGION_DATA", DSRAM); +REGION_ALIAS("REGION_BSS", DSRAM); + +ENTRY(Reset_Handler) +SECTIONS +{ + .text : { + . = ALIGN(0x4) ; + __stext = . ; + KEEP(*startup.o(*.text)) + KEEP(*startup.o(*.vectors)) + KEEP(*vectors.o(*.text)) + KEEP(*whetstone.o(*.text)) + KEEP(*startup.S.obj(*.text)) + KEEP(*startup.S.obj(*.vectors)) + KEEP(*vectors.S.obj(*.text)) + KEEP(*whetstone.c.obj(*.text)) + KEEP(*(.text.entry)) + *(.text*) + *(.gnu.warning) + *(.stub) + *(.gnu.linkonce.t*) + *(.glue_7t) + *(.glue_7) + *(.jcr) + KEEP (*(.init)) + KEEP (*(.fini)) + . = ALIGN (0x4) ; + PROVIDE(__ctbp = .); + *(.call_table_data) + *(.call_table_text) + . = ALIGN(0x10) ; + __etext = . ; + } > REGION_TEXT + .eh_frame_hdr : { + *(.eh_frame_hdr) + } > REGION_TEXT + .eh_frame : ONLY_IF_RO { + KEEP (*(.eh_frame)) + } > REGION_TEXT + .rodata : { + . = ALIGN(0x4) ; + __srodata = .; + *(.rdata) + *(.rdata*) + *(.rdata1) + *(.rdata.*) + *(.rodata*) + *(.srodata*) + . = ALIGN(0x4) ; + __init_array_start = .; + __ctors_start__ = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + __ctors_end__ = .; + + __fini_array_start = .; + __dtors_start__ = .; + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array)) + __fini_array_end = .; + __dtors_end__ = .; + . = ALIGN(0x4) ; + + __ctor_start__ = .; + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + __ctor_end__ = .; + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + __dtor_end__ = .; + . = ALIGN(0x4) ; + __erodata = .; + __rodata_end__ = .; + } > REGION_RODATA + .data : { + . = ALIGN(0x4) ; + __sdata = . ; + __data_start__ = . ; + data_start = . ; + *(.got.plt) + *(.got) + *(.gnu.linkonce.r*) + *(.data*) + *(.gnu.linkonce.d*) + *(.gcc_except_table*) + __start_init_call = .; + *(.initcall.init) + __stop_init_call = .; + __start_cmd = .; + *(.bootloaddata.cmd) + . = ALIGN(0x4) ; + __stop_cmd = .; + __global_pointer$ = .; + *(.sdata) + *(.sdata.*) + *(.sdata2.*) + *(.gnu.linkonce.s.*) + *(__libc_atexit) + *(__libc_subinit) + *(__libc_subfreeres) + *(.note.ABI-tag) + . = ALIGN(0x4) ; + __edata = .; + __data_end__ = .; + } > REGION_DATA AT > REGION_RODATA + ._ram_code : { + . = ALIGN(0x4) ; + __ram_code_start__ = .; + *(.ram.code*) + . = ALIGN(0x4) ; + __ram_code_end__ = .; + } > REGION_DATA AT > REGION_RODATA + .bss : ALIGN(0x20) { + __sbss = . ; + __bss_start__ = . ; + KEEP(*linpack.o(*.bss*)) + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.scommon) + *(.dynbss) + *(.bss*) + *(COMMON) + . = ALIGN(0x4) ; + __ebss = . ; + __bss_end__ = .; + __end = . ; + end = . ; + } > REGION_BSS AT > REGION_BSS + ._user_heap (NOLOAD): { + . = ALIGN(0x4) ; + *(.stack*) + . = ALIGN(0x4) ; + __heap_start = .; + . += __min_heap_size; + . = ALIGN(0x4) ; + } > REGION_BSS AT > REGION_BSS +} diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/include/asm/riscv_asm_macro.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/include/asm/riscv_asm_macro.h new file mode 100644 index 00000000..dfa08578 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/include/asm/riscv_asm_macro.h @@ -0,0 +1,538 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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. + */ + +/* + * attention: don't modify this file as a suggest + * you should copy from chip_riscv_dummy/include/asm/riscv_asm_macro.h and keep it newer + * please contact xuantie-rtos os team if have question + */ + +#ifndef __RISCV_ASM_MACRO_H__ +#define __RISCV_ASM_MACRO_H__ + + +#include "riscv_csr.h" + +.macro RESTORE_xSTATUS + /* t0 and t1 are not restored before using */ + /* now, sp is at the top of the stack (the lowest address)*/ + li t1, 0 +#if __riscv_matrix || __riscv_xtheadmatrix /* matrix registers */ +#if __riscv_xlen == 64 + addi t1, t1, (12 + 12) +#else + addi t1, t1, 12 +#endif /*__riscv_xlen */ + csrr t0, xmlenb + slli t0, t0, 3 + add t1, t1, t0 +#endif /* __riscv_matrix || __riscv_xtheadmatrix */ + +#ifdef __riscv_vector /* vector registers */ + csrr t0, vlenb + slli t0, t0, 5 + add t1, t1, t0 +#if __riscv_xlen == 64 + addi t1, t1, (20+20) +#else + addi t1, t1, 20 +#endif /* __riscv_xlen */ +#endif /* __riscv_vector */ + +#if __riscv_flen == 64 /* float registers */ +#if __riscv_xlen == 64 + addi t1, t1, 168 +#else + addi t1, t1, 164 +#endif /* __riscv_xlen */ + +#elif __riscv_flen == 32 + addi t1, t1, 84 +#endif /* __riscv_flen */ + +#ifdef __riscv_dsp /* vxsat register, 32-bit cpu only */ + addi t1, t1, 4 +#endif /* __riscv_dsp */ + +#if __riscv_xlen == 64 /*general purpose registers*/ + addi t1, t1, (72 + 72) +#elif __riscv_xlen == 32 + addi t1, t1, 72 +#endif + add t1, sp, t1 + + /* now, t1 is the position of mstatus */ + load_x t3, (0)(t1) + csrw MODE_PREFIX(status), t3 +.endm + +.macro SAVE_VECTOR_REGISTERS + /* t0,t1 saved before using */ + /* mstatus->t3 */ +#ifdef __riscv_vector +#if CONFIG_CHECK_VECTOR_DIRTY + /* check if VS filed of MSTATUS is 'dirty' */ + li t1, SR_VS_DIRTY + and t4, t3, t1 + bne t4, t1, 1f +#endif /* CONFIG_CHECK_VECTOR_DIRTY */ + + /* if dirty, save vector registers */ +#if __riscv_xlen == 64 + addi sp, sp, -(20+20) + csrr t0, vl + store_x t0, (0 +0 )(sp) + csrr t0, vtype + store_x t0, (4 +4 )(sp) + csrr t0, vstart + store_x t0, (8 +8 )(sp) + csrr t0, vxsat + store_x t0, (12 +12 )(sp) + csrr t0, vxrm + store_x t0, (16 +16 )(sp) +#else + addi sp, sp, -20 + csrr t0, vl + store_x t0, (0)(sp) + csrr t0, vtype + store_x t0, (4)(sp) + csrr t0, vstart + store_x t0, (8)(sp) + csrr t0, vxsat + store_x t0, (12)(sp) + csrr t0, vxrm + store_x t0, (16)(sp) +#endif /*__riscv_xlen */ + + csrr t0, vlenb + slli t0, t0, 3 + slli t1, t0, 2 + sub sp, sp, t1 +#if (__riscv_v == 7000) + vsetvli zero, zero, e8, m8 + vsb.v v0, (sp) + add sp, sp, t0 + vsb.v v8, (sp) + add sp, sp, t0 + vsb.v v16, (sp) + add sp, sp, t0 + vsb.v v24, (sp) +#elif (__riscv_v == 1000000) + vsetvli zero, zero, e8, m8, ta, ma + vs8r.v v0, (sp) + add sp, sp, t0 + vs8r.v v8, (sp) + add sp, sp, t0 + vs8r.v v16, (sp) + add sp, sp, t0 + vs8r.v v24, (sp) +#endif + sub t0, t1, t0 + sub sp, sp, t0 +#if CONFIG_CHECK_VECTOR_DIRTY + j 2f +1: /* don't need to save vector registers, set sp */ +#if __riscv_xlen == 64 + addi sp, sp, -(20+20) +#else + addi sp, sp, -20 +#endif + csrr t0, vlenb + slli t0, t0, 5 + sub sp, sp, t0 +2: +#endif /* CONFIG_CHECK_VECTOR_DIRTY */ +#endif /*__riscv_vector*/ +.endm + +.macro RESTORE_VECTOR_REGISTERS + /* t0,t1,t2 not restored before using, mstatus has been restored before using */ +#ifdef __riscv_vector +#if CONFIG_CHECK_VECTOR_DIRTY + /* check if VS filed of MSTATUS is 'dirty' */ + li t1, SR_VS_DIRTY + and t4, t3, t1 + bne t4, t1, 1f +#endif /* CONFIG_CHECK_VECTOR_DIRTY */ + + /* get the range of register */ + csrr t0, vlenb + slli t0, t0, 3 + + /* save */ +#if (__riscv_v == 7000) + vsetvli zero, zero, e8, m8 + vlb.v v0, (sp) + add sp, sp, t0 + vlb.v v8, (sp) + add sp, sp, t0 + vlb.v v16, (sp) + add sp, sp, t0 + vlb.v v24, (sp) + add sp, sp, t0 +#elif (__riscv_v == 1000000) + vsetvli zero, zero, e8, m8, ta, ma + vl8r.v v0, (sp) + add sp, sp, t0 + vl8r.v v8, (sp) + add sp, sp, t0 + vl8r.v v16, (sp) + add sp, sp, t0 + vl8r.v v24, (sp) + add sp, sp, t0 +#endif +#if __riscv_xlen == 64 + load_x t0, (0 +0)(sp) + load_x t1, (4 +4)(sp) + load_x t2, (8 +8)(sp) + vsetvl zero, t0, t1 + csrw vstart, t2 + load_x t2, (12 +12)(sp) + csrw vxsat, t2 + load_x t2, (16 +16)(sp) + csrw vxrm, t2 + addi sp, sp, (20+20) +#else + load_x t0, (0)(sp) + load_x t1, (4)(sp) + load_x t2, (8)(sp) + vsetvl zero, t0, t1 + csrw vstart, t2 + load_x t2, (12)(sp) + csrw vxsat, t2 + load_x t2, (16)(sp) + csrw vxrm, t2 + addi sp, sp, 20 +#endif /*__riscv_xlen */ +#if CONFIG_CHECK_VECTOR_DIRTY + j 2f +1: + /* don't restore, move sp only */ +#if __riscv_xlen == 64 + addi sp, sp, (20+20) +#else + addi sp, sp, (20) +#endif + csrr t0, vlenb + slli t0, t0, 5 + add sp, sp, t0 +2: +#endif /* CONFIG_CHECK_VECTOR_DIRTY */ +#endif /*__riscv_vector*/ +.endm + + +.macro SAVE_FLOAT_REGISTERS + /* t0, t1 saved before using */ +#if __riscv_flen == 64 +#if CONFIG_CHECK_FPU_DIRTY + /* check if FS filed of MSTATUS is 'dirty' */ + li t1, SR_FS_DIRTY + and t4, t3, t1 + bne t4, t1, 1f +#endif /*CONFIG_CHECK_FPU_DIRTY*/ + + /* save */ +#if __riscv_xlen == 64 + addi sp, sp, -(4+4) + frcsr t0 + store_x t0, (0 +0 )(sp) +#else + addi sp, sp, -4 + frcsr t0 + store_x t0, 0(sp) +#endif /*__riscv_xlen */ + + addi sp, sp, -160 + fstore_x ft0, (0 +0 )(sp) + fstore_x ft1, (4 +4 )(sp) + fstore_x ft2, (8 +8 )(sp) + fstore_x ft3, (12+12)(sp) + fstore_x ft4, (16+16)(sp) + fstore_x ft5, (20+20)(sp) + fstore_x ft6, (24+24)(sp) + fstore_x ft7, (28+28)(sp) + fstore_x fa0, (32+32)(sp) + fstore_x fa1, (36+36)(sp) + fstore_x fa2, (40+40)(sp) + fstore_x fa3, (44+44)(sp) + fstore_x fa4, (48+48)(sp) + fstore_x fa5, (52+52)(sp) + fstore_x fa6, (56+56)(sp) + fstore_x fa7, (60+60)(sp) + fstore_x ft8, (64+64)(sp) + fstore_x ft9, (68+68)(sp) + fstore_x ft10,(72+72)(sp) + fstore_x ft11,(76+76)(sp) +#elif __riscv_flen == 32 +#if CONFIG_CHECK_FPU_DIRTY + /* check if FS filed of MSTATUS is 'dirty' */ + li t1, SR_FS_DIRTY + and t4, t3, t1 + bne t4, t1, 1f +#endif /* CONFIG_CHECK_FPU_DIRTY */ + + addi sp, sp, -4 + frcsr t0 + store_x t0, 0(sp) + + addi sp, sp, -80 + fstore_x ft0, 0(sp) + fstore_x ft1, 4(sp) + fstore_x ft2, 8(sp) + fstore_x ft3, 12(sp) + fstore_x ft4, 16(sp) + fstore_x ft5, 20(sp) + fstore_x ft6, 24(sp) + fstore_x ft7, 28(sp) + fstore_x fa0, 32(sp) + fstore_x fa1, 36(sp) + fstore_x fa2, 40(sp) + fstore_x fa3, 44(sp) + fstore_x fa4, 48(sp) + fstore_x fa5, 52(sp) + fstore_x fa6, 56(sp) + fstore_x fa7, 60(sp) + fstore_x ft8, 64(sp) + fstore_x ft9, 68(sp) + fstore_x ft10,72(sp) + fstore_x ft11,76(sp) +#endif /*__riscv_flen */ +#if CONFIG_CHECK_FPU_DIRTY + j 2f +1: + /* don't store, move sp only */ +#if __riscv_flen == 64 +#if __riscv_xlen == 64 + addi sp, sp, -168 +#else + addi sp, sp, -164 +#endif /*__riscv_xlen */ +#elif __riscv_flen == 32 + addi sp, sp, -84 +#endif /* __riscv_xlen */ +2: +#endif +.endm + +.macro RESTORE_FLOAT_REGISTERS + /* t0 and t1 are not restored before using, mstatus has been restored before using */ +#if __riscv_flen == 64 +#if CONFIG_CHECK_FPU_DIRTY + /* check if FS filed of MSTATUS is 'dirty' */ + li t1, SR_FS_DIRTY + and t4, t3, t1 + bne t4, t1, 1f +#endif /* CONFIG_CHECK_FPU_DIRTY */ + + /* restore */ + fload_x ft0, (0 +0 )(sp) + fload_x ft1, (4 +4 )(sp) + fload_x ft2, (8 +8 )(sp) + fload_x ft3, (12+12)(sp) + fload_x ft4, (16+16)(sp) + fload_x ft5, (20+20)(sp) + fload_x ft6, (24+24)(sp) + fload_x ft7, (28+28)(sp) + fload_x fa0, (32+32)(sp) + fload_x fa1, (36+36)(sp) + fload_x fa2, (40+40)(sp) + fload_x fa3, (44+44)(sp) + fload_x fa4, (48+48)(sp) + fload_x fa5, (52+52)(sp) + fload_x fa6, (56+56)(sp) + fload_x fa7, (60+60)(sp) + fload_x ft8, (64+64)(sp) + fload_x ft9, (68+68)(sp) + fload_x ft10,(72+72)(sp) + fload_x ft11,(76+76)(sp) + addi sp, sp, 160 + +#if __riscv_xlen == 64 + load_x t0, (0 +0)(sp) + fscsr t0 + addi sp, sp, (4+4) +#else + load_x t0, 0(sp) + fscsr t0 + addi sp, sp, 4 +#endif /*__riscv_xlen */ +#elif __riscv_flen == 32 +#if CONFIG_CHECK_FPU_DIRTY + /* check if FS filed of MSTATUS is 'dirty' */ + li t1, SR_FS_DIRTY + and t4, t3, t1 + bne t4, t1, 1f +#endif /* CONFIG_CHECK_FPU_DIRTY */ + + /* restore */ + fload_x ft0, 0(sp) + fload_x ft1, 4(sp) + fload_x ft2, 8(sp) + fload_x ft3, 12(sp) + fload_x ft4, 16(sp) + fload_x ft5, 20(sp) + fload_x ft6, 24(sp) + fload_x ft7, 28(sp) + fload_x fa0, 32(sp) + fload_x fa1, 36(sp) + fload_x fa2, 40(sp) + fload_x fa3, 44(sp) + fload_x fa4, 48(sp) + fload_x fa5, 52(sp) + fload_x fa6, 56(sp) + fload_x fa7, 60(sp) + fload_x ft8, 64(sp) + fload_x ft9, 68(sp) + fload_x ft10,72(sp) + fload_x ft11,76(sp) + addi sp, sp, 80 + + load_x t0, 0(sp) + fscsr t0 + addi sp, sp, 4 +#endif /*__riscv_flen */ +#if CONFIG_CHECK_FPU_DIRTY + j 2f +1: + /* don't restore, move sp only */ +#if __riscv_flen == 64 +#if __riscv_xlen == 64 + addi sp, sp, 168 +#elif __riscv_xlen == 32 + addi sp, sp, 164 +#endif +#elif __riscv_flen == 32 + addi sp, sp, 84 +#endif /* __riscv_flen */ +2: +#endif /* CONFIG_CHECK_FPU_DIRTY */ +.endm + +.macro SAVE_MATRIX_REGISTERS + /* t0,t1 saved before using */ + +#if __riscv_matrix || __riscv_xtheadmatrix +#if CONFIG_CHECK_MATRIX_DIRTY + /* check if FS filed of MSTATUS is 'dirty' */ + li t1, SR_MS_DIRTY + and t4, t3, t1 + bne t4, t1, 1f +#endif /* CONFIG_CHECK_MATRIX_DIRTY */ + + /* store */ +#if __riscv_xlen == 64 + addi sp, sp, -(12+12) + csrr t0, xmrstart + store_x t0, (0 +0 )(sp) + csrr t0, xmcsr + store_x t0, (4 +4 )(sp) + csrr t0, xmsize + store_x t0, (8 +8 )(sp) +#else + addi sp, sp, -12 + csrr t0, xmrstart + store_x t0, (0)(sp) + csrr t0, xmcsr + store_x t0, (4)(sp) + csrr t0, xmsize + store_x t0, (8)(sp) +#endif /*__riscv_xlen */ + + csrr t0, xmlenb + slli t1, t0, 3 + sub sp, sp, t1 + csrw xmrstart, x0 + mst8mb m0, (sp) +#if CONFIG_CHECK_MATRIX_DIRTY + j 2f +1: + /* don't save, move sp only */ + csrr t0, xmlenb + slli t1, t0, 3 + sub sp, sp, t1 +#if __riscv_xlen == 64 + addi sp, sp, -24 +#else + addi sp, sp, -12 +#endif +2: +#endif /* CONFIG_CHECK_MATRIX_DIRTY */ +#endif /* __riscv_matrix || __riscv_xtheadmatrix */ +.endm + +.macro RESTORE_MATRIX_REGISTERS + /* t0 and t1 are not restored before using, mstatus has been restored before using */ + +#if __riscv_matrix || __riscv_xtheadmatrix +#if CONFIG_CHECK_MATRIX_DIRTY + /* check if FS filed of MSTATUS is 'dirty' */ + li t1, SR_MS_DIRTY + and t4, t3, t1 + bne t4, t1, 1f +#endif /* CONFIG_CHECK_MATRIX_DIRTY */ + + /* restore */ + csrr t0, xmlenb + slli t1, t0, 3 + csrw xmrstart, x0 + mld8mb m0, (sp) + add sp, sp, t1 +#if __riscv_xlen == 64 + load_x t0, (0 + 0)(sp) + csrw xmrstart, t0 + load_x t0, (4 + 4)(sp) + csrw xmcsr, t0 + load_x t0, (8 + 8)(sp) + csrw xmsize, t0 + addi sp, sp, (12+12) +#else + load_x t0, (0)(sp) + csrw xmrstart, t0 + load_x t0, (4)(sp) + csrw xmcsr, t0 + load_x t0, (8)(sp) + csrw xmsize, t0 + addi sp, sp, 12 +#endif /*__riscv_xlen */ +#if CONFIG_CHECK_MATRIX_DIRTY + j 2f +1: + /* don't restore, move sp only */ + csrr t0, xmlenb + slli t1, t0, 3 + add sp, sp, t1 +#if __riscv_xlen == 64 + addi sp, sp, 24 +#else + addi sp, sp, 12 +#endif +2: +#endif /* CONFIG_CHECK_MATRIX_DIRTY */ +#endif /* __riscv_matrix || __riscv_xtheadmatrix */ +.endm + +.macro RESTORE_SYS_GP + .option push + .option norelax + la gp, __global_pointer$ + .option pop +.endm + +#endif /* __RISCV_ASM_MACRO_H__ */ + diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/include/asm/riscv_csr.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/include/asm/riscv_csr.h new file mode 100644 index 00000000..0bea1b57 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/include/asm/riscv_csr.h @@ -0,0 +1,191 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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. + */ + +/* + * attention: don't modify this file as a suggest + * you should copy from chip_riscv_dummy/include/asm/riscv_csr.h and keep it newer + * please contact xuantie-rtos os team if have question + */ + +#ifndef __RISCV_CSR_H__ +#define __RISCV_CSR_H__ + +#if __riscv_xlen == 64 + #define store_x sd + #define load_x ld + #define portWORD_SIZE 8 +#elif __riscv_xlen == 32 + #define store_x sw + #define load_x lw + #define portWORD_SIZE 4 +#else + #error Assembler did not define __riscv_xlen +#endif + +#if __riscv_flen == 64 + #define fstore_x fsd + #define fload_x fld + #define portFPU_REG_SIZE 8 +#elif __riscv_flen == 32 + #define fstore_x fsw + #define fload_x flw + #define portFPU_REG_SIZE 4 +#endif + +#if CONFIG_RISCV_SMODE +#define MODE_PREFIX(suffix) s##suffix +#else +#define MODE_PREFIX(suffix) m##suffix +#endif + +/* Status register flags */ +#define SR_SIE 0x00000002UL /* Supervisor Interrupt Enable */ +#define SR_MIE 0x00000008UL /* Machine Interrupt Enable */ +#define SR_SPIE 0x00000020UL /* Previous Supervisor IE */ +#define SR_MPIE 0x00000080UL /* Previous Machine IE */ +#define SR_SPP_U 0x00000000UL /* Previously User mode */ +#define SR_SPP_S 0x00000100UL /* Previously Supervisor mode */ +#define SR_MPP_U 0x00000000UL /* Previously User mode */ +#define SR_MPP_S 0x00000800UL /* Previously Supervisor mode */ +#define SR_MPP_M 0x00001800UL /* Previously Machine mode */ +#define SR_SUM 0x00040000UL /* Supervisor User Memory Access */ + +#define SR_FS 0x00006000UL /* Floating-point Status */ +#define SR_FS_OFF 0x00000000UL +#define SR_FS_INITIAL 0x00002000UL +#define SR_FS_CLEAN 0x00004000UL +#define SR_FS_DIRTY 0x00006000UL + +#if CONFIG_CPU_XUANTIE_C906 || CONFIG_CPU_XUANTIE_C906FD || CONFIG_CPU_XUANTIE_C906FDV \ + || CONFIG_CPU_XUANTIE_R920 \ + || CONFIG_CPU_XUANTIE_C920 +#define SR_VS 0x01800000 +#define SR_VS_OFF 0x00000000 +#define SR_VS_INITIAL 0x00800000 +#define SR_VS_CLEAN 0x01000000 +#define SR_VS_DIRTY 0x01800000 +#else +#define SR_VS 0x00000600 +#define SR_VS_OFF 0x00000000 +#define SR_VS_INITIAL 0x00000200 +#define SR_VS_CLEAN 0x00000400 +#define SR_VS_DIRTY 0x00000600 +#endif + +#if __riscv_matrix || __riscv_xtheadmatrix +#define SR_MS 0x06000000 +#define SR_MS_OFF 0x00000000 +#define SR_MS_INITIAL 0x02000000 +#define SR_MS_CLEAN 0x04000000 +#define SR_MS_DIRTY 0x06000000 +#endif + +/* Interrupt-enable Registers */ +#define IE_MTIE 0x00000080UL +#define IE_MEIE 0x00000800UL + +/* ===== Trap/Exception Causes ===== */ +#define CAUSE_MISALIGNED_FETCH 0x0 +#define CAUSE_FETCH_ACCESS 0x1 +#define CAUSE_ILLEGAL_INSTRUCTION 0x2 +#define CAUSE_BREAKPOINT 0x3 +#define CAUSE_MISALIGNED_LOAD 0x4 +#define CAUSE_LOAD_ACCESS 0x5 +#define CAUSE_MISALIGNED_STORE 0x6 +#define CAUSE_STORE_ACCESS 0x7 +#define CAUSE_USER_ECALL 0x8 +#define CAUSE_SUPERVISOR_ECALL 0x9 +#define CAUSE_VIRTUAL_SUPERVISOR_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 + +#define PRV_U 0 +#define PRV_S 1 +#define PRV_M 3 + + +#define MSTATUS_SIE 0x00000002 +#define MSTATUS_MIE 0x00000008 +#define MSTATUS_SPIE_SHIFT 5 +#define MSTATUS_SPIE (1 << MSTATUS_SPIE_SHIFT) +#define MSTATUS_UBE 0x00000040 +#define MSTATUS_MPIE 0x00000080 +#define MSTATUS_SPP_SHIFT 8 +#define MSTATUS_SPP (1 << MSTATUS_SPP_SHIFT) +#define MSTATUS_MPP_SHIFT 11 +#define MSTATUS_MPP (3 << MSTATUS_MPP_SHIFT) + +#if CONFIG_CPU_XUANTIE_C906 || CONFIG_CPU_XUANTIE_C906FD || CONFIG_CPU_XUANTIE_C906FDV \ + || CONFIG_CPU_XUANTIE_R910 || CONFIG_CPU_XUANTIE_R920 \ + || CONFIG_CPU_XUANTIE_C910 || CONFIG_CPU_XUANTIE_C920 +#define MSTATUS_VS_SHIFT 23 +#else +#define MSTATUS_VS_SHIFT 9 +#endif +#define MSTATUS_FS_SHIFT 13 +#define MSTATUS_MS_SHIFT 25 + +#define INSERT_FIELD(val, which, fieldval) (((val) & ~(which)) | ((fieldval) * ((which) & ~((which)-1)))) + +#if CONFIG_CPU_XUANTIE_C906 || CONFIG_CPU_XUANTIE_C906FD || CONFIG_CPU_XUANTIE_C906FDV \ + || CONFIG_CPU_XUANTIE_C908 || CONFIG_CPU_XUANTIE_C908V || CONFIG_CPU_XUANTIE_C908I \ + || CONFIG_CPU_XUANTIE_C908_V2 || CONFIG_CPU_XUANTIE_C908V_V2 || CONFIG_CPU_XUANTIE_C908I_V2 \ + || CONFIG_CPU_XUANTIE_C908_CP_V2 || CONFIG_CPU_XUANTIE_C908V_CP_V2 || CONFIG_CPU_XUANTIE_C908I_CP_V2 \ + || CONFIG_CPU_XUANTIE_C908_CP_XT_V2 || CONFIG_CPU_XUANTIE_C908V_CP_XT_V2 || CONFIG_CPU_XUANTIE_C908I_CP_XT_V2 \ + || CONFIG_CPU_XUANTIE_C908VK_CP_V2 || CONFIG_CPU_XUANTIE_C908VK_CP_XT_V2 \ + || CONFIG_CPU_XUANTIE_R910 || CONFIG_CPU_XUANTIE_R920 \ + || CONFIG_CPU_XUANTIE_C910 || CONFIG_CPU_XUANTIE_C920 \ + || CONFIG_CPU_XUANTIE_XT_C930_CP || CONFIG_CPU_XUANTIE_XT_C930V_CP +#define ATTR_SO (1ull << 4) +#define ATTR_CA (1ull << 3) +#define ATTR_BU (1ull << 2) +#define ATTR_SH (1ull << 1) +#define ATTR_SE (1ull << 0) + +#define UPPER_ATTRS_SHIFT (59) +#define UPPER_ATTRS(x) (((x) & 0x1f) << UPPER_ATTRS_SHIFT) +#else +#if __riscv_xlen == 32 +#define PTE_PBMT_SHIFT (30) +#else +#define PTE_PBMT_SHIFT (61) +#endif /* end __riscv_xlen */ +#define SVPBMT_PMA ((unsigned long)0x0 << PTE_PBMT_SHIFT) +#define SVPBMT_NC ((unsigned long)0x1 << PTE_PBMT_SHIFT) +#define SVPBMT_IO ((unsigned long)0x2 << PTE_PBMT_SHIFT) +#define SVPBMT_MASK ((unsigned long)0x3 << PTE_PBMT_SHIFT) + +#endif + +#define DIRTY_FLAG (1 << 6) +#define ACCESS_FLAG (1 << 5) +#define GLOBAL_FLAG (1 << 4) +#define AP_UNPRIV (1 << 3) +#define AP_X (1 << 2) +#define AP_W (1 << 1) +#define AP_R (1 << 0) + +#define LOWER_ATTRS_SHIFT 1 +#define LOWER_ATTRS(x) (((x) & 0x1ff) << LOWER_ATTRS_SHIFT) + + + +#endif /* __RISCV_CSR_H__ */ + diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/include/drv/dev_tag.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/include/drv/dev_tag.h new file mode 100644 index 00000000..4e7590c4 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/include/drv/dev_tag.h @@ -0,0 +1,104 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/dev_tag.h + * @brief Header File for DEV TAG Driver + * @version V1.0 + * @date 31. March 2020 + * @model common + ******************************************************************************/ + +#ifndef _DRV_DEV_TAG_H_ +#define _DRV_DEV_TAG_H_ + +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + DEV_BLANK_TAG = 0U, + DEV_DW_UART_TAG, + DEV_DW_AHB_DMA_TAG, + DEV_DW_AXI_DMA_TAG, + DEV_DW_GPIO_TAG, + DEV_DW_IIC_TAG, + DEV_DW_QSPI_TAG, + DEV_DW_SDMMC_TAG, + DEV_DW_SDHCI_TAG, + DEV_DW_SPI_TAG, + DEV_DW_TIMER_TAG, + DEV_DW_WDT_TAG, + DEV_WJ_ADC_TAG, + DEV_WJ_AES_TAG, + DEV_WJ_CODEC_TAG, + DEV_WJ_CRC_TAG, + DEV_WJ_DMA_TAG, + DEV_WJ_EFLASH_TAG, + DEV_WJ_EFUSE_TAG, + DEV_WJ_ETB_TAG, + DEV_WJ_FFT_TAG, + DEV_WJ_I2S_TAG, + DEV_WJ_MBOX_TAG, + DEV_WJ_PADREG_TAG, + DEV_WJ_PDM_TAG, + DEV_WJ_PINMUX_TAG, + DEV_WJ_PMU_TAG, + DEV_WJ_PWM_TAG, + DEV_WJ_RNG_TAG, + DEV_WJ_ROM_TAG, + DEV_WJ_RSA_TAG, + DEV_WJ_RTC_TAG, + DEV_WJ_SASC_TAG, + DEV_WJ_SHA_TAG, + DEV_WJ_SPDIF_TAG, + DEV_WJ_SPIDF_TAG, + DEV_WJ_TDM_TAG, + DEV_WJ_TIPC_TAG, + DEV_WJ_USB_TAG, + DEV_WJ_USI_TAG, + DEV_WJ_VAD_TAG, + DEV_CD_QSPI_TAG, + DEV_DCD_ISO7816_TAG, + DEV_OSR_RNG_TAG, + DEV_QX_RTC_TAG, + DEV_RCHBAND_CODEC_TAG, + DEV_CMSDK_UART_TAG, + DEV_RAMBUS_150B_PKA_TAG, + DEV_RAMBUS_150B_TRNG_TAG, + DEV_RAMBUS_120SI_TAG, + DEV_RAMBUS_120SII_TAG, + DEV_RAMBUS_120SIII_TAG, + DEV_WJ_AVFS_TAG, + DEV_WJ_BMU_TAG, + DEV_XT_IOPMP_TAG, +} csi_dev_tag_t; + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_TAG_H_ */ + diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/include/dw_timer_ll.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/include/dw_timer_ll.h new file mode 100644 index 00000000..cb7bf108 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/include/dw_timer_ll.h @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + */ + +/******************************************************* + * @file dw_timer_ll.h + * @brief header file for timer ll driver + * @version V1.0 + * @date 9. April 2020 + * ******************************************************/ + +#ifndef _DW_TIMER_LL_H_ +#define _DW_TIMER_LL_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*! Timer1 Control Reg, offset: 0x08 */ +#define DW_TIMER_CTL_ENABLE_SEL_Pos (0U) +#define DW_TIMER_CTL_ENABLE_SEL_Msk (0x1U << DW_TIMER_CTL_ENABLE_SEL_Pos) +#define DW_TIMER_CTL_ENABLE_SEL_EN DW_TIMER_CTL_ENABLE_SEL_Msk + +#define DW_TIMER_CTL_MODE_SEL_Pos (1U) +#define DW_TIMER_CTL_MODE_SEL_Msk (0x1U << DW_TIMER_CTL_MODE_SEL_Pos) +#define DW_TIMER_CTL_MODE_SEL_EN DW_TIMER_CTL_MODE_SEL_Msk + +#define DW_TIMER_CTL_INT_MASK_Pos (2U) +#define DW_TIMER_CTL_INT_MASK_Msk (0x1U << DW_TIMER_CTL_INT_MASK_Pos) +#define DW_TIMER_CTL_INT_MAKS_EN DW_TIMER_CTL_INT_MASK_Msk + +#define DW_TIMER_CTL_HARD_TRIG_Pos (4U) +#define DW_TIMER_CTL_HARD_TRIG_Msk (0x1U << DW_TIMER_CTL_HARD_TRIG_Pos) +#define DW_TIMER_CTL_HARD_TRIG_EN DW_TIMER_CTL_HARD_TRIG_Msk + +/*! Timer EOI, offset: 0x0c */ +#define DW_TIMER_EOI_REG_Pos (0U) +#define DW_TIMER_EOI_REG_Msk (0x1U << DW_TIMER_EOI_REG_Pos) +#define DW_TIMER_EOI_REG_EN DW_TIMER_EOI_REG_Msk + +/*! Timer Int Status, offset: 0x10 */ +#define DW_TIMER_INT_STATUS_Pos (0U) +#define DW_TIMER_INT_STATUS_Msk (0x1U << DW_TIMER_INT_STATUS_Pos) +#define DW_TIMER_INT_STATUS_EN DW_TIMER_INT_STATUS_Msk + +/*! Timers Int Status, offset: 0xa0 */ +#define DW_TIMERS_INT_STATUS_Pos (0U) +#define DW_TIMERS_INT_STATUS_Msk (0x2U << DW_TIMERS_INT_STATUS_Pos) +#define DW_TIMERS_INT_STATUS_EN DW_TIMERS_INT_STATUS_Msk + +/*! Timers EOI, offset: 0xa4 */ +#define DW_TIMERS_EOI_REG_Pos (0U) +#define DW_TIMERS_EOI_REG_Msk (0x2U << DW_TIMERS_EOI_REG_Pos) +#define DW_TIMERS_EOI_REG_EN DW_TIMERS_EOI_REG_Msk + +/*! Timers Raw Int Status,offset: 0xa8 */ +#define DW_TIMERS_RAW_INT_STA_Pos (0U) +#define DW_TIMERS_RAW_INT_STA_Msk (0x2U << DW_TIMERS_RAW_INT_STA_Pos) +#define DW_TIMERS_RAW_INT_STA_EN DW_TIMERS_RAW_INT_STA_Msk + +typedef struct { + __IOM uint32_t TLC; /* Offset: 0x000 (R/W) TimerLoadCount */ + __IM uint32_t TCV; /* Offset: 0x004 (R/ ) TimerCurrentValue */ + __IOM uint32_t TCR; /* Offset: 0x008 (R/W) TimerControlReg */ + __IM uint32_t TEOI; /* Offset: 0x00c (R/ ) TimerEOI */ + __IM uint32_t TIS; /* Offset: 0x010 (R/ ) TimerIntStatus */ +} dw_timer_regs_t; + +typedef struct { + dw_timer_regs_t timer[8]; + __IM uint32_t TSIS; /* Offset: 0x0a0 (R/ ) TimersIntStatus */ + __IM uint32_t TSEOI; /* Offset: 0x0a4 (R/ ) TimersEOI */ + __IM uint32_t TSRIS; /* Offset: 0x0a8 (R/ ) TimersRawIntStatus */ +} dw_timer_general_regs_t; + +static inline uint32_t dw_timer_read_load(dw_timer_regs_t *timer_base) +{ + return (timer_base->TLC); +} +static inline void dw_timer_write_load(dw_timer_regs_t *timer_base, uint32_t value) +{ + timer_base->TLC = value; +} +static inline uint32_t dw_timer_get_current(dw_timer_regs_t *timer_base) +{ + return (timer_base->TCV); +} +static inline void dw_timer_set_enable(dw_timer_regs_t *timer_base) +{ + timer_base->TCR |= (DW_TIMER_CTL_ENABLE_SEL_EN); +} +static inline void dw_timer_set_disable(dw_timer_regs_t *timer_base) +{ + timer_base->TCR &= ~(DW_TIMER_CTL_ENABLE_SEL_EN); +} +static inline uint32_t dw_timer_get_enable(dw_timer_regs_t *timer_base) +{ + return (((timer_base->TCR) & DW_TIMER_CTL_ENABLE_SEL_EN) ? (uint32_t)1 : (uint32_t)0); +} +static inline void dw_timer_set_mode_free(dw_timer_regs_t *timer_base) +{ + timer_base->TCR &= ~(DW_TIMER_CTL_MODE_SEL_EN); +} +static inline void dw_timer_set_mode_load(dw_timer_regs_t *timer_base) +{ + timer_base->TCR |= (DW_TIMER_CTL_MODE_SEL_EN); +} +static inline uint32_t dw_timer_get_model(dw_timer_regs_t *timer_base) +{ + return (((timer_base->TCR) & DW_TIMER_CTL_MODE_SEL_EN) ? (uint32_t)1 : (uint32_t)0); +} +static inline void dw_timer_set_mask(dw_timer_regs_t *timer_base) +{ + timer_base->TCR |= (DW_TIMER_CTL_INT_MAKS_EN); +} +static inline void dw_timer_set_unmask(dw_timer_regs_t *timer_base) +{ + timer_base->TCR &= ~(DW_TIMER_CTL_INT_MAKS_EN); +} +static inline uint32_t dw_timer_get_mask(dw_timer_regs_t *timer_base) +{ + return (((timer_base->TCR) & DW_TIMER_CTL_INT_MAKS_EN) ? (uint32_t)1 : (uint32_t)0); +} +static inline void dw_timer_set_hardtrigger_en(dw_timer_regs_t *timer_base) +{ + timer_base->TCR |= (DW_TIMER_CTL_HARD_TRIG_EN); +} +static inline void dw_timer_set_hardtrigger_dis(dw_timer_regs_t *timer_base) +{ + timer_base->TCR &= ~(DW_TIMER_CTL_HARD_TRIG_EN); +} +static inline uint32_t dw_timer_get_hardtrigger(dw_timer_regs_t *timer_base) +{ + return (((timer_base->TCR) & DW_TIMER_CTL_HARD_TRIG_EN) ? (uint32_t)1 : (uint32_t)0); +} +static inline uint32_t dw_timer_clear_irq(dw_timer_regs_t *timer_base) +{ + return (((timer_base->TEOI) & DW_TIMER_EOI_REG_EN) ? (uint32_t)1 : (uint32_t)0); +} +static inline uint32_t dw_timer_get_int_status(dw_timer_regs_t *timer_base) +{ + return (((timer_base->TIS) & DW_TIMER_INT_STATUS_EN) ? (uint32_t)1 : (uint32_t)0); +} +static inline uint32_t dw_timer_general_active_after_mask(dw_timer_general_regs_t *timer_base) +{ + return ((timer_base->TSIS) & DW_TIMERS_INT_STATUS_EN); +} +static inline uint32_t dw_timer_general_clear_irq(dw_timer_general_regs_t *timer_base) +{ + return ((timer_base->TSEOI) & DW_TIMERS_EOI_REG_EN); +} +static inline uint32_t dw_timer_general_active_prior_mask(dw_timer_general_regs_t *timer_base) +{ + return ((timer_base->TSRIS) & DW_TIMERS_RAW_INT_STA_EN); +} + + +#ifdef __cplusplus +} +#endif + +#endif /* _DW_TIMER_LL_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/include/dw_uart.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/include/dw_uart.h new file mode 100644 index 00000000..e69de29b diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/include/dw_uart_ll.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/include/dw_uart_ll.h new file mode 100644 index 00000000..50a7de0b --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/include/dw_uart_ll.h @@ -0,0 +1,423 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 dw_uart_ll.h + * @brief header file for uart ll driver + * @version V1.0 + * @date 18. December 2024 + ******************************************************************************/ + +#ifndef _DW_UART_LL_H_ +#define _DW_UART_LL_H_ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*! IER, offset: 0x4 */ +#define DW_UART_IER_ERBFI_Pos (0U) +#define DW_UART_IER_ERBFI_Msk (0x1U << DW_UART_IER_ERBFI_Pos) +#define DW_UART_IER_ERBFI_EN DW_UART_IER_ERBFI_Msk + +#define DW_UART_IER_ETBEI_Pos (1U) +#define DW_UART_IER_ETBEI_Msk (0x1U << DW_UART_IER_ETBEI_Pos) +#define DW_UART_IER_ETBEI_EN DW_UART_IER_ETBEI_Msk + +#define DW_UART_IER_ELSI_Pos (2U) +#define DW_UART_IER_ELSI_Msk (0x1U << DW_UART_IER_ELSI_Pos) +#define DW_UART_IER_ELSI_EN DW_UART_IER_ELSI_Msk + +#define DW_UART_IER_EDSSI_Pos (3U) +#define DW_UART_IER_EDSSI_Msk (0x1U << DW_UART_IER_EDSSI_Pos) +#define DW_UART_IER_EDSSI_EN DW_UART_IER_EDSSI_Msk + +/*! IIR, offset: 0x8 */ +#define DW_UART_IIR_IID_Pos (0U) +#define DW_UART_IIR_IID_Msk (0xFU << DW_UART_IIR_IID_Pos) +#define DW_UART_IIR_IID_MODEM_STATUS (0x0U) +#define DW_UART_IIR_IID_NO_INTERRUPT (0x1U) +#define DW_UART_IIR_IID_THR_EMPTY (0x2U) +#define DW_UART_IIR_IID_RECV_DATA_AVAIL (0x4U) +#define DW_UART_IIR_IID_RECV_LINE_STATUS (0x6U) +#define DW_UART_IIR_IID_BUSY_DETECT (0x7U) +#define DW_UART_IIR_IID_CHARACTER_TIMEOUT (0xCU) + +#define DW_UART_IIR_FIFOSE_Pos (6U) +#define DW_UART_IIR_FIFOSE_Msk (0x3U << DW_UART_IIR_FIFOSE_Pos) +#define DW_UART_IIR_FIFOSE_EN DW_UART_IIR_FIFOSE_Msk + +/*! FCR, offset: 0x8 */ +#define DW_UART_FCR_FIFOE_Pos (0U) +#define DW_UART_FCR_FIFOE_Msk (0x1U << DW_UART_FCR_FIFOE_Pos) +#define DW_UART_FCR_FIFOE_EN DW_UART_FCR_FIFOE_Msk + +#define DW_UART_FCR_RFIFOR_Pos (1U) +#define DW_UART_FCR_RFIFOR_Msk (0x1U << DW_UART_FCR_RFIFOR_Pos) +#define DW_UART_FCR_RFIFOR_RESET DW_UART_FCR_RFIFOR_Msk + +#define DW_UART_FCR_XFIFOR_Pos (2U) +#define DW_UART_FCR_XFIFOR_Msk (0x1U << DW_UART_FCR_XFIFOR_Pos) +#define DW_UART_FCR_XFIFOR_RESET DW_UART_FCR_XFIFOR_Msk + +#define DW_UART_FCR_TET_Pos (4U) +#define DW_UART_FCR_TET_Msk (0x3U << DW_UART_FCR_TET_Pos) +#define DW_UART_FCR_TET_FIFO_EMTPY (0x0U) +#define DW_UART_FCR_TET_FIFO_2_CHAR (0x1U << DW_UART_FCR_TET_Pos) +#define DW_UART_FCR_TET_FIFO_1_4_FULL (0x2U << DW_UART_FCR_TET_Pos) +#define DW_UART_FCR_TET_FIFO_1_2_FULL (0x3U << DW_UART_FCR_TET_Pos) + +#define DW_UART_FCR_RT_Pos (6U) +#define DW_UART_FCR_RT_Msk (0x3U << DW_UART_FCR_RT_Pos) +#define DW_UART_FCR_RT_FIFO_1_CHAR (0x0U) +#define DW_UART_FCR_RT_FIFO_1_4_FULL (0x1U << DW_UART_FCR_RT_Pos) +#define DW_UART_FCR_RT_FIFO_1_2_FULL (0x2U << DW_UART_FCR_RT_Pos) +#define DW_UART_FCR_RT_FIFO_2_LESS_FULL (0x3U << DW_UART_FCR_RT_Pos) + +/*! LCR, offset: 0xC */ +#define DW_UART_LCR_DLS_Pos (0U) +#define DW_UART_LCR_DLS_Msk (0x3U << DW_UART_LCR_DLS_Pos) +#define DW_UART_LCR_DLS_5_BITS (0x0U) +#define DW_UART_LCR_DLS_6_BITS (0x1U << DW_UART_LCR_DLS_Pos) +#define DW_UART_LCR_DLS_7_BITS (0x2U << DW_UART_LCR_DLS_Pos) +#define DW_UART_LCR_DLS_8_BITS (0x3U << DW_UART_LCR_DLS_Pos) + +#define DW_UART_LCR_STOP_Pos (2U) +#define DW_UART_LCR_STOP_Msk (0x1U << DW_UART_LCR_STOP_Pos) +#define DW_UART_LCR_STOP_1_BIT (0x0U) +#define DW_UART_LCR_STOP_2_BIT (0x1U << DW_UART_LCR_STOP_Pos) + +#define DW_UART_LCR_PEN_Pos (3U) +#define DW_UART_LCR_PEN_Msk (0x1U << DW_UART_LCR_PEN_Pos) +#define DW_UART_LCR_PEN_EN DW_UART_LCR_PEN_Msk + +#define DW_UART_LCR_EPS_Pos (4U) +#define DW_UART_LCR_EPS_Msk (0x1U << DW_UART_LCR_EPS_Pos) +#define DW_UART_LCR_EPS_EN DW_UART_LCR_EPS_Msk + +#define DW_UART_LCR_BC_Pos (6U) +#define DW_UART_LCR_BC_Msk (0x1U << DW_UART_LCR_BC_Pos) +#define DW_UART_LCR_BC_EN DW_UART_LCR_BC_Msk + +#define DW_UART_LCR_DLAB_Pos (7U) +#define DW_UART_LCR_DLAB_Msk (0x1U << DW_UART_LCR_DLAB_Pos) +#define DW_UART_LCR_DLAB_EN DW_UART_LCR_DLAB_Msk + +/*! MCR, offset: 0x10 */ +#define DW_UART_MCR_RTS_Pos (1U) +#define DW_UART_MCR_RTS_Msk (0x1U << DW_UART_MCR_RTS_Pos) +#define DW_UART_MCR_RTS_EN DW_UART_MCR_RTS_Msk + +#define DW_UART_MCR_LB_Pos (4U) +#define DW_UART_MCR_LB_Msk (0x1U << DW_UART_MCR_LB_Pos) +#define DW_UART_MCR_LB_EN DW_UART_MCR_LB_Msk + +#define DW_UART_MCR_AFCE_Pos (5U) +#define DW_UART_MCR_AFCE_Msk (0x1U << DW_UART_MCR_AFCE_Pos) +#define DW_UART_MCR_AFCE_EN DW_UART_MCR_AFCE_Msk + +/*! LSR, offset: 0x14 */ +#define DW_UART_LSR_DR_Pos (0U) +#define DW_UART_LSR_DR_Msk (0x1U << DW_UART_LSR_DR_Pos) +#define DW_UART_LSR_DR_READY DW_UART_LSR_DR_Msk + +#define DW_UART_LSR_OE_Pos (1U) +#define DW_UART_LSR_OE_Msk (0x1U << DW_UART_LSR_OE_Pos) +#define DW_UART_LSR_OE_ERROR DW_UART_LSR_OE_Msk + +#define DW_UART_LSR_PE_Pos (2U) +#define DW_UART_LSR_PE_Msk (0x1U << DW_UART_LSR_PE_Pos) +#define DW_UART_LSR_PE_ERROR DW_UART_LSR_PE_Msk + +#define DW_UART_LSR_FE_Pos (3U) +#define DW_UART_LSR_FE_Msk (0x1U << DW_UART_LSR_FE_Pos) +#define DW_UART_LSR_FE_ERROR DW_UART_LSR_FE_Msk + +#define DW_UART_LSR_BI_Pos (4U) +#define DW_UART_LSR_BI_Msk (0x1U << DW_UART_LSR_BI_Pos) +#define DW_UART_LSR_BI_SET DW_UART_LSR_BI_Msk + +#define DW_UART_LSR_THRE_Pos (5U) +#define DW_UART_LSR_THRE_Msk (0x1U << DW_UART_LSR_THRE_Pos) +#define DW_UART_LSR_THRE_SET DW_UART_LSR_THRE_Msk + +#define DW_UART_LSR_TEMT_Pos (6U) +#define DW_UART_LSR_TEMT_Msk (0x1U << DW_UART_LSR_TEMT_Pos) +#define DW_UART_LSR_TEMT_SET DW_UART_LSR_TEMT_Msk + +#define DW_UART_LSR_RFE_Pos (7U) +#define DW_UART_LSR_RFE_Msk (0x1U << DW_UART_LSR_RFE_Pos) +#define DW_UART_LSR_RFE_ERROR DW_UART_LSR_RFE_Msk + +/*! MSR, offset: 0x18 */ +#define DW_UART_MSR_DCTS_Pos (0U) +#define DW_UART_MSR_DCTS_Msk (0x1U << DW_UART_MSR_DCTS_Pos) +#define DW_UART_MSR_DCTS_CHANGE DW_UART_MSR_DCTS_Msk + +#define DW_UART_MSR_DDSR_Pos (1U) +#define DW_UART_MSR_DDSR_Msk (0x1U << DW_UART_MSR_DDSR_Pos) +#define DW_UART_MSR_DDSR_CHANGE DW_UART_MSR_DDSR_Msk + +#define DW_UART_MSR_TERI_Pos (2U) +#define DW_UART_MSR_TERI_Msk (0x1U << DW_UART_MSR_TERI_Pos) +#define DW_UART_MSR_TERI_CHANGE DW_UART_MSR_TERI_Msk + +#define DW_UART_MSR_DDCD_Pos (3U) +#define DW_UART_MSR_DDCD_Msk (0x1U << DW_UART_MSR_DDCD_Pos) +#define DW_UART_MSR_DDCD_CHANGE DW_UART_MSR_DDCD_Msk + +#define DW_UART_MSR_CTS_Pos (4U) +#define DW_UART_MSR_CTS_Msk (0x1U << DW_UART_MSR_CTS_Pos) +#define DW_UART_MSR_CTS_ASSERTED DW_UART_MSR_CTS_Msk + +#define DW_UART_MSR_DSR_Pos (5U) +#define DW_UART_MSR_DSR_Msk (0x1U << DW_UART_MSR_DSR_Pos) +#define DW_UART_MSR_DSR_ASSERTED DW_UART_MSR_DSR_Msk + +#define DW_UART_MSR_RI_Pos (6U) +#define DW_UART_MSR_RI_Msk (0x1U << DW_UART_MSR_RI_Pos) +#define DW_UART_MSR_RI_ASSERTED DW_UART_MSR_RI_Msk + +#define DW_UART_MSR_DCD_Pos (7U) +#define DW_UART_MSR_DCD_Msk (0x1U << DW_UART_MSR_DCD_Pos) +#define DW_UART_MSR_DCD_ASSERTED DW_UART_MSR_DCD_Msk + +/*! SCR, offset: 0x1C */ +#define DW_UART_SCR_SCRATCHPAD_Pos (0U) +#define DW_UART_SCR_SCRATCHPAD_Msk (0xFFU << DW_UART_SCR_SCRATCHPAD_Pos) + +/*! USR, offset: 0x7C */ +#define DW_UART_USR_BUSY_Pos (0U) +#define DW_UART_USR_BUSY_Msk (0x1U << DW_UART_USR_BUSY_Pos) +#define DW_UART_USR_BUSY_SET DW_UART_USR_BUSY_Msk + +#define DW_UART_USR_TFNF_Pos (1U) +#define DW_UART_USR_TFNF_Msk (0x1U << DW_UART_USR_TFNF_Pos) +#define DW_UART_USR_TFNF_SET DW_UART_USR_TFNF_Msk + +#define DW_UART_USR_TFE_Pos (2U) +#define DW_UART_USR_TFE_Msk (0x1U << DW_UART_USR_TFE_Pos) +#define DW_UART_USR_TFE_SET DW_UART_USR_TFE_Msk + +#define DW_UART_USR_RFNE_Pos (3U) +#define DW_UART_USR_RFNE_Msk (0x1U << DW_UART_USR_RFNE_Pos) +#define DW_UART_USR_RFNE_SET DW_UART_USR_RFNE_Msk + +#define DW_UART_USR_RFF_Pos (4U) +#define DW_UART_USR_RFF_Msk (0x1U << DW_UART_USR_RFF_Pos) +#define DW_UART_USR_RFF_SET DW_UART_USR_RFF_Msk + +/*! TFL, offset: 0x80 */ +#define DW_UART_TFL_TFIFOL_Pos (0U) +#define DW_UART_TFL_TFIFOL_Msk (0x1FU << DW_UART_TFL_TFIFOL_Pos) +#define DW_UART_TFL_TFIFOL(n) (nU << DW_UART_TFL_TFIFOL_Pos) + +/*! RFL, offset: 0x84 */ +#define DW_UART_RFL_RFIFOL_Pos (0U) +#define DW_UART_RFL_RFIFOL_Msk (0x1FU << DW_UART_RFL_RFIFOL_Pos) +#define DW_UART_RFL_RFIFOL(n) (nU << DW_UART_TFL_TFIFOL_Pos) + +/*! HTX, offset: 0xA4 */ +#define DW_UART_HTX_HALTTX_Pos (0U) +#define DW_UART_HTX_HALTTX_Msk (0x1U << DW_UART_HTX_HALTTX_Pos) +#define DW_UART_HTX_HALTTX_EN DW_UART_HTX_HALTTX_Msk + +#define DW_UART_HTX_RX_ETB_FUNC_Pos (6U) +#define DW_UART_HTX_RX_ETB_FUNC_Msk (0x1U << DW_UART_HTX_RX_ETB_FUNC_Pos) +#define DW_UART_HTX_RX_ETB_FUNC_EN DW_UART_HTX_RX_ETB_FUNC_Msk + +#define DW_UART_HTX_TX_ETB_FUNC_Pos (7U) +#define DW_UART_HTX_TX_ETB_FUNC_Msk (0x1U << DW_UART_HTX_TX_ETB_FUNC_Pos) +#define DW_UART_HTX_TX_ETB_FUNC_EN DW_UART_HTX_TX_ETB_FUNC_Msk + +/*! DMASA, offset: 0xA8 */ +#define DW_UART_DMASA_DMASACK_Pos (0U) +#define DW_UART_DMASA_DMASACK_Msk (0x1U << DW_UART_DMASA_DMASACK_Pos) +#define DW_UART_DMASA_DMASACK_SET DW_UART_DMASA_DMASACK_Msk + +/* FIFO CONFIG */ +#define UART_FIFO_INIT_CONFIG (DW_UART_FCR_FIFOE_EN | DW_UART_FCR_RT_FIFO_1_2_FULL|DW_UART_FCR_RFIFOR_RESET|DW_UART_FCR_XFIFOR_RESET) + +/*! UART_RATE, offset: 0x3FC */ +#define DW_UART_SUPPORT_RATE 0x10102U + +#define UART_BUSY_TIMEOUT 0x70000000U + +typedef struct { + union { + __IM uint32_t RBR; /* Offset: 0x000 (R/ ) Receive buffer register */ + __OM uint32_t THR; /* Offset: 0x000 ( /W) Transmission hold register */ + __IOM uint32_t DLL; /* Offset: 0x000 (R/W) Clock frequency division low section register */ + }; + union { + __IOM uint32_t DLH; /* Offset: 0x004 (R/W) Clock frequency division high section register */ + __IOM uint32_t IER; /* Offset: 0x004 (R/W) Interrupt enable register */ + }; + union { + __IM uint32_t IIR; /* Offset: 0x008 (R/ ) Interrupt identification register */ + __OM uint32_t FCR; /* Offset: 0x008 ( /W) FIFO control register */ + }; + __IOM uint32_t LCR; /* Offset: 0x00C (R/W) Line control register */ + __IOM uint32_t MCR; /* Offset: 0x010 (R/W) Modem control register */ + __IM uint32_t LSR; /* Offset: 0x014 (R/ ) Line state register */ + __IM uint32_t MSR; /* Offset: 0x018 (R/ ) Modem state register */ + uint32_t RESERVED1[21]; + __IM uint32_t USR; /* Offset: 0x07c (R/ ) UART state register */ +} dw_uart_regs_t; + +static inline void dw_uart_enable_recv_irq(dw_uart_regs_t *uart_base) +{ + uart_base->IER |= (DW_UART_IER_ERBFI_EN | DW_UART_IER_ELSI_EN); +} + +static inline void dw_uart_disable_recv_irq(dw_uart_regs_t *uart_base) +{ + uart_base->IER &= ~(DW_UART_IER_ERBFI_EN | DW_UART_IER_ELSI_EN); +} + +static inline void dw_uart_enable_trans_irq(dw_uart_regs_t *uart_base) +{ + uart_base->IER |= DW_UART_IER_ETBEI_EN; +} + +static inline void dw_uart_disable_trans_irq(dw_uart_regs_t *uart_base) +{ + uart_base->IER &= ~(DW_UART_IER_ETBEI_EN); +} + +static inline void dw_uart_fifo_init(dw_uart_regs_t *uart_base) +{ + /* FIFO enable */ + uart_base->FCR = UART_FIFO_INIT_CONFIG; +} + +static inline void dw_uart_fifo_enable(dw_uart_regs_t *uart_base) +{ + uart_base->FCR |= DW_UART_FCR_FIFOE_EN; +} + +static inline void dw_uart_fifo_disable(dw_uart_regs_t *uart_base) +{ + uart_base->FCR &= ~(DW_UART_FCR_FIFOE_EN); +} + +static inline uint32_t dw_uart_putready(dw_uart_regs_t *uart_base) +{ + uint32_t status = 0U, ret = 0U; + + status = uart_base->LSR & DW_UART_LSR_THRE_SET; + + if (status != 0U) { + ret = 1U; + } + + return ret; +} + +static inline uint32_t dw_uart_getready(dw_uart_regs_t *uart_base) +{ + uint32_t status = 0U, ret = 0U; + + status = uart_base->LSR & DW_UART_LSR_DR_READY; + + if (status != 0U) { + ret = 1U; + } + + return ret; +} + +static inline uint32_t dw_uart_get_line_status(dw_uart_regs_t *uart_base) +{ + return uart_base->LSR; +} + +static inline void dw_uart_config_stop_bits_1(dw_uart_regs_t *uart_base) +{ + uart_base->LCR &= ~(DW_UART_LCR_STOP_Msk); +} + +static inline void dw_uart_config_stop_bits_2(dw_uart_regs_t *uart_base) +{ + uart_base->LCR |= DW_UART_LCR_STOP_2_BIT; +} + +static inline void dw_uart_putchar(dw_uart_regs_t *uart_base, uint8_t ch) +{ + uart_base->THR = ch; +} + +static inline uint8_t dw_uart_getchar(dw_uart_regs_t *uart_base) +{ + return (uint8_t)(uart_base->RBR); +} + +static inline uint32_t dw_uart_get_intr_en_status(dw_uart_regs_t *uart_base) +{ + return uart_base->IER; +} + +static inline void dw_uart_set_intr_en_status(dw_uart_regs_t *uart_base, uint32_t status) +{ + uart_base->IER = status; +} + +static inline void dw_uart_set_fcr_reg(dw_uart_regs_t *uart_base, uint32_t value) +{ + uart_base->FCR = value; +} + +static inline void dw_uart_enable_auto_flow_control(dw_uart_regs_t *uart_base) +{ + uart_base->MCR |= DW_UART_MCR_AFCE_EN; + uart_base->MCR |= DW_UART_MCR_RTS_EN; +} + +static inline void dw_uart_disable_auto_flow_control(dw_uart_regs_t *uart_base) +{ + uart_base->MCR &= ~DW_UART_MCR_AFCE_EN; + uart_base->MCR &= ~DW_UART_MCR_RTS_EN; +} + +int32_t dw_uart_wait_timeout(dw_uart_regs_t *uart_base); + +int32_t dw_uart_wait_idle(dw_uart_regs_t *uart_base); + +int32_t dw_uart_config_baudrate(dw_uart_regs_t *uart_base, uint32_t baud, uint32_t uart_freq); + +int32_t dw_uart_config_stop_bits(dw_uart_regs_t *uart_base, uint32_t stop_bits); + +int32_t dw_uart_config_parity_none(dw_uart_regs_t *uart_base); + +int32_t dw_uart_config_parity_odd(dw_uart_regs_t *uart_base); + +int32_t dw_uart_config_parity_even(dw_uart_regs_t *uart_base); + +int32_t dw_uart_config_data_bits(dw_uart_regs_t *uart_base, uint32_t data_bits); + +#ifdef __cplusplus +} +#endif + +#endif /* _DW_UART_LL_H_ */ + diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/include/soc.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/include/soc.h new file mode 100644 index 00000000..e77cb305 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/include/soc.h @@ -0,0 +1,409 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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. + */ + +#ifndef _SOC_H_ +#define _SOC_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef EHS_VALUE +#define EHS_VALUE 20000000U +#endif + +#ifndef ELS_VALUE +#define ELS_VALUE 32768U +#endif + +#ifndef IHS_VALUE +#define IHS_VALUE 20000000U +#endif + +#ifndef ILS_VALUE +#define ILS_VALUE 32768U +#endif + +#if __riscv_xlen == 32 +#define INVALID_ADDRESS 0xFFFFFFFFU +#elif __riscv_xlen == 64 +#define INVALID_ADDRESS 0xFFFFFFFFFFFFFFFFULL +#else +#error "Unsupported RISC-V XLEN." +#endif + +typedef enum { + DW_UART0_RX_DMAN = 0U, + DW_UART0_TX_DMAN = 1U, + DW_UART1_RX_DMAN = 2U, + DW_UART1_TX_DMAN = 3U, + MEMORY_DMAN = 4U, +} dman_type_t; + +typedef enum { + PA0 = 0U, + PA1, + PA2, + PA3, + PA4, + PA5, + PA6, + PA7, + PA8, + PA9, + PA10, + PA11, + PA12, + PA13, + PA14, + PA15, + PA16, + PA17, + PA18, + PA19, + PA20, + PA21, + PA22, + PA23, + PA24, + PA25, + PA26, + PA27, + PA28, + PA29, + PA30, + PA31, + PIN_END = 0xFFFFFFFFU +} pin_name_t; + + +typedef enum { + PA0_I2S0_SCLK = 0U, + PA0_SPI0_CS = 1U, + PA0_UART0_RX = 2U, + PA0_PWM_CH0 = 3U, + PA1_I2S0_WSCLK = 0U, + PA1_SPI0_SCK = 1U, + PA1_UART0_TX = 2U, + PA1_PWM_CH1 = 3U, + PA2_I2S1_SCLK = 0U, + PA2_IIC0_SCL = 1U, + PA2_SPI1_CS = 2U, + PA2_PWM_CH2 = 3U, + PA2_ADC_A0 = 7U, + PA3_I2S1_WSCLK = 0U, + PA3_IIC0_SDA = 1U, + PA3_SPI1_SCK = 2U, + PA3_PWM_CH3 = 3U, + PA3_ADC_A1 = 8U, + PA4_I2S0_SDA = 0U, + PA4_SPI0_MOSI = 1U, + PA4_UART1_CTS = 2U, + PA4_PWM_CH4 = 3U, + PA4_ADC_A2 = 9U, + PA5_I2S1_SDA = 0U, + PA5_SPI0_MISO = 1U, + PA5_UART1_RTS = 2U, + PA5_PWM_CH5 = 3U, + PA5_ADC_A3 = 10U, + PA6_I2S0_SCLK = 0U, + PA6_UART0_TX = 1U, + PA6_SPI1_MOSI = 2U, + PA6_PWM_CH6 = 3U, + PA6_ADC_A4 = 11U, + PA7_I2S0_WSCLK = 0U, + PA7_PWMR_OUT = 1U, + PA7_SPI1_MISO = 2U, + PA7_PWM_CH7 = 3U, + PA7_ADC_A5 = 12U, + PA8_I2S0_SDA = 0U, + PA8_IIC0_SCL = 1U, + PA8_UART0_RX = 2U, + PA8_PWM_CH8 = 3U, + PA8_ADC_A6 = 13U, + PA9_I2S1_SDA = 0U, + PA9_IIC0_SDA = 1U, + PA9_PWMR_OUT = 2U, + PA9_PWM_CH9 = 3U, + PA9_ADC_A7 = 14U, + PA10_I2S0_MCLK = 0U, + PA10_UART0_TX = 1U, + PA10_SPI1_MOSI = 2U, + PA10_SPI1_MISO = 3U, + PA10_ADC_A8 = 15U, + PA15_IIC0_SCL = 0U, + PA15_SPI0_CS = 1U, + PA15_PWMR_OUT = 2U, + PA15_PWM_CH4 = 3U, + PA15_ADC_A9 = 20U, + PA16_IIC0_SDA = 0U, + PA16_SPI0_SCK = 1U, + PA16_UART1_TX = 2U, + PA16_PWM_CH5 = 3U, + PA16_ADC_A10 = 21U, + PA17_UART0_RX = 0U, + PA17_SPI0_MOSI = 1U, + PA17_I2S0_SCLK = 2U, + PA17_PWM_CH10 = 3U, + PA17_ADC_A11 = 22U, + PA18_UART0_TX = 0U, + PA18_SPI0_MISO = 1U, + PA18_I2S0_WSCLK = 2U, + PA18_PWM_CH11 = 3U, + PA18_ADC_A12 = 23U, + PA19_JTAG_TMS = 0U, + PA19_UART1_RX = 1U, + PA19_I2S1_SCLK = 2U, + PA19_IIC0_SCL = 3U, + PA19_ADC_A13 = 24U, + PA20_JTAG_TCK = 0U, + PA20_UART1_TX = 1U, + PA20_I2S1_WSCLK = 2U, + PA20_IIC0_SDA = 3U, + PA20_ADC_A14 = 25U, + PA21_UART0_CTS = 0U, + PA21_UART1_CTS = 1U, + PA21_I2S0_SDA = 2U, + PA21_IIC0_SCL = 3U, + PA21_ADC_A15 = 26U, + PA22_UART0_RTS = 0U, + PA22_UART1_RTS = 1U, + PA22_I2S1_SDA = 2U, + PA22_IIC0_SDA = 3U, + PA23_IIC0_SCL = 0U, + PA23_UART0_TX = 1U, + PA23_PWM_CH0 = 2U, + PA23_SPI0_CS = 3U, + PA24_IIC0_SDA = 0U, + PA24_UART0_RX = 1U, + PA24_PWM_CH1 = 2U, + PA24_SPI0_SCK = 3U, + PA25_PWMR_OUT = 0U, + PA25_UART0_CTS = 1U, + PA25_PWM_CH2 = 2U, + PA25_SPI0_MOSI = 3U, + PA26_I2S1_MCLK = 0U, + PA26_UART0_RTS = 1U, + PA26_PWM_CH3 = 2U, + PA26_SPI0_MISO = 3U, + PA27_I2S0_SCLK = 0U, + PA27_UART1_RX = 1U, + PA27_PWM_CH4 = 2U, + PA27_SPI1_CS = 3U, + PA28_I2S0_WSCLK = 0U, + PA28_UART1_TX = 1U, + PA28_PWM_CH5 = 2U, + PA28_SPI1_SCK = 3U, + PA29_I2S1_SCLK = 0U, + PA29_UART1_CTS = 1U, + PA29_PWM_CH6 = 2U, + PA29_SPI1_MOSI = 3U, + PA30_I2S1_WSCLK = 0U, + PA30_UART1_RTS = 1U, + PA30_PWM_CH7 = 2U, + PA30_SPI1_MISO = 3U, + PA31_I2S0_SDA = 0U, + PA31_PWMR_OUT = 1U, + PA31_PWM_CH8 = 2U, + PA31_UART0_TX = 3U, + PIN_FUNC_GPIO = 4U, + PIN_FUNC_END = 0xFFFFFFFFU +} pin_func_t; + +#define CONFIG_IRQ_NUM 64U +#if CONFIG_INTC_CLIC_PLIC +#undef CONFIG_IRQ_NUM +#define CONFIG_IRQ_NUM (64U + PLIC_IRQ_OFFSET) +#endif + +#if CONFIG_INTC_CLIC_APLIC +#undef CONFIG_IRQ_NUM +#define CONFIG_IRQ_NUM (64U + APLIC_IRQ_OFFSET) +#endif + +#if CONFIG_INTC_IMSIC_APLIC +#undef CONFIG_IRQ_NUM +#define CONFIG_IRQ_NUM (IMSIC_MAX_INTERRUPTS) +#endif + +///< AHB +#define SPIFLASH_BASE 0x18000000UL +#define SPIFLASH_SIZE 0x800000U +#define SRAM_BASE 0x20000000UL +#define SRAM_SIZE 0x20000U + +#if CONFIG_CPU_XUANTIE_E9XX + +typedef enum { + User_Software_IRQn = 0U, /* User software interrupt */ + Supervisor_Software_IRQn = 1U, /* Supervisor software interrupt */ + Machine_Software_IRQn = 3U, /* Machine software interrupt */ + User_Timer_IRQn = 4U, /* User timer interrupt */ + Supervisor_Timer_IRQn = 5U, /* Supervisor timer interrupt */ + CORET_IRQn = 7U, /* Machine timer interrupt */ + Machine_External_IRQn = 11U, /* Machine external interrupt */ + DW_UART0_IRQn = 16U, + TIM0_IRQn = 18U, /* timer0 Interrupt */ + TIM1_IRQn = 19U, /* timer1 Interrupt */ + TIM2_IRQn = 20U, /* timer2 Interrupt */ + TIM3_IRQn = 21U, /* timer3 Interrupt */ +} irqn_type_t; + +#if CONFIG_BOARD_SMARTM_EVB +#define DW_UART0_BASE 0x180000UL +#define DW_TIMER0_BASE 0x181000UL +#define DW_TIMER1_BASE 0x181014UL +#define DW_TIMER2_BASE 0x181028UL +#define DW_TIMER3_BASE 0x18103CUL + +#else + +#define DW_UART0_BASE 0x40015000UL +#define DW_TIMER0_BASE 0x40011000UL +#define DW_TIMER0_SIZE 0x14U +#define DW_TIMER1_BASE (DW_TIMER0_BASE+DW_TIMER0_SIZE) +#define DW_TIMER1_SIZE DW_TIMER0_SIZE +#define DW_TIMER2_BASE 0x40011028UL +#define DW_TIMER2_SIZE 0x14U +#define DW_TIMER3_BASE (DW_TIMER2_BASE+DW_TIMER2_SIZE) +#define DW_TIMER3_SIZE DW_TIMER2_SIZE +#if CONFIG_SUPPORT_NMI_DEMO +/* fake irq is not work, just for nmi test with smartl fpga(connected TIMER4 to nmi-exception on soc bit of smartl) */ +#define FAKE_IRQ_TIMER4 (-1) +#define DW_TIMER4_BASE (0x40021000UL) +#endif +#endif /* CONFIG_BOARD_SMARTM_EVB */ + +#else + +/* ------------------------- Interrupt Number Definition ------------------------ */ + +#define Supervisor_Software_IRQn (1U) +#define Machine_Software_IRQn (3U) +#define Supervisor_Timer_IRQn (5U) +#define CORET_IRQn (7U) +#define Supervisor_External_IRQn (9U) +#define Machine_External_IRQn (11U) +#define L1_CACHE_ECC_IRQn (16U) + +#if CONFIG_BOARD_XIAOHUI_EVB + +#if CONFIG_INTC_CLIC_PLIC +typedef enum IRQn { + L2_CACHE_ECC_IRQn = 1U + PLIC_IRQ_OFFSET, /* l2 cache ecc Interrupt */ + + DW_DMA0_IRQn = 17U, /* dma0 Interrupt */ + DW_UART0_IRQn = 20U + PLIC_IRQ_OFFSET, /* uart Interrupt */ + TIM0_IRQn = 25U, /* timer0 Interrupt for CLIC*/ + TIM1_IRQn = 26U, /* timer1 Interrupt for CLIC*/ + TIM2_IRQn = 27U + PLIC_IRQ_OFFSET, /* timer2 Interrupt */ + TIM3_IRQn = 28U + PLIC_IRQ_OFFSET, /* timer3 Interrupt */ + IOPMP0_IRQn = 32U, /* iopmp0 Interrupt */ + END_IRQn = 1024U + PLIC_IRQ_OFFSET +} irqn_type_t; +#elif CONFIG_INTC_CLIC_APLIC +typedef enum IRQn { + L2_CACHE_ECC_IRQn = 1U + APLIC_IRQ_OFFSET, /* l2 cache ecc Interrupt */ + + DW_DMA0_IRQn = 17U, /* dma0 Interrupt */ + DW_UART0_IRQn = 20U + APLIC_IRQ_OFFSET, /* uart Interrupt */ + TIM0_IRQn = 25U, /* timer0 Interrupt for CLIC*/ + TIM1_IRQn = 26U, /* timer1 Interrupt for CLIC*/ + TIM2_IRQn = 27U + APLIC_IRQ_OFFSET, /* timer2 Interrupt */ + TIM3_IRQn = 28U + APLIC_IRQ_OFFSET, /* timer3 Interrupt */ + IOPMP0_IRQn = 32U, /* iopmp0 Interrupt */ + END_IRQn = 1024U + APLIC_IRQ_OFFSET +} irqn_type_t; +#else +/* extern irq number, 1-16 are reserved for inner-cpu */ +typedef enum IRQn { + L2_CACHE_ECC_IRQn = 1U, /* l2 cache ecc Interrupt */ + + DW_DMA0_IRQn = 17U, /* dma0 Interrupt */ + DW_UART0_IRQn = 20U, /* uart Interrupt */ + TIM0_IRQn = 25U, /* timer0 Interrupt */ + TIM1_IRQn = 26U, /* timer1 Interrupt */ + TIM2_IRQn = 27U, /* timer2 Interrupt */ + TIM3_IRQn = 28U, /* timer3 Interrupt */ + IOPMP0_IRQn = 32U, /* iopmp0 Interrupt */ +} irqn_type_t; +#endif /* CONFIG_INTC_CLIC_PLIC */ + +#define DW_UART0_BASE (0x1900d000UL) +#define DW_TIMER0_BASE (0x19001000UL) +#define DW_TIMER1_BASE (0x19001014UL) +#define DW_TIMER2_BASE (0x19001028UL) +#define DW_TIMER3_BASE (0x1900103CUL) +#if CONFIG_SUPPORT_NMI_DEMO +/* fake irq is not work, just for nmi test with smartl fpga(connected TIMER4 to nmi-exception on soc bit of smartl) */ +#define FAKE_IRQ_TIMER4 (-1) +#define DW_TIMER4_BASE (0x40021000UL) +#endif + +///////////////////////////////////////////////// +#define DW_DMA0_BASE (0x18000000UL) +#define XT_IOPMP0_BASE (0x26f00000UL) + +#define CONFIG_AXI_DMA_CHANNEL_NUM 8U +#define CONFIG_AXI_DMA_FIFO_SIZE 0x8U +#define CONFIG_AXI_DMA_BLK_MAX_SIZE 0x3FFFFFU + +// #define CONFIG_AHB_DMA_CHANNEL_NUM 8U +// #define CONFIG_AHB_DMA_FIFO_SIZE 0x8U +// #define CONFIG_AHB_DMA_BLK_MAX_SIZE 0xFFFU +///////////////////////////////////////////////// + +#else +#error "Not support soc!!!" +#endif /* CONFIG_BOARD_XIAOHUI_EVB */ + +#endif /* end exx*/ + +#if CONFIG_INTC_CLIC && CONFIG_INTC_PLIC +#error "CONFIG_INTC_CLIC and CONFIG_INTC_PLIC cannot coexist" +#endif + +#if CONFIG_INTC_CLIC && CONFIG_INTC_APLIC +#error "CONFIG_INTC_CLIC and CONFIG_INTC_APLIC cannot coexist" +#endif + +#if CONFIG_INTC_PLIC && CONFIG_INTC_APLIC +#error "CONFIG_INTC_PLIC and CONFIG_INTC_APLIC cannot coexist" +#endif + +#if CONFIG_INTC_CLIC && CONFIG_INTC_CLIC_PLIC +#error "CONFIG_INTC_CLIC and CONFIG_INTC_CLIC_PLIC cannot coexist" +#endif + +#if CONFIG_INTC_CLIC && CONFIG_INTC_CLIC_APLIC +#error "CONFIG_INTC_CLIC and CONFIG_INTC_CLIC_APLIC cannot coexist" +#endif + +#if CONFIG_INTC_CLIC_PLIC && CONFIG_INTC_CLIC_APLIC +#error "CONFIG_INTC_CLIC_PLIC and CONFIG_INTC_CLIC_APLIC cannot coexist" +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _SOC_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/include/sys_clk.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/include/sys_clk.h new file mode 100644 index 00000000..3d74f5e9 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/include/sys_clk.h @@ -0,0 +1,117 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 sys_clk.h + * @brief header file for setting system frequency. + * @version V1.0 + * @date 9. April 2020 + ******************************************************************************/ +#ifndef _SYS_CLK_H_ +#define _SYS_CLK_H_ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define PMU_REG_BASE (wj_pmu_reg_t *)WJ_PMU_BASE + +typedef enum { + IHS_CLK = 0U, /* internal high speed clock */ + EHS_CLK, /* external high speed clock */ + ILS_CLK, /* internal low speed clock */ + ELS_CLK, /* external low speed clock */ + PLL_CLK /* PLL clock */ +} clk_src_t; + +typedef enum { + CPU_24MHZ = 24000000U +} sys_freq_t; + + +/* pllclkout : ( pllclkin / 2)*( FN + Frac/4096 ) */ +typedef struct { + + uint32_t pll_is_used; /* pll is used */ + + uint32_t pll_source; /* select pll input source clock */ + + uint32_t pll_src_clk_divider; /* ratio between pll_srcclk clock and pll_clkin clock */ + + uint32_t fn; /* integer value of frequency division */ + + uint32_t frac; /* decimal value of frequency division */ + +} pll_config_t; + + +typedef struct { + uint32_t system_clk; /* system clock */ + + pll_config_t pll_config; /* pll config struct */ + + uint32_t sys_clk_source; /* select sysclk source clock */ + + uint32_t rtc_clk_source; /* select rtcclk source clock */ + + uint32_t mclk_divider; /* ratio between fs_mclk clock and mclk clock */ + + uint32_t apb0_clk_divider; /* ratio between mclk clock and apb0 clock */ + + uint32_t apb1_clk_divider; /* ratio between mclk clock and apb1 clock */ + +} system_clk_config_t; + +typedef enum { + CLK_DIV1 = 0U, +} apb_div_t; + +typedef enum { + PLL_FN_18 = 0U, +} pll_fn_t; + +typedef enum { + UART0_CLK, +} clk_module_t; + + +/** + \brief Set the system clock according to the parameter + \param[in] config system clock config. + \return error code +*/ +csi_error_t soc_sysclk_config(system_clk_config_t *config); + +/** + \brief Set iic reset + \param[in] idx iic idx. + \return Null +*/ +void soc_reset_iic(uint32_t idx); + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_CLK_H_ */ + diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/arch/e906fdp/startup.S b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/arch/e906fdp/startup.S new file mode 100644 index 00000000..2c6f8c3e --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/arch/e906fdp/startup.S @@ -0,0 +1,224 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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. + */ + +#include + +#if !CONFIG_SUPPORT_NON_VECTOR_IRQ +.section .vectors, "aw", @progbits + .align 6 + .globl __Vectors + .type __Vectors, @object +__Vectors: + .long Default_Handler + .long Default_Handler + .long Default_Handler + .long tspend_handler + .long Default_Handler + .long Default_Handler + .long Default_Handler + .long Default_IRQHandler + .long Default_Handler + .long Default_Handler + .long Default_Handler + .long Default_Handler + .long Default_Handler + .long Default_Handler + .long Default_Handler + .long Default_Handler + + /* External interrupts */ + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler + .long Default_IRQHandler +#else /* CONFIG_SUPPORT_NON_VECTOR_IRQ */ +.section .vectors, "aw", @progbits + .align 6 + .globl __Vectors + .type __Vectors, @object +__Vectors: + .long do_irq + .long do_irq + .long do_irq + .long tspend_handler + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + + /* External interrupts */ + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq + .long do_irq +#endif /* CONFIG_SUPPORT_NON_VECTOR_IRQ */ + + .size __Vectors, . - __Vectors + + .text + .align 2 + j Reset_Handler + .align 2 + .long 0x594B5343 /* CSKY ASCII */ + .long 0x594B5343 /* CSKY ASCII */ + .align 2 +_start: + .text + .align 2 + .global Reset_Handler + .type Reset_Handler, %function +Reset_Handler: +.option push +.option norelax + la gp, __global_pointer$ +.option pop + la a0, Default_Handler + ori a0, a0, 3 + csrw mtvec, a0 + + la a0, __Vectors + csrw mtvt, a0 + + la sp, g_top_irqstack + csrw mscratch, sp +#ifdef CONFIG_KERNEL_NONE + la sp, g_top_mainstack +#endif + +#ifndef __NO_SYSTEM_INIT + jal SystemInit +#endif + + jal pre_main + + .size Reset_Handler, . - Reset_Handler + +__exit: + j __exit + +.section .stack, "aw", @nobits + .align 4 + .global g_base_irqstack + .global g_top_irqstack +g_base_irqstack: + .space CONFIG_ARCH_INTERRUPTSTACK +g_top_irqstack: +#ifdef CONFIG_KERNEL_NONE + .align 4 + .global g_base_mainstack + .global g_top_mainstack +g_base_mainstack: + .space CONFIG_ARCH_MAINSTACK +g_top_mainstack: +#endif + diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/arch/e906fdp/system.c b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/arch/e906fdp/system.c new file mode 100644 index 00000000..4b20c58f --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/arch/e906fdp/system.c @@ -0,0 +1,121 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "riscv_csr.h" + +#if (defined(CONFIG_KERNEL_RHINO) || defined(CONFIG_KERNEL_FREERTOS) || defined(CONFIG_KERNEL_RTTHREAD)) && defined(CONFIG_KERNEL_NONE) +#error "Please check the current system is baremetal or not!!!" +#endif + +extern void section_data_copy(void); +extern void section_ram_code_copy(void); +extern void section_bss_clear(void); + +static void cache_init(void) +{ + csi_dcache_enable(); + csi_icache_enable(); +} + +static void section_init(void) +{ +#if CONFIG_XIP + section_data_copy(); + section_ram_code_copy(); + csi_dcache_clean(); + csi_icache_invalid(); +#endif + section_bss_clear(); +} + +static void clic_init(void) +{ + int i; + + /* get interrupt level from info */ + CLIC->CLICCFG = (((CLIC->CLICINFO & CLIC_INFO_CLICINTCTLBITS_Msk) >> CLIC_INFO_CLICINTCTLBITS_Pos) << CLIC_CLICCFG_NLBIT_Pos); + + for (i = 0; i < 64; i++) { + CLIC->CLICINT[i].IP = 0; +#if !CONFIG_SUPPORT_NON_VECTOR_IRQ + CLIC->CLICINT[i].ATTR = 1; /* use vector interrupt */ +#else + CLIC->CLICINT[i].ATTR = 0; /* use non-vector interrupt */ +#endif + csi_vic_set_prio(i, 3); + } + /* tspend use vector&positive interrupt */ + CLIC->CLICINT[Machine_Software_IRQn].ATTR = 0x3; + csi_vic_set_prio(Machine_Software_IRQn, 1); + csi_irq_enable(Machine_Software_IRQn); +} + +static void interrupt_init(void) +{ + clic_init(); +#ifdef CONFIG_KERNEL_NONE + __enable_excp_irq(); +#endif +} + +/** + * @brief initialize the system + * Initialize the psr and vbr. + * @param None + * @return None + */ +void SystemInit(void) +{ + extern int cpu_features_init(void); + cpu_features_init(); + + /* enable theadisaee & MM */ + uint32_t status = __get_MXSTATUS(); + status |= (1 << 22 | 1 << 15); + __set_MXSTATUS(status); + +#if __riscv_flen + /* enable float ISA */ + status = __get_MSTATUS(); + status |= (1 << MSTATUS_FS_SHIFT); + __set_MSTATUS(status); +#endif + /* enable mexstatus SPUSHEN and disable SPSWAPEN */ +#if CONFIG_CPU_XUANTIE_E906 || CONFIG_CPU_XUANTIE_E906F || CONFIG_CPU_XUANTIE_E906FD || CONFIG_CPU_XUANTIE_E906P || CONFIG_CPU_XUANTIE_E906FP || CONFIG_CPU_XUANTIE_E906FDP \ + || CONFIG_CPU_XUANTIE_E907 || CONFIG_CPU_XUANTIE_E907F || CONFIG_CPU_XUANTIE_E907FD || CONFIG_CPU_XUANTIE_E907P || CONFIG_CPU_XUANTIE_E907FP || CONFIG_CPU_XUANTIE_E907FDP + status = __get_MEXSTATUS(); + status |= (0x1 << 16); + status &= ~(0x2 << 16); + __set_MEXSTATUS(status); +#endif + + cache_init(); + section_init(); + interrupt_init(); + soc_set_sys_freq(20000000); + csi_tick_init(); +} + diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/arch/e906fdp/trap_c.c b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/arch/e906fdp/trap_c.c new file mode 100644 index 00000000..f36e86b2 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/arch/e906fdp/trap_c.c @@ -0,0 +1,64 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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. + */ + +#include +#include +#include +#include +#if defined(AOS_COMP_DEBUG) && (AOS_COMP_DEBUG > 0) +#include +#else +#define printk printf +#endif + +void (*trap_c_callback)(void); + +void trap_c(uintptr_t *regs) +{ + int i; + unsigned long vec = 0; + + vec = __get_MCAUSE(); + + printk("CPU Exception(mcause);: NO.0x%lx", vec); + printk("\n"); + + for (i = 0; i < 31; i++) { + printk("x%d: %p\t", i + 1, (void *)regs[i]); + + if ((i % 4) == 3) { + printk("\n"); + } + } + + printk("\n"); + printk("mepc : %p\n", (void *)regs[31]); + printk("mstatus: %p\n", (void *)regs[32]); + + if (trap_c_callback) { + trap_c_callback(); + } + + while (1); +} + +__attribute__((weak)) void exceptionHandler(void *context) +{ + trap_c((uintptr_t *)context); +} + diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/arch/e906fdp/vectors.S b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/arch/e906fdp/vectors.S new file mode 100644 index 00000000..5c0aabb2 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/arch/e906fdp/vectors.S @@ -0,0 +1,898 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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. + */ + +#include "riscv_asm_macro.h" + +#define RISCV_MCAUSE_IRQ_POS 31 + +.section .stack, "aw", @nobits + .align 4 + .global g_trapstackbase + .global g_top_trapstack +g_trapstackbase: + .space CONFIG_ARCH_INTERRUPTSTACK +g_top_trapstack: + +#if CONFIG_SUPPORT_IRQ_NESTED +#define IRQ_NESTED_MAX (6) +.section .bss + .align 2 + irq_nested_level: + .long 0 + + irq_nested_mcause: + .long 0, 0, 0, 0, 0, 0 +#endif + +/* for interrupt tail-chaining debug */ +#if CONFIG_DEBUG_TAIL_CHAINING +.global g_irq_tailchain_loops +g_irq_tailchain_loops: +.long 0 +#endif + +.text + +#if !CONFIG_SUPPORT_IRQ_NESTED + .align 2 + .weak Default_IRQHandler + .type Default_IRQHandler, %function +Default_IRQHandler: +#if CONFIG_PROFILING_PERF && CONFIG_PERF_BACKTRACE_USE_FP + addi sp, sp, -4 + sw s0, (sp) +#endif + + csrw mscratch, sp + la sp, g_top_irqstack + addi sp, sp, -76 + sw t0, 4(sp) + sw t1, 8(sp) + csrr t0, mepc + csrr t1, mcause + sw t1, 64(sp) + sw t0, 68(sp) + csrr t1, mstatus + sw t1, 72(sp) + sw ra, 0(sp) + sw t2, 12(sp) + sw a0, 16(sp) + sw a1, 20(sp) + sw a2, 24(sp) + sw a3, 28(sp) + sw a4, 32(sp) + sw a5, 36(sp) + sw a6, 40(sp) + sw a7, 44(sp) + sw t3, 48(sp) + sw t4, 52(sp) + sw t5, 56(sp) + sw t6, 60(sp) + +#if __riscv_dsp + addi sp, sp, -4 + csrr t0, vxsat + sw t0, 0(sp) +#endif /*__riscv_dsp */ + +#if CONFIG_CHECK_FPU_DIRTY + mv t3, t1 +#endif + SAVE_FLOAT_REGISTERS + + la t0, do_irq + jalr t0 + + /* get mcause from sp */ + addi t0, sp, 64 +#if __riscv_dsp + addi t0, t0, 4 +#endif /*__riscv_dsp */ +#if __riscv_flen == 64 + addi t0, t0, 164 +#elif __riscv_flen == 32 + addi t0, t0, 84 +#endif + lw a1, (t0) + andi a0, a1, 0x3FF + slli a0, a0, 2 + + /* clear pending */ + li a2, 0xE0801000 + add a2, a2, a0 + lb a3, 0(a2) + li a4, 1 + not a4, a4 + and a5, a4, a3 + sb a5, 0(a2) + + RESTORE_xSTATUS + + csrw mcause, a1 + + RESTORE_FLOAT_REGISTERS + +#if __riscv_dsp + lw t0, 0(sp) + csrw vxsat, t0 + addi sp, sp, 4 +#endif /*__riscv_dsp */ + + lw t0, 68(sp) + csrw mepc, t0 + lw ra, 0(sp) + lw t0, 4(sp) + lw t1, 8(sp) + lw t2, 12(sp) + lw a0, 16(sp) + lw a1, 20(sp) + lw a2, 24(sp) + lw a3, 28(sp) + lw a4, 32(sp) + lw a5, 36(sp) + lw a6, 40(sp) + lw a7, 44(sp) + lw t3, 48(sp) + lw t4, 52(sp) + lw t5, 56(sp) + lw t6, 60(sp) + + addi sp, sp, 76 + csrr sp, mscratch + +#if CONFIG_PROFILING_PERF && CONFIG_PERF_BACKTRACE_USE_FP + addi sp, sp, 4 +#endif + mret +#else /* CONFIG_SUPPORT_IRQ_NESTED */ + .align 2 + .weak Default_IRQHandler + .type Default_IRQHandler, %function +Default_IRQHandler: + addi sp, sp, -8 + sw t0, 0(sp) + sw t1, 4(sp) + + la t0, irq_nested_level + lw t1, (t0) + addi t1, t1, 1 + sw t1, (t0) + + li t0, IRQ_NESTED_MAX + /* nested too deeply, may be error happens */ + bgt t1, t0, Default_Handler + + addi t1, t1, -1 + la t0, irq_nested_mcause + slli t1, t1, 2 + add t0, t0, t1 + csrr t1, mcause + sw t1, (t0) + + la t0, irq_nested_level + lw t1, (t0) + li t0, 1 + bgt t1, t0, .Lnested1 + +#if CONFIG_PROFILING_PERF && CONFIG_PERF_BACKTRACE_USE_FP + addi sp, sp, -8 + sw s0, (sp) + csrr t0, mepc + sw t0, 4(sp) +#endif + + csrw mscratch, sp + la sp, g_top_irqstack + j .Lnested2 +.Lnested1: + lw t0, 0(sp) + lw t1, 4(sp) + addi sp, sp, 8 +.Lnested2: + addi sp, sp, -76 + sw t0, 4(sp) + sw t1, 8(sp) + csrr t0, mepc + csrr t1, mcause + sw t1, 64(sp) + sw t0, 68(sp) + csrr t1, mstatus + sw t1, 72(sp) + + csrs mstatus, 8 + + sw ra, 0(sp) + sw t2, 12(sp) + sw a0, 16(sp) + sw a1, 20(sp) + sw a2, 24(sp) + sw a3, 28(sp) + sw a4, 32(sp) + sw a5, 36(sp) + sw a6, 40(sp) + sw a7, 44(sp) + sw t3, 48(sp) + sw t4, 52(sp) + sw t5, 56(sp) + sw t6, 60(sp) + +#if __riscv_dsp + addi sp, sp, -4 + csrr t0, vxsat + sw t0, 0(sp) +#endif /*__riscv_dsp */ + +#if CONFIG_CHECK_FPU_DIRTY + mv t3, t1 +#endif + SAVE_FLOAT_REGISTERS + + la t0, do_irq + jalr t0 + + csrc mstatus, 8 + + /* get mcause from sp */ + addi t0, sp, 64 +#if __riscv_dsp + addi t0, t0, 4 +#endif /*__riscv_dsp */ +#if __riscv_flen == 64 + addi t0, t0, 164 +#elif __riscv_flen == 32 + addi t0, t0, 84 +#endif + lw a1, (t0) + andi a0, a1, 0x3FF + slli a0, a0, 2 + + /* clear pending */ + li a2, 0xE0801000 + add a2, a2, a0 + lb a3, 0(a2) + li a4, 1 + not a4, a4 + and a5, a4, a3 + sb a5, 0(a2) + + la t0, irq_nested_level + lw t1, (t0) + addi t1, t1, -1 + sw t1, (t0) + bgt t1, zero, .Lnested3 + + RESTORE_xSTATUS + + csrw mcause, a1 + + RESTORE_FLOAT_REGISTERS + +#if __riscv_dsp + lw t0, 0(sp) + csrw vxsat, t0 + addi sp, sp, 4 +#endif /*__riscv_dsp */ + + lw t0, 68(sp) + csrw mepc, t0 + lw ra, 0(sp) + lw t0, 4(sp) + lw t1, 8(sp) + lw t2, 12(sp) + lw a0, 16(sp) + lw a1, 20(sp) + lw a2, 24(sp) + lw a3, 28(sp) + lw a4, 32(sp) + lw a5, 36(sp) + lw a6, 40(sp) + lw a7, 44(sp) + lw t3, 48(sp) + lw t4, 52(sp) + lw t5, 56(sp) + lw t6, 60(sp) + + addi sp, sp, 76 + csrr sp, mscratch +#if CONFIG_PROFILING_PERF && CONFIG_PERF_BACKTRACE_USE_FP + addi sp, sp, 8 +#endif + lw t0, 0(sp) + lw t1, 4(sp) + addi sp, sp, 8 + mret + +.Lnested3: + /* keep mpil in current mcause & load exception code before */ + addi t1, t1, -1 + la t0, irq_nested_mcause + slli t1, t1, 2 + add t1, t0, t1 + lw t0, (t1) + andi t0, t0, 0x3FF + andi a0, a1, 0xFFFFFC00 + or t0, a0, t0 + csrw mcause, t0 + + RESTORE_xSTATUS + + RESTORE_FLOAT_REGISTERS + +#if __riscv_dsp + lw t0, 0(sp) + csrw vxsat, t0 + addi sp, sp, 4 +#endif /*__riscv_dsp */ + + lw t0, 68(sp) + csrw mepc, t0 + + lw ra, 0(sp) + lw t0, 4(sp) + lw t1, 8(sp) + lw t2, 12(sp) + lw a0, 16(sp) + lw a1, 20(sp) + lw a2, 24(sp) + lw a3, 28(sp) + lw a4, 32(sp) + lw a5, 36(sp) + lw a6, 40(sp) + lw a7, 44(sp) + lw t3, 48(sp) + lw t4, 52(sp) + lw t5, 56(sp) + lw t6, 60(sp) + + addi sp, sp, 76 + mret +#endif /* CONFIG_SUPPORT_IRQ_NESTED */ + +/****************************************************************************** + * Functions: + * void trap(void); + * default exception handler + ******************************************************************************/ + .align 2 + .global trap + .type trap, %function +trap: + csrw mscratch, sp + la sp, g_top_trapstack + addi sp, sp, -140 + sw x1, ( 0 )(sp) + sw x3, ( 8 )(sp) + sw x4, ( 12)(sp) + sw x5, ( 16)(sp) + sw x6, ( 20)(sp) + sw x7, ( 24)(sp) + sw x8, ( 28)(sp) + sw x9, ( 32)(sp) + sw x10,( 36)(sp) + sw x11,( 40)(sp) + sw x12,( 44)(sp) + sw x13,( 48)(sp) + sw x14,( 52)(sp) + sw x15,( 56)(sp) + sw x16,( 60)(sp) + sw x17,( 64)(sp) + sw x18,( 68)(sp) + sw x19,( 72)(sp) + sw x20,( 76)(sp) + sw x21,( 80)(sp) + sw x22,( 84)(sp) + sw x23,( 88)(sp) + sw x24,( 92)(sp) + sw x25,( 96)(sp) + sw x26,(100)(sp) + sw x27,(104)(sp) + sw x28,(108)(sp) + sw x29,(112)(sp) + sw x30,(116)(sp) + sw x31,(120)(sp) + csrr a0, mepc + sw a0, (124)(sp) + csrr a0, mstatus + sw a0, (128)(sp) + csrr a0, mcause + sw a0, (132)(sp) + csrr a0, mtval + sw a0, (136)(sp) + csrr a0, mscratch + sw a0, ( 4 )(sp) + + mv a0, sp + la a1, exceptionHandler + jalr a1 + +/******************************************************************************* + * Functions: + * void Default_Handler(void); + * Non-Vector Interrupt Handler,Exception Handler,NMI Handler + ******************************************************************************/ +#if !CONFIG_SUPPORT_IRQ_NESTED + .align 6 + .weak Default_Handler + .type Default_Handler, %function +Default_Handler: + /* Check for nmi */ + addi sp, sp, -8 + sw t0, 0x0(sp) + sw t1, 0x4(sp) + csrr t0, mcause + + srli t1, t0, RISCV_MCAUSE_IRQ_POS + bnez t1, is_interrupt + + andi t0, t0, 0x3FF + li t1, 24 + beq t0, t1, .NMI_Handler + lw t0, 0x0(sp) + lw t1, 0x4(sp) + addi sp, sp, 8 + j trap + +is_interrupt: + lw t0, 0x0(sp) + lw t1, 0x4(sp) + addi sp, sp, 8 +#if CONFIG_PROFILING_PERF && CONFIG_PERF_BACKTRACE_USE_FP + addi sp, sp, -4 + sw s0, (sp) +#endif + csrw mscratch, sp + la sp, g_top_irqstack + addi sp, sp, -76 + sw t0, 4(sp) + sw t1, 8(sp) + csrr t0, mepc + csrr t1, mcause + sw t1, 64(sp) + sw t0, 68(sp) + csrr t1, mstatus + sw t1, 72(sp) + + sw ra, 0(sp) + sw t2, 12(sp) + sw a0, 16(sp) + sw a1, 20(sp) + sw a2, 24(sp) + sw a3, 28(sp) + sw a4, 32(sp) + sw a5, 36(sp) + sw a6, 40(sp) + sw a7, 44(sp) + sw t3, 48(sp) + sw t4, 52(sp) + sw t5, 56(sp) + sw t6, 60(sp) + +#if __riscv_dsp + addi sp, sp, -4 + csrr t0, vxsat + sw t0, 0(sp) +#endif /*__riscv_dsp */ + +#if CONFIG_CHECK_FPU_DIRTY + mv t3, t1 +#endif + SAVE_FLOAT_REGISTERS + +#if CONFIG_DEBUG_TAIL_CHAINING + li t2, 0 + la t1, g_irq_tailchain_loops + sw t2, 0(t1) +#endif + + csrrci t0, mnxti, MSTATUS_MIE + beqz t0, irq_done + +irq_loop: +#if CONFIG_DEBUG_TAIL_CHAINING + la t2, g_irq_tailchain_loops + lw t1, 0(t2) + addi t1, t1, 1 + sw t1, 0(t2) +#endif + lw t1, 0(t0) + jalr t1 + csrrci t0, mnxti, MSTATUS_MIE + bnez t0, irq_loop + +irq_done: + RESTORE_xSTATUS + + RESTORE_FLOAT_REGISTERS + +#if __riscv_dsp + lw t0, 0(sp) + csrw vxsat, t0 + addi sp, sp, 4 +#endif /*__riscv_dsp */ + + lw a1, 64(sp) + csrw mcause, a1 + + lw t0, 68(sp) + csrw mepc, t0 + + lw ra, 0(sp) + lw t0, 4(sp) + lw t1, 8(sp) + lw t2, 12(sp) + lw a0, 16(sp) + lw a1, 20(sp) + lw a2, 24(sp) + lw a3, 28(sp) + lw a4, 32(sp) + lw a5, 36(sp) + lw a6, 40(sp) + lw a7, 44(sp) + lw t3, 48(sp) + lw t4, 52(sp) + lw t5, 56(sp) + lw t6, 60(sp) + + addi sp, sp, 76 + csrr sp, mscratch + +#if CONFIG_PROFILING_PERF && CONFIG_PERF_BACKTRACE_USE_FP + addi sp, sp, 4 +#endif + mret + +#else /* CONFIG_SUPPORT_IRQ_NESTED */ + + .align 6 + .weak Default_Handler + .type Default_Handler, %function +Default_Handler: + addi sp, sp, -8 + sw t0, 0x0(sp) + sw t1, 0x4(sp) + + csrr t0, mcause + + /* Check is interrupt */ + srli t1, t0, RISCV_MCAUSE_IRQ_POS + bnez t1, is_interrupt + + /* Check for nmi */ + andi t0, t0, 0x3FF + li t1, 24 + beq t0, t1, .NMI_Handler + + lw t0, 0x0(sp) + lw t1, 0x4(sp) + addi sp, sp, 8 + + /* is exception */ + j trap + +is_interrupt: + la t0, irq_nested_level + lw t1, (t0) + addi t1, t1, 1 + sw t1, (t0) + + li t0, IRQ_NESTED_MAX + /* nested too deeply, may be error happens */ + bgt t1, t0, trap + + addi t1, t1, -1 + la t0, irq_nested_mcause + slli t1, t1, 2 + add t0, t0, t1 + csrr t1, mcause + sw t1, (t0) + + la t0, irq_nested_level + lw t1, (t0) + li t0, 1 + bgt t1, t0, .Nested_Context + +#if CONFIG_PROFILING_PERF && CONFIG_PERF_BACKTRACE_USE_FP + addi sp, sp, -8 + sw s0, (sp) + csrr t0, mepc + sw t0, 4(sp) +#endif + + csrw mscratch, sp + la sp, g_top_irqstack + j .Save_Context + +.Nested_Context: + lw t0, 0(sp) + lw t1, 4(sp) + addi sp, sp, 8 +.Save_Context: + addi sp, sp, -76 + sw t0, 4(sp) + sw t1, 8(sp) + csrr t0, mepc + csrr t1, mcause + sw t1, 64(sp) + sw t0, 68(sp) + csrr t1, mstatus + sw t1, 72(sp) + + sw ra, 0(sp) + sw t2, 12(sp) + sw a0, 16(sp) + sw a1, 20(sp) + sw a2, 24(sp) + sw a3, 28(sp) + sw a4, 32(sp) + sw a5, 36(sp) + sw a6, 40(sp) + sw a7, 44(sp) + sw t3, 48(sp) + sw t4, 52(sp) + sw t5, 56(sp) + sw t6, 60(sp) + +#if __riscv_dsp + addi sp, sp, -4 + csrr t0, vxsat + sw t0, 0(sp) +#endif /*__riscv_dsp */ + +#if CONFIG_CHECK_FPU_DIRTY + mv t3, t1 +#endif + SAVE_FLOAT_REGISTERS + + csrrci t0, mnxti, MSTATUS_MIE + csrs mstatus, 8 /* enable irq for preemption */ + lw t1, 0(t0) /* Get handler from vector table */ + jalr t1 /* Call handler */ + + csrc mstatus, 8 /* disable irq for critical section */ + + /* get mcause from sp */ + addi t0, sp, 64 +#if __riscv_dsp + addi t0, t0, 4 +#endif /*__riscv_dsp */ +#if __riscv_flen == 64 + addi t0, t0, 164 +#elif __riscv_flen == 32 + addi t0, t0, 84 +#endif + lw a1, (t0) + + la t0, irq_nested_level + lw t1, (t0) + addi t1, t1, -1 + sw t1, (t0) + bgt t1, zero, .Nested_Return + + RESTORE_xSTATUS + + csrw mcause, a1 + + RESTORE_FLOAT_REGISTERS + +#if __riscv_dsp + lw t0, 0(sp) + csrw vxsat, t0 + addi sp, sp, 4 +#endif /*__riscv_dsp */ + + lw t0, 68(sp) + csrw mepc, t0 + lw ra, 0(sp) + lw t0, 4(sp) + lw t1, 8(sp) + lw t2, 12(sp) + lw a0, 16(sp) + lw a1, 20(sp) + lw a2, 24(sp) + lw a3, 28(sp) + lw a4, 32(sp) + lw a5, 36(sp) + lw a6, 40(sp) + lw a7, 44(sp) + lw t3, 48(sp) + lw t4, 52(sp) + lw t5, 56(sp) + lw t6, 60(sp) + + addi sp, sp, 76 + csrr sp, mscratch +#if CONFIG_PROFILING_PERF && CONFIG_PERF_BACKTRACE_USE_FP + addi sp, sp, 8 +#endif + lw t0, 0(sp) + lw t1, 4(sp) + addi sp, sp, 8 + mret + +.Nested_Return: + /* keep mpil in current mcause & load exception code before */ + addi t1, t1, -1 + la t0, irq_nested_mcause + slli t1, t1, 2 + add t1, t0, t1 + lw t0, (t1) + andi t0, t0, 0x3FF + andi a0, a1, 0xFFFFFC00 + or t0, a0, t0 + csrw mcause, t0 + + RESTORE_xSTATUS + + RESTORE_FLOAT_REGISTERS + +#if __riscv_dsp + lw t0, 0(sp) + csrw vxsat, t0 + addi sp, sp, 4 +#endif /*__riscv_dsp */ + + lw t0, 68(sp) + csrw mepc, t0 + + lw ra, 0(sp) + lw t0, 4(sp) + lw t1, 8(sp) + lw t2, 12(sp) + lw a0, 16(sp) + lw a1, 20(sp) + lw a2, 24(sp) + lw a3, 28(sp) + lw a4, 32(sp) + lw a5, 36(sp) + lw a6, 40(sp) + lw a7, 44(sp) + lw t3, 48(sp) + lw t4, 52(sp) + lw t5, 56(sp) + lw t6, 60(sp) + + addi sp, sp, 76 + mret +#endif /* CONFIG_SUPPORT_IRQ_NESTED */ +.NMI_Handler: + /* mscratch may be used before */ + addi sp, sp, -4 + csrr t0, mscratch + sw t0, 0x0(sp) + + csrw mscratch, sp + la sp, g_top_trapstack + addi sp, sp, -76 + sw t0, 4(sp) + sw t1, 8(sp) + csrr t0, mepc + csrr t1, mcause + sw t1, 64(sp) + sw t0, 68(sp) + csrr t1, mstatus + sw t1, 72(sp) + + sw ra, 0(sp) + sw t2, 12(sp) + sw a0, 16(sp) + sw a1, 20(sp) + sw a2, 24(sp) + sw a3, 28(sp) + sw a4, 32(sp) + sw a5, 36(sp) + sw a6, 40(sp) + sw a7, 44(sp) + sw t3, 48(sp) + sw t4, 52(sp) + sw t5, 56(sp) + sw t6, 60(sp) + +#if __riscv_dsp + addi sp, sp, -4 + csrr t0, vxsat + sw t0, 0(sp) +#endif /*__riscv_dsp */ + +#if CONFIG_CHECK_FPU_DIRTY + mv t3, t1 +#endif + SAVE_FLOAT_REGISTERS + + la t0, handle_nmi_exception + jalr t0 + + /* get mcause from sp */ + addi t0, sp, 64 +#if __riscv_dsp + addi t0, t0, 4 +#endif /*__riscv_dsp */ +#if __riscv_flen == 64 + addi t0, t0, 164 +#elif __riscv_flen == 32 + addi t0, t0, 84 +#endif + lw a1, (t0) + andi a0, a1, 0x3FF + slli a0, a0, 2 + + /* clear pending */ + li a2, 0xE0801000 + add a2, a2, a0 + lb a3, 0(a2) + li a4, 1 + not a4, a4 + and a5, a4, a3 + sb a5, 0(a2) + + RESTORE_xSTATUS + + csrw mcause, a1 + + RESTORE_FLOAT_REGISTERS + +#if __riscv_dsp + lw t0, 0(sp) + csrw vxsat, t0 + addi sp, sp, 4 +#endif /*__riscv_dsp */ + + lw t0, 68(sp) + csrw mepc, t0 + lw t0, 72(sp) + csrw mstatus, t0 + + lw ra, 0(sp) + lw t0, 4(sp) + lw t1, 8(sp) + lw t2, 12(sp) + lw a0, 16(sp) + lw a1, 20(sp) + lw a2, 24(sp) + lw a3, 28(sp) + lw a4, 32(sp) + lw a5, 36(sp) + lw a6, 40(sp) + lw a7, 44(sp) + lw t3, 48(sp) + lw t4, 52(sp) + lw t5, 56(sp) + lw t6, 60(sp) + + addi sp, sp, 76 + csrr sp, mscratch + + /* restore mscratch */ + lw t0, 0x0(sp) + csrw mscratch, t0 + addi sp, sp, 4 + + lw t0, 0x0(sp) + lw t1, 0x4(sp) + addi sp, sp, 8 + + mret + + .size Default_Handler, . - Default_Handler + +/* Macro to define default handlers. Default handler + * will be weak symbol and just dead loops. They can be + * overwritten by other handlers */ + .macro def_irq_handler handler_name + .weak \handler_name + .set \handler_name, Default_Handler + .endm diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/drivers/dw_uart_ll.c b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/drivers/dw_uart_ll.c new file mode 100644 index 00000000..15ae00be --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/drivers/dw_uart_ll.c @@ -0,0 +1,164 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 dw_uart_ll.c + * @brief dw uart ll driver + * @version V1.0 + * @date 18. December 2024 + ******************************************************************************/ +#include + +int32_t dw_uart_wait_idle(dw_uart_regs_t *uart_base) +{ + uint32_t timecount = 0U; + int32_t ret = 0; + + while ((uart_base->USR & DW_UART_USR_BUSY_SET) && (timecount < UART_BUSY_TIMEOUT)) { + timecount++; + } + + if (timecount >= UART_BUSY_TIMEOUT) { + ret = -1; + } + + return ret; +} + +int32_t dw_uart_wait_timeout(dw_uart_regs_t *uart_base) +{ + uint32_t timecount = 0U; + int32_t ret = 0; + + while ((uart_base->LSR & 0x81U) || (uart_base->USR & 0x1U)) { + uart_base->LSR; + uart_base->RBR; + timecount++; + + if (timecount >= UART_BUSY_TIMEOUT) { + ret = -1; + break; + } + } + + if (ret == 0) { + ret = dw_uart_wait_idle(uart_base); + } + + return ret; +} + +int32_t dw_uart_config_baudrate(dw_uart_regs_t *uart_base, uint32_t baud, uint32_t uart_freq) +{ + uint32_t divisor; + int32_t ret = 0; + ret = dw_uart_wait_timeout(uart_base); + + if (ret == 0) { + if ((uart_freq / 16) % baud >= (baud / 2)) + divisor = (uart_freq / 16) / baud + 1; + else + divisor = (uart_freq / 16) / baud; + + uart_base->LCR |= DW_UART_LCR_DLAB_EN; + + /* DLL and DLH is lower 8-bits and higher 8-bits of divisor.*/ + uart_base->DLH = (divisor >> 8U) & 0xFFU; + uart_base->DLL = divisor & 0xFFU; + /* + * The DLAB must be cleared after the baudrate is setted + * to access other registers. + */ + uart_base->LCR &= (~DW_UART_LCR_DLAB_EN); + } + + return ret; +} + +int32_t dw_uart_config_stop_bits(dw_uart_regs_t *uart_base, uint32_t stop_bits) +{ + int32_t ret; + ret = dw_uart_wait_timeout(uart_base); + + if (ret == 0) { + + //when data length is 5 bits, use dw_uart_config_stop_bits_2 will be 1.5 stop bits + if (stop_bits == 1U) { + dw_uart_config_stop_bits_1(uart_base); + } else if (stop_bits == 2U) { + dw_uart_config_stop_bits_2(uart_base); + } + } + + //FIXME: no console output sometimes + mdelay(1); + + return ret; +} + +int32_t dw_uart_config_parity_none(dw_uart_regs_t *uart_base) +{ + int32_t ret; + ret = dw_uart_wait_timeout(uart_base); + + if (ret == 0) { + uart_base->LCR &= (~DW_UART_LCR_PEN_EN); + } + + return ret; +} + +int32_t dw_uart_config_parity_odd(dw_uart_regs_t *uart_base) +{ + int32_t ret; + + ret = dw_uart_wait_timeout(uart_base); + + if (ret == 0) { + uart_base->LCR |= DW_UART_LCR_PEN_EN; + uart_base->LCR &= ~(DW_UART_LCR_EPS_EN); + } + + return ret; +} + +int32_t dw_uart_config_parity_even(dw_uart_regs_t *uart_base) +{ + int32_t ret; + + ret = dw_uart_wait_timeout(uart_base); + + if (ret == 0) { + uart_base->LCR |= DW_UART_LCR_PEN_EN; + uart_base->LCR |= DW_UART_LCR_EPS_EN; + } + + return ret; +} + +int32_t dw_uart_config_data_bits(dw_uart_regs_t *uart_base, uint32_t data_bits) +{ + int32_t ret; + + ret = dw_uart_wait_timeout(uart_base); + + uart_base->LCR &= 0xFCU; + uart_base->LCR |= (data_bits - 5U); + + return ret; +} diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/drivers/uart.c b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/drivers/uart.c new file mode 100644 index 00000000..5f335b4d --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/drivers/uart.c @@ -0,0 +1,809 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 uart.c + * @brief CSI Source File for uart Driver + * @version V2.01 + * @date 2020-04-09 + ******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define UART_TIMEOUT 0x10000000U +#define UART_MAX_FIFO 0x10U + +extern uint16_t uart_tx_hs_num[]; +extern uint16_t uart_rx_hs_num[]; +extern const csi_pinmap_t uart_pinmap[]; + +static uint8_t find_max_prime_num(uint32_t num) +{ + uint8_t ret; + + if (!(num % 8U)) { + ret = 8U; + } else if (!(num % 4U)) { + ret = 4U; + } else { + ret = 1U; + } + + return ret; +} + +static void dw_uart_intr_recv_data(csi_uart_t *uart) +{ + dw_uart_regs_t *uart_base = (dw_uart_regs_t *)HANDLE_REG_BASE(uart); + uint32_t rxfifo_num = 1;/// uart->rx_size) ? uart->rx_size : rxfifo_num; + + if ((uart->rx_data == NULL) || (uart->rx_size == 0U)) { + if (uart->callback) { + uart->callback(uart, UART_EVENT_RECEIVE_FIFO_READABLE, uart->arg); + } else { + do { + dw_uart_getchar(uart_base); + } while (--rxfifo_num); + } + } else { + do { + *uart->rx_data = dw_uart_getchar(uart_base); + uart->rx_size--; + uart->rx_data++; + } while (--rxdata_num); + + if (uart->rx_size == 0U) { + uart->state.readable = 1U; + + if (uart->callback) { + uart->callback(uart, UART_EVENT_RECEIVE_COMPLETE, uart->arg); + } + } + } +} + +static void uart_intr_send_data(csi_uart_t *uart) +{ + uint32_t i = 0U, trans_num = 0U; + dw_uart_regs_t *uart_base = (dw_uart_regs_t *)uart->dev.reg_base; + + if (uart->tx_size > UART_MAX_FIFO) { + trans_num = UART_MAX_FIFO; + } else { + trans_num = uart->tx_size; + } + + for (i = 0U; i < trans_num; i++) { + //dw_uart_putchar(uart_base, *uart->tx_data); + csi_uart_putc(uart, *uart->tx_data); + uart->tx_size--; + uart->tx_data++; + } + + if (uart->tx_size == 0U) { + dw_uart_disable_trans_irq(uart_base); + uart->state.writeable = 1U; + + if (uart->callback) { + uart->callback(uart, UART_EVENT_SEND_COMPLETE, uart->arg); + } + } +} + +static void uart_intr_line_error(csi_uart_t *uart) +{ + uint32_t uart_status; + dw_uart_regs_t *uart_base = (dw_uart_regs_t *)HANDLE_REG_BASE(uart); + + uart->state.readable = 1U; + uart->state.writeable = 1U; + uart_status = dw_uart_get_line_status(uart_base); + + if (uart->callback) { + if (uart_status & DW_UART_LSR_OE_ERROR) { + uart->callback(uart, UART_EVENT_ERROR_OVERFLOW, uart->arg); + } + + if (uart_status & DW_UART_LSR_PE_ERROR) { + uart->callback(uart, UART_EVENT_ERROR_PARITY, uart->arg); + } + + if (uart_status & DW_UART_LSR_FE_ERROR) { + uart->callback(uart, UART_EVENT_ERROR_FRAMING, uart->arg); + } + + if (uart_status & DW_UART_LSR_BI_SET) { + uart->callback(uart, UART_ENENT_BREAK_INTR, uart->arg); + } + } +} + +void dw_uart_irq_handler(void *arg) +{ + csi_uart_t *uart = (csi_uart_t *)arg; + dw_uart_regs_t *uart_base = (dw_uart_regs_t *)uart->dev.reg_base; + + uint8_t intr_state; + + intr_state = (uint8_t)(uart_base->IIR & 0xfU); + + switch (intr_state) { + case DW_UART_IIR_IID_RECV_LINE_STATUS: /* interrupt source: Overrun/parity/framing errors or break interrupt */ + uart_intr_line_error(uart); + break; + + case DW_UART_IIR_IID_THR_EMPTY: /* interrupt source:sendter holding register empty */ + uart_intr_send_data(uart); + break; + + case DW_UART_IIR_IID_RECV_DATA_AVAIL: /* interrupt source:receiver data available or receiver fifo trigger level reached */ + case DW_UART_IIR_IID_CHARACTER_TIMEOUT: + dw_uart_intr_recv_data(uart); + break; + + default: + break; + } +} + +csi_error_t csi_uart_init(csi_uart_t *uart, uint32_t idx) +{ + CSI_PARAM_CHK(uart, CSI_ERROR); + + csi_error_t ret = CSI_OK; + dw_uart_regs_t *uart_base; + + ret = target_get(DEV_DW_UART_TAG, idx, &uart->dev); + + if (ret == CSI_OK) { + uart_base = (dw_uart_regs_t *)HANDLE_REG_BASE(uart); + + dw_uart_fifo_init(uart_base); + + uart->rx_size = 0U; + uart->tx_size = 0U; + uart->rx_data = NULL; + uart->tx_data = NULL; + uart->tx_dma = NULL; + uart->rx_dma = NULL; + dw_uart_disable_trans_irq(uart_base); + dw_uart_disable_recv_irq(uart_base); + dw_uart_disable_auto_flow_control(uart_base); + } + + return ret; +} + +void csi_uart_uninit(csi_uart_t *uart) +{ + CSI_PARAM_CHK_NORETVAL(uart); + + dw_uart_regs_t *uart_base; + uart_base = (dw_uart_regs_t *)HANDLE_REG_BASE(uart); + + uart->rx_size = 0U; + uart->tx_size = 0U; + uart->rx_data = NULL; + uart->tx_data = NULL; + + dw_uart_disable_trans_irq(uart_base); + dw_uart_disable_recv_irq(uart_base); + csi_irq_disable((uint32_t)(uart->dev.irq_num)); + csi_irq_detach((uint32_t)(uart->dev.irq_num)); +} + +csi_error_t csi_uart_baud(csi_uart_t *uart, uint32_t baud) +{ + CSI_PARAM_CHK(uart, CSI_ERROR); + + int32_t ret = 0; + csi_error_t csi_ret = CSI_OK; + dw_uart_regs_t *uart_base; + uart_base = (dw_uart_regs_t *)HANDLE_REG_BASE(uart); + + ret = dw_uart_config_baudrate(uart_base, baud, soc_get_uart_freq((uint32_t)(uart->dev.idx))); + + if (ret == 0) { + csi_ret = CSI_OK; + } else { + csi_ret = CSI_ERROR; + } + + return csi_ret; +} + +csi_error_t csi_uart_format(csi_uart_t *uart, csi_uart_data_bits_t data_bits, + csi_uart_parity_t parity, csi_uart_stop_bits_t stop_bits) +{ + CSI_PARAM_CHK(uart, CSI_ERROR); + + int32_t ret = 0; + csi_error_t csi_ret = CSI_OK; + dw_uart_regs_t *uart_base; + uart_base = (dw_uart_regs_t *)HANDLE_REG_BASE(uart); + + switch (data_bits) { + case UART_DATA_BITS_5: + ret = dw_uart_config_data_bits(uart_base, 5U); + break; + + case UART_DATA_BITS_6: + ret = dw_uart_config_data_bits(uart_base, 6U); + break; + + case UART_DATA_BITS_7: + ret = dw_uart_config_data_bits(uart_base, 7U); + break; + + case UART_DATA_BITS_8: + ret = dw_uart_config_data_bits(uart_base, 8U); + break; + + default: + ret = -1; + break; + } + + if (ret == 0) { + switch (parity) { + case UART_PARITY_NONE: + ret = dw_uart_config_parity_none(uart_base); + break; + + case UART_PARITY_ODD: + ret = dw_uart_config_parity_odd(uart_base); + break; + + case UART_PARITY_EVEN: + ret = dw_uart_config_parity_even(uart_base); + break; + + default: + ret = -1; + break; + } + + if (ret == 0) { + switch (stop_bits) { + case UART_STOP_BITS_1: + ret = dw_uart_config_stop_bits(uart_base, 1U); + break; + + case UART_STOP_BITS_2: + ret = dw_uart_config_stop_bits(uart_base, 2U); + break; + + case UART_STOP_BITS_1_5: + if (data_bits == UART_DATA_BITS_5) { + ret = dw_uart_config_stop_bits(uart_base, 2U); + break; + } + + default: + ret = -1; + break; + } + + if (ret != 0) { + csi_ret = CSI_ERROR; + } + + } else { + csi_ret = CSI_ERROR; + } + + } else { + csi_ret = CSI_ERROR; + } + + return csi_ret; +} + +csi_error_t csi_uart_flowctrl(csi_uart_t *uart, csi_uart_flowctrl_t flowctrl) +{ + CSI_PARAM_CHK(uart, CSI_ERROR); + csi_error_t csi_ret = CSI_OK; + dw_uart_regs_t *uart_base; + uart_base = (dw_uart_regs_t *)HANDLE_REG_BASE(uart); + + switch (flowctrl) { + case UART_FLOWCTRL_CTS: + dw_uart_wait_idle(uart_base); + dw_uart_enable_auto_flow_control(uart_base); + break; + + case UART_FLOWCTRL_RTS_CTS: + dw_uart_wait_idle(uart_base); + dw_uart_enable_auto_flow_control(uart_base); + break; + + case UART_FLOWCTRL_NONE: + dw_uart_wait_idle(uart_base); + break; + + case UART_FLOWCTRL_RTS: + default: + csi_ret = CSI_UNSUPPORTED; + break; + } + + return csi_ret; +} + +void csi_uart_putc(csi_uart_t *uart, uint8_t ch) +{ + CSI_PARAM_CHK_NORETVAL(uart); + + volatile int i = 10; + uint32_t timeout = UART_TIMEOUT; + dw_uart_regs_t *uart_base = (dw_uart_regs_t *)HANDLE_REG_BASE(uart); + + while (!dw_uart_putready(uart_base) && timeout--); + + if (timeout) { + //FIXME: fix print luanma on irq-mode sometimes. maybe hw bug + while (i--); + dw_uart_putchar(uart_base, ch); + } +} + +uint8_t csi_uart_getc(csi_uart_t *uart) +{ + CSI_PARAM_CHK(uart, 0U); + + dw_uart_regs_t *uart_base = (dw_uart_regs_t *)HANDLE_REG_BASE(uart); + + while (!dw_uart_getready(uart_base)); + + return dw_uart_getchar(uart_base); +} + +int32_t csi_uart_receive(csi_uart_t *uart, void *data, uint32_t size, uint32_t timeout) +{ + CSI_PARAM_CHK(uart, CSI_ERROR); + CSI_PARAM_CHK(data, CSI_ERROR); + + uint8_t *temp_data = (uint8_t *)data; + int32_t recv_num = 0; + uint32_t recv_start, timeout_flag = 0U; + uint32_t intr_en_status; + + recv_start = csi_tick_get_ms(); + dw_uart_regs_t *uart_base = (dw_uart_regs_t *)uart->dev.reg_base; + intr_en_status = dw_uart_get_intr_en_status(uart_base); + dw_uart_disable_recv_irq(uart_base); + + while (recv_num < (int32_t)size) { + while (!dw_uart_getready(uart_base)) { + if ((csi_tick_get_ms() - recv_start) >= timeout) { + timeout_flag = 1U; + break; + } + }; + + if (timeout_flag == 0U) { + *temp_data = dw_uart_getchar(uart_base); + temp_data++; + recv_num++; + recv_start = csi_tick_get_ms(); + } else { + break; + } + } + + dw_uart_set_intr_en_status(uart_base, intr_en_status); + + return recv_num; +} + +csi_error_t dw_uart_receive_intr(csi_uart_t *uart, void *data, uint32_t num) +{ + dw_uart_regs_t *uart_base = (dw_uart_regs_t *)HANDLE_REG_BASE(uart); + uart->rx_data = (uint8_t *)data; + uart->rx_size = num; + + dw_uart_enable_recv_irq(uart_base); + + return CSI_OK; +} + +csi_error_t csi_uart_receive_async(csi_uart_t *uart, void *data, uint32_t size) +{ + CSI_PARAM_CHK(uart, CSI_ERROR); + CSI_PARAM_CHK(data, CSI_ERROR); + CSI_PARAM_CHK(uart->callback, CSI_ERROR); + CSI_PARAM_CHK(uart->receive, CSI_ERROR); + + csi_error_t ret; + + ret = uart->receive(uart, data, size); + + if (ret == CSI_OK) { + uart->state.readable = 0U; + } + + return ret; +} + +int32_t csi_uart_send(csi_uart_t *uart, const void *data, uint32_t size, uint32_t timeout) +{ + /* check data and uart */ + CSI_PARAM_CHK(uart, CSI_ERROR); + CSI_PARAM_CHK(data, CSI_ERROR); + CSI_PARAM_CHK(size, CSI_ERROR); + + dw_uart_regs_t *uart_base; + uint8_t *ch = (uint8_t *)data; + int32_t trans_num = 0; + uint32_t send_start, timeout_flag = 0U; + uint32_t intr_en_status; + + uart_base = (dw_uart_regs_t *)uart->dev.reg_base; + /* store the status of intr */ + intr_en_status = dw_uart_get_intr_en_status(uart_base); + dw_uart_disable_trans_irq(uart_base); + + send_start = csi_tick_get_ms(); + + while (trans_num < (int32_t)size) { + while (!dw_uart_putready(uart_base)) { + if ((csi_tick_get_ms() - send_start) >= timeout) { + timeout_flag = 1U; + break; + } + }; + + if (timeout_flag == 0U) { + dw_uart_putchar(uart_base, *ch++); + /* update the timeout */ + send_start = csi_tick_get_ms(); + trans_num++; + } else { + break; + } + } + + dw_uart_set_intr_en_status(uart_base, intr_en_status); + + return trans_num; +} + +csi_error_t dw_uart_send_intr(csi_uart_t *uart, const void *data, uint32_t size) +{ + dw_uart_regs_t *uart_base = (dw_uart_regs_t *)uart->dev.reg_base; + + uart->tx_data = (uint8_t *)data; + uart->tx_size = size; + dw_uart_enable_trans_irq(uart_base); + + return CSI_OK; +} + +csi_error_t csi_uart_send_async(csi_uart_t *uart, const void *data, uint32_t size) +{ + CSI_PARAM_CHK(uart, CSI_ERROR); + CSI_PARAM_CHK(data, CSI_ERROR); + CSI_PARAM_CHK(uart->callback, CSI_ERROR); + CSI_PARAM_CHK(uart->send, CSI_ERROR); + + csi_error_t ret; + ret = uart->send(uart, data, size); + + if (ret == CSI_OK) { + uart->state.writeable = 0U; + } + + return ret; +} + +csi_error_t csi_uart_attach_callback(csi_uart_t *uart, void *callback, void *arg) +{ + CSI_PARAM_CHK(uart, CSI_ERROR); + + dw_uart_regs_t *uart_base; + uart_base = (dw_uart_regs_t *)HANDLE_REG_BASE(uart); + + uart->callback = callback; + uart->arg = arg; + uart->send = dw_uart_send_intr; + uart->receive = dw_uart_receive_intr; + csi_irq_attach((uint32_t)(uart->dev.irq_num), &dw_uart_irq_handler, &uart->dev); + csi_irq_enable((uint32_t)(uart->dev.irq_num)); + dw_uart_enable_recv_irq(uart_base); + + return CSI_OK; +} + +void csi_uart_detach_callback(csi_uart_t *uart) +{ + CSI_PARAM_CHK_NORETVAL(uart); + + dw_uart_regs_t *uart_base; + uart_base = (dw_uart_regs_t *)HANDLE_REG_BASE(uart); + + uart->callback = NULL; + uart->arg = NULL; + uart->send = NULL; + uart->receive = NULL; + dw_uart_disable_recv_irq(uart_base); + csi_irq_disable((uint32_t)(uart->dev.irq_num)); + csi_irq_detach((uint32_t)(uart->dev.irq_num)); +} + +csi_error_t csi_uart_get_state(csi_uart_t *uart, csi_state_t *state) +{ + CSI_PARAM_CHK(uart, CSI_ERROR); + CSI_PARAM_CHK(state, CSI_ERROR); + + *state = uart->state; + + return CSI_OK; +} + +static void dw_uart_dma_event_cb(csi_dma_ch_t *dma, csi_dma_event_t event, void *arg) +{ + csi_uart_t *uart = (csi_uart_t *)dma->parent; + dw_uart_regs_t *uart_base = (dw_uart_regs_t *)HANDLE_REG_BASE(uart); + + if (event == DMA_EVENT_TRANSFER_ERROR) {/* DMA transfer ERROR */ + if ((uart->tx_dma != NULL) && (uart->tx_dma->ch_id == dma->ch_id)) { + csi_dma_ch_stop(dma); + dw_uart_fifo_init(uart_base); + + uart->state.writeable = 1U; + + if (uart->callback) { + uart->callback(uart, UART_EVENT_ERROR_OVERFLOW, uart->arg); + } + } else { + csi_dma_ch_stop(dma); + dw_uart_fifo_init(uart_base); + /* enable received data available */ + dw_uart_enable_recv_irq(uart_base); + + uart->state.readable = 1U; + + if (uart->callback) { + uart->callback(uart, UART_EVENT_ERROR_FRAMING, uart->arg); + } + } + } else if (event == DMA_EVENT_TRANSFER_DONE) {/* DMA transfer complete */ + if ((uart->tx_dma != NULL) && (uart->tx_dma->ch_id == dma->ch_id)) { + + csi_dma_ch_stop(dma); + dw_uart_fifo_init(uart_base); + + uart->state.writeable = 1U; + + if (uart->callback) { + uart->callback(uart, UART_EVENT_SEND_COMPLETE, uart->arg); + } + } else { + csi_dma_ch_stop(dma); + dw_uart_fifo_init(uart_base); + /* enable received data available */ + dw_uart_enable_recv_irq(uart_base); + + uart->state.readable = 1U; + + if (uart->callback) { + uart->callback(uart, UART_EVENT_RECEIVE_COMPLETE, uart->arg); + } + } + } +} + +csi_error_t dw_uart_send_dma(csi_uart_t *uart, const void *data, uint32_t num) +{ + csi_dma_ch_config_t config; + memset(&config, 0, sizeof(csi_dma_ch_config_t)); + uint32_t fcr_reg = UART_FIFO_INIT_CONFIG; + dw_uart_regs_t *uart_base = (dw_uart_regs_t *)HANDLE_REG_BASE(uart); + csi_dma_ch_t *dma_ch = (csi_dma_ch_t *)uart->tx_dma; + + uart->tx_data = (uint8_t *)data; + uart->tx_size = num; + dw_uart_disable_recv_irq(uart_base); + dw_uart_disable_trans_irq(uart_base); + config.src_inc = DMA_ADDR_INC; + config.dst_inc = DMA_ADDR_CONSTANT; + config.src_tw = DMA_DATA_WIDTH_8_BITS; + config.dst_tw = DMA_DATA_WIDTH_8_BITS; + + /* config for wj_dma */ + config.group_len = find_max_prime_num(num); + config.trans_dir = DMA_MEM2PERH; + + /* config for etb */ + config.handshake = uart_tx_hs_num[uart->dev.idx]; + + csi_dma_ch_config(dma_ch, &config); + + fcr_reg &= ~(DW_UART_FCR_TET_Msk); + + if (config.group_len >= (UART_MAX_FIFO / 2U)) { + fcr_reg |= DW_UART_FCR_TET_FIFO_1_2_FULL; + } else if (config.group_len >= (UART_MAX_FIFO / 4U)) { + fcr_reg |= DW_UART_FCR_TET_FIFO_1_4_FULL; + } else if (config.group_len >= (UART_MAX_FIFO / 8U)) { + fcr_reg |= DW_UART_FCR_TET_FIFO_2_CHAR; + } else { + fcr_reg |= DW_UART_FCR_TET_FIFO_EMTPY; + } + + soc_dcache_clean_invalid_range((unsigned long)uart->tx_data, uart->tx_size); + dw_uart_set_fcr_reg(uart_base, fcr_reg); + csi_dma_ch_start(uart->tx_dma, (void *)uart->tx_data, (uint8_t *) & (uart_base->THR), uart->tx_size); + + return CSI_OK; +} + +csi_error_t dw_uart_receive_dma(csi_uart_t *uart, void *data, uint32_t num) +{ + csi_dma_ch_config_t config; + memset(&config, 0, sizeof(csi_dma_ch_config_t)); + csi_error_t ret = CSI_OK; + uint32_t fcr_reg = UART_FIFO_INIT_CONFIG; + dw_uart_regs_t *uart_base = (dw_uart_regs_t *)HANDLE_REG_BASE(uart); + csi_dma_ch_t *dma = (csi_dma_ch_t *)uart->rx_dma; + + dw_uart_disable_trans_irq(uart_base); + dw_uart_disable_recv_irq(uart_base); + uart->rx_data = (uint8_t *)data; + uart->rx_size = num; + config.src_inc = DMA_ADDR_CONSTANT; + config.dst_inc = DMA_ADDR_INC; + config.src_tw = DMA_DATA_WIDTH_8_BITS; + config.dst_tw = DMA_DATA_WIDTH_8_BITS; + config.group_len = find_max_prime_num(num); + config.trans_dir = DMA_PERH2MEM; + config.handshake = uart_rx_hs_num[uart->dev.idx]; + + ret = csi_dma_ch_config(dma, &config); + + if (ret == CSI_OK) { + + fcr_reg &= ~(DW_UART_FCR_RT_Msk); + + if (config.group_len >= (UART_MAX_FIFO / 2U)) { + fcr_reg |= DW_UART_FCR_RT_FIFO_1_2_FULL; + } else if (config.group_len >= (UART_MAX_FIFO / 4U)) { + fcr_reg |= DW_UART_FCR_RT_FIFO_1_4_FULL; + } else { + fcr_reg |= DW_UART_FCR_RT_FIFO_1_CHAR; + } + + soc_dcache_clean_invalid_range((unsigned long)uart->rx_data, uart->rx_size); + dw_uart_set_fcr_reg(uart_base, fcr_reg | DW_UART_FCR_RFIFOR_RESET); + csi_dma_ch_start(uart->rx_dma, (uint8_t *) & (uart_base->RBR), (void *)uart->rx_data, uart->rx_size); + } + + return ret; +} + +csi_error_t csi_uart_link_dma(csi_uart_t *uart, csi_dma_ch_t *tx_dma, csi_dma_ch_t *rx_dma) +{ + CSI_PARAM_CHK(uart, CSI_ERROR); + CSI_PARAM_CHK(uart->callback, CSI_ERROR); + csi_error_t ret = CSI_OK; + + if (tx_dma != NULL) { + tx_dma->parent = uart; + ret = csi_dma_ch_alloc(tx_dma, -1, -1); + + if (ret == CSI_OK) { + csi_dma_ch_attach_callback(tx_dma, dw_uart_dma_event_cb, NULL); + uart->tx_dma = tx_dma; + uart->send = dw_uart_send_dma; + } else { + tx_dma->parent = NULL; + } + } else { + if (uart->tx_dma) { + csi_dma_ch_detach_callback(uart->tx_dma); + csi_dma_ch_free(uart->tx_dma); + uart->tx_dma = NULL; + } + + uart->send = dw_uart_send_intr; + } + + if (ret != CSI_ERROR) { + if (rx_dma != NULL) { + rx_dma->parent = uart; + ret = csi_dma_ch_alloc(rx_dma, -1, -1); + + if (ret == CSI_OK) { + csi_dma_ch_attach_callback(rx_dma, dw_uart_dma_event_cb, NULL); + uart->rx_dma = rx_dma; + uart->receive = dw_uart_receive_dma; + } else { + rx_dma->parent = NULL; + } + } else { + if (uart->rx_dma) { + csi_dma_ch_detach_callback(uart->rx_dma); + csi_dma_ch_free(uart->rx_dma); + uart->rx_dma = NULL; + } + + uart->receive = dw_uart_receive_intr; + } + } + return ret; +} + +#ifdef CONFIG_PM +csi_error_t dw_uart_pm_action(csi_dev_t *dev, csi_pm_dev_action_t action) +{ + CSI_PARAM_CHK(dev, CSI_ERROR); + + csi_error_t ret = CSI_OK; + csi_pm_dev_t *pm_dev = &dev->pm_dev; + dw_uart_regs_t *uart_base = (dw_uart_regs_t *)dev->reg_base; + + switch (action) { + case PM_DEV_SUSPEND: + dw_uart_fifo_disable(uart_base); + dw_uart_fifo_enable(uart_base); + dw_uart_wait_idle(uart_base); + uart_base->LCR |= DW_UART_LCR_DLAB_EN; + csi_pm_dev_save_regs(pm_dev->reten_mem, (uint32_t *)dev->reg_base, 2U); + uart_base->LCR &= (~DW_UART_LCR_DLAB_EN); + csi_pm_dev_save_regs(pm_dev->reten_mem + 2, (uint32_t *)(dev->reg_base + 4U), 1U); + csi_pm_dev_save_regs(pm_dev->reten_mem + 2 + 1, (uint32_t *)(dev->reg_base + 12U), 2U); + break; + + case PM_DEV_RESUME: + dw_uart_fifo_disable(uart_base); + dw_uart_fifo_enable(uart_base); + dw_uart_wait_idle(uart_base); + uart_base->LCR |= DW_UART_LCR_DLAB_EN; + csi_pm_dev_restore_regs(pm_dev->reten_mem, (uint32_t *)dev->reg_base, 2U); + uart_base->LCR &= (~DW_UART_LCR_DLAB_EN); + csi_pm_dev_restore_regs(pm_dev->reten_mem + 2, (uint32_t *)(dev->reg_base + 4U), 1U); + csi_pm_dev_restore_regs(pm_dev->reten_mem + 2 + 1, (uint32_t *)(dev->reg_base + 12U), 2U); + break; + + default: + ret = CSI_ERROR; + break; + } + + return ret; +} + +csi_error_t csi_uart_enable_pm(csi_uart_t *uart) +{ + return csi_pm_dev_register(&uart->dev, dw_uart_pm_action, 20U, 0U); +} + +void csi_uart_disable_pm(csi_uart_t *uart) +{ + csi_pm_dev_unregister(&uart->dev); +} +#endif + diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/sys/devices.c b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/sys/devices.c new file mode 100644 index 00000000..3979c41d --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/sys/devices.c @@ -0,0 +1,87 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const csi_perip_info_t g_soc_info[] = { + {DW_UART0_BASE, DW_UART0_IRQn, 0, DEV_DW_UART_TAG}, + {DW_TIMER0_BASE, TIM0_IRQn, 0, DEV_DW_TIMER_TAG}, + {DW_TIMER1_BASE, TIM1_IRQn, 1, DEV_DW_TIMER_TAG}, + {DW_TIMER2_BASE, TIM2_IRQn, 2, DEV_DW_TIMER_TAG}, + {DW_TIMER3_BASE, TIM3_IRQn, 3, DEV_DW_TIMER_TAG}, +#if CONFIG_SUPPORT_NMI_DEMO + {DW_TIMER4_BASE, FAKE_IRQ_TIMER4, 4, DEV_DW_TIMER_TAG}, +#endif +#if defined(DW_DMA0_BASE) + {DW_DMA0_BASE, DW_DMA0_IRQn, 0, DEV_DW_AHB_DMA_TAG}, + {DW_DMA0_BASE, DW_DMA0_IRQn, 0, DEV_DW_AXI_DMA_TAG}, +#endif +#if defined(XT_IOPMP0_BASE) + {XT_IOPMP0_BASE, IOPMP0_IRQn, 0, DEV_XT_IOPMP_TAG}, +#endif + {0, 0, 0, 0} +}; + +const csi_dma_ch_info_t g_dma_chnum[] = { + {0, 8}, + {DEV_IDX_INVALID, 0}, +}; + +const uint16_t uart_tx_hs_num[1] = {}; +const uint16_t uart_rx_hs_num[1] = {}; + +const csi_dma_ch_desc_t uart0_dma_ch_list[] = { + {0xff, 0xff} +}; + +const csi_dma_ch_spt_list_t dma_spt_list[] = { + {0xFFFFU, 0xFFU, NULL}, +}; + +const csi_pinmap_t gpio_pinmap[] = { + {0xFFFFFFFFU, 0xFFU, 0xFFU, 0xFFFFFFFFU }, +}; + +const csi_pinmap_t uart_pinmap[] = { + {0xFFFFFFFFU, 0xFFU, 0xFFU, 0xFFFFFFFFU }, +}; + +const csi_clkmap_t clk_map[] = { + {0xFFFFFFFFU, 0xFFFFU, 0xFFU} +}; + +const csi_dma_handshake_ctrl_t xs0_dma0_handshake_ctrl_list[] = { + {DEV_IDX_INVALID, DEV_BLANK_TAG, 0xFFU, 0xFFU}, +}; + +const csi_dma_handshake_list_t g_handshake_list[] = { + {0, xs0_dma0_handshake_ctrl_list}, + {DEV_IDX_INVALID, NULL}, +}; diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/sys/feature.c b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/sys/feature.c new file mode 100644 index 00000000..018011df --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/sys/feature.c @@ -0,0 +1,311 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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. + */ + +#include + +// I/D Cache will enable in cache_init +void cpu_features_init(void) +{ +#if CONFIG_CPU_XUANTIE_E901PLUS_CP || CONFIG_CPU_XUANTIE_E901PLUS_B_CP || CONFIG_CPU_XUANTIE_E901PLUS_M_CP || CONFIG_CPU_XUANTIE_E901PLUS_BM_CP + return; +#endif + +#if CONFIG_CPU_XUANTIE_E901_CP || CONFIG_CPU_XUANTIE_E901_B_CP || CONFIG_CPU_XUANTIE_E901_ZM_CP || CONFIG_CPU_XUANTIE_E901_BZM_CP + return; +#endif + +#if CONFIG_CPU_XUANTIE_E902 || CONFIG_CPU_XUANTIE_E902M + return; +#endif + +#if CONFIG_CPU_XUANTIE_E906 || CONFIG_CPU_XUANTIE_E906F || CONFIG_CPU_XUANTIE_E906FD || CONFIG_CPU_XUANTIE_E906P || CONFIG_CPU_XUANTIE_E906FP || CONFIG_CPU_XUANTIE_E906FDP + rv_csr_write(CSR_MXSTATUS, 0x440800); + rv_csr_write(CSR_MHCR, 0x103f & (~0x3)); + return; +#endif + +#if CONFIG_CPU_XUANTIE_E907 || CONFIG_CPU_XUANTIE_E907F || CONFIG_CPU_XUANTIE_E907FD || CONFIG_CPU_XUANTIE_E907P || CONFIG_CPU_XUANTIE_E907FP || CONFIG_CPU_XUANTIE_E907FDP + rv_csr_write(CSR_MXSTATUS, 0x440800); + rv_csr_write(CSR_MHINT, 0x600c); + rv_csr_write(CSR_MHCR, 0x103f & (~0x3)); + return; +#endif + + volatile unsigned int i, cpu_type, cpu_ver, cpu_tnmodel; + unsigned long version[8]; + + /* As CPUID is a fifo register, try to find + * the CPUID[0] whose index(bit[31:28]) == 0 */ + for (i = 0; i < 8; i++) { + version[0] = rv_csr_read(CSR_MCPUID); + if (((version[0]&0xf0000000) >> 28) == 0) + break; + } + + for (i = 1; i < 8; i++) + version[i] = rv_csr_read(CSR_MCPUID); + + cpu_type = (version[0] >> 18) & 0xf; + cpu_tnmodel = (version[0] >> 14) & 0x1; + cpu_ver = (version[1] >> 12) & 0xffff; + + rv_csr_write(CSR_MCOR, 0x70013); + + /* + * Warning: CSR_MCCR2 contains an L2 cache latency setting, + * you need to confirm it by your own soc design. + */ + switch (cpu_type) { + case 0x1: + if (cpu_ver >= 0x0) { + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xe249000b); + rv_csr_write(CSR_MXSTATUS, 0x638000); + rv_csr_write(CSR_MHINT, 0x1ee30c); + rv_csr_write(CSR_MHCR, 0x11ff & (~0x3)); + rv_csr_write(CSR_MHINT2,0x180); + } else { + while(1); + } + break; + case 0x2: + if (cpu_ver >= 0x0) { + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xa042000a); + rv_csr_write(CSR_MXSTATUS, 0x438100); + rv_csr_write(CSR_MHINT, 0x21aa10c); + rv_csr_write(CSR_MHCR, 0x10011ff & (~0x3)); + rv_csr_write(CSR_MHINT4, 0x10000080); +#if __riscv_xlen == 64 + rv_csr_write(CSR_MENVCFG, 0x4000000000000000); +#endif + } else { + while(1); + } + break; + case 0x3: + if (cpu_ver >= 0x1080 && cpu_ver <= 0x10bf) { //1.2.0~1.2.x + rv_csr_write(CSR_MCCR2, 0xe0010009); + rv_csr_write(CSR_MXSTATUS, 0x638000); + rv_csr_write(CSR_MHINT, 0x6e30c); + rv_csr_write(CSR_MHCR, 0x1ff & (~0x3)); + } else if (cpu_ver == 0x10ca) { //1.3.10 + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xe2490009); + rv_csr_write(CSR_MXSTATUS, 0x638000); + rv_csr_write(CSR_MHINT, 0x66e30c); + rv_csr_write(CSR_MHCR, 0x17f & (~0x3)); + rv_csr_write(CSR_MHINT2, 0x420000); + rv_csr_write(CSR_MHINT4, 0x410); + } else if (cpu_ver >= 0x1100 && cpu_ver <= 0x113f) { //1.4.0~1.4.x + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xe2490009); + rv_csr_write(CSR_MXSTATUS, 0x638000); + rv_csr_write(CSR_MHINT, 0x16e30c); + rv_csr_write(CSR_MHCR, 0x1ff & (~0x3)); + } else if (cpu_ver >= 0x1140 && cpu_ver <= 0x117f) { //1.5.0~1.5.x + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xe2490009); + rv_csr_write(CSR_MXSTATUS, 0x638000); + rv_csr_write(CSR_MHINT, 0xe6e30c); + rv_csr_write(CSR_MHINT2, 0x180); + rv_csr_write(CSR_MHCR, 0x1ff & (~0x3)); + } else if (cpu_ver >= 0x1180 && cpu_ver <= 0x1183) { //1.6.0~1.6.3 + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xe249000b); + rv_csr_write(CSR_MXSTATUS, 0x638000); + rv_csr_write(CSR_MHINT, 0x1ee30c); + rv_csr_write(CSR_MHINT2, 0x180); + rv_csr_write(CSR_MHCR, 0x1ff & (~0x3)); + } else if (cpu_ver >= 0x1184 && cpu_ver <= 0x123f) { //1.6.4~1.8.x + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xe249000b); + rv_csr_write(CSR_MXSTATUS, 0x638000); + rv_csr_write(CSR_MHINT, 0x1ee30c); + rv_csr_write(CSR_MHINT2, 0x180); + rv_csr_write(CSR_MHCR, 0x11ff & (~0x3)); + } else if (cpu_ver >= 0x2000 && cpu_ver <= 0x200e) { //2.0.0~2.0.14 + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xe249000b); + rv_csr_write(CSR_MXSTATUS, 0x438000); + rv_csr_write(CSR_MHINT, 0x31ea32c); + rv_csr_write(CSR_MHINT2, 0x180); + rv_csr_write(CSR_MHCR, 0x11ff & (~0x3)); +#if __riscv_xlen == 64 + rv_csr_write(CSR_MENVCFG, 0x4000000000000000); +#endif + } else if (cpu_ver >= 0x200f && cpu_ver <= 0x2045) { //2.0.15~2.1.5 + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xe249000b); + rv_csr_write(CSR_MXSTATUS, 0x438000); + rv_csr_write(CSR_MHINT, 0x11ea32c); + rv_csr_write(CSR_MHINT2, 0x180); + rv_csr_write(CSR_MHCR, 0x11ff & (~0x3)); +#if __riscv_xlen == 64 + rv_csr_write(CSR_MENVCFG, 0x4000000000000000); +#endif + } else if (cpu_ver >= 0x2046 && cpu_ver <= 0x20c3) { //2.1.6~2.3.3 + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xe249000b); + rv_csr_write(CSR_MXSTATUS, 0x438000); + rv_csr_write(CSR_MHINT, 0x31ea32c); + rv_csr_write(CSR_MHINT2, 0x180); + rv_csr_write(CSR_MHCR, 0x11ff & (~0x3)); +#if __riscv_xlen == 64 + rv_csr_write(CSR_MENVCFG, 0x4000000000000000); +#endif + } else if (cpu_ver >= 0x20c4 && cpu_ver <= 0x2fff) { //2.3.4~2.x.x + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xe249000b); + rv_csr_write(CSR_MXSTATUS, 0x438100); + rv_csr_write(CSR_MHINT, 0x31ea32c); + rv_csr_write(CSR_MHINT2, 0x180); + rv_csr_write(CSR_MHCR, 0x11ff & (~0x3)); + rv_csr_write(CSR_MHINT4, 0x2080); +#if __riscv_xlen == 64 + rv_csr_write(CSR_MENVCFG, 0x4000000000000000); +#endif + } else if (cpu_ver >= 0x3000 && cpu_ver <= 0x3fff) { //3.0.0~3.x.x + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xe249000b); + rv_csr_write(CSR_MXSTATUS, 0x438100); + rv_csr_write(CSR_MHINT, 0x31ea32c); + rv_csr_write(CSR_MHINT2, 0x180); + rv_csr_write(CSR_MHCR, 0x11ff & (~0x3)); + rv_csr_write(CSR_MHINT4, 0x2080); +#if __riscv_xlen == 64 + rv_csr_write(CSR_MENVCFG, 0x4000000000000000); +#endif + } else { + while(1); + } + break; + case 0x4: + if (cpu_ver >= 0x1002 && cpu_ver <= 0xffff) { + rv_csr_write(CSR_MHCR, 0x17f & (~0x3)); + rv_csr_write(CSR_MXSTATUS, 0x638000); + rv_csr_write(CSR_MHINT, 0x650c); + } else { + while(1); + } + break; + case 0x5: + if(cpu_tnmodel == 0) { //c908 + if (cpu_ver >= 0x0000 && cpu_ver <= 0x0007) { //0.0.0~0.0.7 + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xe0420008); + rv_csr_write(CSR_MXSTATUS, 0x638000); + rv_csr_write(CSR_MHINT, 0x2c50c); + rv_csr_write(CSR_MHCR, 0x11ff & (~0x3)); + } else if (cpu_ver >= 0x0040 && cpu_ver <= 0x1002) { //0.1.0~1.0.2 + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xa042000a); + rv_csr_write(CSR_MXSTATUS, 0x438000); + rv_csr_write(CSR_MHINT, 0x21aa10c); + rv_csr_write(CSR_MHCR, 0x10011ff & (~0x3)); +#if __riscv_xlen == 64 + rv_csr_write(CSR_MENVCFG, 0x4000000000000000); +#endif + } else if (cpu_ver >= 0x1003 && cpu_ver <= 0x100b) { //1.0.3~1.0.11 + + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xa042000a); + rv_csr_write(CSR_MXSTATUS, 0x438000); + rv_csr_write(CSR_MHINT, 0x1aa10c); + rv_csr_write(CSR_MHCR, 0x10011ff & (~0x3)); +#if __riscv_xlen == 64 + rv_csr_write(CSR_MENVCFG, 0x4000000000000000); +#endif + } else if (cpu_ver >= 0x100c && cpu_ver <= 0x1fff) { //1.0.12~ + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xa042000a); + rv_csr_write(CSR_MXSTATUS, 0x438100); + rv_csr_write(CSR_MHINT, 0x21aa10c); + rv_csr_write(CSR_MHCR, 0x10011ff & (~0x3)); + rv_csr_write(CSR_MHINT4, 0x10000080); +#if __riscv_xlen == 64 + rv_csr_write(CSR_MENVCFG, 0x4000000000000000); +#endif + } else if (cpu_ver >= 0x2000 && cpu_ver <= 0xffff) { //2.0.0~ + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xa042000a); + rv_csr_write(CSR_MXSTATUS, 0x438100); + rv_csr_write(CSR_MHINT, 0x21aa10c); + rv_csr_write(CSR_MHCR, 0x10011ff & (~0x3)); + rv_csr_write(CSR_MHINT4, 0x10000080); +#if __riscv_xlen == 64 + rv_csr_write(CSR_MENVCFG, 0x4000000000000000); +#endif + } else { + while(1); + } + } else if (cpu_tnmodel == 1) { + if (cpu_ver >= 0x0) { + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xA0420002); + rv_csr_write(CSR_MXSTATUS, 0x438100); + rv_csr_write(CSR_MHINT, 0x21AA10C); + rv_csr_write(CSR_MHCR, 0x10011FF & (~0x3)); + rv_csr_write(CSR_MHINT4, 0x10000080); +#if __riscv_xlen == 64 + rv_csr_write(CSR_MENVCFG, 0x4000000000000000); +#endif + } else { + while(1); + } + } else { + while(1); + } + break; + case 0x6: + if (cpu_ver >= 0x0) { + rv_csr_write(CSR_MSMPR, 0x1); + rv_csr_write(CSR_MCCR2, 0xA0420002); + rv_csr_write(CSR_MXSTATUS, 0x438000); + rv_csr_write(CSR_MHINT, 0x3A1AA10C); + rv_csr_write(CSR_MHCR, 0x10011BF & (~0x3)); +#if __riscv_xlen == 64 + rv_csr_write(CSR_MENVCFG, 0x4000000000000000); +#endif + } else { + while(1); + } + break; + case 0x7: + if (cpu_ver >= 0x0) { + rv_csr_clear(CSR_MXSTATUS, 0x1); + rv_csr_write(CSR_MISELECT,CSR_MNASTATUS); + rv_csr_write(CSR_MIREG,0x1e); + } else { + while(1); + } + break; + case 0x8: + if (cpu_ver >= 0x0) { + rv_csr_clear(CSR_MXSTATUS, 0x1); + rv_csr_write(CSR_MISELECT,CSR_MNASTATUS); + rv_csr_write(CSR_MIREG,0x1e); + } else { + while(1); + } + break; + default: + // FIXME: maybe qemu + break; + } +} diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/sys/irq.c b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/sys/irq.c new file mode 100644 index 00000000..dd38678e --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/sys/irq.c @@ -0,0 +1,282 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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. + */ + +#include +#include +#include +#include +#include + +extern uint32_t soc_irq_get_irq_num(void); +extern void soc_irq_end(uint32_t irq_num); + +#if CONFIG_AOS_OSAL +#include +#include +#define CSI_INTRPT_ENTER() aos_kernel_intrpt_enter() +#define CSI_INTRPT_EXIT() aos_kernel_intrpt_exit() +#else +#ifdef CONFIG_KERNEL_FREERTOS +#include +extern int freertos_intrpt_enter(void); +extern int freertos_intrpt_exit(void); +#define CSI_INTRPT_ENTER() freertos_intrpt_enter() +#define CSI_INTRPT_EXIT() freertos_intrpt_exit() +#elif defined(CONFIG_KERNEL_RTTHREAD) +#include +#define printk rt_kprintf +extern void rt_interrupt_enter(void); +extern void rt_interrupt_leave(void); +#define CSI_INTRPT_ENTER() rt_interrupt_enter() +#define CSI_INTRPT_EXIT() rt_interrupt_leave() +#else +#define printk printf +#define CSI_INTRPT_ENTER() +#define CSI_INTRPT_EXIT() +#endif +#endif /* end CONFIG_AOS_OSAL */ + + +#if CONFIG_INTC_IMSIC_APLIC +csi_dev_t *g_cpu_irq_table[CONFIG_NR_CPUS][CONFIG_IRQ_NUM]; +volatile msi_entry_t g_msi_map[CONFIG_NR_CPUS][CONFIG_IRQ_NUM]; +#define g_irq_table g_cpu_irq_table[csi_get_cpu_id()] +#else +csi_dev_t *g_irq_table[CONFIG_IRQ_NUM]; +#endif + +#if defined(CONFIG_SMP) && CONFIG_SMP +volatile uint32_t g_irq_nested_level[CONFIG_NR_CPUS]; +#else +volatile uint32_t g_irq_nested_level; +#endif + +/** + \brief register irq handler(deprecated). + \param[in] irq_num Number of IRQ. + \return None. +*/ +void csi_irq_attach(uint32_t irq_num, void *irq_handler, csi_dev_t *dev) +{ +#if CONFIG_INTC_IMSIC_APLIC + int cpu_id = csi_get_cpu_id(); + int msi_num = csi_imsic_irqnum_alloc(cpu_id, MSI_SOURCE_APLIC, irq_num); + g_cpu_irq_table[cpu_id][msi_num] = dev; + csi_imsic_irq_attach(cpu_id, msi_num, irq_handler); +#else + dev->irq_handler = irq_handler; + g_irq_table[irq_num] = dev; +#endif +} + +/** + \brief Attach irq handler2 for compatible(Recommended). + \param[in] irq_num Number of IRQ. + \param[in] irq_handler2 IRQ Handler. + \param[in] dev The dev to operate + \param[in] arg user data of irq_handler2 + \return None. +*/ +void csi_irq_attach2(uint32_t irq_num, void *irq_handler2, csi_dev_t *dev, void *arg) +{ +#if CONFIG_INTC_IMSIC_APLIC + int cpu_id = csi_get_cpu_id(); + int msi_num = csi_imsic_irqnum_alloc(cpu_id, MSI_SOURCE_APLIC, irq_num); + g_cpu_irq_table[cpu_id][msi_num] = dev; + csi_imsic_irq_attach2(cpu_id, msi_num, irq_handler2, arg); +#else + dev->arg = arg; + dev->irq_handler2 = irq_handler2; + g_irq_table[irq_num] = dev; +#endif +} + +/** + \brief unregister irq handler. + \param[in] irq_num Number of IRQ. + \param[in] irq_handler IRQ Handler. + \return None. +*/ +void csi_irq_detach(uint32_t irq_num) +{ +#if CONFIG_INTC_IMSIC_APLIC + int msi_num = csi_aplic_get_target_eiid(APLIC_BASE, irq_num); + int cpu_id = csi_aplic_get_target_hart(APLIC_BASE, irq_num); + CSI_ASSERT(csi_imsic_irq_detach(cpu_id, msi_num) == CSI_OK); + CSI_ASSERT(csi_imsic_irqnum_free(cpu_id, msi_num) == CSI_OK); + CSI_ASSERT(g_cpu_irq_table[cpu_id][msi_num] != NULL); + g_cpu_irq_table[cpu_id][msi_num] = NULL; +#else + g_irq_table[irq_num] = NULL; +#endif +} + +/** + \brief gets whether in irq context + \return true or false. +*/ +bool csi_irq_context(void) +{ +#if defined(CONFIG_SMP) && CONFIG_SMP + return ((g_irq_nested_level[csi_get_cpu_id()] > 0U) ? true : false); +#else + return ((g_irq_nested_level > 0U) ? true : false); +#endif +} + +static volatile int g_nmi_cnt; +__attribute__((weak)) void handle_nmi_exception(void) +{ + g_nmi_cnt++; +#if CONFIG_SUPPORT_NMI_DEMO + extern void timer_clear_irq(); + timer_clear_irq(); +#endif +} + +//FIXME: For Non CLIC mode +extern void tick_irq_handler(void *arg); +void CORET_IRQHandler(void) +{ +#if defined(CONFIG_SMP) && CONFIG_SMP + g_irq_nested_level[csi_get_cpu_id()]++; +#else + g_irq_nested_level++; +#endif + CSI_INTRPT_ENTER(); + tick_irq_handler(NULL); + CSI_INTRPT_EXIT(); +#if defined(CONFIG_SMP) && CONFIG_SMP + g_irq_nested_level[csi_get_cpu_id()]--; +#else + g_irq_nested_level--; +#endif +} + +#if CONFIG_ECC_L1_ENABLE || CONFIG_ECC_L2_ENABLE +static struct { + int err_cnt_l1; + int err_cnt_l2; +} g_ecc_stat; + +void __attribute__((weak)) ecc_l1_irqhandler(void *arg) +{ + g_ecc_stat.err_cnt_l1++; + + if (!(__get_MCER() >> 31) || (__get_MCER() & (0x1 << 30))) { + /* may be ecc fatal error happens */ + while (1); + } else { + /* clear MCER EE_VLD */ +#if __riscv_xlen == 32 + __set_MCER(0); + __set_MCERH(0); +#else + __set_MCER(0); +#endif + } +} + +void __attribute__((weak)) ecc_l2_irqhandler(void *arg) +{ + g_ecc_stat.err_cnt_l2++; + +#if __riscv_xlen == 32 + if((__get_MCER2H() >> 30) == 0x2) { + /* clear MCER EE_VLD */ + __set_MCER2(0); + __set_MCER2H(0); + } else { + /* may be ecc fatal error happens */ + while (1); + } +#else + if((__get_MCER2() >> 62) == 0x2) { + /* clear MCER EE_VLD */ + __set_MCER2(0); + } else { + /* may be ecc fatal error happens */ + while (1); + } +#endif +} + +void ECC_L1_IRQHandler(void) +{ +#if defined(CONFIG_SMP) && CONFIG_SMP + g_irq_nested_level[csi_get_cpu_id()]++; +#else + g_irq_nested_level++; +#endif + CSI_INTRPT_ENTER(); + ecc_l1_irqhandler(NULL); + CSI_INTRPT_EXIT(); +#if defined(CONFIG_SMP) && CONFIG_SMP + g_irq_nested_level[csi_get_cpu_id()]--; +#else + g_irq_nested_level--; +#endif +} +#endif /* CONFIG_ECC_L1_ENABLE || CONFIG_ECC_L2_ENABLE */ + +/** + \brief dispatching irq handlers(only handle external irq) + \return None. +*/ +void do_irq(void) +{ + uint32_t irqn; + +#if defined(CONFIG_SMP) && CONFIG_SMP + g_irq_nested_level[csi_get_cpu_id()]++; +#else + g_irq_nested_level++; +#endif + CSI_INTRPT_ENTER(); + irqn = soc_irq_get_irq_num(); + + if (irqn > sizeof(g_irq_table) / sizeof(g_irq_table[0]) - 1 ) { + printk("undefined interrupt: irqn = 0x%x\n", irqn); + while(1); + } + if (g_irq_table[irqn]) { + if (g_irq_table[irqn]->irq_handler) { + /* for compatibility */ + g_irq_table[irqn]->irq_handler(g_irq_table[irqn]); + } + else if (g_irq_table[irqn]->irq_handler2) { + g_irq_table[irqn]->irq_handler2(irqn, g_irq_table[irqn]->arg); + } + else { + printk("undefined interrupt2: irqn = 0x%x\n", irqn); + /*the interrupt has no registered isr*/ + while(1); + } + } else { + printk("null irq_handler: irqn = 0x%x\n", irqn); + while(1); + } + + soc_irq_end(irqn); + CSI_INTRPT_EXIT(); +#if defined(CONFIG_SMP) && CONFIG_SMP + g_irq_nested_level[csi_get_cpu_id()]--; +#else + g_irq_nested_level--; +#endif +} diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/sys/irq_port.c b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/sys/irq_port.c new file mode 100644 index 00000000..8caa0588 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/sys/irq_port.c @@ -0,0 +1,147 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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. + */ + +#include +#include +#include +#include + +void soc_irq_enable(uint32_t irq_num) +{ + csi_vic_enable_irq((int32_t)irq_num); +} + +void soc_irq_disable(uint32_t irq_num) +{ + csi_vic_disable_irq((int32_t)irq_num); +} + +bool soc_irq_is_enabled(uint32_t irq_num) +{ + bool ret; + + if (csi_vic_get_enabled_irq((int32_t)irq_num)) { + ret = true; + } else { + ret = false; + } + + return ret; +} + +void soc_irq_priority(uint32_t irq_num, uint32_t priority) +{ + csi_vic_set_prio((int32_t)irq_num, priority); +} + +/** + * @brief get irq vector num + * @return irq no + */ +uint32_t soc_irq_get_irq_num(void) +{ + int hartid = csi_get_cpu_id(); +#if CONFIG_INTC_CLIC + (void) hartid; +#if CONFIG_RISCV_SMODE + return (__get_SCAUSE() & 0x3FFU); +#else + return (__get_MCAUSE() & 0x3FFU); +#endif /* CONFIG_RISCV_SMODE */ +#endif /* CONFIG_INTC_CLIC */ + +#if CONFIG_INTC_PLIC || CONFIG_INTC_CLIC_PLIC + uint32_t num; +#if CONFIG_RISCV_SMODE + uint32_t irqn = __get_SCAUSE() & 0x3FFU; +#else + uint32_t irqn = __get_MCAUSE() & 0x3FFU; +#endif /* CONFIG_RISCV_SMODE */ + if (irqn == Machine_External_IRQn || irqn == Supervisor_External_IRQn) { +#if CONFIG_RISCV_SMODE + num = PLIC_Hn_MSCLAIM_VAL(&PLIC->PLIC_H0_SCLAIM, hartid); +#else + num = PLIC_Hn_MSCLAIM_VAL(&PLIC->PLIC_H0_MCLAIM, hartid); +#endif +#if CONFIG_INTC_CLIC_PLIC + num += PLIC_IRQ_OFFSET; +#endif + } else { + num = irqn; + } + return num; +#endif /* CONFIG_INTC_PLIC || CONFIG_INTC_CLIC_PLIC */ + +#if CONFIG_INTC_APLIC || CONFIG_INTC_CLIC_APLIC + uint32_t num; +#if CONFIG_RISCV_SMODE + uint32_t irqn = __get_SCAUSE() & 0x3FFU; +#else + uint32_t irqn = __get_MCAUSE() & 0x3FFU; +#endif /* CONFIG_RISCV_SMODE */ + if (irqn == Machine_External_IRQn || irqn == Supervisor_External_IRQn) { + num = csi_aplic_read_claimi(APLIC_BASE, hartid); +#if CONFIG_INTC_CLIC_APLIC + num += APLIC_IRQ_OFFSET; +#endif + } else { + num = irqn; + } + return num; +#endif /* CONFIG_INTC_APLIC || CONFIG_INTC_CLIC_APLIC */ + +#if CONFIG_INTC_IMSIC_APLIC + return g_handing_msi_num[hartid]; +#endif +} + +void soc_irq_end(uint32_t irq_num) +{ +#if CONFIG_INTC_CLIC + // DO NOTHING +#endif /* CONFIG_INTC_CLIC */ + + /** + * If aplic works in msi-mode + * and the current interrupt is level-triggered + * need retrigger + */ +#if CONFIG_INTC_IMSIC_APLIC + extern csi_dev_t *g_cpu_irq_table[CONFIG_NR_CPUS][CONFIG_IRQ_NUM]; + csi_aplic_retrigger_level_irq(APLIC_BASE, g_cpu_irq_table[csi_get_cpu_id()][irq_num]->irq_num); +#endif + + +#if CONFIG_INTC_PLIC || CONFIG_INTC_CLIC_PLIC +#if CONFIG_INTC_CLIC_PLIC + if (irq_num <= PLIC_IRQ_OFFSET) { + return; + } + irq_num -= PLIC_IRQ_OFFSET; +#endif /* CONFIG_INTC_CLIC_PLIC */ +#if CONFIG_RISCV_SMODE + PLIC_Hn_MSCLAIM_VAL(&PLIC->PLIC_H0_SCLAIM, csi_get_cpu_id()) = irq_num; +#else + PLIC_Hn_MSCLAIM_VAL(&PLIC->PLIC_H0_MCLAIM, csi_get_cpu_id()) = irq_num; +#endif +#endif /* CONFIG_INTC_PLIC || CONFIG_INTC_CLIC_PLIC */ + +#if CONFIG_INTC_APLIC || CONFIG_INTC_CLIC_APLIC + // DO NOTHING +#endif /* CONFIG_INTC_APLIC || CONFIG_INTC_CLIC_APLIC */ +} diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/sys/pre_main.c b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/sys/pre_main.c new file mode 100644 index 00000000..99e207c5 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/sys/pre_main.c @@ -0,0 +1,103 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 pre_main.c + * @brief source file for the pre_main + * @version V1.0 + * @date 04. April 2024 + ******************************************************************************/ + +#include +#include +#include + +extern unsigned long __heap_start; +extern unsigned long __heap_end; +unsigned long g_heap_start = (unsigned long)&__heap_start; +unsigned long g_heap_end = (unsigned long)&__heap_end; + +extern int main(void); +/* + * The ranges of copy from/to are specified by following symbols + * __erodata: LMA of start of the section to copy from. Usually end of rodata + * __data_start__: VMA of start of the section to copy to + * __data_end__: VMA of end of the section to copy to + * + * All addresses must be aligned to 4 bytes boundary. + */ +void section_data_copy(void) +{ + extern unsigned long __erodata; + extern unsigned long __data_start__; + extern unsigned long __data_end__; + + if (((unsigned long)&__erodata != (unsigned long)&__data_start__)) { + unsigned long src_addr = (unsigned long)&__erodata; + memcpy((void *)(&__data_start__), \ + (void *)src_addr, \ + (unsigned long)(&__data_end__) - (unsigned long)(&__data_start__)); + } +} + +void section_ram_code_copy(void) +{ + extern unsigned long __erodata; + extern unsigned long __data_start__; + extern unsigned long __data_end__; + extern unsigned long __ram_code_start__; + extern unsigned long __ram_code_end__; + + if (((unsigned long)&__erodata != (unsigned long)&__data_start__)) { + unsigned long src_addr = (unsigned long)&__erodata; + src_addr += (unsigned long)(&__data_end__) - (unsigned long)(&__data_start__); + memcpy((void *)(&__ram_code_start__), \ + (void *)src_addr, \ + (unsigned long)(&__ram_code_end__) - (unsigned long)(&__ram_code_start__)); + } +} + +/* + * The BSS section is specified by following symbols + * __bss_start__: start of the BSS section. + * __bss_end__: end of the BSS section. + * + * Both addresses must be aligned to 4 bytes boundary. + */ +void section_bss_clear(void) +{ + extern unsigned long __bss_start__; + extern unsigned long __bss_end__; + + memset((void *)(&__bss_start__), \ + 0, \ + (unsigned long)(&__bss_end__) - (unsigned long)(&__bss_start__)); + +} + +__attribute__((weak)) void pre_main(void) +{ +#if (!defined(CONFIG_KERNEL_RHINO)) && (!defined(CONFIG_NUTTXMM_NONE)) \ + && (!defined(CONFIG_KERNEL_FREERTOS)) && (!defined(CONFIG_KERNEL_RTTHREAD)) \ + && (!defined(CONFIG_KERNEL_THREADX)) + extern void mm_heap_initialize(void); + mm_heap_initialize(); +#endif + + main(); +} diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/sys/sys_clk.c b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/sys/sys_clk.c new file mode 100644 index 00000000..f79105e8 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/sys/sys_clk.c @@ -0,0 +1,100 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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. + */ + +#include +#include +#include +#include + +uint32_t g_system_clock = IHS_VALUE; + +#if CONFIG_BOARD_XIAOHUI_EVB +uint32_t soc_get_cpu_freq(uint32_t idx) +{ +#ifndef CONFIG_CPU_FREQ_HZ + return 50*1000000; +#else + return CONFIG_CPU_FREQ_HZ; +#endif +} + +uint32_t soc_get_coretim_freq(void) +{ + return 25*1000000; +} + +uint32_t soc_get_uart_freq(uint32_t idx) +{ + return 36*1000000; +} + +uint32_t soc_get_timer_freq(uint32_t idx) +{ + return 25*1000000; +} + +#else +uint32_t soc_get_cpu_freq(uint32_t idx) +{ + return g_system_clock; +} + +uint32_t soc_get_cur_cpu_freq(void) +{ + return g_system_clock; +} + +uint32_t soc_get_coretim_freq(void) +{ + return g_system_clock; +} + +uint32_t soc_get_uart_freq(uint32_t idx) +{ + return g_system_clock; +} + +csi_error_t soc_sysclk_config(system_clk_config_t *config) +{ + return CSI_OK; +} + +void soc_reset_uart(uint32_t idx) +{ +} + +uint32_t soc_get_timer_freq(uint32_t idx) +{ + return g_system_clock; +} +#endif + +void soc_clk_enable(int32_t module) +{ +} + +void soc_clk_disable(int32_t module) +{ +} + +void soc_set_sys_freq(uint32_t val) +{ + g_system_clock = val; +} + + diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/sys/target_get.c b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/sys/target_get.c new file mode 100644 index 00000000..da53b1df --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/sys/target_get.c @@ -0,0 +1,240 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 target_get.c + * @brief CSI Source File for target API + * @version V1.0 + * @date 9. April 2020 + ******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +extern const csi_perip_info_t g_soc_info[]; +extern const csi_dma_ch_bit_spt_list_t dma_spt_list[]; +extern const csi_dma_handshake_list_t g_handshake_list[]; + +csi_error_t target_get(csi_dev_tag_t dev_tag, uint32_t idx, csi_dev_t *dev) +{ + csi_error_t ret = CSI_OK; + csi_perip_info_t *info; + + if (dev == NULL) { + ret = CSI_ERROR; + } + + ///< 使用包含外设基地址,外设中断号,外设设备号,外设设备类型成员的结构体数组变量初始化info + info = (csi_perip_info_t *)&g_soc_info; + + ///< 获取相应的设备类型和设备号 + while (info->reg_base) { + if ((info->dev_tag == (uint16_t)dev_tag) && (info->idx == (uint8_t)idx)) { + break; + } + + info++; + } + + ///< 初始化设备的统一句柄:基地址,中断号,设备号,设备类型 + if (info->reg_base == 0U) { + ret = CSI_ERROR; + } + + if (ret != CSI_ERROR) { + dev->reg_base = info->reg_base; + dev->irq_num = info->irq_num; + dev->idx = info->idx; + dev->dev_tag = (uint16_t)dev_tag; + } + + return ret; +} + +uint32_t target_pin_to_devidx(pin_name_t pin_name, const csi_pinmap_t *pinmap) +{ + const csi_pinmap_t *map = pinmap; + uint32_t ret = 0xFFFFFFFFU; + + while ((uint32_t)map->pin_name != 0xFFFFFFFFU) { + if ((map->pin_name == pin_name) && (csi_pin_get_mux(pin_name) == map->pin_func)) { + ret = map->idx; + break; + } + + map++; + } + + return ret; +} + +uint32_t target_pin_to_channel(pin_name_t pin_name, const csi_pinmap_t *pinmap) +{ + const csi_pinmap_t *map = pinmap; + uint32_t ret = 0xFFFFFFFFU; + + while ((uint32_t)map->pin_name != 0xFFFFFFFFU) { + if (map->pin_name == pin_name) { + ret = (uint32_t)map->channel; + break; + } + + map++; + } + + return ret; +} + +pin_name_t target_gpio_to_pin(uint8_t gpio_idx, uint8_t channel, const csi_pinmap_t *pinmap) +{ + const csi_pinmap_t *map = pinmap; + pin_name_t ret = (pin_name_t)0xFFU; + + while ((uint32_t)map->pin_name != 0xFFFFFFFFU) { + if ((map->idx == gpio_idx) && (map->channel == channel)) { + ret = map->pin_name; + break; + } + + map++; + } + + return ret; +} + +csi_error_t target_get_optimal_dma_channel(void *dma_list, uint32_t ctrl_num, csi_dev_t *parent_dev, void *ch_info) +{ + uint32_t spt_id, ch_id; + uint16_t ctrl_id = 0; + uint16_t index = 0; + csi_dma_t **list = (csi_dma_t **)dma_list; + csi_dma_ch_desc_t *dma_ch_info = (csi_dma_ch_desc_t *)ch_info; + + if (parent_dev == NULL) + { + /* the MEM2MEM mode */ + for (ctrl_id = 0U; ctrl_id < ctrl_num; ctrl_id++) + { + if (list[ctrl_id] == NULL) + { + continue; + } + + for (ch_id = 0U; ch_id < list[ctrl_id]->ch_num; ch_id++) + { + if (!(list[ctrl_id]->alloc_status & ((uint32_t)1 << ch_id))) + { + dma_ch_info->ch_idx = ch_id; + dma_ch_info->ctrl_idx = (uint8_t)ctrl_id; + /* find the channel */ + return CSI_OK; + } + } + } + } + else + { + /* the MEM2PERH mode or PERH2MEM mode */ + for (spt_id = 0U; dma_spt_list[spt_id].parent_dev_id != DEV_IDX_INVALID; spt_id++) + { + if ((dma_spt_list[spt_id].parent_dev_id == parent_dev->idx)) + { + const csi_dma_ch_bit_desc_t *dev_ch_info = dma_spt_list[spt_id].ch_list; + + for (index = 0U; dev_ch_info[index].ctrl_idx != DEV_IDX_INVALID; index++) + { + uint16_t tem_idx = dev_ch_info[index].ctrl_idx; + for (ch_id = 0U; ch_id < list[tem_idx]->ch_num; ch_id++) + { + + if (!(list[tem_idx]->alloc_status & ((uint32_t)1 << ch_id)) && (dev_ch_info[index].ch_bit_info & ((uint32_t)1 << ch_id))) + { + dma_ch_info->ch_idx = ch_id; + dma_ch_info->ctrl_idx = (uint8_t)tem_idx; + return CSI_OK; + } + } + } + return CSI_ERROR; + } + + } + } + return CSI_ERROR; +} + +csi_error_t target_get_check_dma_access(uint32_t ctrl_idx, void *srcaddr, void *dstaddr, void **dma_base_src_addr, void **dma_base_dst_addr) +{ + *dma_base_src_addr = srcaddr; + *dma_base_dst_addr = dstaddr; + return CSI_OK; +} + +csi_error_t target_get_dma_handshake(uint16_t dma_id, uint16_t dev_id, uint16_t dev_tag, uint8_t type, uint16_t *handshake) +{ + const csi_dma_handshake_list_t *handshake_list = &g_handshake_list[0]; + uint16_t index = 0; + uint8_t dma_found_flag = 0; + uint8_t dev_found_flag = 0; + + for (index = 0; handshake_list[index].ctrl_idx != DEV_IDX_INVALID; index++) + { + if (handshake_list[index].ctrl_idx == dma_id) + { + dma_found_flag = 0x1; + break; + } + } + + if (!dma_found_flag) + { + return CSI_UNSUPPORTED; + } + + const csi_dma_handshake_ctrl_t *handshake_ctrl_list = handshake_list[index].handshake_ctrl_list; + + for (index = 0; handshake_ctrl_list[index].parent_dev_id != DEV_IDX_INVALID; index++) + { + if (handshake_ctrl_list[index].parent_dev_id == dev_id && handshake_ctrl_list[index].dev_tag == dev_tag) + { + if (type == DMA_HANDSHAKE_TYPE_RX && handshake_ctrl_list[index].rx_hs != DMA_HANDSHAKE_NONE) + { + *handshake = handshake_ctrl_list[index].rx_hs; + dev_found_flag = 0x1; + } + else if (type == DMA_HANDSHAKE_TYPE_TX && handshake_ctrl_list[index].tx_hs != DMA_HANDSHAKE_NONE) + { + *handshake = handshake_ctrl_list[index].tx_hs; + dev_found_flag = 0x1; + } + break; + } + } + + if (!dev_found_flag) + { + return CSI_UNSUPPORTED; + } + return CSI_OK; +} diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/sys/tick.c b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/sys/tick.c new file mode 100644 index 00000000..1f121916 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/sys/tick.c @@ -0,0 +1,341 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define __WEAK __attribute__((weak)) + +// from 1970-01-01 00:00:00 UTC +static volatile uint64_t timestamp_us_offset; + +#if defined(CONFIG_SMP) && CONFIG_SMP +static volatile uint32_t csi_tick[CONFIG_NR_CPUS] = {0U}; +#else +static volatile uint32_t csi_tick = 0U; +#endif +static volatile uint32_t last_time_ms = 0U; +static volatile uint64_t last_time_us = 0U; + +#ifdef CONFIG_TIMER_FOR_TICK +static csi_timer_t tick_timer; +#ifndef CONFIG_TICK_TIMER_IDX +#define CONFIG_TICK_TIMER_IDX 0U +#endif +#else /* !CONFIG_TIMER_FOR_TICK */ +static csi_dev_t tick_dev; +static volatile uint64_t timer_init_value = 0U; +#endif + +void csi_tick_increase(void) +{ +#if defined(CONFIG_SMP) && CONFIG_SMP + csi_tick[csi_get_cpu_id()]++; +#else + csi_tick++; +#endif +} + +uint32_t csi_tick_get(void) +{ +#if defined(CONFIG_SMP) && CONFIG_SMP + return csi_tick[csi_get_cpu_id()]; +#else + return csi_tick; +#endif +} + +#ifdef CONFIG_TIMER_FOR_TICK +void tick_event_cb(csi_timer_t *timer_handle, void *arg) +{ + csi_tick_increase(); +#if CONFIG_AOS_OSAL + extern void aos_sys_tick_handler(void); + aos_sys_tick_handler(); +#else +#ifdef CONFIG_KERNEL_FREERTOS + extern void xPortSysTickHandler(void); + xPortSysTickHandler(); +#elif defined(CONFIG_KERNEL_RTTHREAD) + extern void rt_tick_increase(void); + rt_tick_increase(); +#elif defined(CONFIG_KERNEL_THREADX) + extern void _tx_timer_interrupt(void); + _tx_timer_interrupt(); +#else +#endif +#endif /* end CONFIG_AOS_OSAL */ +} +#else /* !CONFIG_TIMER_FOR_TICK */ +void tick_irq_handler(void *arg) +{ + csi_tick_increase(); + csi_coret_config((soc_get_coretim_freq() / CONFIG_SYSTICK_HZ), tick_dev.irq_num); +#if CONFIG_AOS_OSAL + extern void aos_sys_tick_handler(void); + aos_sys_tick_handler(); +#else +#ifdef CONFIG_KERNEL_FREERTOS + extern void xPortSysTickHandler(void); + xPortSysTickHandler(); +#elif defined(CONFIG_KERNEL_RTTHREAD) + extern void rt_tick_increase(void); + rt_tick_increase(); +#elif defined(CONFIG_KERNEL_THREADX) + extern void _tx_timer_interrupt(void); + _tx_timer_interrupt(); +#else +#endif +#endif /* end CONFIG_AOS_OSAL */ + +} +#endif /* CONFIG_TIMER_FOR_TICK */ + +csi_error_t csi_tick_init(void) +{ +#if defined(CONFIG_SMP) && CONFIG_SMP + csi_tick[csi_get_cpu_id()] = 0; +#else + csi_tick = 0U; +#endif + +#ifdef CONFIG_TIMER_FOR_TICK + csi_error_t ret = csi_timer_init(&tick_timer, CONFIG_TICK_TIMER_IDX); + if (ret == CSI_OK) { + ret = csi_timer_attach_callback(&tick_timer, tick_event_cb, NULL); + if (ret == CSI_OK) { + ret = csi_timer_start(&tick_timer, (1000000U / CONFIG_SYSTICK_HZ)); + } + } + return ret; +#else /* !CONFIG_TIMER_FOR_TICK */ +#if CONFIG_RISCV_SMODE + tick_dev.irq_num = Supervisor_Timer_IRQn; +#else + tick_dev.irq_num = CORET_IRQn; +#endif +#if CONFIG_CPU_XUANTIE_E9XX || CONFIG_INTC_CLIC || CONFIG_INTC_CLIC_PLIC || CONFIG_INTC_CLIC_APLIC + csi_vic_set_prio(tick_dev.irq_num, 2); + csi_irq_attach(tick_dev.irq_num, &tick_irq_handler, &tick_dev); +#endif /* CONFIG_CPU_XUANTIE_E9XX || CONFIG_INTC_CLIC || CONFIG_INTC_CLIC_PLIC || CONFIG_INTC_CLIC_APLIC */ + timer_init_value = csi_coret_get_value2(); + csi_coret_reset_value2(); + csi_coret_config((soc_get_coretim_freq() / CONFIG_SYSTICK_HZ), tick_dev.irq_num); + csi_coret_irq_enable(); +#endif /* CONFIG_TIMER_FOR_TICK */ + return CSI_OK; +} + +void csi_tick_uninit(void) +{ +#ifdef CONFIG_TIMER_FOR_TICK + csi_timer_stop(&tick_timer); + csi_timer_uninit(&tick_timer); +#else + csi_coret_irq_disable(); +#if CONFIG_CPU_XUANTIE_E9XX || CONFIG_INTC_CLIC_PLIC + csi_irq_detach(tick_dev.irq_num); +#endif +#endif /* CONFIG_TIMER_FOR_TICK */ +} + +#ifdef CONFIG_TIMER_FOR_TICK +uint32_t csi_tick_get_ms(void) +{ + uint32_t time = last_time_ms, freq; + freq = csi_timer_get_load_value(&tick_timer) * CONFIG_SYSTICK_HZ; + + while (freq) { + time = (csi_tick * (1000U / CONFIG_SYSTICK_HZ)) + ((csi_timer_get_load_value(&tick_timer) - csi_timer_get_remaining_value(&tick_timer)) / (freq / 1000U)); + + if (time >= last_time_ms) { + break; + } + } + + last_time_ms = time; + return time; +} + +uint64_t csi_tick_get_us(void) +{ + uint64_t time, freq; + uint32_t temp; + freq = soc_get_timer_freq(CONFIG_TICK_TIMER_IDX); + + while (1) { + /* the time of coretim pass */ + temp = csi_timer_get_load_value(&tick_timer) - csi_timer_get_remaining_value(&tick_timer); + time = ((uint64_t)temp * 1000U) / (freq / 1000U); + /* the time of csi_tick */ + time += ((uint64_t)csi_tick * (1000000U / CONFIG_SYSTICK_HZ)); + + if (time >= last_time_us) { + break; + } + } + + last_time_us = time; + return time; +} + +static void _mdelay(void) +{ + uint32_t load = csi_timer_get_load_value(&tick_timer); + uint32_t start_r = csi_timer_get_remaining_value(&tick_timer); + uint32_t cur_r; + uint32_t cnt = (soc_get_timer_freq(CONFIG_TICK_TIMER_IDX) / 1000U); + + while (1) { + cur_r = csi_timer_get_remaining_value(&tick_timer); + + if (start_r > cur_r) { + if ((start_r - cur_r) >= cnt) { + break; + } + } else { + if (((load - cur_r) + start_r) >= cnt) { + break; + } + } + } +} + +static void _10udelay(void) +{ + uint32_t load = csi_timer_get_load_value(&tick_timer); + uint32_t start_r = csi_timer_get_remaining_value(&tick_timer); + uint32_t cur_r; + uint32_t cnt = (soc_get_timer_freq(CONFIG_TICK_TIMER_IDX) / 100000U); + + while (1) { + cur_r = csi_timer_get_remaining_value(&tick_timer); + + if (start_r > cur_r) { + if ((start_r - cur_r) >= cnt) { + break; + } + } else { + if (((load - cur_r) + start_r) >= cnt) { + break; + } + } + } +} + +#else /* !CONFIG_TIMER_FOR_TICK */ + +uint32_t csi_tick_get_ms(void) +{ + uint32_t time; + + time = (uint32_t)((csi_coret_get_value2() - timer_init_value) * 1000U / (uint64_t)soc_get_coretim_freq()); + last_time_ms = time; + return time; +} + +uint64_t csi_tick_get_us(void) +{ + uint64_t time; + + time = (csi_coret_get_value2() - timer_init_value) * 1000U * 1000U / (uint64_t)soc_get_coretim_freq(); + last_time_us = time; + return time; +} + +static void _mdelay(void) +{ + uint64_t start = csi_coret_get_value2(); + uint64_t cur; + uint32_t cnt = (soc_get_coretim_freq() / 1000U); + + while (1) { + cur = csi_coret_get_value2(); + + if (start > cur) { + if ((start - cur) >= cnt) { + break; + } + } else { + if (cur - start >= cnt) { + break; + } + } + } +} + +static void _10udelay(void) +{ + uint64_t cur; + uint64_t start = csi_coret_get_value2(); + uint32_t cnt = (soc_get_coretim_freq() / 1000U / 100U); + + while (1) { + cur = csi_coret_get_value2(); + + if (start > cur) { + if ((start - cur) >= cnt) { + break; + } + } else { + if (cur - start >= cnt) { + break; + } + } + } +} +#endif + +void csi_set_calendar_us(uint64_t timestamp) +{ + timestamp_us_offset = timestamp; +} + +uint64_t csi_get_calendar_us(void) +{ + return csi_tick_get_us() + timestamp_us_offset; +} + +__WEAK void mdelay(uint32_t ms) +{ + while (ms) { + ms--; + _mdelay(); + } +} + +/** + * Ps: At least delay over 10us +*/ +void udelay(uint32_t us) +{ + us /= 10U; + + while (us) { + us--; + _10udelay(); + } +} + diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/sys/weak.c b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/sys/weak.c new file mode 100644 index 00000000..d6e32655 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/chip_riscv_dummy/src/sys/weak.c @@ -0,0 +1,58 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 weak.c + * @brief source file for the weak + * @version V1.0 + * @date 04. April 2024 + ******************************************************************************/ + +#include +#include +#include + +__WEAK void soc_dcache_clean_invalid_range(unsigned long addr, uint32_t size) +{ + csi_dcache_clean_invalid_range((unsigned long *)addr, size); +} + +__WEAK void soc_dcache_clean_invalid_all(void) +{ + csi_dcache_clean_invalid(); +} + +__WEAK void soc_dcache_invalid_range(unsigned long addr, uint32_t size) +{ + csi_dcache_invalid_range((unsigned long *)addr, size); +} + +__WEAK void soc_dcache_clean(void) +{ + csi_dcache_clean(); +} + +__WEAK void soc_icache_invalid(void) +{ + csi_icache_invalid(); +} + +__WEAK unsigned long soc_dma_address_remap(unsigned long addr) +{ + return addr; +} diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/core/README.txt b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/core/README.txt new file mode 100644 index 00000000..bb1bf4a3 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/core/README.txt @@ -0,0 +1 @@ +Just include csi_core.h! diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/core/core_rv32.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/core/core_rv32.h new file mode 100644 index 00000000..c46e8428 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/core/core_rv32.h @@ -0,0 +1,1452 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 core_rv32.h + * @brief CSI RV32 Core Peripheral Access Layer Header File + * @version V1.0 + * @date 01. Sep 2018 + ******************************************************************************/ + +#ifndef __CORE_RV32_H_GENERIC +#define __CORE_RV32_H_GENERIC + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * CSI definitions + ******************************************************************************/ +/** + \ingroup RV32 + @{ + */ + +#ifndef __RV32 +#define __RV32 (0x01U) +#endif + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __GNUC__ ) +#if defined (__VFP_FP__) && !defined(__SOFTFP__) +#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" +#endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_RV32_H_GENERIC */ + +#ifndef __CSI_GENERIC + +#ifndef __CORE_RV32_H_DEPENDANT +#define __CORE_RV32_H_DEPENDANT + +#ifdef __cplusplus +extern "C" { +#endif + +/* check device defines and use defaults */ +#ifndef __RV32_REV +#define __RV32_REV 0x0000U +#endif + +#ifndef __VIC_PRIO_BITS +#define __VIC_PRIO_BITS 2U +#endif + +#ifndef __Vendor_SysTickConfig +#define __Vendor_SysTickConfig 1U +#endif + +#ifndef __MPU_PRESENT +#define __MPU_PRESENT 1U +#endif + +#ifndef __ICACHE_PRESENT +#define __ICACHE_PRESENT 1U +#endif + +#ifndef __DCACHE_PRESENT +#define __DCACHE_PRESENT 1U +#endif + +#include + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CSI_glob_defs CSI Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus +#define __I volatile /*!< Defines 'read only' permissions */ +#else +#define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group RV32 */ + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core CLIC Register + ******************************************************************************/ +/** + \defgroup CSI_core_register Defines and Type Definitions + \brief Type definitions and defines for CK80X processor based devices. +*/ + +/** + \ingroup CSI_core_register + \defgroup CSI_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \ingroup CSI_core_register + \defgroup CSI_CLIC Core-Local Interrupt Controller (CLIC) + \brief Type definitions for the CLIC Registers + @{ + */ + +/** + \brief Access to the structure of a vector interrupt controller. + */ +typedef struct { + __IOM uint8_t IP; /*!< Offset: 0x000 (R/W) Interrupt set pending register */ + __IOM uint8_t IE; /*!< Offset: 0x004 (R/W) Interrupt set enable register */ + __IOM uint8_t ATTR; /*!< Offset: 0x008 (R/W) Interrupt set attribute register */ + __IOM uint8_t CTL; /*!< Offset: 0x00C (R/W) Interrupt control register */ +} CLIC_INT_Control; + +typedef struct { + __IOM uint32_t CLICCFG:8; /*!< Offset: 0x000 (R/W) CLIC configure register */ + __IM uint32_t CLICINFO; + __IOM uint32_t MINTTHRESH; + uint32_t RESERVED[1021]; + CLIC_INT_Control CLICINT[4096]; +} CLIC_Type; + +#define CLIC_INFO_CLICINTCTLBITS_Pos 21U +#define CLIC_INFO_CLICINTCTLBITS_Msk (0xFUL << CLIC_INFO_CLICINTCTLBITS_Pos) + +#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 */ + +#define CLIC_INTIE_T_Pos 7U /*!< CLIC INTIE: T Position */ +#define CLIC_INTIE_T_Msk (0x1UL << CLIC_INTIE_T_Pos) /*!< CLIC INTIE: T Mask */ + +#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 CLIC_INTCFG_NVBIT_Pos 5U /*!< CLIC INTCFG: NVBIT Position */ +#define CLIC_INTCFG_NVBIT_Msk (0x1UL << CLIC_INTCFG_NVBIT_Pos) /*!< CLIC INTCFG: NVBIT Mask */ + +#define CLIC_INTCFG_PRIO_Pos 5U /*!< CLIC INTCFG: INTCFG Position */ +#define CLIC_INTCFG_PRIO_Msk (0x7UL << CLIC_INTCFG_PRIO_Pos) /*!< CLIC INTCFG: INTCFG Mask */ + +#define CLIC_CLICCFG_NVBIT_Pos 0U /*!< CLIC CLICCFG: NVBIT Position */ +#define CLIC_CLICCFG_NVBIT_Msk (0x1UL << CLIC_CLICCFG_NVBIT_Pos) /*!< CLIC CLICCFG: NVBIT Mask */ + +#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_CLICCFG_NMBIT_Pos 5U /*!< CLIC CLICCFG: NMBIT Position */ +#define CLIC_CLICCFG_NMBIT_Msk (0x3UL << CLIC_CLICCFG_NMBIT_Pos) /*!< CLIC CLICCFG: NMBIT Mask */ + +/*@} end of group CSI_CLIC */ + +/** + \ingroup CSI_core_register + \defgroup CSI_PMP Physical Memory Protection (PMP) + \brief Type definitions for the PMP Registers + @{ + */ + +#define PMP_PMPCFG_R_Pos 0U /*!< PMP PMPCFG: R Position */ +#define PMP_PMPCFG_R_Msk (0x1UL << PMP_PMPCFG_R_Pos) /*!< PMP PMPCFG: R Mask */ + +#define PMP_PMPCFG_W_Pos 1U /*!< PMP PMPCFG: W Position */ +#define PMP_PMPCFG_W_Msk (0x1UL << PMP_PMPCFG_W_Pos) /*!< PMP PMPCFG: W Mask */ + +#define PMP_PMPCFG_X_Pos 2U /*!< PMP PMPCFG: X Position */ +#define PMP_PMPCFG_X_Msk (0x1UL << PMP_PMPCFG_X_Pos) /*!< PMP PMPCFG: X Mask */ + +#define PMP_PMPCFG_A_Pos 3U /*!< PMP PMPCFG: A Position */ +#define PMP_PMPCFG_A_Msk (0x3UL << PMP_PMPCFG_A_Pos) /*!< PMP PMPCFG: A Mask */ + +#define PMP_PMPCFG_L_Pos 7U /*!< PMP PMPCFG: L Position */ +#define PMP_PMPCFG_L_Msk (0x1UL << PMP_PMPCFG_L_Pos) /*!< PMP PMPCFG: L Mask */ + +typedef enum { + REGION_SIZE_4B = -1, + REGION_SIZE_8B = 0, + REGION_SIZE_16B = 1, + REGION_SIZE_32B = 2, + REGION_SIZE_64B = 3, + REGION_SIZE_128B = 4, + REGION_SIZE_256B = 5, + REGION_SIZE_512B = 6, + REGION_SIZE_1KB = 7, + REGION_SIZE_2KB = 8, + REGION_SIZE_4KB = 9, + REGION_SIZE_8KB = 10, + REGION_SIZE_16KB = 11, + REGION_SIZE_32KB = 12, + REGION_SIZE_64KB = 13, + REGION_SIZE_128KB = 14, + REGION_SIZE_256KB = 15, + REGION_SIZE_512KB = 16, + REGION_SIZE_1MB = 17, + REGION_SIZE_2MB = 18, + REGION_SIZE_4MB = 19, + REGION_SIZE_8MB = 20, + REGION_SIZE_16MB = 21, + REGION_SIZE_32MB = 22, + REGION_SIZE_64MB = 23, + REGION_SIZE_128MB = 24, + REGION_SIZE_256MB = 25, + REGION_SIZE_512MB = 26, + REGION_SIZE_1GB = 27, + REGION_SIZE_2GB = 28, + REGION_SIZE_4GB = 29, + REGION_SIZE_8GB = 30, + REGION_SIZE_16GB = 31 +} region_size_e; + +typedef enum { + ADDRESS_MATCHING_TOR = 1, + ADDRESS_MATCHING_NAPOT = 3 +} address_matching_e; + +typedef struct { + uint32_t r: 1; /* readable enable */ + uint32_t w: 1; /* writeable enable */ + uint32_t x: 1; /* execable enable */ + address_matching_e a: 2; /* address matching mode */ + uint32_t reserved: 2; /* reserved */ + uint32_t l: 1; /* lock enable */ +} pmp_region_attr_t; + +/*@} end of group CSI_PMP */ + +/* CACHE Register Definitions */ +#define CACHE_MHCR_BTB_Pos 12U /*!< CACHE MHCR: BTB Position */ +#define CACHE_MHCR_BTB_Msk (0x1UL << CACHE_MHCR_BTB_Pos) /*!< CACHE MHCR: WA Mask */ + +#define CACHE_MHCR_BPE_Pos 5U /*!< CACHE MHCR: BPE Position */ +#define CACHE_MHCR_BPE_Msk (0x1UL << CACHE_MHCR_BPE_Pos) /*!< CACHE MHCR: BPE Mask */ + +#define CACHE_MHCR_RS_Pos 4U /*!< CACHE MHCR: RS Position */ +#define CACHE_MHCR_RS_Msk (0x1UL << CACHE_MHCR_RS_Pos) /*!< CACHE MHCR: RS Mask */ + +#define CACHE_MHCR_WA_Pos 3U /*!< CACHE MHCR: WA Position */ +#define CACHE_MHCR_WA_Msk (0x1UL << CACHE_MHCR_WA_Pos) /*!< CACHE MHCR: WA Mask */ + +#define CACHE_MHCR_WB_Pos 2U /*!< CACHE MHCR: WB Position */ +#define CACHE_MHCR_WB_Msk (0x1UL << CACHE_MHCR_WB_Pos) /*!< CACHE MHCR: WB Mask */ + +#define CACHE_MHCR_DE_Pos 1U /*!< CACHE MHCR: DE Position */ +#define CACHE_MHCR_DE_Msk (0x1UL << CACHE_MHCR_DE_Pos) /*!< CACHE MHCR: DE Mask */ + +#define CACHE_MHCR_IE_Pos 0U /*!< CACHE MHCR: IE Position */ +#define CACHE_MHCR_IE_Msk (0x1UL << CACHE_MHCR_IE_Pos) /*!< CACHE MHCR: IE Mask */ + +#if CONFIG_CPU_XUANTIE_E902 || CONFIG_CPU_XUANTIE_E902M || CONFIG_CPU_XUANTIE_E902T || CONFIG_CPU_XUANTIE_E902MT \ + || CONFIG_CPU_XUANTIE_E901PLUS_CP || CONFIG_CPU_XUANTIE_E901PLUS_B_CP || CONFIG_CPU_XUANTIE_E901PLUS_M_CP || CONFIG_CPU_XUANTIE_E901PLUS_BM_CP \ + || CONFIG_CPU_XUANTIE_E901_CP || CONFIG_CPU_XUANTIE_E901_B_CP || CONFIG_CPU_XUANTIE_E901_ZM_CP || CONFIG_CPU_XUANTIE_E901_BZM_CP +#define CACHE_INV_ADDR_Pos 4U +#else +#define CACHE_INV_ADDR_Pos 5U +#endif +#define CACHE_INV_ADDR_Msk (0xFFFFFFFFUL << CACHE_INV_ADDR_Pos) + +/*@} end of group CSI_CACHE */ + +/** + \ingroup CSI_core_register + \defgroup CSI_SYSMAP system map (SYSMAP) + \brief Type definitions for the SYSMAP Registers + @{ + */ + +#define SYSMAP_SYSMAPCFG_B_Pos 0U /*!< SYSMAP SYSMAPCFG: B Position */ +#define SYSMAP_SYSMAPCFG_B_Msk (0x1UL << SYSMAP_SYSMAPCFG_B_Pos) /*!< SYSMAP SYSMAPCFG: B Mask */ + +#define SYSMAP_SYSMAPCFG_C_Pos 1U /*!< SYSMAP SYSMAPCFG: C Position */ +#define SYSMAP_SYSMAPCFG_C_Msk (0x1UL << SYSMAP_SYSMAPCFG_C_Pos) /*!< SYSMAP SYSMAPCFG: C Mask */ + +#define SYSMAP_SYSMAPCFG_SO_Pos 2U /*!< SYSMAP SYSMAPCFG: SO Position */ +#define SYSMAP_SYSMAPCFG_SO_Msk (0x1UL << SYSMAP_SYSMAPCFG_SO_Pos) /*!< SYSMAP SYSMAPCFG: SO Mask */ + +/** + \ingroup CSI_core_register + \defgroup CSI_SYSMAP system map (SYSMAP) + \brief Type definitions for the SYSMAP Registers + @{ + */ +typedef struct { + __IOM uint32_t SYSMAPADDR0; /*!< Offset: 0x000 (R/W) SYSMAP configure register */ + __IOM uint32_t SYSMAPCFG0; /*!< Offset: 0x004 (R/W) SYSMAP configure register */ + __IOM uint32_t SYSMAPADDR1; /*!< Offset: 0x008 (R/W) SYSMAP configure register */ + __IOM uint32_t SYSMAPCFG1; /*!< Offset: 0x00c (R/W) SYSMAP configure register */ + __IOM uint32_t SYSMAPADDR2; /*!< Offset: 0x010 (R/W) SYSMAP configure register */ + __IOM uint32_t SYSMAPCFG2; /*!< Offset: 0x014 (R/W) SYSMAP configure register */ + __IOM uint32_t SYSMAPADDR3; /*!< Offset: 0x018 (R/W) SYSMAP configure register */ + __IOM uint32_t SYSMAPCFG3; /*!< Offset: 0x01c (R/W) SYSMAP configure register */ + __IOM uint32_t SYSMAPADDR4; /*!< Offset: 0x020 (R/W) SYSMAP configure register */ + __IOM uint32_t SYSMAPCFG4; /*!< Offset: 0x024 (R/W) SYSMAP configure register */ + __IOM uint32_t SYSMAPADDR5; /*!< Offset: 0x028 (R/W) SYSMAP configure register */ + __IOM uint32_t SYSMAPCFG5; /*!< Offset: 0x02c (R/W) SYSMAP configure register */ + __IOM uint32_t SYSMAPADDR6; /*!< Offset: 0x030 (R/W) SYSMAP configure register */ + __IOM uint32_t SYSMAPCFG6; /*!< Offset: 0x034 (R/W) SYSMAP configure register */ + __IOM uint32_t SYSMAPADDR7; /*!< Offset: 0x038 (R/W) SYSMAP configure register */ + __IOM uint32_t SYSMAPCFG7; /*!< Offset: 0x03c (R/W) SYSMAP configure register */ +} SYSMAP_Type; + + +/*@} end of group CSI_SYSMAP */ + + +/** + \ingroup CSI_core_register + \defgroup CSI_SysTick System Tick Timer (CORET) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief The data structure of the access system timer. + */ +typedef struct { + __IOM unsigned long long MTIMECMP; /*!< Offset: 0x000 (R/W) Timer compare register */ + uint32_t RESERVED[8188]; + __IM unsigned long long MTIME; /*!< Offset: 0x7FF8 (R) Timer current register */ +} CORET_Type; + +/*@} end of group CSI_SysTick */ + +/** + \ingroup CSI_core_register + \defgroup CSI_DCC + \brief Type definitions for the DCC. + @{ + */ + +/** + \brief Access to the data structure of DCC. + */ +typedef struct { + uint32_t RESERVED0[13U]; + __IOM uint32_t HCR; /*!< Offset: 0x034 (R/W) */ + __IM uint32_t EHSR; /*!< Offset: 0x03C (R/ ) */ + uint32_t RESERVED1[6U]; + union { + __IM uint32_t DERJW; /*!< Offset: 0x058 (R/ ) Data exchange register CPU read*/ + __OM uint32_t DERJR; /*!< Offset: 0x058 ( /W) Data exchange register CPU writer*/ + }; + +} DCC_Type; + +#define DCC_HCR_JW_Pos 18U /*!< DCC HCR: jw_int_en Position */ +#define DCC_HCR_JW_Msk (1UL << DCC_HCR_JW_Pos) /*!< DCC HCR: jw_int_en Mask */ + +#define DCC_HCR_JR_Pos 19U /*!< DCC HCR: jr_int_en Position */ +#define DCC_HCR_JR_Msk (1UL << DCC_HCR_JR_Pos) /*!< DCC HCR: jr_int_en Mask */ + +#define DCC_EHSR_JW_Pos 1U /*!< DCC EHSR: jw_vld Position */ +#define DCC_EHSR_JW_Msk (1UL << DCC_EHSR_JW_Pos) /*!< DCC EHSR: jw_vld Mask */ + +#define DCC_EHSR_JR_Pos 2U /*!< DCC EHSR: jr_vld Position */ +#define DCC_EHSR_JR_Msk (1UL << DCC_EHSR_JR_Pos) /*!< DCC EHSR: jr_vld Mask */ + +/*@} end of group CSI_DCC */ + + +/** + \ingroup CSI_core_register + \defgroup CSI_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos) + +/*@} end of group CSI_core_bitfield */ + +/** + \ingroup CSI_core_register + \defgroup CSI_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of THEAD CPU */ +#ifndef CONFIG_TCIP_BASE +#define CONFIG_TCIP_BASE 0xE0000000UL +#endif +#define CORET_BASE (CONFIG_TCIP_BASE + 0x4000UL) /*!< CORET Base Address */ +#define CLIC_BASE (CONFIG_TCIP_BASE + 0x800000UL) /*!< CLIC Base Address */ + +#define SYSMAP_BASE (0xEFFFF000UL) /*!< SYSMAP Base Address */ + +#define CORET ((CORET_Type *) CORET_BASE ) /*!< SysTick configuration struct */ +#define CLIC ((CLIC_Type *) CLIC_BASE ) /*!< CLIC configuration struct */ +#define SYSMAP ((SYSMAP_Type *) SYSMAP_BASE ) /*!< SYSMAP configuration struct */ + +/*@} */ + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core VIC Functions + - Core CORET Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CSI_Core_FunctionInterface Functions and Instructions Reference +*/ + +/** + \brief Get current hartid + \return hartid + */ +__STATIC_INLINE int csi_get_cpu_id(void) +{ + unsigned long result; + __ASM volatile("csrr %0, mhartid" : "=r"(result) : : "memory"); + return result; +} + +/** + \brief Get cache line size + \return cache line size + */ +__STATIC_INLINE int csi_get_cache_line_size(void) +{ +#if CONFIG_CPU_XUANTIE_E902 || CONFIG_CPU_XUANTIE_E902M || CONFIG_CPU_XUANTIE_E902T || CONFIG_CPU_XUANTIE_E902MT \ + || CONFIG_CPU_XUANTIE_E901PLUS_CP || CONFIG_CPU_XUANTIE_E901PLUS_B_CP || CONFIG_CPU_XUANTIE_E901PLUS_M_CP || CONFIG_CPU_XUANTIE_E901PLUS_BM_CP \ + || CONFIG_CPU_XUANTIE_E901_CP || CONFIG_CPU_XUANTIE_E901_B_CP || CONFIG_CPU_XUANTIE_E901_ZM_CP || CONFIG_CPU_XUANTIE_E901_BZM_CP + return 16; +#else + return 32; +#endif +} + +/* ########################## VIC functions #################################### */ +/** + \ingroup CSI_Core_FunctionInterface + \defgroup CSI_Core_VICFunctions VIC Functions + \brief Functions that manage interrupts and exceptions via the VIC. + @{ + */ + +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 5UL) ) +#define _IP2_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +/** + \brief Enable External Interrupt + \details Enable a device-specific interrupt in the VIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void csi_vic_enable_irq(int32_t IRQn) +{ + CLIC->CLICINT[IRQn].IE |= CLIC_INTIE_IE_Msk; + __DSB(); +} + +/** + \brief Disable External Interrupt + \details Disable a device-specific interrupt in the VIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void csi_vic_disable_irq(int32_t IRQn) +{ + CLIC->CLICINT[IRQn].IE &= ~CLIC_INTIE_IE_Msk; + __DSB(); +} + +/** + \brief Check Interrupt is Enabled or not + \details Read the enabled register in the VIC and returns the pending bit for the specified interrupt. + \param [in] IRQn Interrupt number. + \return 0 Interrupt status is not enabled. + \return 1 Interrupt status is enabled. + */ +__STATIC_INLINE uint32_t csi_vic_get_enabled_irq(int32_t IRQn) +{ + return (uint32_t)(CLIC->CLICINT[IRQn].IE & CLIC_INTIE_IE_Msk); +} + +/** + \brief Check Interrupt is Pending or not + \details Read the pending register in the VIC and returns the pending bit for the specified interrupt. + \param [in] IRQn Interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t csi_vic_get_pending_irq(int32_t IRQn) +{ + return (uint32_t)(CLIC->CLICINT[IRQn].IP & CLIC_INTIP_IP_Msk); +} + +/** + \brief Set Pending Interrupt + \details Set the pending bit of an external interrupt. + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void csi_vic_set_pending_irq(int32_t IRQn) +{ + CLIC->CLICINT[IRQn].IP |= CLIC_INTIP_IP_Msk; + __DSB(); +} + +/** + \brief Clear Pending Interrupt + \details Clear the pending bit of an external interrupt. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void csi_vic_clear_pending_irq(int32_t IRQn) +{ + CLIC->CLICINT[IRQn].IP &= ~CLIC_INTIP_IP_Msk; + __DSB(); +} + +/** + \brief Set Interrupt Priority + \details Set the priority of an interrupt. + \note The priority cannot be set for every core interrupt. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void csi_vic_set_prio(int32_t IRQn, uint32_t priority) +{ + uint8_t nlbits = (CLIC->CLICINFO & CLIC_INFO_CLICINTCTLBITS_Msk) >> CLIC_INFO_CLICINTCTLBITS_Pos; + uint8_t ctl = CLIC->CLICINT[IRQn].CTL; + ctl <<= nlbits; + ctl >>= nlbits; + CLIC->CLICINT[IRQn].CTL = ctl | (priority << (8 - nlbits)); + __DSB(); +} + +/** + \brief Get Interrupt Priority + \details Read the priority of an interrupt. + The interrupt number can be positive to specify an external (device specific) interrupt, + or negative to specify an internal (core) interrupt. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t csi_vic_get_prio(int32_t IRQn) +{ + uint8_t nlbits = (CLIC->CLICINFO & CLIC_INFO_CLICINTCTLBITS_Msk) >> CLIC_INFO_CLICINTCTLBITS_Pos; + return CLIC->CLICINT[IRQn].CTL >> (8 - nlbits); +} + +/** + \brief Get Interrupt thresh + \details Read the thresh of interrupt + Only the interrupt priority is greater than the value of thresh, the interrupt can be responded to + \return Interrupt thresh value(0~255). + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t csi_vic_get_thresh(void) +{ + return CLIC->MINTTHRESH >> 24; +} + +/** + \brief Set Interrupt thresh + \details Write the thresh of interrupt + Only the interrupt priority is greater than the value of thresh, the interrupt can be responded to + \param [in] Interrupt thresh value(0~255). + */ +__STATIC_INLINE uint32_t csi_vic_set_thresh(uint32_t thresh) +{ + uint32_t temp = CLIC->MINTTHRESH; + uint8_t nlbits = (CLIC->CLICINFO & CLIC_INFO_CLICINTCTLBITS_Msk) >> CLIC_INFO_CLICINTCTLBITS_Pos; + + if(!nlbits) + CLIC->MINTTHRESH = 0xff << 24; + + CLIC->MINTTHRESH = thresh << 24; + __DSB(); + return temp; +} + +/*@} end of CSI_Core_VICFunctions */ + +/* ########################## PMP functions #################################### */ +/** + \ingroup CSI_Core_FunctionInterface + \defgroup CSI_Core_PMPFunctions PMP Functions + \brief Functions that manage interrupts and exceptions via the VIC. + @{ + */ + +/** + \brief configure physical memory protection region. + \details + \param [in] idx memory protection region (0, 1, 2, ..., 15). + \param [in] base_addr base address must be aligned with page size. + \param [in] size \ref region_size_e. memory protection region size. + \param [in] attr \ref pmp_region_attr_t. memory protection region attribute. + \param [in] enable enable or disable memory protection region. + */ +__STATIC_INLINE void csi_pmp_config_region(uint32_t idx, unsigned long base_addr, region_size_e size, + pmp_region_attr_t attr, uint32_t enable) +{ + uint8_t pmpxcfg = 0; + uint32_t addr = 0; + + if (idx > 15) { + return; + } + + if (!enable) { + attr.a = (address_matching_e)0; + } + + if (attr.a == ADDRESS_MATCHING_TOR) { + addr = base_addr >> 2; + } else { + if (size == REGION_SIZE_4B) { + addr = base_addr >> 2; + attr.a = (address_matching_e)2; + } else { + addr = ((base_addr >> 2) & (0xFFFFFFFFU - ((1 << (size + 1)) - 1))) | ((1 << size) - 1); + } + } + + __set_PMPADDRx(idx, addr); + + pmpxcfg |= (attr.r << PMP_PMPCFG_R_Pos) | (attr.w << PMP_PMPCFG_W_Pos) | + (attr.x << PMP_PMPCFG_X_Pos) | (attr.a << PMP_PMPCFG_A_Pos) | + (attr.l << PMP_PMPCFG_L_Pos); + + __set_PMPxCFG(idx, pmpxcfg); +} + +/** + \brief disable physical memory protection region by idx. + \details + \param [in] idx memory protection region (0, 1, 2, ..., 15). + */ +__STATIC_INLINE void csi_pmp_disable_region(uint32_t idx) +{ + __set_PMPxCFG(idx, __get_PMPxCFG(idx) & (~PMP_PMPCFG_A_Msk)); +} + +/*@} end of CSI_Core_PMPFunctions */ + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CSI_Core_FunctionInterface + \defgroup CSI_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +__STATIC_INLINE uint32_t _csi_coret_config(unsigned long coret_base, uint64_t ticks, int32_t IRQn) +{ + CORET_Type *coret = (CORET_Type *)coret_base; + if ((coret->MTIMECMP != 0) && (coret->MTIMECMP != 0xFFFFFFFFFFFFFFFFULL)) { + coret->MTIMECMP = coret->MTIMECMP + ticks; + } else { + coret->MTIMECMP = coret->MTIME + ticks; + } + return (0UL); +} + +/** + \brief CORE timer Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \param [in] IRQn core timer Interrupt number. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t csi_coret_config(uint64_t ticks, int32_t IRQn) +{ + return _csi_coret_config(CORET_BASE, ticks, IRQn); +} + +/** + \brief get CORE timer reload value + \return CORE timer counter value(64bit). + */ +__STATIC_INLINE uint64_t csi_coret_get_load2(void) +{ + return CORET->MTIMECMP; +} + +/** + \brief get CORE timer reload value(deprecated) + \return CORE timer counter value. + */ +__STATIC_INLINE unsigned long csi_coret_get_load(void) +{ + return CORET->MTIMECMP & 0xFFFFFFFF; +} + +/** + \brief get CORE timer reload high value(deprecated) + \return CORE timer counter value. + */ +__STATIC_INLINE uint32_t csi_coret_get_loadh(void) +{ + return (CORET->MTIMECMP >> 32) & 0xFFFFFFFF; +} + +/** + \brief get CORE timer counter value + \return CORE timer counter value(64bit). + */ +__STATIC_INLINE uint64_t csi_coret_get_value2(void) +{ + return CORET->MTIME; +} + +/** + \brief get CORE timer counter value(deprecated) + \return CORE timer counter value. + */ +__STATIC_INLINE unsigned long csi_coret_get_value(void) +{ + return CORET->MTIME & 0xFFFFFFFF; +} + +/** + \brief get CORE timer counter high value(deprecated) + \return CORE timer counter value. + */ +__STATIC_INLINE uint32_t csi_coret_get_valueh(void) +{ + return (CORET->MTIME >> 32) & 0xFFFFFFFF; +} + +__STATIC_INLINE void csi_coret_reset_value2() +{ + CORET_Type *coret = (CORET_Type *)CORET_BASE; + coret->MTIMECMP = 0; +} + +/** + \brief Enable CoreTimer(within clint) Interrupts + */ +__ALWAYS_STATIC_INLINE void csi_coret_irq_enable(void) +{ + extern void soc_irq_enable(uint32_t irq_num); + return soc_irq_enable(7); +} + +/** + \brief Disable CoreTimer(within clint) Interrupts + */ +__ALWAYS_STATIC_INLINE void csi_coret_irq_disable(void) +{ + extern void soc_irq_disable(uint32_t irq_num); + return soc_irq_disable(7); +} + +/*@} end of CSI_Core_SysTickFunctions */ + +/* ########################## SYSMAP functions #################################### */ +/** + \ingroup CSI_Core_FunctionInterface + \defgroup CSI_Core_SYSMAPFunctions SYSMAP Functions + \brief Functions that manage system map attribute + @{ + */ + +/** + \brief Get SYSMAPCFGx Register by index + \details Returns the content of the SYSMAPxCFG Register. + \param [in] idx SYSMAP region index + \return SYSMAPxCFG Register value + */ +__STATIC_INLINE uint8_t __get_SYSMAPCFGx(uint32_t idx) +{ + switch (idx) { + case 0: + return SYSMAP->SYSMAPCFG0; + case 1: + return SYSMAP->SYSMAPCFG1; + case 2: + return SYSMAP->SYSMAPCFG2; + case 3: + return SYSMAP->SYSMAPCFG3; + case 4: + return SYSMAP->SYSMAPCFG4; + case 5: + return SYSMAP->SYSMAPCFG5; + case 6: + return SYSMAP->SYSMAPCFG6; + case 7: + return SYSMAP->SYSMAPCFG7; + default: + return 0; + } +} + +/** + \brief Set SYSMAPCFGx by index + \details Writes the given value to the SYSMAPxCFG Register. + \param [in] idx SYSMAPx region index + \param [in] sysmapxcfg SYSMAPxCFG Register value to set + */ +__STATIC_INLINE void __set_SYSMAPCFGx(uint32_t idx, uint32_t sysmapxcfg) +{ + switch (idx) { + case 0: + SYSMAP->SYSMAPCFG0 = sysmapxcfg; + break; + case 1: + SYSMAP->SYSMAPCFG1 = sysmapxcfg; + break; + case 2: + SYSMAP->SYSMAPCFG2 = sysmapxcfg; + break; + case 3: + SYSMAP->SYSMAPCFG3 = sysmapxcfg; + break; + case 4: + SYSMAP->SYSMAPCFG4 = sysmapxcfg; + break; + case 5: + SYSMAP->SYSMAPCFG5 = sysmapxcfg; + break; + case 6: + SYSMAP->SYSMAPCFG6 = sysmapxcfg; + break; + case 7: + SYSMAP->SYSMAPCFG7 = sysmapxcfg; + break; + default: + return; + } +} + +/** + \brief Get SYSMAPADDRx Register by index + \details Returns the content of the SYSMAPADDRx Register. + \param [in] idx SYSMAP region index + \return SYSMAPADDRx Register value + */ +__STATIC_INLINE uint32_t __get_SYSMAPADDRx(uint32_t idx) +{ + switch(idx) { + case 0: + return SYSMAP->SYSMAPADDR0; + case 1: + return SYSMAP->SYSMAPADDR1; + case 2: + return SYSMAP->SYSMAPADDR2; + case 3: + return SYSMAP->SYSMAPADDR3; + case 4: + return SYSMAP->SYSMAPADDR4; + case 5: + return SYSMAP->SYSMAPADDR5; + case 6: + return SYSMAP->SYSMAPADDR6; + case 7: + return SYSMAP->SYSMAPADDR7; + default: + return 0; + } +} + +/** + \brief Set SYSMAPADDRx by index + \details Writes the given value to the SYSMAPADDRx Register. + \param [in] idx SYSMAP region index + \param [in] sysmapaddr SYSMAPADDRx Register value to set + */ +__STATIC_INLINE void __set_SYSMAPADDRx(uint32_t idx, uint32_t sysmapxaddr) +{ + switch (idx) { + case 0: + SYSMAP->SYSMAPADDR0 = sysmapxaddr; + break; + case 1: + SYSMAP->SYSMAPADDR1 = sysmapxaddr; + break; + case 2: + SYSMAP->SYSMAPADDR2 = sysmapxaddr; + break; + case 3: + SYSMAP->SYSMAPADDR3 = sysmapxaddr; + break; + case 4: + SYSMAP->SYSMAPADDR4 = sysmapxaddr; + break; + case 5: + SYSMAP->SYSMAPADDR5 = sysmapxaddr; + break; + case 6: + SYSMAP->SYSMAPADDR6 = sysmapxaddr; + break; + case 7: + SYSMAP->SYSMAPADDR7 = sysmapxaddr; + break; + default: + return; + } +} + +/** + \brief configure system map attribute. + \details + \param [in] idx system map region (0, 1, 2, ..., 7). + \param [in] base_addr base address must be aligned with page size. + \param [in] enable enable or disable memory protected region. + */ +__STATIC_INLINE void csi_sysmap_config_region(uint32_t idx, uint32_t base_addr, uint32_t attr) +{ + uint32_t addr = 0; + + if (idx > 7) { + return; + } + + addr = base_addr >> 12; + attr = attr << 2; + + __set_SYSMAPADDRx(idx, addr); + __set_SYSMAPCFGx(idx, attr); +} + +/*@} end of CSI_Core_SYSMAPFunctions */ + +/* ########################## Cache functions #################################### */ +/** + \ingroup CSI_Core_FunctionInterface + \defgroup CSI_Core_CacheFunctions Cache Functions + \brief Functions that configure Instruction and Data cache. + @{ + */ + +/** + \brief whether I-Cache enable + */ +__STATIC_INLINE int csi_icache_is_enable() +{ + uint32_t cache = __get_MHCR(); + return (cache & CACHE_MHCR_IE_Msk) >> CACHE_MHCR_IE_Pos; +} + +/** + \brief Enable I-Cache + \details Turns on I-Cache + */ +__STATIC_INLINE void csi_icache_enable (void) +{ +#if (__ICACHE_PRESENT == 1U) + if (!csi_icache_is_enable()) { + uint32_t cache; + __DSB(); + __ICACHE_IALL(); + cache = __get_MHCR(); + cache |= CACHE_MHCR_IE_Msk; + __set_MHCR(cache); + __DSB(); + } +#endif +} + + +/** + \brief Disable I-Cache + \details Turns off I-Cache + */ +__STATIC_INLINE void csi_icache_disable (void) +{ +#if (__ICACHE_PRESENT == 1U) + if (csi_icache_is_enable()) { + uint32_t cache; + __DSB(); + cache = __get_MHCR(); + cache &= ~CACHE_MHCR_IE_Msk; /* disable icache */ + __set_MHCR(cache); + __ICACHE_IALL(); /* invalidate all icache */ + __DSB(); + } +#endif +} + + +/** + \brief Invalidate I-Cache + \details Invalidates I-Cache + */ +__STATIC_INLINE void csi_icache_invalid (void) +{ +#if (__ICACHE_PRESENT == 1U) + __DSB(); + __ICACHE_IALL(); /* invalidate all icache */ + __DSB(); +#endif +} + +/** + \brief whether D-Cache enable + */ +__STATIC_INLINE int csi_dcache_is_enable() +{ + uint32_t cache = __get_MHCR(); + return (cache & CACHE_MHCR_DE_Msk) >> CACHE_MHCR_DE_Pos; +} + +/** + \brief Enable D-Cache + \details Turns on D-Cache + */ +__STATIC_INLINE void csi_dcache_enable (void) +{ +#if (__DCACHE_PRESENT == 1U) + if (!csi_dcache_is_enable()) { + uint32_t cache; + __DSB(); + __DCACHE_IALL(); /* invalidate all dcache */ + cache = __get_MHCR(); + cache |= CACHE_MHCR_DE_Msk; /* enable dcache */ + __set_MHCR(cache); + + __DSB(); + } +#endif +} + + +/** + \brief Disable D-Cache + \details Turns off D-Cache + */ +__STATIC_INLINE void csi_dcache_disable (void) +{ +#if (__DCACHE_PRESENT == 1U) + if (csi_dcache_is_enable()) { + uint32_t cache; + __DSB(); + cache = __get_MHCR(); + cache &= ~(uint32_t)CACHE_MHCR_DE_Msk; /* disable all Cache */ + __set_MHCR(cache); + __DCACHE_IALL(); /* invalidate all Cache */ + __DSB(); + } +#endif +} + + +/** + \brief Invalidate D-Cache + \details Invalidates D-Cache + */ +__STATIC_INLINE void csi_dcache_invalid (void) +{ +#if (__DCACHE_PRESENT == 1U) + __DSB(); + __DCACHE_IALL(); /* invalidate all Cache */ + __DSB(); +#endif +} + + +/** + \brief Clean D-Cache + \details Cleans D-Cache + */ +__STATIC_INLINE void csi_dcache_clean (void) +{ +#if (__DCACHE_PRESENT == 1U) + __DSB(); + __DCACHE_CALL(); /* clean all Cache */ + __DSB(); +#endif +} + + +/** + \brief Clean & Invalidate D-Cache + \details Cleans and Invalidates D-Cache + */ +__STATIC_INLINE void csi_dcache_clean_invalid (void) +{ +#if (__DCACHE_PRESENT == 1U) + __DSB(); + __DCACHE_CIALL(); /* clean and inv all Cache */ + __DSB(); +#endif +} + + +/** + \brief D-Cache Invalidate by address + \details Invalidates D-Cache for the given address + \param[in] addr address (aligned to 32-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_INLINE void csi_dcache_invalid_range (unsigned long *addr, size_t dsize) +{ +#if (__DCACHE_PRESENT == 1U) + int linesize = csi_get_cache_line_size(); + long op_size = dsize + (unsigned long)addr % linesize; + unsigned long op_addr = (unsigned long)addr & CACHE_INV_ADDR_Msk; + + __DSB(); + + while (op_size > 0) { + __DCACHE_IPA(op_addr); + op_addr += linesize; + op_size -= linesize; + } + + __DSB(); +#endif +} + + +/** + \brief D-Cache Clean by address + \details Cleans D-Cache for the given address + \param[in] addr address (aligned to 32-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_INLINE void csi_dcache_clean_range (unsigned long *addr, size_t dsize) +{ + +#if (__DCACHE_PRESENT == 1U) + int linesize = csi_get_cache_line_size(); + long op_size = dsize + (unsigned long)addr % linesize; + unsigned long op_addr = (unsigned long) addr & CACHE_INV_ADDR_Msk; + + __DSB(); + + while (op_size > 0) { + __DCACHE_CPA(op_addr); + op_addr += linesize; + op_size -= linesize; + } + + __DSB(); +#endif + +} + + +/** + \brief D-Cache Clean and Invalidate by address + \details Cleans and invalidates D_Cache for the given address + \param[in] addr address (aligned to 16-byte boundary) + \param[in] dsize size of memory block (aligned to 16-byte boundary) +*/ +__STATIC_INLINE void csi_dcache_clean_invalid_range (unsigned long *addr, size_t dsize) +{ +#if (__DCACHE_PRESENT == 1U) + int linesize = csi_get_cache_line_size(); + long op_size = dsize + (unsigned long)addr % linesize; + unsigned long op_addr = (unsigned long) addr & CACHE_INV_ADDR_Msk; + + __DSB(); + + while (op_size > 0) { + __DCACHE_CIPA(op_addr); + op_addr += linesize; + op_size -= linesize; + } + + __DSB(); +#endif +} + +/*@} end of CSI_Core_CacheFunctions */ + +#if (CONFIG_CPU_XUANTIE_E907 || CONFIG_CPU_XUANTIE_E907F || CONFIG_CPU_XUANTIE_E907FD || CONFIG_CPU_XUANTIE_E907P || CONFIG_CPU_XUANTIE_E907FP || CONFIG_CPU_XUANTIE_E907FDP) +/** + \ingroup CSI_tcm_register + \defgroup CSI_TCM + \brief Type definitions for the tcm Registers + @{ + */ + +/** + \brief Consortium definition for accessing protection area selection register(MITCMCR, csr<0x7f9>). + */ +typedef union { + struct { + uint32_t EN: 1; /*!< bit: 0 Instruction Tightly-Coupled Memory enable */ + uint32_t _reserved0: 1; /*!< bit: 1 Reserved */ + uint32_t _reserved1: 1; /*!< bit: 2 Reserved */ + uint32_t _reserved2: 1; /*!< bit: 3 Reserved */ + uint32_t Size: 4; /*!< bit: 4..7 Size of ITCM */ + uint32_t _reserved4: 4; /*!< bit: 8..11 Reserved */ + uint32_t Base_Address: 20; /*!< bit: 12..31 Base address of ITCM */ + } b; /*!< Structure Access by bit */ + uint32_t w; /*!< Type Access by whole register */ +} MITCMCR_Type; + +#define MITCMCR_Base_Address_Pos 12U /*!< MITCMCR: Base_Address Position */ +#define MITCMCR_Base_Address_Msk (0xfffffUL << MITCMCR_Base_Address_Pos) /*!< MITCMCR: Base_Address Mask */ + +#define MITCMCR_Size_Pos 4U /*!< MITCMCR: Size Position */ +#define MITCMCR_Size_Msk (0xfUL << MITCMCR_Size_Pos) /*!< MITCMCR: Size Mask */ + +#define MITCMCR_EN_Pos 0U /*!< MITCMCR: EN Position */ +#define MITCMCR_EN_Msk (0x1UL << MITCMCR_EN_Pos) /*!< MITCMCR: EN Mask */ + +/** + \brief Consortium definition for accessing protection area selection register(MDTCMCR, csr<0x7f8>). + */ +typedef union { + struct { + uint32_t EN: 1; /*!< bit: 0 Instruction Tightly-Coupled Memory enable */ + uint32_t _reserved0: 1; /*!< bit: 1 Reserved */ + uint32_t _reserved1: 1; /*!< bit: 2 Reserved */ + uint32_t _reserved2: 1; /*!< bit: 3 Reserved */ + uint32_t Size: 4; /*!< bit: 4..7 Size of DTCM */ + uint32_t _reserved4: 4; /*!< bit: 8..11 Reserved */ + uint32_t Base_Address: 20; /*!< bit: 12..31 Base address of DTCM */ + } b; /*!< Structure Access by bit */ + uint32_t w; /*!< Type Access by whole register */ +} MDTCMCR_Type; + +#define MDTCMCR_Base_Address_Pos 12U /*!< MDTCMCR: Base_Address Position */ +#define MDTCMCR_Base_Address_Msk (0xfffffUL << MDTCMCR_Base_Address_Pos) /*!< MDTCMCR: Base_Address Mask */ + +#define MDTCMCR_Size_Pos 4U /*!< MDTCMCR: Size Position */ +#define MDTCMCR_Size_Msk (0xfUL << MDTCMCR_Size_Pos) /*!< MDTCMCR: Size Mask */ + +#define MDTCMCR_EN_Pos 0U /*!< MDTCMCR: EN Position */ +#define MDTCMCR_EN_Msk (0x1UL << MDTCMCR_EN_Pos) /*!< MDTCMCR: EN Mask */ +/*@} end of group CSI_TCM_bitfield */ + +/* ########################## TCM functions #################################### */ +/** + \ingroup CSI_Core_FunctionInterface + \defgroup CSI_Core_TCMFunctions TCM Functions + \brief Functions that configure TCM. + @{ + */ + +/** + \brief Enable ITCM + \details Turns on ITCM + */ +__STATIC_INLINE void csi_itcm_enable (void) +{ + __set_MITCMCR(__get_MITCMCR() | MITCMCR_EN_Msk); +} + +/** + \brief Enable DTCM + \details Turns on DTCM + */ +__STATIC_INLINE void csi_dtcm_enable (void) +{ + __set_MDTCMCR(__get_MDTCMCR() | MDTCMCR_EN_Msk); +} + +/** + \brief Enable ITCM + \details Turns on ITCM + */ +__STATIC_INLINE void csi_itcm_disable (void) +{ + __set_MITCMCR(__get_MITCMCR() & (~MITCMCR_EN_Msk)); +} + +/** + \brief Enable DTCM + \details Turns on DTCM + */ +__STATIC_INLINE void csi_dtcm_disable (void) +{ + __set_MDTCMCR(__get_MDTCMCR() & (~MDTCMCR_EN_Msk)); +} + +/** + \brief Get ITCM Size + \details Get ITCM Size + \return ITCM size (bytes). + */ +__STATIC_INLINE uint32_t csi_itcm_get_size(void) +{ + MITCMCR_Type sizemask; + uint32_t ret; + + sizemask.w = __get_MITCMCR(); + switch (sizemask.b.Size) + { + case 0x3: ret = 4 << 10; break; + case 0x4: ret = 8 << 10; break; + case 0x5: ret = 16 << 10; break; + case 0x6: ret = 32 << 10; break; + case 0x7: ret = 64 << 10; break; + case 0x8: ret = 128 << 10; break; + case 0x9: ret = 256 << 10; break; + case 0xa: ret = 512 << 10; break; + case 0xb: ret = 1 << 20; break; + case 0xc: ret = 2 << 20; break; + case 0xd: ret = 4 << 20; break; + case 0xe: ret = 8 << 20; break; + case 0xf: ret = 16 << 20; break; + default: ret = 0; break; + } + return ret; +} + +/** + \brief Get DTCM Size + \details Get DTCM Size + \return DTCM size (bytes). + */ +__STATIC_INLINE uint32_t csi_dtcm_get_size(void) +{ + MDTCMCR_Type sizemask; + uint32_t ret; + + sizemask.w = __get_MDTCMCR(); + switch (sizemask.b.Size) + { + case 0x3: ret = 4 << 10; break; + case 0x4: ret = 8 << 10; break; + case 0x5: ret = 16 << 10; break; + case 0x6: ret = 32 << 10; break; + case 0x7: ret = 64 << 10; break; + case 0x8: ret = 128 << 10; break; + case 0x9: ret = 256 << 10; break; + case 0xa: ret = 512 << 10; break; + case 0xb: ret = 1 << 20; break; + case 0xc: ret = 2 << 20; break; + case 0xd: ret = 4 << 20; break; + case 0xe: ret = 8 << 20; break; + case 0xf: ret = 16 << 20; break; + default: ret = 0; break; + } + return ret; +} + +/** + \brief Set ITCM Base Address + \details Set ITCM Base Address + \param [in] base_addr itcm base address. + */ +__STATIC_INLINE void csi_itcm_set_base_addr(unsigned long base_addr) +{ + __set_MITCMCR((__get_MITCMCR() & (~MITCMCR_Base_Address_Msk)) | (base_addr & MITCMCR_Base_Address_Msk)); +} + +/** + \brief Set DTCM Base Address + \details Set DTCM Base Address + \param [in] base_addr dtcm base address. + */ +__STATIC_INLINE void csi_dtcm_set_base_addr(unsigned long base_addr) +{ + __set_MDTCMCR((__get_MDTCMCR() & (~MDTCMCR_Base_Address_Msk)) | (base_addr & MDTCMCR_Base_Address_Msk)); +} + +/*@} end of CSI_Core_TCMFunctions */ +#endif /* end e907xx */ + + +/*@} end of CSI_core_DebugFunctions */ + +/* ################################## IRQ Functions ############################################ */ + +/** + \brief Save the Irq context + \details save the psr result before disable irq. + */ +__STATIC_INLINE uint32_t csi_irq_save(void) +{ + uint32_t result; + result = __get_MSTATUS(); + __disable_irq(); + return(result); +} + +/** + \brief Restore the Irq context + \details restore saved primask state. + \param [in] irq_state psr irq state. + */ +__STATIC_INLINE void csi_irq_restore(uint32_t irq_state) +{ + __set_MSTATUS(irq_state); +} + +/*@} end of IRQ Functions */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_RV32_H_DEPENDANT */ + +#endif /* __CSI_GENERIC */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/core/core_rv64.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/core/core_rv64.h new file mode 100644 index 00000000..c5463e93 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/core/core_rv64.h @@ -0,0 +1,2002 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 core_rv64.h + * @brief CSI RV32 Core Peripheral Access Layer Header File + * @version V1.0 + * @date 01. Sep 2018 + ******************************************************************************/ + +#ifndef __CORE_RV64_H_GENERIC +#define __CORE_RV64_H_GENERIC + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * CSI definitions + ******************************************************************************/ +/** + \ingroup RV32 + @{ + */ + +#ifndef __RV64 +#define __RV64 (0x01U) +#endif + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __GNUC__ ) +#if defined (__VFP_FP__) && !defined(__SOFTFP__) +#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" +#endif +#endif + +#if defined(CONFIG_PLIC_BASE) +#ifndef CORET_BASE +#define CORET_BASE (CONFIG_PLIC_BASE + 0x4000000UL) /*!< CORET Base Address */ +#endif +#define PLIC ((PLIC_Type *)CONFIG_PLIC_BASE) +#else +#error "CONFIG_PLIC_BASE is not defined!" +#endif /* end CONFIG_PLIC_BASE */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_RV32_H_GENERIC */ + +#ifndef __CSI_GENERIC + +#ifndef __CORE_RV32_H_DEPENDANT +#define __CORE_RV32_H_DEPENDANT + +#ifdef __cplusplus +extern "C" { +#endif + +/* check device defines and use defaults */ +#ifndef __RV64_REV +#define __RV64_REV 0x0000U +#endif + +#ifndef __VIC_PRIO_BITS +#define __VIC_PRIO_BITS 2U +#endif + +#ifndef __Vendor_SysTickConfig +#define __Vendor_SysTickConfig 1U +#endif + +#ifndef __MPU_PRESENT +#define __MPU_PRESENT 1U +#endif + +#ifndef __ICACHE_PRESENT +#define __ICACHE_PRESENT 1U +#endif + +#ifndef __DCACHE_PRESENT +#define __DCACHE_PRESENT 1U +#endif + + +#ifndef __L2CACHE_PRESENT +#define __L2CACHE_PRESENT 1U +#endif + +#include + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CSI_glob_defs CSI Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus +#define __I volatile /*!< Defines 'read only' permissions */ +#else +#define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group C9xx/R9xx */ + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core CLINT Register + ******************************************************************************/ +/** + \defgroup CSI_core_register Defines and Type Definitions + \brief Type definitions and defines for CK80X processor based devices. +*/ + +/** + \ingroup CSI_core_register + \defgroup CSI_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +#if CONFIG_INTC_CLIC_PLIC +/** + \brief Access to the structure of a CLIC vector interrupt controller. + */ +typedef struct { + __IOM uint8_t IP; /*!< Offset: 0x000 (R/W) Interrupt set pending register */ + __IOM uint8_t IE; /*!< Offset: 0x004 (R/W) Interrupt set enable register */ + __IOM uint8_t ATTR; /*!< Offset: 0x008 (R/W) Interrupt set attribute register */ + __IOM uint8_t CTL; /*!< Offset: 0x00C (R/W) Interrupt control register */ +} CLIC_INT_Control; + +typedef struct { + __IOM uint32_t CLICCFG:8; /*!< Offset: 0x000 (R/W) CLIC configure register */ + __IM uint32_t CLICINFO; + __IOM uint32_t MINTTHRESH; + uint32_t RESERVED[1021]; + CLIC_INT_Control CLICINT[4096]; +} CLIC_Type; + +#define CLIC_INFO_CLICINTCTLBITS_Pos 21U +#define CLIC_INFO_CLICINTCTLBITS_Msk (0xFUL << CLIC_INFO_CLICINTCTLBITS_Pos) + +#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 */ + +#define CLIC_INTIE_T_Pos 7U /*!< CLIC INTIE: T Position */ +#define CLIC_INTIE_T_Msk (0x1UL << CLIC_INTIE_T_Pos) /*!< CLIC INTIE: T Mask */ + +#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 CLIC_INTCFG_NVBIT_Pos 5U /*!< CLIC INTCFG: NVBIT Position */ +#define CLIC_INTCFG_NVBIT_Msk (0x1UL << CLIC_INTCFG_NVBIT_Pos) /*!< CLIC INTCFG: NVBIT Mask */ + +#define CLIC_INTCFG_PRIO_Pos 5U /*!< CLIC INTCFG: INTCFG Position */ +#define CLIC_INTCFG_PRIO_Msk (0x7UL << CLIC_INTCFG_PRIO_Pos) /*!< CLIC INTCFG: INTCFG Mask */ + +#define CLIC_CLICCFG_NVBIT_Pos 0U /*!< CLIC CLICCFG: NVBIT Position */ +#define CLIC_CLICCFG_NVBIT_Msk (0x1UL << CLIC_CLICCFG_NVBIT_Pos) /*!< CLIC CLICCFG: NVBIT Mask */ + +#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_CLICCFG_NMBIT_Pos 5U /*!< CLIC CLICCFG: NMBIT Position */ +#define CLIC_CLICCFG_NMBIT_Msk (0x3UL << CLIC_CLICCFG_NMBIT_Pos) /*!< CLIC CLICCFG: NMBIT Mask */ + +#if defined(CONFIG_CLIC_BASE) +#define CLIC ((CLIC_Type *)CONFIG_CLIC_BASE) /*!< CLIC configuration struct */ +#else +#error "CONFIG_CLIC_BASE is not defined!" +#endif /* end CONFIG_CLIC_BASE */ + +#endif /* CONFIG_INTC_CLIC_PLIC */ + + +/** + \brief Access to the structure of a PLIC vector interrupt controller. + */ + +typedef struct { + uint32_t RESERVED0; + __IOM uint32_t PLIC_PRIO[1023]; + __IOM uint32_t PLIC_IP[32]; + uint32_t RESERVED1[3972 / 4 - 1]; + __IOM uint32_t PLIC_H0_MIE[32]; + __IOM uint32_t PLIC_H0_SIE[32]; + __IOM uint32_t PLIC_H1_MIE[32]; + __IOM uint32_t PLIC_H1_SIE[32]; + __IOM uint32_t PLIC_H2_MIE[32]; + __IOM uint32_t PLIC_H2_SIE[32]; + __IOM uint32_t PLIC_H3_MIE[32]; + __IOM uint32_t PLIC_H3_SIE[32]; + __IOM uint32_t PLIC_H4_MIE[32]; + __IOM uint32_t PLIC_H4_SIE[32]; + __IOM uint32_t PLIC_H5_MIE[32]; + __IOM uint32_t PLIC_H5_SIE[32]; + __IOM uint32_t PLIC_H6_MIE[32]; + __IOM uint32_t PLIC_H6_SIE[32]; + __IOM uint32_t PLIC_H7_MIE[32]; + __IOM uint32_t PLIC_H7_SIE[32]; + + uint32_t RESERVED2[(0x01FFFFC - 0x00027FC) / 4 - 1]; + __IOM uint32_t PLIC_PER; + __IOM uint32_t PLIC_H0_MTH; + __IOM uint32_t PLIC_H0_MCLAIM; + uint32_t RESERVED3[0xFFC / 4 - 1]; + __IOM uint32_t PLIC_H0_STH; + __IOM uint32_t PLIC_H0_SCLAIM; + uint32_t RESERVED4[0xFFC / 4 - 1]; + + __IOM uint32_t PLIC_H1_MTH; + __IOM uint32_t PLIC_H1_MCLAIM; + uint32_t RESERVED5[0xFFC / 4 - 1]; + __IOM uint32_t PLIC_H1_STH; + __IOM uint32_t PLIC_H1_SCLAIM; + uint32_t RESERVED6[0xFFC / 4 - 1]; + + __IOM uint32_t PLIC_H2_MTH; + __IOM uint32_t PLIC_H2_MCLAIM; + uint32_t RESERVED7[0xFFC / 4 - 1]; + __IOM uint32_t PLIC_H2_STH; + __IOM uint32_t PLIC_H2_SCLAIM; + uint32_t RESERVED8[0xFFC / 4 - 1]; + + __IOM uint32_t PLIC_H3_MTH; + __IOM uint32_t PLIC_H3_MCLAIM; + uint32_t RESERVED9[0xFFC / 4 - 1]; + __IOM uint32_t PLIC_H3_STH; + __IOM uint32_t PLIC_H3_SCLAIM; + uint32_t RESERVED10[0xFFC / 4 - 1]; + + __IOM uint32_t PLIC_H4_MTH; + __IOM uint32_t PLIC_H4_MCLAIM; + uint32_t RESERVED11[0xFFC / 4 - 1]; + __IOM uint32_t PLIC_H4_STH; + __IOM uint32_t PLIC_H4_SCLAIM; + uint32_t RESERVED12[0xFFC / 4 - 1]; + + __IOM uint32_t PLIC_H5_MTH; + __IOM uint32_t PLIC_H5_MCLAIM; + uint32_t RESERVED13[0xFFC / 4 - 1]; + __IOM uint32_t PLIC_H5_STH; + __IOM uint32_t PLIC_H5_SCLAIM; + uint32_t RESERVED14[0xFFC / 4 - 1]; + + __IOM uint32_t PLIC_H6_MTH; + __IOM uint32_t PLIC_H6_MCLAIM; + uint32_t RESERVED15[0xFFC / 4 - 1]; + __IOM uint32_t PLIC_H6_STH; + __IOM uint32_t PLIC_H6_SCLAIM; + uint32_t RESERVED16[0xFFC / 4 - 1]; + + __IOM uint32_t PLIC_H7_MTH; + __IOM uint32_t PLIC_H7_MCLAIM; + uint32_t RESERVED17[0xFFC / 4 - 1]; + __IOM uint32_t PLIC_H7_STH; + __IOM uint32_t PLIC_H7_SCLAIM; + uint32_t RESERVED18[0xFFC / 4 - 1]; +} PLIC_Type; + + +/** + \ingroup CSI_core_register + \defgroup CSI_PMP Physical Memory Protection (PMP) + \brief Type definitions for the PMP Registers + @{ + */ + +#define PMP_PMPCFG_R_Pos 0U /*!< PMP PMPCFG: R Position */ +#define PMP_PMPCFG_R_Msk (0x1UL << PMP_PMPCFG_R_Pos) /*!< PMP PMPCFG: R Mask */ + +#define PMP_PMPCFG_W_Pos 1U /*!< PMP PMPCFG: W Position */ +#define PMP_PMPCFG_W_Msk (0x1UL << PMP_PMPCFG_W_Pos) /*!< PMP PMPCFG: W Mask */ + +#define PMP_PMPCFG_X_Pos 2U /*!< PMP PMPCFG: X Position */ +#define PMP_PMPCFG_X_Msk (0x1UL << PMP_PMPCFG_X_Pos) /*!< PMP PMPCFG: X Mask */ + +#define PMP_PMPCFG_A_Pos 3U /*!< PMP PMPCFG: A Position */ +#define PMP_PMPCFG_A_Msk (0x3UL << PMP_PMPCFG_A_Pos) /*!< PMP PMPCFG: A Mask */ + +#define PMP_PMPCFG_L_Pos 7U /*!< PMP PMPCFG: L Position */ +#define PMP_PMPCFG_L_Msk (0x1UL << PMP_PMPCFG_L_Pos) /*!< PMP PMPCFG: L Mask */ + +typedef enum { + REGION_SIZE_4B = -1, + REGION_SIZE_8B = 0, + REGION_SIZE_16B = 1, + REGION_SIZE_32B = 2, + REGION_SIZE_64B = 3, + REGION_SIZE_128B = 4, + REGION_SIZE_256B = 5, + REGION_SIZE_512B = 6, + REGION_SIZE_1KB = 7, + REGION_SIZE_2KB = 8, + REGION_SIZE_4KB = 9, + REGION_SIZE_8KB = 10, + REGION_SIZE_16KB = 11, + REGION_SIZE_32KB = 12, + REGION_SIZE_64KB = 13, + REGION_SIZE_128KB = 14, + REGION_SIZE_256KB = 15, + REGION_SIZE_512KB = 16, + REGION_SIZE_1MB = 17, + REGION_SIZE_2MB = 18, + REGION_SIZE_4MB = 19, + REGION_SIZE_8MB = 20, + REGION_SIZE_16MB = 21, + REGION_SIZE_32MB = 22, + REGION_SIZE_64MB = 23, + REGION_SIZE_128MB = 24, + REGION_SIZE_256MB = 25, + REGION_SIZE_512MB = 26, + REGION_SIZE_1GB = 27, + REGION_SIZE_2GB = 28, + REGION_SIZE_4GB = 29, + REGION_SIZE_8GB = 30, + REGION_SIZE_16GB = 31 +} region_size_e; + +typedef enum { + ADDRESS_MATCHING_TOR = 1, + ADDRESS_MATCHING_NAPOT = 3 +} address_matching_e; + +typedef struct { + uint32_t r: 1; /* readable enable */ + uint32_t w: 1; /* writeable enable */ + uint32_t x: 1; /* execable enable */ + address_matching_e a: 2; /* address matching mode */ + uint32_t reserved: 2; /* reserved */ + uint32_t l: 1; /* lock enable */ +} pmp_region_attr_t; + +/*@} end of group CSI_PMP */ + +/* CACHE Register Definitions */ +#define CACHE_MHCR_WBR_Pos 8U /*!< CACHE MHCR: WBR Position */ +#define CACHE_MHCR_WBR_Msk (0x1UL << CACHE_MHCR_WBR_Pos) /*!< CACHE MHCR: WBR Mask */ + +#define CACHE_MHCR_IBPE_Pos 7U /*!< CACHE MHCR: IBPE Position */ +#define CACHE_MHCR_IBPE_Msk (0x1UL << CACHE_MHCR_IBPE_Pos) /*!< CACHE MHCR: IBPE Mask */ + +#define CACHE_MHCR_BTB_Pos 6U /*!< CACHE MHCR: BTB Position */ +#define CACHE_MHCR_BTB_Msk (0x1UL << CACHE_MHCR_BTB_Pos) /*!< CACHE MHCR: BTB Mask */ + +#define CACHE_MHCR_BPE_Pos 5U /*!< CACHE MHCR: BPE Position */ +#define CACHE_MHCR_BPE_Msk (0x1UL << CACHE_MHCR_BPE_Pos) /*!< CACHE MHCR: BPE Mask */ + +#define CACHE_MHCR_RS_Pos 4U /*!< CACHE MHCR: RS Position */ +#define CACHE_MHCR_RS_Msk (0x1UL << CACHE_MHCR_RS_Pos) /*!< CACHE MHCR: RS Mask */ + +#define CACHE_MHCR_WB_Pos 3U /*!< CACHE MHCR: WB Position */ +#define CACHE_MHCR_WB_Msk (0x1UL << CACHE_MHCR_WB_Pos) /*!< CACHE MHCR: WB Mask */ + +#define CACHE_MHCR_WA_Pos 2U /*!< CACHE MHCR: WA Position */ +#define CACHE_MHCR_WA_Msk (0x1UL << CACHE_MHCR_WA_Pos) /*!< CACHE MHCR: WA Mask */ + +#define CACHE_MHCR_DE_Pos 1U /*!< CACHE MHCR: DE Position */ +#define CACHE_MHCR_DE_Msk (0x1UL << CACHE_MHCR_DE_Pos) /*!< CACHE MHCR: DE Mask */ + +#define CACHE_MHCR_IE_Pos 0U /*!< CACHE MHCR: IE Position */ +#define CACHE_MHCR_IE_Msk (0x1UL << CACHE_MHCR_IE_Pos) /*!< CACHE MHCR: IE Mask */ + +#if CONFIG_CPU_XUANTIE_R908 || CONFIG_CPU_XUANTIE_R908FD || CONFIG_CPU_XUANTIE_R908FDV \ + || CONFIG_CPU_XUANTIE_R908_CP || CONFIG_CPU_XUANTIE_R908FD_CP || CONFIG_CPU_XUANTIE_R908FDV_CP \ + || CONFIG_CPU_XUANTIE_R908_CP_XT || CONFIG_CPU_XUANTIE_R908FD_CP_XT || CONFIG_CPU_XUANTIE_R908FDV_CP_XT \ + || CONFIG_CPU_XUANTIE_C908X || CONFIG_CPU_XUANTIE_C908X_CP || CONFIG_CPU_XUANTIE_C908X_CP_XT +#define MCER_ECC_FATAL_Pos 34U +#define MCER_ECC_FATAL_Msk (0x1ULL << MCER_ECC_FATAL_Pos) + +#define MCER_ECC_VLD_Pos 35U +#define MCER_ECC_VLD_Msk (0x1ULL << MCER_ECC_VLD_Pos) + +#define MCER_RAMID_Pos 25U +#define MCER_RAMID_Msk (0x7ULL << MCER_RAMID_Pos) +#else +#define MCER_ECC_FATAL_Pos 30U +#define MCER_ECC_FATAL_Msk (0x1ULL << MCER_ECC_FATAL_Pos) +#define MCER_ECC_VLD_Pos 31U +#define MCER_ECC_VLD_Msk (0x1ULL << MCER_ECC_VLD_Pos) +#define MCER_RAMID_Pos 21U +#define MCER_RAMID_Msk (0x7ULL << MCER_RAMID_Pos) +#endif + +#define CACHE_MCER2_ECC_FATAL_Pos 62U +#define CACHE_MCER2_ECC_FATAL_Msk (0x1ULL << CACHE_MCER2_ECC_FATAL_Pos) + +#define CACHE_MCER2H_ECC_FATAL_Pos 30U +#define CACHE_MCER2H_ECC_FATAL_Msk (0x1ULL << CACHE_MCER2H_ECC_FATAL_Pos) + +#define CACHE_MCER2_ECC_VLD_Pos 63U +#define CACHE_MCER2_ECC_VLD_Msk (0x1ULL << CACHE_MCER2_ECC_VLD_Pos) + +#define CACHE_MCER2H_ECC_VLD_Pos 31U +#define CACHE_MCER2H_ECC_VLD_Msk (0x1ULL << CACHE_MCER2H_ECC_VLD_Pos) + +#define CACHE_MCER2_RAMID_Pos 53U +#define CACHE_MCER2_RAMID_Msk (0x3ULL << CACHE_MCER2_RAMID_Pos) + +#define CACHE_MCER2H_RAMID_Pos 21U +#define CACHE_MCER2H_RAMID_Msk (0x3ULL << CACHE_MCER2H_RAMID_Pos) + +#define CACHE_INV_ADDR_Pos 6U +#define CACHE_INV_ADDR_Msk (~((0x1ULL << CACHE_INV_ADDR_Pos) - 1)) + +enum MCER_FAULT_RAMID { + /* L1 Cache, JTLB and TCM (RAMID of MCER)*/ + MCER_FAULT_RAMID_L1_ICACHE_TAG = 0, + MCER_FAULT_RAMID_L1_ICACHE_DATA, + MCER_FAULT_RAMID_L1_DCACHE_TAG, + MCER_FAULT_RAMID_L1_DCACHE_DATA, + MCER_FAULT_RAMID_JTLB_TAG, + MCER_FAULT_RAMID_JTLB_DATA, + MCER_FAULT_RAMID_DTCM, + MCER_FAULT_RAMID_ITCM +}; + +enum MCER2_FAULT_RAMID { + MCER2_FAULT_RAMID_L2_CACHE_TAG = 0, + MCER2_FAULT_RAMID_L2_CACHE_DATA, + MCER2_FAULT_RAMID_L2_CACHE_DIRTY +}; + +/*@} end of group CSI_CACHE */ + +// MSTATUS Register +#define MSTATUS_TVM_MASK (1L << 20) // mstatus.TVM [20] +#define MSTATUS_MPP_MASK (3L << 11) // mstatus.SPP [11:12] +#ifndef MSTATUS_MPP_M +#define MSTATUS_MPP_M (3L << 11) // Machine mode 11 +#endif +#define MSTATUS_MPP_S (1L << 11) // Supervisor mode 01 +#define MSTATUS_MPP_U (0L << 11) // User mode 00 + +// SSTATUS Register +#define SSTATUS_SPP_MASK (3L << 8) // sstatus.SPP [8:9] +#define SSTATUS_SPP_S (1L << 8) // Supervisor mode 01 +#define SSTATUS_SPP_U (0L << 8) // User mode 00 + +typedef enum { + USER_MODE = 0, + SUPERVISOR_MODE = 1, + MACHINE_MODE = 3, +} cpu_work_mode_t; + +/** + \brief Get CPU WORK MODE + \details Returns CPU WORK MODE. + \return CPU WORK MODE + */ +__STATIC_INLINE int csi_get_cpu_work_mode(void) +{ + return (int)__get_CPU_WORK_MODE(); +} + +/** + \brief Get current hartid + \return hartid + */ +__STATIC_INLINE int csi_get_cpu_id(void) +{ + unsigned long result; + +#if defined(CONFIG_RISCV_SMODE) && CONFIG_RISCV_SMODE + return 0; +#endif + __ASM volatile("csrr %0, mhartid" : "=r"(result) : : "memory"); + return result; +} + +/** + \brief Get cache line size + \return cache line size + */ +__STATIC_INLINE int csi_get_cache_line_size(void) +{ + return 64; +} + + +/** + \ingroup CSI_core_register + \defgroup CSI_CINT Core Local Interrupt (CLINT) + \brief Type definitions for the Core Local Interrupt Registers. + @{ + */ + +/** + \brief The data structure of the access Clint. + */ +typedef struct { + __IOM uint32_t MSIP0; + __IOM uint32_t MSIP1; + __IOM uint32_t MSIP2; + __IOM uint32_t MSIP3; + __IOM uint32_t MSIP4; + __IOM uint32_t MSIP5; + __IOM uint32_t MSIP6; + __IOM uint32_t MSIP7; + uint32_t RESERVED0[(0x4004000 - 0x400001C) / 4 - 1]; + __IOM uint32_t MTIMECMPL0; + __IOM uint32_t MTIMECMPH0; + __IOM uint32_t MTIMECMPL1; + __IOM uint32_t MTIMECMPH1; + __IOM uint32_t MTIMECMPL2; + __IOM uint32_t MTIMECMPH2; + __IOM uint32_t MTIMECMPL3; + __IOM uint32_t MTIMECMPH3; + __IOM uint32_t MTIMECMPL4; + __IOM uint32_t MTIMECMPH4; + __IOM uint32_t MTIMECMPL5; + __IOM uint32_t MTIMECMPH5; + __IOM uint32_t MTIMECMPL6; + __IOM uint32_t MTIMECMPH6; + __IOM uint32_t MTIMECMPL7; + __IOM uint32_t MTIMECMPH7; + uint32_t RESERVED1[(0x400BFF8 - 0x400403C) / 4 - 1]; + __IOM uint32_t MTIMEL; + __IOM uint32_t MTIMEH; + __IOM uint32_t SSIP0; + __IOM uint32_t SSIP1; + __IOM uint32_t SSIP2; + __IOM uint32_t SSIP3; + __IOM uint32_t SSIP4; + __IOM uint32_t SSIP5; + __IOM uint32_t SSIP6; + __IOM uint32_t SSIP7; + uint32_t RESERVED2[(0x400D000 - 0x400C01C) / 4 - 1]; + __IOM uint32_t STIMECMPL0; + __IOM uint32_t STIMECMPH0; + __IOM uint32_t STIMECMPL1; + __IOM uint32_t STIMECMPH1; + __IOM uint32_t STIMECMPL2; + __IOM uint32_t STIMECMPH2; + __IOM uint32_t STIMECMPL3; + __IOM uint32_t STIMECMPH3; + __IOM uint32_t STIMECMPL4; + __IOM uint32_t STIMECMPH4; + __IOM uint32_t STIMECMPL5; + __IOM uint32_t STIMECMPH5; + __IOM uint32_t STIMECMPL6; + __IOM uint32_t STIMECMPH6; + __IOM uint32_t STIMECMPL7; + __IOM uint32_t STIMECMPH7; + uint32_t RESERVED3[(0x400FFF8 - 0x400D03C) / 4 - 1]; + __IOM uint32_t STIMEL; + __IOM uint32_t STIMEH; +} CLINT_Type; + +typedef struct { +#ifdef CONFIG_RISCV_SMODE + __IOM uint32_t STIMECMPL0; + __IOM uint32_t STIMECMPH0; +#else + __IOM uint32_t MTIMECMPL0; + __IOM uint32_t MTIMECMPH0; +#endif +} CLINT_CMP_Type; + +/*@} end of group CSI_SysTick */ + + +/** + \ingroup CSI_core_register + \defgroup CSI_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos) + +/*@} end of group CSI_core_bitfield */ + +/** + \ingroup CSI_core_register + \defgroup CSI_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/*@} */ + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core VIC Functions + - Core CORET Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CSI_Core_FunctionInterface Functions and Instructions Reference +*/ + +/* ########################## VIC functions #################################### */ +/** + \ingroup CSI_Core_FunctionInterface + \defgroup CSI_Core_VICFunctions VIC Functions + \brief Functions that manage interrupts and exceptions via the VIC. + @{ + */ + +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 5UL) ) +#define _IP2_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +#define PLIC_Hn_MSIE_ADDR(msie_base, hartid) ((unsigned long)(msie_base) + 0x100 * (hartid)) +#define PLIC_Hn_MSIE_VAL(msie_base, hartid) (*(__IOM uint32_t *)(PLIC_Hn_MSIE_ADDR(msie_base, hartid))) +#define PLIC_Hn_MSTH_ADDR(msth_base, hartid) ((unsigned long)(msth_base) + 0x2000 * (hartid)) +#define PLIC_Hn_MSTH_VAL(msth_base, hartid) (*(__IOM uint32_t *)(PLIC_Hn_MSTH_ADDR(msth_base, hartid))) +#define PLIC_Hn_MSCLAIM_ADDR(msclaim_base, hartid) ((unsigned long)(msclaim_base) + 0x2000 * (hartid)) +#define PLIC_Hn_MSCLAIM_VAL(msclaim_base, hartid) (*(__IOM uint32_t *)(PLIC_Hn_MSCLAIM_ADDR(msclaim_base, hartid))) + +/** + \brief Enable External Interrupt + \details Enable a device-specific interrupt in the VIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void csi_vic_enable_irq(int32_t IRQn) +{ + int hartid = csi_get_cpu_id(); + PLIC_Type *plic = (PLIC_Type *)CONFIG_PLIC_BASE; + +#if CONFIG_INTC_CLIC_PLIC + if ((uint32_t)IRQn > PLIC_IRQ_OFFSET) { + IRQn -= PLIC_IRQ_OFFSET; + } else { + CLIC->CLICINT[IRQn].IE |= CLIC_INTIE_IE_Msk; + __DSB(); + return; + } +#endif +#if defined(CONFIG_RISCV_SMODE) && CONFIG_RISCV_SMODE + PLIC_Hn_MSIE_VAL(&plic->PLIC_H0_SIE[IRQn/32], hartid) = PLIC_Hn_MSIE_VAL(&plic->PLIC_H0_SIE[IRQn/32], hartid) | (0x1 << (IRQn%32)); +#else + PLIC_Hn_MSIE_VAL(&plic->PLIC_H0_MIE[IRQn/32], hartid) = PLIC_Hn_MSIE_VAL(&plic->PLIC_H0_MIE[IRQn/32], hartid) | (0x1 << (IRQn%32)); +#endif +} + +/** + \brief Enable External Interrupt(deprecated) + \details Enable a device-specific interrupt in the VIC interrupt controller. + \param [in] plic_base PLIC base address + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void csi_plic_enable_irq(unsigned long plic_base, int32_t IRQn) +{ + int hartid = csi_get_cpu_id(); + PLIC_Type *plic = (PLIC_Type *)plic_base; + +#if defined(CONFIG_RISCV_SMODE) && CONFIG_RISCV_SMODE + PLIC_Hn_MSIE_VAL(&plic->PLIC_H0_SIE[IRQn/32], hartid) = PLIC_Hn_MSIE_VAL(&plic->PLIC_H0_SIE[IRQn/32], hartid) | (0x1 << (IRQn%32)); +#else + PLIC_Hn_MSIE_VAL(&plic->PLIC_H0_MIE[IRQn/32], hartid) = PLIC_Hn_MSIE_VAL(&plic->PLIC_H0_MIE[IRQn/32], hartid) | (0x1 << (IRQn%32)); +#endif +} + +/** + \brief Disable External Interrupt + \details Disable a device-specific interrupt in the VIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void csi_vic_disable_irq(int32_t IRQn) +{ + int hartid = csi_get_cpu_id(); + PLIC_Type *plic = (PLIC_Type *)CONFIG_PLIC_BASE; + +#if CONFIG_INTC_CLIC_PLIC + if ((uint32_t)IRQn > PLIC_IRQ_OFFSET) { + IRQn -= PLIC_IRQ_OFFSET; + } else { + CLIC->CLICINT[IRQn].IE &= ~CLIC_INTIE_IE_Msk; + __DSB(); + return; + } +#endif +#if defined(CONFIG_RISCV_SMODE) && CONFIG_RISCV_SMODE + PLIC_Hn_MSIE_VAL(&plic->PLIC_H0_SIE[IRQn/32], hartid) = PLIC_Hn_MSIE_VAL(&plic->PLIC_H0_SIE[IRQn/32], hartid) & (~(0x1 << (IRQn%32))); +#else + PLIC_Hn_MSIE_VAL(&plic->PLIC_H0_MIE[IRQn/32], hartid) = PLIC_Hn_MSIE_VAL(&plic->PLIC_H0_MIE[IRQn/32], hartid) & (~(0x1 << (IRQn%32))); +#endif +} + +/** + \brief Disable External Interrupt(deprecated) + \details Disable a device-specific interrupt in the VIC interrupt controller. + \param [in] plic_base PLIC base address + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void csi_plic_disable_irq(unsigned long plic_base, int32_t IRQn) +{ + int hartid = csi_get_cpu_id(); + PLIC_Type *plic = (PLIC_Type *)plic_base; + +#if defined(CONFIG_RISCV_SMODE) && CONFIG_RISCV_SMODE + PLIC_Hn_MSIE_VAL(&plic->PLIC_H0_SIE[IRQn/32], hartid) = PLIC_Hn_MSIE_VAL(&plic->PLIC_H0_SIE[IRQn/32], hartid) & (~(0x1 << (IRQn%32))); +#else + PLIC_Hn_MSIE_VAL(&plic->PLIC_H0_MIE[IRQn/32], hartid) = PLIC_Hn_MSIE_VAL(&plic->PLIC_H0_MIE[IRQn/32], hartid) & (~(0x1 << (IRQn%32))); +#endif +} + +/** + \brief Check Interrupt is Enabled or not + \details Read the enabled register in the VIC and returns the pending bit for the specified interrupt. + \param [in] IRQn External interrupt number. Value cannot be negative. + \return 0 Interrupt status is not enabled. + \return 1 Interrupt status is enabled. + */ +__STATIC_INLINE uint32_t csi_vic_get_enabled_irq(int32_t IRQn) +{ + int hartid = csi_get_cpu_id(); + PLIC_Type *plic = (PLIC_Type *)CONFIG_PLIC_BASE; + +#if CONFIG_INTC_CLIC_PLIC + if ((uint32_t)IRQn > PLIC_IRQ_OFFSET) { + IRQn -= PLIC_IRQ_OFFSET; + } else { + return (uint32_t)(CLIC->CLICINT[IRQn].IE & CLIC_INTIE_IE_Msk); + } +#endif +#if defined(CONFIG_RISCV_SMODE) && CONFIG_RISCV_SMODE + return (uint32_t)((PLIC_Hn_MSIE_VAL(&plic->PLIC_H0_SIE[IRQn/32], hartid) >> IRQn%32) & 0x1); +#else + return (uint32_t)((PLIC_Hn_MSIE_VAL(&plic->PLIC_H0_MIE[IRQn/32], hartid) >> IRQn%32) & 0x1); +#endif +} + +/** + \brief Check Interrupt is Enabled or not(deprecated) + \details Read the enabled register in the VIC and returns the pending bit for the specified interrupt. + \param [in] IRQn Interrupt number. + \return 0 Interrupt status is not enabled. + \return 1 Interrupt status is enabled. + */ +__STATIC_INLINE uint32_t csi_plic_get_enabled_irq(unsigned long plic_base, int32_t IRQn) +{ + int hartid = csi_get_cpu_id(); + PLIC_Type *plic = (PLIC_Type *)plic_base; + +#if defined(CONFIG_RISCV_SMODE) && CONFIG_RISCV_SMODE + return (uint32_t)((PLIC_Hn_MSIE_VAL(&plic->PLIC_H0_SIE[IRQn/32], hartid) >> IRQn%32) & 0x1); +#else + return (uint32_t)((PLIC_Hn_MSIE_VAL(&plic->PLIC_H0_MIE[IRQn/32], hartid) >> IRQn%32) & 0x1); +#endif +} + +/** + \brief Check Interrupt is Pending or not + \details Read the pending register in the VIC and returns the pending bit for the specified interrupt. + \param [in] IRQn Interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t csi_vic_get_pending_irq(int32_t IRQn) +{ + PLIC_Type *plic = (PLIC_Type *)CONFIG_PLIC_BASE; +#if CONFIG_INTC_CLIC_PLIC + if ((uint32_t)IRQn > PLIC_IRQ_OFFSET) { + IRQn -= PLIC_IRQ_OFFSET; + } else { + return (uint32_t)(CLIC->CLICINT[IRQn].IP & CLIC_INTIP_IP_Msk); + } +#endif + return (uint32_t)((plic->PLIC_IP[IRQn/32] >> IRQn%32) & 0x1); +} + +/** + \brief Set Pending Interrupt + \details Set the pending bit of an external interrupt. + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void csi_vic_set_pending_irq(int32_t IRQn) +{ + PLIC_Type *plic = (PLIC_Type *)CONFIG_PLIC_BASE; +#if CONFIG_INTC_CLIC_PLIC + if ((uint32_t)IRQn > PLIC_IRQ_OFFSET) { + IRQn -= PLIC_IRQ_OFFSET; + } else { + CLIC->CLICINT[IRQn].IP |= CLIC_INTIP_IP_Msk; + __DSB(); + return; + } +#endif + plic->PLIC_IP[IRQn/32] = plic->PLIC_IP[IRQn/32] | (0x1 << (IRQn%32)); + __DSB(); +} + +/** + \brief Clear Pending Interrupt + \details Clear the pending bit of an external interrupt. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void csi_vic_clear_pending_irq(int32_t IRQn) +{ + PLIC_Type *plic = (PLIC_Type *)CONFIG_PLIC_BASE; +#if CONFIG_INTC_CLIC_PLIC + if ((uint32_t)IRQn > PLIC_IRQ_OFFSET) { + IRQn -= PLIC_IRQ_OFFSET; + } else { + CLIC->CLICINT[IRQn].IP &= ~CLIC_INTIP_IP_Msk; + __DSB(); + return; + } +#endif + plic->PLIC_H0_SCLAIM = IRQn; + __DSB(); +} + +/** + \brief Check Interrupt is Pending or not(deprecated) + \details Read the pending register in the VIC and returns the pending bit for the specified interrupt. + \param [in] IRQn Interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t csi_plic_get_pending_irq(unsigned long plic_base, int32_t IRQn) +{ + PLIC_Type *plic = (PLIC_Type *)plic_base; + return (uint32_t)((plic->PLIC_IP[IRQn/32] >> IRQn%32) & 0x1); +} + +/** + \brief Set Pending Interrupt(deprecated) + \details Set the pending bit of an external interrupt. + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void csi_plic_set_pending_irq(unsigned long plic_base, int32_t IRQn) +{ + PLIC_Type *plic = (PLIC_Type *)plic_base; + plic->PLIC_IP[IRQn/32] = plic->PLIC_IP[IRQn/32] | (0x1 << (IRQn%32)); +} + +/** + \brief Clear Pending Interrupt(deprecated) + \details Clear the pending bit of an external interrupt. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void csi_plic_clear_pending_irq(unsigned long plic_base, int32_t IRQn) +{ + PLIC_Type *plic = (PLIC_Type *)plic_base; + plic->PLIC_H0_SCLAIM = IRQn; +} + +/** + \brief Set Interrupt Priority + \details Set the priority of an interrupt. + \note The priority cannot be set for every core interrupt. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void csi_vic_set_prio(int32_t IRQn, uint32_t priority) +{ + PLIC_Type *plic = (PLIC_Type *)CONFIG_PLIC_BASE; +#if CONFIG_INTC_CLIC_PLIC + if ((uint32_t)IRQn > PLIC_IRQ_OFFSET) { + IRQn -= PLIC_IRQ_OFFSET; + } else { + uint8_t nlbits = (CLIC->CLICINFO & CLIC_INFO_CLICINTCTLBITS_Msk) >> CLIC_INFO_CLICINTCTLBITS_Pos; + uint8_t ctl = CLIC->CLICINT[IRQn].CTL; + ctl <<= nlbits; + ctl >>= nlbits; + CLIC->CLICINT[IRQn].CTL = ctl | (priority << (8 - nlbits)); + __DSB(); + return; + } +#endif + plic->PLIC_PRIO[IRQn - 1] = priority; + __DSB(); +} + +/** + \brief Get Interrupt Priority + \details Read the priority of an interrupt. + The interrupt number can be positive to specify an external (device specific) interrupt, + or negative to specify an internal (core) interrupt. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t csi_vic_get_prio(int32_t IRQn) +{ + PLIC_Type *plic = (PLIC_Type *)CONFIG_PLIC_BASE; +#if CONFIG_INTC_CLIC_PLIC + if ((uint32_t)IRQn > PLIC_IRQ_OFFSET) { + IRQn -= PLIC_IRQ_OFFSET; + } else { + uint8_t nlbits = (CLIC->CLICINFO & CLIC_INFO_CLICINTCTLBITS_Msk) >> CLIC_INFO_CLICINTCTLBITS_Pos; + return CLIC->CLICINT[IRQn].CTL >> (8 - nlbits); + } +#endif + uint32_t prio = plic->PLIC_PRIO[IRQn - 1]; + return prio; +} + +/** + \brief Set Interrupt Priority(deprecated) + \details Set the priority of an interrupt. + \note The priority cannot be set for every core interrupt. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void csi_plic_set_prio(unsigned long plic_base, int32_t IRQn, uint32_t priority) +{ + PLIC_Type *plic = (PLIC_Type *)plic_base; + plic->PLIC_PRIO[IRQn - 1] = priority; +} + +/** + \brief Get Interrupt Priority(deprecated) + \details Read the priority of an interrupt. + The interrupt number can be positive to specify an external (device specific) interrupt, + or negative to specify an internal (core) interrupt. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t csi_plic_get_prio(unsigned long plic_base, int32_t IRQn) +{ + PLIC_Type *plic = (PLIC_Type *)plic_base; + uint32_t prio = plic->PLIC_PRIO[IRQn - 1]; + return prio; +} + +/*@} end of CSI_Core_VICFunctions */ + +/* ########################## PMP functions #################################### */ +/** + \ingroup CSI_Core_FunctionInterface + \defgroup CSI_Core_PMPFunctions PMP Functions + \brief Functions that manage interrupts and exceptions via the VIC. + @{ + */ + +/** + \brief configure physical memory protection region. + \details + \param [in] idx memory protection region (0, 1, 2, ..., 15). + \param [in] base_addr base address must be aligned with page size. + \param [in] size \ref region_size_e. memory protection region size. + \param [in] attr \ref pmp_region_attr_t. memory protection region attribute. + \param [in] enable enable or disable memory protection region. + */ +__STATIC_INLINE void csi_pmp_config_region(uint32_t idx, unsigned long base_addr, region_size_e size, + pmp_region_attr_t attr, uint32_t enable) +{ + uint8_t pmpxcfg = 0; + uint32_t addr = 0; + + if (idx > 15) { + return; + } + + if (!enable) { + attr.a = (address_matching_e)0; + } + + if (attr.a == ADDRESS_MATCHING_TOR) { + addr = base_addr >> 2; + } else { + if (size == REGION_SIZE_4B) { + addr = base_addr >> 2; + attr.a = (address_matching_e)2; + } else { + addr = ((base_addr >> 2) & (0xFFFFFFFFFFFFFFFFUL - ((1 << (size + 1)) - 1))) | ((1 << size) - 1); + } + } + + __set_PMPADDRx(idx, addr); + + pmpxcfg |= (attr.r << PMP_PMPCFG_R_Pos) | (attr.w << PMP_PMPCFG_W_Pos) | + (attr.x << PMP_PMPCFG_X_Pos) | (attr.a << PMP_PMPCFG_A_Pos) | + (attr.l << PMP_PMPCFG_L_Pos); + + __set_PMPxCFG(idx, pmpxcfg); +} + +/** + \brief disable physical memory protection region by idx. + \details + \param [in] idx memory protection region (0, 1, 2, ..., 15). + */ +__STATIC_INLINE void csi_pmp_disable_region(uint32_t idx) +{ + __set_PMPxCFG(idx, __get_PMPxCFG(idx) & (~PMP_PMPCFG_A_Msk)); +} + +/*@} end of CSI_Core_PMPFunctions */ + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CSI_Core_FunctionInterface + \defgroup CSI_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#define CLINT_TIMECMPn_ADDR(time_cmp_base, hartid) ((unsigned long)(time_cmp_base) + 8 * (hartid)) +#define CLINT_TIMECMPn_VAL(time_cmp_base, hartid) (*(__IOM uint32_t *)(CLINT_TIMECMPn_ADDR(time_cmp_base, hartid))) + +__STATIC_INLINE uint32_t _csi_clint_config2(unsigned long coret_base, uint16_t hartid, uint64_t ticks, int32_t IRQn) +{ + CLINT_Type *clint = (CLINT_Type *)coret_base; +#if defined(CONFIG_RISCV_SMODE) && CONFIG_RISCV_SMODE + uint64_t value = (((uint64_t)(CLINT_TIMECMPn_VAL(&clint->STIMECMPH0, hartid))) << 32) + \ + (uint64_t)(CLINT_TIMECMPn_VAL(&clint->STIMECMPL0, hartid)); + + if ((value != 0) && (value != 0xffffffffffffffff)) { + value = value + (uint64_t)ticks; + } else { + value = __get_MTIME() + ticks; + } + CLINT_TIMECMPn_VAL(&clint->STIMECMPH0, hartid) = (uint32_t)(value >> 32); + CLINT_TIMECMPn_VAL(&clint->STIMECMPL0, hartid) = (uint32_t)value; +#else + uint64_t value = (((uint64_t)(CLINT_TIMECMPn_VAL(&clint->MTIMECMPH0, hartid))) << 32) + \ + (uint64_t)(CLINT_TIMECMPn_VAL(&clint->MTIMECMPL0, hartid)); + + if ((value != 0) && (value != 0xffffffffffffffff)) { + value = value + (uint64_t)ticks; + } else { + value = __get_MTIME() + ticks; + } + CLINT_TIMECMPn_VAL(&clint->MTIMECMPH0, hartid) = (uint32_t)(value >> 32); + CLINT_TIMECMPn_VAL(&clint->MTIMECMPL0, hartid) = (uint32_t)value; +#endif + + return (0UL); +} + +__STATIC_INLINE uint32_t csi_clint_config(unsigned long coret_base, uint32_t ticks, int32_t IRQn) +{ + return _csi_clint_config2(coret_base, 0, ticks, IRQn); +} + +__STATIC_INLINE void csi_coret_reset_value2() +{ + uint32_t value = 0x0; + int hartid = csi_get_cpu_id(); + CLINT_Type *clint = (CLINT_Type *)CORET_BASE; + +#if defined(CONFIG_RISCV_SMODE) && CONFIG_RISCV_SMODE + CLINT_TIMECMPn_VAL(&clint->STIMECMPH0, hartid) = (uint32_t)value; + CLINT_TIMECMPn_VAL(&clint->STIMECMPL0, hartid) = (uint32_t)value; +#else + CLINT_TIMECMPn_VAL(&clint->MTIMECMPH0, hartid) = (uint32_t)value; + CLINT_TIMECMPn_VAL(&clint->MTIMECMPL0, hartid) = (uint32_t)value; +#endif +} + +__STATIC_INLINE void csi_coret_reset_value(unsigned long coret_base) +{ + uint32_t value = 0x0; + int hartid = csi_get_cpu_id(); + CLINT_Type *clint = (CLINT_Type *)coret_base; + +#if defined(CONFIG_RISCV_SMODE) && CONFIG_RISCV_SMODE + CLINT_TIMECMPn_VAL(&clint->STIMECMPH0, hartid) = (uint32_t)value; + CLINT_TIMECMPn_VAL(&clint->STIMECMPL0, hartid) = (uint32_t)value; +#else + CLINT_TIMECMPn_VAL(&clint->MTIMECMPH0, hartid) = (uint32_t)value; + CLINT_TIMECMPn_VAL(&clint->MTIMECMPL0, hartid) = (uint32_t)value; +#endif +} + +__STATIC_INLINE uint64_t _csi_clint_get_load2(unsigned long coret_base, uint16_t hartid) +{ + CLINT_Type *clint = (CLINT_Type *)coret_base; +#if defined(CONFIG_RISCV_SMODE) && CONFIG_RISCV_SMODE + uint64_t value = (((uint64_t)CLINT_TIMECMPn_VAL(&clint->STIMECMPH0, hartid)) << 32) + \ + (uint64_t)CLINT_TIMECMPn_VAL(&clint->STIMECMPL0, hartid); +#else + uint64_t value = (((uint64_t)CLINT_TIMECMPn_VAL(&clint->MTIMECMPH0, hartid)) << 32) + \ + (uint64_t)CLINT_TIMECMPn_VAL(&clint->MTIMECMPL0, hartid); +#endif + + return value; +} + +/** + \brief get CORE timer reload high value(deprecated) + \return CORE timer counter value. + */ +__STATIC_INLINE uint64_t csi_clint_get_load(unsigned long coret_base) +{ + return _csi_clint_get_load2(coret_base, 0); +} + +__STATIC_INLINE uint32_t _csi_clint_get_loadh2(unsigned long coret_base, uint16_t hartid) +{ + CLINT_Type *clint = (CLINT_Type *)coret_base; +#if defined(CONFIG_RISCV_SMODE) && CONFIG_RISCV_SMODE + uint64_t value = (((uint64_t)CLINT_TIMECMPn_VAL(&clint->STIMECMPH0, hartid)) << 32) + \ + (uint64_t)CLINT_TIMECMPn_VAL(&clint->STIMECMPL0, hartid); +#else + uint64_t value = (((uint64_t)CLINT_TIMECMPn_VAL(&clint->MTIMECMPH0, hartid)) << 32) + \ + (uint64_t)CLINT_TIMECMPn_VAL(&clint->MTIMECMPL0, hartid); +#endif + + return (value >> 32) & 0xFFFFFFFF; +} + +/** + \brief get CORE timer reload high value(deprecated) + \return CORE timer counter value. + */ +__STATIC_INLINE uint32_t csi_clint_get_loadh(unsigned long coret_base) +{ + return _csi_clint_get_loadh2(coret_base, 0); +} + +/** + \brief get CORE timer counter value(deprecated) + \return CORE timer counter value. + */ +__STATIC_INLINE unsigned long csi_clint_get_value(void) +{ + unsigned long result; + __ASM volatile("csrr %0, time" : "=r"(result)); + return result; +} + +/** + \brief get CORE timer counter high value(deprecated) + \return CORE timer counter value. + */ +__STATIC_INLINE uint32_t csi_clint_get_valueh(void) +{ + uint64_t result; + __ASM volatile("csrr %0, time" : "=r"(result)); + return (result >> 32) & 0xFFFFFFFF; +} + +/** + \brief CORE timer Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \param [in] IRQn core timer Interrupt number. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t csi_coret_config(uint64_t ticks, int32_t IRQn) +{ + return _csi_clint_config2(CORET_BASE, csi_get_cpu_id(), ticks, IRQn); +} + +/** + \brief get CORE timer reload value + \return CORE timer counter value. + */ +__STATIC_INLINE uint64_t csi_coret_get_load2(void) +{ + return _csi_clint_get_load2(CORET_BASE, csi_get_cpu_id()); +} + +/** + \brief get CORE timer counter value + \return CORE timer counter value. + */ +__STATIC_INLINE uint64_t csi_coret_get_value2() +{ +#if __riscv_xlen == 64 + return csi_clint_get_value(); +#else + uint64_t result; + unsigned long high, low; + + __ASM volatile("csrr %0, timeh" : "=r"(high)); + __ASM volatile("csrr %0, time" : "=r"(low)); + result = ((uint64_t)high << 32) | low; + + return result; +#endif +} + +/** + \brief Enable CoreTimer(within clint) Interrupts + */ +__ALWAYS_STATIC_INLINE void csi_coret_irq_enable(void) +{ +#if CONFIG_INTC_CLIC_PLIC + extern void soc_irq_enable(uint32_t irq_num); + return soc_irq_enable(7); +#else + return __enable_coret_irq(); +#endif +} + +/** + \brief Disable CoreTimer(within clint) Interrupts + */ +__ALWAYS_STATIC_INLINE void csi_coret_irq_disable(void) +{ +#if CONFIG_INTC_CLIC_PLIC + extern void soc_irq_disable(uint32_t irq_num); + return soc_irq_disable(7); +#else + return __disable_coret_irq(); +#endif +} + + +/*@} end of CSI_core_DebugFunctions */ + +/* ########################## Cache functions #################################### */ +/** + \ingroup CSI_Core_FunctionInterface + \defgroup CSI_Core_CacheFunctions Cache Functions + \brief Functions that configure Instruction and Data cache. + @{ + */ + +/** + \brief whether I-Cache enable + */ +__STATIC_INLINE int csi_icache_is_enable() +{ + uint32_t cache = __get_MHCR(); + return (cache & CACHE_MHCR_IE_Msk) >> CACHE_MHCR_IE_Pos; +} + +/** + \brief Enable I-Cache + \details Turns on I-Cache + */ +__STATIC_INLINE void csi_icache_enable(void) +{ +#if (__ICACHE_PRESENT == 1U) + if (!csi_icache_is_enable()) { + uint32_t cache; + __DSB(); + __ICACHE_IALL(); + cache = __get_MHCR(); + cache |= CACHE_MHCR_IE_Msk; + __set_MHCR(cache); + __DSB(); + } +#endif +} + + +/** + \brief Disable I-Cache + \details Turns off I-Cache + */ +__STATIC_INLINE void csi_icache_disable(void) +{ +#if (__ICACHE_PRESENT == 1U) + if (csi_icache_is_enable()) { + uint32_t cache; + __DSB(); + cache = __get_MHCR(); + cache &= ~CACHE_MHCR_IE_Msk; /* disable icache */ + __set_MHCR(cache); + __ICACHE_IALL(); /* invalidate all icache */ + __DSB(); + } +#endif +} + + +/** + \brief Invalidate I-Cache + \details Invalidates I-Cache + */ +__STATIC_INLINE void csi_icache_invalid(void) +{ +#if (__ICACHE_PRESENT == 1U) + __DSB(); + __ICACHE_IALL(); /* invalidate all icache */ + __DSB(); +#endif +} + +/** + \brief whether D-Cache enable + */ +__STATIC_INLINE int csi_dcache_is_enable() +{ + uint32_t cache = __get_MHCR(); + return (cache & CACHE_MHCR_DE_Msk) >> CACHE_MHCR_DE_Pos; +} + +/** + \brief Enable D-Cache + \details Turns on D-Cache + */ +__STATIC_INLINE void csi_dcache_enable(void) +{ +#if (__DCACHE_PRESENT == 1U) + if (!csi_dcache_is_enable()) { + uint32_t cache; + __DSB(); + __DCACHE_IALL(); /* invalidate all dcache */ + cache = __get_MHCR(); + cache |= CACHE_MHCR_DE_Msk; /* enable dcache */ + __set_MHCR(cache); + + __DSB(); + } +#endif +} + + +/** + \brief Disable D-Cache + \details Turns off D-Cache + */ +__STATIC_INLINE void csi_dcache_disable(void) +{ +#if (__DCACHE_PRESENT == 1U) + if (csi_dcache_is_enable()) { + uint32_t cache; + __DSB(); + cache = __get_MHCR(); + cache &= ~(uint32_t)CACHE_MHCR_DE_Msk; /* disable all Cache */ + __set_MHCR(cache); + __DCACHE_IALL(); /* invalidate all Cache */ + __DSB(); + } +#endif +} + +/** + \brief Invalidate D-Cache + \details Invalidates D-Cache + */ +__STATIC_INLINE void csi_dcache_invalid(void) +{ +#if (__DCACHE_PRESENT == 1U) + __DSB(); + __DCACHE_IALL(); /* invalidate all Cache */ + __DSB(); +#endif +} + + +/** + \brief Clean D-Cache + \details Cleans D-Cache + */ +__STATIC_INLINE void csi_dcache_clean(void) +{ +#if (__DCACHE_PRESENT == 1U) + __DSB(); + __DCACHE_CALL(); /* clean all Cache */ + __DSB(); +#endif +} + + +/** + \brief Clean & Invalidate D-Cache + \details Cleans and Invalidates D-Cache + */ +__STATIC_INLINE void csi_dcache_clean_invalid(void) +{ +#if (__DCACHE_PRESENT == 1U) + __DSB(); + __DCACHE_CIALL(); /* clean and inv all Cache */ + __DSB(); +#endif +} + +/** + \brief D-Cache Invalidate by address + \details Invalidates D-Cache for the given address + \param[in] addr address (aligned to 64-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_INLINE void csi_dcache_invalid_range(unsigned long *addr, size_t dsize) +{ +#if (__DCACHE_PRESENT == 1U) + int linesize = csi_get_cache_line_size(); + long op_size = dsize + (unsigned long)addr % linesize; + unsigned long op_addr = (unsigned long)addr & CACHE_INV_ADDR_Msk; + + __DSB(); +#if CBO_INSN_SUPPORT + while (op_size > 0) { + __CBO_INVAL(op_addr); + op_addr += linesize; + op_size -= linesize; + } +#else + cpu_work_mode_t cpu_work_mode; + cpu_work_mode = (cpu_work_mode_t)__get_CPU_WORK_MODE(); + + if (cpu_work_mode == MACHINE_MODE) { + while (op_size > 0) { + __DCACHE_IPA(op_addr); + op_addr += linesize; + op_size -= linesize; + } + } else if (cpu_work_mode == SUPERVISOR_MODE) { + while (op_size > 0) { + __DCACHE_IVA(op_addr); + op_addr += linesize; + op_size -= linesize; + } + } +#endif + + __SYNC_IS(); + __DSB(); +#endif +} + + +/** + \brief D-Cache Clean by address + \details Cleans D-Cache for the given address + \param[in] addr address (aligned to 64-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_INLINE void csi_dcache_clean_range(unsigned long *addr, size_t dsize) +{ + +#if (__DCACHE_PRESENT == 1) + int linesize = csi_get_cache_line_size(); + long op_size = dsize + (unsigned long)addr % linesize; + unsigned long op_addr = (unsigned long) addr & CACHE_INV_ADDR_Msk; + + __DSB(); +#if CBO_INSN_SUPPORT + while (op_size > 0) { + __CBO_CLEAN(op_addr); + op_addr += linesize; + op_size -= linesize; + } +#else + cpu_work_mode_t cpu_work_mode; + cpu_work_mode = (cpu_work_mode_t)__get_CPU_WORK_MODE(); + + if (cpu_work_mode == MACHINE_MODE) { + while (op_size > 0) { + __DCACHE_CPA(op_addr); + op_addr += linesize; + op_size -= linesize; + } + } else if (cpu_work_mode == SUPERVISOR_MODE) { + while (op_size > 0) { + __DCACHE_CVA(op_addr); + op_addr += linesize; + op_size -= linesize; + } + } +#endif + __SYNC_IS(); + __DSB(); +#endif + +} + + +/** + \brief D-Cache Clean and Invalidate by address + \details Cleans and invalidates D_Cache for the given address + \param[in] addr address (aligned to 64-byte boundary) + \param[in] dsize size of memory block (aligned to 64-byte boundary) +*/ +__STATIC_INLINE void csi_dcache_clean_invalid_range(unsigned long *addr, size_t dsize) +{ +#if (__DCACHE_PRESENT == 1U) + int linesize = csi_get_cache_line_size(); + long op_size = dsize + (unsigned long)addr % linesize; + unsigned long op_addr = (unsigned long) addr & CACHE_INV_ADDR_Msk; + + __DSB(); +#if CBO_INSN_SUPPORT + while (op_size > 0) { + __CBO_FLUSH(op_addr); + op_addr += linesize; + op_size -= linesize; + } +#else + cpu_work_mode_t cpu_work_mode; + cpu_work_mode = (cpu_work_mode_t)__get_CPU_WORK_MODE(); + + if (cpu_work_mode == MACHINE_MODE) { + while (op_size > 0) { + __DCACHE_CIPA(op_addr); + op_addr += linesize; + op_size -= linesize; + } + } else if (cpu_work_mode == SUPERVISOR_MODE) { + while (op_size > 0) { + __DCACHE_CIVA(op_addr); + op_addr += linesize; + op_size -= linesize; + } + } +#endif + + __SYNC_IS(); + __DSB(); +#endif +} + +/*@} end of CSI_Core_CacheFunctions */ + +/* ########################## FPP functions #################################### */ +/** + \ingroup CSI_Core_FPPFunctionInterface + \defgroup CSI_Core_FPPFunctions FPP Functions + \brief Functions that configure FPP. + @{ + */ + +/** + \ingroup CSI_fpp_register + \defgroup CSI_FPP + \brief Type definitions for the FPP Registers + @{ + */ + +/** + \brief Consortium definition for Machine Mode FPP Configuration register(MFPPCR, 0xBC0). + */ +typedef union { + struct { + uint64_t EN: 1; /*!< bit: 0 FPP enable */ + uint64_t _reversed1: 11; /*!< bit: 1 11 Reserved */ + uint64_t Base_Address: 52; /*!< bit: 12 63 Base Address */ + } b; /*!< Structure Access by bit */ + uint64_t w; /*!< Type Access by whole register */ +} MFPPCR_Type; + +#define MFPPCR_Base_Address_Pos 12U /*!< MFPPCR: Base_Address Position */ +#define MFPPCR_Base_Address_Msk (0xFFFFFFFFFFFFFULL << MFPPCR_Base_Address_Pos) /*!< MFPPCR: Base_Address Mask */ + +#define MFPPCR_Base_EN_Pos 0U /*!< MFPPCR: Enable Bit Position */ +#define MFPPCR_Base_EN_Msk (0x1U << MFPPCR_Base_EN_Pos) /*!< MFPPCR: Enable Bit Mask */ + +/*@} end of group CSI_FPP_bitfield */ + +/** + \brief Enable FPP + \details Turns on FPP + */ +__STATIC_INLINE void csi_fpp_enable(void) +{ + __set_MFPPCR(__get_MFPPCR() | MFPPCR_Base_EN_Msk); +} + +/** + \brief Disable FPP + \details Turns off FPP + */ +__STATIC_INLINE void csi_fpp_disable(void) +{ + __set_MFPPCR(__get_MFPPCR() & (~MFPPCR_Base_EN_Msk)); +} + +/** + \brief Set FPP Base Address + \details Set FPP Base Address + \param [in] base_addr FPP Base Address. + */ +__STATIC_INLINE void csi_fpp_set_base_addr(unsigned long base_addr) +{ + __set_MFPPCR((__get_MFPPCR() & (~MFPPCR_Base_Address_Msk)) + | ((base_addr << MFPPCR_Base_Address_Pos) & MFPPCR_Base_Address_Msk)); +} + +/*@} end of CSI_Core_FPPFunctions */ + + +/* ########################## MMU functions #################################### */ +/** + \ingroup CSI_Core_FunctionInterface + \defgroup CSI_Core_MMUFunctions MMU Functions + \brief Functions that configure MMU. + @{ + */ + +typedef enum { + PAGE_SIZE_4KB = 0x1000, + PAGE_SIZE_2MB = 0x200000, + PAGE_SIZE_1GB = 0x40000000, +} page_size_e; + +#define MMU_MODE_32 (0x1) +#define MMU_MODE_39 (0x8) +#define MMU_MODE_48 (0x9) +#define MMU_MODE_57 (0xa) +#define MMU_MODE_64 (0xb) + +/** + \brief set mmu mode(If there are multiple mmu modes) + \param[in] mode mode of the mmu + \details + */ +__STATIC_INLINE void csi_mmu_set_mode(int mode) +{ + extern int g_mmu_mode; + g_mmu_mode = mode; +} + +/** + \brief enable mmu + \details + */ +__STATIC_INLINE void csi_mmu_enable() +{ + extern int g_mmu_mode; +#if __riscv_xlen == 64 + __set_SATP(__get_SATP() | ((unsigned long)g_mmu_mode << 60)); +#else + __set_SATP(__get_SATP() | ((unsigned long)g_mmu_mode << 31)); +#endif +} + +/** + \brief disable mmu + \details + */ +__STATIC_INLINE void csi_mmu_disable(void) +{ +#if __riscv_xlen == 64 + __set_SATP(__get_SATP() & (~((unsigned long)0xf << 60))); +#else + __set_SATP(__get_SATP() & (~((unsigned long)0x1 << 31))); +#endif +} + +/** + \brief flush all mmu tlb. + \details + */ +__STATIC_INLINE void csi_mmu_invalid_tlb_all(void) +{ + __ASM volatile("sfence.vma" : : : "memory"); +} + +/*@} end of CSI_Core_MMUFunctions */ + +/* ########################## TCM functions #################################### */ +/** + \ingroup CSI_Core_FunctionInterface + \defgroup CSI_Core_TCMFunctions TCM Functions + \brief Functions that configure TCM. + @{ + */ + +#if CONFIG_CPU_XUANTIE_C907 || CONFIG_CPU_XUANTIE_C907FD || CONFIG_CPU_XUANTIE_C907FDV || CONFIG_CPU_XUANTIE_C907FDVM \ + || CONFIG_CPU_XUANTIE_C908 || CONFIG_CPU_XUANTIE_C908V || CONFIG_CPU_XUANTIE_C908I \ + || CONFIG_CPU_XUANTIE_C908X || CONFIG_CPU_XUANTIE_C908X_CP || CONFIG_CPU_XUANTIE_C908X_CP_XT \ + || CONFIG_CPU_XUANTIE_C910 || CONFIG_CPU_XUANTIE_C920 \ + || CONFIG_CPU_XUANTIE_C910V2 || CONFIG_CPU_XUANTIE_C920V2 \ + || CONFIG_CPU_XUANTIE_C910V3 || CONFIG_CPU_XUANTIE_C920V3 \ + || CONFIG_CPU_XUANTIE_C910V3_CP || CONFIG_CPU_XUANTIE_C920V3_CP \ + || CONFIG_CPU_XUANTIE_C910V3_CP_XT || CONFIG_CPU_XUANTIE_C920V3_CP_XT \ + || CONFIG_CPU_XUANTIE_R908 || CONFIG_CPU_XUANTIE_R908FD || CONFIG_CPU_XUANTIE_R908FDV \ + || CONFIG_CPU_XUANTIE_R908_CP || CONFIG_CPU_XUANTIE_R908FD_CP || CONFIG_CPU_XUANTIE_R908FDV_CP \ + || CONFIG_CPU_XUANTIE_R908_CP_XT || CONFIG_CPU_XUANTIE_R908FD_CP_XT || CONFIG_CPU_XUANTIE_R908FDV_CP_XT \ + || CONFIG_CPU_XUANTIE_R910 || CONFIG_CPU_XUANTIE_R920 +/** + \ingroup CSI_tcm_register + \defgroup CSI_TCM + \brief Type definitions for the tcm Registers + @{ + */ + +/** + \brief Consortium definition for accessing protection area selection register(MITCMCR, 0x7f9). + */ +typedef union { + struct { + unsigned long EN: 1; /*!< bit: 0 Instruction Tightly-Coupled Memory enable */ + unsigned long ECC_EN: 1; /*!< bit: 1 ecc_en */ + unsigned long Interleave: 1; /*!< bit: 2 Interleave */ + unsigned long _reserved1: 1; /*!< bit: 3 Reserved */ + unsigned long Size: 4; /*!< bit: 4..7 Size of ITCM */ + unsigned long _reserved2: 4; /*!< bit: 8..11 Reserved */ + unsigned long Base_Address: 52; /*!< bit: 12..63 Base address of DTCM */ + } b; /*!< Structure Access by bit */ + unsigned long w; /*!< Type Access by whole register */ +} MITCMCR_Type; + +#define MITCMCR_Base_Address_Pos 12U /*!< MITCMCR: Base_Address Position */ +#define MITCMCR_Base_Address_Msk (0xfffffffffffffULL << MITCMCR_Base_Address_Pos) /*!< MITCMCR: Base_Address Mask */ + +#define MITCMCR_Size_Pos 4U /*!< MITCMCR: Size Position */ +#define MITCMCR_Size_Msk (0xfULL << MITCMCR_Size_Pos) /*!< MITCMCR: Size Mask */ + +#define MITCMCR_INTERLEAVE_Pos 2U /*!< MITCMCR: Interleave Position */ +#define MITCMCR_INTERLEAVE_Msk (0x1ULL << MITCMCR_INTERLEAVE_Pos) /*!< MITCMCR: Interleave Mask */ + +#define MITCMCR_ECC_EN_Pos 1U /*!< MITCMCR: ECC_EN Position */ +#define MITCMCR_ECC_EN_Msk (0x1ULL << MITCMCR_ECC_EN_Pos) /*!< MITCMCR: ECC_EN Mask */ + +#define MITCMCR_EN_Pos 0U /*!< MITCMCR: EN Position */ +#define MITCMCR_EN_Msk (0x1ULL << MITCMCR_EN_Pos) /*!< MITCMCR: EN Mask */ + +/** + \brief Consortium definition for accessing protection area selection register(MDTCMCR, 0x7f8). + */ +typedef union { + struct { + unsigned long EN: 1; /*!< bit: 0 Data Tightly-Coupled Memory enable */ + unsigned long ECC_EN: 1; /*!< bit: 1 ecc_en */ + unsigned long Interleave: 1; /*!< bit: 2 Interleave */ + unsigned long _reserved1: 1; /*!< bit: 3 Reserved */ + unsigned long Size: 4; /*!< bit: 4..7 Size of ITCM */ + unsigned long _reserved2: 4; /*!< bit: 8..11 Reserved */ + unsigned long Base_Address: 52; /*!< bit: 12..63 Base address of DTCM */ + } b; /*!< Structure Access by bit */ + unsigned long w; /*!< Type Access by whole register */ +} MDTCMCR_Type; + +#define MDTCMCR_Base_Address_Pos 12U /*!< MDTCMCR: Base_Address Position */ +#define MDTCMCR_Base_Address_Msk (0xfffffffffffffULL << MDTCMCR_Base_Address_Pos) /*!< MDTCMCR: Base_Address Mask */ + +#define MDTCMCR_Size_Pos 4U /*!< MDTCMCR: Size Position */ +#define MDTCMCR_Size_Msk (0xfULL << MDTCMCR_Size_Pos) /*!< MDTCMCR: Size Mask */ + +#define MDTCMCR_INTERLEAVE_Pos 2U /*!< MDTCMCR: Interleave Position */ +#define MDTCMCR_INTERLEAVE_Msk (0x1ULL << MDTCMCR_INTERLEAVE_Pos) /*!< MDTCMCR: Interleave Mask */ + +#define MDTCMCR_ECC_EN_Pos 1U /*!< MDTCMCR: ECC_EN Position */ +#define MDTCMCR_ECC_EN_Msk (0x1ULL << MDTCMCR_ECC_EN_Pos) /*!< MDTCMCR: ECC_EN Mask */ + +#define MDTCMCR_EN_Pos 0U /*!< MDTCMCR: EN Position */ +#define MDTCMCR_EN_Msk (0x1ULL << MDTCMCR_EN_Pos) /*!< MDTCMCR: EN Mask */ + +/*@} end of group CSI_TCM_bitfield */ + +/** + \brief Enable ITCM + \details Turns on ITCM + */ +__STATIC_INLINE void csi_itcm_enable (void) +{ + __set_MITCMCR(__get_MITCMCR() | MITCMCR_EN_Msk); +} + +/** + \brief Enable DTCM + \details Turns on DTCM + */ +__STATIC_INLINE void csi_dtcm_enable (void) +{ + __set_MDTCMCR(__get_MDTCMCR() | MDTCMCR_EN_Msk); +} + +/** + \brief Enable ITCM + \details Turns on ITCM + */ +__STATIC_INLINE void csi_itcm_disable (void) +{ + __set_MITCMCR(__get_MITCMCR() & (~MITCMCR_EN_Msk)); +} + +/** + \brief Enable DTCM + \details Turns on DTCM + */ +__STATIC_INLINE void csi_dtcm_disable (void) +{ + __set_MDTCMCR(__get_MDTCMCR() & (~MDTCMCR_EN_Msk)); +} + +/** + \brief Get ITCM Size + \details Get ITCM Size + \return ITCM size (bytes). + */ +__STATIC_INLINE uint32_t csi_itcm_get_size(void) +{ + MITCMCR_Type sizemask; + uint32_t ret; + + sizemask.w = __get_MITCMCR(); + switch (sizemask.b.Size) + { + case 0x3: ret = 8 << 10; break; + case 0x4: ret = 16 << 10; break; + case 0x5: ret = 32 << 10; break; + case 0x6: ret = 64 << 10; break; + case 0x7: ret = 128 << 10; break; + case 0x8: ret = 256 << 10; break; + case 0x9: ret = 512 << 10; break; + case 0xa: ret = 1024 << 10; break; + default: ret = 0; break; + } + return ret; +} + +/** + \brief Get DTCM Size + \details Get DTCM Size + \return DTCM size (bytes). + */ +__STATIC_INLINE uint32_t csi_dtcm_get_size(void) +{ + MDTCMCR_Type sizemask; + uint32_t ret; + + sizemask.w = __get_MDTCMCR(); + switch (sizemask.b.Size) + { + case 0x3: ret = 8 << 10; break; + case 0x4: ret = 16 << 10; break; + case 0x5: ret = 32 << 10; break; + case 0x6: ret = 64 << 10; break; + case 0x8: ret = 128 << 10; break; + case 0x9: ret = 256 << 10; break; + case 0xa: ret = 512 << 10; break; + case 0xb: ret = 1024 << 10; break; + default:ret = 0; break; + } + return ret; +} + +/** + \brief Set ITCM Base Address + \details Set ITCM Base Address + \param [in] base_addr itcm base address. + */ +__STATIC_INLINE void csi_itcm_set_base_addr(unsigned long base_addr) +{ + __set_MITCMCR((__get_MITCMCR() & (~MITCMCR_Base_Address_Msk)) | (base_addr << MITCMCR_Base_Address_Pos)); +} + +/** + \brief Set DTCM Base Address + \details Set DTCM Base Address + \param [in] base_addr dtcm base address. + */ +__STATIC_INLINE void csi_dtcm_set_base_addr(unsigned long base_addr) +{ + __set_MDTCMCR((__get_MDTCMCR() & (~MDTCMCR_Base_Address_Msk)) | (base_addr << MDTCMCR_Base_Address_Pos)); +} + +/*@} end of CSI_Core_TCMFunctions */ + +/* ########################## ECC functions #################################### */ + +/** + * \brief Enable ITCM-ECC + * \details Turns on ITCM-ECC + * */ +__STATIC_INLINE void csi_itcm_ecc_enable (void) +{ + __set_MITCMCR(__get_MITCMCR() | MITCMCR_ECC_EN_Msk); +} + +/** + * \brief Disable ITCM-ECC + * \details Turns off ITCM-ECC + * */ +__STATIC_INLINE void csi_itcm_ecc_disable (void) +{ + __set_MITCMCR(__get_MITCMCR() & (~MITCMCR_ECC_EN_Msk)); +} + +/** + * \brief Enable DTCM-ECC + * \details Turns on DTCM-ECC + * */ +__STATIC_INLINE void csi_dtcm_ecc_enable (void) +{ + __set_MDTCMCR(__get_MDTCMCR() | MDTCMCR_ECC_EN_Msk); +} + +/** + * \brief Disable DTCM-ECC + * \details Turns off DTCM-ECC + * */ +__STATIC_INLINE void csi_dtcm_ecc_disable (void) +{ + __set_MDTCMCR(__get_MDTCMCR() & (~MDTCMCR_ECC_EN_Msk)); +} + +/*@} end of CSI_Core_ECCFunctions */ +#endif /* end ecc */ + +/* ################################## IRQ Functions ############################################ */ + +/** + \brief Save the Irq context + \details save the psr result before disable irq. + */ +__STATIC_INLINE unsigned long csi_irq_save(void) +{ + unsigned long result; +#if defined(CONFIG_RISCV_SMODE) && CONFIG_RISCV_SMODE + result = __get_SSTATUS(); +#else + result = __get_MSTATUS(); +#endif + __disable_irq(); + return(result); +} + +/** + \brief Restore the Irq context + \details restore saved primask state. + \param [in] irq_state psr irq state. + */ +__STATIC_INLINE void csi_irq_restore(unsigned long irq_state) +{ +#if defined(CONFIG_RISCV_SMODE) && CONFIG_RISCV_SMODE + __set_SSTATUS(irq_state); +#else + __set_MSTATUS(irq_state); +#endif +} + +/*@} end of IRQ Functions */ + +/** + \brief Get the byte-width of vector register + \return the byte-width of vector register + */ +__STATIC_INLINE int csi_vlenb_get_value(void) +{ + int result; + __ASM volatile("csrr %0, vlenb" : "=r"(result) : : "memory"); + return result; +} + +#if __riscv_matrix || __riscv_xtheadmatrix +/** + \brief Get the bytes of matrix per register + \return the bytes of matrix per register + */ +__STATIC_INLINE int csi_xmlenb_get_value(void) +{ + int result; + __ASM volatile("csrr %0, xmlenb" : "=r"(result) : : "memory"); + return result; +} +#endif /* __riscv_matrix || __riscv_xtheadmatrix */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_RV32_H_DEPENDANT */ + +#endif /* __CSI_GENERIC */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/core/csi_gcc.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/core/csi_gcc.h new file mode 100644 index 00000000..75b42742 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/core/csi_gcc.h @@ -0,0 +1,3293 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 csi_gcc.h + * @brief CSI Header File for GCC. + * @version V1.0 + * @date 02. June 2020 + ******************************************************************************/ + +#ifndef _CSI_GCC_H_ +#define _CSI_GCC_H_ + +#include +#include + +#ifndef __ASM +#define __ASM __asm /*!< asm keyword for GNU Compiler */ +#endif + +#ifndef __INLINE +#define __INLINE inline /*!< inline keyword for GNU Compiler */ +#endif + +#ifndef __ALWAYS_STATIC_INLINE +#define __ALWAYS_STATIC_INLINE __attribute__((always_inline)) static inline +#endif + +#ifndef __STATIC_INLINE +#define __STATIC_INLINE static inline +#endif + +#ifndef __NO_RETURN +#define __NO_RETURN __attribute__((__noreturn__)) +#endif + +#ifndef __USED +#define __USED __attribute__((used)) +#endif + +#ifndef __WEAK +#define __WEAK __attribute__((weak)) +#endif + +#ifndef __PACKED +#define __PACKED __attribute__((packed, aligned(1))) +#endif + +#ifndef __PACKED_STRUCT +#define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif + +#ifndef __PACKED_UNION +#define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CSI_Core_FunctionInterface + \defgroup CSI_Core_RegAccFunctions CSI Core Register Access Functions + @{ + */ +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by setting the IE-bit in the PSR. + Can only be executed in Privileged modes. + */ +__ALWAYS_STATIC_INLINE void __enable_irq(void) +{ + __ASM volatile("psrset ie"); +} + + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by clearing the IE-bit in the PSR. + Can only be executed in Privileged modes. + */ +__ALWAYS_STATIC_INLINE void __disable_irq(void) +{ + __ASM volatile("psrclr ie"); +} + +/** + \brief Get PSR + \details Returns the content of the PSR Register. + \return PSR Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_PSR(void) +{ + uint32_t result; + + __ASM volatile("mfcr %0, psr" : "=r"(result) :: "memory"); + return (result); +} + +/** + \brief Set PSR + \details Writes the given value to the PSR Register. + \param [in] psr PSR Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_PSR(uint32_t psr) +{ + __ASM volatile("mtcr %0, psr" : : "r"(psr) : "memory"); +} + +/** + \brief Get SP + \details Returns the content of the SP Register. + \return SP Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_SP(void) +{ + uint32_t result; + + __ASM volatile("mov %0, sp" : "=r"(result)); + return (result); +} + +/** + \brief Set SP + \details Writes the given value to the SP Register. + \param [in] sp SP Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_SP(uint32_t sp) +{ + __ASM volatile("mov sp, %0" : : "r"(sp): "sp"); +} + +/** + \brief Get Int SP + \details Returns the content of the Int SP Register. + \return Int SP Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_Int_SP(void) +{ + uint32_t result; + + __ASM volatile("mfcr %0, cr<15, 1>" : "=r"(result)); + return (result); +} + +/** + \brief Set Int SP + \details Writes the given value to the Int SP Register. + \param [in] sp Int SP Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_Int_SP(uint32_t sp) +{ + __ASM volatile("mtcr %0, cr<15, 1>" : : "r"(sp)); +} + +/** + \brief Get VBR Register + \details Returns the content of the VBR Register. + \return VBR Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_VBR(void) +{ + uint32_t result; + + __ASM volatile("mfcr %0, vbr" : "=r"(result)); + return (result); +} + +/** + \brief Set VBR + \details Writes the given value to the VBR Register. + \param [in] vbr VBR Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_VBR(uint32_t vbr) +{ + __ASM volatile("mtcr %0, vbr" : : "r"(vbr)); +} + +/** + \brief Get EPC Register + \details Returns the content of the EPC Register. + \return EPC Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_EPC(void) +{ + uint32_t result; + + __ASM volatile("mfcr %0, epc" : "=r"(result)); + return (result); +} + +/** + \brief Set EPC + \details Writes the given value to the EPC Register. + \param [in] epc EPC Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_EPC(uint32_t epc) +{ + __ASM volatile("mtcr %0, epc" : : "r"(epc)); +} + +/** + \brief Get EPSR + \details Returns the content of the EPSR Register. + \return EPSR Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_EPSR(void) +{ + uint32_t result; + + __ASM volatile("mfcr %0, epsr" : "=r"(result)); + return (result); +} + +/** + \brief Set EPSR + \details Writes the given value to the EPSR Register. + \param [in] epsr EPSR Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_EPSR(uint32_t epsr) +{ + __ASM volatile("mtcr %0, epsr" : : "r"(epsr)); +} + +/** + \brief Get CPUID Register + \details Returns the content of the CPUID Register. + \return CPUID Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_CPUID(void) +{ + uint32_t result; + +#ifdef __CK610 + __ASM volatile("mfcr %0, cr13" : "=r"(result)); +#else + __ASM volatile("mfcr %0, cr<13, 0>" : "=r"(result)); +#endif + return (result); +} + +/** + \brief Get CCR + \details Returns the current value of the CCR. + \return CCR Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_CCR(void) +{ + register uint32_t result; + +#ifdef __CK610 + __ASM volatile("mfcr %0, cr18\n" : "=r"(result)); +#else + __ASM volatile("mfcr %0, cr<18, 0>\n" : "=r"(result)); +#endif + return (result); +} + + +/** + \brief Set CCR + \details Assigns the given value to the CCR. + \param [in] ccr CCR value to set + */ +__ALWAYS_STATIC_INLINE void __set_CCR(uint32_t ccr) +{ +#ifdef __CK610 + __ASM volatile("mtcr %0, cr18\n" : : "r"(ccr)); +#else + __ASM volatile("mtcr %0, cr<18, 0>\n" : : "r"(ccr)); +#endif +} + +/** + \brief Get CCR2 + \details Returns the current value of the CCR2. + \return CCR2 Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_CCR2(void) +{ + register uint32_t result; + + __ASM volatile("mfcr %0, cr<31, 0>\n" : "=r"(result)); + return (result); +} + +/** + \brief Set CCR2 + \details Assigns the given value to the CCR2. + \param [in] ccr2 CCR2 value to set + */ +__ALWAYS_STATIC_INLINE void __set_CCR2(uint32_t ccr2) +{ + __ASM volatile("mtcr %0, cr<31, 0>\n" : : "r"(ccr2)); +} + +/** + \brief Get DCSR + \details Returns the content of the DCSR Register. + \return DCSR Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_DCSR(void) +{ + uint32_t result; +#ifdef __CK610 + __ASM volatile("mfcr %0, cr14" : "=r"(result)); +#else + __ASM volatile("mfcr %0, cr<14, 0>" : "=r"(result)); +#endif + return (result); +} + + +/** + \brief Set DCSR + \details Writes the given value to the DCSR Register. + \param [in] dcsr DCSR Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_DCSR(uint32_t dcsr) +{ +#ifdef __CK610 + __ASM volatile("mtcr %0, cr14" : : "r"(dcsr)); +#else + __ASM volatile("mtcr %0, cr<14, 0>" : : "r"(dcsr)); +#endif +} + + +/** + \brief Get CFR + \details Returns the content of the CFR Register. + \return CFR Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_CFR(void) +{ + uint32_t result; +#ifdef __CK610 + __ASM volatile("mfcr %0, cr17" : "=r"(result)); +#else + __ASM volatile("mfcr %0, cr<17, 0>" : "=r"(result)); +#endif + + return (result); +} + + +/** + \brief Set CFR + \details Writes the given value to the CFR Register. + \param [in] cfr CFR Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_CFR(uint32_t cfr) +{ +#ifdef __CK610 + __ASM volatile("mtcr %0, cr17" : : "r"(cfr)); +#else + __ASM volatile("mtcr %0, cr<17, 0>" : : "r"(cfr)); +#endif +} + + +/** + \brief Get CIR + \details Returns the content of the CIR Register. + \return CIR Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_CIR(void) +{ + uint32_t result; +#ifdef __CK610 + __ASM volatile("mfcr %0, cr22" : "=r"(result)); +#else + __ASM volatile("mfcr %0, cr<22, 0>" : "=r"(result)); +#endif + return (result); +} + + +/** + \brief Set CIR + \details Writes the given value to the CIR Register. + \param [in] cir CIR Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_CIR(uint32_t cir) +{ +#ifdef __CK610 + __ASM volatile("mtcr %0, cr22" : : "r"(cir)); +#else + __ASM volatile("mtcr %0, cr<22, 0>" : : "r"(cir)); +#endif +} + +/** + \brief Get ERRLC + \details Returns the current value of the ERRLC. + \return ERRLC Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_ERRLC(void) +{ + register uint32_t result; + + __ASM volatile("mfcr %0, cr<6, 1>\n" : "=r"(result)); + return (result); +} + +/** + \brief Set ERRLC + \details Assigns the given value to the ERRLC. + \param [in] errlc ERRLC value to set + */ +__ALWAYS_STATIC_INLINE void __set_ERRLC(uint32_t errlc) +{ + __ASM volatile("mtcr %0, cr<6, 1>\n" : : "r"(errlc)); +} + +/** + \brief Get ERRADDR + \details Returns the current value of the ERRADDR. + \return ERRADDR Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_ERRADDR(void) +{ + register uint32_t result; + + __ASM volatile("mfcr %0, cr<7, 1>\n" : "=r"(result)); + return (result); +} + +/** + \brief Set ERRADDR + \details Assigns the given value to the ERRADDR. + \param [in] erraddr ERRADDR value to set + */ +__ALWAYS_STATIC_INLINE void __set_ERRADDR(uint32_t erraddr) +{ + __ASM volatile("mtcr %0, cr<7, 1>\n" : : "r"(erraddr)); +} + +/** + \brief Get ERRSTS + \details Returns the current value of the ERRSTS. + \return ERRSTS Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_ERRSTS(void) +{ + register uint32_t result; + + __ASM volatile("mfcr %0, cr<8, 1>\n" : "=r"(result)); + return (result); +} + +/** + \brief Set ERRSTS + \details Assigns the given value to the ERRSTS. + \param [in] errsts ERRSTS value to set + */ +__ALWAYS_STATIC_INLINE void __set_ERRSTS(uint32_t errsts) +{ + __ASM volatile("mtcr %0, cr<8, 1>\n" : : "r"(errsts)); +} + +/** + \brief Get ERRINJCR + \details Returns the current value of the ERRINJCR. + \return ERRINJCR Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_ERRINJCR(void) +{ + register uint32_t result; + + __ASM volatile("mfcr %0, cr<9, 1>\n" : "=r"(result)); + return (result); +} + +/** + \brief Set ERRINJCR + \details Assigns the given value to the ERRINJCR. + \param [in] errinjcr ERRINJCR value to set + */ +__ALWAYS_STATIC_INLINE void __set_ERRINJCR(uint32_t errinjcr) +{ + __ASM volatile("mtcr %0, cr<9, 1>\n" : : "r"(errinjcr)); +} + +/** + \brief Get ERRINJCNT + \details Returns the current value of the ERRINJCNT. + \return ERRINJCNT Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_ERRINJCNT(void) +{ + register uint32_t result; + + __ASM volatile("mfcr %0, cr<10, 1>\n" : "=r"(result)); + return (result); +} + +/** + \brief Set ERRINJCNT + \details Assigns the given value to the ERRINJCNT. + \param [in] errinjcnt ERRINJCNT value to set + */ +__ALWAYS_STATIC_INLINE void __set_ERRINJCNT(uint32_t errinjcnt) +{ + __ASM volatile("mtcr %0, cr<10, 1>\n" : : "r"(errinjcnt)); +} + +/** + \brief Get ITCMCR + \details Returns the content of the ITCMCR Register. + \return ITCMCR Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_ITCMCR(void) +{ + uint32_t result; + __ASM volatile("mfcr %0, cr<22, 1>" : "=r"(result)); + return (result); +} + +/** + \brief Set ITCMCR + \details Writes the given value to the ITCMCR Register. + \param [in] itcmcr ITCMCR Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_ITCMCR(uint32_t itcmcr) +{ + __ASM volatile("mtcr %0, cr<22, 1>" : : "r"(itcmcr)); +} + +/** + \brief Get DTCMCR + \details Returns the content of the DTCMCR Register. + \return DTCMCR Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_DTCMCR(void) +{ + uint32_t result; + __ASM volatile("mfcr %0, cr<23, 1>" : "=r"(result)); + return (result); +} + +/** + \brief Set DTCMCR + \details Writes the given value to the DTCMCR Register. + \param [in] dtcmcr DTCMCR Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_DTCMCR(uint32_t dtcmcr) +{ + __ASM volatile("mtcr %0, cr<23, 1>" : : "r"(dtcmcr)); +} + +/** + \brief Get CINDEX + \details Returns the current value of the CINDEX. + \return CINDEX Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_CINDEX(void) +{ + register uint32_t result; + + __ASM volatile("mfcr %0, cr<26, 1>\n" : "=r"(result)); + return (result); +} + +/** + \brief Set CINDEX + \details Assigns the given value to the CINDEX. + \param [in] cindex CINDEX value to set + */ +__ALWAYS_STATIC_INLINE void __set_CINDEX(uint32_t cindex) +{ + __ASM volatile("mtcr %0, cr<26, 1>\n" : : "r"(cindex)); +} + +/** + \brief Get CDATAx + \details Returns the current value of the CDATAx. + \return CDATAx Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_CDATA0(void) +{ + register uint32_t result; + + __ASM volatile("mfcr %0, cr<27, 1>\n" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE uint32_t __get_CDATA1(void) +{ + register uint32_t result; + + __ASM volatile("mfcr %0, cr<28, 1>\n" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE uint32_t __get_CDATA2(void) +{ + register uint32_t result; + + __ASM volatile("mfcr %0, cr<29, 1>\n" : "=r"(result)); + return (result); +} + +/** + \brief Set CDATAx + \details Assigns the given value to the CDATAx. + \param [in] cdata CDATAx value to set + */ +__ALWAYS_STATIC_INLINE void __set_CDATA0(uint32_t cdata) +{ + __ASM volatile("mtcr %0, cr<27, 1>\n" : : "r"(cdata)); +} + +__ALWAYS_STATIC_INLINE void __set_CDATA1(uint32_t cdata) +{ + __ASM volatile("mtcr %0, cr<28, 1>\n" : : "r"(cdata)); +} + +__ALWAYS_STATIC_INLINE void __set_CDATA2(uint32_t cdata) +{ + __ASM volatile("mtcr %0, cr<29, 1>\n" : : "r"(cdata)); +} + +/** + \brief Get CINS + \details Returns the current value of the CINS. + \return CINS Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_CINS(void) +{ + register uint32_t result; + + __ASM volatile("mfcr %0, cr<31, 1>\n" : "=r"(result)); + return (result); +} + +/** + \brief Set CINS + \details Assigns the given value to the CINS. + \param [in] cins CINS value to set + */ +__ALWAYS_STATIC_INLINE void __set_CINS(uint32_t cins) +{ + __ASM volatile("mtcr %0, cr<31, 1>\n" : : "r"(cins)); +} + +/** + \brief Get CAPR + \details Returns the current value of the CAPR. + \return CAPR Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_CAPR(void) +{ + register uint32_t result; + +#ifdef __CK610 + __ASM volatile("mfcr %0, cr19\n" : "=r"(result)); +#else + __ASM volatile("mfcr %0, cr<19, 0>\n" : "=r"(result)); +#endif + return (result); +} + +/** + \brief Set CAPR + \details Assigns the given value to the CAPR. + \param [in] capr CAPR value to set + */ +__ALWAYS_STATIC_INLINE void __set_CAPR(uint32_t capr) +{ +#ifdef __CK610 + __ASM volatile("mtcr %0, cr19\n" : : "r"(capr)); +#else + __ASM volatile("mtcr %0, cr<19, 0>\n" : : "r"(capr)); +#endif +} + +/** + \brief Get CAPR1 + \details Returns the current value of the CAPR1. + \return CAPR1 Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_CAPR1(void) +{ + register uint32_t result; + + __ASM volatile("mfcr %0, cr<16, 0>\n" : "=r"(result)); + return (result); +} + +/** + \brief Set CAPR1 + \details Assigns the given value to the CAPR1. + \param [in] capr1 CAPR1 value to set + */ +__ALWAYS_STATIC_INLINE void __set_CAPR1(uint32_t capr1) +{ + __ASM volatile("mtcr %0, cr<16, 0>\n" : : "r"(capr1)); +} + +/** + \brief Set PACR + \details Assigns the given value to the PACR. + + \param [in] pacr PACR value to set + */ +__ALWAYS_STATIC_INLINE void __set_PACR(uint32_t pacr) +{ +#ifdef __CK610 + __ASM volatile("mtcr %0, cr20\n" : : "r"(pacr)); +#else + __ASM volatile("mtcr %0, cr<20, 0>\n" : : "r"(pacr)); +#endif +} + + +/** + \brief Get PACR + \details Returns the current value of PACR. + \return PACR value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_PACR(void) +{ + uint32_t result; + +#ifdef __CK610 + __ASM volatile("mfcr %0, cr20" : "=r"(result)); +#else + __ASM volatile("mfcr %0, cr<20, 0>" : "=r"(result)); +#endif + return (result); +} + +/** + \brief Set PRSR + \details Assigns the given value to the PRSR. + + \param [in] prsr PRSR value to set + */ +__ALWAYS_STATIC_INLINE void __set_PRSR(uint32_t prsr) +{ +#ifdef __CK610 + __ASM volatile("mtcr %0, cr21\n" : : "r"(prsr)); +#else + __ASM volatile("mtcr %0, cr<21, 0>\n" : : "r"(prsr)); +#endif +} + +/** + \brief Get PRSR + \details Returns the current value of PRSR. + \return PRSR value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_PRSR(void) +{ + uint32_t result; + +#ifdef __CK610 + __ASM volatile("mfcr %0, cr21" : "=r"(result)); +#else + __ASM volatile("mfcr %0, cr<21, 0>" : "=r"(result)); +#endif + return (result); +} + +/** + \brief Set ATTR0 + \details Assigns the given value to the ATTR0. + + \param [in] attr0 ATTR0 value to set + */ +__ALWAYS_STATIC_INLINE void __set_ATTR0(uint32_t attr0) +{ + __ASM volatile("mtcr %0, cr<26, 0>\n" : : "r"(attr0)); +} + +/** + \brief Get ATTR0 + \details Returns the current value of ATTR0. + \return ATTR0 value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_ATTR0(void) +{ + uint32_t result; + + __ASM volatile("mfcr %0, cr<26, 0>" : "=r"(result)); + + return (result); +} + +/** + \brief Set ATTR1 + \details Assigns the given value to the ATTR1. + + \param [in] attr0 ATTR1 value to set + */ +__ALWAYS_STATIC_INLINE void __set_ATTR1(uint32_t attr1) +{ + __ASM volatile("mtcr %0, cr<27, 0>\n" : : "r"(attr1)); +} + +/** + \brief Get ATTR1 + \details Returns the current value of ATTR1. + \return ATTR1 value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_ATTR1(void) +{ + uint32_t result; + + __ASM volatile("mfcr %0, cr<27, 0>" : "=r"(result)); + + return (result); +} + +/** + \brief Get user sp + \details Returns the current value of user r14. + \return UR14 value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_UR14(void) +{ + uint32_t result; + +#ifdef __CK610 + __ASM volatile("mov %0, sp" : "=r"(result)); +#else + __ASM volatile("mfcr %0, cr<14, 1>" : "=r"(result)); +#endif + return (result); +} + +/** + \brief Set UR14 + \details Assigns the given value to the UR14. + \param [in] ur14 UR14 value to set + */ +__ALWAYS_STATIC_INLINE void __set_UR14(uint32_t ur14) +{ +#ifdef __CK610 + __ASM volatile("mov sp, %0" : "=r"(ur14)); +#else + __ASM volatile("mtcr %0, cr<14, 1>\n" : : "r"(ur14)); +#endif +} + +/** + \brief Get CHR Register + \details Returns the content of the CHR Register. + \return CHR Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_CHR(void) +{ + uint32_t result; + + __ASM volatile("mfcr %0, cr<31, 0>\n" :"=r"(result)); + return (result); +} + +/** + \brief Set CHR + \details Assigns the given value to the CHR. + \param [in] chr CHR value to set + */ +__ALWAYS_STATIC_INLINE void __set_CHR(uint32_t chr) +{ + __ASM volatile("mtcr %0, cr<31, 0>\n" : : "r"(chr)); +} + +/** + \brief Get HINT + \details Returns the content of the HINT Register. + \return HINT Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_HINT(void) +{ + uint32_t result; +#ifdef __CK610 + __ASM volatile("mfcr %0, cr<30, 0>" : "=r"(result)); +#else + __ASM volatile("mfcr %0, cr<31, 0>" : "=r"(result)); +#endif + return (result); +} + +/** + \brief Set HINT + \details Writes the given value to the HINT Register. + \param [in] hint HINT Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_HINT(uint32_t hint) +{ +#ifdef __CK610 + __ASM volatile("mtcr %0, cr<30, 0>" : "=r"(hint)); +#else + __ASM volatile("mtcr %0, cr<31, 0>" : : "r"(hint)); +#endif +} + +/** + \brief Get MIR + \details Returns the content of the MIR Register. + \return MIR Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MIR(void) +{ + uint32_t result; +#ifdef __CK610 + __ASM volatile("cpseti 15"); + __ASM volatile("cprcr %0, cpcr0" : "=r"(result)); +#else + __ASM volatile("mfcr %0, cr<0, 15>" : "=r"(result)); +#endif + return (result); +} + +/** + \brief Set MIR + \details Writes the given value to the MIR Register. + \param [in] mir MIR Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MIR(uint32_t mir) +{ +#ifdef __CK610 + __ASM volatile("cpseti 15"); + __ASM volatile("cpwcr %0, cpcr0" : : "b"(mir)); +#else + __ASM volatile("mtcr %0, cr<0, 15>" : : "r"(mir)); +#endif +} + + +/** + \brief Get MEL0 + \details Returns the content of the MEL0 Register. + \return MEL0 Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MEL0(void) +{ + uint32_t result; +#ifdef __CK610 + __ASM volatile("cpseti 15"); + __ASM volatile("cprcr %0, cpcr2" : "=r"(result)); +#else + __ASM volatile("mfcr %0, cr<2, 15>" : "=r"(result)); +#endif + return (result); +} + +/** + \brief Set MEL0 + \details Writes the given value to the MEL0 Register. + \param [in] mel0 MEL0 Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MEL0(uint32_t mel0) +{ +#ifdef __CK610 + __ASM volatile("cpseti 15"); + __ASM volatile("cpwcr %0, cpcr2" : : "b"(mel0)); +#else + __ASM volatile("mtcr %0, cr<2, 15>" : : "r"(mel0)); +#endif +} + + +/** + \brief Get MEL1 + \details Returns the content of the MEL1 Register. + \return MEL1 Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MEL1(void) +{ + uint32_t result; +#ifdef __CK610 + __ASM volatile("cpseti 15"); + __ASM volatile("cprcr %0, cpcr3" : "=r"(result)); +#else + __ASM volatile("mfcr %0, cr<3, 15>" : "=r"(result)); +#endif + return (result); +} + +/** + \brief Set MEL1 + \details Writes the given value to the MEL1 Register. + \param [in] mel1 MEL1 Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MEL1(uint32_t mel1) +{ +#ifdef __CK610 + __ASM volatile("cpseti 15"); + __ASM volatile("cpwcr %0, cpcr3" : : "b"(mel1)); +#else + __ASM volatile("mtcr %0, cr<3, 15>" : : "r"(mel1)); +#endif +} + + +/** + \brief Get MEH + \details Returns the content of the MEH Register. + \return MEH Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MEH(void) +{ + uint32_t result; +#ifdef __CK610 + __ASM volatile("cpseti 15"); + __ASM volatile("cprcr %0, cpcr4" : "=r"(result)); +#else + __ASM volatile("mfcr %0, cr<4, 15>" : "=r"(result)); +#endif + return (result); +} + +/** + \brief Set MEH + \details Writes the given value to the MEH Register. + \param [in] meh MEH Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MEH(uint32_t meh) +{ +#ifdef __CK610 + __ASM volatile("cpseti 15"); + __ASM volatile("cpwcr %0, cpcr4" : : "b"(meh)); +#else + __ASM volatile("mtcr %0, cr<4, 15>" : : "r"(meh)); +#endif +} + + +/** + \brief Get MPR + \details Returns the content of the MPR Register. + \return MPR Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MPR(void) +{ + uint32_t result; +#ifdef __CK610 + __ASM volatile("cpseti 15"); + __ASM volatile("cprcr %0, cpcr6" : "=r"(result)); +#else + __ASM volatile("mfcr %0, cr<6, 15>" : "=r"(result)); +#endif + return (result); +} + +/** + \brief Set MPR + \details Writes the given value to the MPR Register. + \param [in] mpr MPR Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MPR(uint32_t mpr) +{ +#ifdef __CK610 + __ASM volatile("cpseti 15"); + __ASM volatile("cpwcr %0, cpcr6" : : "b"(mpr)); +#else + __ASM volatile("mtcr %0, cr<6, 15>" : : "r"(mpr)); +#endif +} + + +/** + \brief Get MCIR + \details Returns the content of the MCIR Register. + \return MCIR Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MCIR(void) +{ + uint32_t result; +#ifdef __CK610 + __ASM volatile("cpseti 15"); + __ASM volatile("cprcr %0, cpcr8" : "=r"(result)); +#else + __ASM volatile("mfcr %0, cr<8, 15>" : "=r"(result)); +#endif + return (result); +} + +/** + \brief Set MCIR + \details Writes the given value to the MCIR Register. + \param [in] mcir MCIR Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MCIR(uint32_t mcir) +{ +#ifdef __CK610 + __ASM volatile("cpseti 15"); + __ASM volatile("cpwcr %0, cpcr8" : : "b"(mcir)); +#else + __ASM volatile("mtcr %0, cr<8, 15>" : : "r"(mcir)); +#endif +} + + +/** + \brief Get MPGD + \details Returns the content of the MPGD Register. + \return MPGD Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MPGD(void) +{ + uint32_t result; +#ifdef __CK610 + __ASM volatile("cpseti 15"); + __ASM volatile("cprcr %0, cpcr29" : "=r"(result)); +#else + __ASM volatile("mfcr %0, cr<29, 15>" : "=r"(result)); +#endif + return (result); +} + +/** + \brief Set MPGD + \details Writes the given value to the MPGD Register. + \param [in] mpgd MPGD Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MPGD(uint32_t mpgd) +{ +#ifdef __CK610 + __ASM volatile("cpseti 15"); + __ASM volatile("cpwcr %0, cpcr29" : : "b"(mpgd)); +#else + __ASM volatile("mtcr %0, cr<29, 15>" : : "r"(mpgd)); +#endif +} + + +/** + \brief Get MSA0 + \details Returns the content of the MSA0 Register. + \return MSA0 Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MSA0(void) +{ + uint32_t result; +#ifdef __CK610 + __ASM volatile("cpseti 15"); + __ASM volatile("cprcr %0, cpcr30" : "=r"(result)); +#else + __ASM volatile("mfcr %0, cr<30, 15>" : "=r"(result)); +#endif + return (result); +} + +/** + \brief Set MSA0 + \details Writes the given value to the MSA0 Register. + \param [in] msa0 MSA0 Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MSA0(uint32_t msa0) +{ +#ifdef __CK610 + __ASM volatile("cpseti 15"); + __ASM volatile("cpwcr %0, cpcr30" : : "b"(msa0)); +#else + __ASM volatile("mtcr %0, cr<30, 15>" : : "r"(msa0)); +#endif +} + + +/** + \brief Get MSA1 + \details Returns the content of the MSA1 Register. + \return MSA1 Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MSA1(void) +{ + uint32_t result; + +#ifdef __CK610 + __ASM volatile("cpseti 15"); + __ASM volatile("cprcr %0, cpcr31" : "=r"(result)); +#else + __ASM volatile("mfcr %0, cr<31, 15>" : "=r"(result)); +#endif + return (result); +} + +/** + \brief Set MSA1 + \details Writes the given value to the MSA1 Register. + \param [in] msa1 MSA1 Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MSA1(uint32_t msa1) +{ +#ifdef __CK610 + __ASM volatile("cpseti 15"); + __ASM volatile("cpwcr %0, cpcr31" : : "b"(msa1)); +#else + __ASM volatile("mtcr %0, cr<31, 15>" : : "r"(msa1)); +#endif +} + + +/** + \brief Enable interrupts and exceptions + \details Enables interrupts and exceptions by setting the IE-bit and EE-bit in the PSR. + Can only be executed in Privileged modes. + */ +__ALWAYS_STATIC_INLINE void __enable_excp_irq(void) +{ + __ASM volatile("psrset ee, ie"); +} + + +/** + \brief Disable interrupts and exceptions + \details Disables interrupts and exceptions by clearing the IE-bit and EE-bit in the PSR. + Can only be executed in Privileged modes. + */ +__ALWAYS_STATIC_INLINE void __disable_excp_irq(void) +{ + __ASM volatile("psrclr ee, ie"); +} + +/** + \brief Get GSR + \details Returns the content of the GSR Register. + \return GSR Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_GSR(void) +{ + uint32_t result; + +#ifdef __CK610 + __ASM volatile("mfcr %0, cr12" : "=r"(result)); +#else + __ASM volatile("mfcr %0, cr<12, 0>" : "=r"(result)); +#endif + return (result); +} + +/** + \brief Get GCR + \details Returns the content of the GCR Register. + \return GCR Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_GCR(void) +{ + uint32_t result; + +#ifdef __CK610 + __ASM volatile("mfcr %0, cr11" : "=r"(result)); +#else + __ASM volatile("mfcr %0, cr<11, 0>" : "=r"(result)); +#endif + return (result); +} + +/** + \brief Set GCR + \details Writes the given value to the GCR Register. + \param [in] gcr GCR Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_GCR(uint32_t gcr) +{ +#ifdef __CK610 + __ASM volatile("mtcr %0, cr11" : : "r"(gcr)); +#else + __ASM volatile("mtcr %0, cr<11, 0>" : : "r"(gcr)); +#endif +} + +/** + \brief Get WSSR + \details Returns the content of the WSSR Register, must be accessed in TEE + \return WSSR Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_WSSR(void) +{ + uint32_t result; + + __ASM volatile("mfcr %0, cr<0, 3>" : "=r"(result)); + return (result); +} + +/** + \brief Get WRCR + \details Returns the content of the WRCR Register, must be accessed in TEE + \return WRCR Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_WRCR(void) +{ + uint32_t result; + + __ASM volatile("mfcr %0, cr<1, 3>" : "=r"(result)); + return (result); +} + +/** + \brief Set WRCR + \details Writes the given value to the WRCR Register, must be accessed in TEE + \param [in] wrcr WRCR Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_WRCR(uint32_t wrcr) +{ + __ASM volatile("mtcr %0, cr<1, 3>" : : "r"(wrcr)); +} + +/** + \brief Get DCR + \details Returns the content of the DCR Register, must be accessed in TEE + \return DCR Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_DCR(void) +{ + uint32_t result; + + __ASM volatile("mfcr %0, cr<8, 3>" : "=r"(result)); + return (result); +} + +/** + \brief Set DCR + \details Writes the given value to the DCR Register, must be accessed in TEE + \param [in] dcr DCR Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_DCR(uint32_t dcr) +{ + __ASM volatile("mtcr %0, cr<8, 3>" : : "r"(dcr)); +} + +/** + \brief Get PCR + \details Returns the content of the PCR Register, must be accessed in TEE + \return PCR Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_PCR(void) +{ + uint32_t result; + + __ASM volatile("mfcr %0, cr<9, 3>" : "=r"(result)); + return (result); +} + +/** + \brief Set PCR + \details Writes the given value to the PCR Register, must be accessed in TEE + \param [in] pcr PCR Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_PCR(uint32_t pcr) +{ + __ASM volatile("mtcr %0, cr<9, 3>" : : "r"(pcr)); +} + +/** + \brief Get EBR + \details Returns the content of the EBR Register. + \return EBR Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_EBR(void) +{ + uint32_t result; + + __ASM volatile("mfcr %0, cr<1, 1>" : "=r"(result)); + return (result); +} + +/** + \brief Set EBR + \details Writes the given value to the EBR Register. + \param [in] ebr EBR Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_EBR(uint32_t ebr) +{ + __ASM volatile("mtcr %0, cr<1, 1>" : : "r"(ebr)); +} + +/*@} end of CSI_Core_RegAccFunctions */ + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CSI_Core_InstructionInterface CSI Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +#define __CSI_GCC_OUT_REG(r) "=r" (r) +#define __CSI_GCC_USE_REG(r) "r" (r) + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +__ALWAYS_STATIC_INLINE void __NOP(void) +{ + __ASM volatile("nop"); +} + + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +__ALWAYS_STATIC_INLINE void __WFI(void) +{ + __ASM volatile("wait"); +} + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one interrupt occurs. + */ +__ALWAYS_STATIC_INLINE void __WAIT(void) +{ + __ASM volatile("wait"); +} + +/** + \brief Doze For Interrupt + \details Doze For Interrupt is a hint instruction that suspends execution until one interrupt occurs. + */ +__ALWAYS_STATIC_INLINE void __DOZE(void) +{ + __ASM volatile("doze"); +} + +/** + \brief Stop For Interrupt + \details Stop For Interrupt is a hint instruction that suspends execution until one interrupt occurs. + */ +__ALWAYS_STATIC_INLINE void __STOP(void) +{ + __ASM volatile("stop"); +} + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +__ALWAYS_STATIC_INLINE void __ISB(void) +{ + __ASM volatile("sync"::: "memory"); +} + + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__ALWAYS_STATIC_INLINE void __DSB(void) +{ + __ASM volatile("sync"::: "memory"); +} + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__ALWAYS_STATIC_INLINE void __DMB(void) +{ + __ASM volatile("sync"::: "memory"); +} + +/** + \brief Search from the highest bit that the very first bit which's value is 1. + \param [in] value Value to bit search. + \return if the highest bit' value is 1, return 0, and if lowest bit's value is 1, return 31, otherwise return 32. + */ +#if !defined(__CK610) || !(__CK80X == 1) +__ALWAYS_STATIC_INLINE uint32_t __FF0(uint32_t value) +{ + uint32_t ret; + + __ASM volatile("ff0 %0, %1" : "=r"(ret) : "r"(value)); + return ret; +} +#endif + +/** + \brief Search from the highest bit that the very first bit which's value is 0. + \param [in] value Value to bit search. + \return if the highest bit' value is 0, return 0, and if lowest bit's value is 0, return 31, otherwise return 32. + */ +#if !(__CK80X == 1) +__ALWAYS_STATIC_INLINE uint32_t __FF1(uint32_t value) +{ + uint32_t ret; +#if !defined (__CK610) + __ASM volatile("ff1 %0, %1" : "=r"(ret) : "r"(value)); +#else + ret = value; + __ASM volatile("ff1 %0" : "=r"(ret):); +#endif + return ret; +} +#endif + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in integer value. + \param [in] value Value to reverse + \return Reversed value + */ +__ALWAYS_STATIC_INLINE uint32_t __REV(uint32_t value) +{ + return __builtin_bswap32(value); +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in two unsigned short values. + \param [in] value Value to reverse + \return Reversed value + */ +__ALWAYS_STATIC_INLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; +#if (__CK80X >= 2) + __ASM volatile("revh %0, %1" : __CSI_GCC_OUT_REG(result) : __CSI_GCC_USE_REG(value)); +#else + result = ((value & 0xFF000000) >> 8) | ((value & 0x00FF0000) << 8) | + ((value & 0x0000FF00) >> 8) | ((value & 0x000000FF) << 8); +#endif + return (result); +} + + +/** + \brief Reverse byte order in signed short value + \details Reverses the byte order in a signed short value with sign extension to integer. + \param [in] value Value to reverse + \return Reversed value + */ +__ALWAYS_STATIC_INLINE int32_t __REVSH(int32_t value) +{ + return (short)(((value & 0xFF00) >> 8) | ((value & 0x00FF) << 8)); +} + + +/** + \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 + \return Rotated value + */ +__ALWAYS_STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \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. + */ +__ALWAYS_STATIC_INLINE void __BKPT(void) +{ + __ASM volatile("bkpt"); +} + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +__ALWAYS_STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + +#if (__CK80X >= 0x03U) + __ASM volatile("brev %0, %1" : "=r"(result) : "r"(value)); +#else + int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + + for (value >>= 1U; value; value >>= 1U) { + result <<= 1U; + result |= value & 1U; + s--; + } + + result <<= s; /* shift when v's highest bits are zero */ +#endif + return (result); +} + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __builtin_clz +/** + \details This function saturates a signed value. + \param [in] x Value to be saturated + \param [in] y Bit position to saturate to [1..32] + \return Saturated value. + */ +__ALWAYS_STATIC_INLINE int32_t __SSAT(int32_t x, uint32_t y) +{ + int32_t posMax, negMin; + uint32_t i; + + posMax = 1; + + for (i = 0; i < (y - 1); i++) { + posMax = posMax * 2; + } + + if (x > 0) { + posMax = (posMax - 1); + + if (x > posMax) { + x = posMax; + } + +// x &= (posMax * 2 + 1); + } else { + negMin = -posMax; + + if (x < negMin) { + x = negMin; + } + +// x &= (posMax * 2 - 1); + } + + return (x); +} + +/** + \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 + */ +__ALWAYS_STATIC_INLINE uint32_t __USAT(uint32_t value, uint32_t sat) +{ + uint32_t result; + + if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) { + result = 0xFFFFFFFF >> (32 - sat); + } else { + result = value; + } + + return (result); +} + +/** + \brief Unsigned Saturate for internal use + \details Saturates an unsigned value, should not call directly. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__ALWAYS_STATIC_INLINE uint32_t __IUSAT(uint32_t value, uint32_t sat) +{ + uint32_t result; + + if (value & 0x80000000) { /* only overflow set bit-31 */ + result = 0; + } else if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) { + result = 0xFFFFFFFF >> (32 - sat); + } else { + result = value; + } + + return (result); +} + +/** + \brief Rotate Right with Extend + \details This function moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \note carry input will always 0. + \param [in] op1 Value to rotate + \return Rotated value + */ +__ALWAYS_STATIC_INLINE uint32_t __RRX(uint32_t op1) +{ +#if (__CK80X >= 2) + uint32_t res = 0; + __ASM volatile("bgeni t0, 31\n\t" + "lsri %0, 1\n\t" + "movt %1, t0\n\t" + "or %1, %1, %0\n\t" + : "=r"(op1), "=r"(res): "0"(op1), "1"(res): "t0"); + return res; +#else + uint32_t res = 0; + __ASM volatile("movi r7, 0\n\t" + "bseti r7, 31\n\t" + "lsri %0, 1\n\t" + "bf 1f\n\t" + "mov %1, r7\n\t" + "1:\n\t" + "or %1, %1, %0\n\t" + : "=r"(op1), "=r"(res): "0"(op1), "1"(res): "r7"); + return res; +#endif +} + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] addr Pointer to location + \return value of type uint8_t at (*ptr) + */ +__ALWAYS_STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *addr) +{ + uint32_t result; +//#warning "__LDRBT" + __ASM volatile("ldb %0, (%1, 0)" : "=r"(result) : "r"(addr)); + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] addr Pointer to location + \return value of type uint16_t at (*ptr) + */ +__ALWAYS_STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *addr) +{ + uint32_t result; + +//#warning "__LDRHT" + __ASM volatile("ldh %0, (%1, 0)" : "=r"(result) : "r"(addr)); + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] addr Pointer to location + \return value of type uint32_t at (*ptr) + */ +__ALWAYS_STATIC_INLINE uint32_t __LDRT(volatile uint32_t *addr) +{ + uint32_t result; + +//#warning "__LDRT" + __ASM volatile("ldw %0, (%1, 0)" : "=r"(result) : "r"(addr)); + return (result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] addr Pointer to location + */ +__ALWAYS_STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr) +{ +//#warning "__STRBT" + __ASM volatile("stb %1, (%0, 0)" :: "r"(addr), "r"((uint32_t)value) : "memory"); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] addr Pointer to location + */ +__ALWAYS_STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr) +{ +//#warning "__STRHT" + __ASM volatile("sth %1, (%0, 0)" :: "r"(addr), "r"((uint32_t)value) : "memory"); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] addr Pointer to location + */ +__ALWAYS_STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *addr) +{ +//#warning "__STRT" + __ASM volatile("stw %1, (%0, 0)" :: "r"(addr), "r"(value) : "memory"); +} + +/*@}*/ /* end of group CSI_Core_InstructionInterface */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CSI_Core_FunctionInterface + \defgroup CSI_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type, always 0. + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__ALWAYS_STATIC_INLINE uint32_t __get_FPUType(void) +{ +//FIXME: + return 0; +} + +/*@} end of CSI_Core_FpuFunctions */ + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CSI_SIMD_intrinsics CSI SIMD Intrinsics + Access to dedicated SIMD instructions \n + Single Instruction Multiple Data (SIMD) extensions are provided to simplify development of application software. SIMD extensions increase the processing capability without materially increasing the power consumption. The SIMD extensions are completely transparent to the operating system (OS), allowing existing OS ports to be used. + + @{ +*/ + +/** + \brief Halfword packing instruction. Combines bits[15:0] of val1 with bits[31:16] + of val2 levitated with the val3. + \details Combine a halfword from one register with a halfword from another register. + The second argument can be left-shifted before extraction of the halfword. + \param [in] val1 first 16-bit operands + \param [in] val2 second 16-bit operands + \param [in] val3 value for left-shifting val2. Value range [0..31]. + \return the combination of halfwords. + \remark + res[15:0] = val1[15:0] \n + res[31:16] = val2[31:16] << val3 + */ +__ALWAYS_STATIC_INLINE uint32_t __PKHBT(uint32_t val1, uint32_t val2, uint32_t val3) +{ + return ((((int32_t)(val1) << 0) & (int32_t)0x0000FFFF) | (((int32_t)(val2) << val3) & (int32_t)0xFFFF0000)); +} + +/** + \brief Halfword packing instruction. Combines bits[31:16] of val1 with bits[15:0] + of val2 right-shifted with the val3. + \details Combine a halfword from one register with a halfword from another register. + The second argument can be right-shifted before extraction of the halfword. + \param [in] val1 first 16-bit operands + \param [in] val2 second 16-bit operands + \param [in] val3 value for right-shifting val2. Value range [1..32]. + \return the combination of halfwords. + \remark + res[15:0] = val2[15:0] >> val3 \n + res[31:16] = val1[31:16] + */ +__ALWAYS_STATIC_INLINE uint32_t __PKHTB(uint32_t val1, uint32_t val2, uint32_t val3) +{ + return ((((int32_t)(val1) << 0) & (int32_t)0xFFFF0000) | (((int32_t)(val2) >> val3) & (int32_t)0x0000FFFF)); +} + +/** + \brief Dual 16-bit signed saturate. + \details This function saturates a signed value. + \param [in] x two signed 16-bit values to be saturated. + \param [in] y bit position for saturation, an integral constant expression in the range 1 to 16. + \return the sum of the absolute differences of the following bytes, added to the accumulation value:\n + the signed saturation of the low halfword in val1, saturated to the bit position specified in + val2 and returned in the low halfword of the return value.\n + the signed saturation of the high halfword in val1, saturated to the bit position specified in + val2 and returned in the high halfword of the return value. + */ +__ALWAYS_STATIC_INLINE uint32_t __SSAT16(int32_t x, const uint32_t y) +{ + int32_t r = 0, s = 0; + + r = __SSAT((((int32_t)x << 16) >> 16), y) & (int32_t)0x0000FFFF; + s = __SSAT((((int32_t)x) >> 16), y) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned saturate. + \details This function enables you to saturate two signed 16-bit values to a selected unsigned range. + \param [in] x two signed 16-bit values to be saturated. + \param [in] y bit position for saturation, an integral constant expression in the range 1 to 16. + \return the saturation of the two signed 16-bit values, as non-negative values: + the saturation of the low halfword in val1, saturated to the bit position specified in + val2 and returned in the low halfword of the return value.\n + the saturation of the high halfword in val1, saturated to the bit position specified in + val2 and returned in the high halfword of the return value. + */ +__ALWAYS_STATIC_INLINE uint32_t __USAT16(uint32_t x, const uint32_t y) +{ + int32_t r = 0, s = 0; + + r = __IUSAT(((x << 16) >> 16), y) & 0x0000FFFF; + s = __IUSAT(((x) >> 16), y) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Quad 8-bit saturating addition. + \details This function enables you to perform four 8-bit integer additions, + saturating the results to the 8-bit signed integer range -2^7 <= x <= 2^7 - 1. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the saturated addition of the first byte of each operand in the first byte of the return value.\n + the saturated addition of the second byte of each operand in the second byte of the return value.\n + the saturated addition of the third byte of each operand in the third byte of the return value.\n + the saturated addition of the fourth byte of each operand in the fourth byte of the return value.\n + The returned results are saturated to the 8-bit signed integer range -2^7 <= x <= 2^7 - 1. + \remark + res[7:0] = val1[7:0] + val2[7:0] \n + res[15:8] = val1[15:8] + val2[15:8] \n + res[23:16] = val1[23:16] + val2[23:16] \n + res[31:24] = val1[31:24] + val2[31:24] + */ +__ALWAYS_STATIC_INLINE uint32_t __QADD8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = __SSAT(((((int32_t)x << 24) >> 24) + (((int32_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((int32_t)x << 16) >> 24) + (((int32_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((int32_t)x << 8) >> 24) + (((int32_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((int32_t)x) >> 24) + (((int32_t)y) >> 24)), 8) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r))); +} + +/** + \brief Quad 8-bit unsigned saturating addition. + \details This function enables you to perform four unsigned 8-bit integer additions, + saturating the results to the 8-bit unsigned integer range 0 < x < 2^8 - 1. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the saturated addition of the first byte of each operand in the first byte of the return value.\n + the saturated addition of the second byte of each operand in the second byte of the return value.\n + the saturated addition of the third byte of each operand in the third byte of the return value.\n + the saturated addition of the fourth byte of each operand in the fourth byte of the return value.\n + The returned results are saturated to the 8-bit signed integer range 0 <= x <= 2^8 - 1. + \remark + res[7:0] = val1[7:0] + val2[7:0] \n + res[15:8] = val1[15:8] + val2[15:8] \n + res[23:16] = val1[23:16] + val2[23:16] \n + res[31:24] = val1[31:24] + val2[31:24] + */ +__ALWAYS_STATIC_INLINE uint32_t __UQADD8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = __IUSAT((((x << 24) >> 24) + ((y << 24) >> 24)), 8) & 0x000000FF; + s = __IUSAT((((x << 16) >> 24) + ((y << 16) >> 24)), 8) & 0x000000FF; + t = __IUSAT((((x << 8) >> 24) + ((y << 8) >> 24)), 8) & 0x000000FF; + u = __IUSAT((((x) >> 24) + ((y) >> 24)), 8) & 0x000000FF; + + return ((u << 24) | (t << 16) | (s << 8) | (r)); +} + +/** + \brief Quad 8-bit signed addition. + \details This function performs four 8-bit signed integer additions. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the addition of the first bytes from each operand, in the first byte of the return value.\n + the addition of the second bytes of each operand, in the second byte of the return value.\n + the addition of the third bytes of each operand, in the third byte of the return value.\n + the addition of the fourth bytes of each operand, in the fourth byte of the return value. + \remark + res[7:0] = val1[7:0] + val2[7:0] \n + res[15:8] = val1[15:8] + val2[15:8] \n + res[23:16] = val1[23:16] + val2[23:16] \n + res[31:24] = val1[31:24] + val2[31:24] + */ +__ALWAYS_STATIC_INLINE uint32_t __SADD8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = ((((int32_t)x << 24) >> 24) + (((int32_t)y << 24) >> 24)) & (int32_t)0x000000FF; + s = ((((int32_t)x << 16) >> 24) + (((int32_t)y << 16) >> 24)) & (int32_t)0x000000FF; + t = ((((int32_t)x << 8) >> 24) + (((int32_t)y << 8) >> 24)) & (int32_t)0x000000FF; + u = ((((int32_t)x) >> 24) + (((int32_t)y) >> 24)) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r))); +} + +/** + \brief Quad 8-bit unsigned addition. + \details This function performs four unsigned 8-bit integer additions. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the addition of the first bytes from each operand, in the first byte of the return value.\n + the addition of the second bytes of each operand, in the second byte of the return value.\n + the addition of the third bytes of each operand, in the third byte of the return value.\n + the addition of the fourth bytes of each operand, in the fourth byte of the return value. + \remark + res[7:0] = val1[7:0] + val2[7:0] \n + res[15:8] = val1[15:8] + val2[15:8] \n + res[23:16] = val1[23:16] + val2[23:16] \n + res[31:24] = val1[31:24] + val2[31:24] + */ +__ALWAYS_STATIC_INLINE uint32_t __UADD8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = (((x << 24) >> 24) + ((y << 24) >> 24)) & 0x000000FF; + s = (((x << 16) >> 24) + ((y << 16) >> 24)) & 0x000000FF; + t = (((x << 8) >> 24) + ((y << 8) >> 24)) & 0x000000FF; + u = (((x) >> 24) + ((y) >> 24)) & 0x000000FF; + + return ((u << 24) | (t << 16) | (s << 8) | (r)); +} + +/** + \brief Quad 8-bit saturating subtract. + \details This function enables you to perform four 8-bit integer subtractions, + saturating the results to the 8-bit signed integer range -2^7 <= x <= 2^7 - 1. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the subtraction of the first byte of each operand in the first byte of the return value.\n + the subtraction of the second byte of each operand in the second byte of the return value.\n + the subtraction of the third byte of each operand in the third byte of the return value.\n + the subtraction of the fourth byte of each operand in the fourth byte of the return value.\n + The returned results are saturated to the 8-bit signed integer range -2^7 <= x <= 2^7 - 1. + \remark + res[7:0] = val1[7:0] - val2[7:0] \n + res[15:8] = val1[15:8] - val2[15:8] \n + res[23:16] = val1[23:16] - val2[23:16] \n + res[31:24] = val1[31:24] - val2[31:24] + */ +__ALWAYS_STATIC_INLINE uint32_t __QSUB8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = __SSAT(((((int32_t)x << 24) >> 24) - (((int32_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((int32_t)x << 16) >> 24) - (((int32_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((int32_t)x << 8) >> 24) - (((int32_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((int32_t)x) >> 24) - (((int32_t)y) >> 24)), 8) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r))); +} + +/** + \brief Quad 8-bit unsigned saturating subtraction. + \details This function enables you to perform four unsigned 8-bit integer subtractions, + saturating the results to the 8-bit unsigned integer range 0 < x < 2^8 - 1. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the subtraction of the first byte of each operand in the first byte of the return value.\n + the subtraction of the second byte of each operand in the second byte of the return value.\n + the subtraction of the third byte of each operand in the third byte of the return value.\n + the subtraction of the fourth byte of each operand in the fourth byte of the return value.\n + The returned results are saturated to the 8-bit unsigned integer range 0 <= x <= 2^8 - 1. + \remark + res[7:0] = val1[7:0] - val2[7:0] \n + res[15:8] = val1[15:8] - val2[15:8] \n + res[23:16] = val1[23:16] - val2[23:16] \n + res[31:24] = val1[31:24] - val2[31:24] + */ +__ALWAYS_STATIC_INLINE uint32_t __UQSUB8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = __IUSAT((((x << 24) >> 24) - ((y << 24) >> 24)), 8) & 0x000000FF; + s = __IUSAT((((x << 16) >> 24) - ((y << 16) >> 24)), 8) & 0x000000FF; + t = __IUSAT((((x << 8) >> 24) - ((y << 8) >> 24)), 8) & 0x000000FF; + u = __IUSAT((((x) >> 24) - ((y) >> 24)), 8) & 0x000000FF; + + return ((u << 24) | (t << 16) | (s << 8) | (r)); +} + +/** + \brief Quad 8-bit signed subtraction. + \details This function enables you to perform four 8-bit signed integer subtractions. + \param [in] x first four 8-bit operands of each subtraction. + \param [in] y second four 8-bit operands of each subtraction. + \return the subtraction of the first bytes from each operand, in the first byte of the return value.\n + the subtraction of the second bytes of each operand, in the second byte of the return value.\n + the subtraction of the third bytes of each operand, in the third byte of the return value.\n + the subtraction of the fourth bytes of each operand, in the fourth byte of the return value. + \remark + res[7:0] = val1[7:0] - val2[7:0] \n + res[15:8] = val1[15:8] - val2[15:8] \n + res[23:16] = val1[23:16] - val2[23:16] \n + res[31:24] = val1[31:24] - val2[31:24] + */ +__ALWAYS_STATIC_INLINE uint32_t __SSUB8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = ((((int32_t)x << 24) >> 24) - (((int32_t)y << 24) >> 24)) & (int32_t)0x000000FF; + s = ((((int32_t)x << 16) >> 24) - (((int32_t)y << 16) >> 24)) & (int32_t)0x000000FF; + t = ((((int32_t)x << 8) >> 24) - (((int32_t)y << 8) >> 24)) & (int32_t)0x000000FF; + u = ((((int32_t)x) >> 24) - (((int32_t)y) >> 24)) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r))); +} + +/** + \brief Quad 8-bit unsigned subtract. + \details This function enables you to perform four 8-bit unsigned integer subtractions. + \param [in] x first four 8-bit operands of each subtraction. + \param [in] y second four 8-bit operands of each subtraction. + \return the subtraction of the first bytes from each operand, in the first byte of the return value.\n + the subtraction of the second bytes of each operand, in the second byte of the return value.\n + the subtraction of the third bytes of each operand, in the third byte of the return value.\n + the subtraction of the fourth bytes of each operand, in the fourth byte of the return value. + \remark + res[7:0] = val1[7:0] - val2[7:0] \n + res[15:8] = val1[15:8] - val2[15:8] \n + res[23:16] = val1[23:16] - val2[23:16] \n + res[31:24] = val1[31:24] - val2[31:24] + */ +__ALWAYS_STATIC_INLINE uint32_t __USUB8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = (((x << 24) >> 24) - ((y << 24) >> 24)) & 0x000000FF; + s = (((x << 16) >> 24) - ((y << 16) >> 24)) & 0x000000FF; + t = (((x << 8) >> 24) - ((y << 8) >> 24)) & 0x000000FF; + u = (((x) >> 24) - ((y) >> 24)) & 0x000000FF; + + return ((u << 24) | (t << 16) | (s << 8) | (r)); +} + +/** + \brief Unsigned sum of quad 8-bit unsigned absolute difference. + \details This function enables you to perform four unsigned 8-bit subtractions, and add the absolute values + of the differences together, returning the result as a single unsigned integer. + \param [in] x first four 8-bit operands of each subtraction. + \param [in] y second four 8-bit operands of each subtraction. + \return the subtraction of the first bytes from each operand, in the first byte of the return value.\n + the subtraction of the second bytes of each operand, in the second byte of the return value.\n + the subtraction of the third bytes of each operand, in the third byte of the return value.\n + the subtraction of the fourth bytes of each operand, in the fourth byte of the return value.\n + The sum is returned as a single unsigned integer. + \remark + absdiff1 = val1[7:0] - val2[7:0] \n + absdiff2 = val1[15:8] - val2[15:8] \n + absdiff3 = val1[23:16] - val2[23:16] \n + absdiff4 = val1[31:24] - val2[31:24] \n + res[31:0] = absdiff1 + absdiff2 + absdiff3 + absdiff4 + */ +__ALWAYS_STATIC_INLINE uint32_t __USAD8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = (((x << 24) >> 24) - ((y << 24) >> 24)) & 0x000000FF; + s = (((x << 16) >> 24) - ((y << 16) >> 24)) & 0x000000FF; + t = (((x << 8) >> 24) - ((y << 8) >> 24)) & 0x000000FF; + u = (((x) >> 24) - ((y) >> 24)) & 0x000000FF; + + return (u + t + s + r); +} + +/** + \brief Unsigned sum of quad 8-bit unsigned absolute difference with 32-bit accumulate. + \details This function enables you to perform four unsigned 8-bit subtractions, and add the absolute values + of the differences to a 32-bit accumulate operand. + \param [in] x first four 8-bit operands of each subtraction. + \param [in] y second four 8-bit operands of each subtraction. + \param [in] sum accumulation value. + \return the sum of the absolute differences of the following bytes, added to the accumulation value: + the subtraction of the first bytes from each operand, in the first byte of the return value.\n + the subtraction of the second bytes of each operand, in the second byte of the return value.\n + the subtraction of the third bytes of each operand, in the third byte of the return value.\n + the subtraction of the fourth bytes of each operand, in the fourth byte of the return value. + \remark + absdiff1 = val1[7:0] - val2[7:0] \n + absdiff2 = val1[15:8] - val2[15:8] \n + absdiff3 = val1[23:16] - val2[23:16] \n + absdiff4 = val1[31:24] - val2[31:24] \n + sum = absdiff1 + absdiff2 + absdiff3 + absdiff4 \n + res[31:0] = sum[31:0] + val3[31:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __USADA8(uint32_t x, uint32_t y, uint32_t sum) +{ + int32_t r, s, t, u; + +#ifdef __cplusplus + r = (abs((long long)((x << 24) >> 24) - ((y << 24) >> 24))) & 0x000000FF; + s = (abs((long long)((x << 16) >> 24) - ((y << 16) >> 24))) & 0x000000FF; + t = (abs((long long)((x << 8) >> 24) - ((y << 8) >> 24))) & 0x000000FF; + u = (abs((long long)((x) >> 24) - ((y) >> 24))) & 0x000000FF; +#else + r = (abs(((x << 24) >> 24) - ((y << 24) >> 24))) & 0x000000FF; + s = (abs(((x << 16) >> 24) - ((y << 16) >> 24))) & 0x000000FF; + t = (abs(((x << 8) >> 24) - ((y << 8) >> 24))) & 0x000000FF; + u = (abs(((x) >> 24) - ((y) >> 24))) & 0x000000FF; +#endif + return (u + t + s + r + sum); +} + +/** + \brief Dual 16-bit saturating addition. + \details This function enables you to perform two 16-bit integer arithmetic additions in parallel, + saturating the results to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the saturated addition of the low halfwords, in the low halfword of the return value.\n + the saturated addition of the high halfwords, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \remark + res[15:0] = val1[15:0] + val2[15:0] \n + res[31:16] = val1[31:16] + val2[31:16] + */ +__ALWAYS_STATIC_INLINE uint32_t __QADD16(uint32_t x, uint32_t y) +{ + int32_t r = 0, s = 0; + + r = __SSAT(((((int32_t)x << 16) >> 16) + (((int32_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((int32_t)x) >> 16) + (((int32_t)y) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned saturating addition. + \details This function enables you to perform two unsigned 16-bit integer additions, saturating + the results to the 16-bit unsigned integer range 0 < x < 2^16 - 1. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the saturated addition of the low halfwords, in the low halfword of the return value.\n + the saturated addition of the high halfwords, in the high halfword of the return value.\n + The results are saturated to the 16-bit unsigned integer range 0 < x < 2^16 - 1. + \remark + res[15:0] = val1[15:0] + val2[15:0] \n + res[31:16] = val1[31:16] + val2[31:16] + */ +__ALWAYS_STATIC_INLINE uint32_t __UQADD16(uint32_t x, uint32_t y) +{ + int32_t r = 0, s = 0; + + r = __IUSAT((((x << 16) >> 16) + ((y << 16) >> 16)), 16) & 0x0000FFFF; + s = __IUSAT((((x) >> 16) + ((y) >> 16)), 16) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit signed addition. + \details This function enables you to perform two 16-bit signed integer additions. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the addition of the low halfwords in the low halfword of the return value.\n + the addition of the high halfwords in the high halfword of the return value. + \remark + res[15:0] = val1[15:0] + val2[15:0] \n + res[31:16] = val1[31:16] + val2[31:16] + */ +__ALWAYS_STATIC_INLINE uint32_t __SADD16(uint32_t x, uint32_t y) +{ + int32_t r = 0, s = 0; + + r = ((((int32_t)x << 16) >> 16) + (((int32_t)y << 16) >> 16)) & (int32_t)0x0000FFFF; + s = ((((int32_t)x) >> 16) + (((int32_t)y) >> 16)) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned addition + \details This function enables you to perform two 16-bit unsigned integer additions. + \param [in] x first two 16-bit summands for each addition. + \param [in] y second two 16-bit summands for each addition. + \return the addition of the low halfwords in the low halfword of the return value.\n + the addition of the high halfwords in the high halfword of the return value. + \remark + res[15:0] = val1[15:0] + val2[15:0] \n + res[31:16] = val1[31:16] + val2[31:16] + */ +__ALWAYS_STATIC_INLINE uint32_t __UADD16(uint32_t x, uint32_t y) +{ + int32_t r = 0, s = 0; + + r = (((x << 16) >> 16) + ((y << 16) >> 16)) & 0x0000FFFF; + s = (((x) >> 16) + ((y) >> 16)) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + + +/** + \brief Dual 16-bit signed addition with halved results. + \details This function enables you to perform two signed 16-bit integer additions, halving the results. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the halved addition of the low halfwords, in the low halfword of the return value.\n + the halved addition of the high halfwords, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] + val2[15:0]) >> 1 \n + res[31:16] = (val1[31:16] + val2[31:16]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __SHADD16(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = (((((int32_t)x << 16) >> 16) + (((int32_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((int32_t)x) >> 16) + (((int32_t)y) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned addition with halved results. + \details This function enables you to perform two unsigned 16-bit integer additions, halving the results. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the halved addition of the low halfwords, in the low halfword of the return value.\n + the halved addition of the high halfwords, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] + val2[15:0]) >> 1 \n + res[31:16] = (val1[31:16] + val2[31:16]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __UHADD16(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = ((((x << 16) >> 16) + ((y << 16) >> 16)) >> 1) & 0x0000FFFF; + s = ((((x) >> 16) + ((y) >> 16)) >> 1) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Quad 8-bit signed addition with halved results. + \details This function enables you to perform four signed 8-bit integer additions, halving the results. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the halved addition of the first bytes from each operand, in the first byte of the return value.\n + the halved addition of the second bytes from each operand, in the second byte of the return value.\n + the halved addition of the third bytes from each operand, in the third byte of the return value.\n + the halved addition of the fourth bytes from each operand, in the fourth byte of the return value. + \remark + res[7:0] = (val1[7:0] + val2[7:0] ) >> 1 \n + res[15:8] = (val1[15:8] + val2[15:8] ) >> 1 \n + res[23:16] = (val1[23:16] + val2[23:16]) >> 1 \n + res[31:24] = (val1[31:24] + val2[31:24]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __SHADD8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = (((((int32_t)x << 24) >> 24) + (((int32_t)y << 24) >> 24)) >> 1) & (int32_t)0x000000FF; + s = (((((int32_t)x << 16) >> 24) + (((int32_t)y << 16) >> 24)) >> 1) & (int32_t)0x000000FF; + t = (((((int32_t)x << 8) >> 24) + (((int32_t)y << 8) >> 24)) >> 1) & (int32_t)0x000000FF; + u = (((((int32_t)x) >> 24) + (((int32_t)y) >> 24)) >> 1) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r))); +} + +/** + \brief Quad 8-bit unsigned addition with halved results. + \details This function enables you to perform four unsigned 8-bit integer additions, halving the results. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the halved addition of the first bytes from each operand, in the first byte of the return value.\n + the halved addition of the second bytes from each operand, in the second byte of the return value.\n + the halved addition of the third bytes from each operand, in the third byte of the return value.\n + the halved addition of the fourth bytes from each operand, in the fourth byte of the return value. + \remark + res[7:0] = (val1[7:0] + val2[7:0] ) >> 1 \n + res[15:8] = (val1[15:8] + val2[15:8] ) >> 1 \n + res[23:16] = (val1[23:16] + val2[23:16]) >> 1 \n + res[31:24] = (val1[31:24] + val2[31:24]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __UHADD8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = ((((x << 24) >> 24) + ((y << 24) >> 24)) >> 1) & 0x000000FF; + s = ((((x << 16) >> 24) + ((y << 16) >> 24)) >> 1) & 0x000000FF; + t = ((((x << 8) >> 24) + ((y << 8) >> 24)) >> 1) & 0x000000FF; + u = ((((x) >> 24) + ((y) >> 24)) >> 1) & 0x000000FF; + + return ((u << 24) | (t << 16) | (s << 8) | (r)); +} + +/** + \brief Dual 16-bit saturating subtract. + \details This function enables you to perform two 16-bit integer subtractions in parallel, + saturating the results to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the saturated subtraction of the low halfwords, in the low halfword of the return value.\n + the saturated subtraction of the high halfwords, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \remark + res[15:0] = val1[15:0] - val2[15:0] \n + res[31:16] = val1[31:16] - val2[31:16] + */ +__ALWAYS_STATIC_INLINE uint32_t __QSUB16(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = __SSAT(((((int32_t)x << 16) >> 16) - (((int32_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((int32_t)x) >> 16) - (((int32_t)y) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned saturating subtraction. + \details This function enables you to perform two unsigned 16-bit integer subtractions, + saturating the results to the 16-bit unsigned integer range 0 < x < 2^16 - 1. + \param [in] x first two 16-bit operands for each subtraction. + \param [in] y second two 16-bit operands for each subtraction. + \return the saturated subtraction of the low halfwords, in the low halfword of the return value.\n + the saturated subtraction of the high halfwords, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \remark + res[15:0] = val1[15:0] - val2[15:0] \n + res[31:16] = val1[31:16] - val2[31:16] + */ +__ALWAYS_STATIC_INLINE uint32_t __UQSUB16(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = __IUSAT((((x << 16) >> 16) - ((y << 16) >> 16)), 16) & 0x0000FFFF; + s = __IUSAT((((x) >> 16) - ((y) >> 16)), 16) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit signed subtraction. + \details This function enables you to perform two 16-bit signed integer subtractions. + \param [in] x first two 16-bit operands of each subtraction. + \param [in] y second two 16-bit operands of each subtraction. + \return the subtraction of the low halfword in the second operand from the low + halfword in the first operand, in the low halfword of the return value. \n + the subtraction of the high halfword in the second operand from the high + halfword in the first operand, in the high halfword of the return value. + \remark + res[15:0] = val1[15:0] - val2[15:0] \n + res[31:16] = val1[31:16] - val2[31:16] + */ +__ALWAYS_STATIC_INLINE uint32_t __SSUB16(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = ((((int32_t)x << 16) >> 16) - (((int32_t)y << 16) >> 16)) & (int32_t)0x0000FFFF; + s = ((((int32_t)x) >> 16) - (((int32_t)y) >> 16)) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned subtract. + \details This function enables you to perform two 16-bit unsigned integer subtractions. + \param [in] x first two 16-bit operands of each subtraction. + \param [in] y second two 16-bit operands of each subtraction. + \return the subtraction of the low halfword in the second operand from the low + halfword in the first operand, in the low halfword of the return value. \n + the subtraction of the high halfword in the second operand from the high + halfword in the first operand, in the high halfword of the return value. + \remark + res[15:0] = val1[15:0] - val2[15:0] \n + res[31:16] = val1[31:16] - val2[31:16] + */ +__ALWAYS_STATIC_INLINE uint32_t __USUB16(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = (((x << 16) >> 16) - ((y << 16) >> 16)) & 0x0000FFFF; + s = (((x) >> 16) - ((y) >> 16)) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit signed subtraction with halved results. + \details This function enables you to perform two signed 16-bit integer subtractions, halving the results. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the halved subtraction of the low halfwords, in the low halfword of the return value.\n + the halved subtraction of the high halfwords, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] - val2[15:0]) >> 1 \n + res[31:16] = (val1[31:16] - val2[31:16]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __SHSUB16(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = (((((int32_t)x << 16) >> 16) - (((int32_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((int32_t)x) >> 16) - (((int32_t)y) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned subtraction with halved results. + \details This function enables you to perform two unsigned 16-bit integer subtractions, halving the results. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the halved subtraction of the low halfwords, in the low halfword of the return value.\n + the halved subtraction of the high halfwords, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] - val2[15:0]) >> 1 \n + res[31:16] = (val1[31:16] - val2[31:16]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __UHSUB16(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = ((((x << 16) >> 16) - ((y << 16) >> 16)) >> 1) & 0x0000FFFF; + s = ((((x) >> 16) - ((y) >> 16)) >> 1) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Quad 8-bit signed addition with halved results. + \details This function enables you to perform four signed 8-bit integer subtractions, halving the results. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the halved subtraction of the first bytes from each operand, in the first byte of the return value.\n + the halved subtraction of the second bytes from each operand, in the second byte of the return value.\n + the halved subtraction of the third bytes from each operand, in the third byte of the return value.\n + the halved subtraction of the fourth bytes from each operand, in the fourth byte of the return value. + \remark + res[7:0] = (val1[7:0] - val2[7:0] ) >> 1 \n + res[15:8] = (val1[15:8] - val2[15:8] ) >> 1 \n + res[23:16] = (val1[23:16] - val2[23:16]) >> 1 \n + res[31:24] = (val1[31:24] - val2[31:24]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __SHSUB8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = (((((int32_t)x << 24) >> 24) - (((int32_t)y << 24) >> 24)) >> 1) & (int32_t)0x000000FF; + s = (((((int32_t)x << 16) >> 24) - (((int32_t)y << 16) >> 24)) >> 1) & (int32_t)0x000000FF; + t = (((((int32_t)x << 8) >> 24) - (((int32_t)y << 8) >> 24)) >> 1) & (int32_t)0x000000FF; + u = (((((int32_t)x) >> 24) - (((int32_t)y) >> 24)) >> 1) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r))); +} + +/** + \brief Quad 8-bit unsigned subtraction with halved results. + \details This function enables you to perform four unsigned 8-bit integer subtractions, halving the results. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the halved subtraction of the first bytes from each operand, in the first byte of the return value.\n + the halved subtraction of the second bytes from each operand, in the second byte of the return value.\n + the halved subtraction of the third bytes from each operand, in the third byte of the return value.\n + the halved subtraction of the fourth bytes from each operand, in the fourth byte of the return value. + \remark + res[7:0] = (val1[7:0] - val2[7:0] ) >> 1 \n + res[15:8] = (val1[15:8] - val2[15:8] ) >> 1 \n + res[23:16] = (val1[23:16] - val2[23:16]) >> 1 \n + res[31:24] = (val1[31:24] - val2[31:24]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __UHSUB8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = ((((x << 24) >> 24) - ((y << 24) >> 24)) >> 1) & 0x000000FF; + s = ((((x << 16) >> 24) - ((y << 16) >> 24)) >> 1) & 0x000000FF; + t = ((((x << 8) >> 24) - ((y << 8) >> 24)) >> 1) & 0x000000FF; + u = ((((x) >> 24) - ((y) >> 24)) >> 1) & 0x000000FF; + + return ((u << 24) | (t << 16) | (s << 8) | (r)); +} + +/** + \brief Dual 16-bit add and subtract with exchange. + \details This function enables you to exchange the halfwords of the one operand, + then add the high halfwords and subtract the low halfwords, + saturating the results to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \param [in] x first operand for the subtraction in the low halfword, + and the first operand for the addition in the high halfword. + \param [in] y second operand for the subtraction in the high halfword, + and the second operand for the addition in the low halfword. + \return the saturated subtraction of the high halfword in the second operand from the + low halfword in the first operand, in the low halfword of the return value.\n + the saturated addition of the high halfword in the first operand and the + low halfword in the second operand, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \remark + res[15:0] = val1[15:0] - val2[31:16] \n + res[31:16] = val1[31:16] + val2[15:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __QASX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = __SSAT(((((int32_t)x << 16) >> 16) - (((int32_t)y) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((int32_t)x) >> 16) + (((int32_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned saturating addition and subtraction with exchange. + \details This function enables you to exchange the halfwords of the second operand and + perform one unsigned 16-bit integer addition and one unsigned 16-bit subtraction, + saturating the results to the 16-bit unsigned integer range 0 <= x <= 2^16 - 1. + \param [in] x first operand for the subtraction in the low halfword, + and the first operand for the addition in the high halfword. + \param [in] y second operand for the subtraction in the high halfword, + and the second operand for the addition in the low halfword. + \return the saturated subtraction of the high halfword in the second operand from the + low halfword in the first operand, in the low halfword of the return value.\n + the saturated addition of the high halfword in the first operand and the + low halfword in the second operand, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit unsigned integer range 0 <= x <= 2^16 - 1. + \remark + res[15:0] = val1[15:0] - val2[31:16] \n + res[31:16] = val1[31:16] + val2[15:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __UQASX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = __IUSAT((((x << 16) >> 16) - ((y) >> 16)), 16) & 0x0000FFFF; + s = __IUSAT((((x) >> 16) + ((y << 16) >> 16)), 16) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit addition and subtraction with exchange. + \details It enables you to exchange the halfwords of the second operand, add the high halfwords + and subtract the low halfwords. + \param [in] x first operand for the subtraction in the low halfword, + and the first operand for the addition in the high halfword. + \param [in] y second operand for the subtraction in the high halfword, + and the second operand for the addition in the low halfword. + \return the subtraction of the high halfword in the second operand from the + low halfword in the first operand, in the low halfword of the return value.\n + the addition of the high halfword in the first operand and the + low halfword in the second operand, in the high halfword of the return value. + \remark + res[15:0] = val1[15:0] - val2[31:16] \n + res[31:16] = val1[31:16] + val2[15:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __SASX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = ((((int32_t)x << 16) >> 16) - (((int32_t)y) >> 16)) & (int32_t)0x0000FFFF; + s = ((((int32_t)x) >> 16) + (((int32_t)y << 16) >> 16)) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned addition and subtraction with exchange. + \details This function enables you to exchange the two halfwords of the second operand, + add the high halfwords and subtract the low halfwords. + \param [in] x first operand for the subtraction in the low halfword, + and the first operand for the addition in the high halfword. + \param [in] y second operand for the subtraction in the high halfword, + and the second operand for the addition in the low halfword. + \return the subtraction of the high halfword in the second operand from the + low halfword in the first operand, in the low halfword of the return value.\n + the addition of the high halfword in the first operand and the + low halfword in the second operand, in the high halfword of the return value. + \remark + res[15:0] = val1[15:0] - val2[31:16] \n + res[31:16] = val1[31:16] + val2[15:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __UASX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = (((x << 16) >> 16) - ((y) >> 16)) & 0x0000FFFF; + s = (((x) >> 16) + ((y << 16) >> 16)) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit signed addition and subtraction with halved results. + \details This function enables you to exchange the two halfwords of one operand, perform one + signed 16-bit integer addition and one signed 16-bit subtraction, and halve the results. + \param [in] x first 16-bit operands. + \param [in] y second 16-bit operands. + \return the halved subtraction of the high halfword in the second operand from the + low halfword in the first operand, in the low halfword of the return value.\n + the halved addition of the low halfword in the second operand from the high + halfword in the first operand, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] - val2[31:16]) >> 1 \n + res[31:16] = (val1[31:16] + val2[15:0]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __SHASX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = (((((int32_t)x << 16) >> 16) - (((int32_t)y) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((int32_t)x) >> 16) + (((int32_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned addition and subtraction with halved results and exchange. + \details This function enables you to exchange the halfwords of the second operand, + add the high halfwords and subtract the low halfwords, halving the results. + \param [in] x first operand for the subtraction in the low halfword, and + the first operand for the addition in the high halfword. + \param [in] y second operand for the subtraction in the high halfword, and + the second operand for the addition in the low halfword. + \return the halved subtraction of the high halfword in the second operand from the + low halfword in the first operand, in the low halfword of the return value.\n + the halved addition of the low halfword in the second operand from the high + halfword in the first operand, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] - val2[31:16]) >> 1 \n + res[31:16] = (val1[31:16] + val2[15:0]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __UHASX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = ((((x << 16) >> 16) - ((y) >> 16)) >> 1) & 0x0000FFFF; + s = ((((x) >> 16) + ((y << 16) >> 16)) >> 1) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit subtract and add with exchange. + \details This function enables you to exchange the halfwords of one operand, + then subtract the high halfwords and add the low halfwords, + saturating the results to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \param [in] x first operand for the addition in the low halfword, + and the first operand for the subtraction in the high halfword. + \param [in] y second operand for the addition in the high halfword, + and the second operand for the subtraction in the low halfword. + \return the saturated addition of the low halfword of the first operand and the high + halfword of the second operand, in the low halfword of the return value.\n + the saturated subtraction of the low halfword of the second operand from the + high halfword of the first operand, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \remark + res[15:0] = val1[15:0] + val2[31:16] \n + res[31:16] = val1[31:16] - val2[15:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __QSAX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = __SSAT(((((int32_t)x << 16) >> 16) + (((int32_t)y) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((int32_t)x) >> 16) - (((int32_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned saturating subtraction and addition with exchange. + \details This function enables you to exchange the halfwords of the second operand and perform + one unsigned 16-bit integer subtraction and one unsigned 16-bit addition, saturating + the results to the 16-bit unsigned integer range 0 <= x <= 2^16 - 1. + \param [in] x first operand for the addition in the low halfword, + and the first operand for the subtraction in the high halfword. + \param [in] y second operand for the addition in the high halfword, + and the second operand for the subtraction in the low halfword. + \return the saturated addition of the low halfword of the first operand and the high + halfword of the second operand, in the low halfword of the return value.\n + the saturated subtraction of the low halfword of the second operand from the + high halfword of the first operand, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit unsigned integer range 0 <= x <= 2^16 - 1. + \remark + res[15:0] = val1[15:0] + val2[31:16] \n + res[31:16] = val1[31:16] - val2[15:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __UQSAX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = __IUSAT((((x << 16) >> 16) + ((y) >> 16)), 16) & 0x0000FFFF; + s = __IUSAT((((x) >> 16) - ((y << 16) >> 16)), 16) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit unsigned subtract and add with exchange. + \details This function enables you to exchange the halfwords of the second operand, + subtract the high halfwords and add the low halfwords. + \param [in] x first operand for the addition in the low halfword, + and the first operand for the subtraction in the high halfword. + \param [in] y second operand for the addition in the high halfword, + and the second operand for the subtraction in the low halfword. + \return the addition of the low halfword of the first operand and the high + halfword of the second operand, in the low halfword of the return value.\n + the subtraction of the low halfword of the second operand from the + high halfword of the first operand, in the high halfword of the return value.\n + \remark + res[15:0] = val1[15:0] + val2[31:16] \n + res[31:16] = val1[31:16] - val2[15:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __USAX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = (((x << 16) >> 16) + ((y) >> 16)) & 0x0000FFFF; + s = (((x) >> 16) - ((y << 16) >> 16)) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit signed subtraction and addition with exchange. + \details This function enables you to exchange the two halfwords of one operand and perform one + 16-bit integer subtraction and one 16-bit addition. + \param [in] x first operand for the addition in the low halfword, and the first operand + for the subtraction in the high halfword. + \param [in] y second operand for the addition in the high halfword, and the second + operand for the subtraction in the low halfword. + \return the addition of the low halfword of the first operand and the high + halfword of the second operand, in the low halfword of the return value.\n + the subtraction of the low halfword of the second operand from the + high halfword of the first operand, in the high halfword of the return value.\n + \remark + res[15:0] = val1[15:0] + val2[31:16] \n + res[31:16] = val1[31:16] - val2[15:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __SSAX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = ((((int32_t)x << 16) >> 16) + (((int32_t)y) >> 16)) & (int32_t)0x0000FFFF; + s = ((((int32_t)x) >> 16) - (((int32_t)y << 16) >> 16)) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + + +/** + \brief Dual 16-bit signed subtraction and addition with halved results. + \details This function enables you to exchange the two halfwords of one operand, perform one signed + 16-bit integer subtraction and one signed 16-bit addition, and halve the results. + \param [in] x first 16-bit operands. + \param [in] y second 16-bit operands. + \return the halved addition of the low halfword in the first operand and the + high halfword in the second operand, in the low halfword of the return value.\n + the halved subtraction of the low halfword in the second operand from the + high halfword in the first operand, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] + val2[31:16]) >> 1 \n + res[31:16] = (val1[31:16] - val2[15:0]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __SHSAX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = (((((int32_t)x << 16) >> 16) + (((int32_t)y) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((int32_t)x) >> 16) - (((int32_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned subtraction and addition with halved results and exchange. + \details This function enables you to exchange the halfwords of the second operand, + subtract the high halfwords and add the low halfwords, halving the results. + \param [in] x first operand for the addition in the low halfword, and + the first operand for the subtraction in the high halfword. + \param [in] y second operand for the addition in the high halfword, and + the second operand for the subtraction in the low halfword. + \return the halved addition of the low halfword in the first operand and the + high halfword in the second operand, in the low halfword of the return value.\n + the halved subtraction of the low halfword in the second operand from the + high halfword in the first operand, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] + val2[31:16]) >> 1 \n + res[31:16] = (val1[31:16] - val2[15:0]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __UHSAX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = ((((x << 16) >> 16) + ((y) >> 16)) >> 1) & 0x0000FFFF; + s = ((((x) >> 16) - ((y << 16) >> 16)) >> 1) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit signed multiply with exchange returning difference. + \details This function enables you to perform two 16-bit signed multiplications, subtracting + one of the products from the other. The halfwords of the second operand are exchanged + before performing the arithmetic. This produces top * bottom and bottom * top multiplication. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \return the difference of the products of the two 16-bit signed multiplications. + \remark + p1 = val1[15:0] * val2[31:16] \n + p2 = val1[31:16] * val2[15:0] \n + res[31:0] = p1 - p2 + */ +__ALWAYS_STATIC_INLINE uint32_t __SMUSDX(uint32_t x, uint32_t y) +{ + return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) - + ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)))); +} + +/** + \brief Sum of dual 16-bit signed multiply with exchange. + \details This function enables you to perform two 16-bit signed multiplications with exchanged + halfwords of the second operand, adding the products together. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \return the sum of the products of the two 16-bit signed multiplications with exchanged halfwords of the second operand. + \remark + p1 = val1[15:0] * val2[31:16] \n + p2 = val1[31:16] * val2[15:0] \n + res[31:0] = p1 + p2 + */ +__ALWAYS_STATIC_INLINE uint32_t __SMUADX(uint32_t x, uint32_t y) +{ + return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) + + ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)))); +} + + +/** + \brief Saturating add. + \details This function enables you to obtain the saturating add of two integers. + \param [in] x first summand of the saturating add operation. + \param [in] y second summand of the saturating add operation. + \return the saturating addition of val1 and val2. + \remark + res[31:0] = SAT(val1 + SAT(val2)) + */ +__ALWAYS_STATIC_INLINE int32_t __QADD(int32_t x, int32_t y) +{ + int32_t result; + + if (y >= 0) { + if (x + y >= x) { + result = x + y; + } else { + result = 0x7FFFFFFF; + } + } else { + if (x + y < x) { + result = x + y; + } else { + result = 0x80000000; + } + } + + return result; +} + +/** + \brief Saturating subtract. + \details This function enables you to obtain the saturating add of two integers. + \param [in] x first summand of the saturating add operation. + \param [in] y second summand of the saturating add operation. + \return the saturating addition of val1 and val2. + \remark + res[31:0] = SAT(val1 - SAT(val2)) + */ +__ALWAYS_STATIC_INLINE int32_t __QSUB(int32_t x, int32_t y) +{ + int64_t tmp; + int32_t result; + + tmp = (int64_t)x - (int64_t)y; + + if (tmp > 0x7fffffff) { + tmp = 0x7fffffff; + } else if (tmp < (-2147483647 - 1)) { + tmp = -2147483647 - 1; + } + + result = tmp; + return result; +} + +/** + \brief Dual 16-bit signed multiply with single 32-bit accumulator. + \details This function enables you to perform two signed 16-bit multiplications, + adding both results to a 32-bit accumulate operand. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the product of each multiplication added to the accumulate value, as a 32-bit integer. + \remark + p1 = val1[15:0] * val2[15:0] \n + p2 = val1[31:16] * val2[31:16] \n + res[31:0] = p1 + p2 + val3[31:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __SMLAD(uint32_t x, uint32_t y, uint32_t sum) +{ + return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) + + ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)) + + (((int32_t)sum)))); +} + +/** + \brief Pre-exchanged dual 16-bit signed multiply with single 32-bit accumulator. + \details This function enables you to perform two signed 16-bit multiplications with exchanged + halfwords of the second operand, adding both results to a 32-bit accumulate operand. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the product of each multiplication with exchanged halfwords of the second + operand added to the accumulate value, as a 32-bit integer. + \remark + p1 = val1[15:0] * val2[31:16] \n + p2 = val1[31:16] * val2[15:0] \n + res[31:0] = p1 + p2 + val3[31:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __SMLADX(uint32_t x, uint32_t y, uint32_t sum) +{ + return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) + + ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)) + + (((int32_t)sum)))); +} + +/** + \brief Dual 16-bit signed multiply with exchange subtract with 32-bit accumulate. + \details This function enables you to perform two 16-bit signed multiplications, take the + difference of the products, subtracting the high halfword product from the low + halfword product, and add the difference to a 32-bit accumulate operand. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the difference of the product of each multiplication, added to the accumulate value. + \remark + p1 = val1[15:0] * val2[15:0] \n + p2 = val1[31:16] * val2[31:16] \n + res[31:0] = p1 - p2 + val3[31:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __SMLSD(uint32_t x, uint32_t y, uint32_t sum) +{ + return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) - + ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)) + + (((int32_t)sum)))); +} + +/** + \brief Dual 16-bit signed multiply with exchange subtract with 32-bit accumulate. + \details This function enables you to exchange the halfwords in the second operand, then perform two 16-bit + signed multiplications. The difference of the products is added to a 32-bit accumulate operand. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the difference of the product of each multiplication, added to the accumulate value. + \remark + p1 = val1[15:0] * val2[31:16] \n + p2 = val1[31:16] * val2[15:0] \n + res[31:0] = p1 - p2 + val3[31:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __SMLSDX(uint32_t x, uint32_t y, uint32_t sum) +{ + return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) - + ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)) + + (((int32_t)sum)))); +} + +/** + \brief Dual 16-bit signed multiply with single 64-bit accumulator. + \details This function enables you to perform two signed 16-bit multiplications, adding both results + to a 64-bit accumulate operand. Overflow is only possible as a result of the 64-bit addition. + This overflow is not detected if it occurs. Instead, the result wraps around modulo2^64. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the product of each multiplication added to the accumulate value. + \remark + p1 = val1[15:0] * val2[15:0] \n + p2 = val1[31:16] * val2[31:16] \n + sum = p1 + p2 + val3[63:32][31:0] \n + res[63:32] = sum[63:32] \n + res[31:0] = sum[31:0] + */ +__ALWAYS_STATIC_INLINE uint64_t __SMLALD(uint32_t x, uint32_t y, uint64_t sum) +{ + return ((uint64_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) + + ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)) + + (((uint64_t)sum)))); +} + +/** + \brief Dual 16-bit signed multiply with exchange with single 64-bit accumulator. + \details This function enables you to exchange the halfwords of the second operand, and perform two + signed 16-bit multiplications, adding both results to a 64-bit accumulate operand. Overflow + is only possible as a result of the 64-bit addition. This overflow is not detected if it occurs. + Instead, the result wraps around modulo2^64. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the product of each multiplication added to the accumulate value. + \remark + p1 = val1[15:0] * val2[31:16] \n + p2 = val1[31:16] * val2[15:0] \n + sum = p1 + p2 + val3[63:32][31:0] \n + res[63:32] = sum[63:32] \n + res[31:0] = sum[31:0] + */ +__ALWAYS_STATIC_INLINE uint64_t __SMLALDX(uint32_t x, uint32_t y, uint64_t sum) +{ + return ((uint64_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) + + ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)) + + (((uint64_t)sum)))); +} + +/** + \brief dual 16-bit signed multiply subtract with 64-bit accumulate. + \details This function It enables you to perform two 16-bit signed multiplications, take the difference + of the products, subtracting the high halfword product from the low halfword product, and add the + difference to a 64-bit accumulate operand. Overflow cannot occur during the multiplications or the + subtraction. Overflow can occur as a result of the 64-bit addition, and this overflow is not + detected. Instead, the result wraps round to modulo2^64. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the difference of the product of each multiplication, added to the accumulate value. + \remark + p1 = val1[15:0] * val2[15:0] \n + p2 = val1[31:16] * val2[31:16] \n + res[63:32][31:0] = p1 - p2 + val3[63:32][31:0] + */ +__ALWAYS_STATIC_INLINE uint64_t __SMLSLD(uint32_t x, uint32_t y, uint64_t sum) +{ + return ((uint64_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) - + ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)) + + (((uint64_t)sum)))); +} + +/** + \brief Dual 16-bit signed multiply with exchange subtract with 64-bit accumulate. + \details This function enables you to exchange the halfwords of the second operand, perform two 16-bit multiplications, + adding the difference of the products to a 64-bit accumulate operand. Overflow cannot occur during the + multiplications or the subtraction. Overflow can occur as a result of the 64-bit addition, and this overflow + is not detected. Instead, the result wraps round to modulo2^64. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the difference of the product of each multiplication, added to the accumulate value. + \remark + p1 = val1[15:0] * val2[31:16] \n + p2 = val1[31:16] * val2[15:0] \n + res[63:32][31:0] = p1 - p2 + val3[63:32][31:0] + */ +__ALWAYS_STATIC_INLINE uint64_t __SMLSLDX(uint32_t x, uint32_t y, uint64_t sum) +{ + return ((uint64_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) - + ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)) + + (((uint64_t)sum)))); +} + +/** + \brief 32-bit signed multiply with 32-bit truncated accumulator. + \details This function enables you to perform a signed 32-bit multiplications, adding the most + significant 32 bits of the 64-bit result to a 32-bit accumulate operand. + \param [in] x first operand for multiplication. + \param [in] y second operand for multiplication. + \param [in] sum accumulate value. + \return the product of multiplication (most significant 32 bits) is added to the accumulate value, as a 32-bit integer. + \remark + p = val1 * val2 \n + res[31:0] = p[63:32] + val3[31:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __SMMLA(int32_t x, int32_t y, int32_t sum) +{ + return (uint32_t)((int32_t)((int64_t)((int64_t)x * (int64_t)y) >> 32) + sum); +} + +/** + \brief Sum of dual 16-bit signed multiply. + \details This function enables you to perform two 16-bit signed multiplications, adding the products together. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \return the sum of the products of the two 16-bit signed multiplications. + \remark + p1 = val1[15:0] * val2[15:0] \n + p2 = val1[31:16] * val2[31:16] \n + res[31:0] = p1 + p2 + */ +__ALWAYS_STATIC_INLINE uint32_t __SMUAD(uint32_t x, uint32_t y) +{ + return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) + + ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)))); +} + +/** + \brief Dual 16-bit signed multiply returning difference. + \details This function enables you to perform two 16-bit signed multiplications, taking the difference + of the products by subtracting the high halfword product from the low halfword product. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \return the difference of the products of the two 16-bit signed multiplications. + \remark + p1 = val1[15:0] * val2[15:0] \n + p2 = val1[31:16] * val2[31:16] \n + res[31:0] = p1 - p2 + */ +__ALWAYS_STATIC_INLINE uint32_t __SMUSD(uint32_t x, uint32_t y) +{ + return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) - + ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)))); +} + +/** + \brief Dual extracted 8-bit to 16-bit signed addition. + \details This function enables you to extract two 8-bit values from the second operand (at bit positions + [7:0] and [23:16]), sign-extend them to 16-bits each, and add the results to the first operand. + \param [in] x values added to the sign-extended to 16-bit values. + \param [in] y two 8-bit values to be extracted and sign-extended. + \return the addition of val1 and val2, where the 8-bit values in val2[7:0] and + val2[23:16] have been extracted and sign-extended prior to the addition. + \remark + res[15:0] = val1[15:0] + SignExtended(val2[7:0]) \n + res[31:16] = val1[31:16] + SignExtended(val2[23:16]) + */ +__ALWAYS_STATIC_INLINE uint32_t __SXTAB16(uint32_t x, uint32_t y) +{ + return ((uint32_t)((((((int32_t)y << 24) >> 24) + (((int32_t)x << 16) >> 16)) & (int32_t)0x0000FFFF) | + (((((int32_t)y << 8) >> 8) + (((int32_t)x >> 16) << 16)) & (int32_t)0xFFFF0000))); +} + +/** + \brief Extracted 16-bit to 32-bit unsigned addition. + \details This function enables you to extract two 8-bit values from one operand, zero-extend + them to 16 bits each, and add the results to two 16-bit values from another operand. + \param [in] x values added to the zero-extended to 16-bit values. + \param [in] y two 8-bit values to be extracted and zero-extended. + \return the addition of val1 and val2, where the 8-bit values in val2[7:0] and + val2[23:16] have been extracted and zero-extended prior to the addition. + \remark + res[15:0] = ZeroExt(val2[7:0] to 16 bits) + val1[15:0] \n + res[31:16] = ZeroExt(val2[31:16] to 16 bits) + val1[31:16] + */ +__ALWAYS_STATIC_INLINE uint32_t __UXTAB16(uint32_t x, uint32_t y) +{ + return ((uint32_t)(((((y << 24) >> 24) + ((x << 16) >> 16)) & 0x0000FFFF) | + ((((y << 8) >> 8) + ((x >> 16) << 16)) & 0xFFFF0000))); +} + +/** + \brief Dual extract 8-bits and sign extend each to 16-bits. + \details This function enables you to extract two 8-bit values from an operand and sign-extend them to 16 bits each. + \param [in] x two 8-bit values in val[7:0] and val[23:16] to be sign-extended. + \return the 8-bit values sign-extended to 16-bit values.\n + sign-extended value of val[7:0] in the low halfword of the return value.\n + sign-extended value of val[23:16] in the high halfword of the return value. + \remark + res[15:0] = SignExtended(val[7:0]) \n + res[31:16] = SignExtended(val[23:16]) + */ +__ALWAYS_STATIC_INLINE uint32_t __SXTB16(uint32_t x) +{ + return ((uint32_t)(((((int32_t)x << 24) >> 24) & (int32_t)0x0000FFFF) | + ((((int32_t)x << 8) >> 8) & (int32_t)0xFFFF0000))); +} + +/** + \brief Dual extract 8-bits and zero-extend to 16-bits. + \details This function enables you to extract two 8-bit values from an operand and zero-extend them to 16 bits each. + \param [in] x two 8-bit values in val[7:0] and val[23:16] to be zero-extended. + \return the 8-bit values sign-extended to 16-bit values.\n + sign-extended value of val[7:0] in the low halfword of the return value.\n + sign-extended value of val[23:16] in the high halfword of the return value. + \remark + res[15:0] = SignExtended(val[7:0]) \n + res[31:16] = SignExtended(val[23:16]) + */ +__ALWAYS_STATIC_INLINE uint32_t __UXTB16(uint32_t x) +{ + return ((uint32_t)((((x << 24) >> 24) & 0x0000FFFF) | + (((x << 8) >> 8) & 0xFFFF0000))); +} + +#endif /* _CSI_GCC_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/core/csi_rv32_gcc.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/core/csi_rv32_gcc.h new file mode 100644 index 00000000..4c7d540c --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/core/csi_rv32_gcc.h @@ -0,0 +1,3374 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 csi_rv32_gcc.h + * @brief CSI Header File for GCC. + * @version V1.0 + * @date 01. Sep 2018 + ******************************************************************************/ + +#ifndef _CSI_RV32_GCC_H_ +#define _CSI_RV32_GCC_H_ + +#include + +#if CONFIG_CPU_XUANTIE_E906 || CONFIG_CPU_XUANTIE_E906F || CONFIG_CPU_XUANTIE_E906FD || CONFIG_CPU_XUANTIE_E906P || CONFIG_CPU_XUANTIE_E906FP || CONFIG_CPU_XUANTIE_E906FDP \ + || CONFIG_CPU_XUANTIE_E907 || CONFIG_CPU_XUANTIE_E907F || CONFIG_CPU_XUANTIE_E907FD || CONFIG_CPU_XUANTIE_E907P || CONFIG_CPU_XUANTIE_E907FP || CONFIG_CPU_XUANTIE_E907FDP \ + || CONFIG_CPU_XUANTIE_E902 || CONFIG_CPU_XUANTIE_E902M || CONFIG_CPU_XUANTIE_E902T || CONFIG_CPU_XUANTIE_E902MT \ + || CONFIG_CPU_XUANTIE_E901PLUS_CP || CONFIG_CPU_XUANTIE_E901PLUS_B_CP || CONFIG_CPU_XUANTIE_E901PLUS_M_CP || CONFIG_CPU_XUANTIE_E901PLUS_BM_CP \ + || CONFIG_CPU_XUANTIE_E901_CP || CONFIG_CPU_XUANTIE_E901_B_CP || CONFIG_CPU_XUANTIE_E901_ZM_CP || CONFIG_CPU_XUANTIE_E901_BZM_CP +#define CONFIG_CPU_XUANTIE_E9XX 1 +#endif + +/* ########################### Core Function Access ########################### */ +/** \ingroup CSI_Core_FunctionInterface + \defgroup CSI_Core_RegAccFunctions CSI Core Register Access Functions + @{ + */ +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by setting the IE-bit in the PSR. + Can only be executed in Privileged modes. + */ +__ALWAYS_STATIC_INLINE void __enable_irq(void) +{ + __ASM volatile("csrs mstatus, 8"); +} + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by clearing the IE-bit in the PSR. + Can only be executed in Privileged modes. + */ +__ALWAYS_STATIC_INLINE void __disable_irq(void) +{ + __ASM volatile("csrc mstatus, 8"); +} + +/** + \brief Get MXSTATUS + \details Returns the content of the MXSTATUS Register. + \return MXSTATUS Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MXSTATUS(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mxstatus" : "=r"(result)); + return (result); +} + +/** + \brief Set MXSTATUS + \details Writes the given value to the MXSTATUS Register. + \param [in] MXSTATUS Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MXSTATUS(unsigned long mxstatus) +{ + __ASM volatile("csrw mxstatus, %0" : : "r"(mxstatus)); +} + +/** + \brief Get MEXSTATUS + \details Returns the content of the MEXSTATUS Register. + \return MEXSTATUS Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MEXSTATUS(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mexstatus" : "=r"(result)); + return (result); +} + +/** + \brief Set MEXSTATUS + \details Writes the given value to the MSTATUS Register. + \param [in] MEXSTATUS Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MEXSTATUS(unsigned long mexstatus) +{ + __ASM volatile("csrw mexstatus, %0" : : "r"(mexstatus)); +} + + +/** + \brief Get MRADDR + \details Returns the content of the MRADDR Register. + \return MRADDR Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MRADDR(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mraddr" : "=r"(result)); + return (result); +} + +/** + \brief Get FXCR + \details Returns the content of the FXCR Register. + \return FXCR Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_FXCR(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, fxcr" : "=r"(result)); + return (result); +} + + +/** + \brief Set FXCR + \details Writes the given value to the FXCR Register. + \param [in] FXCR Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_FXCR(unsigned long fxcr) +{ + __ASM volatile("csrw fxcr, %0" : : "r"(fxcr)); +} + +/** + \brief Get MSTATUS + \details Returns the content of the MSTATUS Register. + \return MSTATUS Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MSTATUS(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mstatus" : "=r"(result)); + return (result); +} + +/** + \brief Set MSTATUS + \details Writes the given value to the MSTATUS Register. + \param [in] mstatus MSTATUS Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MSTATUS(unsigned long mstatus) +{ + __ASM volatile("csrw mstatus, %0" : : "r"(mstatus)); +} + +/** + \brief Get MHCR + \details Returns the content of the MHCR Register. + \return MHCR Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MHCR(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mhcr" : "=r"(result)); + return (result); +} + +/** + \brief Set MHCR + \details Writes the given value to the MHCR Register. + \param [in] MHCR Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MHCR(unsigned long mhcr) +{ + __ASM volatile("csrw mhcr, %0" : : "r"(mhcr)); +} + +/** + \brief Get MHINT + \details Returns the content of the MHINT Register. + \return MHINT Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MHINT(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mhint" : "=r"(result)); + return (result); +} + +/** + \brief Set MHINT + \details Writes the given value to the MHINT Register. + \param [in] MHINT Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MHINT(unsigned long mhint) +{ + __ASM volatile("csrw mhint, %0" : : "r"(mhint)); +} + +/** + \brief Get MISA Register + \details Returns the content of the MISA Register. + \return MISA Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MISA(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, misa" : "=r"(result)); + return (result); +} + +/** + \brief Set MISA + \details Writes the given value to the MISA Register. + \param [in] misa MISA Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MISA(unsigned long misa) +{ + __ASM volatile("csrw misa, %0" : : "r"(misa)); +} + +/** + \brief Get MIE Register + \details Returns the content of the MIE Register. + \return MIE Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MIE(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mie" : "=r"(result)); + return (result); +} + +/** + \brief Set MIE + \details Writes the given value to the MIE Register. + \param [in] mie MIE Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MIE(unsigned long mie) +{ + __ASM volatile("csrw mie, %0" : : "r"(mie)); +} + +/** + \brief Get MTVEC Register + \details Returns the content of the MTVEC Register. + \return MTVEC Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MTVEC(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mtvec" : "=r"(result)); + return (result); +} + +/** + \brief Set MTVEC + \details Writes the given value to the MTVEC Register. + \param [in] mtvec MTVEC Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MTVEC(unsigned long mtvec) +{ + __ASM volatile("csrw mtvec, %0" : : "r"(mtvec)); +} + +/** + \brief Set MTVT + \details Writes the given value to the MTVT Register. + \param [in] mtvt MTVT Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MTVT(unsigned long mtvt) +{ + __ASM volatile("csrw mtvt, %0" : : "r"(mtvt)); +} + +/** + \brief Get MTVT Register + \details Returns the content of the MTVT Register. + \return MTVT Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MTVT(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mtvt" : "=r"(result)); + return (result); +} + +/** + \brief Get MTIME + \details Returns the content of the MTIME Register. + \return MTIME Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MTIME(void) +{ + unsigned long result; + __ASM volatile("rdtime %0" : "=r"(result)); + return (result); +} + +/** + \brief Get MTIMEH + \details Returns the content of the MTIME Register. + \return MTIME Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MTIMEH(void) +{ + unsigned long result; + __ASM volatile("rdtimeh %0" : "=r"(result)); + return (result); +} + +/** + \brief Get SP + \details Returns the content of the SP Register. + \return SP Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_SP(void) +{ + unsigned long result; + + __ASM volatile("mv %0, sp" : "=r"(result)); + return (result); +} + +/** + \brief Set SP + \details Writes the given value to the SP Register. + \param [in] sp SP Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_SP(unsigned long sp) +{ + __ASM volatile("mv sp, %0" : : "r"(sp): "sp"); +} + +/** + \brief Get MSCRATCH Register + \details Returns the content of the MSCRATCH Register. + \return MSCRATCH Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MSCRATCH(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mscratch" : "=r"(result)); + return (result); +} + +/** + \brief Set MSCRATCH + \details Writes the given value to the MSCRATCH Register. + \param [in] mscratch MSCRATCH Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MSCRATCH(unsigned long mscratch) +{ + __ASM volatile("csrw mscratch, %0" : : "r"(mscratch)); +} + +/** + \brief Get MEPC Register + \details Returns the content of the MEPC Register. + \return MEPC Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MEPC(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mepc" : "=r"(result)); + return (result); +} + +/** + \brief Set MEPC + \details Writes the given value to the MEPC Register. + \param [in] mepc MEPC Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MEPC(unsigned long mepc) +{ + __ASM volatile("csrw mepc, %0" : : "r"(mepc)); +} + +/** + \brief Get MCAUSE Register + \details Returns the content of the MCAUSE Register. + \return MCAUSE Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MCAUSE(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mcause" : "=r"(result)); + return (result); +} + +/** + \brief Get MNXTI Register + \details Returns the content of the MNXTI Register. + \return MNXTI Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MNXTI(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mnxti" : "=r"(result)); + return (result); +} + +/** + \brief Set MNXTI + \details Writes the given value to the MNXTI Register. + \param [in] mnxti MNXTI Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MNXTI(unsigned long mnxti) +{ + __ASM volatile("csrw mnxti, %0" : : "r"(mnxti)); +} + +/** + \brief Get MINTSTATUS Register + \details Returns the content of the MINTSTATUS Register. + \return MINTSTATUS Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MINTSTATUS(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mintstatus" : "=r"(result)); + return (result); +} + +/** + \brief Get MTVAL Register + \details Returns the content of the MTVAL Register. + \return MTVAL Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MTVAL(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mtval" : "=r"(result)); + return (result); +} + +/** + \brief Get MIP Register + \details Returns the content of the MIP Register. + \return MIP Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MIP(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mip" : "=r"(result)); + return (result); +} + +/** + \brief Set MIP + \details Writes the given value to the MIP Register. + \param [in] mip MIP Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MIP(unsigned long mip) +{ + __ASM volatile("csrw mip, %0" : : "r"(mip)); +} + +/** + \brief Get MCYCLEL Register + \details Returns the content of the MCYCLEL Register. + \return MCYCLE Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MCYCLE(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mcycle" : "=r"(result)); + return (result); +} + +/** + \brief Set MCYCLE + \details Write MCYCLE Register + \param [in] value MCYCLE Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MCYCLE(unsigned long value) +{ + __ASM volatile("csrw mcycle, %0" : : "r"(value)); +} + +/** + \brief Get MCYCLEH Register + \details Returns the content of the MCYCLEH Register. + \return MCYCLEH Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MCYCLEH(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mcycleh" : "=r"(result)); + return (result); +} + +/** + \brief Set MCYCLEH + \details Write MCYCLEH Register + \param [in] value MCYCLEH Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MCYCLEH(unsigned long value) +{ + __ASM volatile("csrw mcycleh, %0" : : "r"(value)); +} + +/** + \brief Get MINSTRET Register + \details Returns the content of the MINSTRET Register. + \return MINSTRET Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MINSTRET(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, minstret" : "=r"(result)); + return (result); +} + +/** + \brief Set MINSTRET + \details Write MINSTRET Register + \param [in] value MINSTRET Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MINSTRET(unsigned long value) +{ + __ASM volatile("csrw minstret, %0" : : "r"(value)); +} + +/** + \brief Get MINSTRETH Register + \details Returns the content of the MINSTRETH Register. + \return MINSTRETH Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MINSTRETH(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, minstreth" : "=r"(result)); + return (result); +} + +/** + \brief Set MINSTRETH + \details Write MINSTRETH Register + \param [in] value MINSTRETH Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MINSTRETH(unsigned long value) +{ + __ASM volatile("csrw minstreth, %0" : : "r"(value)); +} + +#if (CONFIG_CPU_XUANTIE_E907 || CONFIG_CPU_XUANTIE_E907F || CONFIG_CPU_XUANTIE_E907FD || CONFIG_CPU_XUANTIE_E907P || CONFIG_CPU_XUANTIE_E907FP || CONFIG_CPU_XUANTIE_E907FDP) +/** + \brief Get MITCMCR + \details Returns the content of the MITCMCR Register. + \return MITCMCR Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MITCMCR(void) +{ + unsigned long result; + __ASM volatile("csrr %0, mitcmcr" : "=r"(result)); + + return (result); +} + +/** + \brief Set MITCMCR + \details Writes the given value to the MITCMCR Register. + \param [in] itcmcr MITCMCR Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MITCMCR(unsigned long mitcmcr) +{ + __ASM volatile("csrw mitcmcr, %0" : : "r"(mitcmcr)); +} + +/** + \brief Get MDTCMCR + \details Returns the content of the MDTCMCR Register. + \return MDTCMCR Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MDTCMCR(void) +{ + unsigned long result; + __ASM volatile("csrr %0, mdtcmcr" : "=r"(result)); + return (result); +} + +/** + \brief Set MDTCMCR + \details Writes the given value to the MDTCMCR Register. + \param [in] dtcmcr MDTCMCR Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MDTCMCR(unsigned long mdtcmcr) +{ + __ASM volatile("csrw mdtcmcr, %0" : : "r"(mdtcmcr)); +} +#endif /* end e907xx */ + +/** + \brief Set MCOUNTINHIBIT + \details Write MCOUNTINHIBIT Register. + \param [in] value MCOUNTINHIBIT Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MCOUNTINHIBIT(uint32_t value) +{ + __ASM volatile("csrw mcountinhibit, %0" : : "r"(value)); +} + +/** + \brief Get MCOUNTINHIBIT + \details Read MCOUNTINHIBIT Register + \return MCOUNTINHIBIT Register value + */ +__ALWAYS_STATIC_INLINE unsigned int __get_MCOUNTINHIBIT(void) +{ + uint32_t result; + __ASM volatile("csrr %0, mcountinhibit" : "=r"(result)); + return result; +} + +/** + \brief Set MHPMEVENT + \details Write MHPMEVENT Register + \param [in] idx Index of MHPMEVENT Register + \param [in] value MHPMEVENT Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MHPMEVENT(unsigned long idx, unsigned long value) +{ + switch (idx) { + case 0: rv_csr_write(0x7E0, value); break; + case 2: rv_csr_write(0x7E1, value); break; + case 3: rv_csr_write(0x323, value); break; + case 4: rv_csr_write(0x324, value); break; + case 5: rv_csr_write(0x325, value); break; + case 6: rv_csr_write(0x326, value); break; + case 7: rv_csr_write(0x327, value); break; + case 8: rv_csr_write(0x328, value); break; + case 9: rv_csr_write(0x329, value); break; + case 10: rv_csr_write(0x32a, value); break; + case 11: rv_csr_write(0x32b, value); break; + case 12: rv_csr_write(0x32c, value); break; + case 13: rv_csr_write(0x32d, value); break; + case 14: rv_csr_write(0x32e, value); break; + case 15: rv_csr_write(0x32f, value); break; + case 16: rv_csr_write(0x330, value); break; + case 17: rv_csr_write(0x331, value); break; + case 18: rv_csr_write(0x332, value); break; + case 19: rv_csr_write(0x333, value); break; + case 20: rv_csr_write(0x334, value); break; + case 21: rv_csr_write(0x335, value); break; + case 22: rv_csr_write(0x336, value); break; + case 23: rv_csr_write(0x337, value); break; + case 24: rv_csr_write(0x338, value); break; + case 25: rv_csr_write(0x339, value); break; + case 26: rv_csr_write(0x33a, value); break; + case 27: rv_csr_write(0x33b, value); break; + case 28: rv_csr_write(0x33c, value); break; + case 29: rv_csr_write(0x33d, value); break; + case 30: rv_csr_write(0x33e, value); break; + case 31: rv_csr_write(0x33F, value); break; + default: break; + } +} + +/** + \brief Get MHPMEVENT + \details Read MHPMEVENT Register. + \param [in] idx Index of MHPMEVENT Register to read. + \return MHPMEVENT Register Value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MHPMEVENT(unsigned long idx) +{ + switch (idx) { + case 0: return rv_csr_read(0x7E0); + case 2: return rv_csr_read(0x7E1); + case 3: return rv_csr_read(0x323); + case 4: return rv_csr_read(0x324); + case 5: return rv_csr_read(0x325); + case 6: return rv_csr_read(0x326); + case 7: return rv_csr_read(0x327); + case 8: return rv_csr_read(0x328); + case 9: return rv_csr_read(0x329); + case 10: return rv_csr_read(0x32a); + case 11: return rv_csr_read(0x32b); + case 12: return rv_csr_read(0x32c); + case 13: return rv_csr_read(0x32d); + case 14: return rv_csr_read(0x32e); + case 15: return rv_csr_read(0x32f); + case 16: return rv_csr_read(0x330); + case 17: return rv_csr_read(0x331); + case 18: return rv_csr_read(0x332); + case 19: return rv_csr_read(0x333); + case 20: return rv_csr_read(0x334); + case 21: return rv_csr_read(0x335); + case 22: return rv_csr_read(0x336); + case 23: return rv_csr_read(0x337); + case 24: return rv_csr_read(0x338); + case 25: return rv_csr_read(0x339); + case 26: return rv_csr_read(0x33a); + case 27: return rv_csr_read(0x33b); + case 28: return rv_csr_read(0x33c); + case 29: return rv_csr_read(0x33d); + case 30: return rv_csr_read(0x33e); + case 31: return rv_csr_read(0x33F); + default: return 0; + } +} + +/** + \brief Set MHPMEVENTH + \details Write MHPMEVENTH Register + \param [in] idx Index of MHPMEVENT Register + \param [in] value MHPMEVENTH Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MHPMEVENTH(unsigned long idx, unsigned long value) +{ + switch (idx) { + case 3: rv_csr_write(0x723, value); break; + case 4: rv_csr_write(0x724, value); break; + case 5: rv_csr_write(0x725, value); break; + case 6: rv_csr_write(0x726, value); break; + case 7: rv_csr_write(0x727, value); break; + case 8: rv_csr_write(0x728, value); break; + case 9: rv_csr_write(0x729, value); break; + case 10: rv_csr_write(0x72A, value); break; + case 11: rv_csr_write(0x72B, value); break; + case 12: rv_csr_write(0x72C, value); break; + case 13: rv_csr_write(0x72D, value); break; + case 14: rv_csr_write(0x72E, value); break; + case 15: rv_csr_write(0x72F, value); break; + case 16: rv_csr_write(0x730, value); break; + case 17: rv_csr_write(0x731, value); break; + case 18: rv_csr_write(0x732, value); break; + case 19: rv_csr_write(0x733, value); break; + case 20: rv_csr_write(0x734, value); break; + case 21: rv_csr_write(0x735, value); break; + case 22: rv_csr_write(0x736, value); break; + case 23: rv_csr_write(0x737, value); break; + case 24: rv_csr_write(0x738, value); break; + case 25: rv_csr_write(0x739, value); break; + case 26: rv_csr_write(0x73A, value); break; + case 27: rv_csr_write(0x73B, value); break; + case 28: rv_csr_write(0x73C, value); break; + case 29: rv_csr_write(0x73D, value); break; + case 30: rv_csr_write(0x73E, value); break; + case 31: rv_csr_write(0x73F, value); break; + default: break; + } +} + +/** + \brief Get MHPMEVENTH + \details Read MHPMEVENTH Register. + \param [in] idx Index of MHPMEVENTH Register to read. + \return MHPMEVENTH Register Value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MHPMEVENTH(unsigned long idx) +{ + switch (idx) { + case 3: return rv_csr_read(0x723); + case 4: return rv_csr_read(0x724); + case 5: return rv_csr_read(0x725); + case 6: return rv_csr_read(0x726); + case 7: return rv_csr_read(0x727); + case 8: return rv_csr_read(0x728); + case 9: return rv_csr_read(0x729); + case 10: return rv_csr_read(0x72A); + case 11: return rv_csr_read(0x72B); + case 12: return rv_csr_read(0x72C); + case 13: return rv_csr_read(0x72D); + case 14: return rv_csr_read(0x72E); + case 15: return rv_csr_read(0x72F); + case 16: return rv_csr_read(0x730); + case 17: return rv_csr_read(0x731); + case 18: return rv_csr_read(0x732); + case 19: return rv_csr_read(0x733); + case 20: return rv_csr_read(0x734); + case 21: return rv_csr_read(0x735); + case 22: return rv_csr_read(0x736); + case 23: return rv_csr_read(0x737); + case 24: return rv_csr_read(0x738); + case 25: return rv_csr_read(0x739); + case 26: return rv_csr_read(0x73A); + case 27: return rv_csr_read(0x73B); + case 28: return rv_csr_read(0x73C); + case 29: return rv_csr_read(0x73D); + case 30: return rv_csr_read(0x73E); + case 31: return rv_csr_read(0x73F); + default: return 0; + } +} + +/** + \brief Set MHPMCOUNTER + \details Write MHPMCOUNTER Register + \param [in] idx Index of MHPMCOUNTER Register + \param [in] value MHPMCOUNTER Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MHPMCOUNTER(unsigned long idx, unsigned long value) +{ + switch (idx) { + case 3: rv_csr_write(0xB03, (value)); break; + case 4: rv_csr_write(0xB04, (value)); break; + case 5: rv_csr_write(0xB05, (value)); break; + case 6: rv_csr_write(0xB06, (value)); break; + case 7: rv_csr_write(0xB07, (value)); break; + case 8: rv_csr_write(0xB08, (value)); break; + case 9: rv_csr_write(0xB09, (value)); break; + case 10: rv_csr_write(0xB0A, (value)); break; + case 11: rv_csr_write(0xB0B, (value)); break; + case 12: rv_csr_write(0xB0C, (value)); break; + case 13: rv_csr_write(0xB0D, (value)); break; + case 14: rv_csr_write(0xB0E, (value)); break; + case 15: rv_csr_write(0xB0F, (value)); break; + case 16: rv_csr_write(0xB10, (value)); break; + case 17: rv_csr_write(0xB11, (value)); break; + case 18: rv_csr_write(0xB12, (value)); break; + case 19: rv_csr_write(0xB13, (value)); break; + case 20: rv_csr_write(0xB14, (value)); break; + case 21: rv_csr_write(0xB15, (value)); break; + case 22: rv_csr_write(0xB16, (value)); break; + case 23: rv_csr_write(0xB17, (value)); break; + case 24: rv_csr_write(0xB18, (value)); break; + case 25: rv_csr_write(0xB19, (value)); break; + case 26: rv_csr_write(0xB1A, (value)); break; + case 27: rv_csr_write(0xB1B, (value)); break; + case 28: rv_csr_write(0xB1C, (value)); break; + case 29: rv_csr_write(0xB1D, (value)); break; + case 30: rv_csr_write(0xB1E, (value)); break; + case 31: rv_csr_write(0xB1F, (value)); break; + default: break; + } +} + +/** + \brief Get MHPMCOUNTER + \details Write MHPMCOUNTER Register. + \param [in] idx Index of MHPMCOUNTER Register + \return MHPMCOUNTER Register Value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MHPMCOUNTER(unsigned long idx) +{ + switch (idx) { + case 3: return rv_csr_read(0xB03); + case 4: return rv_csr_read(0xB04); + case 5: return rv_csr_read(0xB05); + case 6: return rv_csr_read(0xB06); + case 7: return rv_csr_read(0xB07); + case 8: return rv_csr_read(0xB08); + case 9: return rv_csr_read(0xB09); + case 10: return rv_csr_read(0xB0A); + case 11: return rv_csr_read(0xB0B); + case 12: return rv_csr_read(0xB0C); + case 13: return rv_csr_read(0xB0D); + case 14: return rv_csr_read(0xB0E); + case 15: return rv_csr_read(0xB0F); + case 16: return rv_csr_read(0xB10); + case 17: return rv_csr_read(0xB11); + case 18: return rv_csr_read(0xB12); + case 19: return rv_csr_read(0xB13); + case 20: return rv_csr_read(0xB14); + case 21: return rv_csr_read(0xB15); + case 22: return rv_csr_read(0xB16); + case 23: return rv_csr_read(0xB17); + case 24: return rv_csr_read(0xB18); + case 25: return rv_csr_read(0xB19); + case 26: return rv_csr_read(0xB1A); + case 27: return rv_csr_read(0xB1B); + case 28: return rv_csr_read(0xB1C); + case 29: return rv_csr_read(0xB1D); + case 30: return rv_csr_read(0xB1E); + case 31: return rv_csr_read(0xB1F); + default: return 0; + } +} + +/** + \brief Set MHPMCOUNTERH + \details Write MHPMCOUNTERH Register + \param [in] idx Index of MHPMCOUNTERH Register + \param [in] value MHPMCOUNTERH Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MHPMCOUNTERH(unsigned long idx, unsigned long value) +{ + switch (idx) { + case 3: rv_csr_write(0xB83, (value)); break; + case 4: rv_csr_write(0xB84, (value)); break; + case 5: rv_csr_write(0xB85, (value)); break; + case 6: rv_csr_write(0xB86, (value)); break; + case 7: rv_csr_write(0xB87, (value)); break; + case 8: rv_csr_write(0xB88, (value)); break; + case 9: rv_csr_write(0xB89, (value)); break; + case 10: rv_csr_write(0xB8A, (value)); break; + case 11: rv_csr_write(0xB8B, (value)); break; + case 12: rv_csr_write(0xB8C, (value)); break; + case 13: rv_csr_write(0xB8D, (value)); break; + case 14: rv_csr_write(0xB8E, (value)); break; + case 15: rv_csr_write(0xB8F, (value)); break; + case 16: rv_csr_write(0xB90, (value)); break; + case 17: rv_csr_write(0xB91, (value)); break; + case 18: rv_csr_write(0xB92, (value)); break; + case 19: rv_csr_write(0xB93, (value)); break; + case 20: rv_csr_write(0xB94, (value)); break; + case 21: rv_csr_write(0xB95, (value)); break; + case 22: rv_csr_write(0xB96, (value)); break; + case 23: rv_csr_write(0xB97, (value)); break; + case 24: rv_csr_write(0xB98, (value)); break; + case 25: rv_csr_write(0xB99, (value)); break; + case 26: rv_csr_write(0xB9A, (value)); break; + case 27: rv_csr_write(0xB9B, (value)); break; + case 28: rv_csr_write(0xB9C, (value)); break; + case 29: rv_csr_write(0xB9D, (value)); break; + case 30: rv_csr_write(0xB9E, (value)); break; + case 31: rv_csr_write(0xB9F, (value)); break; + default: break; + } +} + +/** + \brief Get MHPMCOUNTERH + \details Write MHPMCOUNTERH Register. + \param [in] idx Index of MHPMCOUNTERH Register + \return MHPMCOUNTERH Register Value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MHPMCOUNTERH(unsigned long idx) +{ + switch (idx) { + case 3: return rv_csr_read(0xB83); + case 4: return rv_csr_read(0xB84); + case 5: return rv_csr_read(0xB85); + case 6: return rv_csr_read(0xB86); + case 7: return rv_csr_read(0xB87); + case 8: return rv_csr_read(0xB88); + case 9: return rv_csr_read(0xB89); + case 10: return rv_csr_read(0xB8A); + case 11: return rv_csr_read(0xB8B); + case 12: return rv_csr_read(0xB8C); + case 13: return rv_csr_read(0xB8D); + case 14: return rv_csr_read(0xB8E); + case 15: return rv_csr_read(0xB8F); + case 16: return rv_csr_read(0xB90); + case 17: return rv_csr_read(0xB91); + case 18: return rv_csr_read(0xB92); + case 19: return rv_csr_read(0xB93); + case 20: return rv_csr_read(0xB94); + case 21: return rv_csr_read(0xB95); + case 22: return rv_csr_read(0xB96); + case 23: return rv_csr_read(0xB97); + case 24: return rv_csr_read(0xB98); + case 25: return rv_csr_read(0xB99); + case 26: return rv_csr_read(0xB9A); + case 27: return rv_csr_read(0xB9B); + case 28: return rv_csr_read(0xB9C); + case 29: return rv_csr_read(0xB9D); + case 30: return rv_csr_read(0xB9E); + case 31: return rv_csr_read(0xB9F); + default: return 0; + } +} + +/** + \brief Get MVENDORID Register + \details Returns the content of the MVENDROID Register. + \return MVENDORID Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MVENDORID(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mvendorid" : "=r"(result)); + return (result); +} + +/** + \brief Get MARCHID Register + \details Returns the content of the MARCHID Register. + \return MARCHID Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MARCHID(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, marchid" : "=r"(result)); + return (result); +} + +/** + \brief Get MIMPID Register + \details Returns the content of the MIMPID Register. + \return MIMPID Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MIMPID(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mimpid" : "=r"(result)); + return (result); +} + +/** + \brief Get MHARTID Register + \details Returns the content of the MHARTID Register. + \return MHARTID Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MHARTID(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mhartid" : "=r"(result)); + return (result); +} + +/** + \brief Get PMPCFGx Register + \details Returns the content of the PMPCFGx Register. + \return PMPCFGx Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_PMPCFG0(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpcfg0" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPCFG1(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpcfg1" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPCFG2(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpcfg2" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPCFG3(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpcfg3" : "=r"(result)); + return (result); +} + +/** + \brief Get PMPxCFG Register by index + \details Returns the content of the PMPxCFG Register. + \param [in] idx PMP region index + \return PMPxCFG Register value + */ +__STATIC_INLINE uint8_t __get_PMPxCFG(unsigned long idx) +{ + unsigned long pmpcfgx = 0; + + if (idx < 4) { + pmpcfgx = __get_PMPCFG0(); + } else if (idx >=4 && idx < 8) { + idx -= 4; + pmpcfgx = __get_PMPCFG1(); + } else if (idx >=8 && idx < 12) { + idx -= 8; + pmpcfgx = __get_PMPCFG2(); + } else if (idx >=12 && idx < 16) { + idx -= 12; + pmpcfgx = __get_PMPCFG3(); + } else { + return 0; + } + + return (uint8_t)((pmpcfgx & (0xFF << (idx << 3))) >> (idx << 3)); +} + +/** + \brief Set PMPCFGx + \details Writes the given value to the PMPCFGx Register. + \param [in] pmpcfg PMPCFGx Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_PMPCFG0(unsigned long pmpcfg) +{ + __ASM volatile("csrw pmpcfg0, %0" : : "r"(pmpcfg)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPCFG1(unsigned long pmpcfg) +{ + __ASM volatile("csrw pmpcfg1, %0" : : "r"(pmpcfg)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPCFG2(unsigned long pmpcfg) +{ + __ASM volatile("csrw pmpcfg2, %0" : : "r"(pmpcfg)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPCFG3(unsigned long pmpcfg) +{ + __ASM volatile("csrw pmpcfg3, %0" : : "r"(pmpcfg)); +} + +/** + \brief Set PMPxCFG by index + \details Writes the given value to the PMPxCFG Register. + \param [in] idx PMPx region index + \param [in] pmpxcfg PMPxCFG Register value to set + */ +__STATIC_INLINE void __set_PMPxCFG(unsigned long idx, uint8_t pmpxcfg) +{ + unsigned long pmpcfgx = 0; + + if (idx < 4) { + pmpcfgx = __get_PMPCFG0(); + pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | (pmpxcfg << (idx << 3)); + __set_PMPCFG0(pmpcfgx); + } else if (idx >=4 && idx < 8) { + idx -= 4; + pmpcfgx = __get_PMPCFG1(); + pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | (pmpxcfg << (idx << 3)); + __set_PMPCFG1(pmpcfgx); + } else if (idx >=8 && idx < 12) { + idx -= 8; + pmpcfgx = __get_PMPCFG2(); + pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | (pmpxcfg << (idx << 3)); + __set_PMPCFG2(pmpcfgx); + } else if (idx >=12 && idx < 16) { + idx -= 12; + pmpcfgx = __get_PMPCFG3(); + pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | (pmpxcfg << (idx << 3)); + __set_PMPCFG3(pmpcfgx); + } else { + return; + } +} + +/** + \brief Get PMPADDRx Register + \details Returns the content of the PMPADDRx Register. + \return PMPADDRx Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR0(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpaddr0" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR1(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpaddr1" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR2(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpaddr2" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR3(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpaddr3" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR4(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpaddr4" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR5(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpaddr5" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR6(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpaddr6" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR7(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpaddr7" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR8(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpaddr8" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR9(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpaddr9" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR10(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpaddr10" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR11(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpaddr11" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR12(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpaddr12" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR13(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpaddr13" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR14(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpaddr14" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR15(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpaddr15" : "=r"(result)); + return (result); +} + +/** + \brief Get PMPADDRx Register by index + \details Returns the content of the PMPADDRx Register. + \param [in] idx PMP region index + \return PMPADDRx Register value + */ +__STATIC_INLINE unsigned long __get_PMPADDRx(unsigned long idx) +{ + switch (idx) { + case 0: return __get_PMPADDR0(); + case 1: return __get_PMPADDR1(); + case 2: return __get_PMPADDR2(); + case 3: return __get_PMPADDR3(); + case 4: return __get_PMPADDR4(); + case 5: return __get_PMPADDR5(); + case 6: return __get_PMPADDR6(); + case 7: return __get_PMPADDR7(); + case 8: return __get_PMPADDR8(); + case 9: return __get_PMPADDR9(); + case 10: return __get_PMPADDR10(); + case 11: return __get_PMPADDR11(); + case 12: return __get_PMPADDR12(); + case 13: return __get_PMPADDR13(); + case 14: return __get_PMPADDR14(); + case 15: return __get_PMPADDR15(); + default: return 0; + } +} + +/** + \brief Set PMPADDRx + \details Writes the given value to the PMPADDRx Register. + \param [in] pmpaddr PMPADDRx Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_PMPADDR0(unsigned long pmpaddr) +{ + __ASM volatile("csrw pmpaddr0, %0" : : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR1(unsigned long pmpaddr) +{ + __ASM volatile("csrw pmpaddr1, %0" : : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR2(unsigned long pmpaddr) +{ + __ASM volatile("csrw pmpaddr2, %0" : : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR3(unsigned long pmpaddr) +{ + __ASM volatile("csrw pmpaddr3, %0" : : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR4(unsigned long pmpaddr) +{ + __ASM volatile("csrw pmpaddr4, %0" : : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR5(unsigned long pmpaddr) +{ + __ASM volatile("csrw pmpaddr5, %0" : : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR6(unsigned long pmpaddr) +{ + __ASM volatile("csrw pmpaddr6, %0" : : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR7(unsigned long pmpaddr) +{ + __ASM volatile("csrw pmpaddr7, %0" : : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR8(unsigned long pmpaddr) +{ + __ASM volatile("csrw pmpaddr8, %0" : : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR9(unsigned long pmpaddr) +{ + __ASM volatile("csrw pmpaddr9, %0" : : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR10(unsigned long pmpaddr) +{ + __ASM volatile("csrw pmpaddr10, %0" : : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR11(unsigned long pmpaddr) +{ + __ASM volatile("csrw pmpaddr11, %0" : : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR12(unsigned long pmpaddr) +{ + __ASM volatile("csrw pmpaddr12, %0" : : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR13(unsigned long pmpaddr) +{ + __ASM volatile("csrw pmpaddr13, %0" : : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR14(unsigned long pmpaddr) +{ + __ASM volatile("csrw pmpaddr14, %0" : : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR15(unsigned long pmpaddr) +{ + __ASM volatile("csrw pmpaddr15, %0" : : "r"(pmpaddr)); +} + +/** + \brief Set PMPADDRx by index + \details Writes the given value to the PMPADDRx Register. + \param [in] idx PMP region index + \param [in] pmpaddr PMPADDRx Register value to set + */ +__STATIC_INLINE void __set_PMPADDRx(unsigned long idx, unsigned long pmpaddr) +{ + switch (idx) { + case 0: __set_PMPADDR0(pmpaddr); break; + case 1: __set_PMPADDR1(pmpaddr); break; + case 2: __set_PMPADDR2(pmpaddr); break; + case 3: __set_PMPADDR3(pmpaddr); break; + case 4: __set_PMPADDR4(pmpaddr); break; + case 5: __set_PMPADDR5(pmpaddr); break; + case 6: __set_PMPADDR6(pmpaddr); break; + case 7: __set_PMPADDR7(pmpaddr); break; + case 8: __set_PMPADDR8(pmpaddr); break; + case 9: __set_PMPADDR9(pmpaddr); break; + case 10: __set_PMPADDR10(pmpaddr); break; + case 11: __set_PMPADDR11(pmpaddr); break; + case 12: __set_PMPADDR12(pmpaddr); break; + case 13: __set_PMPADDR13(pmpaddr); break; + case 14: __set_PMPADDR14(pmpaddr); break; + case 15: __set_PMPADDR15(pmpaddr); break; + default: return; + } +} + +/** + \brief Enable interrupts and exceptions + \details Enables interrupts and exceptions by setting the IE-bit and EE-bit in the PSR. + Can only be executed in Privileged modes. + */ +__ALWAYS_STATIC_INLINE void __enable_excp_irq(void) +{ + __enable_irq(); +} + +/** + \brief Disable interrupts and exceptions + \details Disables interrupts and exceptions by clearing the IE-bit and EE-bit in the PSR. + Can only be executed in Privileged modes. + */ +__ALWAYS_STATIC_INLINE void __disable_excp_irq(void) +{ + __disable_irq(); +} + +#define __CSI_GCC_OUT_REG(r) "=r" (r) +#define __CSI_GCC_USE_REG(r) "r" (r) + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +__ALWAYS_STATIC_INLINE void __NOP(void) +{ + __ASM volatile("nop"); +} + + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +__ALWAYS_STATIC_INLINE void __WFI(void) +{ + __ASM volatile("wfi"); +} + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one interrupt occurs. + */ +__ALWAYS_STATIC_INLINE void __WAIT(void) +{ + __ASM volatile("wfi"); +} + +/** + \brief Doze For Interrupt + \details Doze For Interrupt is a hint instruction that suspends execution until one interrupt occurs. + */ +__ALWAYS_STATIC_INLINE void __DOZE(void) +{ + __ASM volatile("wfi"); +} + +/** + \brief Stop For Interrupt + \details Stop For Interrupt is a hint instruction that suspends execution until one interrupt occurs. + */ +__ALWAYS_STATIC_INLINE void __STOP(void) +{ + __ASM volatile("wfi"); +} + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +__ALWAYS_STATIC_INLINE void __ISB(void) +{ + __ASM volatile("fence.i"); + __ASM volatile("fence r, r"); +} + + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__ALWAYS_STATIC_INLINE void __DSB(void) +{ + __ASM volatile("fence iorw, iorw"); +#if __riscv_xtheadsync + __ASM volatile("sync"); +#endif +} + +/** + \brief Invalid all icache + \details invalid all icache. + */ +__ALWAYS_STATIC_INLINE void __ICACHE_IALL(void) +{ +#if __riscv_xtheadcmo + __ASM volatile("icache.iall"); +#endif +} + +/** + \brief Invalid Icache by addr + \details Invalid Icache by addr. + \param [in] addr operate addr + */ +__ALWAYS_STATIC_INLINE void __ICACHE_IPA(unsigned long addr) +{ +#if __riscv_xtheadcmo + __ASM volatile("icache.ipa %0" : : "r"(addr)); +#endif +} + +/** + \brief Invalid all dcache + \details invalid all dcache. + */ +__ALWAYS_STATIC_INLINE void __DCACHE_IALL(void) +{ +#if __riscv_xtheadcmo + __ASM volatile("dcache.iall"); +#endif +} + +/** + \brief Clear all dcache + \details clear all dcache. + */ +__ALWAYS_STATIC_INLINE void __DCACHE_CALL(void) +{ +#if __riscv_xtheadcmo + __ASM volatile("dcache.call"); +#endif +} + +/** + \brief Clear&invalid all dcache + \details clear & invalid all dcache. + */ +__ALWAYS_STATIC_INLINE void __DCACHE_CIALL(void) +{ +#if __riscv_xtheadcmo + __ASM volatile("dcache.ciall"); +#endif +} + +/** + \brief Invalid Dcache by addr + \details Invalid Dcache by addr. + \param [in] addr operate addr + */ +__ALWAYS_STATIC_INLINE void __DCACHE_IPA(unsigned long addr) +{ +#if __riscv_xtheadcmo + __ASM volatile("dcache.ipa %0" : : "r"(addr)); +#endif +} + +/** + \brief Clear Dcache by addr + \details Clear Dcache by addr. + \param [in] addr operate addr + */ +__ALWAYS_STATIC_INLINE void __DCACHE_CPA(unsigned long addr) +{ +#if __riscv_xtheadcmo + __ASM volatile("dcache.cpa %0" : : "r"(addr)); +#endif +} + +/** + \brief Clear & Invalid Dcache by addr + \details Clear & Invalid Dcache by addr. + \param [in] addr operate addr + */ +__ALWAYS_STATIC_INLINE void __DCACHE_CIPA(unsigned long addr) +{ +#if __riscv_xtheadcmo + __ASM volatile("dcache.cipa %0" : : "r"(addr)); +#endif +} + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__ALWAYS_STATIC_INLINE void __DMB(void) +{ + __ASM volatile("fence"); +} + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in integer value. + \param [in] value Value to reverse + \return Reversed value + */ +__ALWAYS_STATIC_INLINE unsigned long __REV(unsigned long value) +{ + return __builtin_bswap32(value); +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in two unsigned short values. + \param [in] value Value to reverse + \return Reversed value + */ +__ALWAYS_STATIC_INLINE unsigned long __REV16(unsigned long value) +{ + unsigned long result; + + result = ((value & 0xFF000000) >> 8) | ((value & 0x00FF0000) << 8) | + ((value & 0x0000FF00) >> 8) | ((value & 0x000000FF) << 8); + + return (result); +} + + +/** + \brief Reverse byte order in signed short value + \details Reverses the byte order in a signed short value with sign extension to integer. + \param [in] value Value to reverse + \return Reversed value + */ +__ALWAYS_STATIC_INLINE int32_t __REVSH(int32_t value) +{ + return (short)(((value & 0xFF00) >> 8) | ((value & 0x00FF) << 8)); +} + + +/** + \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 + \return Rotated value + */ +__ALWAYS_STATIC_INLINE unsigned long __ROR(unsigned long op1, unsigned long op2) +{ + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \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. + */ +__ALWAYS_STATIC_INLINE void __BKPT(void) +{ + __ASM volatile("ebreak"); +} + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +__ALWAYS_STATIC_INLINE unsigned long __RBIT(unsigned long value) +{ + unsigned long result; + + int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + + for (value >>= 1U; value; value >>= 1U) { + result <<= 1U; + result |= value & 1U; + s--; + } + + result <<= s; /* shift when v's highest bits are zero */ + + return (result); +} + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __builtin_clz +/** + \details This function saturates a signed value. + \param [in] x Value to be saturated + \param [in] y Bit position to saturate to [1..32] + \return Saturated value. + */ +__ALWAYS_STATIC_INLINE int32_t __SSAT(int32_t x, unsigned long y) +{ + int32_t posMax, negMin; + unsigned long i; + + posMax = 1; + + for (i = 0; i < (y - 1); i++) { + posMax = posMax * 2; + } + + if (x > 0) { + posMax = (posMax - 1); + + if (x > posMax) { + x = posMax; + } + +// x &= (posMax * 2 + 1); + } else { + negMin = -posMax; + + if (x < negMin) { + x = negMin; + } + +// x &= (posMax * 2 - 1); + } + + return (x); +} + +/** + \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 + */ +__ALWAYS_STATIC_INLINE unsigned long __USAT(unsigned long value, unsigned long sat) +{ + unsigned long result; + + if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) { + result = 0xFFFFFFFF >> (32 - sat); + } else { + result = value; + } + + return (result); +} + +/** + \brief Unsigned Saturate for internal use + \details Saturates an unsigned value, should not call directly. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__ALWAYS_STATIC_INLINE unsigned long __IUSAT(unsigned long value, unsigned long sat) +{ + unsigned long result; + + if (value & 0x80000000) { /* only overflow set bit-31 */ + result = 0; + } else if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) { + result = 0xFFFFFFFF >> (32 - sat); + } else { + result = value; + } + + return (result); +} + +/** + \brief Rotate Right with Extend + \details This function moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \note carry input will always 0. + \param [in] op1 Value to rotate + \return Rotated value + */ +__ALWAYS_STATIC_INLINE unsigned long __RRX(unsigned long op1) +{ + return 0; +} + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] addr Pointer to location + \return value of type uint8_t at (*ptr) + */ +__ALWAYS_STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *addr) +{ + unsigned long result; + + __ASM volatile("lb %0, 0(%1)" : "=r"(result) : "r"(addr)); + + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] addr Pointer to location + \return value of type uint16_t at (*ptr) + */ +__ALWAYS_STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *addr) +{ + unsigned long result; + + __ASM volatile("lh %0, 0(%1)" : "=r"(result) : "r"(addr)); + + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] addr Pointer to location + \return value of type unsigned long at (*ptr) + */ +__ALWAYS_STATIC_INLINE unsigned long __LDRT(volatile unsigned long *addr) +{ + unsigned long result; + + __ASM volatile("lw %0, 0(%1)" : "=r"(result) : "r"(addr)); + + return (result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] addr Pointer to location + */ +__ALWAYS_STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr) +{ + __ASM volatile("sb %1, 0(%0)" :: "r"(addr), "r"((unsigned long)value) : "memory"); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] addr Pointer to location + */ +__ALWAYS_STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr) +{ + __ASM volatile("sh %1, 0(%0)" :: "r"(addr), "r"((unsigned long)value) : "memory"); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] addr Pointer to location + */ +__ALWAYS_STATIC_INLINE void __STRT(unsigned long value, volatile unsigned long *addr) +{ + __ASM volatile("sw %1, 0(%0)" :: "r"(addr), "r"(value) : "memory"); +} + +/*@}*/ /* end of group CSI_Core_InstructionInterface */ + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CSI_SIMD_intrinsics CSI SIMD Intrinsics + Access to dedicated SIMD instructions \n + Single Instruction Multiple Data (SIMD) extensions are provided to simplify development of application software. SIMD extensions increase the processing capability without materially increasing the power consumption. The SIMD extensions are completely transparent to the operating system (OS), allowing existing OS ports to be used. + + @{ +*/ + +/** + \brief Halfword packing instruction. Combines bits[15:0] of val1 with bits[31:16] + of val2 levitated with the val3. + \details Combine a halfword from one register with a halfword from another register. + The second argument can be left-shifted before extraction of the halfword. + \param [in] val1 first 16-bit operands + \param [in] val2 second 16-bit operands + \param [in] val3 value for left-shifting val2. Value range [0..31]. + \return the combination of halfwords. + \remark + res[15:0] = val1[15:0] \n + res[31:16] = val2[31:16] << val3 + */ +__ALWAYS_STATIC_INLINE unsigned long __PKHBT(unsigned long val1, unsigned long val2, unsigned long val3) +{ + return ((((int32_t)(val1) << 0) & (int32_t)0x0000FFFF) | (((int32_t)(val2) << val3) & (int32_t)0xFFFF0000)); +} + +/** + \brief Halfword packing instruction. Combines bits[31:16] of val1 with bits[15:0] + of val2 right-shifted with the val3. + \details Combine a halfword from one register with a halfword from another register. + The second argument can be right-shifted before extraction of the halfword. + \param [in] val1 first 16-bit operands + \param [in] val2 second 16-bit operands + \param [in] val3 value for right-shifting val2. Value range [1..32]. + \return the combination of halfwords. + \remark + res[15:0] = val2[15:0] >> val3 \n + res[31:16] = val1[31:16] + */ +__ALWAYS_STATIC_INLINE unsigned long __PKHTB(unsigned long val1, unsigned long val2, unsigned long val3) +{ + return ((((int32_t)(val1) << 0) & (int32_t)0xFFFF0000) | (((int32_t)(val2) >> val3) & (int32_t)0x0000FFFF)); +} + +/** + \brief Dual 16-bit signed saturate. + \details This function saturates a signed value. + \param [in] x two signed 16-bit values to be saturated. + \param [in] y bit position for saturation, an integral constant expression in the range 1 to 16. + \return the sum of the absolute differences of the following bytes, added to the accumulation value:\n + the signed saturation of the low halfword in val1, saturated to the bit position specified in + val2 and returned in the low halfword of the return value.\n + the signed saturation of the high halfword in val1, saturated to the bit position specified in + val2 and returned in the high halfword of the return value. + */ +__ALWAYS_STATIC_INLINE unsigned long __SSAT16(int32_t x, const unsigned long y) +{ + int32_t r = 0, s = 0; + + r = __SSAT((((int32_t)x << 16) >> 16), y) & (int32_t)0x0000FFFF; + s = __SSAT((((int32_t)x) >> 16), y) & (int32_t)0x0000FFFF; + + return ((unsigned long)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned saturate. + \details This function enables you to saturate two signed 16-bit values to a selected unsigned range. + \param [in] x two signed 16-bit values to be saturated. + \param [in] y bit position for saturation, an integral constant expression in the range 1 to 16. + \return the saturation of the two signed 16-bit values, as non-negative values: + the saturation of the low halfword in val1, saturated to the bit position specified in + val2 and returned in the low halfword of the return value.\n + the saturation of the high halfword in val1, saturated to the bit position specified in + val2 and returned in the high halfword of the return value. + */ +__ALWAYS_STATIC_INLINE unsigned long __USAT16(unsigned long x, const unsigned long y) +{ + int32_t r = 0, s = 0; + + r = __IUSAT(((x << 16) >> 16), y) & 0x0000FFFF; + s = __IUSAT(((x) >> 16), y) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Quad 8-bit saturating addition. + \details This function enables you to perform four 8-bit integer additions, + saturating the results to the 8-bit signed integer range -2^7 <= x <= 2^7 - 1. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the saturated addition of the first byte of each operand in the first byte of the return value.\n + the saturated addition of the second byte of each operand in the second byte of the return value.\n + the saturated addition of the third byte of each operand in the third byte of the return value.\n + the saturated addition of the fourth byte of each operand in the fourth byte of the return value.\n + The returned results are saturated to the 8-bit signed integer range -2^7 <= x <= 2^7 - 1. + \remark + res[7:0] = val1[7:0] + val2[7:0] \n + res[15:8] = val1[15:8] + val2[15:8] \n + res[23:16] = val1[23:16] + val2[23:16] \n + res[31:24] = val1[31:24] + val2[31:24] + */ +__ALWAYS_STATIC_INLINE unsigned long __QADD8(unsigned long x, unsigned long y) +{ + int32_t r, s, t, u; + + r = __SSAT(((((int32_t)x << 24) >> 24) + (((int32_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((int32_t)x << 16) >> 24) + (((int32_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((int32_t)x << 8) >> 24) + (((int32_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((int32_t)x) >> 24) + (((int32_t)y) >> 24)), 8) & (int32_t)0x000000FF; + + return ((unsigned long)((u << 24) | (t << 16) | (s << 8) | (r))); +} + +/** + \brief Quad 8-bit unsigned saturating addition. + \details This function enables you to perform four unsigned 8-bit integer additions, + saturating the results to the 8-bit unsigned integer range 0 < x < 2^8 - 1. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the saturated addition of the first byte of each operand in the first byte of the return value.\n + the saturated addition of the second byte of each operand in the second byte of the return value.\n + the saturated addition of the third byte of each operand in the third byte of the return value.\n + the saturated addition of the fourth byte of each operand in the fourth byte of the return value.\n + The returned results are saturated to the 8-bit signed integer range 0 <= x <= 2^8 - 1. + \remark + res[7:0] = val1[7:0] + val2[7:0] \n + res[15:8] = val1[15:8] + val2[15:8] \n + res[23:16] = val1[23:16] + val2[23:16] \n + res[31:24] = val1[31:24] + val2[31:24] + */ +__ALWAYS_STATIC_INLINE unsigned long __UQADD8(unsigned long x, unsigned long y) +{ + int32_t r, s, t, u; + + r = __IUSAT((((x << 24) >> 24) + ((y << 24) >> 24)), 8) & 0x000000FF; + s = __IUSAT((((x << 16) >> 24) + ((y << 16) >> 24)), 8) & 0x000000FF; + t = __IUSAT((((x << 8) >> 24) + ((y << 8) >> 24)), 8) & 0x000000FF; + u = __IUSAT((((x) >> 24) + ((y) >> 24)), 8) & 0x000000FF; + + return ((u << 24) | (t << 16) | (s << 8) | (r)); +} + +/** + \brief Quad 8-bit signed addition. + \details This function performs four 8-bit signed integer additions. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the addition of the first bytes from each operand, in the first byte of the return value.\n + the addition of the second bytes of each operand, in the second byte of the return value.\n + the addition of the third bytes of each operand, in the third byte of the return value.\n + the addition of the fourth bytes of each operand, in the fourth byte of the return value. + \remark + res[7:0] = val1[7:0] + val2[7:0] \n + res[15:8] = val1[15:8] + val2[15:8] \n + res[23:16] = val1[23:16] + val2[23:16] \n + res[31:24] = val1[31:24] + val2[31:24] + */ +__ALWAYS_STATIC_INLINE unsigned long __SADD8(unsigned long x, unsigned long y) +{ + int32_t r, s, t, u; + + r = ((((int32_t)x << 24) >> 24) + (((int32_t)y << 24) >> 24)) & (int32_t)0x000000FF; + s = ((((int32_t)x << 16) >> 24) + (((int32_t)y << 16) >> 24)) & (int32_t)0x000000FF; + t = ((((int32_t)x << 8) >> 24) + (((int32_t)y << 8) >> 24)) & (int32_t)0x000000FF; + u = ((((int32_t)x) >> 24) + (((int32_t)y) >> 24)) & (int32_t)0x000000FF; + + return ((unsigned long)((u << 24) | (t << 16) | (s << 8) | (r))); +} + +/** + \brief Quad 8-bit unsigned addition. + \details This function performs four unsigned 8-bit integer additions. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the addition of the first bytes from each operand, in the first byte of the return value.\n + the addition of the second bytes of each operand, in the second byte of the return value.\n + the addition of the third bytes of each operand, in the third byte of the return value.\n + the addition of the fourth bytes of each operand, in the fourth byte of the return value. + \remark + res[7:0] = val1[7:0] + val2[7:0] \n + res[15:8] = val1[15:8] + val2[15:8] \n + res[23:16] = val1[23:16] + val2[23:16] \n + res[31:24] = val1[31:24] + val2[31:24] + */ +__ALWAYS_STATIC_INLINE unsigned long __UADD8(unsigned long x, unsigned long y) +{ + int32_t r, s, t, u; + + r = (((x << 24) >> 24) + ((y << 24) >> 24)) & 0x000000FF; + s = (((x << 16) >> 24) + ((y << 16) >> 24)) & 0x000000FF; + t = (((x << 8) >> 24) + ((y << 8) >> 24)) & 0x000000FF; + u = (((x) >> 24) + ((y) >> 24)) & 0x000000FF; + + return ((u << 24) | (t << 16) | (s << 8) | (r)); +} + +/** + \brief Quad 8-bit saturating subtract. + \details This function enables you to perform four 8-bit integer subtractions, + saturating the results to the 8-bit signed integer range -2^7 <= x <= 2^7 - 1. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the subtraction of the first byte of each operand in the first byte of the return value.\n + the subtraction of the second byte of each operand in the second byte of the return value.\n + the subtraction of the third byte of each operand in the third byte of the return value.\n + the subtraction of the fourth byte of each operand in the fourth byte of the return value.\n + The returned results are saturated to the 8-bit signed integer range -2^7 <= x <= 2^7 - 1. + \remark + res[7:0] = val1[7:0] - val2[7:0] \n + res[15:8] = val1[15:8] - val2[15:8] \n + res[23:16] = val1[23:16] - val2[23:16] \n + res[31:24] = val1[31:24] - val2[31:24] + */ +__ALWAYS_STATIC_INLINE unsigned long __QSUB8(unsigned long x, unsigned long y) +{ + int32_t r, s, t, u; + + r = __SSAT(((((int32_t)x << 24) >> 24) - (((int32_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((int32_t)x << 16) >> 24) - (((int32_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((int32_t)x << 8) >> 24) - (((int32_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((int32_t)x) >> 24) - (((int32_t)y) >> 24)), 8) & (int32_t)0x000000FF; + + return ((unsigned long)((u << 24) | (t << 16) | (s << 8) | (r))); +} + +/** + \brief Quad 8-bit unsigned saturating subtraction. + \details This function enables you to perform four unsigned 8-bit integer subtractions, + saturating the results to the 8-bit unsigned integer range 0 < x < 2^8 - 1. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the subtraction of the first byte of each operand in the first byte of the return value.\n + the subtraction of the second byte of each operand in the second byte of the return value.\n + the subtraction of the third byte of each operand in the third byte of the return value.\n + the subtraction of the fourth byte of each operand in the fourth byte of the return value.\n + The returned results are saturated to the 8-bit unsigned integer range 0 <= x <= 2^8 - 1. + \remark + res[7:0] = val1[7:0] - val2[7:0] \n + res[15:8] = val1[15:8] - val2[15:8] \n + res[23:16] = val1[23:16] - val2[23:16] \n + res[31:24] = val1[31:24] - val2[31:24] + */ +__ALWAYS_STATIC_INLINE unsigned long __UQSUB8(unsigned long x, unsigned long y) +{ + int32_t r, s, t, u; + + r = __IUSAT((((x << 24) >> 24) - ((y << 24) >> 24)), 8) & 0x000000FF; + s = __IUSAT((((x << 16) >> 24) - ((y << 16) >> 24)), 8) & 0x000000FF; + t = __IUSAT((((x << 8) >> 24) - ((y << 8) >> 24)), 8) & 0x000000FF; + u = __IUSAT((((x) >> 24) - ((y) >> 24)), 8) & 0x000000FF; + + return ((u << 24) | (t << 16) | (s << 8) | (r)); +} + +/** + \brief Quad 8-bit signed subtraction. + \details This function enables you to perform four 8-bit signed integer subtractions. + \param [in] x first four 8-bit operands of each subtraction. + \param [in] y second four 8-bit operands of each subtraction. + \return the subtraction of the first bytes from each operand, in the first byte of the return value.\n + the subtraction of the second bytes of each operand, in the second byte of the return value.\n + the subtraction of the third bytes of each operand, in the third byte of the return value.\n + the subtraction of the fourth bytes of each operand, in the fourth byte of the return value. + \remark + res[7:0] = val1[7:0] - val2[7:0] \n + res[15:8] = val1[15:8] - val2[15:8] \n + res[23:16] = val1[23:16] - val2[23:16] \n + res[31:24] = val1[31:24] - val2[31:24] + */ +__ALWAYS_STATIC_INLINE unsigned long __SSUB8(unsigned long x, unsigned long y) +{ + int32_t r, s, t, u; + + r = ((((int32_t)x << 24) >> 24) - (((int32_t)y << 24) >> 24)) & (int32_t)0x000000FF; + s = ((((int32_t)x << 16) >> 24) - (((int32_t)y << 16) >> 24)) & (int32_t)0x000000FF; + t = ((((int32_t)x << 8) >> 24) - (((int32_t)y << 8) >> 24)) & (int32_t)0x000000FF; + u = ((((int32_t)x) >> 24) - (((int32_t)y) >> 24)) & (int32_t)0x000000FF; + + return ((unsigned long)((u << 24) | (t << 16) | (s << 8) | (r))); +} + +/** + \brief Quad 8-bit unsigned subtract. + \details This function enables you to perform four 8-bit unsigned integer subtractions. + \param [in] x first four 8-bit operands of each subtraction. + \param [in] y second four 8-bit operands of each subtraction. + \return the subtraction of the first bytes from each operand, in the first byte of the return value.\n + the subtraction of the second bytes of each operand, in the second byte of the return value.\n + the subtraction of the third bytes of each operand, in the third byte of the return value.\n + the subtraction of the fourth bytes of each operand, in the fourth byte of the return value. + \remark + res[7:0] = val1[7:0] - val2[7:0] \n + res[15:8] = val1[15:8] - val2[15:8] \n + res[23:16] = val1[23:16] - val2[23:16] \n + res[31:24] = val1[31:24] - val2[31:24] + */ +__ALWAYS_STATIC_INLINE unsigned long __USUB8(unsigned long x, unsigned long y) +{ + int32_t r, s, t, u; + + r = (((x << 24) >> 24) - ((y << 24) >> 24)) & 0x000000FF; + s = (((x << 16) >> 24) - ((y << 16) >> 24)) & 0x000000FF; + t = (((x << 8) >> 24) - ((y << 8) >> 24)) & 0x000000FF; + u = (((x) >> 24) - ((y) >> 24)) & 0x000000FF; + + return ((u << 24) | (t << 16) | (s << 8) | (r)); +} + +/** + \brief Unsigned sum of quad 8-bit unsigned absolute difference. + \details This function enables you to perform four unsigned 8-bit subtractions, and add the absolute values + of the differences together, returning the result as a single unsigned integer. + \param [in] x first four 8-bit operands of each subtraction. + \param [in] y second four 8-bit operands of each subtraction. + \return the subtraction of the first bytes from each operand, in the first byte of the return value.\n + the subtraction of the second bytes of each operand, in the second byte of the return value.\n + the subtraction of the third bytes of each operand, in the third byte of the return value.\n + the subtraction of the fourth bytes of each operand, in the fourth byte of the return value.\n + The sum is returned as a single unsigned integer. + \remark + absdiff1 = val1[7:0] - val2[7:0] \n + absdiff2 = val1[15:8] - val2[15:8] \n + absdiff3 = val1[23:16] - val2[23:16] \n + absdiff4 = val1[31:24] - val2[31:24] \n + res[31:0] = absdiff1 + absdiff2 + absdiff3 + absdiff4 + */ +__ALWAYS_STATIC_INLINE unsigned long __USAD8(unsigned long x, unsigned long y) +{ + int32_t r, s, t, u; + + r = (((x << 24) >> 24) - ((y << 24) >> 24)) & 0x000000FF; + s = (((x << 16) >> 24) - ((y << 16) >> 24)) & 0x000000FF; + t = (((x << 8) >> 24) - ((y << 8) >> 24)) & 0x000000FF; + u = (((x) >> 24) - ((y) >> 24)) & 0x000000FF; + + return (u + t + s + r); +} + +#if 0 +/** + \brief Unsigned sum of quad 8-bit unsigned absolute difference with 32-bit accumulate. + \details This function enables you to perform four unsigned 8-bit subtractions, and add the absolute values + of the differences to a 32-bit accumulate operand. + \param [in] x first four 8-bit operands of each subtraction. + \param [in] y second four 8-bit operands of each subtraction. + \param [in] sum accumulation value. + \return the sum of the absolute differences of the following bytes, added to the accumulation value: + the subtraction of the first bytes from each operand, in the first byte of the return value.\n + the subtraction of the second bytes of each operand, in the second byte of the return value.\n + the subtraction of the third bytes of each operand, in the third byte of the return value.\n + the subtraction of the fourth bytes of each operand, in the fourth byte of the return value. + \remark + absdiff1 = val1[7:0] - val2[7:0] \n + absdiff2 = val1[15:8] - val2[15:8] \n + absdiff3 = val1[23:16] - val2[23:16] \n + absdiff4 = val1[31:24] - val2[31:24] \n + sum = absdiff1 + absdiff2 + absdiff3 + absdiff4 \n + res[31:0] = sum[31:0] + val3[31:0] + */ +__ALWAYS_STATIC_INLINE unsigned long __USADA8(unsigned long x, unsigned long y, unsigned long sum) +{ + int32_t r, s, t, u; + +#ifdef __cplusplus + r = (abs((long long)((x << 24) >> 24) - ((y << 24) >> 24))) & 0x000000FF; + s = (abs((long long)((x << 16) >> 24) - ((y << 16) >> 24))) & 0x000000FF; + t = (abs((long long)((x << 8) >> 24) - ((y << 8) >> 24))) & 0x000000FF; + u = (abs((long long)((x) >> 24) - ((y) >> 24))) & 0x000000FF; +#else + r = (abs(((x << 24) >> 24) - ((y << 24) >> 24))) & 0x000000FF; + s = (abs(((x << 16) >> 24) - ((y << 16) >> 24))) & 0x000000FF; + t = (abs(((x << 8) >> 24) - ((y << 8) >> 24))) & 0x000000FF; + u = (abs(((x) >> 24) - ((y) >> 24))) & 0x000000FF; +#endif + return (u + t + s + r + sum); +} +#endif + +/** + \brief Dual 16-bit saturating addition. + \details This function enables you to perform two 16-bit integer arithmetic additions in parallel, + saturating the results to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the saturated addition of the low halfwords, in the low halfword of the return value.\n + the saturated addition of the high halfwords, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \remark + res[15:0] = val1[15:0] + val2[15:0] \n + res[31:16] = val1[31:16] + val2[31:16] + */ +__ALWAYS_STATIC_INLINE unsigned long __QADD16(unsigned long x, unsigned long y) +{ + int32_t r = 0, s = 0; + + r = __SSAT(((((int32_t)x << 16) >> 16) + (((int32_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((int32_t)x) >> 16) + (((int32_t)y) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((unsigned long)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned saturating addition. + \details This function enables you to perform two unsigned 16-bit integer additions, saturating + the results to the 16-bit unsigned integer range 0 < x < 2^16 - 1. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the saturated addition of the low halfwords, in the low halfword of the return value.\n + the saturated addition of the high halfwords, in the high halfword of the return value.\n + The results are saturated to the 16-bit unsigned integer range 0 < x < 2^16 - 1. + \remark + res[15:0] = val1[15:0] + val2[15:0] \n + res[31:16] = val1[31:16] + val2[31:16] + */ +__ALWAYS_STATIC_INLINE unsigned long __UQADD16(unsigned long x, unsigned long y) +{ + int32_t r = 0, s = 0; + + r = __IUSAT((((x << 16) >> 16) + ((y << 16) >> 16)), 16) & 0x0000FFFF; + s = __IUSAT((((x) >> 16) + ((y) >> 16)), 16) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit signed addition. + \details This function enables you to perform two 16-bit signed integer additions. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the addition of the low halfwords in the low halfword of the return value.\n + the addition of the high halfwords in the high halfword of the return value. + \remark + res[15:0] = val1[15:0] + val2[15:0] \n + res[31:16] = val1[31:16] + val2[31:16] + */ +__ALWAYS_STATIC_INLINE unsigned long __SADD16(unsigned long x, unsigned long y) +{ + int32_t r = 0, s = 0; + + r = ((((int32_t)x << 16) >> 16) + (((int32_t)y << 16) >> 16)) & (int32_t)0x0000FFFF; + s = ((((int32_t)x) >> 16) + (((int32_t)y) >> 16)) & (int32_t)0x0000FFFF; + + return ((unsigned long)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned addition + \details This function enables you to perform two 16-bit unsigned integer additions. + \param [in] x first two 16-bit summands for each addition. + \param [in] y second two 16-bit summands for each addition. + \return the addition of the low halfwords in the low halfword of the return value.\n + the addition of the high halfwords in the high halfword of the return value. + \remark + res[15:0] = val1[15:0] + val2[15:0] \n + res[31:16] = val1[31:16] + val2[31:16] + */ +__ALWAYS_STATIC_INLINE unsigned long __UADD16(unsigned long x, unsigned long y) +{ + int32_t r = 0, s = 0; + + r = (((x << 16) >> 16) + ((y << 16) >> 16)) & 0x0000FFFF; + s = (((x) >> 16) + ((y) >> 16)) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + + +/** + \brief Dual 16-bit signed addition with halved results. + \details This function enables you to perform two signed 16-bit integer additions, halving the results. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the halved addition of the low halfwords, in the low halfword of the return value.\n + the halved addition of the high halfwords, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] + val2[15:0]) >> 1 \n + res[31:16] = (val1[31:16] + val2[31:16]) >> 1 + */ +__ALWAYS_STATIC_INLINE unsigned long __SHADD16(unsigned long x, unsigned long y) +{ + int32_t r, s; + + r = (((((int32_t)x << 16) >> 16) + (((int32_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((int32_t)x) >> 16) + (((int32_t)y) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((unsigned long)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned addition with halved results. + \details This function enables you to perform two unsigned 16-bit integer additions, halving the results. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the halved addition of the low halfwords, in the low halfword of the return value.\n + the halved addition of the high halfwords, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] + val2[15:0]) >> 1 \n + res[31:16] = (val1[31:16] + val2[31:16]) >> 1 + */ +__ALWAYS_STATIC_INLINE unsigned long __UHADD16(unsigned long x, unsigned long y) +{ + int32_t r, s; + + r = ((((x << 16) >> 16) + ((y << 16) >> 16)) >> 1) & 0x0000FFFF; + s = ((((x) >> 16) + ((y) >> 16)) >> 1) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Quad 8-bit signed addition with halved results. + \details This function enables you to perform four signed 8-bit integer additions, halving the results. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the halved addition of the first bytes from each operand, in the first byte of the return value.\n + the halved addition of the second bytes from each operand, in the second byte of the return value.\n + the halved addition of the third bytes from each operand, in the third byte of the return value.\n + the halved addition of the fourth bytes from each operand, in the fourth byte of the return value. + \remark + res[7:0] = (val1[7:0] + val2[7:0] ) >> 1 \n + res[15:8] = (val1[15:8] + val2[15:8] ) >> 1 \n + res[23:16] = (val1[23:16] + val2[23:16]) >> 1 \n + res[31:24] = (val1[31:24] + val2[31:24]) >> 1 + */ +__ALWAYS_STATIC_INLINE unsigned long __SHADD8(unsigned long x, unsigned long y) +{ + int32_t r, s, t, u; + + r = (((((int32_t)x << 24) >> 24) + (((int32_t)y << 24) >> 24)) >> 1) & (int32_t)0x000000FF; + s = (((((int32_t)x << 16) >> 24) + (((int32_t)y << 16) >> 24)) >> 1) & (int32_t)0x000000FF; + t = (((((int32_t)x << 8) >> 24) + (((int32_t)y << 8) >> 24)) >> 1) & (int32_t)0x000000FF; + u = (((((int32_t)x) >> 24) + (((int32_t)y) >> 24)) >> 1) & (int32_t)0x000000FF; + + return ((unsigned long)((u << 24) | (t << 16) | (s << 8) | (r))); +} + +/** + \brief Quad 8-bit unsigned addition with halved results. + \details This function enables you to perform four unsigned 8-bit integer additions, halving the results. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the halved addition of the first bytes from each operand, in the first byte of the return value.\n + the halved addition of the second bytes from each operand, in the second byte of the return value.\n + the halved addition of the third bytes from each operand, in the third byte of the return value.\n + the halved addition of the fourth bytes from each operand, in the fourth byte of the return value. + \remark + res[7:0] = (val1[7:0] + val2[7:0] ) >> 1 \n + res[15:8] = (val1[15:8] + val2[15:8] ) >> 1 \n + res[23:16] = (val1[23:16] + val2[23:16]) >> 1 \n + res[31:24] = (val1[31:24] + val2[31:24]) >> 1 + */ +__ALWAYS_STATIC_INLINE unsigned long __UHADD8(unsigned long x, unsigned long y) +{ + int32_t r, s, t, u; + + r = ((((x << 24) >> 24) + ((y << 24) >> 24)) >> 1) & 0x000000FF; + s = ((((x << 16) >> 24) + ((y << 16) >> 24)) >> 1) & 0x000000FF; + t = ((((x << 8) >> 24) + ((y << 8) >> 24)) >> 1) & 0x000000FF; + u = ((((x) >> 24) + ((y) >> 24)) >> 1) & 0x000000FF; + + return ((u << 24) | (t << 16) | (s << 8) | (r)); +} + +/** + \brief Dual 16-bit saturating subtract. + \details This function enables you to perform two 16-bit integer subtractions in parallel, + saturating the results to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the saturated subtraction of the low halfwords, in the low halfword of the return value.\n + the saturated subtraction of the high halfwords, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \remark + res[15:0] = val1[15:0] - val2[15:0] \n + res[31:16] = val1[31:16] - val2[31:16] + */ +__ALWAYS_STATIC_INLINE unsigned long __QSUB16(unsigned long x, unsigned long y) +{ + int32_t r, s; + + r = __SSAT(((((int32_t)x << 16) >> 16) - (((int32_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((int32_t)x) >> 16) - (((int32_t)y) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((unsigned long)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned saturating subtraction. + \details This function enables you to perform two unsigned 16-bit integer subtractions, + saturating the results to the 16-bit unsigned integer range 0 < x < 2^16 - 1. + \param [in] x first two 16-bit operands for each subtraction. + \param [in] y second two 16-bit operands for each subtraction. + \return the saturated subtraction of the low halfwords, in the low halfword of the return value.\n + the saturated subtraction of the high halfwords, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \remark + res[15:0] = val1[15:0] - val2[15:0] \n + res[31:16] = val1[31:16] - val2[31:16] + */ +__ALWAYS_STATIC_INLINE unsigned long __UQSUB16(unsigned long x, unsigned long y) +{ + int32_t r, s; + + r = __IUSAT((((x << 16) >> 16) - ((y << 16) >> 16)), 16) & 0x0000FFFF; + s = __IUSAT((((x) >> 16) - ((y) >> 16)), 16) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit signed subtraction. + \details This function enables you to perform two 16-bit signed integer subtractions. + \param [in] x first two 16-bit operands of each subtraction. + \param [in] y second two 16-bit operands of each subtraction. + \return the subtraction of the low halfword in the second operand from the low + halfword in the first operand, in the low halfword of the return value. \n + the subtraction of the high halfword in the second operand from the high + halfword in the first operand, in the high halfword of the return value. + \remark + res[15:0] = val1[15:0] - val2[15:0] \n + res[31:16] = val1[31:16] - val2[31:16] + */ +__ALWAYS_STATIC_INLINE unsigned long __SSUB16(unsigned long x, unsigned long y) +{ + int32_t r, s; + + r = ((((int32_t)x << 16) >> 16) - (((int32_t)y << 16) >> 16)) & (int32_t)0x0000FFFF; + s = ((((int32_t)x) >> 16) - (((int32_t)y) >> 16)) & (int32_t)0x0000FFFF; + + return ((unsigned long)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned subtract. + \details This function enables you to perform two 16-bit unsigned integer subtractions. + \param [in] x first two 16-bit operands of each subtraction. + \param [in] y second two 16-bit operands of each subtraction. + \return the subtraction of the low halfword in the second operand from the low + halfword in the first operand, in the low halfword of the return value. \n + the subtraction of the high halfword in the second operand from the high + halfword in the first operand, in the high halfword of the return value. + \remark + res[15:0] = val1[15:0] - val2[15:0] \n + res[31:16] = val1[31:16] - val2[31:16] + */ +__ALWAYS_STATIC_INLINE unsigned long __USUB16(unsigned long x, unsigned long y) +{ + int32_t r, s; + + r = (((x << 16) >> 16) - ((y << 16) >> 16)) & 0x0000FFFF; + s = (((x) >> 16) - ((y) >> 16)) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit signed subtraction with halved results. + \details This function enables you to perform two signed 16-bit integer subtractions, halving the results. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the halved subtraction of the low halfwords, in the low halfword of the return value.\n + the halved subtraction of the high halfwords, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] - val2[15:0]) >> 1 \n + res[31:16] = (val1[31:16] - val2[31:16]) >> 1 + */ +__ALWAYS_STATIC_INLINE unsigned long __SHSUB16(unsigned long x, unsigned long y) +{ + int32_t r, s; + + r = (((((int32_t)x << 16) >> 16) - (((int32_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((int32_t)x) >> 16) - (((int32_t)y) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((unsigned long)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned subtraction with halved results. + \details This function enables you to perform two unsigned 16-bit integer subtractions, halving the results. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the halved subtraction of the low halfwords, in the low halfword of the return value.\n + the halved subtraction of the high halfwords, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] - val2[15:0]) >> 1 \n + res[31:16] = (val1[31:16] - val2[31:16]) >> 1 + */ +__ALWAYS_STATIC_INLINE unsigned long __UHSUB16(unsigned long x, unsigned long y) +{ + int32_t r, s; + + r = ((((x << 16) >> 16) - ((y << 16) >> 16)) >> 1) & 0x0000FFFF; + s = ((((x) >> 16) - ((y) >> 16)) >> 1) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Quad 8-bit signed addition with halved results. + \details This function enables you to perform four signed 8-bit integer subtractions, halving the results. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the halved subtraction of the first bytes from each operand, in the first byte of the return value.\n + the halved subtraction of the second bytes from each operand, in the second byte of the return value.\n + the halved subtraction of the third bytes from each operand, in the third byte of the return value.\n + the halved subtraction of the fourth bytes from each operand, in the fourth byte of the return value. + \remark + res[7:0] = (val1[7:0] - val2[7:0] ) >> 1 \n + res[15:8] = (val1[15:8] - val2[15:8] ) >> 1 \n + res[23:16] = (val1[23:16] - val2[23:16]) >> 1 \n + res[31:24] = (val1[31:24] - val2[31:24]) >> 1 + */ +__ALWAYS_STATIC_INLINE unsigned long __SHSUB8(unsigned long x, unsigned long y) +{ + int32_t r, s, t, u; + + r = (((((int32_t)x << 24) >> 24) - (((int32_t)y << 24) >> 24)) >> 1) & (int32_t)0x000000FF; + s = (((((int32_t)x << 16) >> 24) - (((int32_t)y << 16) >> 24)) >> 1) & (int32_t)0x000000FF; + t = (((((int32_t)x << 8) >> 24) - (((int32_t)y << 8) >> 24)) >> 1) & (int32_t)0x000000FF; + u = (((((int32_t)x) >> 24) - (((int32_t)y) >> 24)) >> 1) & (int32_t)0x000000FF; + + return ((unsigned long)((u << 24) | (t << 16) | (s << 8) | (r))); +} + +/** + \brief Quad 8-bit unsigned subtraction with halved results. + \details This function enables you to perform four unsigned 8-bit integer subtractions, halving the results. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the halved subtraction of the first bytes from each operand, in the first byte of the return value.\n + the halved subtraction of the second bytes from each operand, in the second byte of the return value.\n + the halved subtraction of the third bytes from each operand, in the third byte of the return value.\n + the halved subtraction of the fourth bytes from each operand, in the fourth byte of the return value. + \remark + res[7:0] = (val1[7:0] - val2[7:0] ) >> 1 \n + res[15:8] = (val1[15:8] - val2[15:8] ) >> 1 \n + res[23:16] = (val1[23:16] - val2[23:16]) >> 1 \n + res[31:24] = (val1[31:24] - val2[31:24]) >> 1 + */ +__ALWAYS_STATIC_INLINE unsigned long __UHSUB8(unsigned long x, unsigned long y) +{ + int32_t r, s, t, u; + + r = ((((x << 24) >> 24) - ((y << 24) >> 24)) >> 1) & 0x000000FF; + s = ((((x << 16) >> 24) - ((y << 16) >> 24)) >> 1) & 0x000000FF; + t = ((((x << 8) >> 24) - ((y << 8) >> 24)) >> 1) & 0x000000FF; + u = ((((x) >> 24) - ((y) >> 24)) >> 1) & 0x000000FF; + + return ((u << 24) | (t << 16) | (s << 8) | (r)); +} + +/** + \brief Dual 16-bit add and subtract with exchange. + \details This function enables you to exchange the halfwords of the one operand, + then add the high halfwords and subtract the low halfwords, + saturating the results to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \param [in] x first operand for the subtraction in the low halfword, + and the first operand for the addition in the high halfword. + \param [in] y second operand for the subtraction in the high halfword, + and the second operand for the addition in the low halfword. + \return the saturated subtraction of the high halfword in the second operand from the + low halfword in the first operand, in the low halfword of the return value.\n + the saturated addition of the high halfword in the first operand and the + low halfword in the second operand, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \remark + res[15:0] = val1[15:0] - val2[31:16] \n + res[31:16] = val1[31:16] + val2[15:0] + */ +__ALWAYS_STATIC_INLINE unsigned long __QASX(unsigned long x, unsigned long y) +{ + int32_t r, s; + + r = __SSAT(((((int32_t)x << 16) >> 16) - (((int32_t)y) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((int32_t)x) >> 16) + (((int32_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((unsigned long)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned saturating addition and subtraction with exchange. + \details This function enables you to exchange the halfwords of the second operand and + perform one unsigned 16-bit integer addition and one unsigned 16-bit subtraction, + saturating the results to the 16-bit unsigned integer range 0 <= x <= 2^16 - 1. + \param [in] x first operand for the subtraction in the low halfword, + and the first operand for the addition in the high halfword. + \param [in] y second operand for the subtraction in the high halfword, + and the second operand for the addition in the low halfword. + \return the saturated subtraction of the high halfword in the second operand from the + low halfword in the first operand, in the low halfword of the return value.\n + the saturated addition of the high halfword in the first operand and the + low halfword in the second operand, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit unsigned integer range 0 <= x <= 2^16 - 1. + \remark + res[15:0] = val1[15:0] - val2[31:16] \n + res[31:16] = val1[31:16] + val2[15:0] + */ +__ALWAYS_STATIC_INLINE unsigned long __UQASX(unsigned long x, unsigned long y) +{ + int32_t r, s; + + r = __IUSAT((((x << 16) >> 16) - ((y) >> 16)), 16) & 0x0000FFFF; + s = __IUSAT((((x) >> 16) + ((y << 16) >> 16)), 16) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit addition and subtraction with exchange. + \details It enables you to exchange the halfwords of the second operand, add the high halfwords + and subtract the low halfwords. + \param [in] x first operand for the subtraction in the low halfword, + and the first operand for the addition in the high halfword. + \param [in] y second operand for the subtraction in the high halfword, + and the second operand for the addition in the low halfword. + \return the subtraction of the high halfword in the second operand from the + low halfword in the first operand, in the low halfword of the return value.\n + the addition of the high halfword in the first operand and the + low halfword in the second operand, in the high halfword of the return value. + \remark + res[15:0] = val1[15:0] - val2[31:16] \n + res[31:16] = val1[31:16] + val2[15:0] + */ +__ALWAYS_STATIC_INLINE unsigned long __SASX(unsigned long x, unsigned long y) +{ + int32_t r, s; + + r = ((((int32_t)x << 16) >> 16) - (((int32_t)y) >> 16)) & (int32_t)0x0000FFFF; + s = ((((int32_t)x) >> 16) + (((int32_t)y << 16) >> 16)) & (int32_t)0x0000FFFF; + + return ((unsigned long)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned addition and subtraction with exchange. + \details This function enables you to exchange the two halfwords of the second operand, + add the high halfwords and subtract the low halfwords. + \param [in] x first operand for the subtraction in the low halfword, + and the first operand for the addition in the high halfword. + \param [in] y second operand for the subtraction in the high halfword, + and the second operand for the addition in the low halfword. + \return the subtraction of the high halfword in the second operand from the + low halfword in the first operand, in the low halfword of the return value.\n + the addition of the high halfword in the first operand and the + low halfword in the second operand, in the high halfword of the return value. + \remark + res[15:0] = val1[15:0] - val2[31:16] \n + res[31:16] = val1[31:16] + val2[15:0] + */ +__ALWAYS_STATIC_INLINE unsigned long __UASX(unsigned long x, unsigned long y) +{ + int32_t r, s; + + r = (((x << 16) >> 16) - ((y) >> 16)) & 0x0000FFFF; + s = (((x) >> 16) + ((y << 16) >> 16)) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit signed addition and subtraction with halved results. + \details This function enables you to exchange the two halfwords of one operand, perform one + signed 16-bit integer addition and one signed 16-bit subtraction, and halve the results. + \param [in] x first 16-bit operands. + \param [in] y second 16-bit operands. + \return the halved subtraction of the high halfword in the second operand from the + low halfword in the first operand, in the low halfword of the return value.\n + the halved addition of the low halfword in the second operand from the high + halfword in the first operand, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] - val2[31:16]) >> 1 \n + res[31:16] = (val1[31:16] + val2[15:0]) >> 1 + */ +__ALWAYS_STATIC_INLINE unsigned long __SHASX(unsigned long x, unsigned long y) +{ + int32_t r, s; + + r = (((((int32_t)x << 16) >> 16) - (((int32_t)y) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((int32_t)x) >> 16) + (((int32_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((unsigned long)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned addition and subtraction with halved results and exchange. + \details This function enables you to exchange the halfwords of the second operand, + add the high halfwords and subtract the low halfwords, halving the results. + \param [in] x first operand for the subtraction in the low halfword, and + the first operand for the addition in the high halfword. + \param [in] y second operand for the subtraction in the high halfword, and + the second operand for the addition in the low halfword. + \return the halved subtraction of the high halfword in the second operand from the + low halfword in the first operand, in the low halfword of the return value.\n + the halved addition of the low halfword in the second operand from the high + halfword in the first operand, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] - val2[31:16]) >> 1 \n + res[31:16] = (val1[31:16] + val2[15:0]) >> 1 + */ +__ALWAYS_STATIC_INLINE unsigned long __UHASX(unsigned long x, unsigned long y) +{ + int32_t r, s; + + r = ((((x << 16) >> 16) - ((y) >> 16)) >> 1) & 0x0000FFFF; + s = ((((x) >> 16) + ((y << 16) >> 16)) >> 1) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit subtract and add with exchange. + \details This function enables you to exchange the halfwords of one operand, + then subtract the high halfwords and add the low halfwords, + saturating the results to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \param [in] x first operand for the addition in the low halfword, + and the first operand for the subtraction in the high halfword. + \param [in] y second operand for the addition in the high halfword, + and the second operand for the subtraction in the low halfword. + \return the saturated addition of the low halfword of the first operand and the high + halfword of the second operand, in the low halfword of the return value.\n + the saturated subtraction of the low halfword of the second operand from the + high halfword of the first operand, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \remark + res[15:0] = val1[15:0] + val2[31:16] \n + res[31:16] = val1[31:16] - val2[15:0] + */ +__ALWAYS_STATIC_INLINE unsigned long __QSAX(unsigned long x, unsigned long y) +{ + int32_t r, s; + + r = __SSAT(((((int32_t)x << 16) >> 16) + (((int32_t)y) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((int32_t)x) >> 16) - (((int32_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((unsigned long)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned saturating subtraction and addition with exchange. + \details This function enables you to exchange the halfwords of the second operand and perform + one unsigned 16-bit integer subtraction and one unsigned 16-bit addition, saturating + the results to the 16-bit unsigned integer range 0 <= x <= 2^16 - 1. + \param [in] x first operand for the addition in the low halfword, + and the first operand for the subtraction in the high halfword. + \param [in] y second operand for the addition in the high halfword, + and the second operand for the subtraction in the low halfword. + \return the saturated addition of the low halfword of the first operand and the high + halfword of the second operand, in the low halfword of the return value.\n + the saturated subtraction of the low halfword of the second operand from the + high halfword of the first operand, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit unsigned integer range 0 <= x <= 2^16 - 1. + \remark + res[15:0] = val1[15:0] + val2[31:16] \n + res[31:16] = val1[31:16] - val2[15:0] + */ +__ALWAYS_STATIC_INLINE unsigned long __UQSAX(unsigned long x, unsigned long y) +{ + int32_t r, s; + + r = __IUSAT((((x << 16) >> 16) + ((y) >> 16)), 16) & 0x0000FFFF; + s = __IUSAT((((x) >> 16) - ((y << 16) >> 16)), 16) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit unsigned subtract and add with exchange. + \details This function enables you to exchange the halfwords of the second operand, + subtract the high halfwords and add the low halfwords. + \param [in] x first operand for the addition in the low halfword, + and the first operand for the subtraction in the high halfword. + \param [in] y second operand for the addition in the high halfword, + and the second operand for the subtraction in the low halfword. + \return the addition of the low halfword of the first operand and the high + halfword of the second operand, in the low halfword of the return value.\n + the subtraction of the low halfword of the second operand from the + high halfword of the first operand, in the high halfword of the return value.\n + \remark + res[15:0] = val1[15:0] + val2[31:16] \n + res[31:16] = val1[31:16] - val2[15:0] + */ +__ALWAYS_STATIC_INLINE unsigned long __USAX(unsigned long x, unsigned long y) +{ + int32_t r, s; + + r = (((x << 16) >> 16) + ((y) >> 16)) & 0x0000FFFF; + s = (((x) >> 16) - ((y << 16) >> 16)) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit signed subtraction and addition with exchange. + \details This function enables you to exchange the two halfwords of one operand and perform one + 16-bit integer subtraction and one 16-bit addition. + \param [in] x first operand for the addition in the low halfword, and the first operand + for the subtraction in the high halfword. + \param [in] y second operand for the addition in the high halfword, and the second + operand for the subtraction in the low halfword. + \return the addition of the low halfword of the first operand and the high + halfword of the second operand, in the low halfword of the return value.\n + the subtraction of the low halfword of the second operand from the + high halfword of the first operand, in the high halfword of the return value.\n + \remark + res[15:0] = val1[15:0] + val2[31:16] \n + res[31:16] = val1[31:16] - val2[15:0] + */ +__ALWAYS_STATIC_INLINE unsigned long __SSAX(unsigned long x, unsigned long y) +{ + int32_t r, s; + + r = ((((int32_t)x << 16) >> 16) + (((int32_t)y) >> 16)) & (int32_t)0x0000FFFF; + s = ((((int32_t)x) >> 16) - (((int32_t)y << 16) >> 16)) & (int32_t)0x0000FFFF; + + return ((unsigned long)((s << 16) | (r))); +} + + +/** + \brief Dual 16-bit signed subtraction and addition with halved results. + \details This function enables you to exchange the two halfwords of one operand, perform one signed + 16-bit integer subtraction and one signed 16-bit addition, and halve the results. + \param [in] x first 16-bit operands. + \param [in] y second 16-bit operands. + \return the halved addition of the low halfword in the first operand and the + high halfword in the second operand, in the low halfword of the return value.\n + the halved subtraction of the low halfword in the second operand from the + high halfword in the first operand, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] + val2[31:16]) >> 1 \n + res[31:16] = (val1[31:16] - val2[15:0]) >> 1 + */ +__ALWAYS_STATIC_INLINE unsigned long __SHSAX(unsigned long x, unsigned long y) +{ + int32_t r, s; + + r = (((((int32_t)x << 16) >> 16) + (((int32_t)y) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((int32_t)x) >> 16) - (((int32_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((unsigned long)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned subtraction and addition with halved results and exchange. + \details This function enables you to exchange the halfwords of the second operand, + subtract the high halfwords and add the low halfwords, halving the results. + \param [in] x first operand for the addition in the low halfword, and + the first operand for the subtraction in the high halfword. + \param [in] y second operand for the addition in the high halfword, and + the second operand for the subtraction in the low halfword. + \return the halved addition of the low halfword in the first operand and the + high halfword in the second operand, in the low halfword of the return value.\n + the halved subtraction of the low halfword in the second operand from the + high halfword in the first operand, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] + val2[31:16]) >> 1 \n + res[31:16] = (val1[31:16] - val2[15:0]) >> 1 + */ +__ALWAYS_STATIC_INLINE unsigned long __UHSAX(unsigned long x, unsigned long y) +{ + int32_t r, s; + + r = ((((x << 16) >> 16) + ((y) >> 16)) >> 1) & 0x0000FFFF; + s = ((((x) >> 16) - ((y << 16) >> 16)) >> 1) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit signed multiply with exchange returning difference. + \details This function enables you to perform two 16-bit signed multiplications, subtracting + one of the products from the other. The halfwords of the second operand are exchanged + before performing the arithmetic. This produces top * bottom and bottom * top multiplication. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \return the difference of the products of the two 16-bit signed multiplications. + \remark + p1 = val1[15:0] * val2[31:16] \n + p2 = val1[31:16] * val2[15:0] \n + res[31:0] = p1 - p2 + */ +__ALWAYS_STATIC_INLINE unsigned long __SMUSDX(unsigned long x, unsigned long y) +{ + return ((unsigned long)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) - + ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)))); +} + +/** + \brief Sum of dual 16-bit signed multiply with exchange. + \details This function enables you to perform two 16-bit signed multiplications with exchanged + halfwords of the second operand, adding the products together. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \return the sum of the products of the two 16-bit signed multiplications with exchanged halfwords of the second operand. + \remark + p1 = val1[15:0] * val2[31:16] \n + p2 = val1[31:16] * val2[15:0] \n + res[31:0] = p1 + p2 + */ +__ALWAYS_STATIC_INLINE unsigned long __SMUADX(unsigned long x, unsigned long y) +{ + return ((unsigned long)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) + + ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)))); +} + + +/** + \brief Saturating add. + \details This function enables you to obtain the saturating add of two integers. + \param [in] x first summand of the saturating add operation. + \param [in] y second summand of the saturating add operation. + \return the saturating addition of val1 and val2. + \remark + res[31:0] = SAT(val1 + SAT(val2)) + */ +__ALWAYS_STATIC_INLINE int32_t __QADD(int32_t x, int32_t y) +{ + int32_t result; + + if (y >= 0) { + if ((int32_t)((unsigned long)x + (unsigned long)y) >= x) { + result = x + y; + } else { + result = 0x7FFFFFFF; + } + } else { + if ((int32_t)((unsigned long)x + (unsigned long)y) < x) { + result = x + y; + } else { + result = 0x80000000; + } + } + + return result; +} + +/** + \brief Saturating subtract. + \details This function enables you to obtain the saturating add of two integers. + \param [in] x first summand of the saturating add operation. + \param [in] y second summand of the saturating add operation. + \return the saturating addition of val1 and val2. + \remark + res[31:0] = SAT(val1 - SAT(val2)) + */ +__ALWAYS_STATIC_INLINE int32_t __QSUB(int32_t x, int32_t y) +{ + int64_t tmp; + int32_t result; + + tmp = (int64_t)x - (int64_t)y; + + if (tmp > 0x7fffffff) { + tmp = 0x7fffffff; + } else if (tmp < (-2147483647 - 1)) { + tmp = -2147483647 - 1; + } + + result = tmp; + return result; +} + +/** + \brief Dual 16-bit signed multiply with single 32-bit accumulator. + \details This function enables you to perform two signed 16-bit multiplications, + adding both results to a 32-bit accumulate operand. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the product of each multiplication added to the accumulate value, as a 32-bit integer. + \remark + p1 = val1[15:0] * val2[15:0] \n + p2 = val1[31:16] * val2[31:16] \n + res[31:0] = p1 + p2 + val3[31:0] + */ +__ALWAYS_STATIC_INLINE unsigned long __SMLAD(unsigned long x, unsigned long y, unsigned long sum) +{ + return ((unsigned long)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) + + ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)) + + (((int32_t)sum)))); +} + +/** + \brief Pre-exchanged dual 16-bit signed multiply with single 32-bit accumulator. + \details This function enables you to perform two signed 16-bit multiplications with exchanged + halfwords of the second operand, adding both results to a 32-bit accumulate operand. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the product of each multiplication with exchanged halfwords of the second + operand added to the accumulate value, as a 32-bit integer. + \remark + p1 = val1[15:0] * val2[31:16] \n + p2 = val1[31:16] * val2[15:0] \n + res[31:0] = p1 + p2 + val3[31:0] + */ +__ALWAYS_STATIC_INLINE unsigned long __SMLADX(unsigned long x, unsigned long y, unsigned long sum) +{ + return ((unsigned long)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) + + ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)) + + (((int32_t)sum)))); +} + +/** + \brief Dual 16-bit signed multiply with exchange subtract with 32-bit accumulate. + \details This function enables you to perform two 16-bit signed multiplications, take the + difference of the products, subtracting the high halfword product from the low + halfword product, and add the difference to a 32-bit accumulate operand. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the difference of the product of each multiplication, added to the accumulate value. + \remark + p1 = val1[15:0] * val2[15:0] \n + p2 = val1[31:16] * val2[31:16] \n + res[31:0] = p1 - p2 + val3[31:0] + */ +__ALWAYS_STATIC_INLINE unsigned long __SMLSD(unsigned long x, unsigned long y, unsigned long sum) +{ + return ((unsigned long)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) - + ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)) + + (((int32_t)sum)))); +} + +/** + \brief Dual 16-bit signed multiply with exchange subtract with 32-bit accumulate. + \details This function enables you to exchange the halfwords in the second operand, then perform two 16-bit + signed multiplications. The difference of the products is added to a 32-bit accumulate operand. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the difference of the product of each multiplication, added to the accumulate value. + \remark + p1 = val1[15:0] * val2[31:16] \n + p2 = val1[31:16] * val2[15:0] \n + res[31:0] = p1 - p2 + val3[31:0] + */ +__ALWAYS_STATIC_INLINE unsigned long __SMLSDX(unsigned long x, unsigned long y, unsigned long sum) +{ + return ((unsigned long)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) - + ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)) + + (((int32_t)sum)))); +} + +/** + \brief Dual 16-bit signed multiply with single 64-bit accumulator. + \details This function enables you to perform two signed 16-bit multiplications, adding both results + to a 64-bit accumulate operand. Overflow is only possible as a result of the 64-bit addition. + This overflow is not detected if it occurs. Instead, the result wraps around modulo2^64. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the product of each multiplication added to the accumulate value. + \remark + p1 = val1[15:0] * val2[15:0] \n + p2 = val1[31:16] * val2[31:16] \n + sum = p1 + p2 + val3[63:32][31:0] \n + res[63:32] = sum[63:32] \n + res[31:0] = sum[31:0] + */ +__ALWAYS_STATIC_INLINE uint64_t __SMLALD(unsigned long x, unsigned long y, uint64_t sum) +{ + return ((uint64_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) + + ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)) + + (((uint64_t)sum)))); +} + +/** + \brief Dual 16-bit signed multiply with exchange with single 64-bit accumulator. + \details This function enables you to exchange the halfwords of the second operand, and perform two + signed 16-bit multiplications, adding both results to a 64-bit accumulate operand. Overflow + is only possible as a result of the 64-bit addition. This overflow is not detected if it occurs. + Instead, the result wraps around modulo2^64. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the product of each multiplication added to the accumulate value. + \remark + p1 = val1[15:0] * val2[31:16] \n + p2 = val1[31:16] * val2[15:0] \n + sum = p1 + p2 + val3[63:32][31:0] \n + res[63:32] = sum[63:32] \n + res[31:0] = sum[31:0] + */ +__ALWAYS_STATIC_INLINE uint64_t __SMLALDX(unsigned long x, unsigned long y, uint64_t sum) +{ + return ((uint64_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) + + ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)) + + (((uint64_t)sum)))); +} + +/** + \brief dual 16-bit signed multiply subtract with 64-bit accumulate. + \details This function It enables you to perform two 16-bit signed multiplications, take the difference + of the products, subtracting the high halfword product from the low halfword product, and add the + difference to a 64-bit accumulate operand. Overflow cannot occur during the multiplications or the + subtraction. Overflow can occur as a result of the 64-bit addition, and this overflow is not + detected. Instead, the result wraps round to modulo2^64. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the difference of the product of each multiplication, added to the accumulate value. + \remark + p1 = val1[15:0] * val2[15:0] \n + p2 = val1[31:16] * val2[31:16] \n + res[63:32][31:0] = p1 - p2 + val3[63:32][31:0] + */ +__ALWAYS_STATIC_INLINE uint64_t __SMLSLD(unsigned long x, unsigned long y, uint64_t sum) +{ + return ((uint64_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) - + ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)) + + (((uint64_t)sum)))); +} + +/** + \brief Dual 16-bit signed multiply with exchange subtract with 64-bit accumulate. + \details This function enables you to exchange the halfwords of the second operand, perform two 16-bit multiplications, + adding the difference of the products to a 64-bit accumulate operand. Overflow cannot occur during the + multiplications or the subtraction. Overflow can occur as a result of the 64-bit addition, and this overflow + is not detected. Instead, the result wraps round to modulo2^64. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the difference of the product of each multiplication, added to the accumulate value. + \remark + p1 = val1[15:0] * val2[31:16] \n + p2 = val1[31:16] * val2[15:0] \n + res[63:32][31:0] = p1 - p2 + val3[63:32][31:0] + */ +__ALWAYS_STATIC_INLINE uint64_t __SMLSLDX(unsigned long x, unsigned long y, uint64_t sum) +{ + return ((uint64_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) - + ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)) + + (((uint64_t)sum)))); +} + +/** + \brief 32-bit signed multiply with 32-bit truncated accumulator. + \details This function enables you to perform a signed 32-bit multiplications, adding the most + significant 32 bits of the 64-bit result to a 32-bit accumulate operand. + \param [in] x first operand for multiplication. + \param [in] y second operand for multiplication. + \param [in] sum accumulate value. + \return the product of multiplication (most significant 32 bits) is added to the accumulate value, as a 32-bit integer. + \remark + p = val1 * val2 \n + res[31:0] = p[63:32] + val3[31:0] + */ +__ALWAYS_STATIC_INLINE unsigned long __SMMLA(int32_t x, int32_t y, int32_t sum) +{ + return (unsigned long)((int32_t)((int64_t)((int64_t)x * (int64_t)y) >> 32) + sum); +} + +/** + \brief Sum of dual 16-bit signed multiply. + \details This function enables you to perform two 16-bit signed multiplications, adding the products together. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \return the sum of the products of the two 16-bit signed multiplications. + \remark + p1 = val1[15:0] * val2[15:0] \n + p2 = val1[31:16] * val2[31:16] \n + res[31:0] = p1 + p2 + */ +__ALWAYS_STATIC_INLINE unsigned long __SMUAD(unsigned long x, unsigned long y) +{ + return ((unsigned long)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) + + ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)))); +} + +/** + \brief Dual 16-bit signed multiply returning difference. + \details This function enables you to perform two 16-bit signed multiplications, taking the difference + of the products by subtracting the high halfword product from the low halfword product. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \return the difference of the products of the two 16-bit signed multiplications. + \remark + p1 = val1[15:0] * val2[15:0] \n + p2 = val1[31:16] * val2[31:16] \n + res[31:0] = p1 - p2 + */ +__ALWAYS_STATIC_INLINE unsigned long __SMUSD(unsigned long x, unsigned long y) +{ + return ((unsigned long)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) - + ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)))); +} + +/** + \brief Dual extracted 8-bit to 16-bit signed addition. + \details This function enables you to extract two 8-bit values from the second operand (at bit positions + [7:0] and [23:16]), sign-extend them to 16-bits each, and add the results to the first operand. + \param [in] x values added to the sign-extended to 16-bit values. + \param [in] y two 8-bit values to be extracted and sign-extended. + \return the addition of val1 and val2, where the 8-bit values in val2[7:0] and + val2[23:16] have been extracted and sign-extended prior to the addition. + \remark + res[15:0] = val1[15:0] + SignExtended(val2[7:0]) \n + res[31:16] = val1[31:16] + SignExtended(val2[23:16]) + */ +__ALWAYS_STATIC_INLINE unsigned long __SXTAB16(unsigned long x, unsigned long y) +{ + return ((unsigned long)((((((int32_t)y << 24) >> 24) + (((int32_t)x << 16) >> 16)) & (int32_t)0x0000FFFF) | + (((((int32_t)y << 8) >> 8) + (((int32_t)x >> 16) << 16)) & (int32_t)0xFFFF0000))); +} + +/** + \brief Extracted 16-bit to 32-bit unsigned addition. + \details This function enables you to extract two 8-bit values from one operand, zero-extend + them to 16 bits each, and add the results to two 16-bit values from another operand. + \param [in] x values added to the zero-extended to 16-bit values. + \param [in] y two 8-bit values to be extracted and zero-extended. + \return the addition of val1 and val2, where the 8-bit values in val2[7:0] and + val2[23:16] have been extracted and zero-extended prior to the addition. + \remark + res[15:0] = ZeroExt(val2[7:0] to 16 bits) + val1[15:0] \n + res[31:16] = ZeroExt(val2[31:16] to 16 bits) + val1[31:16] + */ +__ALWAYS_STATIC_INLINE unsigned long __UXTAB16(unsigned long x, unsigned long y) +{ + return ((unsigned long)(((((y << 24) >> 24) + ((x << 16) >> 16)) & 0x0000FFFF) | + ((((y << 8) >> 8) + ((x >> 16) << 16)) & 0xFFFF0000))); +} + +/** + \brief Dual extract 8-bits and sign extend each to 16-bits. + \details This function enables you to extract two 8-bit values from an operand and sign-extend them to 16 bits each. + \param [in] x two 8-bit values in val[7:0] and val[23:16] to be sign-extended. + \return the 8-bit values sign-extended to 16-bit values.\n + sign-extended value of val[7:0] in the low halfword of the return value.\n + sign-extended value of val[23:16] in the high halfword of the return value. + \remark + res[15:0] = SignExtended(val[7:0]) \n + res[31:16] = SignExtended(val[23:16]) + */ +__ALWAYS_STATIC_INLINE unsigned long __SXTB16(unsigned long x) +{ + return ((unsigned long)(((((int32_t)x << 24) >> 24) & (int32_t)0x0000FFFF) | + ((((int32_t)x << 8) >> 8) & (int32_t)0xFFFF0000))); +} + +/** + \brief Dual extract 8-bits and zero-extend to 16-bits. + \details This function enables you to extract two 8-bit values from an operand and zero-extend them to 16 bits each. + \param [in] x two 8-bit values in val[7:0] and val[23:16] to be zero-extended. + \return the 8-bit values sign-extended to 16-bit values.\n + sign-extended value of val[7:0] in the low halfword of the return value.\n + sign-extended value of val[23:16] in the high halfword of the return value. + \remark + res[15:0] = SignExtended(val[7:0]) \n + res[31:16] = SignExtended(val[23:16]) + */ +__ALWAYS_STATIC_INLINE unsigned long __UXTB16(unsigned long x) +{ + return ((unsigned long)((((x << 24) >> 24) & 0x0000FFFF) | + (((x << 8) >> 8) & 0xFFFF0000))); +} + +#endif /* _CSI_RV32_GCC_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/core/csi_rv64_gcc.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/core/csi_rv64_gcc.h new file mode 100644 index 00000000..9878668e --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/core/csi_rv64_gcc.h @@ -0,0 +1,4383 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 csi_rv64_gcc.h + * @brief CSI Header File for GCC. + * @version V1.0 + * @date 01. Sep 2018 + ******************************************************************************/ + +#ifndef _CSI_RV64_GCC_H_ +#define _CSI_RV64_GCC_H_ + +#include + +#if CONFIG_CPU_XUANTIE_C907 || CONFIG_CPU_XUANTIE_C907FD || CONFIG_CPU_XUANTIE_C907FDV || CONFIG_CPU_XUANTIE_C907FDVM \ + || CONFIG_CPU_XUANTIE_C907_RV32 || CONFIG_CPU_XUANTIE_C907FD_RV32 || CONFIG_CPU_XUANTIE_C907FDV_RV32 || CONFIG_CPU_XUANTIE_C907FDVM_RV32 \ + || CONFIG_CPU_XUANTIE_C908 || CONFIG_CPU_XUANTIE_C908V || CONFIG_CPU_XUANTIE_C908I \ + || CONFIG_CPU_XUANTIE_C908X || CONFIG_CPU_XUANTIE_C908X_CP || CONFIG_CPU_XUANTIE_C908X_CP_XT \ + || CONFIG_CPU_XUANTIE_C910V2 || CONFIG_CPU_XUANTIE_C920V2 \ + || CONFIG_CPU_XUANTIE_C910V3 || CONFIG_CPU_XUANTIE_C920V3 \ + || CONFIG_CPU_XUANTIE_C910V3_CP || CONFIG_CPU_XUANTIE_C920V3_CP \ + || CONFIG_CPU_XUANTIE_C910V3_CP_XT || CONFIG_CPU_XUANTIE_C920V3_CP_XT \ + || CONFIG_CPU_XUANTIE_R908 || CONFIG_CPU_XUANTIE_R908FD || CONFIG_CPU_XUANTIE_R908FDV \ + || CONFIG_CPU_XUANTIE_R908_CP || CONFIG_CPU_XUANTIE_R908FD_CP || CONFIG_CPU_XUANTIE_R908FDV_CP \ + || CONFIG_CPU_XUANTIE_R908_CP_XT || CONFIG_CPU_XUANTIE_R908FD_CP_XT || CONFIG_CPU_XUANTIE_R908FDV_CP_XT +#define CBO_INSN_SUPPORT 1 +#endif + +#if CONFIG_INTC_CLIC_PLIC +#ifndef CONFIG_PLIC_IRQ_OFFSET +#define PLIC_IRQ_OFFSET 255U +#else +#define PLIC_IRQ_OFFSET CONFIG_PLIC_IRQ_OFFSET +#endif +#endif /* CONFIG_INTC_CLIC_PLIC */ + +/* ########################### Core Function Access ########################### */ +/** \ingroup CSI_Core_FunctionInterface + \defgroup CSI_Core_RegAccFunctions CSI Core Register Access Functions + @{ + */ +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by setting the IE-bit in the PSR. + Can only be executed in Privileged modes. + */ +__ALWAYS_STATIC_INLINE void __enable_irq(void) +{ +#if defined(CONFIG_RISCV_SMODE) && CONFIG_RISCV_SMODE + __ASM volatile("csrs sstatus, 2"); + __ASM volatile("li a0, 0x222"); + __ASM volatile("csrs sie, a0"); +#else + __ASM volatile("csrs mstatus, 8"); + __ASM volatile("li a0, 0x888"); + __ASM volatile("csrs mie, a0"); +#endif +} + +/** + \brief Enable supervisor IRQ Interrupts + \details Enables IRQ interrupts by setting the IE-bit in the PSR. + Can only be executed in Privileged modes. + */ +__ALWAYS_STATIC_INLINE void __enable_supervisor_irq(void) +{ + __ASM volatile("csrs sstatus, 2"); + __ASM volatile("li a0, 0x222"); + __ASM volatile("csrs sie, a0"); +} + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by clearing the IE-bit in the PSR. + Can only be executed in Privileged modes. + */ +__ALWAYS_STATIC_INLINE void __disable_irq(void) +{ +#if defined(CONFIG_RISCV_SMODE) && CONFIG_RISCV_SMODE + __ASM volatile("csrc sstatus, 2"); +#else + __ASM volatile("csrc mstatus, 8"); +#endif +} + +/** + \brief Disable supervisor IRQ Interrupts + \details Disables supervisor IRQ interrupts by clearing the IE-bit in the PSR. + Can only be executed in Privileged modes. + */ +__ALWAYS_STATIC_INLINE void __disable_supervisor_irq(void) +{ + __ASM volatile("csrc sstatus, 2"); +} + +/** + \brief Enable CoreTimer(within clint) Interrupts + */ +__ALWAYS_STATIC_INLINE void __enable_coret_irq(void) +{ +#if defined(CONFIG_RISCV_SMODE) && CONFIG_RISCV_SMODE + __ASM volatile("li a0, 0x20"); + __ASM volatile("csrs sie, a0"); +#else + __ASM volatile("li a0, 0x80"); + __ASM volatile("csrs mie, a0"); +#endif +} + +/** + \brief Disable CoreTimer(within clint) Interrupts + */ +__ALWAYS_STATIC_INLINE void __disable_coret_irq(void) +{ +#if defined(CONFIG_RISCV_SMODE) && CONFIG_RISCV_SMODE + __ASM volatile("li a0, 0x20"); + __ASM volatile("csrc sie, a0"); +#else + __ASM volatile("li a0, 0x80"); + __ASM volatile("csrc mie, a0"); +#endif +} + +/** + \brief Get MXSTATUS + \details Returns the content of the MXSTATUS Register. + \return MXSTATUS Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MXSTATUS(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mxstatus" : "=r"(result)); + return (result); +} + +/** + \brief Set MXSTATUS + \details Writes the given value to the MXSTATUS Register. + \param [in] mxstatus MXSTATUS Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MXSTATUS(unsigned long mxstatus) +{ + __ASM volatile("csrw mxstatus, %0" : : "r"(mxstatus)); +} + +/** + \brief Get SXSTATUS + \details Returns the content of the SXSTATUS Register. + \return SXSTATUS Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_SXSTATUS(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, sxstatus" : "=r"(result)); + return (result); +} + +#if __riscv_xlen == 32 +/** + \brief Get MENVCFGH + \details Returns the content of the MENVCFGH Register. + \return MENVCFGH Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MENVCFGH(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, menvcfgh" : "=r"(result)); + return (result); +} + +/** + \brief Set MENVCFGH + \details Writes the given value to the MENVCFGH Register. + \param [in] menvcfgh MENVCFGH Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MENVCFGH(unsigned long menvcfgh) +{ + __ASM volatile("csrw menvcfgh, %0" : : "r"(menvcfgh)); +} +#endif + +/** + \brief Get MENVCFG + \details Returns the content of the MENVCFG Register. + \return MENVCFG Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MENVCFG(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, menvcfg" : "=r"(result)); + return (result); +} + +/** + \brief Set MENVCFG + \details Writes the given value to the MENVCFG Register. + \param [in] menvcfg MENVCFG Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MENVCFG(unsigned long menvcfg) +{ + __ASM volatile("csrw menvcfg, %0" : : "r"(menvcfg)); +} + +/** + \brief Get CPU WORK MODE + \details Returns CPU WORK MODE. + \return CPU WORK MODE + */ +__ALWAYS_STATIC_INLINE unsigned long __get_CPU_WORK_MODE(void) +{ + unsigned long result; + __ASM volatile("csrr %0, sxstatus" : "=r"(result)); + return ((result >> 30U) & 0x3U); +} + +/** + \brief Set MEPC + \details Writes the given value to the MEPC Register. + \param [in] mepc MEPC Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MEPC(unsigned long mepc) +{ + __ASM volatile("csrw mepc, %0" : : "r"(mepc)); +} + +/** + \brief Get MEPC + \details Returns the content of the MEPC Register. + \return MEPC Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MEPC(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mepc" : "=r"(result)); + return (result); +} + +/** + \brief Set SEPC + \details Writes the given value to the SEPC Register. + \param [in] sepc SEPC Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_SEPC(unsigned long sepc) +{ + __ASM volatile("csrw sepc, %0" : : "r"(sepc)); +} + +/** + \brief Get SEPC + \details Returns the content of the SEPC Register. + \return SEPC Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_SEPC(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, sepc" : "=r"(result)); + return (result); +} + + +/** + \brief Get MSTATUS + \details Returns the content of the MSTATUS Register. + \return MSTATUS Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MSTATUS(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mstatus" : "=r"(result)); + return (result); +} + +/** + \brief Set MSTATUS + \details Writes the given value to the MSTATUS Register. + \param [in] mstatus MSTATUS Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MSTATUS(unsigned long mstatus) +{ + __ASM volatile("csrw mstatus, %0" : : "r"(mstatus)); +} + +/** + \brief Get MCOR + \details Returns the content of the MCOR Register. + \return MCOR Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MCOR(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mcor" : "=r"(result)); + return (result); +} + +/** + \brief Set MCOR + \details Writes the given value to the MCOR Register. + \param [in] mstatus MCOR Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MCOR(unsigned long mcor) +{ + __ASM volatile("csrw mcor, %0" : : "r"(mcor)); +} + +/** + \brief Get MHCR + \details Returns the content of the MHCR Register. + \return MHCR Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MHCR(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mhcr" : "=r"(result)); + return (result); +} + +/** + \brief Set MHCR + \details Writes the given value to the MHCR Register. + \param [in] mstatus MHCR Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MHCR(unsigned long mhcr) +{ + __ASM volatile("csrw mhcr, %0" : : "r"(mhcr)); +} + +/** + \brief Get MHINT + \details Returns the content of the MHINT Register. + \return MHINT Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MHINT(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mhint" : "=r"(result)); + return (result); +} + +/** + \brief Set MHINT + \details Writes the given value to the MHINT Register. + \param [in] mstatus MHINT Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MHINT(unsigned long mhint) +{ + __ASM volatile("csrw mhint, %0" : : "r"(mhint)); +} + +/** + \brief Get MCCR2 + \details Returns the content of the MCCR2 Register. + \return MCCR2 Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MCCR2(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mccr2" : "=r"(result)); + return (result); +} + +/** + \brief Set MCCR2 + \details Writes the given value to the MCCR2 Register. + \param [in] mstatus MCCR2 Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MCCR2(unsigned long mccr2) +{ + __ASM volatile("csrw mccr2, %0" : : "r"(mccr2)); +} + +/** + \brief Get MISA Register + \details Returns the content of the MISA Register. + \return MISA Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MISA(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, misa" : "=r"(result)); + return (result); +} + +/** + \brief Set MISA + \details Writes the given value to the MISA Register. + \param [in] misa MISA Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MISA(unsigned long misa) +{ + __ASM volatile("csrw misa, %0" : : "r"(misa)); +} + +/** + \brief Get MIE Register + \details Returns the content of the MIE Register. + \return MIE Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MIE(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mie" : "=r"(result)); + return (result); +} + +/** + \brief Set MIE + \details Writes the given value to the MIE Register. + \param [in] mie MIE Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MIE(unsigned long mie) +{ + __ASM volatile("csrw mie, %0" : : "r"(mie)); +} + +/** + \brief Get MTVEC Register + \details Returns the content of the MTVEC Register. + \return MTVEC Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MTVEC(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mtvec" : "=r"(result)); + return (result); +} + +/** + \brief Set MTVEC + \details Writes the given value to the MTVEC Register. + \param [in] mtvec MTVEC Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MTVEC(unsigned long mtvec) +{ + __ASM volatile("csrw mtvec, %0" : : "r"(mtvec)); +} + +/** + \brief Set MTVT + \details Writes the given value to the MTVT Register. + \param [in] mtvt MTVT Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MTVT(unsigned long mtvt) +{ + __ASM volatile("csrw mtvt, %0" : : "r"(mtvt)); +} + +/** + \brief Get MTVT Register + \details Returns the content of the MTVT Register. + \return MTVT Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MTVT(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mtvt" : "=r"(result)); + return (result); +} + +/** + \brief Get MTIME + \details Returns the content of the MTIME Register. + \return MTIME Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MTIME(void) +{ + unsigned long result; + + __ASM volatile("rdtime %0" : "=r"(result)); + //__ASM volatile("csrr %0, 0xc01" : "=r"(result)); + return (result); +} + +/** + \brief Get MTIMEH + \details Returns the content of the MTIME Register. + \return MTIME Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MTIMEH(void) +{ + unsigned long result; + __ASM volatile("rdtimeh %0" : "=r"(result)); + return (result); +} + +/** + \brief Get SP + \details Returns the content of the SP Register. + \return SP Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_SP(void) +{ + unsigned long result; + + __ASM volatile("mv %0, sp" : "=r"(result)); + return (result); +} + +/** + \brief Set SP + \details Writes the given value to the SP Register. + \param [in] sp SP Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_SP(unsigned long sp) +{ + __ASM volatile("mv sp, %0" : : "r"(sp): "sp"); +} + +/** + \brief Get MSCRATCH Register + \details Returns the content of the MSCRATCH Register. + \return MSCRATCH Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MSCRATCH(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mscratch" : "=r"(result)); + return (result); +} + +/** + \brief Set MSCRATCH + \details Writes the given value to the MSCRATCH Register. + \param [in] mscratch MSCRATCH Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MSCRATCH(unsigned long mscratch) +{ + __ASM volatile("csrw mscratch, %0" : : "r"(mscratch)); +} + +/** + \brief Get MCAUSE Register + \details Returns the content of the MCAUSE Register. + \return MCAUSE Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MCAUSE(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mcause" : "=r"(result)); + return (result); +} + +/** + \brief Get SCAUSE Register + \details Returns the content of the SCAUSE Register. + \return SCAUSE Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_SCAUSE(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, scause" : "=r"(result)); + return (result); +} + +/** + \brief Get MNXTI Register + \details Returns the content of the MNXTI Register. + \return MNXTI Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MNXTI(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mnxti" : "=r"(result)); + return (result); +} + +/** + \brief Set MNXTI + \details Writes the given value to the MNXTI Register. + \param [in] mnxti MNXTI Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MNXTI(unsigned long mnxti) +{ + __ASM volatile("csrw mnxti, %0" : : "r"(mnxti)); +} + +/** + \brief Get MINTSTATUS Register + \details Returns the content of the MINTSTATUS Register. + \return MINTSTATUS Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MINTSTATUS(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mintstatus" : "=r"(result)); + return (result); +} + +/** + \brief Get MTVAL Register + \details Returns the content of the MTVAL Register. + \return MTVAL Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MTVAL(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mtval" : "=r"(result)); + return (result); +} + +/** + \brief Get MIP Register + \details Returns the content of the MIP Register. + \return MIP Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MIP(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mip" : "=r"(result)); + return (result); +} + +/** + \brief Set MIP + \details Writes the given value to the MIP Register. + \param [in] mip MIP Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MIP(unsigned long mip) +{ + __ASM volatile("csrw mip, %0" : : "r"(mip)); +} + +/** + \brief Get MCYCLEL Register + \details Returns the content of the MCYCLEL Register. + \return MCYCLE Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MCYCLE(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mcycle" : "=r"(result)); + return (result); +} + +/** + \brief Set MCYCLE + \details Write MCYCLE Register + \param [in] value MCYCLE Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MCYCLE(unsigned long value) +{ + __ASM volatile("csrw mcycle, %0" : : "r"(value)); +} + +/** + \brief Get MCYCLEH Register + \details Returns the content of the MCYCLEH Register. + \return MCYCLEH Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MCYCLEH(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mcycleh" : "=r"(result)); + return (result); +} + +/** + \brief Set MCYCLEH + \details Write MCYCLEH Register + \param [in] value MCYCLEH Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MCYCLEH(unsigned long value) +{ + __ASM volatile("csrw mcycleh, %0" : : "r"(value)); +} + +/** + \brief Get MINSTRET Register + \details Returns the content of the MINSTRET Register. + \return MINSTRET Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MINSTRET(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, minstret" : "=r"(result)); + return (result); +} + +/** + \brief Set MINSTRET + \details Write MINSTRET Register + \param [in] value MINSTRET Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MINSTRET(unsigned long value) +{ + __ASM volatile("csrw minstret, %0" : : "r"(value)); +} + +/** + \brief Get MINSTRETH Register + \details Returns the content of the MINSTRETH Register. + \return MINSTRETH Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MINSTRETH(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, minstreth" : "=r"(result)); + return (result); +} + +/** + \brief Set MINSTRETH + \details Write MINSTRETH Register + \param [in] value MINSTRETH Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MINSTRETH(unsigned long value) +{ + __ASM volatile("csrw minstreth, %0" : : "r"(value)); +} + +/** + \brief Get MVENDORID Register + \details Returns the content of the MVENDROID Register. + \return MVENDORID Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MVENDORID(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mvendorid" : "=r"(result)); + return (result); +} + +/** + \brief Get MARCHID Register + \details Returns the content of the MARCHID Register. + \return MARCHID Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MARCHID(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, marchid" : "=r"(result)); + return (result); +} + +/** + \brief Get MIMPID Register + \details Returns the content of the MIMPID Register. + \return MIMPID Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MIMPID(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mimpid" : "=r"(result)); + return (result); +} + +/** + \brief Get MHARTID Register + \details Returns the content of the MHARTID Register. + \return MHARTID Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MHARTID(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, mhartid" : "=r"(result)); + return (result); +} + +/** + \brief Get PMPCFGx Register + \details Returns the content of the PMPCFGx Register. + \return PMPCFGx Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_PMPCFG0(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpcfg0" : "=r"(result)); + return (result); +} + +#if __riscv_xlen == 32 +__ALWAYS_STATIC_INLINE unsigned long __get_PMPCFG1(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpcfg1" : "=r"(result)); + return (result); +} +#endif + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPCFG2(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpcfg2" : "=r"(result)); + return (result); +} + +#if __riscv_xlen == 32 +__ALWAYS_STATIC_INLINE unsigned long __get_PMPCFG3(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpcfg3" : "=r"(result)); + return (result); +} +#endif + +/** + \brief Get PMPxCFG Register by index + \details Returns the content of the PMPxCFG Register. + \param [in] idx PMP region index + \return PMPxCFG Register value + */ +__STATIC_INLINE uint8_t __get_PMPxCFG(unsigned long idx) +{ + unsigned long pmpcfgx = 0; + +#if __riscv_xlen == 32 + if (idx < 4) { + pmpcfgx = __get_PMPCFG0(); + } else if (idx >= 4 && idx < 8) { + idx -= 4; + pmpcfgx = __get_PMPCFG1(); + } else if (idx >= 8 && idx < 12) { + idx -= 8; + pmpcfgx = __get_PMPCFG2(); + } else if (idx >= 12 && idx < 16) { + idx -= 12; + pmpcfgx = __get_PMPCFG3(); + } else { + return 0; + } +#else + if (idx < 8) { + pmpcfgx = __get_PMPCFG0(); + } else if (idx >= 8 && idx < 16) { + idx -= 8; + pmpcfgx = __get_PMPCFG2(); + } else { + return 0; + } +#endif + + return (uint8_t)((pmpcfgx & (0xFF << (idx << 3))) >> (idx << 3)); +} + +/** + \brief Set PMPCFGx + \details Writes the given value to the PMPCFGx Register. + \param [in] pmpcfg PMPCFGx Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_PMPCFG0(unsigned long pmpcfg) +{ + __ASM volatile("csrw pmpcfg0, %0" : : "r"(pmpcfg)); +} + +#if __riscv_xlen == 32 +__ALWAYS_STATIC_INLINE void __set_PMPCFG1(unsigned long pmpcfg) +{ + __ASM volatile("csrw pmpcfg1, %0" : : "r"(pmpcfg)); +} +#endif + +__ALWAYS_STATIC_INLINE void __set_PMPCFG2(unsigned long pmpcfg) +{ + __ASM volatile("csrw pmpcfg2, %0" : : "r"(pmpcfg)); +} + +#if __riscv_xlen == 32 +__ALWAYS_STATIC_INLINE void __set_PMPCFG3(unsigned long pmpcfg) +{ + __ASM volatile("csrw pmpcfg3, %0" : : "r"(pmpcfg)); +} +#endif + +/** + \brief Set PMPxCFG by index + \details Writes the given value to the PMPxCFG Register. + \param [in] idx PMPx region index + \param [in] pmpxcfg PMPxCFG Register value to set + */ +__STATIC_INLINE void __set_PMPxCFG(unsigned long idx, uint8_t pmpxcfg) +{ + unsigned long pmpcfgx = 0; + +#if __riscv_xlen == 32 + if (idx < 4) { + pmpcfgx = __get_PMPCFG0(); + pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | ((unsigned long)(pmpxcfg) << (idx << 3)); + __set_PMPCFG0(pmpcfgx); + } else if (idx >= 4 && idx < 8) { + idx -= 4; + pmpcfgx = __get_PMPCFG1(); + pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | ((unsigned long)(pmpxcfg) << (idx << 3)); + __set_PMPCFG1(pmpcfgx); + } else if (idx >= 8 && idx < 12) { + idx -= 8; + pmpcfgx = __get_PMPCFG2(); + pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | ((unsigned long)(pmpxcfg) << (idx << 3)); + __set_PMPCFG2(pmpcfgx); + } else if (idx >= 12 && idx < 16) { + idx -= 12; + pmpcfgx = __get_PMPCFG3(); + pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | ((unsigned long)(pmpxcfg) << (idx << 3)); + __set_PMPCFG3(pmpcfgx); + } else { + return; + } +#else + if (idx < 8) { + pmpcfgx = __get_PMPCFG0(); + pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | ((unsigned long)(pmpxcfg) << (idx << 3)); + __set_PMPCFG0(pmpcfgx); + } else if (idx >= 8 && idx < 16) { + idx -= 8; + pmpcfgx = __get_PMPCFG2(); + pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | ((unsigned long)(pmpxcfg) << (idx << 3)); + __set_PMPCFG2(pmpcfgx); + } else { + return; + } +#endif +} + +/** + \brief Get PMPADDRx Register + \details Returns the content of the PMPADDRx Register. + \return PMPADDRx Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR0(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpaddr0" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR1(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpaddr1" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR2(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpaddr2" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR3(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpaddr3" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR4(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpaddr4" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR5(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpaddr5" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR6(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpaddr6" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR7(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpaddr7" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR8(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpaddr8" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR9(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpaddr9" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR10(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpaddr10" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR11(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpaddr11" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR12(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpaddr12" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR13(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpaddr13" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR14(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpaddr14" : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE unsigned long __get_PMPADDR15(void) +{ + unsigned long result; + + __ASM volatile("csrr %0, pmpaddr15" : "=r"(result)); + return (result); +} + +/** + \brief Get PMPADDRx Register by index + \details Returns the content of the PMPADDRx Register. + \param [in] idx PMP region index + \return PMPADDRx Register value + */ +__STATIC_INLINE unsigned long __get_PMPADDRx(unsigned long idx) +{ + switch (idx) { + case 0: + return __get_PMPADDR0(); + + case 1: + return __get_PMPADDR1(); + + case 2: + return __get_PMPADDR2(); + + case 3: + return __get_PMPADDR3(); + + case 4: + return __get_PMPADDR4(); + + case 5: + return __get_PMPADDR5(); + + case 6: + return __get_PMPADDR6(); + + case 7: + return __get_PMPADDR7(); + + case 8: + return __get_PMPADDR8(); + + case 9: + return __get_PMPADDR9(); + + case 10: + return __get_PMPADDR10(); + + case 11: + return __get_PMPADDR11(); + + case 12: + return __get_PMPADDR12(); + + case 13: + return __get_PMPADDR13(); + + case 14: + return __get_PMPADDR14(); + + case 15: + return __get_PMPADDR15(); + + default: + return 0; + } +} + +/** + \brief Set PMPADDRx + \details Writes the given value to the PMPADDRx Register. + \param [in] pmpaddr PMPADDRx Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_PMPADDR0(unsigned long pmpaddr) +{ + __ASM volatile("csrw pmpaddr0, %0" : : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR1(unsigned long pmpaddr) +{ + __ASM volatile("csrw pmpaddr1, %0" : : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR2(unsigned long pmpaddr) +{ + __ASM volatile("csrw pmpaddr2, %0" : : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR3(unsigned long pmpaddr) +{ + __ASM volatile("csrw pmpaddr3, %0" : : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR4(unsigned long pmpaddr) +{ + __ASM volatile("csrw pmpaddr4, %0" : : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR5(unsigned long pmpaddr) +{ + __ASM volatile("csrw pmpaddr5, %0" : : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR6(unsigned long pmpaddr) +{ + __ASM volatile("csrw pmpaddr6, %0" : : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR7(unsigned long pmpaddr) +{ + __ASM volatile("csrw pmpaddr7, %0" : : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR8(unsigned long pmpaddr) +{ + __ASM volatile("csrw pmpaddr8, %0" : : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR9(unsigned long pmpaddr) +{ + __ASM volatile("csrw pmpaddr9, %0" : : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR10(unsigned long pmpaddr) +{ + __ASM volatile("csrw pmpaddr10, %0" : : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR11(unsigned long pmpaddr) +{ + __ASM volatile("csrw pmpaddr11, %0" : : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR12(unsigned long pmpaddr) +{ + __ASM volatile("csrw pmpaddr12, %0" : : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR13(unsigned long pmpaddr) +{ + __ASM volatile("csrw pmpaddr13, %0" : : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR14(unsigned long pmpaddr) +{ + __ASM volatile("csrw pmpaddr14, %0" : : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR15(unsigned long pmpaddr) +{ + __ASM volatile("csrw pmpaddr15, %0" : : "r"(pmpaddr)); +} + +/** + \brief Set PMPADDRx by index + \details Writes the given value to the PMPADDRx Register. + \param [in] idx PMP region index + \param [in] pmpaddr PMPADDRx Register value to set + */ +__STATIC_INLINE void __set_PMPADDRx(unsigned long idx, unsigned long pmpaddr) +{ + switch (idx) { + case 0: + __set_PMPADDR0(pmpaddr); + break; + + case 1: + __set_PMPADDR1(pmpaddr); + break; + + case 2: + __set_PMPADDR2(pmpaddr); + break; + + case 3: + __set_PMPADDR3(pmpaddr); + break; + + case 4: + __set_PMPADDR4(pmpaddr); + break; + + case 5: + __set_PMPADDR5(pmpaddr); + break; + + case 6: + __set_PMPADDR6(pmpaddr); + break; + + case 7: + __set_PMPADDR7(pmpaddr); + break; + + case 8: + __set_PMPADDR8(pmpaddr); + break; + + case 9: + __set_PMPADDR9(pmpaddr); + break; + + case 10: + __set_PMPADDR10(pmpaddr); + break; + + case 11: + __set_PMPADDR11(pmpaddr); + break; + + case 12: + __set_PMPADDR12(pmpaddr); + break; + + case 13: + __set_PMPADDR13(pmpaddr); + break; + + case 14: + __set_PMPADDR14(pmpaddr); + break; + + case 15: + __set_PMPADDR15(pmpaddr); + break; + + default: + return; + } +} + +/** + \brief Get MCOUNTEREN + \details Returns the content of the MCOUNTEREN Register. + \return MCOUNTEREN Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MCOUNTEREN(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, mcounteren" : "=r"(result)); + return (result); +} + +/** + \brief Set MCOUNTEREN + \details Writes the given value to the MCOUNTEREN Register. + \param [in] mcounteren MCOUNTEREN Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MCOUNTEREN(uint32_t mcounteren) +{ + __ASM volatile("csrw mcounteren, %0" : : "r"(mcounteren)); +} + +/** + \brief Get MCOUNTERWEN + \details Returns the content of the MCOUNTERWEN Register. + \return MCOUNTERWEN Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MCOUNTERWEN(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, mcounterwen" : "=r"(result)); + return (result); +} + +/** + \brief Set MCOUNTERWEN + \details Writes the given value to the MCOUNTERWEN Register. + \param [in] mcounterwen MCOUNTERWEN Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MCOUNTERWEN(uint32_t mcounterwen) +{ + __ASM volatile("csrw mcounterwen, %0" : : "r"(mcounterwen)); +} +/** + \brief Set MEDELEG Register + \details Writes the given value to the MEDELEG Register. + */ +__ALWAYS_STATIC_INLINE void __set_MEDELEG(unsigned long x) +{ + __ASM volatile("csrw medeleg, %0"::"r"(x)); +} + +/** + \brief Set MEDELEG Register + \details Writes the given value to the MEDELEG Register. + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MEDELEG(void) +{ + unsigned long x; + __ASM volatile("csrr %0, medeleg":"=r"(x)); + return x; +} + +/** + \brief Set MIDELEG Register + \details Writes the given value to the MIDELEG Register. + */ +__ALWAYS_STATIC_INLINE void __set_MIDELEG(unsigned long x) +{ + __ASM volatile("csrw mideleg, %0"::"r"(x)); +} + +/** + \brief Get MIDELEG Register + \details Returns the content of the MIDELEG Register. + \return MIDELEG Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MIDELEG(void) +{ + unsigned long x; + __ASM volatile("csrr %0, mideleg":"=r"(x)); + return x; +} + +/** + \brief Set SSTATUS Register + \details Writes the given value to the SSTATUS Register. + */ +__ALWAYS_STATIC_INLINE void __set_SSTATUS(unsigned long x) +{ + __ASM volatile("csrw sstatus, %0"::"r"(x)); +} + +/** + \brief Get SSTATUS Register + \details Returns the content of the SSTATUS Register. + \return SSTATUS Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_SSTATUS(void) +{ + unsigned long x; + __ASM volatile("csrr %0, sstatus":"=r"(x)); + return x; +} + +/** + \brief Set SXSTATUS Register + \details Writes the given value to the SXSTATUS Register. + */ +__ALWAYS_STATIC_INLINE void __set_SXSTATUS(unsigned long x) +{ + __ASM volatile("csrw sxstatus, %0"::"r"(x)); +} + +/** + \brief Get SXSTATUS Register + \details Returns the content of the SXSTATUS Register. + \return SXSTATUS Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get__SXSTATUS(void) +{ + unsigned long x; + __ASM volatile("csrr %0, sxstatus":"=r"(x)); + return x; +} + +/** + \brief Set SIE Register + \details Writes the given value to the SIE Register. + */ +__ALWAYS_STATIC_INLINE void __set_SIE(unsigned long x) +{ + __ASM volatile("csrw sie, %0"::"r"(x)); +} + +/** + \brief Get SIE Register + \details Returns the content of the SIE Register. + \return SIE Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_SIE(void) +{ + unsigned long x; + __ASM volatile("csrr %0, sie":"=r"(x)); + return x; +} + +/** + \brief Set STVAC Register + \details Writes the given value to the STVEC Register. + */ +__ALWAYS_STATIC_INLINE void __set_STVEC(unsigned long x) +{ + __ASM volatile("csrw stvec, %0"::"r"(x)); +} + +/** + \brief Get STVAC Register + \details Returns the content of the STVAC Register. + \return STVAC Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_STVEC(void) +{ + unsigned long x; + __ASM volatile("csrr %0, stvec":"=r"(x)); + return x; +} + +/** + \brief Enable interrupts and exceptions + \details Enables interrupts and exceptions by setting the IE-bit and EE-bit in the PSR. + Can only be executed in Privileged modes. + */ +__ALWAYS_STATIC_INLINE void __enable_excp_irq(void) +{ +#ifdef CONFIG_MMU + __enable_supervisor_irq(); +#else + __enable_irq(); +#endif +} + + +/** + \brief Disable interrupts and exceptions + \details Disables interrupts and exceptions by clearing the IE-bit and EE-bit in the PSR. + Can only be executed in Privileged modes. + */ +__ALWAYS_STATIC_INLINE void __disable_excp_irq(void) +{ +#ifdef CONFIG_MMU + __disable_supervisor_irq(); +#else + __disable_irq(); +#endif +} + +#define __CSI_GCC_OUT_REG(r) "=r" (r) +#define __CSI_GCC_USE_REG(r) "r" (r) + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +__ALWAYS_STATIC_INLINE void __NOP(void) +{ + __ASM volatile("nop"); +} + +/** + \brief return from S-MODE + \details return from S-MODE. + */ +__ALWAYS_STATIC_INLINE void __SRET(void) +{ + __ASM volatile("sret"); +} + +/** + \brief return from M-MODE + \details return from M-MODE. + */ +__ALWAYS_STATIC_INLINE void __MRET(void) +{ + __ASM volatile("mret"); +} + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +__ALWAYS_STATIC_INLINE void __WFI(void) +{ + __ASM volatile("wfi"); +} + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one interrupt occurs. + */ +__ALWAYS_STATIC_INLINE void __WAIT(void) +{ + __ASM volatile("wfi"); +} + +/** + \brief Doze For Interrupt + \details Doze For Interrupt is a hint instruction that suspends execution until one interrupt occurs. + */ +__ALWAYS_STATIC_INLINE void __DOZE(void) +{ + __ASM volatile("wfi"); +} + +/** + \brief Stop For Interrupt + \details Stop For Interrupt is a hint instruction that suspends execution until one interrupt occurs. + */ +__ALWAYS_STATIC_INLINE void __STOP(void) +{ + __ASM volatile("wfi"); +} + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +__ALWAYS_STATIC_INLINE void __ISB(void) +{ + __ASM volatile("fence.i"); + __ASM volatile("fence r, r"); +} + + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__ALWAYS_STATIC_INLINE void __DSB(void) +{ + __ASM volatile("fence iorw, iorw"); +#if __riscv_xtheadsync + __ASM volatile("sync"); +#endif +} + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__ALWAYS_STATIC_INLINE void __DMB(void) +{ + __ASM volatile("fence rw, rw"); +} + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__ALWAYS_STATIC_INLINE void __SYNC_IS(void) +{ +#if __riscv_xtheadsync + __ASM volatile("sync.is"); +#endif +} + +/** + \brief Invalid all icache + \details invalid all icache. + */ +__ALWAYS_STATIC_INLINE void __ICACHE_IALL(void) +{ +#if __riscv_xtheadcmo + __ASM volatile("icache.iall"); +#endif +} + +/** + \brief Invalid all icache and broadcast to other cores + \details Invalid all icache and broadcast to other cores + */ +__ALWAYS_STATIC_INLINE void __ICACHE_IALLS(void) +{ +#if __riscv_xtheadcmo + __ASM volatile("icache.ialls"); +#endif +} + +/** + \brief Invalid Icache by physical addr + \details Invalid Icache by physical addr. + \param [in] addr operate addr + */ +__ALWAYS_STATIC_INLINE void __ICACHE_IPA(unsigned long addr) +{ +#if __riscv_xtheadcmo + __ASM volatile("icache.ipa %0" : : "r"(addr)); +#endif +} + +/** + \brief Invalid Icache by virsual addr + \details Invalid Icache by virsual addr. + \param [in] addr operate addr + */ +__ALWAYS_STATIC_INLINE void __ICACHE_IVA(unsigned long addr) +{ +#if __riscv_xtheadcmo + __ASM volatile("icache.iva %0" : : "r"(addr)); +#endif +} + +/** + \brief Invalid all L1dcache + \details invalid all L1dcache. + */ +__ALWAYS_STATIC_INLINE void __DCACHE_IALL(void) +{ +#if __riscv_xtheadcmo + __ASM volatile("dcache.iall"); +#endif +} + +/** + \brief Clear all dcache + \details clear all dcache. + */ +__ALWAYS_STATIC_INLINE void __DCACHE_CALL(void) +{ +#if __riscv_xtheadcmo + __ASM volatile("dcache.call"); +#endif +} + +/** + \brief Clear & invalid all dcache + \details clear & invalid all dcache. + */ +__ALWAYS_STATIC_INLINE void __DCACHE_CIALL(void) +{ +#if __riscv_xtheadcmo + __ASM volatile("dcache.ciall"); +#endif +} + +/** + \brief Clear & Invalid Dcache by way/set + \details Clear & Invalid Dcache by way/set + \param [in] addr operate addr + */ +__ALWAYS_STATIC_INLINE void __DCACHE_CISW(unsigned long wayset) +{ +#if __riscv_xtheadcmo + __ASM volatile("dcache.cisw %0" : : "r"(wayset)); +#endif +} + +#if CBO_INSN_SUPPORT +/** + \brief Clear Dcache/L2cache by addr + \details Clear Dcache/L2cache by addr. + \param [in] addr operate addr + */ +__ALWAYS_STATIC_INLINE void __CBO_CLEAN(unsigned long addr) +{ + __ASM volatile("cbo.clean 0(%0)" : : "r"(addr)); +} + +/** + \brief Clear & Invalid Dcache/L2cache by addr + \details Clear & Invalid Dcache/L2cache by addr. + \param [in] addr operate addr + */ +__ALWAYS_STATIC_INLINE void __CBO_FLUSH(unsigned long addr) +{ + __ASM volatile("cbo.flush 0(%0)" : : "r"(addr)); +} + +/** + \brief Invalid Dcache/L2cache by addr + \details Invalid Dcache/L2cache by addr. + \param [in] addr operate addr + */ +__ALWAYS_STATIC_INLINE void __CBO_INVAL(unsigned long addr) +{ + __ASM volatile("cbo.inval 0(%0)" : : "r"(addr)); +} + +/** + \brief Set Dcache to zero by addr + \details Set Dcache to zero by addr. + \param [in] addr operate addr + */ +__ALWAYS_STATIC_INLINE void __CBO_ZERO(unsigned long addr) +{ + __ASM volatile("cbo.zero %0" : : "r"(addr)); +} +#else +/** + \brief Clear Dcache/L2cache by physical addr + \details Clear Dcache/L2cache by physical addr. + \param [in] addr operate addr + */ +__ALWAYS_STATIC_INLINE void __DCACHE_CPA(unsigned long addr) +{ +#if __riscv_xtheadcmo + __ASM volatile("dcache.cpa %0" : : "r"(addr)); +#endif +} + +/** + \brief Clear Dcache/L2cache by virsual addr + \details Clear Dcache/L2cache by virsual addr. + \param [in] addr operate addr + */ +__ALWAYS_STATIC_INLINE void __DCACHE_CVA(unsigned long addr) +{ +#if __riscv_xtheadcmo + __ASM volatile("dcache.cva %0" : : "r"(addr)); +#endif +} + +/** + \brief Clear & Invalid Dcache by physical addr + \details Clear & Invalid Dcache by physical addr. + \param [in] addr operate addr + */ +__ALWAYS_STATIC_INLINE void __DCACHE_CIPA(unsigned long addr) +{ +#if __riscv_xtheadcmo + __ASM volatile("dcache.cipa %0" : : "r"(addr)); +#endif +} + +/** + \brief Clear & Invalid Dcache by virsual addr + \details Clear & Invalid Dcache by virsual addr. + \param [in] addr operate addr + */ +__ALWAYS_STATIC_INLINE void __DCACHE_CIVA(unsigned long addr) +{ +#if __riscv_xtheadcmo + __ASM volatile("dcache.civa %0" : : "r"(addr)); +#endif +} + +/** + \brief Invalid Dcache/L2cache by physical addr + \details Invalid Dcache/L2cache by physical addr. + \param [in] addr operate addr + */ +__ALWAYS_STATIC_INLINE void __DCACHE_IPA(unsigned long addr) +{ +#if __riscv_xtheadcmo + __ASM volatile("dcache.ipa %0" : : "r"(addr)); +#endif +} + +/** + \brief Invalid Dcache/L2cache by virsual addr + \details Invalid Dcache/L2cache by virsual addr. + \param [in] addr operate addr + */ +__ALWAYS_STATIC_INLINE void __DCACHE_IVA(unsigned long addr) +{ +#if __riscv_xtheadcmo + __ASM volatile("dcache.iva %0" : : "r"(addr)); +#endif +} + +#endif + +/** + \brief Clear L1-Dcache by physical addr and broadcast to other cores + \details Clear L1-Dcache by physical addr and broadcast to other cores + \param [in] addr operate addr + */ +__ALWAYS_STATIC_INLINE void __DCACHE_CPAL1(unsigned long addr) +{ +#if __riscv_xtheadcmo + __ASM volatile("dcache.cpal1 %0" : : "r"(addr)); +#endif +} + +/** + \brief Clear L1-Dcache by virsual addr and broadcast to other cores + \details Clear L1-Dcache by virsual addr and broadcast to other cores + \param [in] addr operate addr + */ +__ALWAYS_STATIC_INLINE void __DCACHE_CVAL1(unsigned long addr) +{ +#if __riscv_xtheadcmo + __ASM volatile("dcache.cval1 %0" : : "r"(addr)); +#endif +} + +/** + \brief Invalid Dcache by way/set + \details Invalid Dcache by way/set + \param [in] addr operate addr + */ +__ALWAYS_STATIC_INLINE void __DCACHE_ISW(unsigned long wayset) +{ +#if __riscv_xtheadcmo + __ASM volatile("dcache.isw %0" : : "r"(wayset)); +#endif +} + +#if (__L2CACHE_PRESENT == 1U) +/** + \brief Invalid L2 cache + \details invalid L2 cache. + */ +__ALWAYS_STATIC_INLINE void __L2CACHE_IALL(void) +{ + __ASM volatile("l2cache.iall"); +} + +/** + \brief Clear L2cache + \details clear L2cache. + */ +__ALWAYS_STATIC_INLINE void __L2CACHE_CALL(void) +{ + __ASM volatile("l2cache.call"); +} + +/** + \brief Clear&invalid L2cache + \details clear & invalid L2cache. + */ +__ALWAYS_STATIC_INLINE void __L2CACHE_CIALL(void) +{ + __ASM volatile("l2cache.ciall"); +} +#endif + +/** + \brief Get SATP + \details Returns the current value of the SATP. + \return SATP Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_SATP(void) +{ + register unsigned long result; + + __ASM volatile("csrr %0, satp" : "=r"(result)); + return (result); +} + +/** + \brief Set SATP + \details Assigns the given value to the SATP. + \param [in] satp SATP value to set + */ +__ALWAYS_STATIC_INLINE void __set_SATP(unsigned long satp) +{ + __ASM volatile("sfence.vma"); + __ASM volatile("csrw satp, %0" : : "r"(satp)); +} + +/** + \brief Get SCER2 + \details Returns the current value of the SCER2. + \return SCER2 Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_SCER2(void) +{ + register unsigned long result; + __ASM volatile("csrr %0, scer2" : "=r"(result)); + return (result); +} + +/** + \brief Set SCER2 + \details Assigns the given value to the SCER2. + \param [in] scer2 SCER2 value to set + */ +__ALWAYS_STATIC_INLINE void __set_SCER2(unsigned long scer2) +{ + __ASM volatile("csrw scer2, %0" : : "r"(scer2)); +} + +/** + \brief Get MCER2 + \details Returns the current value of the MCER2. + \return MCER2 Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MCER2(void) +{ + register unsigned long result; + __ASM volatile("csrr %0, mcer2" : "=r"(result)); + return (result); +} + +/** + \brief Set MCER2 + \details Assigns the given value to the MCER2. + \param [in] mcer2 MCER2 value to set + */ +__ALWAYS_STATIC_INLINE void __set_MCER2(unsigned long mcer2) +{ + __ASM volatile("csrw mcer2, %0" : : "r"(mcer2)); +} + +#if __riscv_xlen == 32 +/** + \brief Get MCER2H + \details Returns the current value of the MCER2H. + \return MCER2H Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MCER2H(void) +{ + register unsigned long result; + __ASM volatile("csrr %0, mcer2h" : "=r"(result)); + return (result); +} + +/** + \brief Set MCER2H + \details Assigns the given value to the MCER2H. + \param [in] mcer2h MCER2H value to set + */ +__ALWAYS_STATIC_INLINE void __set_MCER2H(unsigned long mcer2h) +{ + __ASM volatile("csrw mcer2h, %0" : : "r"(mcer2h)); +} +#endif + +/** + \brief Get SSBEPA2 + \details Returns the current value of the SSBEPA2. + \return SSBEPA2 Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_SSBEPA2(void) +{ + register unsigned long result; + //__ASM volatile("csrr %0, ssbepa2" : "=r"(result)); + __ASM volatile("csrr %0, 0x5d2" : "=r"(result)); + return (result); +} + +/** + \brief Set SSBEPA2 + \details Assigns the given value to the SSBEPA2. + \param [in] ssbepa2 SSBEPA2 value to set + */ +__ALWAYS_STATIC_INLINE void __set_SSBEPA2(unsigned long ssbepa2) +{ + //__ASM volatile("csrw ssbepa2, %0" : : "r"(ssbepa2)); + __ASM volatile("csrw 0x5d2, %0" : : "r"(ssbepa2)); +} + +/** + \brief Get MSBEPA2 + \details Returns the current value of the MSBEPA2. + \return MSBEPA2 Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MSBEPA2(void) +{ + register unsigned long result; + //__ASM volatile("csrr %0, msbepa2" : "=r"(result)); + __ASM volatile("csrr %0, 0x7fc" : "=r"(result)); + return (result); +} + +/** + \brief Set MSBEPA2 + \details Assigns the given value to the MSBEPA2. + \param [in] msbepa2 MSBEPA2 value to set + */ +__ALWAYS_STATIC_INLINE void __set_MSBEPA2(unsigned long msbepa2) +{ + //__ASM volatile("csrw msbepa2, %0" : : "r"(msbepa2)); + __ASM volatile("csrw 0x7fc, %0" : : "r"(msbepa2)); +} + +/** + \brief Get SCER + \details Returns the current value of the SCER. + \return SCER Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_SCER(void) +{ + register unsigned long result; + __ASM volatile("csrr %0, scer" : "=r"(result)); + return (result); +} + +/** + \brief Set SCER + \details Assigns the given value to the SCER. + \param [in] scer SCER value to set + */ +__ALWAYS_STATIC_INLINE void __set_SCER(unsigned long scer) +{ + __ASM volatile("csrw scer, %0" : : "r"(scer)); +} + +/** + \brief Get MCER + \details Returns the current value of the MCER. + \return MCER Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MCER(void) +{ + register unsigned long result; + __ASM volatile("csrr %0, mcer" : "=r"(result)); + return (result); +} + +/** + \brief Set MCER + \details Assigns the given value to the MCER. + \param [in] mcer MCER value to set + */ +__ALWAYS_STATIC_INLINE void __set_MCER(unsigned long mcer) +{ + __ASM volatile("csrw mcer, %0" : : "r"(mcer)); +} + +#if __riscv_xlen == 32 +/** + \brief Get MCERH + \details Returns the current value of the MCERH. + \return MCERH Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MCERH(void) +{ + register unsigned long result; + __ASM volatile("csrr %0, mcerh" : "=r"(result)); + return (result); +} + +/** + \brief Set MCERH + \details Assigns the given value to the MCERH. + \param [in] mcerh MCERH value to set + */ +__ALWAYS_STATIC_INLINE void __set_MCERH(unsigned long mcerh) +{ + __ASM volatile("csrw mcerh, %0" : : "r"(mcerh)); +} +#endif + +/** + \brief Get SSBEPA + \details Returns the current value of the SSBEPA. + \return SSBEPA Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_SSBEPA(void) +{ + register unsigned long result; + //__ASM volatile("csrr %0, ssbepa" : "=r"(result)); + __ASM volatile("csrr %0, 0x5d1" : "=r"(result)); + return (result); +} + +/** + \brief Set SSBEPA + \details Assigns the given value to the SSBEPA. + \param [in] ssbepa SSBEPA value to set + */ +__ALWAYS_STATIC_INLINE void __set_SSBEPA(unsigned long ssbepa) +{ + //__ASM volatile("csrw ssbepa, %0" : : "r"(ssbepa)); + __ASM volatile("csrw 0x5d1, %0" : : "r"(ssbepa)); +} + +/** + \brief Get MSBEPA + \details Returns the current value of the MSBEPA. + \return MSBEPA Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MSBEPA(void) +{ + register unsigned long result; + //__ASM volatile("csrr %0, msbepa" : "=r"(result)); + __ASM volatile("csrr %0, 0x7fb" : "=r"(result)); + return (result); +} + +/** + \brief Set MSBEPA + \details Assigns the given value to the MSBEPA. + \param [in] msbepa MSBEPA value to set + */ +__ALWAYS_STATIC_INLINE void __set_MSBEPA(unsigned long msbepa) +{ + //__ASM volatile("csrw msbepa, %0" : : "r"(msbepa)); + __ASM volatile("csrw 0x7fb, %0" : : "r"(msbepa)); +} + +/** + \brief Get ERRSTS + \details Returns the current value of the ERRSTS. + \return ERRSTS Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MIESR(void) +{ + register unsigned long result; + + __ASM volatile("csrr %0, miesr" : "=r"(result)); + return (result); +} + +/** + \brief Get MEICR2 + \details Returns the current value of the MEICR2. + \return MEICR2 Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MEICR2(void) +{ + register unsigned long result; + + __ASM volatile("csrr %0, meicr2" : "=r"(result)); + return (result); +} + +/** + \brief Set MEICR2 + \details Assigns the given value to the MEICR2. + \param [in] errinjcr MEICR2 value to set + */ +__ALWAYS_STATIC_INLINE void __set_MEICR2(unsigned long meicr2) +{ + __ASM volatile("csrw meicr2, %0" : : "r"(meicr2)); +} + +/** + \brief Get MEICR + \details Returns the current value of the MEICR. + \return MEICR Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MEICR(void) +{ + register unsigned long result; + + __ASM volatile("csrr %0, meicr" : "=r"(result)); + return (result); +} + +/** + \brief Set MEICR + \details Assigns the given value to the MEICR. + \param [in] errinjcr MEICR value to set + */ +__ALWAYS_STATIC_INLINE void __set_MEICR(unsigned long meicr) +{ + __ASM volatile("csrw meicr, %0" : : "r"(meicr)); +} + +/** + \brief Get ITCMCR + \details Returns the content of the ITCMCR Register. + \return ITCMCR Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MITCMCR(void) +{ + unsigned long result; + __ASM volatile("csrr %0, mitcmcr" : "=r"(result)); + return (result); +} + +/** + \brief Set ITCMCR + \details Writes the given value to the ITCMCR Register. + \param [in] itcmcr ITCMCR Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MITCMCR(unsigned long itcmcr) +{ + __ASM volatile("csrw mitcmcr, %0" : : "r"(itcmcr)); +} + +/** + \brief Get DTCMCR + \details Returns the content of the DTCMCR Register. + \return DTCMCR Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MDTCMCR(void) +{ + unsigned long result; + __ASM volatile("csrr %0, mdtcmcr" : "=r"(result)); + return (result); +} + +/** + \brief Set DTCMCR + \details Writes the given value to the DTCMCR Register. + \param [in] dtcmcr DTCMCR Registed value to set + */ +__ALWAYS_STATIC_INLINE void __set_MDTCMCR(unsigned long dtcmcr) +{ + __ASM volatile("csrw mdtcmcr, %0" : : "r"(dtcmcr)); +} + +/** + \brief Get MFPPCR + \details Read MFPPCR Register. + \return MFPPCR Register value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MFPPCR(void) +{ + unsigned long result; + __ASM volatile("csrr %0, mfppcr" : "=r"(result)); + return (result); +} + +/** + \brief Set MFPPCR + \details Write MFPPCR Register. + \param [in] fppcr MFPPCR Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MFPPCR(unsigned long fppcr) +{ + __ASM volatile("csrw mfppcr, %0" : : "r"(fppcr)); +} + +/** + \brief Set MCOUNTINHIBIT + \details Write MCOUNTINHIBIT Register. + \param [in] value MCOUNTINHIBIT Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MCOUNTINHIBIT(uint32_t value) +{ + __ASM volatile("csrw mcountinhibit, %0" : : "r"(value)); +} + +/** + \brief Get MCOUNTINHIBIT + \details Read MCOUNTINHIBIT Register + \return MCOUNTINHIBIT Register value + */ +__ALWAYS_STATIC_INLINE unsigned int __get_MCOUNTINHIBIT(void) +{ + uint32_t result; + __ASM volatile("csrr %0, mcountinhibit" : "=r"(result)); + return result; +} + +/** + \brief Set MHPMEVENT + \details Write MHPMEVENT Register + \param [in] idx Index of MHPMEVENT Register + \param [in] value MHPMEVENT Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MHPMEVENT(unsigned long idx, unsigned long value) +{ + switch (idx) { + case 0: rv_csr_write(0x7E0, value); break; + case 2: rv_csr_write(0x7E1, value); break; + case 3: rv_csr_write(0x323, value); break; + case 4: rv_csr_write(0x324, value); break; + case 5: rv_csr_write(0x325, value); break; + case 6: rv_csr_write(0x326, value); break; + case 7: rv_csr_write(0x327, value); break; + case 8: rv_csr_write(0x328, value); break; + case 9: rv_csr_write(0x329, value); break; + case 10: rv_csr_write(0x32a, value); break; + case 11: rv_csr_write(0x32b, value); break; + case 12: rv_csr_write(0x32c, value); break; + case 13: rv_csr_write(0x32d, value); break; + case 14: rv_csr_write(0x32e, value); break; + case 15: rv_csr_write(0x32f, value); break; + case 16: rv_csr_write(0x330, value); break; + case 17: rv_csr_write(0x331, value); break; + case 18: rv_csr_write(0x332, value); break; + case 19: rv_csr_write(0x333, value); break; + case 20: rv_csr_write(0x334, value); break; + case 21: rv_csr_write(0x335, value); break; + case 22: rv_csr_write(0x336, value); break; + case 23: rv_csr_write(0x337, value); break; + case 24: rv_csr_write(0x338, value); break; + case 25: rv_csr_write(0x339, value); break; + case 26: rv_csr_write(0x33a, value); break; + case 27: rv_csr_write(0x33b, value); break; + case 28: rv_csr_write(0x33c, value); break; + case 29: rv_csr_write(0x33d, value); break; + case 30: rv_csr_write(0x33e, value); break; + case 31: rv_csr_write(0x33F, value); break; + default: break; + } +} + +/** + \brief Get MHPMEVENT + \details Read MHPMEVENT Register. + \param [in] idx Index of MHPMEVENT Register to read. + \return MHPMEVENT Register Value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MHPMEVENT(unsigned long idx) +{ + switch (idx) { + case 0: return rv_csr_read(0x7E0); + case 2: return rv_csr_read(0x7E1); + case 3: return rv_csr_read(0x323); + case 4: return rv_csr_read(0x324); + case 5: return rv_csr_read(0x325); + case 6: return rv_csr_read(0x326); + case 7: return rv_csr_read(0x327); + case 8: return rv_csr_read(0x328); + case 9: return rv_csr_read(0x329); + case 10: return rv_csr_read(0x32a); + case 11: return rv_csr_read(0x32b); + case 12: return rv_csr_read(0x32c); + case 13: return rv_csr_read(0x32d); + case 14: return rv_csr_read(0x32e); + case 15: return rv_csr_read(0x32f); + case 16: return rv_csr_read(0x330); + case 17: return rv_csr_read(0x331); + case 18: return rv_csr_read(0x332); + case 19: return rv_csr_read(0x333); + case 20: return rv_csr_read(0x334); + case 21: return rv_csr_read(0x335); + case 22: return rv_csr_read(0x336); + case 23: return rv_csr_read(0x337); + case 24: return rv_csr_read(0x338); + case 25: return rv_csr_read(0x339); + case 26: return rv_csr_read(0x33a); + case 27: return rv_csr_read(0x33b); + case 28: return rv_csr_read(0x33c); + case 29: return rv_csr_read(0x33d); + case 30: return rv_csr_read(0x33e); + case 31: return rv_csr_read(0x33F); + default: return 0; + } +} + +/** + \brief Set MHPMEVENTH + \details Write MHPMEVENTH Register + \param [in] idx Index of MHPMEVENT Register + \param [in] value MHPMEVENTH Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MHPMEVENTH(unsigned long idx, unsigned long value) +{ + switch (idx) { + case 3: rv_csr_write(0x723, value); break; + case 4: rv_csr_write(0x724, value); break; + case 5: rv_csr_write(0x725, value); break; + case 6: rv_csr_write(0x726, value); break; + case 7: rv_csr_write(0x727, value); break; + case 8: rv_csr_write(0x728, value); break; + case 9: rv_csr_write(0x729, value); break; + case 10: rv_csr_write(0x72A, value); break; + case 11: rv_csr_write(0x72B, value); break; + case 12: rv_csr_write(0x72C, value); break; + case 13: rv_csr_write(0x72D, value); break; + case 14: rv_csr_write(0x72E, value); break; + case 15: rv_csr_write(0x72F, value); break; + case 16: rv_csr_write(0x730, value); break; + case 17: rv_csr_write(0x731, value); break; + case 18: rv_csr_write(0x732, value); break; + case 19: rv_csr_write(0x733, value); break; + case 20: rv_csr_write(0x734, value); break; + case 21: rv_csr_write(0x735, value); break; + case 22: rv_csr_write(0x736, value); break; + case 23: rv_csr_write(0x737, value); break; + case 24: rv_csr_write(0x738, value); break; + case 25: rv_csr_write(0x739, value); break; + case 26: rv_csr_write(0x73A, value); break; + case 27: rv_csr_write(0x73B, value); break; + case 28: rv_csr_write(0x73C, value); break; + case 29: rv_csr_write(0x73D, value); break; + case 30: rv_csr_write(0x73E, value); break; + case 31: rv_csr_write(0x73F, value); break; + default: break; + } +} + +/** + \brief Get MHPMEVENTH + \details Read MHPMEVENTH Register. + \param [in] idx Index of MHPMEVENTH Register to read. + \return MHPMEVENTH Register Value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MHPMEVENTH(unsigned long idx) +{ + switch (idx) { + case 3: return rv_csr_read(0x723); + case 4: return rv_csr_read(0x724); + case 5: return rv_csr_read(0x725); + case 6: return rv_csr_read(0x726); + case 7: return rv_csr_read(0x727); + case 8: return rv_csr_read(0x728); + case 9: return rv_csr_read(0x729); + case 10: return rv_csr_read(0x72A); + case 11: return rv_csr_read(0x72B); + case 12: return rv_csr_read(0x72C); + case 13: return rv_csr_read(0x72D); + case 14: return rv_csr_read(0x72E); + case 15: return rv_csr_read(0x72F); + case 16: return rv_csr_read(0x730); + case 17: return rv_csr_read(0x731); + case 18: return rv_csr_read(0x732); + case 19: return rv_csr_read(0x733); + case 20: return rv_csr_read(0x734); + case 21: return rv_csr_read(0x735); + case 22: return rv_csr_read(0x736); + case 23: return rv_csr_read(0x737); + case 24: return rv_csr_read(0x738); + case 25: return rv_csr_read(0x739); + case 26: return rv_csr_read(0x73A); + case 27: return rv_csr_read(0x73B); + case 28: return rv_csr_read(0x73C); + case 29: return rv_csr_read(0x73D); + case 30: return rv_csr_read(0x73E); + case 31: return rv_csr_read(0x73F); + default: return 0; + } +} + +/** + \brief Set MHPMCOUNTER + \details Write MHPMCOUNTER Register + \param [in] idx Index of MHPMCOUNTER Register + \param [in] value MHPMCOUNTER Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MHPMCOUNTER(unsigned long idx, unsigned long value) +{ + switch (idx) { + case 3: rv_csr_write(0xB03, (value)); break; + case 4: rv_csr_write(0xB04, (value)); break; + case 5: rv_csr_write(0xB05, (value)); break; + case 6: rv_csr_write(0xB06, (value)); break; + case 7: rv_csr_write(0xB07, (value)); break; + case 8: rv_csr_write(0xB08, (value)); break; + case 9: rv_csr_write(0xB09, (value)); break; + case 10: rv_csr_write(0xB0A, (value)); break; + case 11: rv_csr_write(0xB0B, (value)); break; + case 12: rv_csr_write(0xB0C, (value)); break; + case 13: rv_csr_write(0xB0D, (value)); break; + case 14: rv_csr_write(0xB0E, (value)); break; + case 15: rv_csr_write(0xB0F, (value)); break; + case 16: rv_csr_write(0xB10, (value)); break; + case 17: rv_csr_write(0xB11, (value)); break; + case 18: rv_csr_write(0xB12, (value)); break; + case 19: rv_csr_write(0xB13, (value)); break; + case 20: rv_csr_write(0xB14, (value)); break; + case 21: rv_csr_write(0xB15, (value)); break; + case 22: rv_csr_write(0xB16, (value)); break; + case 23: rv_csr_write(0xB17, (value)); break; + case 24: rv_csr_write(0xB18, (value)); break; + case 25: rv_csr_write(0xB19, (value)); break; + case 26: rv_csr_write(0xB1A, (value)); break; + case 27: rv_csr_write(0xB1B, (value)); break; + case 28: rv_csr_write(0xB1C, (value)); break; + case 29: rv_csr_write(0xB1D, (value)); break; + case 30: rv_csr_write(0xB1E, (value)); break; + case 31: rv_csr_write(0xB1F, (value)); break; + default: break; + } +} + +/** + \brief Get MHPMCOUNTER + \details Write MHPMCOUNTER Register. + \param [in] idx Index of MHPMCOUNTER Register + \return MHPMCOUNTER Register Value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MHPMCOUNTER(unsigned long idx) +{ + switch (idx) { + case 3: return rv_csr_read(0xB03); + case 4: return rv_csr_read(0xB04); + case 5: return rv_csr_read(0xB05); + case 6: return rv_csr_read(0xB06); + case 7: return rv_csr_read(0xB07); + case 8: return rv_csr_read(0xB08); + case 9: return rv_csr_read(0xB09); + case 10: return rv_csr_read(0xB0A); + case 11: return rv_csr_read(0xB0B); + case 12: return rv_csr_read(0xB0C); + case 13: return rv_csr_read(0xB0D); + case 14: return rv_csr_read(0xB0E); + case 15: return rv_csr_read(0xB0F); + case 16: return rv_csr_read(0xB10); + case 17: return rv_csr_read(0xB11); + case 18: return rv_csr_read(0xB12); + case 19: return rv_csr_read(0xB13); + case 20: return rv_csr_read(0xB14); + case 21: return rv_csr_read(0xB15); + case 22: return rv_csr_read(0xB16); + case 23: return rv_csr_read(0xB17); + case 24: return rv_csr_read(0xB18); + case 25: return rv_csr_read(0xB19); + case 26: return rv_csr_read(0xB1A); + case 27: return rv_csr_read(0xB1B); + case 28: return rv_csr_read(0xB1C); + case 29: return rv_csr_read(0xB1D); + case 30: return rv_csr_read(0xB1E); + case 31: return rv_csr_read(0xB1F); + default: return 0; + } +} + +/** + \brief Set MHPMCOUNTERH + \details Write MHPMCOUNTERH Register + \param [in] idx Index of MHPMCOUNTERH Register + \param [in] value MHPMCOUNTERH Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MHPMCOUNTERH(unsigned long idx, unsigned long value) +{ + switch (idx) { + case 3: rv_csr_write(0xB83, (value)); break; + case 4: rv_csr_write(0xB84, (value)); break; + case 5: rv_csr_write(0xB85, (value)); break; + case 6: rv_csr_write(0xB86, (value)); break; + case 7: rv_csr_write(0xB87, (value)); break; + case 8: rv_csr_write(0xB88, (value)); break; + case 9: rv_csr_write(0xB89, (value)); break; + case 10: rv_csr_write(0xB8A, (value)); break; + case 11: rv_csr_write(0xB8B, (value)); break; + case 12: rv_csr_write(0xB8C, (value)); break; + case 13: rv_csr_write(0xB8D, (value)); break; + case 14: rv_csr_write(0xB8E, (value)); break; + case 15: rv_csr_write(0xB8F, (value)); break; + case 16: rv_csr_write(0xB90, (value)); break; + case 17: rv_csr_write(0xB91, (value)); break; + case 18: rv_csr_write(0xB92, (value)); break; + case 19: rv_csr_write(0xB93, (value)); break; + case 20: rv_csr_write(0xB94, (value)); break; + case 21: rv_csr_write(0xB95, (value)); break; + case 22: rv_csr_write(0xB96, (value)); break; + case 23: rv_csr_write(0xB97, (value)); break; + case 24: rv_csr_write(0xB98, (value)); break; + case 25: rv_csr_write(0xB99, (value)); break; + case 26: rv_csr_write(0xB9A, (value)); break; + case 27: rv_csr_write(0xB9B, (value)); break; + case 28: rv_csr_write(0xB9C, (value)); break; + case 29: rv_csr_write(0xB9D, (value)); break; + case 30: rv_csr_write(0xB9E, (value)); break; + case 31: rv_csr_write(0xB9F, (value)); break; + default: break; + } +} + +/** + \brief Get MHPMCOUNTERH + \details Write MHPMCOUNTERH Register. + \param [in] idx Index of MHPMCOUNTERH Register + \return MHPMCOUNTERH Register Value + */ +__ALWAYS_STATIC_INLINE unsigned long __get_MHPMCOUNTERH(unsigned long idx) +{ + switch (idx) { + case 3: return rv_csr_read(0xB83); + case 4: return rv_csr_read(0xB84); + case 5: return rv_csr_read(0xB85); + case 6: return rv_csr_read(0xB86); + case 7: return rv_csr_read(0xB87); + case 8: return rv_csr_read(0xB88); + case 9: return rv_csr_read(0xB89); + case 10: return rv_csr_read(0xB8A); + case 11: return rv_csr_read(0xB8B); + case 12: return rv_csr_read(0xB8C); + case 13: return rv_csr_read(0xB8D); + case 14: return rv_csr_read(0xB8E); + case 15: return rv_csr_read(0xB8F); + case 16: return rv_csr_read(0xB90); + case 17: return rv_csr_read(0xB91); + case 18: return rv_csr_read(0xB92); + case 19: return rv_csr_read(0xB93); + case 20: return rv_csr_read(0xB94); + case 21: return rv_csr_read(0xB95); + case 22: return rv_csr_read(0xB96); + case 23: return rv_csr_read(0xB97); + case 24: return rv_csr_read(0xB98); + case 25: return rv_csr_read(0xB99); + case 26: return rv_csr_read(0xB9A); + case 27: return rv_csr_read(0xB9B); + case 28: return rv_csr_read(0xB9C); + case 29: return rv_csr_read(0xB9D); + case 30: return rv_csr_read(0xB9E); + case 31: return rv_csr_read(0xB9F); + default: return 0; + } +} + +#if 0 +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in integer value. + \param [in] value Value to reverse + \return Reversed value + */ +__ALWAYS_STATIC_INLINE unsigned long __REV(unsigned long value) +{ + return __builtin_bswap32(value); +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in two unsigned short values. + \param [in] value Value to reverse + \return Reversed value + */ +__ALWAYS_STATIC_INLINE 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 in signed short value + \details Reverses the byte order in a signed short value with sign extension to integer. + \param [in] value Value to reverse + \return Reversed value + */ +__ALWAYS_STATIC_INLINE int32_t __REVSH(int32_t value) +{ + return (short)(((value & 0xFF00) >> 8) | ((value & 0x00FF) << 8)); +} + + +/** + \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 + \return Rotated value + */ +__ALWAYS_STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \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. + */ +__ALWAYS_STATIC_INLINE void __BKPT(void) +{ + __ASM volatile("ebreak"); +} + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +__ALWAYS_STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + + int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + + for (value >>= 1U; value; value >>= 1U) { + result <<= 1U; + result |= value & 1U; + s--; + } + + result <<= s; /* shift when v's highest bits are zero */ + + return (result); +} + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __builtin_clz +/** + \details This function saturates a signed value. + \param [in] x Value to be saturated + \param [in] y Bit position to saturate to [1..32] + \return Saturated value. + */ +__ALWAYS_STATIC_INLINE int32_t __SSAT(int32_t x, uint32_t y) +{ + int32_t posMax, negMin; + uint32_t i; + + posMax = 1; + + for (i = 0; i < (y - 1); i++) { + posMax = posMax * 2; + } + + if (x > 0) { + posMax = (posMax - 1); + + if (x > posMax) { + x = posMax; + } + +// x &= (posMax * 2 + 1); + } else { + negMin = -posMax; + + if (x < negMin) { + x = negMin; + } + +// x &= (posMax * 2 - 1); + } + + return (x); +} + +/** + \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 + */ +__ALWAYS_STATIC_INLINE uint32_t __USAT(uint32_t value, uint32_t sat) +{ + uint32_t result; + + if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) { + result = 0xFFFFFFFF >> (32 - sat); + } else { + result = value; + } + + return (result); +} + +/** + \brief Unsigned Saturate for internal use + \details Saturates an unsigned value, should not call directly. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__ALWAYS_STATIC_INLINE uint32_t __IUSAT(uint32_t value, uint32_t sat) +{ + uint32_t result; + + if (value & 0x80000000) { /* only overflow set bit-31 */ + result = 0; + } else if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) { + result = 0xFFFFFFFF >> (32 - sat); + } else { + result = value; + } + + return (result); +} + +/** + \brief Rotate Right with Extend + \details This function moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \note carry input will always 0. + \param [in] op1 Value to rotate + \return Rotated value + */ +__ALWAYS_STATIC_INLINE uint32_t __RRX(uint32_t op1) +{ + return 0; +} + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] addr Pointer to location + \return value of type uint8_t at (*ptr) + */ +__ALWAYS_STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile("lb %0, 0(%1)" : "=r"(result) : "r"(addr)); + + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] addr Pointer to location + \return value of type uint16_t at (*ptr) + */ +__ALWAYS_STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile("lh %0, 0(%1)" : "=r"(result) : "r"(addr)); + + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] addr Pointer to location + \return value of type uint32_t at (*ptr) + */ +__ALWAYS_STATIC_INLINE uint32_t __LDRT(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile("lw %0, 0(%1)" : "=r"(result) : "r"(addr)); + + return (result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] addr Pointer to location + */ +__ALWAYS_STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr) +{ + __ASM volatile("sb %1, 0(%0)" :: "r"(addr), "r"((uint32_t)value) : "memory"); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] addr Pointer to location + */ +__ALWAYS_STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr) +{ + __ASM volatile("sh %1, 0(%0)" :: "r"(addr), "r"((uint32_t)value) : "memory"); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] addr Pointer to location + */ +__ALWAYS_STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *addr) +{ + __ASM volatile("sw %1, 0(%0)" :: "r"(addr), "r"(value) : "memory"); +} + +/*@}*/ /* end of group CSI_Core_InstructionInterface */ + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CSI_SIMD_intrinsics CSI SIMD Intrinsics + Access to dedicated SIMD instructions \n + Single Instruction Multiple Data (SIMD) extensions are provided to simplify development of application software. SIMD extensions increase the processing capability without materially increasing the power consumption. The SIMD extensions are completely transparent to the operating system (OS), allowing existing OS ports to be used. + + @{ +*/ + +/** + \brief Halfword packing instruction. Combines bits[15:0] of val1 with bits[31:16] + of val2 levitated with the val3. + \details Combine a halfword from one register with a halfword from another register. + The second argument can be left-shifted before extraction of the halfword. + \param [in] val1 first 16-bit operands + \param [in] val2 second 16-bit operands + \param [in] val3 value for left-shifting val2. Value range [0..31]. + \return the combination of halfwords. + \remark + res[15:0] = val1[15:0] \n + res[31:16] = val2[31:16] << val3 + */ +__ALWAYS_STATIC_INLINE uint32_t __PKHBT(uint32_t val1, uint32_t val2, uint32_t val3) +{ + return ((((int32_t)(val1) << 0) & (int32_t)0x0000FFFF) | (((int32_t)(val2) << val3) & (int32_t)0xFFFF0000)); +} + +/** + \brief Halfword packing instruction. Combines bits[31:16] of val1 with bits[15:0] + of val2 right-shifted with the val3. + \details Combine a halfword from one register with a halfword from another register. + The second argument can be right-shifted before extraction of the halfword. + \param [in] val1 first 16-bit operands + \param [in] val2 second 16-bit operands + \param [in] val3 value for right-shifting val2. Value range [1..32]. + \return the combination of halfwords. + \remark + res[15:0] = val2[15:0] >> val3 \n + res[31:16] = val1[31:16] + */ +__ALWAYS_STATIC_INLINE uint32_t __PKHTB(uint32_t val1, uint32_t val2, uint32_t val3) +{ + return ((((int32_t)(val1) << 0) & (int32_t)0xFFFF0000) | (((int32_t)(val2) >> val3) & (int32_t)0x0000FFFF)); +} + +/** + \brief Dual 16-bit signed saturate. + \details This function saturates a signed value. + \param [in] x two signed 16-bit values to be saturated. + \param [in] y bit position for saturation, an integral constant expression in the range 1 to 16. + \return the sum of the absolute differences of the following bytes, added to the accumulation value:\n + the signed saturation of the low halfword in val1, saturated to the bit position specified in + val2 and returned in the low halfword of the return value.\n + the signed saturation of the high halfword in val1, saturated to the bit position specified in + val2 and returned in the high halfword of the return value. + */ +__ALWAYS_STATIC_INLINE uint32_t __SSAT16(int32_t x, const uint32_t y) +{ + int32_t r = 0, s = 0; + + r = __SSAT((((int32_t)x << 16) >> 16), y) & (int32_t)0x0000FFFF; + s = __SSAT((((int32_t)x) >> 16), y) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned saturate. + \details This function enables you to saturate two signed 16-bit values to a selected unsigned range. + \param [in] x two signed 16-bit values to be saturated. + \param [in] y bit position for saturation, an integral constant expression in the range 1 to 16. + \return the saturation of the two signed 16-bit values, as non-negative values: + the saturation of the low halfword in val1, saturated to the bit position specified in + val2 and returned in the low halfword of the return value.\n + the saturation of the high halfword in val1, saturated to the bit position specified in + val2 and returned in the high halfword of the return value. + */ +__ALWAYS_STATIC_INLINE uint32_t __USAT16(uint32_t x, const uint32_t y) +{ + int32_t r = 0, s = 0; + + r = __IUSAT(((x << 16) >> 16), y) & 0x0000FFFF; + s = __IUSAT(((x) >> 16), y) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Quad 8-bit saturating addition. + \details This function enables you to perform four 8-bit integer additions, + saturating the results to the 8-bit signed integer range -2^7 <= x <= 2^7 - 1. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the saturated addition of the first byte of each operand in the first byte of the return value.\n + the saturated addition of the second byte of each operand in the second byte of the return value.\n + the saturated addition of the third byte of each operand in the third byte of the return value.\n + the saturated addition of the fourth byte of each operand in the fourth byte of the return value.\n + The returned results are saturated to the 8-bit signed integer range -2^7 <= x <= 2^7 - 1. + \remark + res[7:0] = val1[7:0] + val2[7:0] \n + res[15:8] = val1[15:8] + val2[15:8] \n + res[23:16] = val1[23:16] + val2[23:16] \n + res[31:24] = val1[31:24] + val2[31:24] + */ +__ALWAYS_STATIC_INLINE uint32_t __QADD8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = __SSAT(((((int32_t)x << 24) >> 24) + (((int32_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((int32_t)x << 16) >> 24) + (((int32_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((int32_t)x << 8) >> 24) + (((int32_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((int32_t)x) >> 24) + (((int32_t)y) >> 24)), 8) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r))); +} + +/** + \brief Quad 8-bit unsigned saturating addition. + \details This function enables you to perform four unsigned 8-bit integer additions, + saturating the results to the 8-bit unsigned integer range 0 < x < 2^8 - 1. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the saturated addition of the first byte of each operand in the first byte of the return value.\n + the saturated addition of the second byte of each operand in the second byte of the return value.\n + the saturated addition of the third byte of each operand in the third byte of the return value.\n + the saturated addition of the fourth byte of each operand in the fourth byte of the return value.\n + The returned results are saturated to the 8-bit signed integer range 0 <= x <= 2^8 - 1. + \remark + res[7:0] = val1[7:0] + val2[7:0] \n + res[15:8] = val1[15:8] + val2[15:8] \n + res[23:16] = val1[23:16] + val2[23:16] \n + res[31:24] = val1[31:24] + val2[31:24] + */ +__ALWAYS_STATIC_INLINE uint32_t __UQADD8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = __IUSAT((((x << 24) >> 24) + ((y << 24) >> 24)), 8) & 0x000000FF; + s = __IUSAT((((x << 16) >> 24) + ((y << 16) >> 24)), 8) & 0x000000FF; + t = __IUSAT((((x << 8) >> 24) + ((y << 8) >> 24)), 8) & 0x000000FF; + u = __IUSAT((((x) >> 24) + ((y) >> 24)), 8) & 0x000000FF; + + return ((u << 24) | (t << 16) | (s << 8) | (r)); +} + +/** + \brief Quad 8-bit signed addition. + \details This function performs four 8-bit signed integer additions. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the addition of the first bytes from each operand, in the first byte of the return value.\n + the addition of the second bytes of each operand, in the second byte of the return value.\n + the addition of the third bytes of each operand, in the third byte of the return value.\n + the addition of the fourth bytes of each operand, in the fourth byte of the return value. + \remark + res[7:0] = val1[7:0] + val2[7:0] \n + res[15:8] = val1[15:8] + val2[15:8] \n + res[23:16] = val1[23:16] + val2[23:16] \n + res[31:24] = val1[31:24] + val2[31:24] + */ +__ALWAYS_STATIC_INLINE uint32_t __SADD8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = ((((int32_t)x << 24) >> 24) + (((int32_t)y << 24) >> 24)) & (int32_t)0x000000FF; + s = ((((int32_t)x << 16) >> 24) + (((int32_t)y << 16) >> 24)) & (int32_t)0x000000FF; + t = ((((int32_t)x << 8) >> 24) + (((int32_t)y << 8) >> 24)) & (int32_t)0x000000FF; + u = ((((int32_t)x) >> 24) + (((int32_t)y) >> 24)) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r))); +} + +/** + \brief Quad 8-bit unsigned addition. + \details This function performs four unsigned 8-bit integer additions. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the addition of the first bytes from each operand, in the first byte of the return value.\n + the addition of the second bytes of each operand, in the second byte of the return value.\n + the addition of the third bytes of each operand, in the third byte of the return value.\n + the addition of the fourth bytes of each operand, in the fourth byte of the return value. + \remark + res[7:0] = val1[7:0] + val2[7:0] \n + res[15:8] = val1[15:8] + val2[15:8] \n + res[23:16] = val1[23:16] + val2[23:16] \n + res[31:24] = val1[31:24] + val2[31:24] + */ +__ALWAYS_STATIC_INLINE uint32_t __UADD8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = (((x << 24) >> 24) + ((y << 24) >> 24)) & 0x000000FF; + s = (((x << 16) >> 24) + ((y << 16) >> 24)) & 0x000000FF; + t = (((x << 8) >> 24) + ((y << 8) >> 24)) & 0x000000FF; + u = (((x) >> 24) + ((y) >> 24)) & 0x000000FF; + + return ((u << 24) | (t << 16) | (s << 8) | (r)); +} + +/** + \brief Quad 8-bit saturating subtract. + \details This function enables you to perform four 8-bit integer subtractions, + saturating the results to the 8-bit signed integer range -2^7 <= x <= 2^7 - 1. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the subtraction of the first byte of each operand in the first byte of the return value.\n + the subtraction of the second byte of each operand in the second byte of the return value.\n + the subtraction of the third byte of each operand in the third byte of the return value.\n + the subtraction of the fourth byte of each operand in the fourth byte of the return value.\n + The returned results are saturated to the 8-bit signed integer range -2^7 <= x <= 2^7 - 1. + \remark + res[7:0] = val1[7:0] - val2[7:0] \n + res[15:8] = val1[15:8] - val2[15:8] \n + res[23:16] = val1[23:16] - val2[23:16] \n + res[31:24] = val1[31:24] - val2[31:24] + */ +__ALWAYS_STATIC_INLINE uint32_t __QSUB8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = __SSAT(((((int32_t)x << 24) >> 24) - (((int32_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((int32_t)x << 16) >> 24) - (((int32_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((int32_t)x << 8) >> 24) - (((int32_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((int32_t)x) >> 24) - (((int32_t)y) >> 24)), 8) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r))); +} + +/** + \brief Quad 8-bit unsigned saturating subtraction. + \details This function enables you to perform four unsigned 8-bit integer subtractions, + saturating the results to the 8-bit unsigned integer range 0 < x < 2^8 - 1. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the subtraction of the first byte of each operand in the first byte of the return value.\n + the subtraction of the second byte of each operand in the second byte of the return value.\n + the subtraction of the third byte of each operand in the third byte of the return value.\n + the subtraction of the fourth byte of each operand in the fourth byte of the return value.\n + The returned results are saturated to the 8-bit unsigned integer range 0 <= x <= 2^8 - 1. + \remark + res[7:0] = val1[7:0] - val2[7:0] \n + res[15:8] = val1[15:8] - val2[15:8] \n + res[23:16] = val1[23:16] - val2[23:16] \n + res[31:24] = val1[31:24] - val2[31:24] + */ +__ALWAYS_STATIC_INLINE uint32_t __UQSUB8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = __IUSAT((((x << 24) >> 24) - ((y << 24) >> 24)), 8) & 0x000000FF; + s = __IUSAT((((x << 16) >> 24) - ((y << 16) >> 24)), 8) & 0x000000FF; + t = __IUSAT((((x << 8) >> 24) - ((y << 8) >> 24)), 8) & 0x000000FF; + u = __IUSAT((((x) >> 24) - ((y) >> 24)), 8) & 0x000000FF; + + return ((u << 24) | (t << 16) | (s << 8) | (r)); +} + +/** + \brief Quad 8-bit signed subtraction. + \details This function enables you to perform four 8-bit signed integer subtractions. + \param [in] x first four 8-bit operands of each subtraction. + \param [in] y second four 8-bit operands of each subtraction. + \return the subtraction of the first bytes from each operand, in the first byte of the return value.\n + the subtraction of the second bytes of each operand, in the second byte of the return value.\n + the subtraction of the third bytes of each operand, in the third byte of the return value.\n + the subtraction of the fourth bytes of each operand, in the fourth byte of the return value. + \remark + res[7:0] = val1[7:0] - val2[7:0] \n + res[15:8] = val1[15:8] - val2[15:8] \n + res[23:16] = val1[23:16] - val2[23:16] \n + res[31:24] = val1[31:24] - val2[31:24] + */ +__ALWAYS_STATIC_INLINE uint32_t __SSUB8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = ((((int32_t)x << 24) >> 24) - (((int32_t)y << 24) >> 24)) & (int32_t)0x000000FF; + s = ((((int32_t)x << 16) >> 24) - (((int32_t)y << 16) >> 24)) & (int32_t)0x000000FF; + t = ((((int32_t)x << 8) >> 24) - (((int32_t)y << 8) >> 24)) & (int32_t)0x000000FF; + u = ((((int32_t)x) >> 24) - (((int32_t)y) >> 24)) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r))); +} + +/** + \brief Quad 8-bit unsigned subtract. + \details This function enables you to perform four 8-bit unsigned integer subtractions. + \param [in] x first four 8-bit operands of each subtraction. + \param [in] y second four 8-bit operands of each subtraction. + \return the subtraction of the first bytes from each operand, in the first byte of the return value.\n + the subtraction of the second bytes of each operand, in the second byte of the return value.\n + the subtraction of the third bytes of each operand, in the third byte of the return value.\n + the subtraction of the fourth bytes of each operand, in the fourth byte of the return value. + \remark + res[7:0] = val1[7:0] - val2[7:0] \n + res[15:8] = val1[15:8] - val2[15:8] \n + res[23:16] = val1[23:16] - val2[23:16] \n + res[31:24] = val1[31:24] - val2[31:24] + */ +__ALWAYS_STATIC_INLINE uint32_t __USUB8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = (((x << 24) >> 24) - ((y << 24) >> 24)) & 0x000000FF; + s = (((x << 16) >> 24) - ((y << 16) >> 24)) & 0x000000FF; + t = (((x << 8) >> 24) - ((y << 8) >> 24)) & 0x000000FF; + u = (((x) >> 24) - ((y) >> 24)) & 0x000000FF; + + return ((u << 24) | (t << 16) | (s << 8) | (r)); +} + +/** + \brief Unsigned sum of quad 8-bit unsigned absolute difference. + \details This function enables you to perform four unsigned 8-bit subtractions, and add the absolute values + of the differences together, returning the result as a single unsigned integer. + \param [in] x first four 8-bit operands of each subtraction. + \param [in] y second four 8-bit operands of each subtraction. + \return the subtraction of the first bytes from each operand, in the first byte of the return value.\n + the subtraction of the second bytes of each operand, in the second byte of the return value.\n + the subtraction of the third bytes of each operand, in the third byte of the return value.\n + the subtraction of the fourth bytes of each operand, in the fourth byte of the return value.\n + The sum is returned as a single unsigned integer. + \remark + absdiff1 = val1[7:0] - val2[7:0] \n + absdiff2 = val1[15:8] - val2[15:8] \n + absdiff3 = val1[23:16] - val2[23:16] \n + absdiff4 = val1[31:24] - val2[31:24] \n + res[31:0] = absdiff1 + absdiff2 + absdiff3 + absdiff4 + */ +__ALWAYS_STATIC_INLINE uint32_t __USAD8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = (((x << 24) >> 24) - ((y << 24) >> 24)) & 0x000000FF; + s = (((x << 16) >> 24) - ((y << 16) >> 24)) & 0x000000FF; + t = (((x << 8) >> 24) - ((y << 8) >> 24)) & 0x000000FF; + u = (((x) >> 24) - ((y) >> 24)) & 0x000000FF; + + return (u + t + s + r); +} + +/** + \brief Unsigned sum of quad 8-bit unsigned absolute difference with 32-bit accumulate. + \details This function enables you to perform four unsigned 8-bit subtractions, and add the absolute values + of the differences to a 32-bit accumulate operand. + \param [in] x first four 8-bit operands of each subtraction. + \param [in] y second four 8-bit operands of each subtraction. + \param [in] sum accumulation value. + \return the sum of the absolute differences of the following bytes, added to the accumulation value: + the subtraction of the first bytes from each operand, in the first byte of the return value.\n + the subtraction of the second bytes of each operand, in the second byte of the return value.\n + the subtraction of the third bytes of each operand, in the third byte of the return value.\n + the subtraction of the fourth bytes of each operand, in the fourth byte of the return value. + \remark + absdiff1 = val1[7:0] - val2[7:0] \n + absdiff2 = val1[15:8] - val2[15:8] \n + absdiff3 = val1[23:16] - val2[23:16] \n + absdiff4 = val1[31:24] - val2[31:24] \n + sum = absdiff1 + absdiff2 + absdiff3 + absdiff4 \n + res[31:0] = sum[31:0] + val3[31:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __USADA8(uint32_t x, uint32_t y, uint32_t sum) +{ + int32_t r, s, t, u; + +#ifdef __cplusplus + r = (abs((long long)((x << 24) >> 24) - ((y << 24) >> 24))) & 0x000000FF; + s = (abs((long long)((x << 16) >> 24) - ((y << 16) >> 24))) & 0x000000FF; + t = (abs((long long)((x << 8) >> 24) - ((y << 8) >> 24))) & 0x000000FF; + u = (abs((long long)((x) >> 24) - ((y) >> 24))) & 0x000000FF; +#else + r = (abs(((x << 24) >> 24) - ((y << 24) >> 24))) & 0x000000FF; + s = (abs(((x << 16) >> 24) - ((y << 16) >> 24))) & 0x000000FF; + t = (abs(((x << 8) >> 24) - ((y << 8) >> 24))) & 0x000000FF; + u = (abs(((x) >> 24) - ((y) >> 24))) & 0x000000FF; +#endif + return (u + t + s + r + sum); +} + +/** + \brief Dual 16-bit saturating addition. + \details This function enables you to perform two 16-bit integer arithmetic additions in parallel, + saturating the results to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the saturated addition of the low halfwords, in the low halfword of the return value.\n + the saturated addition of the high halfwords, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \remark + res[15:0] = val1[15:0] + val2[15:0] \n + res[31:16] = val1[31:16] + val2[31:16] + */ +__ALWAYS_STATIC_INLINE uint32_t __QADD16(uint32_t x, uint32_t y) +{ + int32_t r = 0, s = 0; + + r = __SSAT(((((int32_t)x << 16) >> 16) + (((int32_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((int32_t)x) >> 16) + (((int32_t)y) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned saturating addition. + \details This function enables you to perform two unsigned 16-bit integer additions, saturating + the results to the 16-bit unsigned integer range 0 < x < 2^16 - 1. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the saturated addition of the low halfwords, in the low halfword of the return value.\n + the saturated addition of the high halfwords, in the high halfword of the return value.\n + The results are saturated to the 16-bit unsigned integer range 0 < x < 2^16 - 1. + \remark + res[15:0] = val1[15:0] + val2[15:0] \n + res[31:16] = val1[31:16] + val2[31:16] + */ +__ALWAYS_STATIC_INLINE uint32_t __UQADD16(uint32_t x, uint32_t y) +{ + int32_t r = 0, s = 0; + + r = __IUSAT((((x << 16) >> 16) + ((y << 16) >> 16)), 16) & 0x0000FFFF; + s = __IUSAT((((x) >> 16) + ((y) >> 16)), 16) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit signed addition. + \details This function enables you to perform two 16-bit signed integer additions. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the addition of the low halfwords in the low halfword of the return value.\n + the addition of the high halfwords in the high halfword of the return value. + \remark + res[15:0] = val1[15:0] + val2[15:0] \n + res[31:16] = val1[31:16] + val2[31:16] + */ +__ALWAYS_STATIC_INLINE uint32_t __SADD16(uint32_t x, uint32_t y) +{ + int32_t r = 0, s = 0; + + r = ((((int32_t)x << 16) >> 16) + (((int32_t)y << 16) >> 16)) & (int32_t)0x0000FFFF; + s = ((((int32_t)x) >> 16) + (((int32_t)y) >> 16)) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned addition + \details This function enables you to perform two 16-bit unsigned integer additions. + \param [in] x first two 16-bit summands for each addition. + \param [in] y second two 16-bit summands for each addition. + \return the addition of the low halfwords in the low halfword of the return value.\n + the addition of the high halfwords in the high halfword of the return value. + \remark + res[15:0] = val1[15:0] + val2[15:0] \n + res[31:16] = val1[31:16] + val2[31:16] + */ +__ALWAYS_STATIC_INLINE uint32_t __UADD16(uint32_t x, uint32_t y) +{ + int32_t r = 0, s = 0; + + r = (((x << 16) >> 16) + ((y << 16) >> 16)) & 0x0000FFFF; + s = (((x) >> 16) + ((y) >> 16)) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + + +/** + \brief Dual 16-bit signed addition with halved results. + \details This function enables you to perform two signed 16-bit integer additions, halving the results. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the halved addition of the low halfwords, in the low halfword of the return value.\n + the halved addition of the high halfwords, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] + val2[15:0]) >> 1 \n + res[31:16] = (val1[31:16] + val2[31:16]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __SHADD16(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = (((((int32_t)x << 16) >> 16) + (((int32_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((int32_t)x) >> 16) + (((int32_t)y) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned addition with halved results. + \details This function enables you to perform two unsigned 16-bit integer additions, halving the results. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the halved addition of the low halfwords, in the low halfword of the return value.\n + the halved addition of the high halfwords, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] + val2[15:0]) >> 1 \n + res[31:16] = (val1[31:16] + val2[31:16]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __UHADD16(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = ((((x << 16) >> 16) + ((y << 16) >> 16)) >> 1) & 0x0000FFFF; + s = ((((x) >> 16) + ((y) >> 16)) >> 1) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Quad 8-bit signed addition with halved results. + \details This function enables you to perform four signed 8-bit integer additions, halving the results. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the halved addition of the first bytes from each operand, in the first byte of the return value.\n + the halved addition of the second bytes from each operand, in the second byte of the return value.\n + the halved addition of the third bytes from each operand, in the third byte of the return value.\n + the halved addition of the fourth bytes from each operand, in the fourth byte of the return value. + \remark + res[7:0] = (val1[7:0] + val2[7:0] ) >> 1 \n + res[15:8] = (val1[15:8] + val2[15:8] ) >> 1 \n + res[23:16] = (val1[23:16] + val2[23:16]) >> 1 \n + res[31:24] = (val1[31:24] + val2[31:24]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __SHADD8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = (((((int32_t)x << 24) >> 24) + (((int32_t)y << 24) >> 24)) >> 1) & (int32_t)0x000000FF; + s = (((((int32_t)x << 16) >> 24) + (((int32_t)y << 16) >> 24)) >> 1) & (int32_t)0x000000FF; + t = (((((int32_t)x << 8) >> 24) + (((int32_t)y << 8) >> 24)) >> 1) & (int32_t)0x000000FF; + u = (((((int32_t)x) >> 24) + (((int32_t)y) >> 24)) >> 1) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r))); +} + +/** + \brief Quad 8-bit unsigned addition with halved results. + \details This function enables you to perform four unsigned 8-bit integer additions, halving the results. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the halved addition of the first bytes from each operand, in the first byte of the return value.\n + the halved addition of the second bytes from each operand, in the second byte of the return value.\n + the halved addition of the third bytes from each operand, in the third byte of the return value.\n + the halved addition of the fourth bytes from each operand, in the fourth byte of the return value. + \remark + res[7:0] = (val1[7:0] + val2[7:0] ) >> 1 \n + res[15:8] = (val1[15:8] + val2[15:8] ) >> 1 \n + res[23:16] = (val1[23:16] + val2[23:16]) >> 1 \n + res[31:24] = (val1[31:24] + val2[31:24]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __UHADD8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = ((((x << 24) >> 24) + ((y << 24) >> 24)) >> 1) & 0x000000FF; + s = ((((x << 16) >> 24) + ((y << 16) >> 24)) >> 1) & 0x000000FF; + t = ((((x << 8) >> 24) + ((y << 8) >> 24)) >> 1) & 0x000000FF; + u = ((((x) >> 24) + ((y) >> 24)) >> 1) & 0x000000FF; + + return ((u << 24) | (t << 16) | (s << 8) | (r)); +} + +/** + \brief Dual 16-bit saturating subtract. + \details This function enables you to perform two 16-bit integer subtractions in parallel, + saturating the results to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the saturated subtraction of the low halfwords, in the low halfword of the return value.\n + the saturated subtraction of the high halfwords, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \remark + res[15:0] = val1[15:0] - val2[15:0] \n + res[31:16] = val1[31:16] - val2[31:16] + */ +__ALWAYS_STATIC_INLINE uint32_t __QSUB16(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = __SSAT(((((int32_t)x << 16) >> 16) - (((int32_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((int32_t)x) >> 16) - (((int32_t)y) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned saturating subtraction. + \details This function enables you to perform two unsigned 16-bit integer subtractions, + saturating the results to the 16-bit unsigned integer range 0 < x < 2^16 - 1. + \param [in] x first two 16-bit operands for each subtraction. + \param [in] y second two 16-bit operands for each subtraction. + \return the saturated subtraction of the low halfwords, in the low halfword of the return value.\n + the saturated subtraction of the high halfwords, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \remark + res[15:0] = val1[15:0] - val2[15:0] \n + res[31:16] = val1[31:16] - val2[31:16] + */ +__ALWAYS_STATIC_INLINE uint32_t __UQSUB16(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = __IUSAT((((x << 16) >> 16) - ((y << 16) >> 16)), 16) & 0x0000FFFF; + s = __IUSAT((((x) >> 16) - ((y) >> 16)), 16) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit signed subtraction. + \details This function enables you to perform two 16-bit signed integer subtractions. + \param [in] x first two 16-bit operands of each subtraction. + \param [in] y second two 16-bit operands of each subtraction. + \return the subtraction of the low halfword in the second operand from the low + halfword in the first operand, in the low halfword of the return value. \n + the subtraction of the high halfword in the second operand from the high + halfword in the first operand, in the high halfword of the return value. + \remark + res[15:0] = val1[15:0] - val2[15:0] \n + res[31:16] = val1[31:16] - val2[31:16] + */ +__ALWAYS_STATIC_INLINE uint32_t __SSUB16(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = ((((int32_t)x << 16) >> 16) - (((int32_t)y << 16) >> 16)) & (int32_t)0x0000FFFF; + s = ((((int32_t)x) >> 16) - (((int32_t)y) >> 16)) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned subtract. + \details This function enables you to perform two 16-bit unsigned integer subtractions. + \param [in] x first two 16-bit operands of each subtraction. + \param [in] y second two 16-bit operands of each subtraction. + \return the subtraction of the low halfword in the second operand from the low + halfword in the first operand, in the low halfword of the return value. \n + the subtraction of the high halfword in the second operand from the high + halfword in the first operand, in the high halfword of the return value. + \remark + res[15:0] = val1[15:0] - val2[15:0] \n + res[31:16] = val1[31:16] - val2[31:16] + */ +__ALWAYS_STATIC_INLINE uint32_t __USUB16(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = (((x << 16) >> 16) - ((y << 16) >> 16)) & 0x0000FFFF; + s = (((x) >> 16) - ((y) >> 16)) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit signed subtraction with halved results. + \details This function enables you to perform two signed 16-bit integer subtractions, halving the results. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the halved subtraction of the low halfwords, in the low halfword of the return value.\n + the halved subtraction of the high halfwords, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] - val2[15:0]) >> 1 \n + res[31:16] = (val1[31:16] - val2[31:16]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __SHSUB16(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = (((((int32_t)x << 16) >> 16) - (((int32_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((int32_t)x) >> 16) - (((int32_t)y) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned subtraction with halved results. + \details This function enables you to perform two unsigned 16-bit integer subtractions, halving the results. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the halved subtraction of the low halfwords, in the low halfword of the return value.\n + the halved subtraction of the high halfwords, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] - val2[15:0]) >> 1 \n + res[31:16] = (val1[31:16] - val2[31:16]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __UHSUB16(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = ((((x << 16) >> 16) - ((y << 16) >> 16)) >> 1) & 0x0000FFFF; + s = ((((x) >> 16) - ((y) >> 16)) >> 1) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Quad 8-bit signed addition with halved results. + \details This function enables you to perform four signed 8-bit integer subtractions, halving the results. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the halved subtraction of the first bytes from each operand, in the first byte of the return value.\n + the halved subtraction of the second bytes from each operand, in the second byte of the return value.\n + the halved subtraction of the third bytes from each operand, in the third byte of the return value.\n + the halved subtraction of the fourth bytes from each operand, in the fourth byte of the return value. + \remark + res[7:0] = (val1[7:0] - val2[7:0] ) >> 1 \n + res[15:8] = (val1[15:8] - val2[15:8] ) >> 1 \n + res[23:16] = (val1[23:16] - val2[23:16]) >> 1 \n + res[31:24] = (val1[31:24] - val2[31:24]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __SHSUB8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = (((((int32_t)x << 24) >> 24) - (((int32_t)y << 24) >> 24)) >> 1) & (int32_t)0x000000FF; + s = (((((int32_t)x << 16) >> 24) - (((int32_t)y << 16) >> 24)) >> 1) & (int32_t)0x000000FF; + t = (((((int32_t)x << 8) >> 24) - (((int32_t)y << 8) >> 24)) >> 1) & (int32_t)0x000000FF; + u = (((((int32_t)x) >> 24) - (((int32_t)y) >> 24)) >> 1) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r))); +} + +/** + \brief Quad 8-bit unsigned subtraction with halved results. + \details This function enables you to perform four unsigned 8-bit integer subtractions, halving the results. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the halved subtraction of the first bytes from each operand, in the first byte of the return value.\n + the halved subtraction of the second bytes from each operand, in the second byte of the return value.\n + the halved subtraction of the third bytes from each operand, in the third byte of the return value.\n + the halved subtraction of the fourth bytes from each operand, in the fourth byte of the return value. + \remark + res[7:0] = (val1[7:0] - val2[7:0] ) >> 1 \n + res[15:8] = (val1[15:8] - val2[15:8] ) >> 1 \n + res[23:16] = (val1[23:16] - val2[23:16]) >> 1 \n + res[31:24] = (val1[31:24] - val2[31:24]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __UHSUB8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = ((((x << 24) >> 24) - ((y << 24) >> 24)) >> 1) & 0x000000FF; + s = ((((x << 16) >> 24) - ((y << 16) >> 24)) >> 1) & 0x000000FF; + t = ((((x << 8) >> 24) - ((y << 8) >> 24)) >> 1) & 0x000000FF; + u = ((((x) >> 24) - ((y) >> 24)) >> 1) & 0x000000FF; + + return ((u << 24) | (t << 16) | (s << 8) | (r)); +} + +/** + \brief Dual 16-bit add and subtract with exchange. + \details This function enables you to exchange the halfwords of the one operand, + then add the high halfwords and subtract the low halfwords, + saturating the results to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \param [in] x first operand for the subtraction in the low halfword, + and the first operand for the addition in the high halfword. + \param [in] y second operand for the subtraction in the high halfword, + and the second operand for the addition in the low halfword. + \return the saturated subtraction of the high halfword in the second operand from the + low halfword in the first operand, in the low halfword of the return value.\n + the saturated addition of the high halfword in the first operand and the + low halfword in the second operand, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \remark + res[15:0] = val1[15:0] - val2[31:16] \n + res[31:16] = val1[31:16] + val2[15:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __QASX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = __SSAT(((((int32_t)x << 16) >> 16) - (((int32_t)y) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((int32_t)x) >> 16) + (((int32_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned saturating addition and subtraction with exchange. + \details This function enables you to exchange the halfwords of the second operand and + perform one unsigned 16-bit integer addition and one unsigned 16-bit subtraction, + saturating the results to the 16-bit unsigned integer range 0 <= x <= 2^16 - 1. + \param [in] x first operand for the subtraction in the low halfword, + and the first operand for the addition in the high halfword. + \param [in] y second operand for the subtraction in the high halfword, + and the second operand for the addition in the low halfword. + \return the saturated subtraction of the high halfword in the second operand from the + low halfword in the first operand, in the low halfword of the return value.\n + the saturated addition of the high halfword in the first operand and the + low halfword in the second operand, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit unsigned integer range 0 <= x <= 2^16 - 1. + \remark + res[15:0] = val1[15:0] - val2[31:16] \n + res[31:16] = val1[31:16] + val2[15:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __UQASX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = __IUSAT((((x << 16) >> 16) - ((y) >> 16)), 16) & 0x0000FFFF; + s = __IUSAT((((x) >> 16) + ((y << 16) >> 16)), 16) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit addition and subtraction with exchange. + \details It enables you to exchange the halfwords of the second operand, add the high halfwords + and subtract the low halfwords. + \param [in] x first operand for the subtraction in the low halfword, + and the first operand for the addition in the high halfword. + \param [in] y second operand for the subtraction in the high halfword, + and the second operand for the addition in the low halfword. + \return the subtraction of the high halfword in the second operand from the + low halfword in the first operand, in the low halfword of the return value.\n + the addition of the high halfword in the first operand and the + low halfword in the second operand, in the high halfword of the return value. + \remark + res[15:0] = val1[15:0] - val2[31:16] \n + res[31:16] = val1[31:16] + val2[15:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __SASX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = ((((int32_t)x << 16) >> 16) - (((int32_t)y) >> 16)) & (int32_t)0x0000FFFF; + s = ((((int32_t)x) >> 16) + (((int32_t)y << 16) >> 16)) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned addition and subtraction with exchange. + \details This function enables you to exchange the two halfwords of the second operand, + add the high halfwords and subtract the low halfwords. + \param [in] x first operand for the subtraction in the low halfword, + and the first operand for the addition in the high halfword. + \param [in] y second operand for the subtraction in the high halfword, + and the second operand for the addition in the low halfword. + \return the subtraction of the high halfword in the second operand from the + low halfword in the first operand, in the low halfword of the return value.\n + the addition of the high halfword in the first operand and the + low halfword in the second operand, in the high halfword of the return value. + \remark + res[15:0] = val1[15:0] - val2[31:16] \n + res[31:16] = val1[31:16] + val2[15:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __UASX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = (((x << 16) >> 16) - ((y) >> 16)) & 0x0000FFFF; + s = (((x) >> 16) + ((y << 16) >> 16)) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit signed addition and subtraction with halved results. + \details This function enables you to exchange the two halfwords of one operand, perform one + signed 16-bit integer addition and one signed 16-bit subtraction, and halve the results. + \param [in] x first 16-bit operands. + \param [in] y second 16-bit operands. + \return the halved subtraction of the high halfword in the second operand from the + low halfword in the first operand, in the low halfword of the return value.\n + the halved addition of the low halfword in the second operand from the high + halfword in the first operand, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] - val2[31:16]) >> 1 \n + res[31:16] = (val1[31:16] + val2[15:0]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __SHASX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = (((((int32_t)x << 16) >> 16) - (((int32_t)y) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((int32_t)x) >> 16) + (((int32_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned addition and subtraction with halved results and exchange. + \details This function enables you to exchange the halfwords of the second operand, + add the high halfwords and subtract the low halfwords, halving the results. + \param [in] x first operand for the subtraction in the low halfword, and + the first operand for the addition in the high halfword. + \param [in] y second operand for the subtraction in the high halfword, and + the second operand for the addition in the low halfword. + \return the halved subtraction of the high halfword in the second operand from the + low halfword in the first operand, in the low halfword of the return value.\n + the halved addition of the low halfword in the second operand from the high + halfword in the first operand, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] - val2[31:16]) >> 1 \n + res[31:16] = (val1[31:16] + val2[15:0]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __UHASX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = ((((x << 16) >> 16) - ((y) >> 16)) >> 1) & 0x0000FFFF; + s = ((((x) >> 16) + ((y << 16) >> 16)) >> 1) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit subtract and add with exchange. + \details This function enables you to exchange the halfwords of one operand, + then subtract the high halfwords and add the low halfwords, + saturating the results to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \param [in] x first operand for the addition in the low halfword, + and the first operand for the subtraction in the high halfword. + \param [in] y second operand for the addition in the high halfword, + and the second operand for the subtraction in the low halfword. + \return the saturated addition of the low halfword of the first operand and the high + halfword of the second operand, in the low halfword of the return value.\n + the saturated subtraction of the low halfword of the second operand from the + high halfword of the first operand, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \remark + res[15:0] = val1[15:0] + val2[31:16] \n + res[31:16] = val1[31:16] - val2[15:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __QSAX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = __SSAT(((((int32_t)x << 16) >> 16) + (((int32_t)y) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((int32_t)x) >> 16) - (((int32_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned saturating subtraction and addition with exchange. + \details This function enables you to exchange the halfwords of the second operand and perform + one unsigned 16-bit integer subtraction and one unsigned 16-bit addition, saturating + the results to the 16-bit unsigned integer range 0 <= x <= 2^16 - 1. + \param [in] x first operand for the addition in the low halfword, + and the first operand for the subtraction in the high halfword. + \param [in] y second operand for the addition in the high halfword, + and the second operand for the subtraction in the low halfword. + \return the saturated addition of the low halfword of the first operand and the high + halfword of the second operand, in the low halfword of the return value.\n + the saturated subtraction of the low halfword of the second operand from the + high halfword of the first operand, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit unsigned integer range 0 <= x <= 2^16 - 1. + \remark + res[15:0] = val1[15:0] + val2[31:16] \n + res[31:16] = val1[31:16] - val2[15:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __UQSAX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = __IUSAT((((x << 16) >> 16) + ((y) >> 16)), 16) & 0x0000FFFF; + s = __IUSAT((((x) >> 16) - ((y << 16) >> 16)), 16) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit unsigned subtract and add with exchange. + \details This function enables you to exchange the halfwords of the second operand, + subtract the high halfwords and add the low halfwords. + \param [in] x first operand for the addition in the low halfword, + and the first operand for the subtraction in the high halfword. + \param [in] y second operand for the addition in the high halfword, + and the second operand for the subtraction in the low halfword. + \return the addition of the low halfword of the first operand and the high + halfword of the second operand, in the low halfword of the return value.\n + the subtraction of the low halfword of the second operand from the + high halfword of the first operand, in the high halfword of the return value.\n + \remark + res[15:0] = val1[15:0] + val2[31:16] \n + res[31:16] = val1[31:16] - val2[15:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __USAX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = (((x << 16) >> 16) + ((y) >> 16)) & 0x0000FFFF; + s = (((x) >> 16) - ((y << 16) >> 16)) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit signed subtraction and addition with exchange. + \details This function enables you to exchange the two halfwords of one operand and perform one + 16-bit integer subtraction and one 16-bit addition. + \param [in] x first operand for the addition in the low halfword, and the first operand + for the subtraction in the high halfword. + \param [in] y second operand for the addition in the high halfword, and the second + operand for the subtraction in the low halfword. + \return the addition of the low halfword of the first operand and the high + halfword of the second operand, in the low halfword of the return value.\n + the subtraction of the low halfword of the second operand from the + high halfword of the first operand, in the high halfword of the return value.\n + \remark + res[15:0] = val1[15:0] + val2[31:16] \n + res[31:16] = val1[31:16] - val2[15:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __SSAX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = ((((int32_t)x << 16) >> 16) + (((int32_t)y) >> 16)) & (int32_t)0x0000FFFF; + s = ((((int32_t)x) >> 16) - (((int32_t)y << 16) >> 16)) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + + +/** + \brief Dual 16-bit signed subtraction and addition with halved results. + \details This function enables you to exchange the two halfwords of one operand, perform one signed + 16-bit integer subtraction and one signed 16-bit addition, and halve the results. + \param [in] x first 16-bit operands. + \param [in] y second 16-bit operands. + \return the halved addition of the low halfword in the first operand and the + high halfword in the second operand, in the low halfword of the return value.\n + the halved subtraction of the low halfword in the second operand from the + high halfword in the first operand, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] + val2[31:16]) >> 1 \n + res[31:16] = (val1[31:16] - val2[15:0]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __SHSAX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = (((((int32_t)x << 16) >> 16) + (((int32_t)y) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((int32_t)x) >> 16) - (((int32_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned subtraction and addition with halved results and exchange. + \details This function enables you to exchange the halfwords of the second operand, + subtract the high halfwords and add the low halfwords, halving the results. + \param [in] x first operand for the addition in the low halfword, and + the first operand for the subtraction in the high halfword. + \param [in] y second operand for the addition in the high halfword, and + the second operand for the subtraction in the low halfword. + \return the halved addition of the low halfword in the first operand and the + high halfword in the second operand, in the low halfword of the return value.\n + the halved subtraction of the low halfword in the second operand from the + high halfword in the first operand, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] + val2[31:16]) >> 1 \n + res[31:16] = (val1[31:16] - val2[15:0]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __UHSAX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = ((((x << 16) >> 16) + ((y) >> 16)) >> 1) & 0x0000FFFF; + s = ((((x) >> 16) - ((y << 16) >> 16)) >> 1) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit signed multiply with exchange returning difference. + \details This function enables you to perform two 16-bit signed multiplications, subtracting + one of the products from the other. The halfwords of the second operand are exchanged + before performing the arithmetic. This produces top * bottom and bottom * top multiplication. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \return the difference of the products of the two 16-bit signed multiplications. + \remark + p1 = val1[15:0] * val2[31:16] \n + p2 = val1[31:16] * val2[15:0] \n + res[31:0] = p1 - p2 + */ +__ALWAYS_STATIC_INLINE uint32_t __SMUSDX(uint32_t x, uint32_t y) +{ + return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) - + ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)))); +} + +/** + \brief Sum of dual 16-bit signed multiply with exchange. + \details This function enables you to perform two 16-bit signed multiplications with exchanged + halfwords of the second operand, adding the products together. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \return the sum of the products of the two 16-bit signed multiplications with exchanged halfwords of the second operand. + \remark + p1 = val1[15:0] * val2[31:16] \n + p2 = val1[31:16] * val2[15:0] \n + res[31:0] = p1 + p2 + */ +__ALWAYS_STATIC_INLINE uint32_t __SMUADX(uint32_t x, uint32_t y) +{ + return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) + + ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)))); +} + + +/** + \brief Saturating add. + \details This function enables you to obtain the saturating add of two integers. + \param [in] x first summand of the saturating add operation. + \param [in] y second summand of the saturating add operation. + \return the saturating addition of val1 and val2. + \remark + res[31:0] = SAT(val1 + SAT(val2)) + */ +__ALWAYS_STATIC_INLINE int32_t __QADD(int32_t x, int32_t y) +{ + int32_t result; + + if (y >= 0) { + if ((int32_t)((uint32_t)x + (uint32_t)y) >= x) { + result = x + y; + } else { + result = 0x7FFFFFFF; + } + } else { + if ((int32_t)((uint32_t)x + (uint32_t)y) < x) { + result = x + y; + } else { + result = 0x80000000; + } + } + + return result; +} + +/** + \brief Saturating subtract. + \details This function enables you to obtain the saturating add of two integers. + \param [in] x first summand of the saturating add operation. + \param [in] y second summand of the saturating add operation. + \return the saturating addition of val1 and val2. + \remark + res[31:0] = SAT(val1 - SAT(val2)) + */ +__ALWAYS_STATIC_INLINE int32_t __QSUB(int32_t x, int32_t y) +{ + long tmp; + int32_t result; + + tmp = (long)x - (long)y; + + if (tmp > 0x7fffffff) { + tmp = 0x7fffffff; + } else if (tmp < (-2147483647 - 1)) { + tmp = -2147483647 - 1; + } + + result = tmp; + return result; +} + +/** + \brief Dual 16-bit signed multiply with single 32-bit accumulator. + \details This function enables you to perform two signed 16-bit multiplications, + adding both results to a 32-bit accumulate operand. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the product of each multiplication added to the accumulate value, as a 32-bit integer. + \remark + p1 = val1[15:0] * val2[15:0] \n + p2 = val1[31:16] * val2[31:16] \n + res[31:0] = p1 + p2 + val3[31:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __SMLAD(uint32_t x, uint32_t y, uint32_t sum) +{ + return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) + + ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)) + + (((int32_t)sum)))); +} + +/** + \brief Pre-exchanged dual 16-bit signed multiply with single 32-bit accumulator. + \details This function enables you to perform two signed 16-bit multiplications with exchanged + halfwords of the second operand, adding both results to a 32-bit accumulate operand. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the product of each multiplication with exchanged halfwords of the second + operand added to the accumulate value, as a 32-bit integer. + \remark + p1 = val1[15:0] * val2[31:16] \n + p2 = val1[31:16] * val2[15:0] \n + res[31:0] = p1 + p2 + val3[31:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __SMLADX(uint32_t x, uint32_t y, uint32_t sum) +{ + return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) + + ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)) + + (((int32_t)sum)))); +} + +/** + \brief Dual 16-bit signed multiply with exchange subtract with 32-bit accumulate. + \details This function enables you to perform two 16-bit signed multiplications, take the + difference of the products, subtracting the high halfword product from the low + halfword product, and add the difference to a 32-bit accumulate operand. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the difference of the product of each multiplication, added to the accumulate value. + \remark + p1 = val1[15:0] * val2[15:0] \n + p2 = val1[31:16] * val2[31:16] \n + res[31:0] = p1 - p2 + val3[31:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __SMLSD(uint32_t x, uint32_t y, uint32_t sum) +{ + return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) - + ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)) + + (((int32_t)sum)))); +} + +/** + \brief Dual 16-bit signed multiply with exchange subtract with 32-bit accumulate. + \details This function enables you to exchange the halfwords in the second operand, then perform two 16-bit + signed multiplications. The difference of the products is added to a 32-bit accumulate operand. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the difference of the product of each multiplication, added to the accumulate value. + \remark + p1 = val1[15:0] * val2[31:16] \n + p2 = val1[31:16] * val2[15:0] \n + res[31:0] = p1 - p2 + val3[31:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __SMLSDX(uint32_t x, uint32_t y, uint32_t sum) +{ + return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) - + ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)) + + (((int32_t)sum)))); +} + +/** + \brief Dual 16-bit signed multiply with single 64-bit accumulator. + \details This function enables you to perform two signed 16-bit multiplications, adding both results + to a 64-bit accumulate operand. Overflow is only possible as a result of the 64-bit addition. + This overflow is not detected if it occurs. Instead, the result wraps around modulo2^64. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the product of each multiplication added to the accumulate value. + \remark + p1 = val1[15:0] * val2[15:0] \n + p2 = val1[31:16] * val2[31:16] \n + sum = p1 + p2 + val3[63:32][31:0] \n + res[63:32] = sum[63:32] \n + res[31:0] = sum[31:0] + */ +__ALWAYS_STATIC_INLINE unsigned long __SMLALD(uint32_t x, uint32_t y, unsigned long sum) +{ + return ((unsigned long)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) + + ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)) + + (((unsigned long)sum)))); +} + +/** + \brief Dual 16-bit signed multiply with exchange with single 64-bit accumulator. + \details This function enables you to exchange the halfwords of the second operand, and perform two + signed 16-bit multiplications, adding both results to a 64-bit accumulate operand. Overflow + is only possible as a result of the 64-bit addition. This overflow is not detected if it occurs. + Instead, the result wraps around modulo2^64. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the product of each multiplication added to the accumulate value. + \remark + p1 = val1[15:0] * val2[31:16] \n + p2 = val1[31:16] * val2[15:0] \n + sum = p1 + p2 + val3[63:32][31:0] \n + res[63:32] = sum[63:32] \n + res[31:0] = sum[31:0] + */ +__ALWAYS_STATIC_INLINE unsigned long __SMLALDX(uint32_t x, uint32_t y, unsigned long sum) +{ + return ((unsigned long)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) + + ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)) + + (((unsigned long)sum)))); +} + +/** + \brief dual 16-bit signed multiply subtract with 64-bit accumulate. + \details This function It enables you to perform two 16-bit signed multiplications, take the difference + of the products, subtracting the high halfword product from the low halfword product, and add the + difference to a 64-bit accumulate operand. Overflow cannot occur during the multiplications or the + subtraction. Overflow can occur as a result of the 64-bit addition, and this overflow is not + detected. Instead, the result wraps round to modulo2^64. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the difference of the product of each multiplication, added to the accumulate value. + \remark + p1 = val1[15:0] * val2[15:0] \n + p2 = val1[31:16] * val2[31:16] \n + res[63:32][31:0] = p1 - p2 + val3[63:32][31:0] + */ +__ALWAYS_STATIC_INLINE unsigned long __SMLSLD(uint32_t x, uint32_t y, unsigned long sum) +{ + return ((unsigned long)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) - + ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)) + + (((unsigned long)sum)))); +} + +/** + \brief Dual 16-bit signed multiply with exchange subtract with 64-bit accumulate. + \details This function enables you to exchange the halfwords of the second operand, perform two 16-bit multiplications, + adding the difference of the products to a 64-bit accumulate operand. Overflow cannot occur during the + multiplications or the subtraction. Overflow can occur as a result of the 64-bit addition, and this overflow + is not detected. Instead, the result wraps round to modulo2^64. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the difference of the product of each multiplication, added to the accumulate value. + \remark + p1 = val1[15:0] * val2[31:16] \n + p2 = val1[31:16] * val2[15:0] \n + res[63:32][31:0] = p1 - p2 + val3[63:32][31:0] + */ +__ALWAYS_STATIC_INLINE unsigned long __SMLSLDX(uint32_t x, uint32_t y, unsigned long sum) +{ + return ((unsigned long)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) - + ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)) + + (((unsigned long)sum)))); +} + +/** + \brief 32-bit signed multiply with 32-bit truncated accumulator. + \details This function enables you to perform a signed 32-bit multiplications, adding the most + significant 32 bits of the 64-bit result to a 32-bit accumulate operand. + \param [in] x first operand for multiplication. + \param [in] y second operand for multiplication. + \param [in] sum accumulate value. + \return the product of multiplication (most significant 32 bits) is added to the accumulate value, as a 32-bit integer. + \remark + p = val1 * val2 \n + res[31:0] = p[63:32] + val3[31:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __SMMLA(int32_t x, int32_t y, int32_t sum) +{ + return (uint32_t)((int32_t)((long)((long)x * (long)y) >> 32) + sum); +} + +/** + \brief Sum of dual 16-bit signed multiply. + \details This function enables you to perform two 16-bit signed multiplications, adding the products together. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \return the sum of the products of the two 16-bit signed multiplications. + \remark + p1 = val1[15:0] * val2[15:0] \n + p2 = val1[31:16] * val2[31:16] \n + res[31:0] = p1 + p2 + */ +__ALWAYS_STATIC_INLINE uint32_t __SMUAD(uint32_t x, uint32_t y) +{ + return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) + + ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)))); +} + +/** + \brief Dual 16-bit signed multiply returning difference. + \details This function enables you to perform two 16-bit signed multiplications, taking the difference + of the products by subtracting the high halfword product from the low halfword product. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \return the difference of the products of the two 16-bit signed multiplications. + \remark + p1 = val1[15:0] * val2[15:0] \n + p2 = val1[31:16] * val2[31:16] \n + res[31:0] = p1 - p2 + */ +__ALWAYS_STATIC_INLINE uint32_t __SMUSD(uint32_t x, uint32_t y) +{ + return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) - + ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)))); +} + +/** + \brief Dual extracted 8-bit to 16-bit signed addition. + \details This function enables you to extract two 8-bit values from the second operand (at bit positions + [7:0] and [23:16]), sign-extend them to 16-bits each, and add the results to the first operand. + \param [in] x values added to the sign-extended to 16-bit values. + \param [in] y two 8-bit values to be extracted and sign-extended. + \return the addition of val1 and val2, where the 8-bit values in val2[7:0] and + val2[23:16] have been extracted and sign-extended prior to the addition. + \remark + res[15:0] = val1[15:0] + SignExtended(val2[7:0]) \n + res[31:16] = val1[31:16] + SignExtended(val2[23:16]) + */ +__ALWAYS_STATIC_INLINE uint32_t __SXTAB16(uint32_t x, uint32_t y) +{ + return ((uint32_t)((((((int32_t)y << 24) >> 24) + (((int32_t)x << 16) >> 16)) & (int32_t)0x0000FFFF) | + (((((int32_t)y << 8) >> 8) + (((int32_t)x >> 16) << 16)) & (int32_t)0xFFFF0000))); +} + +/** + \brief Extracted 16-bit to 32-bit unsigned addition. + \details This function enables you to extract two 8-bit values from one operand, zero-extend + them to 16 bits each, and add the results to two 16-bit values from another operand. + \param [in] x values added to the zero-extended to 16-bit values. + \param [in] y two 8-bit values to be extracted and zero-extended. + \return the addition of val1 and val2, where the 8-bit values in val2[7:0] and + val2[23:16] have been extracted and zero-extended prior to the addition. + \remark + res[15:0] = ZeroExt(val2[7:0] to 16 bits) + val1[15:0] \n + res[31:16] = ZeroExt(val2[31:16] to 16 bits) + val1[31:16] + */ +__ALWAYS_STATIC_INLINE uint32_t __UXTAB16(uint32_t x, uint32_t y) +{ + return ((uint32_t)(((((y << 24) >> 24) + ((x << 16) >> 16)) & 0x0000FFFF) | + ((((y << 8) >> 8) + ((x >> 16) << 16)) & 0xFFFF0000))); +} + +/** + \brief Dual extract 8-bits and sign extend each to 16-bits. + \details This function enables you to extract two 8-bit values from an operand and sign-extend them to 16 bits each. + \param [in] x two 8-bit values in val[7:0] and val[23:16] to be sign-extended. + \return the 8-bit values sign-extended to 16-bit values.\n + sign-extended value of val[7:0] in the low halfword of the return value.\n + sign-extended value of val[23:16] in the high halfword of the return value. + \remark + res[15:0] = SignExtended(val[7:0]) \n + res[31:16] = SignExtended(val[23:16]) + */ +__ALWAYS_STATIC_INLINE uint32_t __SXTB16(uint32_t x) +{ + return ((uint32_t)(((((int32_t)x << 24) >> 24) & (int32_t)0x0000FFFF) | + ((((int32_t)x << 8) >> 8) & (int32_t)0xFFFF0000))); +} + +/** + \brief Dual extract 8-bits and zero-extend to 16-bits. + \details This function enables you to extract two 8-bit values from an operand and zero-extend them to 16 bits each. + \param [in] x two 8-bit values in val[7:0] and val[23:16] to be zero-extended. + \return the 8-bit values sign-extended to 16-bit values.\n + sign-extended value of val[7:0] in the low halfword of the return value.\n + sign-extended value of val[23:16] in the high halfword of the return value. + \remark + res[15:0] = SignExtended(val[7:0]) \n + res[31:16] = SignExtended(val[23:16]) + */ +__ALWAYS_STATIC_INLINE uint32_t __UXTB16(uint32_t x) +{ + return ((uint32_t)((((x << 24) >> 24) & 0x0000FFFF) | + (((x << 8) >> 8) & 0xFFFF0000))); +} +#endif + +#endif /* _CSI_RV32_GCC_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/core/csi_rv_common.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/core/csi_rv_common.h new file mode 100644 index 00000000..4a57b718 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/core/csi_rv_common.h @@ -0,0 +1,126 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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. + */ + +#ifndef __CSI_RV_COMMON_H__ +#define __CSI_RV_COMMON_H__ + +#include +#include + +#ifndef __ASM +#define __ASM __asm /*!< asm keyword for GNU Compiler */ +#endif + +#ifndef __INLINE +#define __INLINE inline /*!< inline keyword for GNU Compiler */ +#endif + +#ifndef __ALWAYS_STATIC_INLINE +#define __ALWAYS_STATIC_INLINE __attribute__((always_inline)) static inline +#endif + +#ifndef __STATIC_INLINE +#define __STATIC_INLINE static inline +#endif + +#ifndef __NO_RETURN +#define __NO_RETURN __attribute__((__noreturn__)) +#endif + +#ifndef __USED +#define __USED __attribute__((used)) +#endif + +#ifndef __WEAK +#define __WEAK __attribute__((weak)) +#endif + +#ifndef __PACKED +#define __PACKED __attribute__((packed, aligned(1))) +#endif + +#ifndef __PACKED_STRUCT +#define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif + +#ifndef __PACKED_UNION +#define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif + +#ifdef __ASSEMBLY__ +#define __ASM_STR(x) x +#else +#define __ASM_STR(x) #x +#endif + +#ifndef __ASSEMBLY__ +#define rv_csr_read(csr) \ + ({ \ + register unsigned long __v; \ + __asm__ __volatile__("csrr %0, " __ASM_STR(csr) \ + : "=r"(__v) \ + : \ + : "memory"); \ + __v; \ + }) + +#define rv_csr_write(csr, val) \ + ({ \ + unsigned long __v = (unsigned long)(val); \ + __asm__ __volatile__("csrw " __ASM_STR(csr) ", %0" \ + : \ + : "rK"(__v) \ + : "memory"); \ + }) + +#define rv_csr_read_set(csr, val) \ + ({ \ + unsigned long __v = (unsigned long)(val); \ + __asm__ __volatile__("csrrs %0, " __ASM_STR(csr) ", %1" \ + : "=r"(__v) : "rK"(__v) \ + : "memory"); \ + __v; \ + }) + +#define rv_csr_set(csr, val) \ + ({ \ + unsigned long __v = (unsigned long)(val); \ + __asm__ __volatile__("csrs " __ASM_STR(csr) ", %0" \ + : : "rK"(__v) \ + : "memory"); \ + }) + +#define rv_csr_read_clear(csr, val) \ + ({ \ + unsigned long __v = (unsigned long)(val); \ + __asm__ __volatile__("csrrc %0, " __ASM_STR(csr) ", %1" \ + : "=r"(__v) : "rK"(__v) \ + : "memory"); \ + __v; \ + }) + +#define rv_csr_clear(csr, val) \ + ({ \ + unsigned long __v = (unsigned long)(val); \ + __asm__ __volatile__("csrc " __ASM_STR(csr) ", %0" \ + : : "rK"(__v) \ + : "memory"); \ + }) +#endif + +#endif /* __CSI_RV_COMMON_H__ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/core/csi_rv_encoding.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/core/csi_rv_encoding.h new file mode 100644 index 00000000..82df61a9 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/core/csi_rv_encoding.h @@ -0,0 +1,716 @@ +/* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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. + */ + +#ifndef __CSI_RV_ENCODING_H__ +#define __CSI_RV_ENCODING_H__ + +/* ===== User-level CSRs ===== */ + +/* User Trap Setup (N-extension) */ +#define CSR_USTATUS 0x000 +#define CSR_UIE 0x004 +#define CSR_UTVEC 0x005 + +/* User Trap Handling (N-extension) */ +#define CSR_USCRATCH 0x040 +#define CSR_UEPC 0x041 +#define CSR_UCAUSE 0x042 +#define CSR_UTVAL 0x043 +#define CSR_UIP 0x044 + +/* User Floating-point CSRs */ +#define CSR_FFLAGS 0x001 +#define CSR_FRM 0x002 +#define CSR_FCSR 0x003 + +/* User Vector CSRs */ +#define CSR_VSTART 0x008 +#define CSR_VXSAT 0x009 +#define CSR_VXRM 0x00A +#define CSR_VCSR 0x00F +#define CSR_VL 0xC20 +#define CSR_VTYPE 0xC21 +#define CSR_VLENB 0xC22 + +/* User Counters/Timers */ +#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_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 + +/* ===== Supervisor-level CSRs ===== */ + +/* Supervisor Trap Setup */ +#define CSR_SSTATUS 0x100 +#define CSR_SIE 0x104 +#define CSR_STVEC 0x105 +#define CSR_SCOUNTEREN 0x106 + +/* Supervisor Counter Overflow CSR */ +#define CSR_SCOUNTOVF 0xda0 + +/* Supervisor Configuration */ +#define CSR_SENVCFG 0x10a + +/* Supervisor Trap Handling */ +#define CSR_SSCRATCH 0x140 +#define CSR_SEPC 0x141 +#define CSR_SCAUSE 0x142 +#define CSR_STVAL 0x143 +#define CSR_SIP 0x144 + +/* Supervisor CLIC CSRs */ +#define CSR_STVT 0x107 +#define CSR_SNXTI 0x145 +#define CSR_SINTSTATUS 0xDB1 +#define CSR_SINTTHRESH 0x147 +#define CSR_SSCRATCHCSW 0x148 +#define CSR_SSCRATCHCSWL 0x149 + +/* Sstc extension */ +#define CSR_STIMECMP 0x14D +#define CSR_STIMECMPH 0x15D + +/* Supervisor Protection and Translation */ +#define CSR_SATP 0x180 + +/* Supervisor Debug/Trace */ +#define CSR_SCONTEXT 0x5a8 + +/* Supervisor-Level Window to Indirectly Accessed Registers (AIA) */ +#define CSR_SISELECT 0x150 +#define CSR_SIREG 0x151 +#define CSR_SIREG2 0x152 +#define CSR_SIREG3 0x153 +#define CSR_SIREG4 0x155 +#define CSR_SIREG5 0x156 +#define CSR_SIREG6 0x157 + +/* Supervisor-Level Interrupts (AIA) */ +#define CSR_STOPEI 0x15c +#define CSR_STOPI 0xdb0 + +/* Supervisor-Level High-Half CSRs (AIA) */ +#define CSR_SIEH 0x114 +#define CSR_SIPH 0x154 + +/* Supervisor stateen CSRs */ +#define CSR_SSTATEEN0 0x10C +#define CSR_SSTATEEN1 0x10D +#define CSR_SSTATEEN2 0x10E +#define CSR_SSTATEEN3 0x10F + +/* ===== Hypervisor-level CSRs ===== */ + +/* Hypervisor Trap Setup (H-extension) */ +#define CSR_HSTATUS 0x600 +#define CSR_HEDELEG 0x602 +#define CSR_HIDELEG 0x603 +#define CSR_HIE 0x604 +#define CSR_HCOUNTEREN 0x606 +#define CSR_HGEIE 0x607 + +/* Hypervisor Configuration */ +#define CSR_HENVCFG 0x60a +#define CSR_HENVCFGH 0x61a + +/* Hypervisor Trap Handling (H-extension) */ +#define CSR_HTVAL 0x643 +#define CSR_HIP 0x644 +#define CSR_HVIP 0x645 +#define CSR_HTINST 0x64a +#define CSR_HGEIP 0xe12 + +/* Hypervisor Protection and Translation (H-extension) */ +#define CSR_HGATP 0x680 + +/* Hypervisor Counter/Timer Virtualization Registers (H-extension) */ +#define CSR_HTIMEDELTA 0x605 +#define CSR_HTIMEDELTAH 0x615 + +/* Virtual Supervisor Registers (H-extension) */ +#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_VSATP 0x280 + +/* Virtual Interrupts and Interrupt Priorities (H-extension with AIA) */ +#define CSR_HVIEN 0x608 +#define CSR_HVICTL 0x609 +#define CSR_HVIPRIO1 0x646 +#define CSR_HVIPRIO2 0x647 + +/* VS-Level Window to Indirectly Accessed Registers (H-extension with AIA) */ +#define CSR_VSISELECT 0x250 +#define CSR_VSIREG 0x251 + +/* VS-Level Interrupts (H-extension with AIA) */ +#define CSR_VSTOPEI 0x25c +#define CSR_VSTOPI 0xeb0 + +/* Hypervisor and VS-Level High-Half CSRs (H-extension with AIA) */ +#define CSR_HIDELEGH 0x613 +#define CSR_HVIENH 0x618 +#define CSR_HVIPH 0x655 +#define CSR_HVIPRIO1H 0x656 +#define CSR_HVIPRIO2H 0x657 +#define CSR_VSIEH 0x214 +#define CSR_VSIPH 0x254 + +/* Hypervisor stateen CSRs */ +#define CSR_HSTATEEN0 0x60C +#define CSR_HSTATEEN0H 0x61C +#define CSR_HSTATEEN1 0x60D +#define CSR_HSTATEEN1H 0x61D +#define CSR_HSTATEEN2 0x60E +#define CSR_HSTATEEN2H 0x61E +#define CSR_HSTATEEN3 0x60F +#define CSR_HSTATEEN3H 0x61F + +/* ===== Machine-level CSRs ===== */ + +/* Machine Information Registers */ +#define CSR_MVENDORID 0xf11 +#define CSR_MARCHID 0xf12 +#define CSR_MIMPID 0xf13 +#define CSR_MHARTID 0xf14 +#define CSR_MCONFIGPTR 0xf15 + +/* Machine Trap Setup */ +#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_MSTATUSH 0x310 + +/* Machine Configuration */ +#define CSR_MENVCFG 0x30a +#define CSR_MENVCFGH 0x31a + +/* Machine Trap Handling */ +#define CSR_MSCRATCH 0x340 +#define CSR_MEPC 0x341 +#define CSR_MCAUSE 0x342 +#define CSR_MTVAL 0x343 +#define CSR_MIP 0x344 +#define CSR_MTINST 0x34a +#define CSR_MTVAL2 0x34b + +/* Machine CLIC CSRs */ +#define CSR_MTVT 0x307 +#define CSR_MNXTI 0x345 +#define CSR_MINTSTATUS 0xFB1 +#define CSR_MINTTHRESH 0x347 +#define CSR_MSCRATCHCSW 0x348 +#define CSR_MSCRATCHCSWL 0x349 + +/* Machine Memory Protection */ +#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 + +/* Machine Counters/Timers */ +#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_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 + +/* Machine Counter Setup */ +#define CSR_MCOUNTINHIBIT 0x320 +#define CSR_MCYCLECFG 0x321 +#define CSR_MINSTRETCFG 0x322 +#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 + +/* For RV32 */ +#define CSR_MCYCLECFGH 0x721 +#define CSR_MINSTRETCFGH 0x722 +#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 + +/* Machine Security Configuration CSR (mseccfg) */ +#define CSR_MSECCFG 0x747 +#define CSR_MSECCFGH 0x757 + +/* Debug/Trace Registers */ +#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 + +/* Debug Mode Registers */ +#define CSR_DCSR 0x7b0 +#define CSR_DPC 0x7b1 +#define CSR_DSCRATCH0 0x7b2 +#define CSR_DSCRATCH1 0x7b3 + +/* Machine-Level Window to Indirectly Accessed Registers */ +#define CSR_MISELECT 0x350 +#define CSR_MIREG 0x351 +#define CSR_MIREG2 0x352 +#define CSR_MIREG3 0x353 +#define CSR_MIREG4 0x355 +#define CSR_MIREG5 0x356 +#define CSR_MIREG6 0x357 + +/* Machine-Level Interrupts (AIA) */ +#define CSR_MTOPEI 0x35c +#define CSR_MTOPI 0xfb0 + +/* Virtual Interrupts for Supervisor Level (AIA) */ +#define CSR_MVIEN 0x308 +#define CSR_MVIP 0x309 + +/* Smstateen extension registers */ +/* Machine stateen CSRs */ +#define CSR_MSTATEEN0 0x30C +#define CSR_MSTATEEN0H 0x31C +#define CSR_MSTATEEN1 0x30D +#define CSR_MSTATEEN1H 0x31D +#define CSR_MSTATEEN2 0x30E +#define CSR_MSTATEEN2H 0x31E +#define CSR_MSTATEEN3 0x30F +#define CSR_MSTATEEN3H 0x31F + +/* Machine-Level High-Half CSRs (AIA) */ +#define CSR_MIDELEGH 0x313 +#define CSR_MIEH 0x314 +#define CSR_MVIENH 0x318 +#define CSR_MVIPH 0x319 +#define CSR_MIPH 0x354 + +/* XuanTie custom */ +/* Machine-Level XuanTie custom CSRs */ +#define CSR_MXSTATUS 0x7c0 +#define CSR_MHCR 0x7c1 +#define CSR_MCOR 0x7c2 +#define CSR_MCCR2 0x7c3 +#define CSR_MCER2 0x7c4 +#define CSR_MHINT 0x7c5 +#define CSR_MRMR 0x7c6 +#define CSR_MRVBR 0x7c7 +#define CSR_MCER 0x7c8 +#define CSR_MCOUNTERWEN 0x7c9 +#define CSR_MHINT2 0x7cc +#define CSR_MHINT3 0x7cd +#define CSR_MHINT4 0x7ce +#define CSR_MHPMEVENT0 0x7e0 +#define CSR_MHPMEVENT2 0x7e1 +#define CSR_MHPMCR 0x7f0 +#define CSR_MHPMSR 0x7f1 +#define CSR_MHPMER 0x7f2 +#define CSR_MSMPR 0x7f3 +#define CSR_MZONEID 0x7f5 +#define CSR_MLLCPID 0x7f6 +#define CSR_MLLWP 0x7f7 + +#define CSR_MCINS 0x7d2 +#define CSR_MCINDEX 0x7d3 +#define CSR_MCDATA0 0x7d4 +#define CSR_MCDATA1 0x7d5 +#define CSR_MEICR 0x7d6 +#define CSR_MEICR2 0x7d7 +#define CSR_MBEADDR 0x7d8 + +#define CSR_MCPUID 0xfc0 +#define CSR_MAPBADDR 0xfc1 + +#define CSR_MHALTCAUSE 0xfe0 +#define CSR_MDBGINFO 0xfe1 +#define CSR_MPCFIFO 0xfe2 +#define CSR_MDBGINFO2 0xfe3 + +#define CSR_MNASTATUS 0x8000000000000210 + +#define CSR_MRPLCNTLST 0xbd8 +#define CSR_MCACHELOCK 0xbd9 +#define CSR_MCACHERPLPRI0 0xbda +#define CSR_MCACHERPLPRI1 0xbdb +#define CSR_MCACHERPLPRI2 0xbdc +#define CSR_MCACHERPLPRI3 0xbdd +#define CSR_MCACHERPLPRI4 0xbde +#define CSR_MCACHERPLPRI5 0xbdf + +/* Supervisor-Level XuanTie custom CSRs */ +#define CSR_SXSTATUS 0x5c0 +#define CSR_SHCR 0x5c1 +#define CSR_SCER2 0x5c2 +#define CSR_SCER 0x5c3 +#define CSR_SHINT 0x5c6 +#define CSR_SHINT2 0x5c7 +#define CSR_SHPMINHIBIT 0x5c8 +#define CSR_SHPMCR 0x5c9 +#define CSR_SHPMSR 0x5ca +#define CSR_SHPMER 0x5cb +#define CSR_SL2PID 0x5cc +#define CSR_SL2WP 0x5cd +#define CSR_SBEADDR 0x5d0 +#define CSR_SSBEPA 0x5d1 +#define CSR_SSBEPA2 0x5d2 +#define CSR_SCYCLE 0x5e0 +#define CSR_SINSTRET 0x5e2 +#define CSR_SHPMCOUNTER3 0x5e3 +#define CSR_SHPMCOUNTER4 0x5e4 +#define CSR_SHPMCOUNTER5 0x5e5 +#define CSR_SHPMCOUNTER6 0x5e6 +#define CSR_SHPMCOUNTER7 0x5e7 +#define CSR_SHPMCOUNTER8 0x5e8 +#define CSR_SHPMCOUNTER9 0x5e9 +#define CSR_SHPMCOUNTER10 0x5ea +#define CSR_SHPMCOUNTER11 0x5eb +#define CSR_SHPMCOUNTER12 0x5ec +#define CSR_SHPMCOUNTER13 0x5ed +#define CSR_SHPMCOUNTER14 0x5ee +#define CSR_SHPMCOUNTER15 0x5ef +#define CSR_SHPMCOUNTER16 0x5f0 +#define CSR_SHPMCOUNTER17 0x5f1 +#define CSR_SHPMCOUNTER18 0x5f2 +#define CSR_SHPMCOUNTER19 0x5f3 +#define CSR_SHPMCOUNTER20 0x5f4 +#define CSR_SHPMCOUNTER21 0x5f5 +#define CSR_SHPMCOUNTER22 0x5f6 +#define CSR_SHPMCOUNTER23 0x5f7 +#define CSR_SHPMCOUNTER24 0x5f8 +#define CSR_SHPMCOUNTER25 0x5f9 +#define CSR_SHPMCOUNTER26 0x5fa +#define CSR_SHPMCOUNTER27 0x5fb +#define CSR_SHPMCOUNTER28 0x5fc +#define CSR_SHPMCOUNTER29 0x5fd +#define CSR_SHPMCOUNTER30 0x5fe +#define CSR_SHPMCOUNTER31 0x5ff +#define CSR_SCYCLEH 0x9e0 +#define CSR_SINSTRETH 0x9e2 +#define CSR_SHPMCOUNTER3H 0x9e3 +#define CSR_SHPMCOUNTER4H 0x9e4 +#define CSR_SHPMCOUNTER5H 0x9e5 +#define CSR_SHPMCOUNTER6H 0x9e6 +#define CSR_SHPMCOUNTER7H 0x9e7 +#define CSR_SHPMCOUNTER8H 0x9e8 +#define CSR_SHPMCOUNTER9H 0x9e9 +#define CSR_SHPMCOUNTER10H 0x9ea +#define CSR_SHPMCOUNTER11H 0x9eb +#define CSR_SHPMCOUNTER12H 0x9ec +#define CSR_SHPMCOUNTER13H 0x9ed +#define CSR_SHPMCOUNTER14H 0x9ee +#define CSR_SHPMCOUNTER15H 0x9ef +#define CSR_SHPMCOUNTER16H 0x9f0 +#define CSR_SHPMCOUNTER17H 0x9f1 +#define CSR_SHPMCOUNTER18H 0x9f2 +#define CSR_SHPMCOUNTER19H 0x9f3 +#define CSR_SHPMCOUNTER20H 0x9f4 +#define CSR_SHPMCOUNTER21H 0x9f5 +#define CSR_SHPMCOUNTER22H 0x9f6 +#define CSR_SHPMCOUNTER23H 0x9f7 +#define CSR_SHPMCOUNTER24H 0x9f8 +#define CSR_SHPMCOUNTER25H 0x9f9 +#define CSR_SHPMCOUNTER26H 0x9fa +#define CSR_SHPMCOUNTER27H 0x9fb +#define CSR_SHPMCOUNTER28H 0x9fc +#define CSR_SHPMCOUNTER29H 0x9fd +#define CSR_SHPMCOUNTER30H 0x9fe +#define CSR_SHPMCOUNTER31H 0x9ff + +#define CSR_SRPLCNTLST 0x9d8 +#define CSR_SCACHELOCK 0x9d9 +#define CSR_SCACHERPLPRI0 0x9da +#define CSR_SCACHERPLPRI1 0x9db +#define CSR_SCACHERPLPRI2 0x9dc +#define CSR_SCACHERPLPRI3 0x9dd +#define CSR_SCACHERPLPRI4 0x9de +#define CSR_SCACHERPLPRI5 0x9df + +/* User-Level XuanTie custom CSRs */ +#define CSR_TWCOUNTER 0x804 +#define CSR_FXCR 0x800 +#define CSR_XMRSTART 0x801 +#define CSR_XMCSR 0x802 +#define CSR_XMSIZE 0x803 +#define CSR_XMLENB 0xcc0 +#define CSR_XRLENB 0xcc1 +#define CSR_XMISA 0xcc2 + +#define CSR_URPLCNTLST 0x8e8 +#define CSR_UCACHELOCK 0x8e9 +#define CSR_UCACHERPLPRI0 0x8ea +#define CSR_UCACHERPLPRI1 0x8eb +#define CSR_UCACHERPLPRI2 0x8ec +#define CSR_UCACHERPLPRI3 0x8ed +#define CSR_UCACHERPLPRI4 0x8ee +#define CSR_UCACHERPLPRI5 0x8ef + +#endif /* __CSI_RV_ENCODING_H__ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/csi_core.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/csi_core.h new file mode 100644 index 00000000..bbb859ff --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/csi_core.h @@ -0,0 +1,224 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 csi_core.h + * @brief CSI Core Layer Header File + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ + +#ifndef _CORE_H_ +#define _CORE_H_ + +#include + +#if defined(__csky__) + +#if defined(__CK801__) || defined(__E801__) +#include +#elif defined(__CK802__) || defined(__E802__) || defined(__E802T__) || defined(__S802__) || defined(__S802T__) +#include +#elif defined(__CK804__) || defined(__E804D__) || defined(__E804DT__) || defined(__E804F__) || defined(__E804FT__) || defined (__E804DF__) || defined(__E804DFT__) +#include +#elif defined(__CK803__) || defined(__E803__) || defined(__E803T__) || defined(__S803__) || defined(__S803T__) +#include +#elif defined(__CK805__) || defined(__I805__) || defined(__I805F__) +#include +#elif defined(__CK610__) +#include +#elif defined(__CK810__) || defined(__C810__) || defined(__C810T__) || defined(__C810V__) || defined(__C810VT__) +#include +#elif defined(__CK807__) || defined(__C807__) || defined(__C807F__) || defined(__C807FV__) || defined(__R807__) +#include +#endif +#include + +#elif defined(__riscv) + +#include +#if CONFIG_CPU_XUANTIE_E906 || CONFIG_CPU_XUANTIE_E906F || CONFIG_CPU_XUANTIE_E906FD || CONFIG_CPU_XUANTIE_E906P || CONFIG_CPU_XUANTIE_E906FP || CONFIG_CPU_XUANTIE_E906FDP \ + || CONFIG_CPU_XUANTIE_E907 || CONFIG_CPU_XUANTIE_E907F || CONFIG_CPU_XUANTIE_E907FD || CONFIG_CPU_XUANTIE_E907P || CONFIG_CPU_XUANTIE_E907FP || CONFIG_CPU_XUANTIE_E907FDP \ + || CONFIG_CPU_XUANTIE_E902 || CONFIG_CPU_XUANTIE_E902M || CONFIG_CPU_XUANTIE_E902T || CONFIG_CPU_XUANTIE_E902MT \ + || CONFIG_CPU_XUANTIE_E901PLUS_CP || CONFIG_CPU_XUANTIE_E901PLUS_B_CP || CONFIG_CPU_XUANTIE_E901PLUS_M_CP || CONFIG_CPU_XUANTIE_E901PLUS_BM_CP \ + || CONFIG_CPU_XUANTIE_E901_CP || CONFIG_CPU_XUANTIE_E901_B_CP || CONFIG_CPU_XUANTIE_E901_ZM_CP || CONFIG_CPU_XUANTIE_E901_BZM_CP +#include +#include +#else +#include +#include +#endif /* end exx */ + +#endif /* __csky__ */ + +#ifdef __arm__ +#include +#endif + +#ifdef __ARM_ARCH_ISA_A64 +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if CONFIG_CPU_XUANTIE_E9XX || CONFIG_CPU_XUANTIE_C906 || CONFIG_CPU_XUANTIE_C906FD || CONFIG_CPU_XUANTIE_C906FDV +#if CONFIG_SMP +#error "This CPU does not support SMP." +#endif +#endif + +__STATIC_INLINE const char* csi_get_cpu_name() +{ +#if CONFIG_CPU_XUANTIE_C906 + return "c906"; +#elif CONFIG_CPU_XUANTIE_C906FD + return "c906fd"; +#elif CONFIG_CPU_XUANTIE_C906FDV + return "c906fdv"; +#elif CONFIG_CPU_XUANTIE_C907 + return "c907"; +#elif CONFIG_CPU_XUANTIE_C907FD + return "c907fd"; +#elif CONFIG_CPU_XUANTIE_C907FDV + return "c907fdv"; +#elif CONFIG_CPU_XUANTIE_C907FDVM + return "c907fdvm"; +#elif CONFIG_CPU_XUANTIE_C907_RV32 + return "c907-rv32"; +#elif CONFIG_CPU_XUANTIE_C907FD_RV32 + return "c907fd-rv32"; +#elif CONFIG_CPU_XUANTIE_C907FDV_RV32 + return "c907fdv-rv32"; +#elif CONFIG_CPU_XUANTIE_C907FDVM_RV32 + return "c907fdvm-rv32"; +#elif CONFIG_CPU_XUANTIE_C908 + return "c908"; +#elif CONFIG_CPU_XUANTIE_C908V + return "c908v"; +#elif CONFIG_CPU_XUANTIE_C908I + return "c908i"; +#elif CONFIG_CPU_XUANTIE_C908X + return "c908x"; +#elif CONFIG_CPU_XUANTIE_C908X_CP + return "c908x-cp"; +#elif CONFIG_CPU_XUANTIE_C908X_CP_XT + return "c908x-cp-xt"; +#elif CONFIG_CPU_XUANTIE_C910 + return "c910"; +#elif CONFIG_CPU_XUANTIE_C920 + return "c920"; +#elif CONFIG_CPU_XUANTIE_C910V2 + return "c910v2"; +#elif CONFIG_CPU_XUANTIE_C910V3 + return "c910v3"; +#elif CONFIG_CPU_XUANTIE_C910V3_CP + return "c910v3-cp"; +#elif CONFIG_CPU_XUANTIE_C910V3_CP_XT + return "c910v3-cp-xt"; +#elif CONFIG_CPU_XUANTIE_C920V2 + return "c920v2"; +#elif CONFIG_CPU_XUANTIE_C920V3 + return "c920v3"; +#elif CONFIG_CPU_XUANTIE_C920V3_CP + return "c920v3-cp"; +#elif CONFIG_CPU_XUANTIE_C920V3_CP_XT + return "c920v3-cp-xt"; +#elif CONFIG_CPU_XUANTIE_R910 + return "r910"; +#elif CONFIG_CPU_XUANTIE_R920 + return "r920"; +#elif CONFIG_CPU_XUANTIE_R908 + return "r908"; +#elif CONFIG_CPU_XUANTIE_R908FD + return "r908fd"; +#elif CONFIG_CPU_XUANTIE_R908FDV + return "r908fdv"; +#elif CONFIG_CPU_XUANTIE_R908_CP + return "r908-cp"; +#elif CONFIG_CPU_XUANTIE_R908FD_CP + return "r908fd-cp"; +#elif CONFIG_CPU_XUANTIE_R908FDV_CP + return "r908fdv-cp"; +#elif CONFIG_CPU_XUANTIE_R908_CP_XT + return "r908-cp-xt"; +#elif CONFIG_CPU_XUANTIE_R908FD_CP_XT + return "r908fd-cp-xt"; +#elif CONFIG_CPU_XUANTIE_R908FDV_CP_XT + return "r908fdv-cp-xt"; +#elif CONFIG_CPU_XUANTIE_E901PLUS_CP + return "e901plus-cp"; +#elif CONFIG_CPU_XUANTIE_E901PLUS_B_CP + return "e901plusb-cp"; +#elif CONFIG_CPU_XUANTIE_E901PLUS_M_CP + return "e901plusm-cp"; +#elif CONFIG_CPU_XUANTIE_E901PLUS_BM_CP + return "e901plusbm-cp"; +#elif CONFIG_CPU_XUANTIE_E901_CP + return "e901-cp"; +#elif CONFIG_CPU_XUANTIE_E901_B_CP + return "e901b-cp"; +#elif CONFIG_CPU_XUANTIE_E901_ZM_CP + return "e901zm-cp"; +#elif CONFIG_CPU_XUANTIE_E901_BZM_CP + return "e901bzm-cp"; +#elif CONFIG_CPU_XUANTIE_E902 + return "e902"; +#elif CONFIG_CPU_XUANTIE_E902M + return "e902m"; +#elif CONFIG_CPU_XUANTIE_E902T + return "e902t"; +#elif CONFIG_CPU_XUANTIE_E902MT + return "e902mt"; +#elif CONFIG_CPU_XUANTIE_E906 + return "e906"; +#elif CONFIG_CPU_XUANTIE_E906F + return "e906f"; +#elif CONFIG_CPU_XUANTIE_E906FD + return "e906fd"; +#elif CONFIG_CPU_XUANTIE_E906P + return "e906p"; +#elif CONFIG_CPU_XUANTIE_E906FP + return "e906fp"; +#elif CONFIG_CPU_XUANTIE_E906FDP + return "e906fdp"; +#elif CONFIG_CPU_XUANTIE_E907 + return "e907"; +#elif CONFIG_CPU_XUANTIE_E907F + return "e907f"; +#elif CONFIG_CPU_XUANTIE_E907FD + return "e907fd"; +#elif CONFIG_CPU_XUANTIE_E907P + return "e907p"; +#elif CONFIG_CPU_XUANTIE_E907FP + return "e907fp"; +#elif CONFIG_CPU_XUANTIE_E907FDP + return "e907fdp"; +#else + return "unknown"; +#endif +} + + +#ifdef __cplusplus +} +#endif + +#endif /* _CORE_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/adc.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/adc.h new file mode 100755 index 00000000..dd69fd3d --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/adc.h @@ -0,0 +1,213 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/adc.h + * @brief Header File for ADC Driver + * @version V1.0 + * @date 08. Apr 2020 + * @model adc + ******************************************************************************/ + +#ifndef _DRV_ADC_H_ +#define _DRV_ADC_H_ + +#include +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/****** ADC Event *****/ +typedef enum { + ADC_EVENT_CONVERT_COMPLETE = 0, ///< All data convert completed + ADC_EVENT_CONVERT_HALF_DONE, ///< Convert half done + ADC_EVENT_ERROR ///< All errors including but not limited to what converted data has not been read before the new conversion result is load to the data register +} csi_adc_event_t; + +typedef struct csi_adc csi_adc_t; +struct csi_adc { + csi_dev_t dev; ///< Hw-device info + void (*callback)(csi_adc_t *adc, csi_adc_event_t event, void *arg); ///< User callback ,signaled by driver event + void *arg; ///< User private param ,passed to user callback + uint32_t *data; ///< Data buf + uint32_t num; ///< Data size by word + csi_dma_ch_t *dma; ///< Dma channel handle + csi_error_t (*start)(csi_adc_t *adc); ///< Start function + csi_error_t (*stop)(csi_adc_t *adc); ///< Stop function + csi_state_t state; ///< ADC current state + void *priv; +}; + +/** + \brief Initialize adc Interface. Initialize the resources needed for the adc interface + \param[in] adc ADC handle to operate + \param[in] idx ADC controller index + \return Error code \ref csi_error_t +*/ +csi_error_t csi_adc_init(csi_adc_t *adc, uint32_t idx); + +/** + \brief De-initialize adc Interface. stops operation and releases the software resources used by the interface + \param[in] handle ADC handle to operate + \return None +*/ +void csi_adc_uninit(csi_adc_t *adc); + +/** + \brief Set adc receive buffer + \param[in] adc ADC handle to operate + \param[in] num The receive data length by word. + \return Error code \ref csi_error_t +*/ +csi_error_t csi_adc_set_buffer(csi_adc_t *adc, uint32_t *data, uint32_t num); + +/** + \brief Start adc + \param[in] handle ADC handle to operate + \return Error code \ref csi_error_t +*/ +csi_error_t csi_adc_start(csi_adc_t *adc); + +/** + \brief Enable dma or interrupt, and start adc conversion + \param[in] handle ADC handle to operate + \return Error code \ref csi_error_t +*/ +csi_error_t csi_adc_start_async(csi_adc_t *adc); + +/** + \brief Stop adc + \param[in] handle ADC handle to operate + \return Error code \ref csi_error_t +*/ +csi_error_t csi_adc_stop(csi_adc_t *adc); + +/** + \brief Disable dma or interrupt, and stop adc conversion + \param[in] handle ADC handle to operate + \return Error code \ref csi_error_t +*/ +csi_error_t csi_adc_stop_async(csi_adc_t *adc); + +/** + \brief ADC channel enable + \param[in] adc ADC handle to operate + \param[in] ch_id ADC channel id + \param[in] is_enable true->enable, false->disable + \return Error code \ref csi_error_t +*/ +csi_error_t csi_adc_channel_enable(csi_adc_t *adc, uint8_t ch_id, bool is_enable); + +/** + \brief Set the ADC sampling time for the selected channel + \param[in] adc ADC handle to operate + \param[in] ch_id ADC channel id + \param[in] clock_num Channel sampling clock number + \return Error code \ref csi_error_t +*/ +csi_error_t csi_adc_channel_sampling_time(csi_adc_t *adc, uint8_t ch_id, uint16_t clock_num); + +/** + \brief Set the ADC controller sampling time + \param[in] adc ADC handle to operate + \param[in] clock_num ADC controller sampling clock number + \return Error code \ref csi_error_t +*/ +csi_error_t csi_adc_sampling_time(csi_adc_t *adc, uint16_t clock_num); + +/** + \brief Enable the continue mode of ADC + \param[in] adc ADC handle to operate + \param[in] is_enable true->enable, false->disable + \return Error code \ref csi_error_t +*/ +csi_error_t csi_adc_continue_mode(csi_adc_t *adc, bool is_enable); + +/** + \brief Set ADC frequence division + \param[in] adc ADC handle to operate + \param[in] div The division of frequence + \return The actual config frequency +*/ +uint32_t csi_adc_freq_div(csi_adc_t *adc, uint32_t div); + +/** + \brief Receiving data from ADC receiver + \param[in] handle ADC handle to operate + \return If read successful, this function shall return the result of convert value + otherwise, the function shall return error code +*/ +int32_t csi_adc_read(csi_adc_t *adc); + +/** + \brief Get ADC state + \param[in] adc ADC handle to operate + \param[in] state ADC state + \return Error code \ref csi_error_t +*/ +csi_error_t csi_adc_get_state(csi_adc_t *adc, csi_state_t *state); + +/** + \brief Attach the callback handler to adc + \param[in] adc Operate handle + \param[in] callback Callback function + \param[in] arg User can define it by himself as callback's param + \return Error code \ref csi_error_t +*/ +csi_error_t csi_adc_attach_callback(csi_adc_t *adc, void *callback, void *arg); + +/** + \brief Detach the callback handler + \param[in] adc Operate handle + \return None +*/ +void csi_adc_detach_callback(csi_adc_t *adc); + +/** + \brief Link DMA channel to adc device + \param[in] adc ADC handle to operate + \param[in] dma The DMA channel handle for send, when it is NULL means to unlink the channel + \return Error code \ref csi_error_t +*/ +csi_error_t csi_adc_link_dma(csi_adc_t *adc, csi_dma_ch_t *dma); + +/** + \brief Enable adc low power mode + \param[in] adc ADC handle to operate + \return Error code \ref csi_error_t +*/ +csi_error_t csi_adc_enable_pm(csi_adc_t *adc); + +/** + \brief Disable adc low power mode + \param[in] adc ADC handle to operate + \return None +*/ +void csi_adc_disable_pm(csi_adc_t *adc); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_ADC_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/aes.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/aes.h new file mode 100755 index 00000000..a395fa7c --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/aes.h @@ -0,0 +1,309 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/aes.h + * @brief Header File for AES Driver + * @version V1.0 + * @date 9. Oct 2020 + * @model aes + ******************************************************************************/ + +#ifndef _DRV_AES_H_ +#define _DRV_AES_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*----- Encrypt & Decrypt: Config key length -----*/ +typedef enum { + AES_KEY_LEN_BITS_128 = 0, /* 128 Data bits */ + AES_KEY_LEN_BITS_192, /* 192 Data bits */ + AES_KEY_LEN_BITS_256 /* 256 Data bits */ +} csi_aes_key_bits_t; + +/** +\brief AES Ctrl Block +*/ +typedef struct { + csi_dev_t dev; + void *priv; +} csi_aes_t; + +/** + \brief Initialize AES interface. Initializes the resources needed for the AES interface + \param[in] aes Handle to operate + \param[in] idx Device id + \return Error code \ref csi_error_t +*/ +csi_error_t csi_aes_init(csi_aes_t *aes, uint32_t idx); + +/** + \brief De-initialize AES interface. Stops operation and releases the software resources used by the interface + \param[in] aes Dandle to operate + \return None +*/ +void csi_aes_uninit(csi_aes_t *aes); + +/** + \brief Set encrypt key + \param[in] aes Handle to operate + \param[in] key Pointer to the key buf + \param[in] key_len Pointer to \ref csi_aes_key_bits_t + \return Error code \ref Csi_error_t +*/ +csi_error_t csi_aes_set_encrypt_key(csi_aes_t *aes, void *key, csi_aes_key_bits_t key_len); + +/** + \brief Set decrypt key + \param[in] aes Handle to operate + \param[in] key Pointer to the key buf + \param[in] key_len Pointer to \ref csi_aes_key_bits_t + \return Error code \ref Csi_error_t +*/ +csi_error_t csi_aes_set_decrypt_key(csi_aes_t *aes, void *key, csi_aes_key_bits_t key_len); +/** + \brief Set encrypt key2. This API is used for the algorithm which has two keys, + such as xts, used for the key of tweak + \param[in] aes Handle to operate + \param[in] key Pointer to the key buf + \param[in] key_len Pointer to \ref csi_aes_key_bits_t + \return Error code \ref Csi_error_t +*/ +csi_error_t csi_aes_set_encrypt_key2(csi_aes_t *aes, void *key, csi_aes_key_bits_t key_len); + +/** + \brief Set decrypt key2. This API is used for the algorithm which has two keys, + such as xts, used for the key of tweak + \param[in] aes Handle to operate + \param[in] key Pointer to the key buf + \param[in] key_len Pointer to \ref csi_aes_key_bits_t + \return Error code \ref Csi_error_t +*/ +csi_error_t csi_aes_set_decrypt_key2(csi_aes_t *aes, void *key, csi_aes_key_bits_t key_len); + +/** + \brief AES ecb encrypt + \param[in] aes Handle to operate + \param[in] in Pointer to the source data + \param[out] out Pointer to the result data + \param[in] size The source data size + \return Error code \ref Csi_error_t +*/ +csi_error_t csi_aes_ecb_encrypt(csi_aes_t *aes, void *in, void *out, uint32_t size); + +/** + \brief AES ecb decrypt + \param[in] aes Handle to operate + \param[in] in Pointer to the source data + \param[out] out Pointer to the result data + \param[in] size The source data size + \return Error code \ref Csi_error_t +*/ +csi_error_t csi_aes_ecb_decrypt(csi_aes_t *aes, void *in, void *out, uint32_t size); + +/** + \brief AES cbc encrypt + \param[in] aes Handle to operate + \param[in] in Pointer to the source data + \param[out] out Pointer to the result data + \param[in] size The source data size + \param[in] iv Init vector + \return Error code \ref Csi_error_t +*/ +csi_error_t csi_aes_cbc_encrypt(csi_aes_t *aes, void *in, void *out, uint32_t size, void *iv); + +/** + \brief AES cbc decrypt + \param[in] aes Handle to operate + \param[in] in Pointer to the source data + \param[out] out Pointer to the result data + \param[in] size The source data size + \param[in] iv Init vector + \return Error code \ref Csi_error_t +*/ +csi_error_t csi_aes_cbc_decrypt(csi_aes_t *aes, void *in, void *out, uint32_t size, void *iv); + +/** + \brief AES cfb1 encrypt + \param[in] aes Handle to operate + \param[in] in Pointer to the source data + \param[out] out Pointer to the result data + \param[in] size The source data size + \param[in] iv Init vector + \return Error code \ref Csi_error_t +*/ +csi_error_t csi_aes_cfb1_encrypt(csi_aes_t *aes, void *in, void *out, uint32_t size, void *iv); + +/** + \brief AES cfb1 decrypt + \param[in] aes Handle to operate + \param[in] in Pointer to the source data + \param[out] out Pointer to the result data + \param[in] size The source data size + \param[in] iv Init vector + \return Error code \ref Csi_error_t +*/ +csi_error_t csi_aes_cfb1_decrypt(csi_aes_t *aes, void *in, void *out, uint32_t size, void *iv); + +/** + \brief AES cfb8 encrypt + \param[in] aes Handle to operate + \param[in] in Pointer to the source data + \param[out] out Pointer to the result data + \param[in] size The source data size + \param[in] iv Init vector + \return Error code \ref Csi_error_t +*/ +csi_error_t csi_aes_cfb8_encrypt(csi_aes_t *aes, void *in, void *out, uint32_t size, void *iv); + +/** + \brief AES cfb8 decrypt + \param[in] aes Handle to operate + \param[in] in Pointer to the source data + \param[out] out Pointer to the result data + \param[in] size The source data size + \param[in] iv Init vector + \return Error code \ref Csi_error_t +*/ +csi_error_t csi_aes_cfb8_decrypt(csi_aes_t *aes, void *in, void *out, uint32_t size, void *iv); + +/** + \brief AES cfb128 decrypt + \param[in] aes Handle to operate + \param[in] in Pointer to the source data + \param[out] out Pointer to the result data + \param[in] size The source data size + \param[in] iv Init vector + \param[out] num The number of the 128-bit block we have used + \return Error code \ref csi_error_t +*/ +csi_error_t csi_aes_cfb128_decrypt(csi_aes_t *aes, void *in, void *out, uint32_t size, void *iv, uint32_t *num); + +/** + \brief AES cfb128 encrypt + \param[in] aes Handle to operate + \param[in] in Pointer to the source data + \param[out] out Pointer to the result data + \param[in] size The source data size + \param[in] iv Init vector + \param[out] num The number of the 128-bit block we have used + \return Error code \ref csi_error_t +*/ +csi_error_t csi_aes_cfb128_encrypt(csi_aes_t *aes, void *in, void *out, uint32_t size, void *iv, uint32_t *num); + +/** + \brief AES ofb encrypt + \param[in] aes Handle to operate + \param[in] in Pointer to the source data + \param[out] out Pointer to the result data + \param[in] size The source data size + \param[in] iv Init vector + \param[out] num The number of the 128-bit block we have used + \return Error code \ref csi_error_t +*/ +csi_error_t csi_aes_ofb_encrypt(csi_aes_t *aes, void *in, void *out, uint32_t size, void *iv, uint32_t *num); + +/** + \brief AES ofb decrypt + \param[in] aes Handle to operate + \param[in] in Pointer to the source data + \param[out] out Pointer to the result data + \param[in] size The source data size + \param[in] iv Init vector + \param[out] num The number of the 128-bit block we have used + \return Error code \ref csi_error_t +*/ +csi_error_t csi_aes_ofb_decrypt(csi_aes_t *aes, void *in, void *out, uint32_t size, void *iv, uint32_t *num); + +/** + \brief AES ctr encrypt + \param[in] aes Handle to operate + \param[in] in Pointer to the source data + \param[out] out Pointer to the result data + \param[in] size The source data size + \param[in] iv Init vector + \return Error code \ref csi_error_t +*/ +csi_error_t csi_aes_ctr_encrypt(csi_aes_t *aes, void *in,void *out, uint32_t size, void *iv); + +/** + \brief AES ctr decrypt + \param[in] aes Handle to operate + \param[in] in Pointer to the source data + \param[out] out Pointer to the result data + \param[in] size The source data size + \param[in] iv Init vecotr + \return Error code \ref csi_error_t +*/ +csi_error_t csi_aes_ctr_decrypt(csi_aes_t *aes, void *in, void *out, uint32_t size, void *iv); + +/** + \brief AES cts encrypt + \param[in] aes Handle to operate + \param[in] in Pointer to the source data + \param[out] out Pointer to the result data + \param[in] size The source data size + \param[in] iv Init vector + \return Error code \ref csi_error_t +*/ +csi_error_t csi_aes_cts_encrypt(csi_aes_t *aes, void *in,void *out, uint32_t size, void *iv); + +/** + \brief AES cts decrypt + \param[in] aes Handle to operate + \param[in] in Pointer to the source data + \param[out] out Pointer to the result data + \param[in] size The source data size + \param[in] iv Init vecotr + \return Error code \ref csi_error_t +*/ +csi_error_t csi_aes_cts_decrypt(csi_aes_t *aes, void *in, void *out, uint32_t size, void *iv); + + +/** + \brief AES xts encrypt + \param[in] aes Handle to operate + \param[in] in Pointer to the source data + \param[out] out Pointer to the result data + \param[in] size The source data size + \param[in] iv Init vector + \return Error code \ref csi_error_t +*/ +csi_error_t csi_aes_xts_encrypt(csi_aes_t *aes, void *in,void *out, uint32_t size, void *iv); + +/** + \brief AES xts decrypt + \param[in] aes Handle to operate + \param[in] in Pointer to the source data + \param[out] out Pointer to the result data + \param[in] size The source data size + \param[in] iv Init vecotr + \return Error code \ref csi_error_t +*/ +csi_error_t csi_aes_xts_decrypt(csi_aes_t *aes, void *in, void *out, uint32_t size, void *iv); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_AES_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/baud_calc.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/baud_calc.h new file mode 100755 index 00000000..1a077c10 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/baud_calc.h @@ -0,0 +1,60 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/baud_calc.h + * @brief Header File for the PWM capture uart bandrate Driver + * @version V1.0 + * @date 9. Oct 2020 + * @model baud_calc + ******************************************************************************/ + +#ifndef _DRV_BAUD_CALC_H_ +#define _DRV_BAUD_CALC_H_ + +#include +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +/** + \brief Baud rate calculation(Algorithm level) + \param[in] idx PWM idx + \param[in] channel Channel num + \return Error code(-1) or Baudare value +*/ +int drv_calc_baud_adjust(uint32_t idx, uint32_t channel); + +/** + \brief Baud rate calculation(Capture level) + \param[in] idx PWM idx + \param[in] channel Channel num + \return Error code(-1) or Baudare value +*/ +int drv_calc_baud_original(uint32_t idx, uint32_t channel); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_BAUD_CALC_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/clk.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/clk.h new file mode 100755 index 00000000..9e9ee03e --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/clk.h @@ -0,0 +1,50 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/clk.h + * @brief Header File for CLK Driver. + * @version V1.0 + * @date 18. Mar 2020 + ******************************************************************************/ + +#ifndef _DRV_CLK_H_ +#define _DRV_CLK_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + uint32_t module; + uint16_t dev_tag; + uint8_t idx; +} csi_clkmap_t; + +void csi_clk_enable(csi_dev_t *dev); +void csi_clk_disable(csi_dev_t *dev); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_CLK_H_ */ + diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/codec.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/codec.h new file mode 100755 index 00000000..d96a40b0 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/codec.h @@ -0,0 +1,450 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/codec.h + * @brief head file for codec + * @version V1.0 + * @date 17. Mar 2020 + * @model codec + ******************************************************************************/ +#ifndef _DRV_CODEC_H_ +#define _DRV_CODEC_H_ + +#include +#include +#include +#include +#include "drv/ringbuf.h" + +typedef enum { + CODEC_EVENT_PERIOD_READ_COMPLETE = 0U, ///< A peroid data read completed + CODEC_EVENT_PERIOD_WRITE_COMPLETE = 1U, ///< A peroid data write completed + CODEC_EVENT_WRITE_BUFFER_EMPTY = 2U, ///< Fifo is empty + CODEC_EVENT_READ_BUFFER_FULL = 3U, ///< Fifo is full + CODEC_EVENT_ERROR_OVERFLOW = 4U, ///< Fifo overflow error + CODEC_EVENT_ERROR_UNDERFLOW = 5U, ///< Fifo underflow error + CODEC_EVENT_ERROR = 6U, ///< The device has a hardware error +} csi_codec_event_t; + +struct csi_codec; +typedef struct csi_codec csi_codec_t; +typedef struct csi_codec_output csi_codec_output_t; +struct csi_codec_output { + csi_codec_t *codec; + uint32_t ch_idx; ///< Codec output channel idx + void (*callback)(csi_codec_output_t *output, csi_codec_event_t event, void *arg); + void *arg; + csi_ringbuf_t *ring_buf; ///< The csi_ringbuf used to save audio data + uint32_t period; ///< When the period data is sent, the callback function will be called + uint32_t sound_channel_num; ///< Number of sound channel + csi_dma_ch_t *dma; ///< Dma channel handle + csi_state_t state; ///< Codec output channel current state + void *priv; + struct csi_codec_output *next; +}; + +typedef struct csi_codec_input csi_codec_input_t; +struct csi_codec_input { + csi_codec_t *codec; + uint32_t ch_idx; ///< Codec input channel idx + void (*callback)(csi_codec_input_t *input, csi_codec_event_t event, void *arg); + void *arg; + csi_ringbuf_t *ring_buf; ///< The csi_ringbuf used to save audio data + uint32_t period; ///< When the period data is received, the callback function will be called + uint32_t sound_channel_num; ///< Number of sound channel + csi_dma_ch_t *dma; ///< Codec input channel current state + csi_state_t state; ///< Dma channel handle + void *priv; + struct csi_codec_input *next; +}; + +struct csi_codec { + csi_dev_t dev; ///< Codec hw-device info + csi_codec_output_t *output_chs; ///< Codec output channel operate handle + csi_codec_input_t *input_chs; ///< Codec input channel operate handle + void *priv; ///< User private param passed to user callback +}; + +typedef enum { + CODEC_OUTPUT_SINGLE_ENDED, ///< Single-ended output + CODEC_OUTPUT_DIFFERENCE, ///< Differential output +} csi_codec_output_mode_t; + +typedef enum { + CODEC_INPUT_SINGLE_ENDED, ///< Single-ended input + CODEC_INPUT_DIFFERENCE, ///< Differential input +} csi_codec_input_mode_t; + +typedef struct { + uint32_t sample_rate; ///< Input data sample rate + uint32_t bit_width; ///< Input data sample width + csi_codec_input_mode_t mode; ///< Input work mode + uint8_t *buffer; ///< The buffer used to save audio data + uint32_t buffer_size; ///< Input buffer size + uint32_t period; ///< When a peroid data is reached,the callback function is called + uint32_t sound_channel_num; ///< Number of soundtrack per channel +} csi_codec_input_config_t; + +typedef struct { + uint32_t sample_rate; ///< Output data sample rate + uint32_t bit_width; ///< Onput data sample width + csi_codec_output_mode_t mode; ///< Onput work mode + uint8_t *buffer; ///< The buffer used to save audio data + uint32_t buffer_size; ///< Output buffer size + uint32_t period; ///< When a peroid data is reached,the callback function is called + uint32_t sound_channel_num; ///< Number of soundchannel per channel +} csi_codec_output_config_t; + +/** + \brief Init the codec according to the specified + \param[in] codec Codec handle to operate + \param[in] idx Codec interface idx + \return error code \ref csi_error_t +*/ +csi_error_t csi_codec_init(csi_codec_t *codec, uint32_t idx); + +/** + \brief Codec uninit + \param[in] codec Codec handle to operate + \return None +*/ +void csi_codec_uninit(csi_codec_t *codec); + +/** + \brief Open a codec output channel + \param[in] codec Codec handle to operate + \param[in] ch Codec output channel handle + \param[in] ch_idx Codec output channel idx + \return error code \ref csi_error_t +*/ +csi_error_t csi_codec_output_open(csi_codec_t *codec, csi_codec_output_t *ch, uint32_t ch_idx); + +/** + \brief Config codec output channel + \param[in] ch Codec output channel handle + \param[in] config Codec channel param. \ref csi_codec_output_config_t + \return error code \ref csi_error_t +*/ +csi_error_t csi_codec_output_config(csi_codec_output_t *ch, csi_codec_output_config_t *config); + +/** + \brief Attach the callback handler to codec output + \param[in] ch Codec output channel handle + \param[in] cb Callback function + \param[in] arg User private param + \return error code \ref csi_error_t +*/ +csi_error_t csi_codec_output_attach_callback(csi_codec_output_t *ch, void *callback, void *arg); + +/** + \brief Detach the callback handler + \param[in] ch Codec output channel handle + \return None +*/ +void csi_codec_output_detach_callback(csi_codec_output_t *ch); + +/** + \brief Close a codec output channel + \param[in] ch Codec output channel handle + \return error code \ref csi_error_t +*/ +void csi_codec_output_close(csi_codec_output_t *ch); + +/** + \brief Link DMA channel to codec output channel + \param[in] ch Codec output channel handle + \param[in] dma The codec output DMA channel handle, when it is NULL means to unlink the channel + \return error code \ref csi_error_t +*/ +csi_error_t csi_codec_output_link_dma(csi_codec_output_t *ch, csi_dma_ch_t *dma); + +/** + \brief Send an amount of data to buffer in blocking mode + \param[in] ch The codec output channel + \param[in] data Pointer to send data buffer + \param[in] size Send data size + \return the num of data witch is send successful +*/ +uint32_t csi_codec_output_write(csi_codec_output_t *ch, const void *data, uint32_t size); + +/** + \brief Send data to the buffer with asynchronous sending + The data is first written to the buffer and then output through the codec interface + This function does not block, and the return value is the number + Of data that was successfully written to the buffer + \param[in] ch The codec output channel + \param[in] data Pointer to send data buffer + \param[in] size Send data size + \return The data size that send to buffer +*/ +uint32_t csi_codec_output_write_async(csi_codec_output_t *ch, const void *data, uint32_t size); + +/** + \brief Start sending data from the buffer + \param[in] ch Codec output channel handle + \return error code \ref csi_error_t +*/ +csi_error_t csi_codec_output_start(csi_codec_output_t *ch); + +/** + \brief Stop sending data from the buffer + \param[in] ch Codec output channel handle + \return None +*/ +void csi_codec_output_stop(csi_codec_output_t *ch); + +/** + \brief Pause sending data from the buffer + \param[in] ch Codec output channel handle + \return error code \ref csi_error_t +*/ +csi_error_t csi_codec_output_pause(csi_codec_output_t *ch); + +/** + \brief Resume sending data from the buffer + \param[in] ch Codec output channel handle + \return error code \ref csi_error_t +*/ +csi_error_t csi_codec_output_resume(csi_codec_output_t *ch); + +/** + \brief Get output-buffer free space + \param[in] ch Codec output channel handle + \return Buffer free space (bytes) +*/ +uint32_t csi_codec_output_buffer_avail(csi_codec_output_t *ch); + +/** + \brief Get used space of output-buffer + \param[in] ch Codec output channel handle + \return Buffer free space (bytes) +*/ +uint32_t csi_codec_output_buffer_remain(csi_codec_output_t *ch); + +/** + \brief Reset the buf, discard all data in the buffer + \param[in] ch Codec output channel handle + \return error code \ref csi_error_t +*/ +csi_error_t csi_codec_output_buffer_reset(csi_codec_output_t *ch); + +/** + \brief Mute codec ouput channel + \param[in] ch Codec output channel handle + \param[in] en True enable codec mute. false disable codec mute + \return error code \ref csi_error_t +*/ +csi_error_t csi_codec_output_mute(csi_codec_output_t *ch, bool enable); + +/** + \brief Set codec ouput channel digital gain + \param[in] ch Codec output channel handle + \param[in] val Gain val + \return error code \ref csi_error_t +*/ +csi_error_t csi_codec_output_digital_gain(csi_codec_output_t *ch, uint32_t val); + +/** + \brief Set codec ouput channel analog gain + \param[in] ch Codec output channel handle + \param[in] val Gain val + \return error code \ref csi_error_t +*/ +csi_error_t csi_codec_output_analog_gain(csi_codec_output_t *ch, uint32_t val); + +/** + \brief Set codec ouput channel mix gain + \param[in] ch Codec output channel handle + \param[in] val Gain val + \return error code \ref csi_error_t +*/ +csi_error_t csi_codec_output_mix_gain(csi_codec_output_t *ch, uint32_t val); + +/** + \brief Get codec output channel state + \param[in] ch Codec output channel handle + \param[out] state Channel state. \ref csi_state_t + \return channel state +*/ +csi_error_t csi_codec_output_get_state(csi_codec_output_t *ch, csi_state_t *state); + +/** + \brief Open a codec input channel + \param[in] codec Codec handle to operate + \param[in] ch Codec input channel handle + \param[in] ch_idx Codec input channel idx + \return error code \ref csi_error_t +*/ +csi_error_t csi_codec_input_open(csi_codec_t *codec, csi_codec_input_t *ch, uint32_t ch_idx); + +/** + \brief Config codec input channel + \param[in] ch Codec input channel handle + \param[in] config Codec channel prarm. \ref csi_codec_input_config_t + \return error code \ref csi_error_t +*/ +csi_error_t csi_codec_input_config(csi_codec_input_t *ch, csi_codec_input_config_t *config); + +/** + \brief Attach the callback handler to codec output + \param[in] ch Codec input channel handle + \param[in] cb Callback function + \param[in] arg User private param for event callback + \return error code \ref csi_error_t +*/ +csi_error_t csi_codec_input_attach_callback(csi_codec_input_t *ch, void *callback, void *arg); + +/** + \brief Detach the callback handler + \param[in] ch Codec input channel handle + \return None +*/ +void csi_codec_input_detach_callback(csi_codec_input_t *ch); + +/** + \brief Close a codec input channel + \param[in] ch Codec input channel handle + \return None +*/ +void csi_codec_input_close(csi_codec_input_t *ch); + +/** + \brief Link DMA channel to codec input channel + \param[in] ch Codec input channel handle + \param[in] dma The codec input DMA channel handle, when it is NULL means to unlink the channel + \return error code \ref csi_error_t +*/ +csi_error_t csi_codec_input_link_dma(csi_codec_input_t *ch, csi_dma_ch_t *dma); + +/** + \brief Read an amount of data in blocking mode + \param[in] ch Codec input channel handle + \param[in] data Pointer to receive data buffer + \param[in] size Receive data size + \return The size of data read successfully +*/ +uint32_t csi_codec_input_read(csi_codec_input_t *ch, void *data, uint32_t size); + +/** + \brief Read data from the buffer + using asynchronous receive + this function read data from the buffer, returns the number of successful receive + and returns 0 if there is no data in the buffer + \param[in] ch Codec input channel handle + \param[in] data Pointer to receive data buffer + \param[in] size Receive data size + \return The size of data read successfully +*/ +uint32_t csi_codec_input_read_async(csi_codec_input_t *ch, void *data, uint32_t size); + +/** + \brief Start receive data to the buffer + \param[in] ch Codec input channel handle + \return error code \ref csi_error_t +*/ +csi_error_t csi_codec_input_start(csi_codec_input_t *ch); + +/** + \brief Stop receive data + \param[in] ch Codec input channel handle + \return None +*/ +void csi_codec_input_stop(csi_codec_input_t *ch); + +/** + \brief Reset the buf, discard all data in the buffer + \param[in] ch Codec input channel handle + \return error code \ref csi_error_t +*/ +csi_error_t csi_codec_input_buffer_reset(csi_codec_input_t *ch); + +/** + \brief Get input-buffer free space + \param[in] ch Codec input channel handle + \return Buffer free space (bytes) +*/ +uint32_t csi_codec_input_buffer_avail(csi_codec_input_t *ch); + +/** + \brief Get used space of input-buffer + \param[in] ch Codec input channel handle + \return Buffer free space (bytes) +*/ +uint32_t csi_codec_input_buffer_remain(csi_codec_input_t *ch); + +/** + \brief Mute codec input channel + \param[in] ch Codec input channel handle + \param[in] en True enable codec mute. false disable codec mute + \return error code \ref csi_error_t +*/ +csi_error_t csi_codec_input_mute(csi_codec_input_t *ch, bool en); + +/** + \brief Set codec input channel digital gain + \param[in] ch Codec input channel handle + \param[in] val Gain val + \return error code \ref csi_error_t +*/ +csi_error_t csi_codec_input_digital_gain(csi_codec_input_t *ch, uint32_t val); + +/** + \brief Set codec input channel analog gain + \param[in] ch Codec input channel handle + \param[in] val Gain val + \return error code \ref csi_error_t +*/ +csi_error_t csi_codec_input_analog_gain(csi_codec_input_t *ch, uint32_t val); + +/** + \brief Set codec input channel mix gain + \param[in] ch Codec input channel handle + \param[in] val Gain val + \return error code \ref csi_error_t +*/ +csi_error_t csi_codec_input_mix_gain(csi_codec_input_t *ch, uint32_t val); + +/** + \brief Get codec input channel state + \param[in] ch Codec input channel handle + \param[out] state Channel state + \return Channel state +*/ +csi_error_t csi_codec_input_get_state(csi_codec_input_t *ch, csi_state_t *state); + +/** + \brief Enable codec power manage + \param[in] codec Codec handle to operate + \return error code \ref csi_error_t +*/ +csi_error_t csi_codec_enable_pm(csi_codec_t *codec); + +/** + \brief Disable codec power manage + \param[in] codec Codec handle to operate + \return None +*/ +void csi_codec_disable_pm(csi_codec_t *codec); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_CODEC_H_ */ + diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/common.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/common.h new file mode 100755 index 00000000..c2c2f84f --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/common.h @@ -0,0 +1,154 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/common.h + * @brief Header File for Common Driver + * @version V1.0 + * @date 31. March 2020 + * @model common + ******************************************************************************/ + +#ifndef _DRV_COMMON_H_ +#define _DRV_COMMON_H_ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef CONFIG_DEBUG_MODE +#define CSI_ASSERT(expr) \ + do { \ + if ((long)expr == (long)NULL) { \ + printf("PROGRAM ASSERT\n"); \ + while(1); \ + } \ + } while(0); +#else +#define CSI_ASSERT(expr) ((void)0U) +#endif + +#ifndef CONFIG_PARAM_NOT_CHECK +#define CSI_PARAM_CHK(para, err) \ + do \ + { \ + if ((unsigned long)para == (unsigned long)NULL) \ + { \ + return (err); \ + } \ + } while (0) + +#define CSI_PARAM_CHK_NORETVAL(para) \ + do \ + { \ + if ((unsigned long)para == (unsigned long)NULL) \ + { \ + return; \ + } \ + } while (0) +#else +#define CSI_PARAM_CHK(para, err) +#define CSI_PARAM_CHK_NORETVAL(para) +#endif + +typedef enum { + CSI_OK = 0, + CSI_ERROR = -1, + CSI_BUSY = -2, + CSI_TIMEOUT = -3, + CSI_UNSUPPORTED = -4 +} csi_error_t; + +typedef struct { + uint8_t readable; + uint8_t writeable; + uint8_t error; +} csi_state_t; + +typedef struct csi_dev csi_dev_t; + +#ifdef CONFIG_PM +typedef enum { + PM_DEV_SUSPEND, + PM_DEV_RESUME, +} csi_pm_dev_action_t; + +typedef enum { + PM_MODE_RUN = 0, ///< Running mode + PM_MODE_SLEEP_1, ///< Sleep LV1 mode + PM_MODE_SLEEP_2, ///< Sleep LV2 mode + PM_MODE_DEEP_SLEEP_1, ///< Deep sleep LV1 mode + PM_MODE_DEEP_SLEEP_2, ///< Deep sleep LV2 mode +} csi_pm_mode_t; + +typedef struct { + slist_t next; + csi_error_t (*pm_action)(csi_dev_t *dev, csi_pm_dev_action_t action); + uint32_t *reten_mem; + uint32_t size; +} csi_pm_dev_t; +#include +#endif + +struct csi_dev { + unsigned long reg_base; + uint16_t irq_num; + uint16_t idx; + uint16_t dev_tag; + void (*irq_handler)(void *); + void (*irq_handler2)(uint32_t irqn, void *arg); + void *arg; +#ifdef CONFIG_PM + csi_pm_dev_t pm_dev; +#endif +}; + +#define DEV_IDX_INVALID 0xFFFFU +#define HANDLE_REG_BASE(handle) (handle->dev.reg_base) +#define HANDLE_IRQ_NUM(handle) (handle->dev.irq_num) +#define HANDLE_DEV_IDX(handle) (handle->dev.idx) +#define HANDLE_IRQ_HANDLER(handle) (handle->dev.irq_handler) + +typedef struct { + unsigned long reg_base; + uint16_t irq_num; + uint16_t idx; + uint16_t dev_tag; +} csi_perip_info_t; + +csi_error_t target_get(csi_dev_tag_t dev_tag, uint32_t idx, csi_dev_t *dev); +csi_error_t target_get_optimal_dma_channel(void *dma_list, uint32_t ctrl_num, csi_dev_t *parent_dev, void *ch_info); +csi_error_t target_get_check_dma_access(uint32_t ctrl_idx, void *srcaddr, void *dstaddr, void **dma_base_src_addr, void **dma_base_dst_addr); +csi_error_t target_get_dma_handshake(uint16_t dma_id, uint16_t dev_id, uint16_t dev_tag, uint8_t type, uint16_t *handshake); +void mdelay(uint32_t ms); +void udelay(uint32_t us); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_COMMON_H_ */ + diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/crc.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/crc.h new file mode 100755 index 00000000..2fbd43db --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/crc.h @@ -0,0 +1,136 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 crc.h + * @brief Header File for CRC Driver + * @version V1.0 + * @date 02. June 2020 + * @model crc + ******************************************************************************/ + +#ifndef _DRV_CRC_H_ +#define _DRV_CRC_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Compute the CRC-7 checksum of a buffer. + * + * See JESD84-A441. Used by the MMC protocol. Uses 0x09 as the + * polynomial with no reflection. The CRC is left + * justified, so bit 7 of the result is bit 6 of the CRC. + * init = 0; poly = 0x09 refin = 0 refout = 0 xorout = 0 + * \param[in] crc Crc init value or crc immediate result + * \param[in] data Data buf to be calculate + * \param[in] size Data size + * + * \return The computed CRC7 value + */ +uint8_t csi_crc7_be(uint8_t crc, uint8_t *data, uint32_t size); + +/** + * \brief Compute the CRC-8 checksum of a buffer. + * init = 0 or 0xff; poly = 0x07 refin = 0 refout = 0 xorout = 0 + * \param[in] crc Crc init value or crc immediate result + * \param[in] data Data buf to be calculate + * \param[in] size Data size + * \return The computed CRC8 value + */ +uint8_t csi_crc8(uint8_t crc, uint8_t *data, size_t size); + +/** + * \brief Compute the CRC-8 checksum of a buffer. + * init = 0; poly = 0x31 refin = 1 refout = 1 xorout = 0 + * \param[in] crc Crc init value or crc immediate result + * \param[in] data Data buf to be calculate + * \param[in] size Data size + * \return The computed CRC8 value + */ +uint8_t csi_crc8_maxim(uint8_t crc, uint8_t *data, size_t size); + +/** + * \brief Compute the CRC-16 checksum of a buffer. + * init = 0 or 0xffff; poly = 0x8005 refin = 1 refout = 1 xorout = 0 + * \param[in] crc Crc init value or crc immediate result + * \param[in] data Data buf to be calculate + * \param[in] size Data size + * \return The computed CRC16 without xorout + */ +uint16_t csi_crc16(uint16_t crc, uint8_t *data, uint32_t size); + +/** + * \brief Compute the CRC-16 checksum of a buffer. + * init = 0; poly = 0x1021 refin = 1 refout = 1 xorout = 0 + * \param[in] crc Crc init value or crc immediate result + * \param[in] data Data buf to be calculate + * \param[in] size Data size + * \return The computed CRC16 without xorout + */ +uint16_t csi_crc16_ccitt(uint16_t crc, uint8_t *data, uint32_t size); + +/** + * \brief Compute the CRC-16 checksum of a buffer. + * init = 0; poly = 0x3d65 refin = 1 refout = 1 xorout = 0xffff + * \param[in] init_value Crc init value + * \param[in] data Data buf to be calculate + * \param[in] size Data size + * \return The computed CRC16 with xorout + */ +uint16_t csi_crc16_dnp(uint16_t init_value, uint8_t *data, uint32_t size); + +/** + * \brief Compute the CRC-16 checksum of a buffer. + * init = 0; poly = 0x1021 refin = 0 refout = 0 xorout = 0 + * \param[in] crc Crc init value or crc immediate result + * \param[in] data Data buf to be calculate + * \param[in] size Data size + * \return The computed CRC16 without xorout + */ +uint16_t csi_crc16_itu(uint16_t crc, uint8_t *data, uint32_t size); + +/** + * \brief Compute the CRC-32 checksum of a buffer.Little-endian by bit. + * init = 0; poly = 0xEDB88320 refin = 0 refout = 0 xorout = 0 + * \param[in] crc Crc init value or crc immediate result + * \param[in] data Data buf to be calculate + * \param[in] size Data size + * \return The computed CRC32 without xorout + */ +uint32_t csi_crc32_le(uint32_t crc, uint8_t *data, uint32_t size); + +/** + * \brief Compute the CRC-32 checksum of a buffer.Big-endian by bit. + * init = 0; poly = 0x04C11DB7 refin = 0 refout = 0 xorout = 0 + * \param[in] crc Crc init value or crc immediate result + * \param[in] data Data buf to be calculate + * \param[in] size Data size + * \return The computed CRC32 without xorout + */ +uint32_t csi_crc32_be(uint32_t crc, uint8_t *data, uint32_t size); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_CRC_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/des.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/des.h new file mode 100755 index 00000000..2b0540ea --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/des.h @@ -0,0 +1,174 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/des.h + * @brief Header File for DES Driver + * @version V1.0 + * @date 24. Oct 2022 + * @model des + ******************************************************************************/ + +#ifndef _DRV_DES_H_ +#define _DRV_DES_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** +\brief DES key-len-bits type +*/ +typedef enum { + DES_KEY_LEN_BITS_64 = 0, /*64 Data bits*/ + DES_KEY_LEN_BITS_128, /*128 Data bits*/ + DES_KEY_LEN_BITS_192, /*192 Data bits*/ +} csi_des_key_bits_t; + +/** +\brief DES Ctrl Block +*/ +typedef struct { + csi_dev_t dev; + void *priv; +} csi_des_t; + +/** + \brief Initialize DES interface. Initializes the resources needed for the DES interface + \param[in] des Handle to operate + \param[in] idx Device id + \return Error code \ref csi_error_t +*/ +csi_error_t csi_des_init(csi_des_t *des, uint32_t idx); + +/** + \brief De-initialize DES interface. Stops operation and releases the software resources used by the interface + \param[in] des Dandle to operate + \return None +*/ +void csi_des_uninit(csi_des_t *des); + +/** + \brief Set encrypt key + \param[in] des Handle to operate + \param[in] key Pointer to the key buf + \param[in] key_len Pointer to \ref csi_des_key_bits_t + \return Error code \ref Csi_error_t +*/ +csi_error_t csi_des_set_encrypt_key(csi_des_t *des, void *key, csi_des_key_bits_t key_len); + +/** + \brief Set decrypt key + \param[in] des Handle to operate + \param[in] key Pointer to the key buf + \param[in] key_len Pointer to \ref csi_des_key_bits_t + \return Error code \ref Csi_error_t +*/ +csi_error_t csi_des_set_decrypt_key(csi_des_t *des, void *key, csi_des_key_bits_t key_len); + +/** + \brief DES ecb encrypt + \param[in] des Handle to operate + \param[in] in Pointer to the source data + \param[out] out Pointer to the result data + \param[in] size The source data size + \return Error code \ref Csi_error_t +*/ +csi_error_t csi_des_ecb_encrypt(csi_des_t *des, void *in, void *out, uint32_t size); + +/** + \brief DES ecb decrypt + \param[in] des Handle to operate + \param[in] in Pointer to the source data + \param[out] out Pointer to the result data + \param[in] size The source data size + \return Error code \ref Csi_error_t +*/ +csi_error_t csi_des_ecb_decrypt(csi_des_t *des, void *in, void *out, uint32_t size); + +/** + \brief DES cbc encrypt + \param[in] des Handle to operate + \param[in] in Pointer to the source data + \param[out] out Pointer to the result data + \param[in] size The source data size + \param[in] iv Init vector + \return Error code \ref Csi_error_t +*/ +csi_error_t csi_des_cbc_encrypt(csi_des_t *des, void *in, void *out, uint32_t size, void *iv) ; + +/** + \brief DES cbc decrypt + \param[in] des Handle to operate + \param[in] in Pointer to the source data + \param[out] out Pointer to the result data + \param[in] size The source data size + \param[in] iv Init vector + \return Error code \ref Csi_error_t +*/ +csi_error_t csi_des_cbc_decrypt(csi_des_t *des, void *in, void *out, uint32_t size, void *iv); + +/** + \brief TDES ecb encrypt + \param[in] des Handle to operate + \param[in] in Pointer to the source data + \param[out] out Pointer to the result data + \param[in] size The source data size + \return Error code \ref Csi_error_t +*/ +csi_error_t csi_tdes_ecb_encrypt(csi_des_t *des, void *in, void *out, uint32_t size); + +/** + \brief TDES ecb decrypt + \param[in] des Handle to operate + \param[in] in Pointer to the source data + \param[out] out Pointer to the result data + \param[in] size The source data size + \return Error code \ref Csi_error_t +*/ +csi_error_t csi_tdes_ecb_decrypt(csi_des_t *des, void *in, void *out, uint32_t size); + +/** + \brief TDES cbc encrypt + \param[in] des Handle to operate + \param[in] in Pointer to the source data + \param[out] out Pointer to the result data + \param[in] size The source data size + \param[in] iv Init vector + \return Error code \ref Csi_error_t +*/ +csi_error_t csi_tdes_cbc_encrypt(csi_des_t *des, void *in, void *out, uint32_t size, void *iv) ; + +/** + \brief TDES cbc decrypt + \param[in] des Handle to operate + \param[in] in Pointer to the source data + \param[out] out Pointer to the result data + \param[in] size The source data size + \param[in] iv Init vector + \return Error code \ref Csi_error_t +*/ +csi_error_t csi_tdes_cbc_decrypt(csi_des_t *des, void *in, void *out, uint32_t size, void *iv); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_DES_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/dma.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/dma.h new file mode 100644 index 00000000..7dcf5b5c --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/dma.h @@ -0,0 +1,306 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 dma.h + * @brief header file for dma driver + * @version V1.0 + * @date 08. Apr 2020 + * @model dma + ******************************************************************************/ + +#ifndef _DRV_DMA_H_ +#define _DRV_DMA_H_ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/****** DMA Event *****/ +typedef enum { + DMA_EVENT_TRANSFER_DONE = 0, ///< transfer complete + DMA_EVENT_TRANSFER_BLOCK_DONE, ///< transfer block done + DMA_EVENT_TRANSFER_HALF_DONE, ///< transfer half done + DMA_EVENT_TRANSFER_ERROR, ///< transfer error +} csi_dma_event_t; + +typedef enum { + DMA_ADDR_INC = 0, + DMA_ADDR_DEC, + DMA_ADDR_CONSTANT +} csi_dma_addr_inc_t; + +typedef enum { + DMA_DATA_WIDTH_8_BITS = 0, + DMA_DATA_WIDTH_16_BITS, + DMA_DATA_WIDTH_32_BITS, + DMA_DATA_WIDTH_64_BITS, + DMA_DATA_WIDTH_128_BITS, + DMA_DATA_WIDTH_512_BITS +} csi_dma_data_width_t; + +typedef enum { + DMA_MEM2MEM = 0, + DMA_MEM2PERH, + DMA_PERH2MEM, +} csi_dma_trans_dir_t; + +typedef struct { + uint16_t ctrl_idx; + uint8_t ch_idx; +} csi_dma_ch_desc_t; + + typedef struct { + uint16_t dev_tag; + uint16_t ctrl_idx; + const csi_dma_ch_desc_t *ch_list; + } csi_dma_ch_spt_list_t; + +typedef struct { + uint16_t ctrl_idx; + uint64_t ch_bit_info; +} csi_dma_ch_bit_desc_t; + + +typedef struct { + uint16_t ctrl_idx; + uint8_t ch_num; +} csi_dma_ch_info_t; + +typedef struct { + uint16_t parent_dev_id; + uint16_t dev_tag; + const csi_dma_ch_bit_desc_t *ch_list; +} csi_dma_ch_bit_spt_list_t; + +#define DMA_HANDSHAKE_NONE 0xff + +typedef enum { + DMA_HANDSHAKE_TYPE_RX = 0x0, + DMA_HANDSHAKE_TYPE_TX = 0x1, +} csi_dma_handshake_type_t; + +typedef struct { + uint16_t parent_dev_id; + uint16_t dev_tag; + uint8_t rx_hs; + uint8_t tx_hs; +} csi_dma_handshake_ctrl_t; + +typedef struct { + uint16_t ctrl_idx; + const csi_dma_handshake_ctrl_t* handshake_ctrl_list; +} csi_dma_handshake_list_t; + +typedef struct { + void* cpu_base_addr; + void* dma_base_addr; + size_t mem_size; +} csi_dma_mem_desc_t; + +typedef struct { + uint16_t ctrl_idx; + const csi_dma_mem_desc_t *mem_list; +} csi_dma_mem_list_t; + +typedef enum { + DMA_LINK_LIST_STOP = 0, + DMA_LINK_LIST_RUNNING, + DMA_LINK_LIST_READY, +} csi_dma_link_list_state_t; + +typedef enum { + DMA_CYCLIC_STOP = 0, + DMA_CYCLIC_RUNNING, + DMA_CYCLIC_READY, +} csi_dma_cyclic_state_t; + +typedef struct { + void *srcaddr; + void *dstaddr; + uint32_t length; +} csi_dma_link_list_item_t; + +typedef struct { + csi_dma_addr_inc_t src_inc; ///< source address increment + csi_dma_addr_inc_t dst_inc; ///< destination address increment + csi_dma_data_width_t src_tw; ///< source transfer width in byte + csi_dma_data_width_t dst_tw; ///< destination transfer width in byte + csi_dma_trans_dir_t trans_dir; ///< transfer direction + uint16_t handshake; ///< handshake id + uint16_t group_len; ///< group transaction length (unit: bytes) + uint8_t src_reload_en; ///< 1:dma enable src addr auto reload, 0:disable + uint8_t dst_reload_en; ///< 1:dma enable dst addr auto reload, 0:disable + uint8_t half_int_en; ///< 1:dma enable half interrupt, 0: disable + uint8_t lli_src_en; ///< 1:dma enable llp, 0 disable + uint8_t lli_dst_en; ///< 1:dma enable llp, 0 disable + uint8_t link_list_en; ///< 1:dma enable link list mode, 0: disable + void *lli_buf; ///< link list config +} csi_dma_ch_config_t; + + +typedef struct { + csi_dma_addr_inc_t src_inc; ///< source address increment + csi_dma_addr_inc_t dst_inc; ///< destination address increment + csi_dma_data_width_t src_tw; ///< source transfer width in byte + csi_dma_data_width_t dst_tw; ///< destination transfer width in byte + uint16_t group_len; ///< group transaction length (unit: bytes) + uint8_t lli_src_en; ///< 1:dma enable llp, 0 disable + uint8_t lli_dst_en; ///< 1:dma enable llp, 0 disable +} csi_dma_lli_config_t; + +#ifndef DMA_LLI_SIZE +#define DMA_LLI_SIZE 64 +#endif + +#define DEFINE_DESC_BUF(buf_name, num) uint8_t buf_name[num * DMA_LLI_SIZE] __attribute__((aligned(64))); + +typedef struct csi_dma_ch csi_dma_ch_t; + +struct csi_dma_ch { + void *parent; + int8_t ctrl_id; + int8_t ch_id; + void (*callback)(csi_dma_ch_t *dma_ch, csi_dma_event_t event, void *arg); + void *arg; + uint32_t lli_num; //lli buffer len + uint32_t lli_count; //lli data count + int32_t lli_w_p; //write position + int32_t lli_r_p; //read position + void *lli; //lli buffer + uint32_t lli_loop_buf0; //lli loop data + uint32_t lli_loop_buf1; //lli loop data + uint8_t lli_loop[DMA_LLI_SIZE]; //lli loop handle + int16_t etb_ch_id; + csi_dma_trans_dir_t trans_dir; + csi_dma_link_list_state_t link_list_state; + slist_t next; +}; + +typedef struct { + csi_dev_t dev; + slist_t head; + uint64_t alloc_status; + uint32_t ch_num; + void *priv; +} csi_dma_t; + +/** + \brief Init dma controller + \param[in] dma the dma controller operate handle + \param[in] ctrl_id the dma controller id + \return csi error code +*/ +csi_error_t csi_dma_init(csi_dma_t *dma, int8_t ctrl_id); + +/** + \brief Uninit dma controller + \param[in] dma the dma controller operate handle + \return none +*/ +void csi_dma_uninit(csi_dma_t *dma); + +/** + \brief Alloc a dma channel + \param[in] dma_ch the dma channel operate handle + \param[in] ch_id the channel id of dma; when set -1, means auto alloc + \param[in] ctrl_id the dma controller id; when set -1, means auto alloc + \return csi error code +*/ +csi_error_t csi_dma_ch_alloc(csi_dma_ch_t *dma_ch, int8_t ch_id, int8_t ctrl_id); + +/** + \brief Free a dma channel + \param[in] dma_ch the dma channel operate handle + \return none +*/ +void csi_dma_ch_free(csi_dma_ch_t *dma_ch); + +/** + \brief Config a dma channel + \param[in] dma_ch the dma channel operate handle + \param[in] config the config structure for dma channel + \return csi error code +*/ +csi_error_t csi_dma_ch_config(csi_dma_ch_t *dma_ch, csi_dma_ch_config_t *config); + +/** + \brief Start a dma channel + \param[in] dma_ch the dma channel operate handle + \param[in] psrcaddr transfer source address + \param[in] pdstaddr transfer destination address + \param[in] length transfer length (unit: bytes), if set data_width is 16, the length should be the multiple of 2, and + if set data_width is 32, the length should be the multiple of 4 + \return none +*/ +void csi_dma_ch_start(csi_dma_ch_t *dma_ch, void *srcaddr, void *dstaddr, uint32_t length); + +/** + \brief Stop a dma channel + \param[in] dma_ch the dma channel operate handle + \return none +*/ +void csi_dma_ch_stop(csi_dma_ch_t *dma_ch); + +/** + \brief add dma lli + \param[in] dma_ch the dma channel operate handle + \param[in] config lli config + \param[in] item lli + \return csi error code +*/ +csi_error_t csi_dma_add_link_list_item(csi_dma_ch_t *dma_ch, csi_dma_lli_config_t *config, csi_dma_link_list_item_t *item); + +/** + \brief Attach the callback handler to DMA channel + \param[in] dma_ch operate handle. + \param[in] callback callback function + \param[in] arg user can define it by himself as callback's param + \return error code +*/ +csi_error_t csi_dma_ch_attach_callback(csi_dma_ch_t *dma_ch, void *callback, void *arg); + +/** + \brief detach the callback handler + \param[in] uart operate handle. +*/ +void csi_dma_ch_detach_callback(csi_dma_ch_t *dma_ch); + +/** + \brief enable dma power manage + \param[in] dma dma handle to operate. + \return error code +*/ +csi_error_t csi_dma_enable_pm(csi_dma_t *dma); + +/** + \brief disable dma power manage + \param[in] dma dma handle to operate. +*/ +void csi_dma_disable_pm(csi_dma_t *dma); + +#ifdef __cplusplus +} +#endif + +#endif /* _CSI_DMA_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/drv_fft.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/drv_fft.h new file mode 100755 index 00000000..76330849 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/drv_fft.h @@ -0,0 +1,83 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv_fft.h + * @brief header file for gpio driver + * @version V1.0 + * @date 11. Nov 2017 + * @model fft + ******************************************************************************/ + +#ifndef _CSI_FFT_H_ +#define _CSI_FFT_H_ + + +#include +#include +#include +//#include + +#ifdef __cplusplus + extern "C" { +#endif + +typedef enum { + // 512-point FFT + CSKY_MCA_FFT_LEN_512 = 0x1, + // 256-point FFT + CSKY_MCA_FFT_LEN_256 = 0x2, + // 128-point FFT + CSKY_MCA_FFT_LEN_128 = 0x4, + // 64-point FFT + CSKY_MCA_FFT_LEN_64 = 0x8, + // 32-point FFT + CSKY_MCA_FFT_LEN_32 = 0x10, + // 16-point FFT + CSKY_MCA_FFT_LEN_16 = 0x20, +} csky_mca_fft_len_t; + +/* 8-bit fixed-point numeric type in user-defined format */ +typedef int8_t fxp8_t; +/* 16-bit fixed-point numeric type in user-defined format */ +typedef int16_t fxp16_t; +/* 24-bit fixed-point numeric type in user-defined format */ +typedef int32_t fxp24_t; +/* 32-bit fixed-point numeric type in user-defined format */ +typedef int32_t fxp32_t; +/* 64-bit fixed-point numeric type in user-defined format */ +typedef int64_t fxp64_t; + +/* 8-bit fixed-point numeric type in 1.0.7 format */ +typedef fxp8_t q7_t; +/* 16-bit fixed-point numeric type in 1.0.15 format */ +typedef fxp16_t q15_t; +/* 32-bit fixed-point numeric type in 1.15.16 format */ +typedef fxp32_t q16_t; + +void csky_mca_rfft_fxp32(csky_mca_fft_len_t fft_len, const fxp32_t *input, size_t input_size, fxp32_t *output); +void csky_mca_cfft_fxp32(csky_mca_fft_len_t fft_len, const fxp32_t *input, fxp32_t *output); +void csky_mca_rifft_fxp32(csky_mca_fft_len_t fft_len, const fxp32_t *input, fxp32_t *output); +void csky_mca_cifft_fxp32(csky_mca_fft_len_t fft_len, const fxp32_t *input, fxp32_t *output); +void csky_mca_power_spectrum_fxp32(csky_mca_fft_len_t fft_len, const fxp32_t *input, size_t input_size, fxp64_t *output); + +#ifdef __cplusplus +} +#endif + +#endif /* _CSI_FFT_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/ecdh.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/ecdh.h new file mode 100755 index 00000000..5e9acf78 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/ecdh.h @@ -0,0 +1,92 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/ecdh.h + * @brief Header File for ECDH Driver + * @version V1.0 + * @date 9. May 2023 + * @model ecdh + ******************************************************************************/ + +#ifndef _DRV_ECDH_H_ +#define _DRV_ECDH_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** +\brief ECDH Ctrl Block +*/ +typedef struct { + csi_dev_t dev; + void *priv; +} csi_ecdh_t; + +/** + \brief Initialize ECDH interface. Initializes the resources needed for the ECDH interface + \param[in] ecdh Handle to operate + \param[in] idx Device id + \return Error code \ref csi_error_t +*/ +csi_error_t csi_ecdh_init(csi_ecdh_t *ecdh, uint32_t idx); + +/** + \brief De-initialize ECDH interface. Stops operation and releases the software resources used by the interface + \param[in] ecdh Dandle to operate + \return None +*/ +void csi_ecdh_uninit(csi_ecdh_t *ecdh); + +/** + \brief Load curve param to engin + \param[in] ecdh Handle to operate + \param[in] type Pointer to \ref csi_curve_type_t + \return Error code \ref csi_error_t +*/ +csi_error_t csi_ecdh_load_curve(csi_ecdh_t *ecdh, csi_curve_type_t type); + +/** + \brief ECDH generate key pair + \param[in] ecdh Handle to operate + \param[out] prikey Pointer to the private key buf + \param[out] pubkey Pointer to the public key buf + \return Error code \ref Csi_error_t +*/ +csi_error_t csi_ecdh_gen_keypair(csi_ecdh_t *ecdh, uint8_t *prikey, uint8_t *pubkey); + +/** + \brief ECDH generate secret key + \param[in] ecdh Handle to operate + \param[in] prikey Pointer to the private key buf + \param[in] pubkey Pointer to the public key buf + \param[out] sk Pointer to the secret key buf + \param[out] sk_len The secret key length + \return Error code \ref Csi_error_t +*/ +csi_error_t csi_ecdh_calc_secret(csi_ecdh_t *ecdh, const uint8_t *privkey, const uint8_t *pubkey, uint8_t *sk, uint32_t *sk_len); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_ECDH_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/ecdsa.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/ecdsa.h new file mode 100755 index 00000000..4c6d91a6 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/ecdsa.h @@ -0,0 +1,112 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/ecdsa.h + * @brief Header File for ECDSA Driver + * @version V1.0 + * @date 9. May 2023 + * @model ecdsa + ******************************************************************************/ + +#ifndef _DRV_ECDSA_H_ +#define _DRV_ECDSA_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** +\brief EC curve type +*/ +typedef enum { + CSI_CURVES_SECP256K1 = 0U, /* SECG curve over a 256 bit prime field */ + CSI_CURVES_SECP384R1, /* NIST/SECG curve over a 384 bit prime field */ + CSI_CURVES_SECP521R1, /* NIST/SECG curve over a 521 bit prime field */ + CSI_CURVES_BRAINPOOL256R1, /* RFC 5639 curve over a 256 prime field */ + CSI_CURVES_BRAINPOOL256T1, /* RFC 5639 curve over a 256 prime field */ + CSI_CURVES_BRAINPOOL512R1, /* RFC 5639 curve over a 512 prime field */ + CSI_CURVES_BRAINPOOL512T1, /* RFC 5639 curve over a 512 prime field */ +} csi_curve_type_t; + +/** +\brief ECDSA Ctrl Block +*/ +typedef struct { + csi_dev_t dev; + void *priv; +} csi_ecdsa_t; + +/** + \brief Initialize ECDSA interface. Initializes the resources needed for the ECDSA interface + \param[in] ecdsa Handle to operate + \param[in] idx Device id + \return Error code \ref csi_error_t +*/ +csi_error_t csi_ecdsa_init(csi_ecdsa_t *ecdsa, uint32_t idx); + +/** + \brief De-initialize ECDSA interface. Stops operation and releases the software resources used by the interface + \param[in] ecdsa Dandle to operate + \return None +*/ +void csi_ecdsa_uninit(csi_ecdsa_t *ecdsa); + +/** + \brief Load curve param to engin + \param[in] ecdsa Handle to operate + \param[in] type Pointer to \ref csi_curve_type_t + \return Error code \ref csi_error_t +*/ +csi_error_t csi_ecdsa_load_curve(csi_ecdsa_t *ecdsa, csi_curve_type_t type); + +/** + \brief Ecdsa Sign + \param[in] ecdsa Handle to operate + \param[in] prikey Pointer to the private key buf + \param[in] prikey_len The private key length + \param[in] dgst Pointer to the digest buf + \param[in] dgst_len The digest length + \param[out] sig Pointer to the signature buf + \param[out] sig_len The signature length + \return Error code \ref Csi_error_t +*/ +csi_error_t csi_ecdsa_sign(csi_ecdsa_t *ecdsa, const uint8_t *prikey, uint32_t prikey_len, + const uint8_t *dgst, uint32_t dgst_len, uint8_t *sig, uint32_t *sig_len); + +/** + \brief Ecdsa Verify + \param[in] ecdsa Handle to operate + \param[in] pubkey Pointer to the public key buf + \param[in] prikey_len The public key length + \param[in] dgst Pointer to the digest buf + \param[in] dgst_len The digest length + \param[in] sig Pointer to the signature buf + \param[in] sig_len The signature length + \return Error code \ref Csi_error_t +*/ +csi_error_t csi_ecdsa_verify(csi_ecdsa_t *ecdsa, const uint8_t *pubkey, uint32_t pubkey_len, + const uint8_t *dgst, uint32_t gst_len, const uint8_t *sig, uint32_t sig_len); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_ECDSA_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/eflash.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/eflash.h new file mode 100755 index 00000000..8d6c41d0 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/eflash.h @@ -0,0 +1,140 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 eflash.h + * @brief header file for eflash driver + * @version V1.0 + * @date 02. June 2017 + * @model eflash + ******************************************************************************/ +#ifndef _DRV_EFLASH_H_ +#define _DRV_EFLASH_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** +\brief Flash information +*/ +typedef struct { + uint32_t flash_size; ///< Chip End address (start+size-1) + uint32_t sector_size; ///< Uniform sector size in bytes + uint32_t erased_value; ///< erased value +} csi_eflash_info_t; + +/** +\brief Flash Status +*/ +typedef struct { + uint32_t busy : 1; ///< Flash busy flag + uint32_t error : 1; ///< Read/Program/Erase error flag (cleared on start of next operation) +} eflash_status_t; + +/// definition for eflash handle. +typedef struct { + csi_dev_t dev; + void *arg; + csi_eflash_info_t eflashinfo; + uint16_t prog; + uint16_t erase; + void *priv; +} csi_eflash_t; + +// Function documentation + +/** + \brief Initialize EFLASH Interface. 1. Initializes the resources needed for the EFLASH interface 2.registers event callback function + \param[in] eflash eflash handle to operate. + \param[in] idx device id + \param[in] arg User can define it by himself as callback's param + \return error code +*/ +csi_error_t csi_eflash_init(csi_eflash_t *eflash, int32_t idx, void *arg); + +/** + \brief De-initialize EFLASH Interface. stops operation and releases the software resources used by the interface + \param[in] eflash eflash handle to operate. + \return error code +*/ +csi_error_t csi_eflash_uninit(csi_eflash_t *eflash); + +/** + \brief Read data from Flash. + \param[in] eflash eflash handle to operate. + \param[in] offset Data address. + \param[out] data Pointer to a buffer storing the data read from Flash. + \param[in] size Number of data items to read. + \return error code +*/ +csi_error_t csi_eflash_read(csi_eflash_t *eflash, uint32_t offset, void *data, uint32_t size); + +/** + \brief Program data to Flash. + \param[in] eflash eflash handle to operate. + \param[in] offset Data address. + \param[in] data Pointer to a buffer containing the data to be programmed to Flash. + \param[in] size Number of data items to program. + \return error code +*/ +csi_error_t csi_eflash_program(csi_eflash_t *eflash, uint32_t offset, const void *data, uint32_t size); + +/** + \brief Erase Flash Sector. + \param[in] eflash eflash handle to operate. + \param[in] offset flash address, flash address need sector size aligned + \param[in] size erase size + \return error code +*/ +csi_error_t csi_eflash_erase(csi_eflash_t *eflash, uint32_t offset,uint32_t size); + +/** + \brief Erase whole flash + \param[in] eflash eflash handle to operate. + \return error code +*/ +csi_error_t csi_eflash_erase_chip(csi_eflash_t *eflash); + +/** + \brief Get Flash information. + \param[in] eflash eflash handle to operate. +*/ +void csi_eflash_dev_info(csi_eflash_t *eflash,csi_eflash_info_t *eflash_info); + +/** + \brief enable eflash power manage + \param[in] eflash eflash handle to operate. + \return error code +*/ +csi_error_t csi_eflash_enable_pm(csi_eflash_t *eflash); + +/** + \brief disable eflash power manage + \param[in] eflash eflash handle to operate. +*/ +void csi_eflash_disable_pm(csi_eflash_t *eflash); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_EFLASH_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/efuse.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/efuse.h new file mode 100755 index 00000000..2c697074 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/efuse.h @@ -0,0 +1,93 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/efuse.h + * @brief Header File for EFUSE Driver + * @version V1.0 + * @date 22. Mar 2020 + * @model efuse + ******************************************************************************/ +#ifndef _DEV_EFUSEC_H_ +#define _DEV_EFUSEC_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + uint32_t start; ///< Efuse start address + uint32_t end; ///< Efuse end address + uint32_t size; ///< Efuse size +} csi_efuse_info_t; + +typedef struct { + csi_dev_t dev; + csi_efuse_info_t info; +} csi_efuse_t; + +/** + \brief Initialize EFUSEC Interface. 1. Initializes the resources needed for the EFUSEC interface + \param[in] idx Device id + \return Error code +*/ +csi_error_t csi_efuse_init(csi_efuse_t *efuse, int32_t idx); + +/** + \brief De-initialize EFUSEC Interface. stops operation and releases the software resources used by the interface + \param[in] efuse Efuse efuse to operate. + \return None +*/ +void csi_efuse_uninit(csi_efuse_t *efuse); + +/** + \brief Read data from Efuse. + \param[in] efuse Efuse handle to operate. + \param[in] addr Data address. + \param[out] data Pointer to a buffer storing the data read from Efuse. + \param[in] size Number of data items to read. + \return Number of data items read or error code +*/ +int32_t csi_efuse_read(csi_efuse_t *efuse, uint32_t addr, void *data, uint32_t size); + +/** + \brief Program data to Efuse. + \param[in] efuse Efuse handle to operate. + \param[in] addr Data address. + \param[in] data Pointer to a buffer containing the data to be programmed to Efuse. + \param[in] cnt Number of data items to program. + \return number of data items programmed or error code +*/ +int32_t csi_efuse_program(csi_efuse_t *efuse, uint32_t addr, const void *data, uint32_t size); + +/** + \brief Get Efuse information. + \param[in] efuse Efuse handle to operate. + \param[out] info Efuse info \refs csi_efuse_info_t. + \return Error code +*/ +csi_error_t csi_efuse_get_info(csi_efuse_t *efuse, csi_efuse_info_t *info); + +#ifdef __cplusplus +} +#endif + +#endif /* _CSI_EFUSEC_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/etb.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/etb.h new file mode 100755 index 00000000..20dcfac7 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/etb.h @@ -0,0 +1,102 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv_etb.h + * @brief header file for event trigger driver + * @version V1.0 + * @date 27. octorber 2017 + * @model etb + ******************************************************************************/ + +#ifndef _DRV_ETB_H_ +#define _DRV_ETB_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + ETB_HARDWARE_TRIG = 0, ///< etb channel inout is hardware trigger. + ETB_SOFTWARE_TRIG ///< etb channel inout is software trigger. +} csi_etb_trig_mode_t; + +typedef enum { + ETB_CH_ONE_TRIGGER_ONE = 0, ///< one device trig one deivce + ETB_CH_ONE_TRIGGER_MORE, ///< one device trig two for more device + ETB_CH_MORE_TRIGGER_ONE ///< two or more device trig one deivce +} csi_etb_ch_type_t; + +typedef struct { + uint8_t src_ip; ///< a specific number represent a location in an source trigger location map to trigger other ip(s). + uint8_t dst_ip; ///< a specific number represent an location in an dest trigger map to wait signal(s) from source ip(s) or location(s). + csi_etb_trig_mode_t trig_mode; ///< the input source is hardware trigger or software trigger. + csi_etb_ch_type_t ch_type; ///< channel type +} csi_etb_config_t; + +/** + \brief Init the etb device + \return error code +*/ +csi_error_t csi_etb_init(void); + +/** + \brief Uninit the etb device + \return none +*/ +void csi_etb_uninit(void); + +/** + \brief alloc an etb channel + \param[in] ch_mode etb channel work mode + \return channel id or CSI_ERROR +*/ +int32_t csi_etb_ch_alloc(csi_etb_ch_type_t ch_type); + +/** + \brief free an etb channel + \param[in] ch_id etb channel work mode + \return none +*/ +void csi_etb_ch_free(int32_t ch_id); + +/** + \brief config etb channel + \param[in] ch_id etb channel id + \param[in] config the config structure for etb channel + \return csi error code +*/ +csi_error_t csi_etb_ch_config(int32_t ch_id, csi_etb_config_t *config); + +/** + \brief start an etb channel + \param[in] ch_id etb channel id + \return none +*/ +void csi_etb_ch_start(int32_t ch_id); + +/** + \brief stop an etb channel + \param[in] etb etb channel id + \return none +*/ +void csi_etb_ch_stop(int32_t ch_id); + +#endif /* _CSI_ETB_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/eth.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/eth.h new file mode 100644 index 00000000..3a2aedb4 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/eth.h @@ -0,0 +1,111 @@ +/** + * Copyright (C) 2016 CSI Project. All rights reserved. + * + * 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. + */ + + +#ifndef _CSI_NET_H_ +#define _CSI_NET_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define CSI_ETH_VERSION_MAJOR_MINOR(major,minor) (((major) << 8) | (minor)) + +/** +\brief Driver Version +*/ +typedef struct csi_driver_version { + uint16_t api; ///< API version + uint16_t drv; ///< Driver version +} csi_drv_version_t; + +/* General return codes */ +#define CSI_ETH_OK 0 ///< Operation succeeded +#define CSI_ETH_ERROR CSI_DRV_ERRNO_ETH_BASE+1 ///< Unspecified error +#define CSI_ETH_ERROR_BUSY CSI_DRV_ERRNO_ETH_BASE+2 ///< Driver is busy +#define CSI_ETH_ERROR_TIMEOUT CSI_DRV_ERRNO_ETH_BASE+3 ///< Timeout occurred +#define CSI_ETH_ERROR_UNSUPPORTED CSI_DRV_ERRNO_ETH_BASE+4 ///< Operation not supported +#define CSI_ETH_ERROR_PARAMETER CSI_DRV_ERRNO_ETH_BASE+5 ///< Parameter error +#define CSI_ETH_ERROR_SPECIFIC CSI_DRV_ERRNO_ETH_BASE+6 ///< Start of driver specific errors + +/** +\brief General power states +*/ +typedef enum eth_power_state { + CSI_ETH_POWER_OFF, ///< Power off: no operation possible + CSI_ETH_POWER_LOW, ///< Low Power mode: retain state, detect and signal wake-up events + CSI_ETH_POWER_FULL ///< Power on: full operation at maximum performance +} eth_power_state_t; + +/** +\brief Ethernet Media Interface type +*/ +#define CSI_ETH_INTERFACE_MII (0) ///< Media Independent Interface (MII) +#define CSI_ETH_INTERFACE_RMII (1) ///< Reduced Media Independent Interface (RMII) +#define CSI_ETH_INTERFACE_SMII (2) ///< Serial Media Independent Interface (SMII) + +/** +\brief Ethernet link speed +*/ +#define CSI_ETH_SPEED_10M (0) ///< 10 Mbps link speed +#define CSI_ETH_SPEED_100M (1) ///< 100 Mbps link speed +#define CSI_ETH_SPEED_1G (2) ///< 1 Gpbs link speed + +/** +\brief Ethernet duplex mode +*/ +#define CSI_ETH_DUPLEX_HALF (0) ///< Half duplex link +#define CSI_ETH_DUPLEX_FULL (1) ///< Full duplex link + +/** +\brief Ethernet auto-negotiation +*/ +#define CSI_ETH_AUTONEG_DISABLE (0) ///< Disable auto-negotiation +#define CSI_ETH_AUTONEG_ENABLE (1) ///< Enable auto-negotiation + +/** +\brief Ethernet link state +*/ +typedef enum eth_link_state { + ETH_LINK_DOWN, ///< Link is down + ETH_LINK_UP ///< Link is up +} eth_link_state_t; + +/** +\brief Ethernet link information +*/ +typedef volatile struct eth_link_info { + uint32_t speed : 2; ///< Link speed: 0= 10 MBit, 1= 100 MBit, 2= 1 GBit + uint32_t duplex : 1; ///< Duplex mode: 0= Half, 1= Full + uint32_t autoneg : 1; ///< Set the interface to Auto Negotiation mode of transmission parameters + uint32_t loopback : 1; ///< Set the interface into a Loop-back test mode + uint32_t isolation : 1; ///< Set to indicate electrical isolation of PHY interface from MII/RMII interface + uint32_t reserved : 26; +} eth_link_info_t; + +/** +\brief Ethernet MAC Address +*/ +typedef struct eth_mac_addr { + uint8_t b[6]; ///< MAC Address (6 bytes), MSB first +} eth_mac_addr_t; + +#ifdef __cplusplus +} +#endif + +#endif /* CSI_NET_H_ */ + diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/eth_mac.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/eth_mac.h new file mode 100644 index 00000000..bc5757d2 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/eth_mac.h @@ -0,0 +1,377 @@ +/** + * Copyright (C) 2016 CSI Project. All rights reserved. + * + * 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. + */ + +#ifndef _CSI_ETH_H_ +#define _CSI_ETH_H_ + +#include +#include "drv/eth.h" +#include "drv/eth_phy.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *eth_mac_handle_t; + +#define MAX_FRAMELEN 1518 /* (note: maximum ethernet frame length would be 1518) */ + +#define CSI_ETH_MAC_API_VERSION CSI_DRIVER_VERSION_MAJOR_MINOR(2,1) /* API version */ + +#define _CSI_Driver_ETH_MAC_(n) Driver_ETH_MAC##n +#define CSI_Driver_ETH_MAC_(n) _CSI_Driver_ETH_MAC_(n) + +/****** Ethernet MAC Control Codes *****/ + +#define CSI_ETH_MAC_CONFIGURE (0x01) ///< Configure MAC; arg = configuration +#define CSI_ETH_MAC_CONTROL_TX (0x02) ///< Transmitter; arg: 0=disabled (default), 1=enabled +#define CSI_ETH_MAC_CONTROL_RX (0x03) ///< Receiver; arg: 0=disabled (default), 1=enabled +#define CSI_ETH_MAC_FLUSH (0x04) ///< Flush buffer; arg = CSI_ETH_MAC_FLUSH_... +#define CSI_ETH_MAC_SLEEP (0x05) ///< Sleep mode; arg: 1=enter and wait for Magic packet, 0=exit +#define CSI_ETH_MAC_VLAN_FILTER (0x06) ///< VLAN Filter for received frames; arg15..0: VLAN Tag; arg16: optional CSI_ETH_MAC_VLAN_FILTER_ID_ONLY; 0=disabled (default) +#define DRV_ETH_MAC_ADJUST_LINK (0x07) ///< Adjust MAC link state according to phy state; arg: phy handle +#define DRV_ETH_MAC_CONTROL_IRQ (0x08) ///< Interrupt request; arg: 0=disable, 1=enable + +/*----- Ethernet MAC Configuration -----*/ +#define CSI_ETH_MAC_SPEED_Pos 0 +#define CSI_ETH_MAC_SPEED_Msk (3UL << CSI_ETH_MAC_SPEED_Pos) +#define CSI_ETH_MAC_SPEED_10M (CSI_ETH_SPEED_10M << CSI_ETH_MAC_SPEED_Pos) ///< 10 Mbps link speed +#define CSI_ETH_MAC_SPEED_100M (CSI_ETH_SPEED_100M << CSI_ETH_MAC_SPEED_Pos) ///< 100 Mbps link speed +#define CSI_ETH_MAC_SPEED_1G (CSI_ETH_SPEED_1G << CSI_ETH_MAC_SPEED_Pos) ///< 1 Gpbs link speed +#define CSI_ETH_MAC_DUPLEX_Pos 2 +#define CSI_ETH_MAC_DUPLEX_Msk (1UL << CSI_ETH_MAC_DUPLEX_Pos) +#define CSI_ETH_MAC_DUPLEX_HALF (CSI_ETH_DUPLEX_HALF << CSI_ETH_MAC_DUPLEX_Pos) ///< Half duplex link +#define CSI_ETH_MAC_DUPLEX_FULL (CSI_ETH_DUPLEX_FULL << CSI_ETH_MAC_DUPLEX_Pos) ///< Full duplex link +#define CSI_ETH_MAC_LOOPBACK (1UL << 4) ///< Loop-back test mode +#define CSI_ETH_MAC_CHECKSUM_OFFLOAD_RX (1UL << 5) ///< Receiver Checksum offload +#define CSI_ETH_MAC_CHECKSUM_OFFLOAD_TX (1UL << 6) ///< Transmitter Checksum offload +#define CSI_ETH_MAC_ADDRESS_BROADCAST (1UL << 7) ///< Accept frames with Broadcast address +#define CSI_ETH_MAC_ADDRESS_MULTICAST (1UL << 8) ///< Accept frames with any Multicast address +#define CSI_ETH_MAC_ADDRESS_ALL (1UL << 9) ///< Accept frames with any address (Promiscuous Mode) + +/*----- Ethernet MAC Flush Flags -----*/ +#define CSI_ETH_MAC_FLUSH_RX (1UL << 0) ///< Flush Receive buffer +#define CSI_ETH_MAC_FLUSH_TX (1UL << 1) ///< Flush Transmit buffer + +/*----- Ethernet MAC VLAN Filter Flag -----*/ +#define CSI_ETH_MAC_VLAN_FILTER_ID_ONLY (1UL << 16) ///< Compare only the VLAN Identifier (12-bit) + + +/****** Ethernet MAC Frame Transmit Flags *****/ +#define CSI_ETH_MAC_TX_FRAME_FRAGMENT (1UL << 0) ///< Indicate frame fragment +#define CSI_ETH_MAC_TX_FRAME_EVENT (1UL << 1) ///< Generate event when frame is transmitted +#define CSI_ETH_MAC_TX_FRAME_TIMESTAMP (1UL << 2) ///< Capture frame time stamp + + +/****** Ethernet MAC Timer Control Codes *****/ +#define CSI_ETH_MAC_TIMER_GET_TIME (0x01) ///< Get current time +#define CSI_ETH_MAC_TIMER_SET_TIME (0x02) ///< Set new time +#define CSI_ETH_MAC_TIMER_INC_TIME (0x03) ///< Increment current time +#define CSI_ETH_MAC_TIMER_DEC_TIME (0x04) ///< Decrement current time +#define CSI_ETH_MAC_TIMER_SET_ALCSI (0x05) ///< Set alarm time +#define CSI_ETH_MAC_TIMER_ADJUST_CLOCK (0x06) ///< Adjust clock frequency; time->ns: correction factor * 2^31 + + +/** +\brief Ethernet MAC Time +*/ +typedef struct eth_mac_time { + uint32_t ns; ///< Nano seconds + uint32_t sec; ///< Seconds +} eth_mac_time_t; + + +/****** Ethernet MAC Event *****/ +#define CSI_ETH_MAC_EVENT_RX_FRAME (1UL << 0) ///< Frame Received +#define CSI_ETH_MAC_EVENT_TX_FRAME (1UL << 1) ///< Frame Transmitted +#define CSI_ETH_MAC_EVENT_WAKEUP (1UL << 2) ///< Wake-up (on Magic Packet) +#define CSI_ETH_MAC_EVENT_TIMER_ALCSI (1UL << 3) ///< Timer Alarm +#define CSI_ETH_MAC_EVENT_LINK_CHANGE (1UL << 4) ///< Link state + +typedef void (*eth_event_cb_t)(int32_t idx, uint32_t event); ///< Pointer to \ref eth_event_cb_t : Signal Ethernet Event. + +typedef enum { + FRAME_FILTER_RULE_POSITIVE_MATCHING = 0, /*!< Specifies that a filter should match a given pattern */ + FRAME_FILTER_RULE_NEGATIVE_MATCHING = 1, /*!< Specifies that a filter should NOT match a given pattern */ +} frame_filter_rule_t; + +/** +\brief Ethernet MAC Capabilities +*/ +typedef struct eth_capabilities { + uint32_t checksum_offload_rx_ip4 : 1; ///< 1 = IPv4 header checksum verified on receive + uint32_t checksum_offload_rx_ip6 : 1; ///< 1 = IPv6 checksum verification supported on receive + uint32_t checksum_offload_rx_udp : 1; ///< 1 = UDP payload checksum verified on receive + uint32_t checksum_offload_rx_tcp : 1; ///< 1 = TCP payload checksum verified on receive + uint32_t checksum_offload_rx_icmp : 1; ///< 1 = ICMP payload checksum verified on receive + uint32_t checksum_offload_tx_ip4 : 1; ///< 1 = IPv4 header checksum generated on transmit + uint32_t checksum_offload_tx_ip6 : 1; ///< 1 = IPv6 checksum generation supported on transmit + uint32_t checksum_offload_tx_udp : 1; ///< 1 = UDP payload checksum generated on transmit + uint32_t checksum_offload_tx_tcp : 1; ///< 1 = TCP payload checksum generated on transmit + uint32_t checksum_offload_tx_icmp : 1; ///< 1 = ICMP payload checksum generated on transmit + uint32_t media_interface : 2; ///< Ethernet Media Interface type + uint32_t mac_address : 1; ///< 1 = driver provides initial valid MAC address + uint32_t event_rx_frame : 1; ///< 1 = callback event generated + uint32_t event_tx_frame : 1; ///< 1 = callback event generated + uint32_t event_wakeup : 1; ///< 1 = wakeup event generated + uint32_t precision_timer : 1; ///< 1 = Precision Timer supported + uint32_t reserved : 15; ///< Reserved (must be zero) +} eth_capabilities_t; + +/** + * Structure describing a frame filter list item + */ +typedef struct { + uint32_t id; /*!< Unique identifier for a packet filter item */ + frame_filter_rule_t rule; /*!< Filter matches are either POSITIVE or NEGATIVE matching */ + uint16_t offset; /*!< Offset in bytes to start filtering (referenced to the start of the ethernet packet) */ + uint16_t mask_size; /*!< Size of the mask in bytes */ + uint8_t *mask; /*!< Pattern mask bytes to be ANDed with the pattern eg. "\xff00" (must be in network byte order) */ + uint8_t *pattern; /*!< Pattern bytes used to filter eg. "\x0800" (must be in network byte order) */ + bool enabled_status; /*!< When returned from mhd_get_packet_filters, indicates if the filter is enabled */ +} eth_frame_filter_t; + +struct eth_frame_filter_list { + struct eth_frame_filter_list *next; +}; + +typedef struct eth_frame_filter_list eth_frame_filter_list_t; + +typedef struct { + eth_event_cb_t cb_event; + eth_capabilities_t capabilities; +} eth_mac_priv_t; + +/** + \brief Get driver version. + \param[in] handle ethernet handle + \return ethernet version including chip version and driver version +*/ +csi_drv_version_t csi_eth_mac_get_version(eth_mac_handle_t handle); + +/** + \brief Get driver capabilities. + \param[in] idx device id + \return ethernet capabilities +*/ +eth_capabilities_t csi_eth_mac_get_capabilities(int32_t idx); + +/** + \brief This function is used to initialize Ethernet device and related resource, an event callback is registered. It is called when the middleware component like TCPIP starts operation. + \param[in] idx device id + \param[in] cb callback to handle ethernet event + \return return ethernet handle if success + */ +eth_mac_handle_t csi_eth_mac_initialize(int32_t idx, eth_event_cb_t cb_event); + +/** + \brief This function is used to de-initialize Ethernet device. It is called when the middleware component stops operation and releases the software resources used by the interface. + \param[in] handle ethernet handle + \return error code + */ +int32_t csi_eth_mac_uninitialize(eth_mac_handle_t handle); + +/** + \brief Connect phy device to mac device. + \param[in] handle_mac mac handle + \param[in] handle_phy phy handle +*/ +void csi_eth_mac_connect_phy(eth_mac_handle_t handle_mac, eth_phy_handle_t handle_phy); + +/** + \brief Control Ethernet MAC Device Power. + \param[in] handle ethernet handle + \param[in] state Power state + \return error code +*/ +int32_t csi_eth_mac_power_control(eth_mac_handle_t handle, eth_power_state_t state); + +/** + \brief Get Ethernet MAC Address. + \param[in] handle ethernet handle + \param[in] mac Pointer to address + \return error code +*/ +int32_t csi_eth_mac_get_macaddr(eth_mac_handle_t handle, eth_mac_addr_t *mac); + +/** + \brief Set Ethernet MAC Address. + \param[in] handle ethernet handle + \param[in] mac Pointer to address + \return error code +*/ +int32_t csi_eth_mac_set_macaddr(eth_mac_handle_t handle, const eth_mac_addr_t *mac); + +/** + \brief Configure Address Filter. + \param[in] handle ethernet handle + \param[in] addr Pointer to addresses + \param[in] num_addr Number of addresses to configure + \return error code +*/ +int32_t csi_eth_mac_set_addrfilter(eth_mac_handle_t handle, const eth_mac_addr_t *addr, uint32_t num_addr); + +/** + \brief Send Ethernet frame. + \param[in] handle ethernet handle + \param[in] frame Pointer to frame buffer with data to send + \param[in] len Frame buffer length in bytes + \param[in] flags Frame transmit flags (see CSI_ETH_MAC_TX_FRAME_...) + \return error code +*/ +int32_t csi_eth_mac_send_frame(eth_mac_handle_t handle, const uint8_t *frame, uint32_t len, uint32_t flags); + +/** + \brief Read data of received Ethernet frame. + \param[in] handle ethernet handle + \param[in] frame Pointer to frame buffer for data to read into + \param[in] len Frame buffer length in bytes + \return number of data bytes read or execution status + - value >= 0: number of data bytes read + - value < 0: error occurred, value is execution status as defined with execution_status +*/ +int32_t csi_eth_mac_read_frame(eth_mac_handle_t handle, uint8_t *frame, uint32_t len); + +/** + \brief Request data of received Ethernet frame. + csi_eth_mac_request_frame() and csi_eth_mac_release_frame() + must be called in pairs. + \param[in] handle ethernet handle + \param[in] frame Pointer to frame buffer pointer + \return number of data bytes read or execution status + - value >= 0: number of data bytes read + - value < 0: error occurred +*/ +int32_t csi_eth_mac_request_frame(eth_mac_handle_t handle, uint8_t **frame); + +/** + \brief Release current Ethernet frame. + csi_eth_mac_request_frame() and csi_eth_mac_release_frame() + must be called in pairs. + \param[in] handle ethernet handle + \return error code +*/ +int32_t csi_eth_mac_release_frame(eth_mac_handle_t handle); + +/** + \brief Get size of received Ethernet frame. + \param[in] handle ethernet handle + \return number of bytes in received frame +*/ +int32_t csi_eth_mac_get_rx_framesize(eth_mac_handle_t handle); + +/** + \brief Get time of received Ethernet frame. + \param[in] handle ethernet handle + \param[in] time Pointer to time structure for data to read into + \return error code +*/ +int32_t csi_eth_mac_get_rx_frametime(eth_mac_handle_t handle, eth_mac_time_t *time); + +/** + \brief Get time of transmitted Ethernet frame. + \param[in] handle ethernet handle + \param[in] time Pointer to time structure for data to read into + \return error code +*/ +int32_t csi_eth_mac_get_tx_frametime(eth_mac_handle_t handle, eth_mac_time_t *time); + +/** + \brief Control Ethernet Interface. + \param[in] handle ethernet handle + \param[in] control Operation + \param[in] arg Argument of operation (optional) + \return error code +*/ +int32_t csi_eth_mac_control(eth_mac_handle_t handle, uint32_t control, uint32_t arg); + +/** + \brief Control Precision Timer. + \param[in] handle ethernet handle + \param[in] control Operation + \param[in] time Pointer to time structure + \return error code +*/ +int32_t csi_eth_mac_control_time(eth_mac_handle_t handle, uint32_t control, eth_mac_time_t *time); + +/** + \brief Read Ethernet PHY Register through Management Interface. + \param[in] handle ethernet handle + \param[in] phy_addr 5-bit device address + \param[in] reg_addr 5-bit register address + \param[out] data Pointer where the result is written to + \return error code +*/ +int32_t csi_eth_mac_phy_read(eth_mac_handle_t handle, uint8_t phy_addr, uint8_t reg_addr, uint16_t *data); + +/** + \brief Write Ethernet PHY Register through Management Interface. + \param[in] handle ethernet handle + \param[in] phy_addr 5-bit device address + \param[in] reg_addr 5-bit register address + \param[in] data 16-bit data to write + \return error code +*/ +int32_t csi_eth_mac_phy_write(eth_mac_handle_t handle, uint8_t phy_addr, uint8_t reg_addr, uint16_t data); + +/** + \brief Callback function that signals a Ethernet Event. + \param[in] handle ethernet handle + \param[in] event event notification mask + \return none +*/ +void csi_eth_mac_signal_event(eth_mac_handle_t handle, uint32_t event); + +/** + \brief Add Frame Filter Setting with Filter ID. + \param[in] handle ethernet handle + \param[in] filter Pointer to filter setting + \return error code +*/ +int32_t csi_eth_mac_add_framefilter(eth_mac_handle_t handle, const eth_frame_filter_t *filter); + +/** + \brief Remove Frame Filter Setting. + \param[in] handle ethernet handle + \param[in] filter_id Frame Filter ID + \return error code +*/ +int32_t csi_eth_mac_remove_framefilter(eth_mac_handle_t handle, uint32_t filter_id); + +/** + \brief Enable/Disable Specified Frame Filter ID. + \param[in] handle ethernet handle + \param[in] filter_id Frame Filter ID + \param[in] en Enable or disable + \return error code +*/ +int32_t csi_eth_mac_en_framefilter(eth_mac_handle_t handle, uint32_t filter_id, bool en); + +/** + \brief Get frame filter table list. + \param[in] handle ethernet handle + \param[in] list frame filter table list + \param[in] count_out the count of filter setting added + \param[in] max_count max filter setting can be supported + \return error code +*/ +int32_t csi_eth_mac_get_framefilter(eth_mac_handle_t handle, eth_frame_filter_list_t *list, uint32_t *count_out, uint32_t max_count); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/eth_phy.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/eth_phy.h new file mode 100644 index 00000000..5ef87565 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/eth_phy.h @@ -0,0 +1,124 @@ +/** + * Copyright (C) 2016 CSI Project. All rights reserved. + * + * 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. + */ + +#ifndef _CSI_ETH_PHY_H_ +#define _CSI_ETH_PHY_H_ + +#include "drv/eth.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *eth_phy_handle_t; + +#define CSI_ETH_PHY_API_VERSION CSI_ETH_VERSION_MAJOR_MINOR(2,1) /* API version */ + + +#define _CSI_Driver_ETH_PHY_(n) Driver_ETH_PHY##n +#define CSI_Driver_ETH_PHY_(n) _CSI_Driver_ETH_PHY_(n) + + +/****** Ethernet PHY Mode *****/ +#define CSI_ETH_PHY_SPEED_Pos 0 +#define CSI_ETH_PHY_SPEED_Msk (3UL << CSI_ETH_PHY_SPEED_Pos) +#define CSI_ETH_PHY_SPEED_10M (CSI_ETH_SPEED_10M << CSI_ETH_PHY_SPEED_Pos) ///< 10 Mbps link speed +#define CSI_ETH_PHY_SPEED_100M (CSI_ETH_SPEED_100M << CSI_ETH_PHY_SPEED_Pos) ///< 100 Mbps link speed +#define CSI_ETH_PHY_SPEED_1G (CSI_ETH_SPEED_1G << CSI_ETH_PHY_SPEED_Pos) ///< 1 Gpbs link speed +#define CSI_ETH_PHY_DUPLEX_Pos 2 +#define CSI_ETH_PHY_DUPLEX_Msk (1UL << CSI_ETH_PHY_DUPLEX_Pos) +#define CSI_ETH_PHY_DUPLEX_HALF (CSI_ETH_DUPLEX_HALF << CSI_ETH_PHY_DUPLEX_Pos) ///< Half duplex link +#define CSI_ETH_PHY_DUPLEX_FULL (CSI_ETH_DUPLEX_FULL << CSI_ETH_PHY_DUPLEX_Pos) ///< Full duplex link +#define CSI_ETH_PHY_AUTO_NEGOTIATE (1UL << 3) ///< Auto Negotiation mode +#define CSI_ETH_PHY_LOOPBACK (1UL << 4) ///< Loop-back test mode +#define CSI_ETH_PHY_ISOLATE (1UL << 5) ///< Isolate PHY from MII/RMII interface + +typedef int32_t (*csi_eth_phy_read_t)(uint8_t phy_addr, uint8_t reg_addr, uint16_t *data); ///< Read Ethernet PHY Register. +typedef int32_t (*csi_eth_phy_write_t)(uint8_t phy_addr, uint8_t reg_addr, uint16_t data); ///< Write Ethernet PHY Register. + +typedef struct { + csi_eth_phy_read_t phy_read; + csi_eth_phy_write_t phy_write; + eth_link_info_t link_info; +} eth_phy_priv_t; + +// Function documentation +/** + \brief Get driver version. + \param[in] handle ethernet phy handle + \return driver version +*/ +csi_drv_version_t csi_eth_phy_get_version(eth_phy_handle_t handle); + +/** + \brief Initialize Ethernet PHY Device. + \param[in] fn_read + \param[in] fn_write + \return ethernet phy handle +*/ +eth_phy_handle_t csi_eth_phy_initialize(csi_eth_phy_read_t fn_read, csi_eth_phy_write_t fn_write); + +/** + \brief De-initialize Ethernet PHY Device. + \param[in] handle ethernet phy handle + \return error code +*/ +int32_t csi_eth_phy_uninitialize(eth_phy_handle_t handle); + +/** + \brief Control Ethernet PHY Device Power. + \param[in] handle ethernet phy handle + \param[in] state Power state + \return error code +*/ +int32_t csi_eth_phy_power_control(eth_phy_handle_t handle, eth_power_state_t state); + +/** + \brief Set Ethernet Media Interface. + \param[in] handle ethernet phy handle + \param[in] interface Media Interface type + \return error code +*/ +int32_t csi_eth_phy_set_interface(eth_phy_handle_t handle, uint32_t interface); + +/** + \brief Set Ethernet PHY Device Operation mode. + \param[in] handle ethernet phy handle + \param[in] mode Operation Mode + \return error code +*/ +int32_t csi_eth_phy_set_mode(eth_phy_handle_t handle, uint32_t mode); + +/** + \brief Get Ethernet PHY Device Link state. + \param[in] handle ethernet phy handle + \return current link status \ref eth_link_state_t +*/ +eth_link_state_t csi_eth_phy_get_linkstate(eth_phy_handle_t handle); + +/** + \brief Get Ethernet PHY Device Link information. + \param[in] handle ethernet phy handle + \return current link parameters \ref eth_link_info_t +*/ +eth_link_info_t csi_eth_phy_get_linkinfo(eth_phy_handle_t handle); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/fft.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/fft.h new file mode 100755 index 00000000..a3cd312b --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/fft.h @@ -0,0 +1,87 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/fft.h + * @brief Header File for FFT Driver + * @version V1.0 + * @date 11. Nov 2020 + * @model fft + ******************************************************************************/ + +#ifndef _DRV_FFT_H_ +#define _DRV_FFT_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + ///< 512-point FFT + CSKY_MCA_FFT_LEN_512 = 0x1, + ///< 256-point FFT + CSKY_MCA_FFT_LEN_256 = 0x2, + ///< 128-point FFT + CSKY_MCA_FFT_LEN_128 = 0x4, + ///< 64-point FFT + CSKY_MCA_FFT_LEN_64 = 0x8, + ///< 32-point FFT + CSKY_MCA_FFT_LEN_32 = 0x10, + ///< 16-point FFT + CSKY_MCA_FFT_LEN_16 = 0x20, +} csky_mca_fft_len_t; + +/* 8-bit fixed-point numeric type in user-defined format */ +typedef int8_t fxp8_t; + +/* 16-bit fixed-point numeric type in user-defined format */ +typedef int16_t fxp16_t; + +/* 24-bit fixed-point numeric type in user-defined format */ +typedef int32_t fxp24_t; + +/* 32-bit fixed-point numeric type in user-defined format */ +typedef int32_t fxp32_t; + +/* 64-bit fixed-point numeric type in user-defined format */ +typedef int64_t fxp64_t; + +/* 8-bit fixed-point numeric type in 1.0.7 format */ +typedef fxp8_t q7_t; + +/* 16-bit fixed-point numeric type in 1.0.15 format */ +typedef fxp16_t q15_t; + +/* 32-bit fixed-point numeric type in 1.15.16 format */ +typedef fxp32_t q16_t; + +void csky_mca_rfft_fxp32(csky_mca_fft_len_t fft_len, const fxp32_t *input, size_t input_size, fxp32_t *output); +void csky_mca_cfft_fxp32(csky_mca_fft_len_t fft_len, const fxp32_t *input, fxp32_t *output); +void csky_mca_rifft_fxp32(csky_mca_fft_len_t fft_len, const fxp32_t *input, fxp32_t *output); +void csky_mca_cifft_fxp32(csky_mca_fft_len_t fft_len, const fxp32_t *input, fxp32_t *output); +void csky_mca_power_spectrum_fxp32(csky_mca_fft_len_t fft_len, const fxp32_t *input, size_t input_size, fxp64_t *output); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_FFT_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/gpio.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/gpio.h new file mode 100755 index 00000000..fb8aed65 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/gpio.h @@ -0,0 +1,214 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/gpio.h + * @brief Header File for GPIO Driver + * @version V1.0 + * @date 8. Apr 2020 + * @model gpio + ******************************************************************************/ + +#ifndef _DRV_GPIO_H_ +#define _DRV_GPIO_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \enum csi_gpio_dir_t + * \brief GPIO dir define + */ +typedef enum { + GPIO_DIRECTION_INPUT = 0, ///< GPIO as input + GPIO_DIRECTION_OUTPUT, ///< GPIO as output +} csi_gpio_dir_t; + +/** + * \enum csi_gpio_pin_state_t + * \brief GPIO pin state define + */ +typedef enum { + GPIO_PIN_LOW = 0, ///< GPIO low level + GPIO_PIN_HIGH, ///< GPIO high level +} csi_gpio_pin_state_t; + +/** + * \enum csi_gpio_mode_t + * \brief GPIO mode define + */ +typedef enum { + GPIO_MODE_PULLNONE = 0, ///< Pull none + GPIO_MODE_PULLUP, ///< Pull up for input + GPIO_MODE_PULLDOWN, ///< Pull down for input + GPIO_MODE_OPEN_DRAIN, ///< Open drain mode for output + GPIO_MODE_PUSH_PULL, ///< Push-pull mode for output +} csi_gpio_mode_t; + +/** + * \enum csi_gpio_irq_mode_t + * \brief GPIO irq triger type + */ +typedef enum { + GPIO_IRQ_MODE_RISING_EDGE = 0, ///< Interrupt mode for rising edge + GPIO_IRQ_MODE_FALLING_EDGE, ///< Interrupt mode for falling edge + GPIO_IRQ_MODE_BOTH_EDGE, ///< Interrupt mode for both edge + GPIO_IRQ_MODE_LOW_LEVEL, ///< Interrupt mode for low level + GPIO_IRQ_MODE_HIGH_LEVEL, ///< Interrupt mode for high level +} csi_gpio_irq_mode_t; + +/** + * \struct csi_gpio_t + * \brief GPIO control block + */ + +typedef struct csi_gpio csi_gpio_t; +struct csi_gpio { + csi_dev_t dev; ///< Hw-dev info + void (*callback)(csi_gpio_t *gpio, uint32_t pins, void *arg); ///< Call-back of gpio port + void *arg; ///< User param passed to callback + void *priv; ///< User private param +}; + +/** + \brief Initialize GPIO Port handle + \param[in] gpio GPIO port handle + \param[in] port_idx GPIO port index + \return Error code +*/ +csi_error_t csi_gpio_init(csi_gpio_t *gpio, uint32_t port_idx); + +/** + \brief De-initialize GPIO pin.stops operation + releases the software resources used by the gpio-pin + \param[in] gpio GPIO port handle + \return None +*/ +void csi_gpio_uninit(csi_gpio_t *gpio); + +/** + \brief Config pin direction + \param[in] gpio GPIO port handle + \param[in] pin_mask Pin mask need to be set + \param[in] dir \ref csi_gpio_dir_t + \return Error code +*/ +csi_error_t csi_gpio_dir(csi_gpio_t *gpio, uint32_t pin_mask, csi_gpio_dir_t dir); + +/** + \brief Config pin mode + If one of pins config error, then the rest of pins will not config, and function return CSI_ERROR + If one or more pin unsupport, function will return CSI_UNSUPPORT, but the other pin still configured + \param[in] gpio GPIO port handle + \param[in] pin_mask Pin mask need to be set + \param[in] mode \ref csi_gpio_mode_t + \return Error code +*/ +csi_error_t csi_gpio_mode(csi_gpio_t *gpio, uint32_t pin_mask, csi_gpio_mode_t mode); + +/** + \brief Config gpio irq params + \param[in] gpio GPIO port handle + \param[in] pin_mask Pin mask need to be set + \param[in] mode Interrupt trigger mode \ref csi_gpio_irq_mode_t + \return Error code +*/ +csi_error_t csi_gpio_irq_mode(csi_gpio_t *gpio, uint32_t pin_mask, csi_gpio_irq_mode_t mode); + +/** + \brief Enable or disable gpio pin interrupt + \param[in] gpio GPIO port handle + \param[in] pin_mask Pin mask need to be set + \param[in] enable 0:disable 1:enable + \return Error code +*/ +csi_error_t csi_gpio_irq_enable(csi_gpio_t *gpio, uint32_t pin_mask, bool enable); + +/** + \brief Set debounce of gpio when gpio configed as input + \param[in] gpio GPIO port handle + \param[in] pin_mask Pin mask need to be set + \param[in] enbale 0: disable 1:enable + \return Error code +*/ +csi_error_t csi_gpio_debounce(csi_gpio_t *gpio, uint32_t pin_mask, bool enable); +/** + \brief Set one or zero to the selected pin mask + \param[in] gpio GPIO port handle + \param[in] pin_mask Pin mask need to be set + \param[in] value Value to be set \ref csi_gpio_pin_state_t + \return None +*/ +void csi_gpio_write(csi_gpio_t *gpio, uint32_t pin_mask, csi_gpio_pin_state_t value); + +/** + \brief Toggle output gpio value,ex.if previous value is 1, then output 0 + \param[in] gpio GPIO port handle + \param[in] pin_mask Pin mask need to be set + \return None +*/ +void csi_gpio_toggle(csi_gpio_t *gpio, uint32_t pin_mask); + +/** + \brief Get the value of selected GPIO pin mask + \param[in] gpio GPIO port handle + \param[in] pin_mask Pin mask need to be set + \return According to the bit mask, the corresponding pin status is obtained +*/ +uint32_t csi_gpio_read(csi_gpio_t *gpio, uint32_t pin_mask); + +/** + \brief Attach the interrupt callback to the port + \param[in] gpio GPIO port handle + \param[in] callback Callback function + \param[in] arg User param passed to callback + \return Error code +*/ +csi_error_t csi_gpio_attach_callback(csi_gpio_t *gpio, void *callback, void *arg); + +/** + \brief Detach the interrupt callback to the port + \param[in] gpio GPIO port handle + \return None +*/ +void csi_gpio_detach_callback(csi_gpio_t *gpio); + +/** + \brief Enable gpio power manage + \param[in] gpio GPIO handle to operate + \return Error code +*/ +csi_error_t csi_gpio_enable_pm(csi_gpio_t *gpio); + +/** + \brief Disable gpio power manage + \param[in] gpio GPIO handle to operate + \return None +*/ +void csi_gpio_disable_pm(csi_gpio_t *gpio); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_GPIO_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/gpio_pin.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/gpio_pin.h new file mode 100755 index 00000000..1cb81fc3 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/gpio_pin.h @@ -0,0 +1,144 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/gpio_pin.h + * @brief Header File for GPIO PIN Driver + * @version v1.0 + * @date 2020-06-28 + * @note Only one of gpio or gpio_pin interface can be selected + ******************************************************************************/ + +#ifndef _DRV_GPIO_PIN_H_ +#define _DRV_GPIO_PIN_H_ + +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \struct csi_gpio_pin_t + * \brief GPIO PIN control block + */ + +typedef struct csi_gpio_pin csi_gpio_pin_t; +struct csi_gpio_pin { + csi_gpio_t *gpio; + uint32_t pin_idx; + void (*callback)(csi_gpio_pin_t *pin, void *arg); + void *arg; +}; + +/** + \brief Initialize GPIO pin handle + \param[in] pin GPIO pin handle + \param[in] pin_name GPIO pin name + \return Error code +*/ +csi_error_t csi_gpio_pin_init(csi_gpio_pin_t *pin, pin_name_t pin_name); + +/** + \brief De-initialize GPIO pin + \param[in] pin GPIO pin handle + \return None +*/ +void csi_gpio_pin_uninit(csi_gpio_pin_t *pin); + +/** + \brief Attach the interrupt callback to the GPIO pin + \param[in] pin GPIO pin handle + \param[in] callback Callback function + \param[in] arg User param passed to callback + \return Error code +*/ +csi_error_t csi_gpio_pin_attach_callback(csi_gpio_pin_t *pin, void *callback, void *arg); + +/** + \brief Config pin direction + \param[in] pin GPIO pin handle + \param[in] dir \ref csi_gpio_dir_t + \return Error code +*/ +csi_error_t csi_gpio_pin_dir(csi_gpio_pin_t *pin, csi_gpio_dir_t dir); + +/** + \brief Config pin mode + \param[in] pin GPIO pin handle + \param[in] mode \ref csi_gpio_mode_t + \return Error code +*/ +csi_error_t csi_gpio_pin_mode(csi_gpio_pin_t *pin, csi_gpio_mode_t mode); + +/** + \brief Config pin irq params + \param[in] pin GPIO pin handle + \param[in] mode Interrupt trigger mode \ref csi_gpio_irq_mode_t + \return Error code +*/ +csi_error_t csi_gpio_pin_irq_mode(csi_gpio_pin_t *pin, csi_gpio_irq_mode_t mode); + +/** + \brief Enable or disable gpio pin interrupt + \param[in] pin GPIO pin handle + \param[in] enable 0:disable 1:enable + \return Error code +*/ +csi_error_t csi_gpio_pin_irq_enable(csi_gpio_pin_t *pin, bool enable); + +/** + \brief Set debounce of pin when pin configed as input + \param[in] pin GPIO pin handle + \param[in] enbale 0: disable 1:enable + \return Error code +*/ +csi_error_t csi_gpio_pin_debounce(csi_gpio_pin_t *pin, bool enable); + +/** + \brief Set one or zero to specified pin + \param[in] pin GPIO pin handle + \param[in] value Value to be set \ref csi_gpio_pin_state_t + \return None +*/ +void csi_gpio_pin_write(csi_gpio_pin_t *pin, csi_gpio_pin_state_t value); + +/** + \brief Toggle output pin value,ex.if previous value is 1, then output 0 + \param[in] pin GPIO pin handle + \return None +*/ +void csi_gpio_pin_toggle(csi_gpio_pin_t *pin); + +/** + \brief Get the value of specified GPIO pin + \param[in] pin GPIO port handle + \return gpio pin state, \ref csi_gpio_pin_state_t +*/ +csi_gpio_pin_state_t csi_gpio_pin_read(csi_gpio_pin_t *pin); + +#ifdef __cplusplus +} +#endif + +#endif /* _GPIO_PIN_H_*/ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/hmac.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/hmac.h new file mode 100644 index 00000000..1033306e --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/hmac.h @@ -0,0 +1,122 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/hmac.h + * @brief Header File for HMAC + * @version V1.0 + * @date 27. Apri 2023 + * @model hmac + ******************************************************************************/ +#ifndef _DRV_HMAC_H_ +#define _DRV_HMAC_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/****** HMAC Event ******/ +typedef enum { + HMAC_EVENT_COMPLETE = 0U, /* Calculate completed */ + HMAC_EVENT_ERROR /* Calculate error */ +} csi_hmac_event_t; + +/****** HMAC Context ******/ +typedef struct { + csi_sha_mode_t mode; /* SHA mode */ + uint32_t total[2]; /* Number of bytes processed */ + uint8_t buffer[128]; /* Data block being processed */ +} csi_hmac_context_t; + +/****** HMAC Ctrl ******/ +typedef struct csi_hmac { + csi_dev_t dev; + void *priv; +}csi_hmac_t; + +/** + \brief Initialize MAC Interface. Initializes the resources needed for the MAC interface + \param[in] mac operate handle. + \param[in] idx index of mac + \return error code \ref csi_error_t +*/ +csi_error_t csi_hmac_init(csi_hmac_t *mac, uint32_t idx); + +/** + \brief De-initialize MAC Interface. stops operation and releases the software resources used by the interface + \param[in] mac mac handle to operate. + \return none +*/ +void csi_hmac_uninit(csi_hmac_t *mac); + +/** + \brief MAC set key function. + \param[in] mac mac handle to operate. + \param[in] key Pointer to the mac key. + \param[in] key_len Length of key. + \return error code \ref csi_error_t +*/ +csi_error_t csi_hmac_set_key(csi_hmac_t *mac, uint8_t *key, uint32_t key_len); + +/** + \brief MAC start operation function. + \param[in] mac mac handle to operate. + \param[in] context mac context pointer. + \param[in] mode sc_sha_mode_t. + \return error code \ref csi_error_t +*/ +csi_error_t csi_hmac_start(csi_hmac_t *mac, csi_hmac_context_t *context, csi_sha_mode_t mode); + +/** + \brief MAC start operation function. + \param[in] mac mac handle to operate. + \param[in] msg Pointer to the mac input message. + \param[in] msg_len Length of msg. + \return error code \ref csi_error_t +*/ +csi_error_t csi_hmac_update(csi_hmac_t *mac, csi_hmac_context_t *context, uint8_t *msg, uint32_t msg_len); + +/** + \brief MAC start operation function. + \param[in] mac mac handle to operate. + \param[out] out mac buffer, malloc by caller. + \param[out] out_len out mac length, + \return error code \ref csi_error_t +*/ +csi_error_t csi_hmac_finish(csi_hmac_t *mac, csi_hmac_context_t *context, uint8_t *out, uint32_t *out_len); + +/** + \brief MAC cacl operation function. + \param[in] mac mac handle to operate. + \param[in] mode sc_sha_mode_t. + \param[in] msg Pointer to the mac input message. + \param[in] msg_len Length of msg. + \param[out] out mac buffer, malloc by caller. + \param[out] out_len out mac length, + \return error code \ref csi_error_t +*/ +csi_error_t csi_hmac_calc(csi_hmac_t *mac, csi_sha_mode_t mode, uint8_t *msg, + uint32_t msg_len, uint8_t *out, uint32_t *out_len); +#ifdef __cplusplus +} +#endif + +#endif /* _SC_MAC_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/i2s.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/i2s.h new file mode 100755 index 00000000..f783d21d --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/i2s.h @@ -0,0 +1,397 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/i2s.h + * @brief header file for i2s driver + * @version V1.0 + * @date 16. Mar 2020 + * @model i2s + ******************************************************************************/ + +#ifndef _DRV_I2S_H_ +#define _DRV_I2S_H_ + +#include +#include +#include +#include +#include "drv/ringbuf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + I2S_MODE_MASTER, ///< I2s transmitter master mode + I2S_MODE_SLAVE, ///< I2s transmitter slave mode +} csi_i2s_mode_t; + +typedef enum { + I2S_PROTOCOL_I2S, ///< I2S protocol + I2S_PROTOCOL_MSB_JUSTIFIED, ///< MSB (left) justified protocol + I2S_PROTOCOL_LSB_JUSTIFIED, ///< LSB (right) justified protocol + I2S_PROTOCOL_PCM, ///< PCM protocol +} csi_i2s_protocol_t; + +typedef enum { + I2S_LEFT_POLARITY_LOW, ///< Low level represents the left channel + I2S_LEFT_POLARITY_HIGH, ///< High level represents the left channel +} csi_i2s_ws_left_polarity_t; + +typedef enum { + I2S_SAMPLE_RATE_8000 = 8000U, ///< I2S sample rate is 8000 + I2S_SAMPLE_RATE_11025 = 11025U, + I2S_SAMPLE_RATE_12000 = 12000U, + I2S_SAMPLE_RATE_16000 = 16000U, + I2S_SAMPLE_RATE_22050 = 22050U, + I2S_SAMPLE_RATE_24000 = 24000U, + I2S_SAMPLE_RATE_32000 = 32000U, + I2S_SAMPLE_RATE_44100 = 44100U, + I2S_SAMPLE_RATE_48000 = 48000U, + I2S_SAMPLE_RATE_96000 = 96000U, + I2S_SAMPLE_RATE_192000 = 192000U, + I2S_SAMPLE_RATE_256000 = 256000U, +} csi_i2s_sample_rate_t; + +typedef enum { + I2S_SAMPLE_WIDTH_16BIT = 16U, ///< I2S sample width is 16bit + I2S_SAMPLE_WIDTH_24BIT = 24U, + I2S_SAMPLE_WIDTH_32BIT = 32U, +} csi_i2s_sample_width_t; + +typedef enum { + I2S_SCLK_16FS = 16U, ///< SCLK frequency is 16 times that of I2S sample rate + I2S_SCLK_32FS = 32U, + I2S_SCLK_48FS = 48U, + I2S_SCLK_64FS = 64U, +} csi_i2s_sclk_freq_t; + +typedef enum { + I2S_MCLK_256FS = 256U, ///< MCLK frequency is 256 times that of I2S sample rate + I2S_MCLK_384FS = 384U, +} csi_i2s_mclk_freq_t; + +typedef struct { + csi_i2s_mode_t mode; ///< I2S work mode + csi_i2s_protocol_t protocol; ///< Protocols used by I2S + csi_i2s_ws_left_polarity_t polarity; ///< left channel polarity + csi_i2s_sample_rate_t rate; ///< I2S sample rate + csi_i2s_sample_width_t width; ///< I2S sample width + csi_i2s_sclk_freq_t sclk_nfs; ///< SCLK frequency is N times that of I2S sample rate + csi_i2s_mclk_freq_t mclk_nfs; ///< MCLK frequency is N times that of I2S sample rate +} csi_i2s_format_t; + +typedef enum { + I2S_LEFT_CHANNEL, + I2S_RIGHT_CHANNEL, + I2S_LEFT_RIGHT_CHANNEL, +} csi_i2s_sound_channel_t; + +typedef enum { + I2S_EVENT_SEND_COMPLETE, + I2S_EVENT_RECEIVE_COMPLETE, + I2S_EVENT_TX_BUFFER_EMPTY, + I2S_EVENT_RX_BUFFER_FULL, + I2S_EVENT_ERROR_OVERFLOW, + I2S_EVENT_ERROR_UNDERFLOW, + I2S_EVENT_ERROR, +} csi_i2s_event_t; + +typedef struct csi_i2s csi_i2s_t; + +struct csi_i2s { + csi_dev_t dev; ///< I2S hw-device info + void (*callback)(csi_i2s_t *i2s, csi_i2s_event_t event, void *arg); ///< I2S event callback for user + void *arg; ///< user private param passed to user callback + csi_ringbuf_t *tx_buf; ///< I2S send buffer + csi_ringbuf_t *rx_buf; ///< I2S receive buffer + csi_dma_ch_t *tx_dma; ///< send dma channel handle + csi_dma_ch_t *rx_dma; ///< receive dma channel handle + uint32_t tx_period; ///< I2S send period num data will callback + uint32_t rx_period; ///< I2S receive period num data will callback + csi_state_t state; ///< I2S communication state + void *priv; +}; + +/** + \brief Init i2s + \param[in] i2s I2s handle to operate + \param[in] idx I2s interface idx + \return error code \ref csi_error_t +*/ +csi_error_t csi_i2s_init(csi_i2s_t *i2s, uint32_t idx); + +/** + \brief Uninit i2s + \param[in] i2s I2s handle to operate + \return none +*/ +void csi_i2s_uninit(csi_i2s_t *i2s); + +/** + \brief Enable i2s + \param[in] i2s I2s handle to operate + \param[in] en True enable, False disable + \return None +*/ +void csi_i2s_enable(csi_i2s_t *i2s, bool enable); + +/** + \brief I2s config format + \param[in] i2s I2s handle to operate + \param[in] format I2s config param \ref csi_i2s_format_t + \return error code \ref csi_error_t +*/ +csi_error_t csi_i2s_format(csi_i2s_t *i2s, csi_i2s_format_t *format); + +/** + \brief Set the i2s tx mono + \param[in] i2s I2s handle to operate + \param[in] ch Mono channel selection + \return error code \ref csi_error_t +*/ +csi_error_t csi_i2s_tx_select_sound_channel(csi_i2s_t *i2s, csi_i2s_sound_channel_t ch); + +/** + \brief Set the i2s rx mono + \param[in] i2s I2s handle to operate + \param[in] ch Mono channel selection + \return error code \ref csi_error_t +*/ +csi_error_t csi_i2s_rx_select_sound_channel(csi_i2s_t *i2s, csi_i2s_sound_channel_t ch); + +/** + \brief Link DMA channel to i2s device + \param[in] i2s I2s handle to operate + \param[in] rx_dma The DMA channel for receive, when it is NULL means to unused dma + \return error code \ref csi_error_t +*/ +csi_error_t csi_i2s_rx_link_dma(csi_i2s_t *i2s, csi_dma_ch_t *rx_dma); + +/** + \brief Link DMA channel to i2s device + \param[in] i2s I2s handle to operate + \param[in] tx_dma The DMA channel for send, when it is NULL means to unused dma + \return error code \ref csi_error_t +*/ +csi_error_t csi_i2s_tx_link_dma(csi_i2s_t *i2s, csi_dma_ch_t *tx_dma); + +/** + \brief I2s rx buffer config + \param[in] i2s I2s handle to operate + \param[in] buffer I2s rx buffer + \return None +*/ +void csi_i2s_rx_set_buffer(csi_i2s_t *i2s, csi_ringbuf_t *buffer); + +/** + \brief I2s tx buffer config + \param[in] i2s I2s handle to operate + \param[in] buffer I2s tx buffer + \return None +*/ +void csi_i2s_tx_set_buffer(csi_i2s_t *i2s, csi_ringbuf_t *buffer); + +/** + \brief I2s rx set period.The value of period is to report a receive completion event + after each period value data is received + \param[in] i2s I2s handle to operate + \param[in] period I2s rx period + \return error code \ref csi_error_t +*/ +csi_error_t csi_i2s_rx_set_period(csi_i2s_t *i2s, uint32_t period); + +/** + \brief I2s tx set period.The value of period is to report a receive completion event + after each period value data is send + \param[in] i2s I2s handle to operate + \param[in] period I2s tx period + \return error code \ref csi_error_t +*/ +csi_error_t csi_i2s_tx_set_period(csi_i2s_t *i2s, uint32_t period); + +/** + \brief Get rx csi_ringbuf buffer free space + \param[in] i2s I2s handle to operate + \return Buffer free space (bytes) +*/ +uint32_t csi_i2s_rx_buffer_avail(csi_i2s_t *i2s); + +/** + \brief Get rx csi_ringbuf buffer used space + \param[in] i2s I2s handle to operate + \return Buffer used space (bytes) +*/ +uint32_t csi_i2s_rx_buffer_remain(csi_i2s_t *i2s); + +/** + \brief Reset the rx csi_ringbuf, discard all data in the buffer + \param[in] i2s I2s handle to operate + \return error code \ref csi_error_t +*/ +csi_error_t csi_i2s_rx_buffer_reset(csi_i2s_t *i2s); + +/** + \brief Get tx csi_ringbuf buffer free space + \param[in] i2s I2s handle to operate + \return Buffer free space (bytes) +*/ +uint32_t csi_i2s_tx_buffer_avail(csi_i2s_t *i2s); + +/** + \brief Get tx csi_ringbuf buffer used space + \param[in] i2s I2s handle to operate + \return Buffer used space (bytes) +*/ +uint32_t csi_i2s_tx_buffer_remain(csi_i2s_t *i2s); + +/** + \brief Reset the tx csi_ringbuf, discard all data in the buffer + \param[in] i2s Handle to operate + \return error code \ref csi_error_t +*/ +csi_error_t csi_i2s_tx_buffer_reset(csi_i2s_t *i2s); + +/** + \brief Send an amount of data to buffer in blocking mode + \param[in] i2s Operate handle + \param[in] data Pointer to send data buffer + \param[in] size Send data size + \return The num of data witch is send successful +*/ +int32_t csi_i2s_send(csi_i2s_t *i2s, const void *data, uint32_t size); + +/** + \brief Receive an amount of data to buffer in blocking mode + \param[in] i2s Operate handle + \param[out] data Pointer to receive data buffer + \param[in] size Receive data size + \return The size of data receive successfully +*/ +int32_t csi_i2s_receive(csi_i2s_t *i2s, void *data, uint32_t size); + +/** + \brief Write data to the buffer + With asynchronous sending + The data is first written to the buffer and then output through the i2s interface + Return value is the number of data that was successfully written to the buffer + \param[in] i2s Operate handle + \param[in] data Pointer to send data buffer + \param[in] size Send data size + \return The data size that write to buffer +*/ +uint32_t csi_i2s_send_async(csi_i2s_t *i2s, const void *data, uint32_t size); + +/** + \brief Read data from the buffer + Using asynchronous receive, i2s writes the received data to the buffer + This function reads data from the buffer, returns the number of successful reads + Returns 0 if there is no data in the buffer + \param[in] i2s Operate handle + \param[out] data Pointer to receive data buffer + \param[in] size Receive data size + \return The size of data read successfully +*/ +uint32_t csi_i2s_receive_async(csi_i2s_t *i2s, void *data, uint32_t size); + +/** + \brief Start i2s pause asynchronous send + \param[in] i2s Operate handle + \return error code \ref csi_error_t +*/ +csi_error_t csi_i2s_send_pause(csi_i2s_t *i2s); + +/** + \brief Start i2s resume asynchronous send + \param[in] i2s Operate handle + \return error code \ref csi_error_t +*/ +csi_error_t csi_i2s_send_resume(csi_i2s_t *i2s); + +/** + \brief Start i2s asynchronous send + \param[in] i2s Operate handle + \return error code \ref csi_error_t +*/ +csi_error_t csi_i2s_send_start(csi_i2s_t *i2s); + +/** + \brief Start i2s asynchronous receive + \param[in] i2s Operate handle + \return error code \ref csi_error_t +*/ +csi_error_t csi_i2s_receive_start(csi_i2s_t *i2s); + +/** + \brief Stop i2s asynchronous send + \param[in] i2s Operate handle + \return None +*/ +void csi_i2s_send_stop(csi_i2s_t *i2s); + +/** + \brief Stop i2s asynchronous receive + \param[in] i2s Operate handle + \return None +*/ +void csi_i2s_receive_stop(csi_i2s_t *i2s); + +/** + \brief Attach the callback handler to i2s + \param[in] i2s Operate handle + \param[in] cb Callback function + \param[in] arg User private param + \return error code \ref csi_error_t +*/ +csi_error_t csi_i2s_attach_callback(csi_i2s_t *i2s, void *callback, void *arg); + +/** + \brief Detach the callback handler + \param[in] i2s Operate handle + \return None +*/ +void csi_i2s_detach_callback(csi_i2s_t *i2s); + +/** + \brief Get i2s status + \param[in] i2s I2s handle to operate + \param[out] state I2s state + \return error code \ref csi_error_t +*/ +csi_error_t csi_i2s_get_state(csi_i2s_t *i2s, csi_state_t *state); + +/** + \brief Enable i2s power manage + \param[in] i2s I2s handle to operate + \return error code \ref csi_error_t +*/ +csi_error_t csi_i2s_enable_pm(csi_i2s_t *i2s); + +/** + \brief Disable i2s power manage + \param[in] i2s I2s handle to operate + \return None +*/ +void csi_i2s_disable_pm(csi_i2s_t *i2s); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_I2S_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/iic.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/iic.h new file mode 100755 index 00000000..ee46ea22 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/iic.h @@ -0,0 +1,338 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 iic.h + * @brief header file for iic driver + * @version V1.0 + * @date 08. Apr 2020 + * @model iic + ******************************************************************************/ + +#ifndef _DRV_IIC_H_ +#define _DRV_IIC_H_ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + \enum csi_iic_mode_t + \brief iic work in master/slave mode + */ +typedef enum { + IIC_MODE_MASTER = 0U, ///< IIC master + IIC_MODE_SLAVE ///< IIC slave +} csi_iic_mode_t; + +/** + \enum csi_iic_speed_t + \brief iic speed mode + */ +typedef enum { + IIC_BUS_SPEED_STANDARD = 0U, ///< Standard Speed (<=100kHz) + IIC_BUS_SPEED_FAST, ///< Fast Speed (<=400kHz) + IIC_BUS_SPEED_FAST_PLUS, ///< Fast plus Speed (<= 1MHz) + IIC_BUS_SPEED_HIGH ///< High Speed (<=3.4MHz) +} csi_iic_speed_t; + +/** + \enum csi_iic_address_mode_t + \brief iic address mode + */ +typedef enum { + IIC_ADDRESS_7BIT = 0U, ///< 7-bit address mode + IIC_ADDRESS_10BIT ///< 10-bit address mode +} csi_iic_addr_mode_t; + +/** + \enum csi_iic_mem_addr_size_t + \brief iic memory address size + */ +typedef enum { + IIC_MEM_ADDR_SIZE_8BIT = 0U, ///< IIC e2prom 8bit address mode + IIC_MEM_ADDR_SIZE_16BIT ///< IIC e2prom 16bit address mode +} csi_iic_mem_addr_size_t; + +/** + \enum csi_iic_event_t + \brief iic event signaled by iic driver + */ +typedef enum { + IIC_EVENT_SEND_COMPLETE = 0U, ///< Master/slave Send finished + IIC_EVENT_RECEIVE_COMPLETE, ///< Master/slave Receive finished + IIC_EVENT_ERROR_OVERFLOW, ///< Master/slave fifo overflow error + IIC_EVENT_ERROR_UNDERFLOW, ///< Master/slave fifo underflow error + IIC_EVENT_ERROR ///< The receive buffer was completely filled to FIFO and more data arrived. That data is lost +} csi_iic_event_t; + +/** + \struct csi_iic_t + \brief iic ctrl block + */ +typedef struct csi_iic csi_iic_t; +struct csi_iic { + csi_dev_t dev; ///< IIC hw-device info + void (*callback)(csi_iic_t *iic, csi_iic_event_t event, void *arg); ///< IIC event callback for user + void *arg; ///< User private param passed to user callback + uint8_t *data; ///< IIC transfer-data buffer + uint32_t size; ///< IIC transfer-data size + csi_iic_mode_t mode; ///< IIC mode + csi_dma_ch_t *tx_dma; ///< Send dma channel handle + csi_dma_ch_t *rx_dma; ///< Receive dma channel handle + void *send; ///< Send function pointer asynchronously + void *receive; ///< Receive function pointer asynchronously + csi_state_t state; ///< IIC current state + void *priv; +}; + +typedef csi_error_t (*csi_iic_master_send_async_t)(csi_iic_t *iic, uint32_t devaddr, const void *data, uint32_t size); +typedef csi_error_t (*csi_iic_master_receive_async_t)(csi_iic_t *iic, uint32_t devaddr, void *data, uint32_t size); +typedef csi_error_t (*csi_iic_slave_send_async_t)(csi_iic_t *iic, const void *data, uint32_t size); +typedef csi_error_t (*csi_iic_slave_receive_async_t)(csi_iic_t *iic, void *data, uint32_t size); + +/** + \brief Init iic ctrl block + Initializes the resources needed for the iic instance + \param[in] iic Handle of iic instance + \param[in] idx Index of instance + \return error code \ref csi_error_t +*/ +csi_error_t csi_iic_init(csi_iic_t *iic, uint32_t idx); + +/** + \brief Uninit iic ctrl block + Stops operation and releases the software resources used by the instance + \param[in] iic Handle of iic instance + \return None +*/ +void csi_iic_uninit(csi_iic_t *iic); + +/** + \brief Config iic master or slave mode + \param[in] iic Handle of iic instance + \param[in] mode iic mode \ref csi_iic_mode_t + \return error code \ref csi_error_t +*/ +csi_error_t csi_iic_mode(csi_iic_t *iic, csi_iic_mode_t mode); + +/** + \brief Config iic addr mode + \param[in] iic Handle of iic instance + \param[in] addr_mode iic addr mode \ref csi_iic_addr_mode_t + \return error code \ref csi_error_t +*/ +csi_error_t csi_iic_addr_mode(csi_iic_t *iic, csi_iic_addr_mode_t addr_mode); + +/** + \brief Config iic speed + \param[in] iic Handle of iic instance + \param[in] speed iic speed mode \ref csi_iic_speed_t + \return error code \ref csi_error_t +*/ +csi_error_t csi_iic_speed(csi_iic_t *iic, csi_iic_speed_t speed); + +/** + \brief Config iic own addr + \param[in] iic Handle of iic instance + \param[in] own_addr iic set own addr at slave mode + \return error code \ref csi_error_t +*/ +csi_error_t csi_iic_own_addr(csi_iic_t *iic, uint32_t own_addr); + +/** + \brief Start sending data as iic master + This function is blocking + \param[in] iic Handle of iic instance + \param[in] devaddr Addrress of slave device + \param[in] data Pointer to send data buffer + \param[in] size Size of data items to send + \param[in] timout Unit of time delay(ms) + \return The amount of real data sent or error code +*/ +int32_t csi_iic_master_send(csi_iic_t *iic, uint32_t devaddr, const void *data, uint32_t size, uint32_t timeout); + +/** + \brief Start receiving data as iic master + This function is blocking + \param[in] iic Handle to operate + \param[in] devaddr iic addrress of slave device + \param[out] data Pointer to buffer for data to receive from iic receiver + \param[in] size Size of data items to receive + \param[in] timeout Unit of time delay(ms) + \return The amount of real data received or error code +*/ +int32_t csi_iic_master_receive(csi_iic_t *iic, uint32_t devaddr, void *data, uint32_t size, uint32_t timeout); + +/** + \brief Start sending data as iic master + This function is non-blocking,\ref csi_iic_event_t is signaled when transfer completes or error happens + \param[in] iic Handle to operate + \param[in] devaddr iic addrress of slave device + \param[in] data Pointer to send data buffer + \param[in] size Size of data items to send + \return error code \ref csi_error_t +*/ +csi_error_t csi_iic_master_send_async(csi_iic_t *iic, uint32_t devaddr, const void *data, uint32_t size); + +/** + \brief Start receiving data as iic master. + This function is non-blocking.\ref csi_iic_event_t is signaled when transfer completes or error happens + \param[in] iic Handle to operate + \param[in] devaddr iic addrress of slave device + \param[out] data Pointer to buffer for data to receive from iic receiver + \param[in] size Size of data items to receive + \return error code \ref csi_error_t +*/ +csi_error_t csi_iic_master_receive_async(csi_iic_t *iic, uint32_t devaddr, void *data, uint32_t size); + +/** + \brief Start sending data as iic master + This function is blocking + \param[in] iic Handle of iic instance + \param[in] devaddr Addrress of slave device + \param[in] memaddr Internal addr of device + \param[in] memaddr_size Internal addr mode of device + \param[in] data Pointer to send data buffer + \param[in] size Size of data items to send + \param[in] timout Unit of time delay(ms) + \return The amount of real data sent or error code +*/ +int32_t csi_iic_mem_send(csi_iic_t *iic, uint32_t devaddr, uint16_t memaddr, csi_iic_mem_addr_size_t memaddr_size, const void *data, uint32_t size, uint32_t timeout); + +/** + \brief Start receiving data as iic master + This function is blocking + \param[in] iic Handle to operate + \param[in] devaddr iic addrress of slave device + \param[in] memaddr Internal addr of device + \param[in] memaddr_mode Internal addr mode of device + \param[out] data Pointer to buffer for data to receive from eeprom device + \param[in] size Size of data items to receive + \param[in] timeout Unit of time delay(ms) + \return The amount of real data received or error code +*/ +int32_t csi_iic_mem_receive(csi_iic_t *iic, uint32_t devaddr, uint16_t memaddr, csi_iic_mem_addr_size_t memaddr_size, void *data, uint32_t size, uint32_t timeout); + +/** + \brief Start sending data as iic slave + This function is blocking + \param[in] iic Handle to operate + \param[in] data Pointer to buffer with data to send to iic master + \param[in] size Size of data items to send + \param[in] timeout Unit of time delay(ms) + \return The amount of real data sent or error code +*/ +int32_t csi_iic_slave_send(csi_iic_t *iic, const void *data, uint32_t size, uint32_t timeout); + +/** + \brief Start receiving data as iic slave + This function is blocking + \param[in] iic Handle to operate + \param[out] data Pointer to buffer for data to receive from iic master + \param[in] size Size of data items to receive + \param[in] timeout Unit of time delay(ms) + \return The amount of real data received or error code +*/ +int32_t csi_iic_slave_receive(csi_iic_t *iic, void *data, uint32_t size, uint32_t timeout); + +/** + \brief Start sending data as iic slave + This function is non-blocking,\ref csi_iic_event_t is signaled when transfer completes or error happens + \param[in] iic Handle to operate + \param[in] data Pointer to buffer with data to send to iic master + \param[in] size Size of data items to send + \return error code \ref csi_error_t +*/ +csi_error_t csi_iic_slave_send_async(csi_iic_t *iic, const void *data, uint32_t size); + +/** + \brief Start receiving data as iic slave + This function is non-blocking,\ref csi_iic_event_t is signaled when transfer completes or error happens + \param[in] handle iic handle to operate + \param[out] data Pointer to buffer for data to receive from iic master + \param[in] size Size of data items to receive + \return error code \ref csi_error_t +*/ +csi_error_t csi_iic_slave_receive_async(csi_iic_t *iic, void *data, uint32_t size); + +/** + \brief Attach callback to the iic + \param[in] iic iic handle to operate + \param[in] cb Event callback function \ref csi_iic_callback_t + \param[in] arg User private param for event callback + \return error code \ref csi_error_t +*/ +csi_error_t csi_iic_attach_callback(csi_iic_t *iic, void *callback, void *arg); + +/** + \brief Detach callback from the iic + \param[in] iic iic handle to operate + \return None +*/ +void csi_iic_detach_callback(csi_iic_t *iic); + +/** + \brief Config iic stop to generate + \param[in] iic iic handle to operate + \param[in] enable Transfer operation is pending - stop condition will not be generated + \return error code \ref csi_error_t +*/ +csi_error_t csi_iic_xfer_pending(csi_iic_t *iic, bool enable); + +/** + \brief Link DMA channel to iic device + \param[in] iic Handle to operate + \param[in] tx_dma The DMA channel handle for send, when it is NULL means to unlink the channel + \param[in] rx_dma The DMA channel handle for receive, when it is NULL means to unlink the channel + \return error code \ref csi_error_t +*/ +csi_error_t csi_iic_link_dma(csi_iic_t *iic, csi_dma_ch_t *tx_dma, csi_dma_ch_t *rx_dma); + +/** + \brief Get iic state + \param[in] iic Handle to operate + \param[out] state iic state \ref csi_state_t + \return error code \ref csi_error_t +*/ +csi_error_t csi_iic_get_state(csi_iic_t *iic, csi_state_t *state); + +/** + \brief Enable iic power manage + \param[in] iic iic handle to operate + \return error code \ref csi_error_t +*/ +csi_error_t csi_iic_enable_pm(csi_iic_t *iic); + +/** + \brief Disable iic power manage + \param[in] iic iic handle to operate + \return None +*/ +void csi_iic_disable_pm(csi_iic_t *iic); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_IIC_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/intc.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/intc.h new file mode 100755 index 00000000..573f33eb --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/intc.h @@ -0,0 +1,178 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/intc.h + * @brief Header File for INTC Driver + * @version V1.0 + * @date 02. June 2020 + * @model intc + ******************************************************************************/ + +#ifndef _DRV_INTC_H_ +#define _DRV_INTC_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +typedef enum int_trigger_mode_t { + INT_MODE_LOW_LEVEL, + INT_MODE_HIGH_LEVEL, + INT_MODE_RISING_EDGE, + INT_MODE_FALLING_EDGE, + INT_MODE_DOUBLE_EDGE, +} int_trigger_mode_t; + +/** + \brief Initialize the INTC interrupt controller + */ +void csi_intc_init(void); + +/** + \brief Enable External Interrupt + \details Enables a device-specific interrupt in the INTC interrupt controller. + \param[in] IRQn External interrupt number. Value cannot be negative. + */ +void csi_intc_enable_irq(int32_t IRQn); + +/** + \brief Disable External Interrupt + \details Disables a device-specific interrupt in the INTC interrupt controller. + \param[in] IRQn External interrupt number. Value cannot be negative. + */ +void csi_intc_disable_irq(int32_t IRQn); + +/** + \brief Get Pending Interrupt + \details Reads the pending register in the INTC and returns the pending bit for the specified interrupt. + \param[in] IRQn Interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +uint32_t csi_intc_get_pending_irq(int32_t IRQn); + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of an external interrupt. + \param[in] IRQn Interrupt number. Value cannot be negative. + */ +void csi_intc_set_pending_irq(int32_t IRQn); + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of an external interrupt. + \param[in] IRQn External interrupt number. Value cannot be negative. + */ +void csi_intc_clear_pending_irq(int32_t IRQn); + +/** + \brief Get Wake up Interrupt + \details Reads the wake up register in the INTC and returns the pending bit for the specified interrupt. + \param[in] IRQn Interrupt number. + \return 0 Interrupt is not set as wake up interrupt. + \return 1 Interrupt is set as wake up interrupt. + */ +uint32_t csi_intc_get_wakeup_irq(int32_t IRQn); + +/** + \brief Set Wake up Interrupt + \details Sets the wake up bit of an external interrupt. + \param[in] IRQn Interrupt number. Value cannot be negative. + */ +void csi_intc_set_wakeup_irq(int32_t IRQn); + +/** + \brief Clear Wake up Interrupt + \details Clears the wake up bit of an external interrupt. + \param[in] IRQn External interrupt number. Value cannot be negative. + */ +void csi_intc_clear_wakeup_irq(int32_t IRQn); + +/** + \brief Get Active Interrupt + \details Reads the active register in the INTC and returns the active bit for the device specific interrupt. + \param[in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +uint32_t csi_intc_get_active(int32_t IRQn); + +/** + \brief Set Threshold register + \details set the threshold register in the INTC. + \param[in] VectThreshold specific vecter threshold. + \param[in] PrioThreshold specific priority threshold. + */ +void csi_intc_set_threshold(uint32_t VectThreshold, uint32_t PrioThreshold); + +/** + \brief Set Interrupt Priority + \details Sets the priority of an interrupt. + \note The priority cannot be set for every core interrupt. + \param[in] IRQn Interrupt number. + \param[in] priority Priority to set. + */ +void csi_intc_set_prio(int32_t IRQn, uint32_t priority); + +/** + \brief Get Interrupt Priority + \details Reads the priority of an interrupt. + The interrupt number can be positive to specify an external (device specific) interrupt, + or negative to specify an internal (core) interrupt. + \param[in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +uint32_t csi_intc_get_prio(int32_t IRQn); + +/** + \brief funciton is acknowledge the IRQ. this interface is internally used by irq system + \param[in] irq irq number to operate + \return 0 on success; -1 on failure + */ +int csi_intc_ack_irq(int32_t IRQn); + +/** + \brief This function is set the attributes of an IRQ. + \param[in] irq irq number to operate + \param[in] priority interrupt priority + \param[in] trigger_mode interrupt trigger_mode + \return 0 on success; -1 on failure +*/ +int csi_intc_set_attribute(int32_t IRQn, uint32_t priority, int_trigger_mode_t trigger_mode); + +/** + \brief Set interrupt handler + \details Set the interrupt handler according to the interrupt num, the handler will be filled in g_irqvector[]. + \param[in] IRQn Interrupt number. + \param[in] handler Interrupt handler. + */ +void csi_intc_set_vector(int32_t IRQn, uint32_t handler); + +/** + \brief Get interrupt handler + \details Get the address of interrupt handler function. + \param[in] IRQn Interrupt number. + */ +uint32_t csi_intc_get_vector(int32_t IRQn); + +#endif /* _DRV_INTC_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/io.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/io.h new file mode 100755 index 00000000..5b970c33 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/io.h @@ -0,0 +1,131 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/io.h + * @brief Header File for register bits operation + * @version V1.0 + * @date 9. Oct 2020 + * @model io + ******************************************************************************/ + +#ifndef _DRV_IO_H_ +#define _DRV_IO_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Bit field operate*/ +#define REG64(addr) (*(volatile uint64_t *)(addr)) +#define REG32(addr) (*(volatile uint32_t *)(addr)) +#define REG16(addr) (*(volatile uint16_t *)(addr)) +#define REG8(addr) (*(volatile uint8_t *)(addr)) + +/* Insert value to some field in reg, other field is set to 0(the field make macro) */ +#define HAL_FMK(PER_REG_FIELD, val) \ + (((val) << PER_REG_FIELD##_SHIFT) & PER_REG_FIELD##_MASK) + +/* Get value of some field in reg(the field extract macro) */ +#define HAL_FEXT(reg, PER_REG_FIELD) \ + (((reg) & PER_REG_FIELD##_MASK) >> PER_REG_FIELD##_SHIFT) + +/* Insert value to some field in reg, other field don't change(the field insert macro) */ +#define HAL_FINS(reg, PER_REG_FIELD, val) \ + ((reg) = ((reg) & ~PER_REG_FIELD##_MASK) \ + | HAL_FMK(PER_REG_FIELD, val)) + + +/* Bit operate */ +/* Set one value to 1, other bit don't change*/ +#define HAL_BIT_SET(reg, bit) ((reg) = ((reg) | (1U << (bit)))) + +/* Set one value to 0, other bit don't change*/ +#define HAL_BIT_CLR(reg, bit) ((reg) = ((reg) & (~(1U << (bit))))) + +/* Get value of one bit(0/1) */ +#define HAL_GET_BIT_VAL(reg, bit) (((reg)>> (bit)) & 1U) + +/* Judge one bit is 1 or not */ +#define HAL_IS_BIT_SET(reg, pos) (((reg) & (1U << (pos))) != 0x0U) + +/* Judge one bit is 0 or not */ +#define HAL_IS_BIT_CLR(reg, pos) (((reg) & (1U << (pos))) == 0x0U) + +/* Set one value to bit, other bit don't change*/ +#define HAL_BIT_INSR(reg, bit, val) \ + ((reg) = (((reg) & (~(1U << (bit)))) | (((val) & 1U) << (bit)))) + + +static inline uint8_t getreg8(volatile void *addr) +{ + return *(volatile uint8_t *)addr; +} + +static inline void putreg8(uint8_t val, volatile void *addr) +{ + *(volatile uint8_t *)addr = val; +} + +static inline uint16_t getreg16(volatile void *addr) +{ + return *(volatile uint16_t *)addr; +} + +static inline void putreg16(uint16_t val, volatile void *addr) +{ + *(volatile uint16_t *)addr = val; +} + +static inline uint32_t getreg32(volatile void *addr) +{ + return *(volatile uint32_t *)addr; +} + +static inline void putreg32(uint32_t val, volatile void *addr) +{ + *(volatile uint32_t *)addr = val; +} + +static inline uint64_t getreg64(volatile void *addr) +{ + return *(volatile uint64_t *)addr; +} + +static inline void putreg64(uint32_t val, volatile void *addr) +{ + *(volatile uint64_t *)addr = val; +} + +static inline uint32_t inl(void *addr) +{ + return *(volatile uint32_t *)addr; +} + +static inline void outl(uint32_t val, void *addr) +{ + *(volatile uint32_t *)addr = val; +} + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_IO_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/irq.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/irq.h new file mode 100755 index 00000000..6272d15b --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/irq.h @@ -0,0 +1,149 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/irq.h + * @brief header File for IRQ Driver + * @version V1.0 + * @date 16. Mar 2020 + * @model irq + ******************************************************************************/ + +#ifndef _DRV_IRQ_H_ +#define _DRV_IRQ_H_ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + \brief Enable irq. + \param[in] irq_num Number of IRQ. + \return None. +*/ +__ALWAYS_STATIC_INLINE void csi_irq_enable(uint32_t irq_num) +{ + extern void soc_irq_enable(uint32_t irq_num); + soc_irq_enable(irq_num); +} + +/** + \brief Disable irq. + \param[in] irq_num Number of IRQ. + \return None. +*/ +__ALWAYS_STATIC_INLINE void csi_irq_disable(uint32_t irq_num) +{ + extern void soc_irq_disable(uint32_t irq_num); + soc_irq_disable(irq_num); +} + +/** + \brief Attach irq handler. + \param[in] irq_num Number of IRQ. + \param[in] irq_handler IRQ Handler. + \param[in] dev The dev to operate + \return None. +*/ +void csi_irq_attach(uint32_t irq_num, void *irq_handler, csi_dev_t *dev); + +/** + \brief Attach irq handler2 for compatible. + \param[in] irq_num Number of IRQ. + \param[in] irq_handler2 IRQ Handler. + \param[in] dev The dev to operate + \param[in] arg user data of irq_handler2 + \return None. +*/ +void csi_irq_attach2(uint32_t irq_num, void *irq_handler2, csi_dev_t *dev, void *arg); + +/** + \brief detach irq handler. + \param[in] irq_num Number of IRQ. + \param[in] irq_handler IRQ Handler. + \return None. +*/ +void csi_irq_detach(uint32_t irq_num); + +/** + \brief Set irq priority + \param[in] irq_num Number of IRQ. + \param[in] priority IRQ Priority. + \return None. +*/ +__ALWAYS_STATIC_INLINE void csi_irq_priority(uint32_t irq_num, uint32_t priority) +{ + extern void soc_irq_priority(uint32_t irq_num, uint32_t priority); + soc_irq_priority(irq_num, priority); +} + +/** + \brief Gets whether the interrupt is enabled + \param[in] irq_num Number of IRQ. + \return true or false. +*/ +static inline bool csi_irq_is_enabled(uint32_t irq_num) +{ + extern bool soc_irq_is_enabled(uint32_t irq_num); + return soc_irq_is_enabled(irq_num); +} + +/** + \brief Enable the interrupt wakeup attribution + \param[in] irq_num Number of IRQ. + \return None. +*/ +__ALWAYS_STATIC_INLINE void csi_irq_enable_wakeup(uint32_t irq_num) +{ + extern void soc_irq_enable_wakeup(uint32_t irq_num); + soc_irq_enable_wakeup(irq_num); +} + +/** + \brief Disable the interrupt wakeup attribution + \param[in] irq_num Number of IRQ. + \return None. +*/ +__ALWAYS_STATIC_INLINE void csi_irq_disable_wakeup(uint32_t irq_num) +{ + extern void soc_irq_disable_wakeup(uint32_t irq_num); + soc_irq_disable_wakeup(irq_num); +} + +/** + \brief Gets whether in irq context + \return true or false. +*/ +bool csi_irq_context(void); + +/** + \brief Dispatching irq handlers + \return None. +*/ +void do_irq(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_IRQ_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/iso7816.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/iso7816.h new file mode 100755 index 00000000..706d4fa6 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/iso7816.h @@ -0,0 +1,409 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/iso7816.h + * @brief Header File for ISO7816 Driver + * @version V1.0 + * @date 9. Oct 2020 + * @model iso7816 + ******************************************************************************/ + +#ifndef _DRV_ISO7816_H_ +#define _DRV_ISO7816_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + A_5V, + B_3_3V, + C_1_8V, +} dcd_vclass_t; + +typedef enum { + T0, + T1, +} iso7816_tprotocol_t; + +typedef enum { + ISO7816_EVENT_CARD_DETECTED, + ISO7816_EVENT_READ_COMPLETE, + ISO7816_EVENT_WRITE_COMPLETE, + ISO7816_EVENT_READ_ERROR, + ISO7816_EVENT_WRITE_ERROR, + ISO7816_EVENT_ACTIVATE_SUCCESS, + ISO7816_EVENT_ACTIVATE_FAILED, + ISO7816_EVENT_CARD_ERROR_DEACTIVATE, + ISO7816_EVENT_CARD_SESSION_CLOSED, + ISO7816_EVENT_RX_FULL, + ISO7816_EVENT_CWT_TIME_OUT, + ISO7816_EVENT_RX_OVER, + ISO7816_EVENT_CRC_ERR, + ISO7816_EVENT_PARITY_ERR, + ISO7816_EVENT_SLAVE_ATR_DETECTED, + ISO7816_EVENT_SLAVE_ATR_DONE, +} iso7816_event_t; + +typedef void (*iso7816_event_cb_t)(iso7816_event_t event, void *arg); + +typedef enum { + ISO7816_SLAVE, + ISO7816_MASTER, +} iso7816_mode_t; + +typedef struct { + uint8_t clk_div; + dcd_vclass_t vclass; + iso7816_mode_t mode; + int32_t card_detected_en; +} iso7816_config_t; + +typedef enum { + ISO7816_A_ONLY = 1U, + ISO7816_B_ONLY, + ISO7816_C_ONLY, + ISO7816_AB, + ISO7816_AC, + ISO7816_BC, + ISO7816_ABC, +} iso7816_voltage_class_t; + +typedef struct { + iso7816_voltage_class_t support_voltage_class; + int32_t proto_t; + int32_t clk_stop_is_support; + int32_t history_byte_num; + uint8_t history_data[15]; +} iso7816_atr_info_t; + +typedef enum { + EVEN_PARITY, + ODD_PARITY, +} iso7816_parity_type_t; + +typedef enum { + ISO7816_DRIECT, + ISO7816_INVERSE, +} iso7816_convention_t; + +typedef enum { + INVCTIVE, + ACTIVATEING, + PSS_TRF, + PSS_RECV, + ACTIVATE, +} iso7816_card_sta_t; + +/** + \brief Initialize ISO7816 master interface + \param[in] idx Master index + \param[in] cb_event Pointer to \ref iso7816_event_cb_t + \param[in] cb_arg Event callback arg + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_master_init(int idx, iso7816_event_cb_t cb_event, void *cb_arg); + +/** + \brief Uninit ISO7816 master interface + \param[in] idx Master index + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_master_uninit(int idx); + +/** + \brief Config ISO7816 master attributes + \param[in] idx Master index + \param[in] config master config \ref iso7816_config_t + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_master_config(int idx, iso7816_config_t *config); + +/** + \brief Receiving data from ISO7816 master receiver, used polling mode + \param[in] idx Master index + \param[in] buf Pointer to buffer for data to receive from i2s receiver + \param[in] len Size of receiver data + \param[in] time_out Receive time out value + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_master_receive(int idx, uint8_t *buf, uint32_t len, uint32_t time_out); + +/** + \brief Receiving data from ISO7816 master receiver, used interrupt mode + \param[in] idx Master index + \param[in] buf Pointer to buffer for data to receive from i2s receiver + \param[in] len Size of receiver data + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_master_receive_it(int idx, uint8_t *buf, uint32_t len); + +/** + \brief Sending data to ISO7816 master transmitter, used polling mode + \param[in] idx Master index + \param[in] buf Pointer to buffer for data to send + \param[in] len Size of tranmitter data + \param[in] time_out Send time out value + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_master_send(int idx, uint8_t *buf, uint32_t len, uint32_t time_out); + +/** + \brief Sending data to ISO7816 master transmitter, used interrupt mode + \param[in] idx Master index + \param[in] buf Pointer to buffer for data to send + \param[in] len Size of tranmitter data + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_master_send_it(int idx, uint8_t *buf, uint32_t len); + +/** + \brief ISO7816 master performs the activation smart card process, this process + is non-blocking,should monitor callback event or read card status to check card is activate + \param[in] idx Master index + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_master_card_activate(int idx); + +/** + \brief ISO7816 master performs the deactivation smart card process, this process + is non-blocking,should monitor callback event or read card status to check card is activate + \param[in] idx Master index + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_master_card_deactivate(int idx); + +/** + \brief The smard card session status + \param[in] idx Master index + \return smart card status. +*/ +iso7816_card_sta_t csi_iso7816_master_card_status(int idx); + +/** + \brief ISO7816 master performs the warm reset smart card process + \param[in] idx Master index + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_master_card_warm_reset(int idx); + +/** + \brief ISO7816 master performs clock stop + \param[in] idx Master index + \param[in] en The clk last state when power down + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_master_card_clk_stop_enable(int idx, int en); + +/** + \brief ISO7816 master performs pwoer down + \param[in] idx Master index + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_master_power_down(int idx); + +/** + \brief Get atr analytical results + \param[in] idx Master index + \param[out] info The result of atr information + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_master_atr_info(int idx, iso7816_atr_info_t *info); + +/** + \brief Initialize ISO7816 slave interface + \param[in] idx Slave index + \param[in] cb Pointer to \ref iso7816_event_cb_t + \param[in] cb_arg Event callback arg + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_slave_init(int idx, iso7816_event_cb_t cb, void *cb_arg); + +/** + \brief Uninit ISO7816 slave interface + \param[in] idx Slave index + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_slave_uninit(int idx); + +/** + \brief Enable ISO7816 slave interface + \param[in] idx Slave index + \param[in] en Slave enable + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_slave_enable(int idx, int en); + +/** + \brief Enable ISO7816 slave receive parity + \param[in] idx Slave index + \param[in] en Enable receive parity + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_slave_receive_parity_enable(int idx, int en); + +/** + \brief Set ISO7816 slave receive parity attributes + \param[in] idx Slave index + \param[in] type Set receiver parity type + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_slave_set_receive_parity(int idx, iso7816_parity_type_t type); + +/** + \brief Enable ISO7816 slave send parity + \param[in] idx Slave index + \param[in] en Enable send parity + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_slave_send_parity_enable(int idx, int en); + +/** + \brief Set ISO7816 slave send parity attributes + \param[in] idx Slave index + \param[in] type Set send parity attributes + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_slave_set_send_parity(int idx, iso7816_parity_type_t type); + +/** + \brief Set the number of ISO7816 slave receive retry + \param[in] idx Slave index + \param[in] val Set the number retry + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_slave_set_receive_retry(int idx, uint8_t val); + +/** + \brief Set the number of ISO7816 send send retry + \param[in] idx Slave index + \param[in] val Set the number retry + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_slave_set_send_retry(int idx, uint8_t val); + +/** + \brief Set the ISO7816 slave GT + \param[in] idx Slave index + \param[in] val Set the slave GT + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_slave_set_gt(int idx, uint8_t val); + +/** + \brief Set the ISO7816 slave WT + \param[in] idx Slave index + \param[in] val Set the slave WT + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_slave_set_wt(int idx, uint16_t val); + +/** + \brief Set the ISO7816 slave baud, baud = F/D + \param[in] idx Slave index + \param[in] val Set the slave baud + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_slave_set_baud(int idx, uint16_t val); + +/** + \brief Set the ISO7816 slave convention + \param[in] idx Slave index + \param[in] convention Set the slave convention \ref iso7816_convention_t + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_slave_set_convention(int idx, iso7816_convention_t convention); + +/** + \brief Set the ISO7816 slave art response time, val range is 400~40000 + \param[in] idx Slave index + \param[in] val Set the slave art response time + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_slave_set_atr_ack_time(int idx, int val); + +/** + \brief Set the ISO7816 slave send atr data + \param[in] idx Slave index + \param[in] buf Pointer to buffer for data to send + \param[in] len Size of tranmitter data + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_slave_send_atr(int idx, uint8_t *buf, int len); + +/** + \brief Receiving data from ISO7816 slave receiver, used polling mode + \param[in] idx Master index + \param[in] buf Pointer to buffer for data to receive from i2s receiver + \param[in] len Size of receiver data + \param[in] timer_out receive time out value + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_slave_receive(int idx, uint8_t *buf, uint32_t len, uint32_t time_out); + +/** + \brief Flushed the ISO7816 slave receive fifo + \param[in] idx Master index + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_slave_flushed_receive_fifo(int idx); + +/** + \brief Receiving data from ISO7816 slave receiver, used interrupt mode + \param[in] idx Master index + \param[in] buf Pointer to buffer for data to receive from i2s receiver + \param[in] len Size of receiver data + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_slave_receive_it(int idx, uint8_t *buf, uint32_t len); + +/** + \brief Sending data to ISO7816 slave transmitter, used polling mode + \param[in] idx Slave index + \param[in] buf Pointer to buffer for data to send + \param[in] len Size of tranmitter data + \param[in] timer_out Send time out value + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_slave_send(int idx, uint8_t *buf, uint32_t len, uint32_t time_out); + +/** + \brief Flushed the ISO7816 slave send fifo. + \param[in] idx Master index + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_slave_flushed_send_fifo(int idx); + +/** + \brief Sending data to ISO7816 slave transmitter, used interrupt mode + \param[in] idx Slave index + \param[in] buf Pointer to buffer for data to send + \param[in] len Size of tranmitter data + \return 0 for success, negative for error code +*/ +int32_t csi_iso7816_slave_send_it(int idx, uint8_t *buf, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_ISO7816_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/list.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/list.h new file mode 100755 index 00000000..9f65050c --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/list.h @@ -0,0 +1,350 @@ +#ifndef AOS_LIST_H +#define AOS_LIST_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Get offset of a member variable. + * + * @param[in] type the type of the struct this is embedded in. + * @param[in] member the name of the variable within the struct. + */ +#define aos_offsetof(type, member) ((size_t)&(((type *)0)->member)) + +/* + * Get the struct for this entry. + * + * @param[in] ptr the list head to take the element from. + * @param[in] type the type of the struct this is embedded in. + * @param[in] member the name of the variable within the struct. + */ +#define aos_container_of(ptr, type, member) \ + ((type *) ((char *) (ptr) - aos_offsetof(type, member))) + +/* for double link list */ +typedef struct dlist_s { + struct dlist_s *prev; + struct dlist_s *next; +} dlist_t; + +static inline void __dlist_add(dlist_t *node, dlist_t *prev, dlist_t *next) +{ + node->next = next; + node->prev = prev; + + prev->next = node; + next->prev = node; +} + +/* + * Get the struct for this entry. + * + * @param[in] addr the list head to take the element from. + * @param[in] type the type of the struct this is embedded in. + * @param[in] member the name of the dlist_t within the struct. + */ +#define dlist_entry(addr, type, member) \ + ((type *)((long)addr - aos_offsetof(type, member))) + + +static inline void dlist_add(dlist_t *node, dlist_t *queue) +{ + __dlist_add(node, queue, queue->next); +} + +static inline void dlist_add_tail(dlist_t *node, dlist_t *queue) +{ + __dlist_add(node, queue->prev, queue); +} + +static inline void dlist_del(dlist_t *node) +{ + dlist_t *prev = node->prev; + dlist_t *next = node->next; + + prev->next = next; + next->prev = prev; +} + +static inline void dlist_init(dlist_t *node) +{ + node->next = node->prev = node; +} + +static inline void INIT_AOS_DLIST_HEAD(dlist_t *list) +{ + list->next = list; + list->prev = list; +} + +static inline int dlist_empty(const dlist_t *head) +{ + return head->next == head; +} + +/* + * Initialise the list. + * + * @param[in] list the list to be inited. + */ +#define AOS_DLIST_INIT(list) {&(list), &(list)} + +/* + * Get the first element from a list + * + * @param[in] ptr the list head to take the element from. + * @param[in] type the type of the struct this is embedded in. + * @param[in] member the name of the dlist_t within the struct. + */ +#define dlist_first_entry(ptr, type, member) \ + dlist_entry((ptr)->next, type, member) + +/* + * Iterate over a list. + * + * @param[in] pos the &struct dlist_t to use as a loop cursor. + * @param[in] head he head for your list. + */ +#define dlist_for_each(pos, head) \ + for (pos = (head)->next; pos != (head); pos = pos->next) + +/* + * Iterate over a list safe against removal of list entry. + * + * @param[in] pos the &struct dlist_t to use as a loop cursor. + * @param[in] n another &struct dlist_t to use as temporary storage. + * @param[in] head he head for your list. + */ +#define dlist_for_each_safe(pos, n, head) \ + for (pos = (head)->next, n = pos->next; pos != (head); \ + pos = n, n = pos->next) + +/* + * Iterate over list of given type. + * + * @param[in] queue he head for your list. + * @param[in] node the &struct dlist_t to use as a loop cursor. + * @param[in] type the type of the struct this is embedded in. + * @param[in] member the name of the dlist_t within the struct. + */ +#define dlist_for_each_entry(queue, node, type, member) \ + for (node = aos_container_of((queue)->next, type, member); \ + &node->member != (queue); \ + node = aos_container_of(node->member.next, type, member)) + +/* + * Iterate over list of given type safe against removal of list entry. + * + * @param[in] queue the head for your list. + * @param[in] n the type * to use as a temp. + * @param[in] node the type * to use as a loop cursor. + * @param[in] type the type of the struct this is embedded in. + * @param[in] member the name of the dlist_t within the struct. + */ +#define dlist_for_each_entry_safe(queue, n, node, type, member) \ + for (node = aos_container_of((queue)->next, type, member), \ + n = (queue)->next ? (queue)->next->next : NULL; \ + &node->member != (queue); \ + node = aos_container_of(n, type, member), n = n ? n->next : NULL) + +/* + * Get the struct for this entry. + * @param[in] ptr the list head to take the element from. + * @param[in] type the type of the struct this is embedded in. + * @param[in] member the name of the variable within the struct. + */ +#define list_entry(ptr, type, member) \ + aos_container_of(ptr, type, member) + + +/* + * Iterate backwards over list of given type. + * + * @param[in] pos the type * to use as a loop cursor. + * @param[in] head he head for your list. + * @param[in] member the name of the dlist_t within the struct. + * @param[in] type the type of the struct this is embedded in. + */ +#define dlist_for_each_entry_reverse(pos, head, member, type) \ + for (pos = list_entry((head)->prev, type, member); \ + &pos->member != (head); \ + pos = list_entry(pos->member.prev, type, member)) + + +/* + * Get the list length. + * + * @param[in] queue the head for your list. + */ +int dlist_entry_number(dlist_t *queue); + + + +/* + * Initialise the list. + * + * @param[in] name the list to be initialized. + */ +#define AOS_DLIST_HEAD_INIT(name) { &(name), &(name) } + +/* + * Initialise the list. + * + * @param[in] name the list to be initialized. + */ +#define AOS_DLIST_HEAD(name) \ + dlist_t name = AOS_DLIST_HEAD_INIT(name) + +/* for single link list */ +typedef struct slist_s { + struct slist_s *next; +} slist_t; + +static inline void slist_add(slist_t *node, slist_t *head) +{ + node->next = head->next; + head->next = node; +} + +void slist_add_tail(slist_t *node, slist_t *head); + +static inline void slist_del(slist_t *node, slist_t *head) +{ + while (head->next) { + if (head->next == node) { + head->next = node->next; + break; + } + + head = head->next; + } +} + +static inline int slist_empty(const slist_t *head) +{ + return !head->next; +} + +static inline void slist_init(slist_t *head) +{ + head->next = 0; +} + +static inline slist_t *slist_remove(slist_t *l, slist_t *n) +{ + /* remove slist head */ + struct slist_s *node = l; + while (node->next && node->next != n) node = node->next; + + /* remove node */ + if (node->next != (slist_t *)0) node->next = node->next->next; + + return l; +} + +static inline slist_t *slist_first(slist_t *l) +{ + return l->next; +} + +static inline slist_t *slist_tail(slist_t *l) +{ + while (l->next) l = l->next; + + return l; +} + +static inline slist_t *slist_next(slist_t *n) +{ + return n->next; +} + +/* +* Iterate over list of given type. +* +* @param[in] queue he head for your list. +* @param[in] node the type * to use as a loop cursor. +* @param[in] type the type of the struct this is embedded in. +* @param[in] member the name of the slist_t within the struct. +*/ +#define slist_for_each_entry(queue, node, type, member) \ + for (node = (queue)->next? aos_container_of((queue)->next, type, member) : NULL; \ + node; \ + node = node->member.next ? aos_container_of(node->member.next, type, member) : NULL) + +/* + * Iterate over list of given type safe against removal of list entry. + * + * @param[in] queue the head for your list. + * @param[in] tmp the type * to use as a temp. + * @param[in] node the type * to use as a loop cursor. + * @param[in] type the type of the struct this is embedded in. + * @param[in] member the name of the slist_t within the struct. + */ +#define slist_for_each_entry_safe(queue, tmp, node, type, member) \ + for (node = (queue)->next? aos_container_of((queue)->next, type, member) : NULL, \ + tmp = (queue)->next ? (queue)->next->next : NULL; \ + node; \ + node = tmp ? aos_container_of(tmp, type, member) : NULL, tmp = tmp ? tmp->next : NULL) + +/* + * Initialise the list. + * + * @param[in] name the list to be initialized. + */ +#define AOS_SLIST_HEAD_INIT(name) {0} + +/* + * Initialise the list. + * + * @param[in] name the list to be initialized. + */ +#define AOS_SLIST_HEAD(name) \ + slist_t name = AOS_SLIST_HEAD_INIT(name) + +/* + * Get the struct for this entry. + * @param[in] addr the list head to take the element from. + * @param[in] type the type of the struct this is embedded in. + * @param[in] member the name of the slist_t within the struct. + */ +#define slist_entry(addr, type, member) ( \ + addr ? (type *)((long)addr - aos_offsetof(type, member)) : (type *)addr \ +) + +/* +* Get the first element from a list. +* +* @param[in] ptr the list head to take the element from. +* @param[in] type the type of the struct this is embedded in. +* @param[in] member the name of the slist_t within the struct. +*/ +#define slist_first_entry(ptr, type, member) \ + slist_entry((ptr)->next, type, member) + +/** + * slist_tail_entry - get the tail element from a slist + * @ptr: the slist head to take the element from. + * @type: the type of the struct this is embedded in. + * @member: the name of the slist_struct within the struct. + * + * Note, that slist is expected to be not empty. + */ +#define slist_tail_entry(ptr, type, member) \ + slist_entry(slist_tail(ptr), type, member) + +/* + * Get the list length. + * + * @param[in] queue the head for your list. + */ +int slist_entry_number(slist_t *queue); + +#ifdef __cplusplus +} +#endif + +#endif /* AOS_LIST_H */ + diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/mbox.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/mbox.h new file mode 100755 index 00000000..c5090425 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/mbox.h @@ -0,0 +1,104 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/mbox.h + * @brief Header File for MBOX Driver + * @version V1.0 + * @date 5. Apr 2020 + * @model mbox + ******************************************************************************/ + +#ifndef _DRV_MBOX_H_ +#define _DRV_MBOX_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + MBOX_EVENT_SEND_COMPLETE = 0U, ///< Send completed; however mbox may still transmit data + MBOX_EVENT_RECEIVED = 1U, ///< Data Received, only in mbox buf, call memcpy() get the data + MBOX_EVENT_ERROR = 2U, ///< Mbox transmit error occurred +} csi_mbox_event_t; + +typedef struct csi_mbox csi_mbox_t; +struct csi_mbox { + csi_dev_t dev; + void (*callback)(csi_mbox_t *mbox, csi_mbox_event_t event, uint32_t channel_id, uint32_t received_len, void *arg); + void *arg; + void *priv; +}; + +/** + \brief Initialize mbox Interface. + Initializes the resources needed for the mbox interface. + \param[in] mbox Operate handle. + \param[in] idx The device idx. + \return Error code \ref csi_error_t. +*/ +csi_error_t csi_mbox_init(csi_mbox_t *mbox, uint32_t idx); + +/** + \brief Uninitialize mbox interface. stops operation and releases the software resources used by the interface. + \param[in] mbox Operate handle. +*/ +void csi_mbox_uninit(csi_mbox_t *mbox); + +/** + \brief Start sending data to mbox transmitter. + \param[in] mbox Operate handle. + \param[in] channel_id Index of channel. + \param[in] data Pointer to buffer with data to send to mbox transmitter. + \param[in] size Number of data items to send. + \return sent Number of data or error code. +*/ +int32_t csi_mbox_send(csi_mbox_t *mbox, uint32_t channel_id, const void *data, uint32_t size); + +/** + \brief Start receiving data from mbox receiver. + \param[in] mbox Operate handle. + \param[in] channel_id Index of channel. + \param[out] data Pointer to buffer with data to receive from mailbox. + \param[in] size Number of data items to receive. + \return received Number or error code. +*/ +int32_t csi_mbox_receive(csi_mbox_t *mbox, uint32_t channel_id, void *data, uint32_t size); + +/** + \brief Attach callback to the mbox. + \param[in] mbox Operate handle. + \param[in] cb Event callback function. + \param[in] arg User private param for event callback. + \return Error code \ref csi_error_t. +*/ +csi_error_t csi_mbox_attach_callback(csi_mbox_t *mbox, void *callback, void *arg); + +/** + \brief Detach callback from the mbox + \param[in] mbox Operate handle. +*/ +void csi_mbox_detach_callback(csi_mbox_t *mbox); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_MBOX_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/pin.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/pin.h new file mode 100755 index 00000000..d1a614b6 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/pin.h @@ -0,0 +1,198 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 soc.h + * @brief For pin + * @version V1.0 + * @date 11. Mar 2020 + ******************************************************************************/ + +#ifndef _DRV_PIN_H_ +#define _DRV_PIN_H_ + +#include +#include +#include +#include + +typedef csi_gpio_mode_t csi_pin_mode_t; + +typedef enum { + PIN_SPEED_LV0 = 0U, + PIN_SPEED_LV1, + PIN_SPEED_LV2, + PIN_SPEED_LV3 +} csi_pin_speed_t; + +typedef enum { + PIN_DRIVE_LV0 = 0U, + PIN_DRIVE_LV1, + PIN_DRIVE_LV2, + PIN_DRIVE_LV3 +} csi_pin_drive_t; + +typedef enum{ + PIN_UART_TX = 0U, + PIN_UART_RX, + PIN_UART_CTS, + PIN_UART_RTS +}csi_pin_uart_t; + +typedef enum{ + PIN_IIC_SCL = 0U, + PIN_IIC_SDA +}csi_pin_iic_t; + +typedef enum{ + PIN_SPI_MISO = 0U, + PIN_SPI_MOSI, + PIN_SPI_SCK, + PIN_SPI_CS +}csi_pin_spi_t; + +typedef enum{ + PIN_I2S_MCLK = 0U, + PIN_I2S_SCLK, + PIN_I2S_WSCLK, + PIN_I2S_SDA, + PIN_I2S_SDI, + PIN_I2S_SDO +}csi_pin_i2s_t; + +typedef struct { + pin_name_t pin_name; + uint8_t idx; ///< ctrl idx. e.g: ADC0 channel 1, idx = 0, channel = 1 + uint8_t channel; ///< channel idx. e.g: same as the previous line + pin_func_t pin_func; +} csi_pinmap_t; + +extern uint32_t target_pin_to_devidx(pin_name_t pin_name, const csi_pinmap_t *pinmap); +extern uint32_t target_pin_to_channel(pin_name_t pin_name,const csi_pinmap_t *pinmap); +extern pin_name_t target_gpio_to_pin(uint8_t gpio_idx, uint8_t channel,const csi_pinmap_t *pinmap); + +/** + \brief Set pin mux function + \param[in] pin_name Pin name, defined in soc.h + \param[in] pin_func Pin function, defined in soc.h + \return \ref csi_error_t +*/ +csi_error_t csi_pin_set_mux(pin_name_t pin_name, pin_func_t pin_func); + +/** + \brief Get pin function + \param[in] pin_name Pin name, defined in soc.h + \return pin function +*/ +pin_func_t csi_pin_get_mux(pin_name_t pin_name); + +/** + \brief Set pin mode + \param[in] pin_name Pin name, defined in soc.h + \param[in] mode Push/pull mode + \return \ref csi_error_t +*/ +csi_error_t csi_pin_mode(pin_name_t pin_name, csi_pin_mode_t mode); + +/** + \brief Set pin speed + \param[in] pin_name Pin name, defined in soc.h + \param[in] speed Io speed + \return \ref csi_error_t +*/ +csi_error_t csi_pin_speed(pin_name_t pin_name, csi_pin_speed_t speed); + +/** + \brief Set pin drive + \param[in] pin_name Pin name, defined in soc.h + \param[in] drive Io drive + \return \ref csi_error_t +*/ +csi_error_t csi_pin_drive(pin_name_t pin_name, csi_pin_drive_t drive); + +/** + \brief Get ctrl idx by pin + \param[in] pin_name Pin name, defined in soc.h + \return idx +*/ +__ALWAYS_STATIC_INLINE uint32_t csi_pin_get_gpio_devidx(pin_name_t pin_name) +{ + extern const csi_pinmap_t gpio_pinmap[]; + return target_pin_to_devidx(pin_name, gpio_pinmap); +} + +__ALWAYS_STATIC_INLINE uint32_t csi_pin_get_uart_devidx(pin_name_t pin_name) +{ + extern const csi_pinmap_t uart_pinmap[]; + return target_pin_to_devidx(pin_name, uart_pinmap); +} + +__ALWAYS_STATIC_INLINE uint32_t csi_pin_get_iic_devidx(pin_name_t pin_name) +{ + extern const csi_pinmap_t iic_pinmap[]; + return target_pin_to_devidx(pin_name, iic_pinmap); +} + +__ALWAYS_STATIC_INLINE uint32_t csi_pin_get_spi_devidx(pin_name_t pin_name) +{ + extern const csi_pinmap_t spi_pinmap[]; + return target_pin_to_devidx(pin_name, spi_pinmap); +} + +__ALWAYS_STATIC_INLINE uint32_t csi_pin_get_i2s_devidx(pin_name_t pin_name) +{ + extern const csi_pinmap_t i2s_pinmap[]; + return target_pin_to_devidx(pin_name, i2s_pinmap); +} + +/** + \brief Get channel by pin + \param[in] pin_name Pin name, defined in soc.h + \return channel +*/ +__ALWAYS_STATIC_INLINE uint32_t csi_pin_get_adc_channel(pin_name_t pin_name) +{ + extern const csi_pinmap_t adc_pinmap[]; + return target_pin_to_channel(pin_name, adc_pinmap); +} + +__ALWAYS_STATIC_INLINE uint32_t csi_pin_get_pwm_channel(pin_name_t pin_name) +{ + extern const csi_pinmap_t pwm_pinmap[]; + return target_pin_to_channel(pin_name, pwm_pinmap); +} + +__ALWAYS_STATIC_INLINE uint32_t csi_pin_get_gpio_channel(pin_name_t pin_name) +{ + extern const csi_pinmap_t gpio_pinmap[]; + return target_pin_to_channel(pin_name, gpio_pinmap); +} + +/** + \brief Get pin name by gpio ctrl idx and channel + \param[in] gpio_idx Idx, defined in soc.h + \param[in] channel Channel, defined in soc.h + \return pin name +*/ +__ALWAYS_STATIC_INLINE pin_name_t csi_pin_get_pinname_by_gpio(uint8_t gpio_idx, uint8_t channel) +{ + extern const csi_pinmap_t gpio_pinmap[]; + return target_gpio_to_pin(gpio_idx,channel,gpio_pinmap); +} + +#endif /* _DRV_PIN_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/pm.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/pm.h new file mode 100755 index 00000000..1894f206 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/pm.h @@ -0,0 +1,122 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/pm.h + * @brief Header File for PM Driver + * @version V1.0 + * @date 10. Oct 2020 + * @model pm + ******************************************************************************/ + +#ifndef _DRV_PM_H_ +#define _DRV_PM_H_ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + \brief Initialize PM module + \return Error code \ref csi_error_t +*/ +csi_error_t csi_pm_init(void); + +/** + \brief De-initialize PM module + \return None +*/ +void csi_pm_uninit(void); + +/** + \brief Set the retention memory used to save registers + \param[in] mem Retention memory(word align) + \param[in] num Number of memory(1: 1 word) + \return Error code \ref csi_error_t +*/ +csi_error_t csi_pm_set_reten_mem(uint32_t *mem, uint32_t num); + +/** + \brief Config the wakeup source + \param[in] wakeup_num Wakeup source num + \param[in] enable Flag control the wakeup source is enable or not + \return Error code \ref csi_error_t +*/ +csi_error_t csi_pm_config_wakeup_source(uint32_t wakeup_num, bool enable); + +/** + \brief System enter low-power mode + \param[in] mode Low-power mode, \ref csi_pm_mode_t + \return Error code \ref csi_error_t +*/ +csi_error_t csi_pm_enter_sleep(csi_pm_mode_t mode); + +/** + \brief Register device to the PM list + \param[in] dev Csi dev + \param[in] pm_action PM action function + \param[in] mem_size Size of memory for saving registers + \param[in] priority PM dev priority(0-3), The smaller the value, + the last execution before entering low power consumption, + the first execution after exiting low power consumption + \return Error code \ref csi_error_t +*/ +csi_error_t csi_pm_dev_register(csi_dev_t *dev, void *pm_action, uint32_t mem_size, uint8_t priority); + +/** + \brief Deregister device to the PM list + \param[in] dev Csi dev + \return None +*/ +void csi_pm_dev_unregister(csi_dev_t *dev); + +/** + \brief Save registers to memory + \param[in] mem Mem to store registers + \param[in] addr Registers address + \param[in] num Number of memory(1: 1 word) + \return None +*/ +void csi_pm_dev_save_regs(uint32_t *mem, uint32_t *addr, uint32_t num); + +/** + \brief Save registers to memory + \param[in] mem Mem to store registers + \param[in] addr Registers address + \param[in] num Number of memory(1: 1 word) + \return None +*/ +void csi_pm_dev_restore_regs(uint32_t *mem, uint32_t *addr, uint32_t num); + +/** + \brief Notify devices enter low-power states + \param[in] action Device low-power action + \return Error code \ref csi_error_t +*/ +csi_error_t csi_pm_dev_notify(csi_pm_dev_action_t action); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_PM_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/pmu.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/pmu.h new file mode 100755 index 00000000..ac5bbadf --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/pmu.h @@ -0,0 +1,118 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv_pmu.h + * @brief header file for pmu driver + * @version V1.0 + * @date 02. June 2017 + * @model pmu + ******************************************************************************/ + +#ifndef _DRV_PMU_H_ +#define _DRV_PMU_H_ + + +#include + +#ifdef __cplusplus +extern "C" { +#endif +/// definition for pmu handle. +typedef void *pmu_handle_t; + +/****** PMU specific error codes *****/ +typedef enum { + EDRV_PMU_MODE = (1), ///< Specified Mode not supported +} pmu_error_e; + +/*----- PMU Control Codes: Mode -----*/ +typedef enum { + PMU_MODE_RUN = 0, ///< Running mode + PMU_MODE_SLEEP, ///< Sleep mode + PMU_MODE_DOZE, ///< Doze mode + PMU_MODE_DORMANT, ///< Dormant mode + PMU_MODE_STANDBY, ///< Standby mode + PMU_MODE_SHUTDOWN ///< Shutdown mode +} pmu_mode_e; + +/*----- PMU Control Codes: Wakeup type -----*/ +typedef enum { + PMU_WAKEUP_TYPE_PULSE = 0, ///< Pulse interrupt + PMU_WAKEUP_TYPE_LEVEL ///< Level interrupt +} pmu_wakeup_type_e; + +/*----- PMU Control Codes: Wakeup polarity -----*/ +typedef enum { + PMU_WAKEUP_POL_LOW = 0, ///< Low or negedge + PMU_WAKEUP_POL_HIGH ///< High or posedge +} pmu_wakeup_pol_e; + +/****** PMU Event *****/ +typedef enum { + PMU_EVENT_SLEEP_DONE = 0, ///< Send completed; however PMU may still transmit data + PMU_EVENT_PREPARE_SLEEP = 1 +} pmu_event_e; + +typedef void (*pmu_event_cb_t)(int32_t idx, pmu_event_e event, pmu_mode_e mode); ///< Pointer to \ref pmu_event_cb_t : PMU Event call back. + +/** + \brief Initialize PMU Interface. 1. Initializes the resources needed for the PMU interface 2.registers event callback function + \param[in] idx the id of the pmu + \param[in] cb_event Pointer to \ref pmu_event_cb_t + \return return pmu handle if success +*/ +pmu_handle_t csi_pmu_initialize(int32_t idx, pmu_event_cb_t cb_event); + +/** + \brief De-initialize PMU Interface. stops operation and releases the software resources used by the interface + \param[in] handle pmu handle to operate. + \return error code +*/ +int32_t csi_pmu_uninitialize(pmu_handle_t handle); + +/** + \brief choose the pmu mode to enter + \param[in] handle pmu handle to operate. + \param[in] mode \ref pmu_mode_e + \return error code +*/ +int32_t csi_pmu_enter_sleep(pmu_handle_t handle, pmu_mode_e mode); + +/** + \brief control pmu power. + \param[in] handle pmu handle to operate. + \param[in] state power state.\ref csi_power_stat_e. + \return error code +*/ +/** + \brief Config the wakeup source. + \param[in] handle pmu handle to operate + \param[in] wakeup_num wakeup source num + \param[in] type \ref pmu_wakeup_type + \param[in] pol \ref pmu_wakeup_pol + \param[in] enable flag control the wakeup source is enable or not + \return error code +*/ +int32_t csi_pmu_config_wakeup_source(pmu_handle_t handle, uint32_t wakeup_num, pmu_wakeup_type_e type, pmu_wakeup_pol_e pol, uint8_t enable); + +#ifdef __cplusplus +} +#endif + +#endif /* _CSI_PMU_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/porting.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/porting.h new file mode 100755 index 00000000..6ea647a1 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/porting.h @@ -0,0 +1,184 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/porting.h + * @brief Header File for SOC Porting + * @version V1.0 + * @date 8. Apr 2020 + * @model porting + ******************************************************************************/ + +#ifndef _DRV_PORTING_H_ +#define _DRV_PORTING_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + BOOTREASON_WDT = 0, // System WDT reset + BOOTREASON_SOFT = 1, // soft reset + BOOTREASON_POWER = 2, // chip power on reset + BOOTREASON_OTHER = 0xFF +} boot_reason_t; + +/* + \brief Soc get boot reason + \return boot reason, \ref boot_reason_t +*/ +boot_reason_t soc_get_boot_reason(void); + +/** + \brief Soc get device frequence. + \param[in] idx Device index + \return frequence +*/ +uint32_t soc_get_apb_freq(uint32_t idx); +uint32_t soc_get_ahb_freq(uint32_t idx); +uint32_t soc_get_cpu_freq(uint32_t idx); + +uint32_t soc_get_uart_freq(uint32_t idx); +uint32_t soc_get_spi_freq(uint32_t idx); +uint32_t soc_get_iic_freq(uint32_t idx); +uint32_t soc_get_i2s_freq(uint32_t idx); +uint32_t soc_get_pwm_freq(uint32_t idx); +uint32_t soc_get_adc_freq(uint32_t idx); +uint32_t soc_get_qspi_freq(uint32_t idx); +uint32_t soc_get_usi_freq(uint32_t idx); +uint32_t soc_get_timer_freq(uint32_t idx); +uint32_t soc_get_rtc_freq(uint32_t idx); +uint32_t soc_get_wdt_freq(uint32_t idx); +uint32_t soc_get_sdio_freq(uint32_t idx); +uint32_t soc_get_emmc_freq(uint32_t idx); +uint32_t soc_get_usb_freq(uint32_t idx); +uint32_t soc_get_ref_clk_freq(uint32_t idx); +uint32_t soc_get_coretim_freq(void); +uint32_t soc_get_cur_cpu_freq(void); +uint32_t soc_get_sys_freq(void); + +/** + \brief Soc get device frequence. + \param[in] freq CPU frequence + \return none +*/ +void soc_set_sys_freq(uint32_t freq); + +/* + \brief Soc init clock unit + \return none +*/ +void soc_clk_init(void); + +/* + \brief Soc enable device clock + \param[in] module Clock module, defined in sys_clk.h, \ref clk_module_t + \return none +*/ +void soc_clk_enable(int32_t module); + +/* + \brief Soc disable device clock + \param[in] module Clock module, defined in sys_clk.h, \ref clk_module_t + \return none +*/ +void soc_clk_disable(int32_t module); + +/* + \brief Get CPU ID + \return CPU ID, the val is 0, 1, 2... +*/ +uint32_t soc_get_cpu_id(void); + +/** + \brief SOC Dcache clean & invalid by range. + \return None +*/ +void soc_dcache_clean_invalid_range(unsigned long addr, uint32_t size); + +/** + \brief SOC Dcache clean & invalid all. + \return None +*/ +void soc_dcache_clean_invalid_all(void); + +/** + \brief SOC Dcache invalid by range. + \return None +*/ +void soc_dcache_invalid_range(unsigned long addr, uint32_t size); + +/** + \brief SOC Dcache invalid all. + \return None +*/ +void soc_dcache_invalid(void); + +/** + \brief SOC Dcache clean all. + \return None +*/ +void soc_dcache_clean(void); + + +/** + \brief SOC Dcache clean by range. + \return None +*/ +void soc_dcache_clean_range(unsigned long addr, uint32_t size); + +/** + \brief SOC Icache invalid all. + \return None +*/ +void soc_icache_invalid(void); + +/** + \brief SOC dma address remap. + \return Remaped address +*/ +extern unsigned long soc_dma_address_remap(unsigned long addr); + + +#ifdef CONFIG_PM +/** + \brief SoC enter low-power mode, each chip's implementation is different + called by csi_pm_enter_sleep + \param[in] mode low-power mode + \return Error code +*/ +csi_error_t soc_pm_enter_sleep(csi_pm_mode_t mode); + +/** + \brief SoC the wakeup source. + \param[in] wakeup_num Wakeup source num + \param[in] enable Flag control the wakeup source is enable or not + \return Error code +*/ +csi_error_t soc_pm_config_wakeup_source(uint32_t wakeup_num, bool enable); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_PORTING_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/pwm.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/pwm.h new file mode 100755 index 00000000..0db71e97 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/pwm.h @@ -0,0 +1,172 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/pwm.h + * @brief Header File for PWM Driver + * @version V1.0 + * @date 9. Oct 2020 + * @model pwm + ******************************************************************************/ + +#ifndef _DRV_PWM_H_ +#define _DRV_PWM_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PWM_POLARITY_HIGH = 0U, ///< High level + PWM_POLARITY_LOW ///< Low level +} csi_pwm_polarity_t; + +typedef enum { + PWM_CAPTURE_POLARITY_POSEDGE = 0U, ///< Posedge Edge + PWM_CAPTURE_POLARITY_NEGEDGE, ///< Negedge Edge + PWM_CAPTURE_POLARITY_BOTHEDGE ///< Both Edge +} csi_pwm_capture_polarity_t; + +typedef enum { + PWM_EVENT_CAPTURE_POSEDGE = 0U, ///< Capture Posedge Event + PWM_EVENT_CAPTURE_NEGEDGE, ///< Capture Negedge Event + PWM_EVENT_CAPTURE_BOTHEDGE, ///< Capture Bothedge Event + PWM_EVENT_ERROR, ///< Error +} csi_pwm_event_t; + +typedef struct csi_pwm csi_pwm_t; + +struct csi_pwm { + csi_dev_t dev; + void (*callback)(csi_pwm_t *pwm, csi_pwm_event_t event, uint32_t ch, uint32_t time_us, void *arg); + void *arg; + void *priv; +}; + +/** + \brief Initialize PWM interface. Initializes the resources needed for the PWM interface + \param[in] pwm Handle to operate + \param[in] idx PWM idx + \return Error code \ref csi_error_t +*/ +csi_error_t csi_pwm_init(csi_pwm_t *pwm, uint32_t idx); + +/** + \brief De-initialize PWM interface. Stops operation and releases the software resources used by the interface + \param[in] pwm Handle to operate + \return None +*/ +void csi_pwm_uninit(csi_pwm_t *pwm); + +/** + \brief Config PWM out mode + \param[in] pwm Handle to operate + \param[in] channel Channel num + \param[in] period_us The PWM period in us + \param[in] pulse_width_us The PMW pulse width in us + \param[in] polarity The PWM polarity \ref csi_pwm_polarity_t + \return Error code \ref csi_error_t +*/ +csi_error_t csi_pwm_out_config(csi_pwm_t *pwm, + uint32_t channel, + uint32_t period_us, + uint32_t pulse_width_us, + csi_pwm_polarity_t polarity); + +/** + \brief Start generate PWM signal + \param[in] pwm Handle to operate + \param[in] channel Channel num + \return Error code \ref csi_error_t +*/ +csi_error_t csi_pwm_out_start(csi_pwm_t *pwm, uint32_t channel); + +/** + \brief Stop generate PWM signal + \param[in] pwm Handle to operate + \param[in] channel Channel num + \return None +*/ +void csi_pwm_out_stop(csi_pwm_t *pwm, uint32_t channel); + +/** + \brief Config PWM capture mode + \param[in] pwm Handle to operate + \param[in] channel Channel num + \param[in] polarity PWM capture polarity \ref csi_pwm_capture_polarity_t + \param[in] count PWM capture polarity count + \return Error code \ref csi_error_t +*/ +csi_error_t csi_pwm_capture_config(csi_pwm_t *pwm, + uint32_t channel, + csi_pwm_capture_polarity_t polarity, + uint32_t count); + +/** + \brief Start PWM capture + \param[in] pwm Handle to operate + \param[in] channel Channel num + \return Error code \ref csi_error_t +*/ +csi_error_t csi_pwm_capture_start(csi_pwm_t *pwm, uint32_t channel); + +/** + \brief Stop PWM capture + \param[in] pwm Handle to operate + \param[in] channel Channel num + \return None +*/ +void csi_pwm_capture_stop(csi_pwm_t *pwm, uint32_t channel); + +/** + \brief Attach PWM callback + \param[in] pwm Handle to operate + \param[in] callback Callback func + \param[in] arg Callback's param + \return Error code \ref csi_error_t +*/ +csi_error_t csi_pwm_attach_callback(csi_pwm_t *pwm, void *callback, void *arg); + +/** + \brief Detach PWM callback + \param[in] pwm Handle to operate + \return None +*/ +void csi_pwm_detach_callback(csi_pwm_t *pwm); + +/** + \brief Enable PWM power manage + \param[in] pwm Handle to operate + \return Error code \ref csi_error_t +*/ +csi_error_t csi_pwm_enable_pm(csi_pwm_t *pwm); + +/** + \brief Disable PWM power manage + \param[in] pwm Handle to operate + \return None +*/ +void csi_pwm_disable_pm(csi_pwm_t *pwm); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_PWM_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/qspi.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/qspi.h new file mode 100755 index 00000000..e8f33312 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/qspi.h @@ -0,0 +1,304 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/qspi.h + * @brief Header File for QSPI Driver + * @version V1.0 + * @date 8. Apr 2020 + * @model qspi + ******************************************************************************/ + +#ifndef _DRV_QSPI_H_ +#define _DRV_QSPI_H_ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \enum csi_qspi_clock_mode_t + * \brief QSPI clock mode + */ +typedef enum { + QSPI_CLOCK_MODE_0 = 0, ///< Clock Polarity 0, Clock Phase 0 + QSPI_CLOCK_MODE_1, ///< Clock Polarity 0, Clock Phase 1 + QSPI_CLOCK_MODE_2, ///< Clock Polarity 1, Clock Phase 0 + QSPI_CLOCK_MODE_3, ///< Clock Polarity 1, Clock Phase 1 +} csi_qspi_mode_t; + +/** + * \enum csi_qspi_bus_width_t + * \brief QSPI bus width + */ +typedef enum { + QSPI_CFG_BUS_SINGLE = 0, ///< Single line + QSPI_CFG_BUS_DUAL, ///< Two line + QSPI_CFG_BUS_QUAD, ///< Four line +} csi_qspi_bus_width_t; + +/** + * \enum csi_qspi_address_size_t + * \brief Address size in bits + */ +typedef enum { + QSPI_ADDRESS_8_BITS = 0, + QSPI_ADDRESS_16_BITS, + QSPI_ADDRESS_24_BITS, + QSPI_ADDRESS_32_BITS, +} csi_qspi_address_size_t; + +/** + * \enum csi_qspi_alternate_bytes_size_t + * rief QSPI alternate bytes + */ +typedef enum { + QSPI_ALTERNATE_8_BITS = 0, + QSPI_ALTERNATE_16_BITS, + QSPI_ALTERNATE_24_BITS, + QSPI_ALTERNATE_32_BITS, +} csi_qspi_alt_size_t; + +/** QSPI command + * + * Defines a frame format. It consists of instruction, address, alternative, dummy count and data + */ +typedef struct { + struct { + csi_qspi_bus_width_t bus_width; ///< Bus width for the instruction + uint8_t value; ///< Instruction value + bool disabled; ///< Instruction phase skipped if disabled is set to true + } instruction; + struct { + csi_qspi_bus_width_t bus_width; ///< Bus width for the address + csi_qspi_address_size_t size; ///< Address size + uint32_t value; ///< Address value + bool disabled; ///< Address phase skipped if disabled is set to true + } address; + struct { + csi_qspi_bus_width_t bus_width; ///< Bus width for alternative + csi_qspi_alt_size_t size; ///< Alternative size + uint32_t value; ///< Alternative value + bool disabled; ///< Alternative phase skipped if disabled is set to true + } alt; + uint8_t dummy_count; ///< Dummy cycles count + struct { + csi_qspi_bus_width_t bus_width; ///< Bus width for data + } data; + uint8_t ddr_enable; +} csi_qspi_command_t; + +/** + * \enum csi_qspi_event_t + * \brief QSPI event + */ +typedef enum { + QSPI_EVENT_COMMAND_COMPLETE = 0, ///< Command completed + QSPI_EVENT_ERROR, ///< An error has occurred +} csi_qspi_event_t; + +/** + * \struct csi_qspi_t + * \brief QSPI Handle Structure definition + */ + +typedef struct csi_qspi csi_qspi_t; +struct csi_qspi { + csi_dev_t dev; ///< QSPI hw-device info + void (*callback)(csi_qspi_t *qspi, csi_qspi_event_t event, void *arg); ///< User callback function + void *arg; ///< QSPI custom designed param passed to evt_cb + uint8_t *tx_data; ///< Pointer to QSPI Tx transfer Buffer + uint32_t tx_size; ///< QSPI Tx Transfer size + uint8_t *rx_data; ///< Pointer to QSPI Rx transfer Buffer + uint32_t rx_size; ///< QSPI Rx Transfer size + void *send; ///< The send_async func + void *receive; ///< The receive_async func + void *send_receive; ///< The send_receive_async func + csi_state_t state; ///< Peripheral state + csi_dma_ch_t *tx_dma; + csi_dma_ch_t *rx_dma; + void *priv; +}; + +/** + \brief Init QSPI ctrl block + 1. Initializes the QSPI mode according to the specified parameters in the csi_qspi_init_t + 2. Registers event callback function and user param for the callback + \param[in] qspi Handle of QSPI instance + \param[in] idx Index of instance + \return Error code +*/ +csi_error_t csi_qspi_init(csi_qspi_t *qspi, uint32_t idx); + + +/** + \brief De-initialize QSPI Instance + stops operation and releases the software resources used by the Instance + \param[in] qspi Handle of QSPI instance +*/ +void csi_qspi_uninit(csi_qspi_t *qspi); + +/** + \brief Attach the callback handler to QSPI + \param[in] qspi Operate handle + \param[in] callback Callback function + \param[in] arg User can define it by himself as callback's param + \return Error code +*/ +csi_error_t csi_qspi_attach_callback(csi_qspi_t *qspi, void *callback, void *arg); + +/** + \brief Detach the callback handler + \param[in] qspi Operate handle + \return None +*/ +void csi_qspi_detach_callback(csi_qspi_t *qspi); + +/** + \brief Config qspi frequence + \param[in] qspi Handle of qspi instance + \param[in] hz QSPI frequence + \return The actual config frequency +*/ +uint32_t csi_qspi_frequence(csi_qspi_t *qspi, uint32_t hz); + +/** + \brief Config qspi mode + \param[in] qspi Handle of qspi instance + \param[in] mode QSPI mode + \return Error code +*/ +csi_error_t csi_qspi_mode(csi_qspi_t *qspi, csi_qspi_mode_t mode); + +/** + \brief Send an amount of data in blocking mode + \param[in] qspi QSPI handle + \param[in] cmd Structure that contains the command configuration information + \param[in] data Pointer to data buffer + \param[in] size Size of data to send + \param[in] timeout Time out duration + \return If send successful, this function shall return the num of data witch is sent successful + otherwise, the function shall return error code + */ +int32_t csi_qspi_send(csi_qspi_t *qspi, csi_qspi_command_t *cmd, const void *data, uint32_t size, uint32_t timeout); + +/** + \brief Receive an amount of data in blocking mode + \param[in] qspi QSPI handle + \param[in] cmd Structure that contains the command configuration information + \param[out] data Pointer to data buffer + \param[in] size Size of data items to receive + \param[in] timeout Time out duration + \return If receive successful, this function shall return the num of data witch is received successfulful + otherwise, the function shall return error code + */ +int32_t csi_qspi_receive(csi_qspi_t *qspi, csi_qspi_command_t *cmd, void *data, uint32_t size, uint32_t timeout); + +/** + \brief Transfer an amount of data in blocking mode + \param[in] qspi QSPI handle + \param[in] cmd Structure that contains the command configuration information + \param[in] tx_data Pointer to send data buffer + \param[out] rx_data Pointer to receive data buffer + \param[in] size Size of data to transfer + \param[in] timeout Time out duration + \return If transfer successful, this function shall return the num of data witch is transfer successfulful + otherwise, the function shall return error code + */ +int32_t csi_qspi_send_receive(csi_qspi_t *qspi, csi_qspi_command_t *cmd, const void *tx_data, void *rx_data, uint32_t size, uint32_t timeout); + +/** + \brief Send an amount of data in async mode + \param[in] qspi QSPI handle + \param[in] cmd Structure that contains the command configuration information + \param[in] data Pointer to data buffer + \param[in] size Size of data to send + \return Data number send + */ +csi_error_t csi_qspi_send_async(csi_qspi_t *qspi, csi_qspi_command_t *cmd, const void *data, uint32_t size); + +/** + \brief Receive an amount of data in async mode + \param[in] qspi QSPI handle + \param[in] cmd Structure that contains the command configuration information + \param[out] data Pointer to data buffer + \param[in] size Size of data items to receive + \return Data number received + */ +csi_error_t csi_qspi_receive_async(csi_qspi_t *qspi, csi_qspi_command_t *cmd, void *data, uint32_t size); + +/** + \brief Transfer an amount of data in async mode + \param[in] qspi QSPI handle + \param[in] cmd Structure that contains the command configuration information + \param[in] tx_data Pointer to send data buffer + \param[out] rx_data Pointer to receive data buffer + \param[in] size Size of data to transfer + \return Data number transfered + */ +csi_error_t csi_qspi_send_receive_async(csi_qspi_t *qspi, csi_qspi_command_t *cmd, const void *tx_data, void *rx_data, uint32_t size); + +/** + \brief Link DMA channel to qspi device + \param[in] qspi QSPI handle to operate + \param[in] tx_dma The DMA channel handle for send, when it is NULL means to unlink the channel + \param[in] rx_dma The DMA channel handle for receive, when it is NULL means to unlink the channel + \return Error code +*/ +csi_error_t csi_qspi_link_dma(csi_qspi_t *qspi, csi_dma_ch_t *tx_dma, csi_dma_ch_t *rx_dma); + +/** + \brief Get the state of qspi device + \param[in] qspi QSPI handle + \param[in] state QSPI state \ref csi_state_t + \return Error code + */ +csi_error_t csi_qspi_get_state(csi_qspi_t *qspi, csi_state_t *state); + +/** + \brief Comfigure the memory mapped mode + \param[in] qspi QSPI handle + \param[in] cmd Structure that contains the command configuration information + \return Error code + */ +csi_error_t csi_qspi_memory_mapped(csi_qspi_t *qspi, csi_qspi_command_t *cmd); + +/** + \brief Enable qspi power manage + \param[in] qspi QSPI handle to operate + \return Error code +*/ +csi_error_t csi_qspi_enable_pm(csi_qspi_t *qspi); + +/** + \brief Disable qspi power manage + \param[in] qspi QSPI handle to operate + \return None +*/ +void csi_qspi_disable_pm(csi_qspi_t *qspi); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_QSPI_H_*/ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/ringbuf.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/ringbuf.h new file mode 100755 index 00000000..e5006e16 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/ringbuf.h @@ -0,0 +1,62 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 ringbuffer.h +* @brief header file for ringbuffer Driver +* @version V1.0 +* @date August 15. 2019 +******************************************************************************/ +#ifndef _RING_BUFFER_H_ +#define _RING_BUFFER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stdint.h" +#include + +typedef struct ringbuffer { + uint8_t *buffer; + uint32_t size; + uint32_t write; + uint32_t read; + uint32_t data_len; +} csi_ringbuf_t; + +void csi_ringbuf_reset(csi_ringbuf_t *fifo); +uint32_t csi_ringbuf_len(csi_ringbuf_t *fifo); +uint32_t csi_ringbuf_avail(csi_ringbuf_t *fifo); +bool csi_ringbuf_is_empty(csi_ringbuf_t *fifo); +bool csi_ringbuf_is_full(csi_ringbuf_t *fifo); + +/*write to ringbuffer*/ +uint32_t csi_ringbuf_in(csi_ringbuf_t *fifo, const void *in, uint32_t len); + +/*read to ringbuffer*/ +uint32_t csi_ringbuf_out(csi_ringbuf_t *fifo, void *out, uint32_t len); + +/*move to another ringbuffer*/ +uint32_t csi_ringbuf_move(csi_ringbuf_t *fifo_in, csi_ringbuf_t *fifo_out); + +#ifdef __cplusplus +} +#endif + +#endif /* _RING_BUFFER_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/rng.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/rng.h new file mode 100755 index 00000000..11e03f44 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/rng.h @@ -0,0 +1,54 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/tng.h + * @brief Header File for RNG Driver + * @version V1.0 + * @date 22. Apr 2020 + * @model tng + ******************************************************************************/ +#ifndef _DRV_TNG_H_ +#define _DRV_TNG_H_ + +#include "drv/common.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + \brief Get data from the TNG engine + \param[out] Data Pointer to buffer with data get from TNG + \param[in] Num Number of data items,uinit in uint32 + \return Error code \ref csi_error_t +*/ +csi_error_t csi_rng_get_multi_word(uint32_t *data, uint32_t num); + +/** + \brief Get data from the TNG engine + \return Error code \ref csi_error_t +*/ +csi_error_t csi_rng_get_single_word(uint32_t* data); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_TNG_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/rsa.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/rsa.h new file mode 100755 index 00000000..ea5b005d --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/rsa.h @@ -0,0 +1,198 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/rsa.h + * @brief Header File for RSA Driver + * @version V1.0 + * @date 02. June 2020 + * @model rsa + ******************************************************************************/ +#ifndef _DRV_RSA_H_ +#define _DRV_RSA_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/*----- RSA Control Codes: Mode Parameters: Key Bits -----*/ +/****** RSA Key bits Type *****/ +typedef enum { + RSA_KEY_BITS_192 = 0U, /* 192 Key bits */ + RSA_KEY_BITS_256, /* 256 Key bits */ + RSA_KEY_BITS_512, /* 512 Key bits */ + RSA_KEY_BITS_1024, /* 1024 Key bits */ + RSA_KEY_BITS_2048, /* 2048 Key bits */ + RSA_KEY_BITS_3072, /* 3072 Key bits */ + RSA_KEY_BITS_4096 /* 4096 Key bits */ +} csi_rsa_key_bits_t; + +/****** RSA Padding Type *****/ +typedef enum { + RSA_PADDING_MODE_NO = 0, /* RSA NO Padding Mode */ + RSA_PADDING_MODE_PKCS1, /* RSA PKCS1 Padding Mode */ + RSA_PADDING_MODE_PKCS1_OAEP, /* RSA PKCS1 OAEP Padding Mode */ + RSA_PADDING_MODE_SSLV23, /* RSA SSLV23 Padding Mode */ + RSA_PADDING_MODE_X931, /* RSA X931 Padding Mode */ + RSA_PADDING_MODE_PSS /* RSA PSS Padding Mode */ +} csi_rsa_padding_type_t; + +/****** RSA Hash Type *****/ +typedef enum { + RSA_HASH_TYPE_MD5 = 0, + RSA_HASH_TYPE_SHA1, + RSA_HASH_TYPE_SHA224, + RSA_HASH_TYPE_SHA256, + RSA_HASH_TYPE_SHA384, + RSA_HASH_TYPE_SHA512 +} csi_rsa_hash_type_t; + +/****** RSA Context *****/ +typedef struct { + void *n; /* Pointer to the public modulus */ + void *e; /* Pointer to the public exponent */ + void *d; /* Pointer to the private exponent */ + csi_rsa_key_bits_t key_bits; /* RSA KEY BITS */ + csi_rsa_padding_type_t padding_type; /* RSA PADDING TYPE */ +} csi_rsa_context_t; + +/****** RSA State *****/ +typedef struct { + uint8_t busy : 1; /* Calculate busy flag */ + uint8_t error : 1; /* Calculate error flag */ +} csi_rsa_state_t; + +/****** RSA Ctrl *****/ +typedef struct { + csi_dev_t dev; + void *cb; + void *arg; + csi_rsa_state_t state; + void *prim; +} csi_rsa_t; + +/****** RSA Moddle *****/ +typedef struct { + uint32_t pout[64]; + uint8_t *pouts; + uint32_t *pout_size; + uint32_t u32keywords; + uint8_t *pdst; + uint32_t u32padding; + uint32_t u32dst_words; + uint32_t u32type; + uint32_t rsa_state; +}rsa_middle_t; + +/****** RSA Event *****/ +typedef enum { + RSA_EVENT_COMPLETE = 0, /* rsa event completed */ + RSA_EVENT_VERIFY_SUCCESS, /* rsa event verify success */ + RSA_EVENT_VERIFY_FAILED, /* rsa event verify failed */ + RSA_EVENT_ERROR, /* rsa event error */ +} csi_rsa_event_t; + +typedef void (*csi_rsa_callback_t)(csi_rsa_t *rsa, csi_rsa_event_t event, void *arg); ///< Pointer to \ref csi_rsa_callback_t : RSA Event call back. + +/** + \brief Initialize RSA Interface. 1. Initializes the resources needed for the RSA interface 2.registers event callback function + \param[in] rsa RSA handle to operate. + \param[in] idx Device id + \return Error code \ref csi_error_t +*/ +csi_error_t csi_rsa_init(csi_rsa_t *rsa, uint32_t idx); + +/** + \brief De-initialize RSA Interface. stops operation and releases the software resources used by the interface + \param[in] rsa RSA handle to operate. + \return none +*/ +void csi_rsa_uninit(csi_rsa_t *rsa); + +/** + \brief Generate rsa key pair. + \param[in] rsa RSA handle to operate. + \param[out] context Pointer to the rsa context + \return Error code \ref csi_error_t +*/ +csi_error_t csi_rsa_gen_key(csi_rsa_t *rsa, csi_rsa_context_t *context); + +/** + \brief Encrypt + \param[in] rsa RSA handle to operate. + \param[in] context Pointer to the rsa context + \param[in] src Pointer to the source data. + \param[in] src_size The source data len + \param[out] out Pointer to the result buffer + \return Error code \ref csi_error_t +*/ +csi_error_t csi_rsa_encrypt(csi_rsa_t *rsa, csi_rsa_context_t *context, void *src, uint32_t src_size, void *out); + +/** + \brief decrypt + \param[in] rsa RSA handle to operate. + \param[in] context Pointer to the rsa context + \param[in] src Pointer to the source data. + \param[in] src_size The source data len + \param[out] out Pointer to the result buffer + \param[out] out_size The result size + \return Error code \ref csi_error_t +*/ +csi_error_t csi_rsa_decrypt(csi_rsa_t *rsa, csi_rsa_context_t *context, void *src, uint32_t src_size, void *out, uint32_t *out_size); + +/** + \brief RSA sign + \param[in] rsa RSA handle to operate. + \param[in] context Pointer to the rsa context + \param[in] src Pointer to the source data. + \param[in] src_size The source data len + \param[out] signature Pointer to the signature + \param[in] hash_type The source data hash type + \return Error code \ref csi_error_t +*/ +csi_error_t csi_rsa_sign(csi_rsa_t *rsa, csi_rsa_context_t *context, void *src, uint32_t src_size, void *signature, csi_rsa_hash_type_t hash_type); + +/** + \brief RSA verify + \param[in] rsa RSA handle to operate. + \param[in] context Pointer to the rsa context + \param[in] src Pointer to the source data. + \param[in] src_size The source data len + \param[in] signature Pointer to the signature + \param[in] sig_size The signature size + \param[in] hash_type The source data hash type + \return Verify result +*/ +bool csi_rsa_verify(csi_rsa_t *rsa, csi_rsa_context_t *context, void *src, uint32_t src_size, void *signature, uint32_t sig_size, csi_rsa_hash_type_t hash_type); + +/** + \brief Get big prime data + \param[in] rsa RSA handle to operate. + \param[in] p Pointer to the prime + \param[in] bit_length Pointer to the prime bit length + \return Error code \ref csi_error_t +*/ +csi_error_t csi_rsa_get_prime(csi_rsa_t *rsa, void *p, uint32_t bit_length); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_RSA_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/rtc.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/rtc.h new file mode 100755 index 00000000..29742f3c --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/rtc.h @@ -0,0 +1,148 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/rtc.h + * @brief Header File for RTC Driver + * @version V1.0 + * @date 9. Oct 2020 + * @model rtc + ******************************************************************************/ + +#ifndef _DRV_RTC_H_ +#define _DRV_RTC_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/****** RTC time ******/ +typedef struct { + int tm_sec; ///< Second. [0-59] + int tm_min; ///< Minute. [0-59] + int tm_hour; ///< Hour. [0-23] + int tm_mday; ///< Day. [1-31] + int tm_mon; ///< Month. [0-11] + int tm_year; ///< Year-1900. [70- ] !NOTE:Set 100 mean 2000 + int tm_wday; ///< Day of week. [0-6 ] !NOTE:Set 0 mean Sunday + int tm_yday; ///< Days in year.[0-365] !NOTE:Set 0 mean January 1st +} csi_rtc_time_t; + +/****** definition for RTC ******/ +typedef struct csi_rtc csi_rtc_t; + +struct csi_rtc { + csi_dev_t dev; + void (*callback)(csi_rtc_t *rtc, void *arg); + void *arg; + void *priv; +}; + +/** + \brief Initialize RTC interface. Initializes the resources needed for the RTC interface + \param[in] rtc Handle to operate + \param[in] idx RTC index + \return Error code \ref csi_error_t +*/ +csi_error_t csi_rtc_init(csi_rtc_t *rtc, uint32_t idx); + +/** + \brief De-initialize RTC interface. Stops operation and releases the software resources used by the interface + \param[in] rtc Handle to operate + \return None +*/ +void csi_rtc_uninit(csi_rtc_t *rtc); + +/** + \brief Set system date and wait for synchro + \param[in] rtc Handle to operate + \param[in] rtctime Pointer to RTC time + \return Error code \ref csi_error_t +*/ +csi_error_t csi_rtc_set_time(csi_rtc_t *rtc, const csi_rtc_time_t *rtctime); + +/** + \brief Set system date but no wait + \param[in] rtc Handle to operate + \param[in] rtctime Pointer to RTC time + \return Error code \ref csi_error_t +*/ +csi_error_t csi_rtc_set_time_no_wait(csi_rtc_t *rtc, const csi_rtc_time_t *rtctime); + +/** + \brief Get system date + \param[in] rtc Handle to operate + \param[out] rtctime Pointer to RTC time + \return Error code \ref csi_error_t +*/ +csi_error_t csi_rtc_get_time(csi_rtc_t *rtc, csi_rtc_time_t *rtctime); + +/** + \brief Get alarm remaining time + \param[in] rtc Handle to operate + \return The remaining time(s) +*/ +uint32_t csi_rtc_get_alarm_remaining_time(csi_rtc_t *rtc); + +/** + \brief Config RTC alarm timer + \param[in] rtc Handle to operate + \param[in] rtctime Time to wake up + \param[in] callback Callback function + \param[in] arg Callback's param + \return Error code \ref csi_error_t +*/ +csi_error_t csi_rtc_set_alarm(csi_rtc_t *rtc, const csi_rtc_time_t *rtctime, void *callback, void *arg); + +/** + \brief Cancel the RTC alarm + \param[in] rtc Handle to operate + \return Error code \ref csi_error_t +*/ +csi_error_t csi_rtc_cancel_alarm(csi_rtc_t *rtc); + +/** + \brief Judge RTC is running + \param[in] rtc Handle to operate + \return + true - RTC is running + false - RTC is not running +*/ +bool csi_rtc_is_running(csi_rtc_t *rtc); + +/** + \brief Enable RTC power manage + \param[in] rtc Handle to operate + \return Error code \ref csi_error_t +*/ +csi_error_t csi_rtc_enable_pm(csi_rtc_t *rtc); + +/** + \brief Disable RTC power manage + \param[in] rtc Handle to operate + \return None +*/ +void csi_rtc_disable_pm(csi_rtc_t *rtc); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_RTC_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/sasc.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/sasc.h new file mode 100755 index 00000000..6a7f6a04 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/sasc.h @@ -0,0 +1,144 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/sasc.h + * @brief Header File for SASC driver + * @version V1.0 + * @date 02. June 2020 + * @model sasc + ******************************************************************************/ +#ifndef _DRV_SASC_H_ +#define _DRV_SASC_H_ + + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +typedef enum { + SASC_RW = 0, + SASC_RO = 1, + SASC_WO = 2, + SASC_AP_DENY = 3 +} csi_sasc_ap_t; + +typedef enum { + SASC_DI = 0, + SASC_DO = 1, + SASC_IO = 2, + SASC_DI_DENY = 3 +} csi_sasc_di_t; + +typedef enum { + SASC_RAM_4B = 5, + SASC_RAM_8B = 6, + SASC_RAM_16B = 7, + SASC_RAM_32B = 8, + SASC_RAM_64B = 9, + SASC_RAM_128B = 10, + SASC_RAM_256B = 11, + SASC_RAM_512B = 12, + SASC_RAM_1KB = 13, + SASC_RAM_2KB = 14, + SASC_RAM_4KB = 15, + SASC_RAM_8KB = 16, + SASC_RAM_16KB = 17, + SASC_RAM_32KB = 18, + SASC_RAM_64KB = 19, + SASC_RAM_128KB = 20, +} csi_sasc_ram_size_t; + +typedef enum { + SASC_FLASH_1S = 0, + SASC_FLASH_2S, + SASC_FLASH_4S, + SASC_FLASH_8S, + SASC_FLASH_16S, + SASC_FLASH_32S, + SASC_FLASH_64S, + SASC_FLASH_128S, + SASC_FLASH_256S, + SASC_FLASH_512S, + SASC_FLASH_1024S, + SASC_FLASH_2048S +} csi_sasc_flash_size_t; + +typedef struct { + csi_sasc_ap_t super_ap; + csi_sasc_ap_t user_ap; + csi_sasc_di_t super_di; + csi_sasc_di_t user_di; + bool is_secure; +} csi_sasc_attr_t; + +/** + \brief Config the sasc ram region attribute. + \param[in] region_id Config region index + \param[in] base_addr Config region base address. + \param[in] size config region size. + \param[in] attr Region attr. + \return Error code +*/ +csi_error_t csi_sasc_ram_config(uint8_t region_id, uint32_t base_addr, csi_sasc_ram_size_t size, csi_sasc_attr_t attr); + +/** + \brief Config the sasc flash region attribute. + \param[in] region_id Config region index + \param[in] base_addr Config region base address. + \param[in] size Config region size. + \param[in] attr Region attr. + \return Error code +*/ +csi_error_t csi_sasc_flash_config(uint8_t region_id, uint32_t base_addr, csi_sasc_flash_size_t size, csi_sasc_attr_t attr); + +/** + \brief Enable sasc ram config. + \param[in] region_id Region index + \return error code +*/ +csi_error_t csi_sasc_ram_enable(uint8_t region_id); + +/** + \brief Enable sasc flash config + \param[in] region_id Config region index + \return error code +*/ +csi_error_t csi_sasc_flash_enable(uint8_t region_id); + +/** + \brief Disable sasc ram config. + \param[in] region_id Region index + \return error code +*/ +csi_error_t csi_sasc_ram_disable(uint8_t region_id); + +/** + \brief Disable sasc flash config + \param[in] region_id Region index + \return error code +*/ +csi_error_t csi_sasc_flash_disable(uint8_t region_id); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_SASC_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/sdif.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/sdif.h new file mode 100755 index 00000000..0508912b --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/sdif.h @@ -0,0 +1,441 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/sdif.h + * @brief Header File for SDIF Driver + * @version V1.0 + * @date 28. June 2020 + * @model sdif + ******************************************************************************/ +#ifndef _DRV_SDIF_H_ +#define _DRV_SDIF_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *sdif_handle_t; + +/*! @brief Construct a status code value from a group and code number. */ +#define MAKE_STATUS(group, code) ((((group)*100) + (code))) + +/*! @brief Status group numbers. */ +enum _status_groups { + kStatusGroup_Generic = 0, /*!< Group number for generic status codes. */ + kStatusGroup_SDMMC = 18, /*!< Group number for SDMMC status code */ + kStatusGroup_SDIF = 59, /*!< Group number for SDIF status codes.*/ + kStatusGroup_ApplicationRangeStart = 101, /*!< Starting number for application groups. */ +}; + +/*! @brief Generic status return codes. */ +enum _generic_status { + kStatus_Success = MAKE_STATUS(kStatusGroup_Generic, 0), + kStatus_Fail = MAKE_STATUS(kStatusGroup_Generic, 1), + kStatus_ReadOnly = MAKE_STATUS(kStatusGroup_Generic, 2), + kStatus_OutOfRange = MAKE_STATUS(kStatusGroup_Generic, 3), + kStatus_InvalidArgument = MAKE_STATUS(kStatusGroup_Generic, 4), + kStatus_Timeout = MAKE_STATUS(kStatusGroup_Generic, 5), + kStatus_NoTransferInProgress = MAKE_STATUS(kStatusGroup_Generic, 6), +}; + +/*! @brief SDIF status */ +enum _sdif_status { + kStatus_SDIF_DescriptorBufferLenError = MAKE_STATUS(kStatusGroup_SDIF, 0U), /*!< Set DMA descriptor failed */ + kStatus_SDIF_InvalidArgument = MAKE_STATUS(kStatusGroup_SDIF, 1U), /*!< invalid argument status */ + kStatus_SDIF_SyncCmdTimeout = MAKE_STATUS(kStatusGroup_SDIF, 2U), /*!< sync command to CIU timeout status */ + kStatus_SDIF_SendCmdFail = MAKE_STATUS(kStatusGroup_SDIF, 3U), /*!< send command to card fail */ + kStatus_SDIF_SendCmdErrorBufferFull = + MAKE_STATUS(kStatusGroup_SDIF, 4U), /*!< send command to card fail, due to command buffer full + user need to resend this command */ + kStatus_SDIF_DMATransferFailWithFBE = + MAKE_STATUS(kStatusGroup_SDIF, 5U), /*!< DMA transfer data fail with fatal bus error , + to do with this error :issue a hard reset/controller reset*/ + kStatus_SDIF_DMATransferDescriptorUnavailable = + MAKE_STATUS(kStatusGroup_SDIF, 6U), /*!< DMA descriptor unavailable */ + kStatus_SDIF_DataTransferFail = MAKE_STATUS(kStatusGroup_SDIF, 6U), /*!< transfer data fail */ + kStatus_SDIF_ResponseError = MAKE_STATUS(kStatusGroup_SDIF, 7U), /*!< response error */ + kStatus_SDIF_DMAAddrNotAlign = MAKE_STATUS(kStatusGroup_SDIF, 8U), /*!< DMA address not align */ +}; + +/*! @brief Type used for all status and error return values. */ +typedef int32_t status_t; + +/*! @brief Computes the number of elements in an array. */ +#if !defined(ARRAY_SIZE) +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#endif + +/*! Macro to change a value to a given size aligned value */ +#define SDK_SIZEALIGN(var, alignbytes) \ + ((unsigned int)((var) + ((alignbytes)-1)) & (unsigned int)(~(unsigned int)((alignbytes)-1))) + +///< #define assert(__e) ((void)0) +/*! @name Min/max macros */ +#if !defined(MIN) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif + +#if !defined(MAX) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#endif + +#define SDK_ALIGN(var, alignbytes) var + +static inline unsigned long cpu_to_dma(unsigned long addr) +{ + return addr; +} + +static inline unsigned long *ptr_cpu_to_dma(unsigned long *addr) +{ + return (unsigned long *)cpu_to_dma((unsigned long)addr); +} + +typedef enum { + SDIF_ERROR_CMD_CRC_FAIL = (1), ///< Command response received (but CRC check failed) + SDIF_ERROR_DATA_CRC_FAIL, ///< Data block sent/received (CRC check failed) + SDIF_ERROR_CMD_RSP_TIMEOUT, ///< Command response timeout + SDIF_ERROR_DATA_TIMEOUT, ///< Data timeout + SDIF_ERROR_TX_UNDERRUN, ///< Transmit FIFO underrun + SDIF_ERROR_RX_OVERRUN, ///< Receive FIFO overrun + SDIF_ERROR_ADDR_MISALIGNED, ///< Misaligned address + SDIF_ERROR_BLOCK_LEN_ERR, ///< Transferred block length is not allowed for the card or the number of transferred bytes does not match the block length + SDIF_ERROR_ERASE_SEQ_ERR, ///< An error in the sequence of erase command occurs + SDIF_ERROR_BAD_ERASE_PARAM, ///< An invalid selection for erase groups + SDIF_ERROR_WRITE_PROT_VIOLATION, ///< Attempt to program a write protect block + SDIF_ERROR_LOCK_UNLOCK_FAILED, ///< Sequence or password error has been detected in unlock command or if there was an attempt to access a locked card + SDIF_ERROR_COM_CRC_FAILED, ///< CRC check of the previous command failed + SDIF_ERROR_ILLEGAL_CMD, ///< Command is not legal for the card state + SDIF_ERROR_CARD_ECC_FAILED, ///< Card internal ECC was applied but failed to correct the data + SDIF_ERROR_CC_ERR, ///< Internal card controller error + SDIF_ERROR_GENERAL_UNKNOWN_ERR, ///< General or unknown error + SDIF_ERROR_STREAM_READ_UNDERRUN, ///< The card could not sustain data reading in stream rmode + SDIF_ERROR_STREAM_WRITE_OVERRUN, ///< The card could not sustain data programming in stream mode + SDIF_ERROR_CID_CSD_OVERWRITE, ///< CID/CSD overwrite error + SDIF_ERROR_WP_ERASE_SKIP, ///< Only partial address space was erased + SDIF_ERROR_CARD_ECC_DISABLED, ///< Command has been executed without using internal ECC + SDIF_ERROR_ERASE_RESET, ///< Erase sequence was cleared before executing because an out + SDIF_ERROR_AKE_SEQ_ERR, ///< Error in sequence of authentication + SDIF_ERROR_INVALID_VOLTRANGE, ///< Error in case of invalid voltage range + SDIF_ERROR_ADDR_OUT_OF_RANGE, ///< Error when addressed block is out of range + SDIF_ERROR_REQUEST_NOT_APPLICABLE, ///< Error when command request is not applicable + SDIF_ERROR_UNSUPPORTED_FEATURE, ///< Error when feature is not insupported +} sdif_error_e; + +/* Host controller capabilities flag mask */ +typedef enum { + SDIF_SUPPORT_HIGH_SPEED = 0x1U, ///< Support high-speed + SDIF_SUPPORT_DMA_SPEED = 0x2U, ///< Support DMA + SDIF_SUPPORT_USPEND_RESUME = 0x4U, ///< Support suspend/resume + SDIF_SUPPORT_V330 = 0x8U, ///< Support voltage 3.3V + SDIF_SUPPORT_4BIT = 0x10U, ///< Support 4 bit mode + SDIF_SUPPORT_8BIT = 0x20U, ///< Support 8 bit mode +} sdif_capability_flag_e; + +/* \brief define the internal DMA mode */ +typedef enum { + SDIF_CHAIN_DMA_MODE = 0x01U, ///< one descriptor with one buffer,but one descriptor point to another + SDIF_DUAL_DMA_MODE = 0x02U, ///< dual mode is one descriptor with two buffer +} sdif_dma_mode_e; + +/* The command type */ +typedef enum { + SDIF_CARD_COMMAND_NORMAL = 0U, ///< Normal command + SDIF_CARD_COMMAND_SUSPEND = 1U, ///< Suspend command + SDIF_CARD_COMMAND_RESUME = 2U, ///< Resume command + SDIF_CARD_COMMAND_ABORT = 3U, ///< Abort command +} sdif_card_command_type_e; + +/* The command response type */ +typedef enum { + SDIF_CARD_RESPONSE_NONE = 0U, ///< Response type: none + SDIF_CARD_RESPONSE_R1 = 1U, ///< Response type: R1 + SDIF_CARD_RESPONSE_R1b = 2U, ///< Response type: R1b + SDIF_CARD_RESPONSE_R2 = 3U, ///< Response type: R2 + SDIF_CARD_RESPONSE_R3 = 4U, ///< Response type: R3 + SDIF_CARD_RESPONSE_R4 = 5U, ///< Response type: R4 + SDIF_CARD_RESPONSE_R5 = 6U, ///< Response type: R5 + SDIF_CARD_RESPONSE_R5b = 7U, ///< Response type: R5b + SDIF_CARD_RESPONSE_R6 = 8U, ///< Response type: R6 + SDIF_CARD_RESPONSE_R7 = 9U, ///< Response type: R7 +} sdif_card_response_type_e; + +/* \brief define the card bus width type */ +typedef enum { + SDIF_BUS_1BIT_WIDTH = 0U, ///< 1bit bus width, 1bit mode and 4bit mode share one register bit + SDIF_BUS_4BIT_WIDTH = 1U, ///< 4bit mode mask + SDIF_BUS_8BIT_WIDTH = 2U, ///< support 8 bit mode +} sdif_bus_width_e; + +/* \brief Defines the internal DMA configure structure. */ +typedef struct { + bool enable_fix_burst_len; ///< fix burst len enable/disable flag,When set, the AHB will + ///< use only SINGLE, INCR4, INCR8 or INCR16 during start of + ///< normal burst transfers. When reset, the AHB will use SINGLE + ///< and INCR burst transfer operations + + sdif_dma_mode_e mode; ///< define the DMA mode */ + + + uint32_t *dma_des_buffer_start_addr; ///< internal DMA descriptor start address + uint32_t dma_des_buffer_len; ///< internal DMA buffer descriptor buffer len ,user need to pay attention to the + ///< dma descriptor buffer length if it is bigger enough for your transfer + uint8_t dma_dws_skip_len; ///< define the descriptor skip length ,the length between two descriptor + ///< this field is special for dual DMA mode +} sdif_dma_config_t; + +/* \brief sdif callback functions. */ +typedef struct { + void (*card_inserted)(uint32_t idx, void *user_data); ///< card insert call back + void (*card_removed)(uint32_t idx, void *user_data); ///< card remove call back + void (*sdif_interrupt)(uint32_t idx, void *user_data); ///< SDIF card interrupt occurs + void (*dma_des_unavailable)(uint32_t idx, void *user_data);///< DMA descriptor unavailable + void (*command_reload)(uint32_t idx, void *user_data); ///< command buffer full,need re-load + void (*transfer_complete)(uint32_t idx, + void *state, + int32_t status, + void *user_data); /// +#include +#include + + +typedef enum { + SENSOR_VDS_3V3_3V3 = 1, + SENSOR_VDS_2V5_3V3, + SENSOR_VDS_1V8_1V8, + SENSOR_VDS_1V5_1V8, + SENSOR_VDS_1V2_1V2, + SENSOR_VDS_1V1_1V2 +}drv_sensor_vds_t; + +typedef enum { + SENSOR_VHS_RANGE_15 = 0, + SENSOR_VHS_RANGE_12, + SENSOR_VHS_RANGE_9, + SENSOR_VHS_RANGE_6, +}drv_sensor_vhs_t; + +typedef enum { + SENSOR_VLS_RANGE_6 = 0, + SENSOR_VLS_RANGE_9, + SENSOR_VLS_RANGE_12, + SENSOR_VLS_RANGE_15, +}drv_sensor_vls_t; + +typedef enum { + SENSOR_TDHS_NEG_55 = 0, ///< -55 + SENSOR_TDHS_NEG_50, + SENSOR_TDHS_NEG_45, + SENSOR_TDHS_NEG_40, + SENSOR_TDHS_NEG_35, + SENSOR_TDHS_NEG_30, + SENSOR_TDHS_NEG_25, + SENSOR_TDHS_NEG_20, + SENSOR_TDHS_NEG_15, + SENSOR_TDHS_NEG_10, + SENSOR_TDHS_NEG_5, + SENSOR_TDHS_NEG_0, + SENSOR_TDHS_POS_5, ///< +5 + SENSOR_TDHS_POS_10, + SENSOR_TDHS_POS_15, + SENSOR_TDHS_POS_20, + SENSOR_TDHS_POS_25, + SENSOR_TDHS_POS_30, + SENSOR_TDHS_POS_35, + SENSOR_TDHS_POS_40, + SENSOR_TDHS_POS_45, + SENSOR_TDHS_POS_50, + SENSOR_TDHS_POS_55, + SENSOR_TDHS_POS_60, + SENSOR_TDHS_POS_65, + SENSOR_TDHS_POS_70, + SENSOR_TDHS_POS_75, + SENSOR_TDHS_POS_80, + SENSOR_TDHS_POS_85, + SENSOR_TDHS_POS_90, + SENSOR_TDHS_POS_95, + SENSOR_TDHS_POS_100, + SENSOR_TDHS_POS_105, + SENSOR_TDHS_POS_110, + SENSOR_TDHS_POS_115, + SENSOR_TDHS_POS_120, + SENSOR_TDHS_POS_125 +}drv_sensor_tdhs_t; + +typedef enum { + SENSOR_TDLS_NEG_55 = 0, ///< -55 + SENSOR_TDLS_NEG_50, + SENSOR_TDLS_NEG_45, + SENSOR_TDLS_NEG_40, + SENSOR_TDLS_NEG_35, + SENSOR_TDLS_NEG_30, + SENSOR_TDLS_NEG_25, + SENSOR_TDLS_NEG_20, + SENSOR_TDLS_NEG_15, + SENSOR_TDLS_NEG_10, + SENSOR_TDLS_NEG_5, + SENSOR_TDLS_NEG_0, + SENSOR_TDLS_POS_5, ///< +5 + SENSOR_TDLS_POS_10, + SENSOR_TDLS_POS_15, + SENSOR_TDLS_POS_20, +}drv_sensor_tdls_t; + +typedef enum { + SENSOR_FHS_RANGE_50 = 0, + SENSOR_FHS_RANGE_30, + SENSOR_FHS_RANGE_10, + SENSOR_FHS_RANGE_5, +}drv_sensor_fhs_t; + +typedef enum { + SENSOR_FLS_RANGE_50 = 0, + SENSOR_FLS_RANGE_30, + SENSOR_FLS_RANGE_10, + SENSOR_FLS_RANGE_5, +}drv_sensor_fls_t; + +typedef enum { + SENSOR_FHS_FREQ_33M = 0, + SENSOR_FHS_FREQ_66M, + SENSOR_FHS_FREQ_24M, + SENSOR_FHS_FREQ_12M, + SENSOR_FHS_FREQ_99M, + SENSOR_FHS_FREQ_198M, + SENSOR_FHS_FREQ_72M, + SENSOR_FHS_FREQ_36M, +}drv_sensor_freq_t; + +typedef enum { + SENSOR_WARN_H = 0, + SENSOR_WARN_L, + SENSOR_WARN_RST, +}drv_sensor_warn_t; + +/** + \brief Initialize Sensor VD + \param[in] vds Voltage range + \param[in] vhs Voltage high threshold + \param[in] vls Voltage low threshold + \param[in] vtm Used to modify the threshold value of the voltage detection point + \return Error code +*/ +csi_error_t drv_sensor_vd_init(drv_sensor_vds_t vds,drv_sensor_vhs_t vhs,drv_sensor_vls_t vls,uint8_t vtm); + +/** + \brief Get vd warn + \param[in] warn Vd warn select + \return Vd warn code +*/ +uint32_t drv_sensor_vd_get_warn(drv_sensor_warn_t warn); + +/** + \brief Initialize Sensor td + \param[in] hs Temp high threshold + \param[in] ls Temp low threshold + \return Error code +*/ +csi_error_t drv_sensor_td_init(drv_sensor_tdhs_t hs,drv_sensor_tdls_t ls); + +/** + \brief Get td warn + \param[in] warn Td warn select + \return Td warn code +*/ +uint32_t drv_sensor_td_get_warn(drv_sensor_warn_t warn); + +/** + \brief Initialize Sensor FD + \param[in] hs Temp high threshold + \param[in] ls Temp low threshold + \return Error code +*/ +csi_error_t drv_sensor_fd_init(drv_sensor_freq_t freq,drv_sensor_fhs_t fhs,drv_sensor_fls_t fls); + +/** + \brief Get fd warn + \param[in] warn Fd warn select + \return FD warn code +*/ +uint32_t drv_sensor_fd_get_warn(drv_sensor_warn_t warn); + +#endif /* _DRV_SENSOR_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/sha.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/sha.h new file mode 100755 index 00000000..668b9dcc --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/sha.h @@ -0,0 +1,128 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/sha.h + * @brief Header File for SHA Driver + * @version V1.0 + * @date 9. Oct 2020 + * @model sha + ******************************************************************************/ + +#ifndef _DRV_SHA_H_ +#define _DRV_SHA_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/****** SHA mode ******/ +typedef enum { + SHA_MODE_1 = 1U, /* SHA_1 mode */ + SHA_MODE_256, /* SHA_256 mode */ + SHA_MODE_224, /* SHA_224 mode */ + SHA_MODE_512, /* SHA_512 mode */ + SHA_MODE_384, /* SHA_384 mode */ + SHA_MODE_512_256, /* SHA_512_256 mode */ + SHA_MODE_512_224, /* SHA_512_224 mode */ + SHA_MODE_MD5 /* MD5 mode */ +} csi_sha_mode_t; + +/****** SHA State ******/ +typedef struct { + uint32_t busy : 1; /* Calculate busy flag */ + uint32_t error : 1; /* Calculate error flag */ +} csi_sha_state_t; + +/****** SHA Context ******/ +typedef struct { + csi_sha_mode_t mode; /* SHA mode */ + uint32_t total[2]; /* Number of bytes processed */ + uint32_t state[16]; /* Intermediate digest state */ + uint8_t buffer[128]; /* Data block being processed */ +} csi_sha_context_t; + +/****** SHA Event ******/ +typedef enum { + SHA_EVENT_COMPLETE = 0U, /*Calculate completed*/ + SHA_EVENT_ERROR /*Calculate error*/ +} csi_sha_event_t; + +/****** SHA Ctrl ******/ +typedef struct csi_sha csi_sha_t; +struct csi_sha{ + csi_dev_t dev; + void (*callback)(csi_sha_t *sha, csi_sha_event_t event, void *arg); /* SHA event callback for user */ + void *arg; /* SHA custom designed param passed to evt_cb */ + csi_dma_ch_t *dma_in; /* SHA in dma handle param */ + csi_sha_state_t state; /* SHA state */ + void *priv; +}; + +/** + \brief Initialize SHA Interface. Initializes the resources needed for the SHA interface + \param[in] sha Operate handle + \param[in] idx Index of SHA + \return Error code \ref csi_error_t +*/ +csi_error_t csi_sha_init(csi_sha_t *sha, uint32_t idx); + +/** + \brief De-initialize SHA Interface. Stops operation and releases the software resources used by the interface + \param[in] sha SHA handle to operate + \return None +*/ +void csi_sha_uninit(csi_sha_t *sha); + +/** + \brief Start the engine + \param[in] sha Handle to operate + \param[in] context Pointer to the SHA context \ref csi_sha_context_t + \param[in] mode SHA mode \ref csi_sha_mode_t + \return Error code \ref csi_error_t +*/ +csi_error_t csi_sha_start(csi_sha_t *sha, csi_sha_context_t *context, csi_sha_mode_t mode); + +/** + \brief Update the engine + \param[in] sha Handle to operate + \param[in] context Pointer to the SHA context \ref csi_sha_context_t + \param[in] input Pointer to the Source data + \param[in] size The data size + \return Error code \ref csi_error_t +*/ +csi_error_t csi_sha_update(csi_sha_t *sha, csi_sha_context_t *context, const void *input, uint32_t size); + +/** + \brief Finish the engine + \param[in] sha Handle to operate + \param[in] context Pointer to the SHA context \ref csi_sha_context_t + \param[out] output Pointer to the result data + \param[out] out_size Pointer to the result data size(bytes) + \return Error code \ref csi_error_t +*/ +csi_error_t csi_sha_finish(csi_sha_t *sha, csi_sha_context_t *context, void *output, uint32_t *out_size); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_SHA_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/spi.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/spi.h new file mode 100755 index 00000000..80f7e4d3 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/spi.h @@ -0,0 +1,293 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/spi.h + * @brief Header File for SPI Driver + * @version V1.0 + * @date 08. Apr 2020 + * @model spi + ******************************************************************************/ + +#ifndef _DRV_SPI_H_ +#define _DRV_SPI_H_ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \enum csi_spi_mode_t + * \brief Function mode of spi + */ +typedef enum { + SPI_MASTER, ///< SPI Master (Output on MOSI, Input on MISO); arg = Bus Speed in bps + SPI_SLAVE, ///< SPI Slave (Output on MISO, Input on MOSI) +} csi_spi_mode_t; + +/** + * \enum csi_spi_frame_len_t + * \brief SPI data width (4bit ~ 16bit) + */ +typedef enum { + SPI_FRAME_LEN_4 = 4, + SPI_FRAME_LEN_5, + SPI_FRAME_LEN_6, + SPI_FRAME_LEN_7, + SPI_FRAME_LEN_8, + SPI_FRAME_LEN_9, + SPI_FRAME_LEN_10, + SPI_FRAME_LEN_11, + SPI_FRAME_LEN_12, + SPI_FRAME_LEN_13, + SPI_FRAME_LEN_14, + SPI_FRAME_LEN_15, + SPI_FRAME_LEN_16 +} csi_spi_frame_len_t; + +/** + * \enum csi_spi_format_t + * \brief Timing format of spi + */ +typedef enum { + SPI_FORMAT_CPOL0_CPHA0 = 0, ///< Clock Polarity 0, Clock Phase 0 + SPI_FORMAT_CPOL0_CPHA1, ///< Clock Polarity 0, Clock Phase 1 + SPI_FORMAT_CPOL1_CPHA0, ///< Clock Polarity 1, Clock Phase 0 + SPI_FORMAT_CPOL1_CPHA1, ///< Clock Polarity 1, Clock Phase 1 +} csi_spi_cp_format_t; + +/** + * \enum csi_spi_event_t + * \brief Signaled event for user by driver + */ +typedef enum { + SPI_EVENT_SEND_COMPLETE, ///< Data Send completed. Occurs after call to csi_spi_send_async to indicate that all the data has been send over + SPI_EVENT_RECEIVE_COMPLETE, ///< Data Receive completed. Occurs after call to csi_spi_receive_async to indicate that all the data has been received + SPI_EVENT_SEND_RECEIVE_COMPLETE, ///< Data Send_receive completed. Occurs after call to csi_spi_send_receive_async to indicate that all the data has been send_received + SPI_EVENT_ERROR_OVERFLOW, ///< Data overflow: Receive overflow + SPI_EVENT_ERROR_UNDERFLOW, ///< Data underflow: Transmit underflow + SPI_EVENT_ERROR ///< Master Mode Fault (SS deactivated when Master).Occurs in master mode when Slave Select is deactivated and indicates Master Mode Fault +} csi_spi_event_t; + +/** + * \struct csi_spi_t + * \brief Ctrl block of spi instance + */ +typedef struct csi_spi csi_spi_t; +struct csi_spi { + csi_dev_t dev; ///< Hw-device info + void (*callback)(csi_spi_t *spi, csi_spi_event_t event, void *arg); ///< User callback ,signaled by driver event + void *arg; ///< User private param ,passed to user callback + uint8_t *tx_data; ///< Output data buf + uint32_t tx_size; ///< Output data size specified by user + uint8_t *rx_data; ///< Input data buf + uint32_t rx_size; ///< Input data size specified by user + csi_error_t (*send)(csi_spi_t *spi, const void *data, uint32_t size); ///< The send_async func + csi_error_t (*receive)(csi_spi_t *spi, void *data, uint32_t size); ///< The receive_async func + csi_error_t (*send_receive)(csi_spi_t *spi, const void *data_out, void *data_in, uint32_t size); ///< The send_receive_async func + csi_state_t state; ///< Peripheral state + csi_dma_ch_t *tx_dma; + csi_dma_ch_t *rx_dma; + void *priv; +}; + +/** + \brief Initialize SPI Interface + Initialize the resources needed for the SPI instance + \param[in] spi SPI handle + \param[in] idx SPI instance index + \return Error code +*/ +csi_error_t csi_spi_init(csi_spi_t *spi, uint32_t idx); + +/** + \brief De-initialize SPI Interface + stops Operation and releases the software resources used by the spi instance + \param[in] spi Handle + \return None +*/ +void csi_spi_uninit(csi_spi_t *spi); + +/** + \brief Attach the callback handler to SPI + \param[in] spi Operate handle + \param[in] callback Callback function + \param[in] arg User can define it by himself as callback's param + \return Error code +*/ +csi_error_t csi_spi_attach_callback(csi_spi_t *spi, void *callback, void *arg); + +/** + \brief Detach the callback handler + \param[in] spi Operate handle + \return None +*/ +void csi_spi_detach_callback(csi_spi_t *spi); + +/** + \brief Config spi mode (master or slave) + \param[in] spi SPI handle + \param[in] mode The mode of spi (master or slave) + \return Error code +*/ +csi_error_t csi_spi_mode(csi_spi_t *spi, csi_spi_mode_t mode); + +/** + \brief Config spi cp format + \param[in] spi SPI handle + \param[in] format SPI cp format + \return Error code +*/ +csi_error_t csi_spi_cp_format(csi_spi_t *spi, csi_spi_cp_format_t format); + +/** + \brief Config spi frame len + \param[in] spi SPI handle + \param[in] length SPI frame len + \return Error code +*/ +csi_error_t csi_spi_frame_len(csi_spi_t *spi, csi_spi_frame_len_t length); + +/** + \brief Config spi work frequence + \param[in] spi SPI handle + \param[in] baud SPI work baud + \return the actual config frequency +*/ +uint32_t csi_spi_baud(csi_spi_t *spi, uint32_t baud); + +/** + \brief Sending data to SPI transmitter,(received data is ignored) + blocking mode ,return unti all data has been sent or err happened + \param[in] spi Handle to operate + \param[in] data Pointer to buffer with data to send to SPI transmitter + \param[in] size Number of data to send(byte) + \param[in] timeout Unit in mini-second + \return If send successful, this function shall return the num of data witch is sent successful + otherwise, the function shall return Error code +*/ +int32_t csi_spi_send(csi_spi_t *spi, const void *data, uint32_t size, uint32_t timeout); + +/** + \brief Sending data to SPI transmitter,(received data is ignored) + non-blocking mode,transfer done event will be signaled by driver + \param[in] spi Handle to operate + \param[in] data Pointer to buffer with data to send to SPI transmitter + \param[in] size Number of data items to send(byte) + \return Error code +*/ +csi_error_t csi_spi_send_async(csi_spi_t *spi, const void *data, uint32_t size); + +/** + \brief Receiving data from SPI receiver + blocking mode, return untill curtain data items are readed + \param[in] spi Handle to operate + \param[out] data Pointer to buffer for data to receive from SPI receiver + \param[in] size Number of data items to receive(byte) + \param[in] timeout Unit in mini-second + \return If receive successful, this function shall return the num of data witch is received successful + otherwise, the function shall return Error code +*/ +int32_t csi_spi_receive(csi_spi_t *spi, void *data, uint32_t size, uint32_t timeout); + +/** + \brief Receiving data from SPI receiver + not-blocking mode, event will be signaled when receive done or err happend + \param[in] spi Handle to operate + \param[out] data Pointer to buffer for data to receive from SPI receiver + \param[in] size Number of data items to receive(byte) + \return Error code +*/ +csi_error_t csi_spi_receive_async(csi_spi_t *spi, void *data, uint32_t size); + +/** + \brief Dulplex,sending and receiving data at the same time + \ref csi_spi_event_t is signaled when operation completes or error happens + \ref csi_spi_get_state can get operation status + blocking mode, this function returns after operation completes or error happens + \param[in] spi SPI handle to operate + \param[in] data_out Pointer to buffer with data to send to SPI transmitter + \param[out] data_in Pointer to buffer for data to receive from SPI receiver + \param[in] size Data size(byte) + \return If transfer successful, this function shall return the num of data witch is transfer successful, + otherwise, the function shall return Error code +*/ +int32_t csi_spi_send_receive(csi_spi_t *spi, const void *data_out, void *data_in, uint32_t size, uint32_t timeout); + +/** + \brief Transmit first then receive ,receive will begin after transmit is done + if non-blocking mode, this function only starts the transfer, + \ref csi_spi_event_t is signaled when operation completes or error happens + \ref csi_spi_get_state can get operation status + \param[in] spi SPI handle to operate + \param[in] data_out Pointer to buffer with data to send to SPI transmitter + \param[out] data_in Pointer to buffer for data to receive from SPI receiver + \param[in] size Data size(byte) + \return Error code +*/ +csi_error_t csi_spi_send_receive_async(csi_spi_t *spi, const void *data_out, void *data_in, uint32_t size); + +/* + \brief Set slave select num. Only valid for master + \param[in] handle SPI handle to operate + \param[in] slave_num SPI slave num + \return None + */ +void csi_spi_select_slave(csi_spi_t *spi, uint32_t slave_num); + +/** + \brief Link DMA channel to spi device + \param[in] spi SPI handle to operate + \param[in] tx_dma The DMA channel handle for send, when it is NULL means to unlink the channel + \param[in] rx_dma The DMA channel handle for receive, when it is NULL means to unlink the channel + \return Error code +*/ +csi_error_t csi_spi_link_dma(csi_spi_t *spi, csi_dma_ch_t *tx_dma, csi_dma_ch_t *rx_dma); + +/** + \brief Get the state of spi device + \param[in] spi SPI handle to operate + \param[out] state The state of spi device + \return Error code +*/ +csi_error_t csi_spi_get_state(csi_spi_t *spi, csi_state_t *state); + +/** + \brief Enable spi power manage + \param[in] spi SPI handle to operate + \return Error code +*/ +csi_error_t csi_spi_enable_pm(csi_spi_t *spi); + +/** + \brief Disable spi power manage + \param[in] spi SPI handle to operate + \return Error code +*/ +void csi_spi_disable_pm(csi_spi_t *spi); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_SPI_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/spiflash.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/spiflash.h new file mode 100755 index 00000000..64a24ca9 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/spiflash.h @@ -0,0 +1,303 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/spiflash.h + * @brief Header File for SPIFLASH Driver + * @version V1.0 + * @date 02. June 2020 + * @model spiflash + ******************************************************************************/ +#ifndef _DRV_SPIFLASH_H_ +#define _DRV_SPIFLASH_H_ + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** +* \brief Build a flash ID +* \param [in] vendor_id Vendor id(8bit) +* \param [in] device_id Flash device id (ID15~ID0) 16bit +* \return 24bit flash id +*/ +#define FLASH_ID_BUILD(VENDOR_ID,DEVICE_ID) + +/** +* \struct csi_spiflash_lock_info_t +* \ flash use status register 1 to protect data in memory array +* \ different flash vendor support different protect region (top/bottom/none) +* also support different protect number +* status1 register bif field show as follow +* 7 |6 |5 |4 |3 |2 |1 |0 +* --------------------------------------------------------------------- +* vensor def | vendor def | vendor def | BP2 | BP1 | BP0 | WEL | BUSY +* \ Protect type +* \ Protect block size : Vendor define ,user should check flash datasheet of vendor +* : Use w25q64fw as example , min protect block size is 128 KB +* \ TOP : Protect address from flash top address +* \ BOTTOM : Protect address from flash bottom address +* \ SEC : Protect addres base on sector unit and protect region only must not exceed one block +* \ BPx : Protect start addres base on TOP/BOTTOM feature,and BPx value denote protect number +* \ BP[x..0]'s value : 2^(n-1) protect block unit, ex, BP[x..0] = 5, protect block number = 2^(5-1) = 16 +* \ If BP[x..0] = 0 denote protect none +* \ If BP[x..0]'s all bis is 1 ,denote protect all flash +* \ +* \ NOTE: +* \ only support SEC = 0 +* \ only support CMP = 0 +* \ +* +* Sample table portion for 8MB flash (Winbond w25q64fw): +* +* SEC | TB | BP2 | BP1 | BP0 | Prot Length | Protected Portion +* -------------------------------------------------------------------------- +* X | X | 0 | 0 | 0 | NONE | NONE +* 0 | 0 | 0 | 0 | 1 | 128 KB | Upper 1/64 +* 0 | 0 | 0 | 1 | 0 | 256 KB | Upper 1/32 +* 0 | 0 | 0 | 1 | 1 | 512 KB | Upper 1/16 +* 0 | 0 | 1 | 0 | 0 | 1 MB | Upper 1/8 +* 0 | 0 | 1 | 0 | 1 | 2 MB | Upper 1/4 +* 0 | 0 | 1 | 1 | 0 | 4 MB | Upper 1/2 +* X | X | 1 | 1 | 1 | 8 MB | ALL +* ------|-------|-------|-------|-------|---------------|------------------- +* 0 | 1 | 0 | 0 | 1 | 128 KB | Lower 1/64 +* 0 | 1 | 0 | 1 | 0 | 256 KB | Lower 1/32 +* 0 | 1 | 0 | 1 | 1 | 512 KB | Lower 1/16 +* 0 | 1 | 1 | 0 | 0 | 1 MB | Lower 1/8 +* 0 | 1 | 1 | 0 | 1 | 2 MB | Lower 1/4 +* 0 | 1 | 1 | 1 | 0 | 4 MB | Lower 1/2 +* +*/ +typedef enum { + LOCK_TP_NONE, + LOCK_TP_TOP, + LOCK_TP_BOTTOM, + LOCK_TP_DUAL +} csi_spiflash_lock_region_t; +typedef enum { + SPIFLASH_DATA_1_LINE = 1, + SPIFLASH_DATA_2_LINES = 2, + SPIFLASH_DATA_4_LINES = 4 +} csi_spiflash_data_line_t; +typedef union { + csi_spi_t spi; + csi_qspi_t qspi; +} csi_spi_qspi_t; + +/** +\brief Flash information +*/ +typedef struct { + char *flash_name; ///< Name string of spiflash + uint32_t flash_id; ///< JEDEC ID = manufature ID <<16 | device ID (ID15~ID0) + uint32_t flash_size; ///< Flash chip size + uint32_t xip_addr; ///< If use qspi controler to access flash ,code can be ececuted on flash ,the addr is xip addr + uint32_t sector_size; ///< Sector size + uint32_t page_size; ///< Page size for read or program +} csi_spiflash_info_t; + +typedef struct{ + struct{ + uint8_t buswidth; ///< cmd buswidth + }cmd; + struct { + uint8_t buswidth; ///< addr buswidth + }addr; + struct { + uint8_t nbytes; ///< dummy bytes + }dummy; + struct { + uint8_t buswidth; ///< data buswidth + }data; +} csi_spiflash_cmd_t; + +/** +\brief Flash control block +*/ +typedef struct { + csi_spi_qspi_t spi_qspi; ///< Spi/qspi handle + void (*spi_cs_callback)(csi_gpio_pin_state_t value); + void *flash_prv_info; ///< Point to vendor private feature struct + int32_t (*spi_send)(void *spi, uint8_t cmd, uint32_t addr, uint32_t addr_size, const void *data, uint32_t size); + int32_t (*spi_receive)(void *spi, uint8_t cmd, uint32_t addr, uint32_t addr_size, void *data, uint32_t size); + csi_error_t (*set_cmd)(void *spi, csi_spiflash_cmd_t *cmd); + void *priv; ///< User private param +} csi_spiflash_t; + +/** + \brief Initialize SPIFLASH with spi controler and probe flash device + \param[in] spiflash SPIFLASH handle + \param[in] spi_idx SPI controler index + \param[in] spi_cs GPIO info for chip select,if NULL, not use gpio cs + \return Error code +*/ +csi_error_t csi_spiflash_spi_init(csi_spiflash_t *spiflash, uint32_t spi_idx, void *spi_cs_callback); + +/** + \brief Initialize SPIFLASH with qspi controler and probe flash device + \param[in] spiflash SPIFLASH handle + \param[in] qspi_idx QSPI controler index + \return Error code +*/ +csi_error_t csi_spiflash_qspi_init(csi_spiflash_t *spiflash, uint32_t qspi_idx, void *qspi_cs_callback); + +/** + \brief De-initialize SPIFLASH Interface based on spi controler. stops operation and releases the software resources used by the interface + \param[in] spiflash SPIFLASH handle to operate + \return Error code +*/ +void csi_spiflash_spi_uninit(csi_spiflash_t *spiflash); + +/** + \brief De-initialize SPIFLASH Interface based on qspi controler. stops operation and releases the software resources used by the interface + \param[in] spiflash SPIFLASH handle to operate + \return Error code +*/ +void csi_spiflash_qspi_uninit(csi_spiflash_t *spiflash); + + +/** + \brief Get flash device infomation + \param[in] spiflash SPIFLASH handle to operate + \param[in] flash_info User storage to get flash vendor info after flash init + \return spiflash_info_t +*/ +csi_error_t csi_spiflash_get_flash_info(csi_spiflash_t *spiflash, csi_spiflash_info_t *flash_info); + + +/** + \brief Read data from Flash + \param[in] spiflash SPIFLASH handle to operate + \param[in] offset Data address, offset address relative to zero + \param[out] data Pointer to a buffer storing the data read from Flash + \param[in] size Number of data items to read + \return If receive successful, this function shall return the num of data witch is received successful + otherwise, the function shall return Error code +*/ +int32_t csi_spiflash_read(csi_spiflash_t *spiflash, uint32_t offset, void *data, uint32_t size); + +/** + \brief Program data to Flash + \param[in] spiflash SPIFLASH handle to operate + \param[in] offset Data address, offset address relative to zero + \param[in] data Pointer to a buffer containing the data to be programmed to Flash. + \param[in] size Number of data items to program + \return If program successful, this function shall return the num of data witch is program successful, + otherwise, the function shall return Error code +*/ +int32_t csi_spiflash_program(csi_spiflash_t *spiflash, uint32_t offset, const void *data, uint32_t size); + +/** + \brief Erase Flash Sector + \param[in] spiflash SPIFLASH handle to operate + \param[in] offset Data address, offset address relative to zero + \param[in] size Length to be erased + \return Error code +*/ +csi_error_t csi_spiflash_erase(csi_spiflash_t *spiflash, uint32_t offset, uint32_t size); + +/** + \brief Read flash status register + \param[in] spiflash SPIFLASH handle to operate + \param[in] cmd_code Cmd code + \param[out] data Data buf to save flash status register + \param[in] size Register length in byte + \return Error code +*/ +csi_error_t csi_spiflash_read_reg(csi_spiflash_t *spiflash, uint8_t cmd_code, uint8_t *data, uint32_t size); + +/** + \brief Write status register + \param[in] spiflash SPIFLASH handle to operate + \param[in] cmd Cmd code + \param[out] data Data buf to save flash status register + \param[in] size Register length in byte + \return Error code +*/ +csi_error_t csi_spiflash_write_reg(csi_spiflash_t *spiflash, uint8_t cmd_code, uint8_t *data, uint32_t size); + + +/** + \brief Enable spiflash write protection + \param[in] spiflash SPIFLASH handle to operate + \param[in] offset Protect flash offset,offset need protect block size aligned + \param[in] size Lock size(byte) + \return Error code +*/ +csi_error_t csi_spiflash_lock(csi_spiflash_t *spiflash, uint32_t offset, uint32_t size); + +/** + \brief Enable spiflash write protection + \param[in] spiflash SPIFLASH handle to operate + \param[in] offset Protect flash offset,offset need protect block size aligned + \param[in] size Unlock size(byte) + \return Error code +*/ +csi_error_t csi_spiflash_unlock(csi_spiflash_t *spiflash, uint32_t offset, uint32_t size); + +/** + \brief check flash is locked(write protect) + \param[in] spiflash SPIFLASH handle to operate + \param[in] offset Protect flash offset,offset need protect block size aligned + \param[in] size Locked size(byte) + \return 0:unlocked if query region overlay with locked region 1: locked if query reigon is fully in locked region +*/ +int csi_spiflash_is_locked(csi_spiflash_t *spiflash, uint32_t offset, uint32_t size); + +/** + \brief Set QSPI data line + \param[in] spiflash SPIFLASH handle to operate + \param[in] line SPIFLASH data line mode + \return Error code +*/ +csi_error_t csi_spiflash_config_data_line(csi_spiflash_t *spiflash, csi_spiflash_data_line_t line); + +/** + \brief Set QSPI frequence + \param[in] spiflash SPIFLASH handle to operate + \param[in] hz SPIFLASH frequence + \return The actual config frequency +*/ +uint32_t csi_spiflash_frequence(csi_spiflash_t *spiflash, uint32_t hz); + +/** + \brief Flash power down. + \param[in] spiflash SPIFLASH handle to operate. + \return error code +*/ +csi_error_t csi_spiflash_release_power_down(csi_spiflash_t *spiflash); + +/** + \brief Flash power release. + \param[in] spiflash SPIFLASH handle to operate. + \return none +*/ +void csi_spiflash_power_down(csi_spiflash_t *spiflash); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_SPIFLASH_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/spinand.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/spinand.h new file mode 100644 index 00000000..8a011987 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/spinand.h @@ -0,0 +1,321 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 spinand.h + * @brief header file for spinand driver + * @version V1.0 + * @date 17. Aug 2017 + * @model spinand + ******************************************************************************/ +#ifndef _DRV_NANDFLASH_H_ +#define _DRV_NANDFLASH_H_ + + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SPINAND_DEF_SPEED (1000000) +#define SPIANND_DEF_MAX_WAIT_TIME (1000) ///< max wait time in ms + +typedef union { + csi_qspi_t qspi; ///< hold qspi object +} csi_nand_spi_qspi_t; + + +typedef struct { +uint32_t target; ///< target in chip +uint32_t lun; ///< lun in target +uint32_t plane; ///< plane number in lun +uint32_t block; ///< block index in lun +uint32_t page; ///< page index in lun +uint32_t offset; ///< column offset within page +}csi_nand_pos_t; + +typedef enum{ + SPI_MEM_NODATA, ///< no data portion + SPI_MEM_DATA_IN, ///< read data + SPI_MEM_DATA_OUT ///< write data +}csi_spi_mem_dir_t; + +typedef struct{ + + struct{ + uint8_t buswidth; ///< cmd buswidth + uint8_t opcode; ///< cmd code + }cmd; + + struct { + uint8_t buswidth; ///< addr buswidth + uint8_t nbytes; ///< bytes of addr + uint64_t val; ///< addr value + }addr; + + struct { + uint8_t nbytes; ///< dummy bytes + uint8_t buswidth; ///< bus width + }dummy; + + + struct { + uint8_t buswidth; ///< data buswidth + uint32_t nbytes; ///< data len + csi_spi_mem_dir_t dir; ///< data xfer dir + union{ + void* in; ///< read data buf ptr + void* out; ///< write datat buf ptr + }buf; + }data; + +}spi_mem_op_t; + +typedef struct { + const uint8_t *id; ///< point to chip id array + const uint8_t len; ///< id length +}csi_spinand_id_t; + +typedef struct { + uint8_t id[4]; ///< id data + uint8_t len; ///< id length +}csi_nand_id_t; + + +typedef struct{ + uint16_t strength; ///< number of hw-ecc engine bits + uint16_t step_size; ///< corect size by ecc per-step +}csi_nand_ecc_req_t; + +typedef struct { + uint32_t bits_per_cell; ///< bit per-cell + uint32_t pagesize; ///< page size + uint32_t oobsize; ///< spare area size + uint32_t pages_per_eraseblock; ///< pages per block + uint32_t eraseblocks_per_lun; ///< blocks per lun(logic unit number== max block index ) + uint32_t max_bad_eraseblocks_per_lun; ///< max bad blocks per lun + uint32_t planes_per_lun; ///< planes per-lun + uint32_t luns_per_target; ///< luns per die + uint32_t ntargets; ///< target index +}csi_nand_mem_layout_t; + + + +typedef struct { + char *model; ///< chip name of vendor + uint32_t flags; ///< chip-specific feature bits group + csi_spinand_id_t devid; ///< devid of chip + csi_nand_mem_layout_t memorg; ///< mem layout of chip + csi_nand_ecc_req_t eccreq; ///< ecc capabilty of chip + csi_error_t (*select_target)(void *spinand, uint32_t target); ///< select target + csi_error_t (*check_ecc_status)(void *spinand,uint8_t status); ///< check vendor specific ecc status +}csi_spinand_info_t; + + +typedef struct { + csi_error_t (*init) (void *spinand); ///< vendor chip inition + void (*uninit) (void *spinand); ///< vendor chip uninition +}csi_spinand_manufacturer_ops_t; + +typedef struct { + uint8_t id; ///< vendor id + char *name; ///< vendor name + const csi_spinand_info_t *chips; ///< vendor chip param + uint32_t nchips; ///< chips number supported + const csi_spinand_manufacturer_ops_t *ops; ///< vendor specific operations +}csi_spinand_manufacturer_t; + + +typedef struct { + char *model_name; ///< name of nand-device module + uint16_t page_size; ///< page-size of nand-device + uint16_t oob_size; ///< oob-size(spare size) of nand-device + uint16_t pages_per_block; ///< pages-per-block + uint16_t max_bad_blocks; ///< max possible bad blocks of nand-device + uint32_t total_blocks; ///< total blocks of nand-device +}csi_spinand_dev_params_t; + +typedef struct +{ + void *xfer_buf; ///< point to xfer data buf + uint32_t xfer_buf_len; ///< length of xfer buf ,count in byte + uint16_t rxfer_copy_offset; ///< copy offset from word-aligned buf + uint16_t rxfer_origin_len; ///< copy length from word-aligned buf +}csi_xfer_data_buf_t; + + +/** +\brief Flash control block +*/ +typedef struct { + #define SPINAND_SCRAT_BUF_LEN 4 ///< scratch buf len + csi_nand_spi_qspi_t spi_qspi; ///< Spi/qspi handle + uint8_t scractbuf[SPINAND_SCRAT_BUF_LEN]; ///< scracthbuf for read/write id or reg + uint8_t cur_target; ///< current target + uint16_t max_tx_size; ///< max tx op size + uint16_t max_rx_size; ///< max rx op size + csi_xfer_data_buf_t xfer; ///< xfer buf + csi_spinand_info_t *chip_info; ///< Point to vendor private feature struct + csi_spinand_manufacturer_t *maf; ///< point to manufacture + void (*spi_cs_callback)(csi_gpio_pin_state_t value); ///< gpio chip select for spi or qspi + csi_error_t (*spi_mem)(void *spinand,spi_mem_op_t *op); ///< spi-mem op function + void *priv; ///< User private param +} csi_spinand_t; + +typedef enum { + XFER_CPU_POLLING, ///< transfer by qspi with cpu polling mode + XFER_DMA, ///< transfer by qspi with external dma engine + XFER_INTR, ///< transfer by qspi with cpu-interrut +}csi_spinand_xfer_t; + +/** + \brief Initialize NANDFLASH with qspi controler and probe flash device + \param[in] spinand NANDFLASH handle + \param[in] qspi_idx QSPI controler index + \param[in] spi_cs_callback GPIO info for chip select,if NULL, not use gpio cs + \return Error code +*/ +csi_error_t csi_spinand_qspi_init(csi_spinand_t *spinand, uint32_t qspi_idx,void *gpio_cs_callback); + +/** + \brief De-initialize NANDFLASH Interface based on spi controler. stops operation and releases the software resources used by the interface + \param[in] spinand NANDFLASH handle to operate + \return Error code +*/ +void csi_spinand_qspi_uninit(csi_spinand_t *spinand); + +/** + \brief set xfer mode + \param[in] spinand NANDFLASH handle to operate + \param[in] xfer_mode please ref csi_spinand_xfer_t + \return Error code +*/ +csi_error_t csi_spinand_set_xfer_mode(csi_spinand_t *spinand,csi_spinand_xfer_t xfer_mode); + + +/** + \brief get flash device infomation + \param[in] spinand NANDFLASH handle to operate + \param[in] flash_info User storage to get flash vendor info after flash init + \return spinand_info_t +*/ + +csi_error_t csi_spinand_get_flash_info(csi_spinand_t *spinand, csi_spinand_dev_params_t *flash_info); + +/** + \brief Read data from Flash + \param[in] spinand NANDFLASH handle to operate + \param[in] offset Data address, offset address relative to zero + \param[out] data Pointer to a buffer storing the data read from Flash + \param[in] cnt Number of data items to read + \return If receive successful, this function shall return the num of data witch is received successfulful + otherwise, the function shall return Error code +*/ +int32_t csi_spinand_read(csi_spinand_t *spinand, uint64_t offset, void *data, uint32_t size); + + +/** + \brief Read spare data from specific page + \param[in] spinand NANDFLASH handle to operate + \param[in] page_addr page addr, address relative to zero, addr need page size aligned + \param[in] spare_offset offset address within the spare area of the page + \param[out] data Pointer to a buffer storing the data read from Flash + \param[in] size Number of data items to read + \return If receive successful, this function shall return the num of data witch is received successfully + otherwise, the function shall return Error code +*/ +int32_t csi_spinand_read_spare_data(csi_spinand_t *spinand,uint64_t page_addr,uint32_t spare_offset,void *data, uint32_t size); + +/** + \brief write data to Flash + \param[in] spinand NANDFLASH handle to operate + \param[in] offset Data address, offset address relative to zero + \param[in] data Pointer to a buffer containing the data to be programmed to Flash. + \param[in] size Number of data items to program + \return If program successful, this function shall return the num of data witch is programed successfully + otherwise, the function shall return Error code +*/ +int32_t csi_spinand_write(csi_spinand_t *spinand, uint64_t offset, const void *data, uint64_t size); + +/** + \brief write spare data to specific page + \param[in] spinand NANDFLASH handle to operate + \param[in] page_addr page addr, address relative to zero, addr need page size aligned + \param[in] spare_offset offset address within the spare area of the page + \param[out] data Pointer to a buffer storing the data write to Flash + \param[in] size Number of data items to write + \return If program successful, this function shall return the num of data witch is programed successfully + otherwise, the function shall return Error code +*/ +int32_t csi_spinand_write_spare_data(csi_spinand_t *spinand,uint64_t page_addr,uint32_t spare_offset,void *data, uint32_t size); + + +/** + \brief Erase Flash Sector + \param[in] spinand NANDFLASH handle to operate + \param[in] offset Data address, offset address relative to zero + \param[in] size Length to be erased + \param[out] last erased block addr + \return Error code +*/ +csi_error_t csi_spinand_erase(csi_spinand_t *spinand, uint64_t offset, uint64_t size, uint64_t *last_fail_addr); + +/** + \brief check whether the block is bad + \param[in] spinand NANDFLASH handle to operate + \param[in] block_addr block addr (count in bytes) + \return 1: bad 0: not bad <0 err code +*/ + + +int32_t csi_spinand_block_is_bad(csi_spinand_t *spinand,uint64_t block_addr); + +/** + \brief mark block as a bad block + \param[in] spinand NANDFLASH handle to operate + \param[in] block_addr block addr (count in bytes) + \return Error code +*/ +csi_error_t csi_spinand_block_mark_bad(csi_spinand_t *spinand, uint64_t block_addr); + +/** + \brief reset spinand device + \param[in] spinand NANDFLASH handle to operate + \return Error code +*/ +int32_t csi_spinand_reset(csi_spinand_t *spinand); + +/** + \brief Set QSPI frequence + \param[in] spinand NANDFLASH handle to operate + \param[in] hz NANDFLASH frequence + \return The actual config frequency +*/ +uint32_t csi_spinand_frequence(csi_spinand_t *spinand, uint32_t hz); + + + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_NANDFLASH_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/tee.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/tee.h new file mode 100755 index 00000000..dc85c7b9 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/tee.h @@ -0,0 +1,643 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/tee.h + * @brief Header File for TEE Driver + * @version V1.0 + * @date 12 Sep 2020 + * @model tee + ******************************************************************************/ +#ifndef _DRV_TEE_H_ +#define _DRV_TEE_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif +/****** TEE AES mode *****/ +typedef enum { + TEE_AES_MODE_ECB = 0, ///< TEE AES ECB mode + TEE_AES_MODE_CBC = 1, ///< TEE AES CBC mode + TEE_AES_MODE_MAX, ///< invaild mode +} +tee_aes_mode_e; + +/** + \brief TEE AES encrypt + \note Length should be a multiple of the block size (16 bytes) + After calling this function, the content of iv is updated. + \param[in] in Pointer to plaintext buffer + \param[in] in_len Plaintext buffer length + \param[in] key Pointer to secret key + \param[in] key_len Secret key size,must be 16 bytes for AES128,24 bytes for AES192 or 32byes for AES256 + \param[out] out Pointer to ciphertext buffer + \param[in] mode \ref tee_aes_mode_e + \return Return 0 if successful,otherwise error code +*/ +int32_t csi_tee_aes_encrypt(const uint8_t *in, uint32_t in_len, + const uint8_t *key, uint32_t key_len, + uint8_t iv[16], + uint8_t *out, + tee_aes_mode_e mode); + +/** + \brief TEE AES decrypt + \note Length should be a multiple of the block size (16 bytes) + After calling this function, the content of iv is updated. + \param[in] in Pointer to ciphertext buffer + \param[in] in_len Ciphertext buffer length + \param[in] key Pointer to secret key + \param[in] key_len Secret key size,must be 16 bytes for AES128,24 bytes for AES192 or 32byes for AES256 + \param[out] out Pointer to plaintext buffer + \param[in] mode \ref tee_aes_mode_e + \return Return 0 if successful,otherwise error code +*/ +int32_t csi_tee_aes_decrypt(const uint8_t *in, uint32_t in_len, + const uint8_t *key, uint32_t key_len, + uint8_t iv[16], + uint8_t *out, + uint32_t mode); + +/** + \brief TEE AES ECB encrypt + \note Length should be a multiple of the block size (16 bytes) + After calling this function, the content of iv is updated. + \param[in] in Pointer to plaintext buffer + \param[in] in_len Plaintext buffer length + \param[in] key Pointer to secret key + \param[in] key_len Secret key size,must be 16 bytes for AES128,24 bytes for AES192 or 32byes for AES256 + \param[out] out Pointer to ciphertext buffer + \return Return 0 if successful,otherwise error code +*/ +#define csi_tee_aes_encrypt_ecb(in, in_len, key, key_len, out) \ + csi_tee_aes_encrypt(in, in_len, key, key_len, NULL, out, TEE_AES_MODE_ECB) + +/** + \brief TEE AES ECB decrypt + \note Length should be a multiple of the block size (16 bytes) + After calling this function, the content of iv is updated. + \param[in] in Pointer to ciphertext buffer + \param[in] in_len Ciphertext buffer length + \param[in] key Pointer to secret key + \param[in] key_len Secret key size,must be 16 bytes for AES128,24 bytes for AES192 or 32byes for AES256 + \param[out] out Pointer to plaintext buffer + \return Return 0 if successful,otherwise error code +*/ +#define csi_tee_aes_decrypt_ecb(in, in_len, key, key_len, out) \ + csi_tee_aes_decrypt(in, in_len, key, key_len, NULL, out, TEE_AES_MODE_ECB) + +/** + \brief TEE AES CBC encrypt + \note Length should be a multiple of the block size (16 bytes) + After calling this function, the content of iv is updated. + \param[in] in Pointer to ciphertext buffer + \param[in] in_len Ciphertext buffer length + \param[in] key Pointer to secret key + \param[in] key_len Secret key size,must be 16 bytes for AES128,24 bytes for AES192 or 32byes for AES256 + \param[out] out Pointer to plaintext buffer + \return Return 0 if successful,otherwise error code +*/ +#define csi_tee_aes_encrypt_cbc(in, in_len, key, key_len, iv, out) \ + csi_tee_aes_encrypt(in, in_len, key, key_len, iv, out, TEE_AES_MODE_CBC) + +/** + \brief TEE AES CBC decrypt + \note Length should be a multiple of the block size (16 bytes) + After calling this function, the content of iv is updated. + \param[in] in Pointer to ciphertext buffer + \param[in] in_len Ciphertext buffer length + \param[in] key Pointer to secret key + \param[in] key_len Secret key size,must be 16 bytes for AES128,24 bytes for AES192 or 32byes for AES256 + \param[out] out Pointer to plaintext buffer + \return Return 0 if successful,otherwise error code +*/ +#define csi_tee_aes_decrypt_cbc(in, in_len, key, key_len, iv, out) \ + csi_tee_aes_decrypt(in, in_len, key, key_len, iv, out, TEE_AES_MODE_CBC) + +/** + \brief TEE BASE64 encode/decode + \param[in] in Pointer to input data buffer + \param[in] in_len Input data buffer length + \param[out] out Pointer to output data buffer + \param[out] out_len Output data buffer length + \param[in] is_encode 1 encode 0 decode + \param[in] wsafe Base64 websafe feature,set 1, replace "+/" with "-_" + \return Return 0 if successful,otherwise error code +*/ +int32_t csi_tee_base64(const uint8_t *in, uint32_t in_len, + uint8_t *out, uint32_t *out_len, + uint32_t is_encode, + uint32_t wsafe); + +/** + \brief TEE BASE64 encode + \param[in] in Pointer to input data buffer + \param[in] in_len Input data buffer length + \param[out] out Pointer to output data buffer + \param[out] out_len Output data buffer length + \return Return 0 if successful,otherwise error code +*/ +#define csi_tee_base64_encode(in,in_len,out,out_len) \ + csi_tee_base64(in,in_len,out,out_len,1,0) + +/** + \brief TEE BASE64 decode + \param[in] in Pointer to input data buffer + \param[in] in_len Input data buffer length + \param[out] out Pointer to output data buffer + \param[out] out_len Output data buffer length + \return Return 0 if successful,otherwise error code +*/ +#define csi_tee_base64_decode(in,in_len,out,out_len) \ + csi_tee_base64(in,in_len,out,out_len,0,0) + +/** + \brief TEE BASE64 web safe encode + \param[in] in Pointer to input data buffer + \param[in] in_len Input data buffer length + \param[out] out Pointer to output data buffer + \param[out] out_len Output data buffer length + \return Return 0 if successful,otherwise error code +*/ +#define csi_tee_base64_websafe_encode(in,in_len,out,out_len) \ + csi_tee_base64(in,in_len,out,out_len,1,1) + +/** + \brief TEE BASE64 web safe decode + \param[in] in Pointer to input data buffer + \param[in] in_len Input data buffer length + \param[out] out Pointer to output data buffer + \param[out] out_len Output data buffer length + \return Return 0 if successful,otherwise error code +*/ +#define csi_tee_base64_websafe_decode(in,in_len,out,out_len) \ + csi_tee_base64(in,in_len,out,out_len,0,1) + +/** + \brief TEE obtain CID from Key Provisioning + \param[out] out Pointer to cid buffer + \param[out] out_len CID buffer length,if cid obtain successfully, + out_len is updated to actual cid sizes + \return Return 0 if successful,otherwise error code +*/ +int32_t csi_tee_get_cid(uint8_t *out, uint32_t *out_len); + +/****** lpm mode *****/ +typedef enum { + TEE_LPM_MODE_WAIT = 0, ///< lpm wait + TEE_LPM_MODE_DOZE = 1, ///< lpm doze + TEE_LPM_MODE_STOP = 2, ///< lpm stop + TEE_LPM_MODE_STANDBY = 3, ///< lpm standby + TEE_LPM_MODE_CLOCK = 4, ///< lpm clock gate + TEE_LPM_MODE_MAX, +} tee_lpm_mode_e; + +/** + \brief TEE set low power mode + \param[in] gate Not use for now + \param[in] irqid Not use for now + \param[in] mode \ref tee_lpm_mode_e + \return Return 0 if successful,otherwise error code +*/ +int32_t csi_tee_enter_lpm(uint32_t gate, uint32_t irqid, tee_lpm_mode_e mode); + +/** + \brief TEE obtain manifest info from manifest table + \note call csi_tee_get_sys_img_info, csi_tee_get_sys_os_version or csi_tee_get_sys_partition is better + \param[out] out Pointer to info buffer + \param[out] out_len Info buffer length,if info obtain successfully, + out_len is updated to actual sizes + \param[in] name info name + \return Return 0 if successful,otherwise error code +*/ +int32_t csi_tee_get_manifest_info(uint8_t *out, uint32_t *out_len, char *name); + +/** + \brief TEE obtain image buffer from manifest table + \param[out] out Pointer to image buffer + \param[out] out_len Image buffer length,if info obtain successfully, + out_len is updated to actual image buffer sizes + \param[in] img_name Image name + \return Return 0 if successful,otherwise error code +*/ +#define csi_tee_get_sys_img_info(out,out_len,img_name) \ + csi_tee_get_manifest_info(out,out_len,img_name) + +/** + \brief TEE obtain os version from manifest table + \param[out] out Pointer to os version buffer + \param[out] out_len OS version buffer length,if info obtain successfully, + out_len is updated to actual os version buffer sizes + \return Return 0 if successful,otherwise error code +*/ +#define csi_tee_get_sys_os_version(out,out_len) \ + csi_tee_get_manifest_info(out,out_len,"os_v") + +/** + \brief TEE obtain partition buffer from manifest table + \param[out] out Pointer to partition buffer + \param[out] out_len Partition buffer length,if info obtain successfully, + out_len is updated to actual partition buffer sizes + \return Return 0 if successful,otherwise error code +*/ +#define csi_tee_get_sys_partition(out,out_len) \ + csi_tee_get_manifest_info(out,out_len,"sys_p") + +/** + \brief TEE set random seed + \param[in] Seed random sedd + \return Return 0 if successful,otherwise error code +*/ +int32_t csi_tee_rand_seed(uint32_t seed); + +/** + \brief TEE ramdom date generation + \param[out] out Pointer to random data buffer + \param[in] out_len Data buffer length + \return Return 0 if successful,otherwise error code +*/ +int32_t csi_tee_rand_generate(uint8_t *out, uint32_t out_len); + +/****** TEE RSA sign type *****/ +typedef enum { + TEE_RSA_MD5 = 0, ///< MD5 + TEE_RSA_SHA1 = 1, ///< SHA1 + TEE_RSA_SHA256 = 3, ///< SHA256 + TEE_RSA_SIGN_TYPE_MAX, ///< invailed type +} tee_rsa_sign_type_e; + +/** + \brief TEE RSA sign with private key + \param[in] in Pointer to digest buffer + \param[in] in_len Digest buffer length + \param[in] key Pointer to private key,key contains n, e, d + \param[in] key_len Private key size,must be 128*3 = 384 bytes for RSA1024, 256*3 = 768 bytes for RSA2048 + \param[out] sign Pointer to sign buffer + \param[out] sign_len Sign buffer length + \param[in] type \ref tee_rsa_sign_type_e + \return Return 0 if successful,otherwise error code +*/ +int32_t csi_tee_rsa_sign(const uint8_t *in, uint32_t in_len, + const uint8_t *key, uint32_t key_len, + uint8_t *sign, uint32_t *sign_len, + tee_rsa_sign_type_e type); + +/** + \brief TEE RSA verify with public key + \param[in] in Pointer to digest buffer + \param[in] in_len Digest buffer length + \param[in] key Pointer to public key,key contains n, e + \param[in] key_len Public key size,must be 128*2 = 256 bytes for RSA1024, 256*2 = 512 bytes for RSA2048 + \param[in] sign Pointer to sign buffer + \param[in] sign_len Sign buffer length + \param[in] type \ref tee_rsa_sign_type_e + \return Return 0 if verify successful,otherwise error code +*/ +int32_t csi_tee_rsa_verify(const uint8_t *in, uint32_t in_len, + const uint8_t *key, uint32_t key_len, + uint8_t *sign, uint32_t sign_len, + tee_rsa_sign_type_e type); + +/****** TEE RSA padding mode *****/ +typedef enum { + TEE_RSA_PKCS1_PADDING = 0x01, ///< RSA PKCS padding mode + TEE_RSA_NO_PADDING = 0x02, ///< RSA no padding mode +} tee_rsa_padding_mode_e; + +/** + \brief TEE RSA encrypt with public key + \param[in] in Pointer to plaintext buffer + \param[in] in_len Plaintext buffer length + \param[in] key Pointer to public key,key contains n, e + \param[in] key_len Public key size, must be 128*2 = 256 bytes for RSA1024, 256*2 = 512 bytes for RSA2048 + \param[in] out Pointer to ciphertext buffer + \param[in] out_len Ciphertext buffer length + \param[in] padding \ref tee_rsa_padding_mode_e + \return Return 0 if successful,otherwise error code +*/ +int32_t csi_tee_rsa_encrypt(const uint8_t *in, uint32_t in_len, + const uint8_t *key, uint32_t key_len, + uint8_t *out, uint32_t *out_len, + tee_rsa_padding_mode_e padding); +/** + \brief TEE RSA decrypt with private key + \param[in] in Pointer to ciphertext buffer + \param[in] in_len Ciphertext buffer length + \param[in] key Pointer to private key,key contains n, e, d + \param[in] key_len Private key size,must be 128*3 = 384 bytes for RSA1024, 256*3 = 768 bytes for RSA2048 + \param[in] out Pointer to plaintext buffer + \param[in] out_len Plaintext buffer length + \param[in] padding \ref tee_rsa_padding_mode_e + \return Return 0 if successful,otherwise error code +*/ +int32_t csi_tee_rsa_decrypt(const uint8_t *in, uint32_t in_len, + const uint8_t *key, uint32_t key_len, + uint8_t *out, uint32_t *out_len, + tee_rsa_padding_mode_e padding); + +/** + \brief TEE RSA sign with internal private key + \note Only use if key provisioning exist + \param[in] in Pointer to digest buffer + \param[in] in_len Digest buffer length + \param[out] sign Pointer to sign buffer + \param[out] sign_len Sign buffer length + \param[in] type \ref tee_rsa_sign_type_e + \return Return 0 if successful,otherwise error code +*/ +#define csi_tee_cid_rsa_sign(in,in_len,sign,sign_len,type) \ + csi_tee_rsa_sign(in,in_len,NULL,0,sign,sign_len,type) + +/** + \brief TEE RSA verify with internal public key + \note Only use if key provisioning exist + \param[in] in Pointer to digest buffer + \param[in] in_len Digest buffer length + \param[in] sign Pointer to sign buffer + \param[in] sign_len Sign buffer length + \param[in] type \ref tee_rsa_sign_type_e + \return Return 0 if verify successful,otherwise error code +*/ +#define csi_tee_cid_rsa_verify(in,in_len,sign,sign_len,type) \ + csi_tee_rsa_verify(in,in_len,NULL,0,sign,sign_len,type) + +/** + \brief TEE RSA encrypt with internal public key + \note Only use if key provisioning exist + \param[in] in Pointer to plaintext buffer + \param[in] in_len Plaintext buffer length + \param[in] out Pointer to ciphertext buffer + \param[in] out_len Ciphertext buffer length + \param[in] padding \ref tee_rsa_padding_mode_e + \return Return 0 if successful,otherwise error code +*/ +#define csi_tee_cid_rsa_encrypt(in,in_len,out,out_len,padding) \ + csi_tee_rsa_encrypt(in,in_len,NULL,0,out,out_len,padding) + +/** + \brief TEE RSA decrypt with internal private key + \note Only use if key provisioning exist + \param[in] in Pointer to ciphertext buffer + \param[in] in_len Ciphertext buffer length + \param[in] key Pointer to private key,key contains n, e, d + \param[in] key_len Private key size,must be 128*3 = 384 bytes for RSA1024, 256*3 = 768 bytes for RSA2048 + \param[in] out Pointer to plaintext buffer + \param[in] out_len Plaintext buffer length + \param[in] padding \ref tee_rsa_padding_mode_e + \return Return 0 if successful,otherwise error code +*/ +#define csi_tee_cid_rsa_decrypt(in,in_len,out,out_len,padding) \ + csi_tee_rsa_decrypt(in,in_len,NULL,0,out,out_len,padding) + +/** + \brief verify boot image with boot public key + \note Only use if key provisioning exist + \param[in] in Pointer to digest buffer + \param[in] in_len Digest buffer length + \param[in] sign Pointer to sign buffer + \param[in] sign_len Sign buffer length + \param[in] type \ref tee_rsa_sign_type_e + \return Return 0 if verify successful,otherwise error code +*/ +int32_t csi_tee_img_rsa_verify(const uint8_t *in, uint32_t in_len, + uint8_t *sign, uint32_t sign_len, + tee_rsa_sign_type_e type); + +/****** TEE HASH operation mode *****/ +typedef enum { + TEE_HASH_OP_NONE = 0, ///< No operation + TEE_HASH_OP_START = 1, ///< HASH init + TEE_HASH_OP_UPDATA = 2, ///< HASH update + TEE_HASH_OP_FINISH = 3, ///< HASH finish + TEE_HASH_OP_MAX, ///< invailed operation +} tee_hash_op_e; + +/****** TEE HMAC type *****/ +typedef enum { + TEE_HMAC_SHA1 = 1, ///< HMAC with SHA1 +} tee_hmac_type_e; + +/** + \brief TEE HAMC + \note Call csi_tee_hmac_digest is better + out buffer size must be large enough according to type, eg. 20 bytes for TEE_HMAC_SHA1 + \param[in] in Pointer to input data buffer + \param[in] in_len Input data buffer length + \param[in] key Pointer to key buffer + \param[in] key_len Key buffer size + \param[out] out Pointer to output date buffer + \param[in] type \ref tee_hmac_type_e + \param[in] hash_op \ref tee_hash_op_e + \param[in] ctx Pointer to context of hmac + \return Return 0 if successful,otherwise error code +*/ +int32_t csi_tee_hmac(const uint8_t *in, uint32_t in_len, + const uint8_t *key, uint32_t key_len, + uint8_t *out, + tee_hmac_type_e type, + tee_hash_op_e hash_op, + uint32_t *ctx); + +/** + \brief TEE HAMC digest + \note out buffer size must be large enough according to type, eg. 20 bytes for TEE_HMAC_SHA1 + \param[in] in Pointer to input data buffer + \param[in] in_len Input data buffer length + \param[in] key Pointer to key buffer + \param[in] key_len Key buffer size + \param[out] out Pointer to output date buffer + \param[in] type \ref tee_hmac_type_e + \return Return 0 if successful,otherwise error code +*/ +#define csi_tee_hmac_digest(in,in_len,key,key_len,out,type) \ + csi_tee_hmac(in,in_len,key,key_len,out,type,TEE_HASH_OP_NONE,NULL) + +/****** TEE SHA type *****/ +typedef enum { + TEE_SHA1 = 0, ///< SHA1 + TEE_SHA256 = 1, ///< SHA256 + TEE_SHA224 = 2, ///< SHA224 + TEE_SHA384 = 3, ///< SHA384 + TEE_SHA512 = 4, ///< SHA512 + TEE_SHA_MAX, ///< invaild sha type +} tee_sha_type_t; + +/** + \brief TEE SHA + \note Call csi_tee_sha_digest, csi_tee_sha_start, csi_tee_sha_update or csi_tee_sha_finish is better + out buffer size must be large enough according to type, eg. 20 bytes for TEE_SHA1, 32 bytes for TEE_SHA256 + \param[in] in Pointer to input data buffer + \param[in] in_len Input data buffer length + \param[out] out Pointer to output date buffer + \param[in] type \ref tee_sha_type_t + \param[in] hash_op \ref tee_hash_op_e + \param[in] ctx Pointer to context of sha + \return Return 0 if successful,otherwise error code +*/ +int32_t csi_tee_sha(const uint8_t *in, uint32_t in_len, + uint8_t *out, + tee_sha_type_t type, + tee_hash_op_e hash_op, + void *ctx); + +/** + \brief TEE SHA digest + \note out buffer size must be large enough according to type, eg. 20 bytes for TEE_SHA1, 32 bytes for TEE_SHA256 + \param[in] in Pointer to input data buffer + \param[in] in_len Input data buffer length + \param[out] out Pointer to output date buffer + \param[in] type \ref tee_sha_type_t + \return Return 0 if successful,otherwise error code +*/ +#define csi_tee_sha_digest(in,in_len,out,type) \ + csi_tee_sha(in,in_len,out,type,TEE_HASH_OP_NONE,NULL); + +/** + \brief TEE SHA start, initial sha + \param[in] type \ref tee_sha_type_t + \param[in] ctx Pointer to context of sha + \return Return 0 if successful,otherwise error code +*/ +#define csi_tee_sha_start(type,ctx) \ + csi_tee_sha(NULL,0,NULL,type,TEE_HASH_OP_START,ctx); + +/** + \brief TEE SHA update, update data + \param[in] in Pointer to input data buffer + \param[in] in_len Input data buffer length + \param[in] ctx Pointer to context of sha + \return Return 0 if successful,otherwise error code +*/ +#define csi_tee_sha_update(in,in_len,ctx) \ + csi_tee_sha(in,in_len,NULL,0,TEE_HASH_OP_UPDATA,ctx); + +/** + \brief TEE SHA digest, get sha digest + \note out buffer size must be large enough according to type, eg. 20 bytes for TEE_SHA1, 32 bytes for TEE_SHA256 + \param[out] out Pointer to output date buffer + \param[in] ctx Pointer to context of sha + \return Return 0 if successful,otherwise error code +*/ +#define csi_tee_sha_finish(out,ctx) \ + csi_tee_sha(NULL,0,out,0,TEE_HASH_OP_FINISH,ctx); + +/** + \brief TEE get device name and product key + \param[in] name_encrypted Pointer to device name ciphertext + \param[in] name_encrypted_len device name ciphertext length + \param[in] product_key_encrypted Pointer to device product key ciphertext + \param[in] product_key_encrypted_len Device product key ciphertext length + \param[out] name Pointer to device name + \param[out] name_len Device name length + \param[out] product_key Pointer to device product key + \param[out] product_key_len Device product key length + \return Return 0 if successful,otherwise error code +*/ +int32_t csi_tee_dev_info_get(const uint8_t *name_encrypted, uint32_t name_encrypted_len, + const uint8_t *product_key_encrypted, uint32_t product_key_encrypted_len, + const uint8_t *name, uint32_t *name_len, + const uint8_t *product_key, uint32_t *product_key_len); + +/** + \brief TEE device info sign + \param[in] in Pointer to input date buffer + \param[in] in_len Input data buffer length + \param[in] device_secret Pointer to device secret ciphertext + \param[in] device_secret_len Device secret ciphertext length + \param[out] sign Pointer to signed buffer + \param[out] sign_len Signed buffer length + \return Return 0 if successful,otherwise error code +*/ +int32_t csi_tee_dev_info_sign(const uint8_t *in, uint32_t in_len, + const uint8_t *device_secret, uint32_t device_secret_len, + const uint8_t *sign, uint32_t *sign_len); + +/** + \brief TEE device info encrypt/decrypt + \param[in] in Pointer to input date buffer + \param[in] in_len Input data buffer length + \param[in] out Pointer to output date buffer + \param[in] out_len Onput data buffer length + \param[in] is_enc 1 incrypt 0 decrypt + \return Return 0 if successful,otherwise error code +*/ +int32_t csi_tee_dev_info_crypt(const uint8_t *in, uint32_t in_len, + uint8_t *out, uint32_t *out_len, + uint8_t is_enc); + +/** + \brief TEE device info encrypt + \param[in] in Pointer to input date buffer + \param[in] in_len Input data buffer length + \param[in] out Pointer to output date buffer + \param[in] out_len Onput data buffer length + \return Return 0 if successful,otherwise error code +*/ +#define csi_tee_dev_info_encrypt(in, in_len, out, out_len) \ + csi_tee_dev_info_crypt(in, in_len, out, out_len, 1) + +/** + \brief TEE device info decrypt + \param[in] in Pointer to input date buffer + \param[in] in_len Input data buffer length + \param[in] out Pointer to output date buffer + \param[in] out_len Onput data buffer length + \return Return 0 if successful,otherwise error code +*/ +#define csi_tee_dev_info_decrypt(in, in_len, out, out_len) \ + csi_tee_dev_info_crypt(in, in_len, out, out_len, 0) + +/** + \brief Set system frequence + \param[in] clk_src Indicate clock source type + \param[in] clk_val System freqence to be set + \return Return 0 if successful,otherwise error code +*/ +int32_t csi_tee_set_sys_freq(uint32_t clk_src, uint32_t clk_val); + +/** + \brief Get system frequence + \param[in] clk_val Value address to store system freqence + \return Return 0 if successful,otherwise error code +*/ +int32_t csi_tee_get_sys_freq(uint32_t *clk_val); + +/** + \brief Read system register + \param[in] addr Indicate register address + \param[out] val Value to read from the address + \return Return 0 if successful,otherwise error code +*/ +int32_t csi_tee_read_reg(uint32_t addr, uint32_t *val); + +/** + \brief Wrte system register + \param[in] addr Indicate register address + \param[in] val Value to be written into the address + \return Return 0 if successful,otherwise error code +*/ +int32_t csi_tee_write_reg(uint32_t addr, uint32_t val); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_TEE_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/tick.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/tick.h new file mode 100755 index 00000000..a5e0a3f1 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/tick.h @@ -0,0 +1,92 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 tick.h + * @brief Header File for TICK Driver + * @version V1.0 + * @date 28. Sep 2020 + ******************************************************************************/ + +#ifndef _DRV_TICK_H_ +#define _DRV_TICK_H_ + +#include +#include +#include + +#ifndef CONFIG_SYSTICK_HZ +#define CONFIG_SYSTICK_HZ 100U +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + \brief Initializes the resources needed for the TICK interface + \return error code \ref csi_error_t +*/ +csi_error_t csi_tick_init(void); + +/** + \brief De-initialize TICK Interface +*/ +void csi_tick_uninit(void); + +/** + \brief Get the sys-tick, one tick == (1000 / CONFIG_SYSTICK_HZ) ms + \return the sys-tick +*/ +uint32_t csi_tick_get(void); + +/** + \brief Get the time which start from csi_tick_init + \return The time which start from csi_tick_init (ms) +*/ +uint32_t csi_tick_get_ms(void); + +/** + \brief Get the time which start from csi_tick_init + \return The time which start from csi_tick_init (us) +*/ +uint64_t csi_tick_get_us(void); + +/** + \brief Get the calendar time in microseconds + \return The absolute timestamp in microseconds since Unix epoch (1970-01-01 00:00:00 UTC) +*/ +uint64_t csi_get_calendar_us(void); + +/** + \brief Set the calendar time in microseconds + \param[in] timestamp The absolute timestamp in microseconds since Unix epoch (1970-01-01 00:00:00 UTC) + \return None +*/ +void csi_set_calendar_us(uint64_t timestamp); + +/** + \brief Increase the sys-tick +*/ +void csi_tick_increase(void); + +#ifdef __cplusplus +} +#endif + +#endif /*_DRV_TICK_H_*/ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/timer.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/timer.h new file mode 100755 index 00000000..9f1039c1 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/timer.h @@ -0,0 +1,132 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/timer.h + * @brief Header File for TIMER Driver + * @version V1.0 + * @date 9. Oct 2020 + * @model timer + ******************************************************************************/ + +#ifndef _DRV_TIMER_H_ +#define _DRV_TIMER_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct csi_timer csi_timer_t; + +struct csi_timer { + csi_dev_t dev; + void (*callback)(csi_timer_t *timer, void *arg); + void *arg; + void *priv; +}; + +/** + \brief Initialize TIMER interface. initializes the resources needed for the TIMER interface + \param[in] timer Handle to operate + \param[in] idx TIMER index + \return Error code \ref csi_error_t +*/ +csi_error_t csi_timer_init(csi_timer_t *timer, uint32_t idx); + +/** + \brief De-initialize TIMER interface. stops operation and releases the software resources used by the interface + \param[in] timer Handle to operate + \return None +*/ +void csi_timer_uninit(csi_timer_t *timer); + +/** + \brief Start TIMER + \param[in] timer Handle to operate + \param[in] timeout_us The timeout for TIMER + \return Error code \ref csi_error_t +*/ +csi_error_t csi_timer_start(csi_timer_t *timer, uint32_t timeout_us); + +/** + \brief Stop TIMER + \param[in] timer Handle to operate + \return None +*/ +void csi_timer_stop(csi_timer_t *timer); + +/** + \brief Get TIMER remaining value + \param[in] timer Handle to operate + \return remaining value +*/ +uint32_t csi_timer_get_remaining_value(csi_timer_t *timer); + +/** + \brief Get TIMER load value + \param[in] timer Handle to operate + \return Load value +*/ +uint32_t csi_timer_get_load_value(csi_timer_t *timer); + +/** + \brief Check TIMER is running + \param[in] timer Handle to operate + \return + true - TIMER is running + false - TIMER is stopped +*/ +bool csi_timer_is_running(csi_timer_t *timer); + +/** + \brief Attach the callback handler to TIMER + \param[in] timer Operate handle + \param[in] callback Callback function + \param[in] arg Callback's param + \return Error code \ref csi_error_t +*/ +csi_error_t csi_timer_attach_callback(csi_timer_t *timer, void *callback, void *arg); + +/** + \brief Detach the callback handler + \param[in] timer Operate handle + \return None +*/ +void csi_timer_detach_callback(csi_timer_t *timer); + +/** + \brief Enable TIMER power manage + \param[in] timer Handle to operate + \return Error code \ref csi_error_t +*/ +csi_error_t csi_timer_enable_pm(csi_timer_t *timer); + +/** + \brief Disable TIMER power manage + \param[in] timer Handle to operate + \return None +*/ +void csi_timer_disable_pm(csi_timer_t *timer); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_TIMER_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/tipc.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/tipc.h new file mode 100755 index 00000000..da117ebc --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/tipc.h @@ -0,0 +1,56 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/tipc.h + * @brief Header File for TIPC Driver + * @version V1.0 + * @date 08. Mar 2020 + * @model tipc + ******************************************************************************/ + +#ifndef _DRV_TIPC_H_ +#define _DRV_TIPC_H_ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + uint32_t ip; + uint16_t dev_tag; + uint8_t idx; +} csi_tipcmap_t; + +/** + \brief Config the tipc module properity + \param[in] dev Dev handle \ref csi_dev_t + \param[in] is_secure is secure or not +*/ +csi_error_t csi_dev_secure_config(csi_dev_t *dev, bool is_secure); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_TIPC_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/uart.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/uart.h new file mode 100755 index 00000000..20ecc29d --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/uart.h @@ -0,0 +1,241 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/uart.h + * @brief Header File for UART Driver + * @version V1.0 + * @date 08. Apr 2020 + * @model uart + ******************************************************************************/ + +#ifndef _DRV_UART_H_ +#define _DRV_UART_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*----- UART Control Codes: Mode Parameters: Data Bits -----*/ +typedef enum { + UART_DATA_BITS_5 = 0, ///< 5 Data bits + UART_DATA_BITS_6, ///< 6 Data bit + UART_DATA_BITS_7, ///< 7 Data bits + UART_DATA_BITS_8, ///< 8 Data bits (default) + UART_DATA_BITS_9 ///< 9 Data bits +} csi_uart_data_bits_t; + +/*----- UART Control Codes: Mode Parameters: Parity -----*/ +typedef enum { + UART_PARITY_NONE = 0, ///< No Parity (default) + UART_PARITY_EVEN, ///< Even Parity + UART_PARITY_ODD, ///< Odd Parity +} csi_uart_parity_t; + +/*----- UART Control Codes: Mode Parameters: Stop Bits -----*/ +typedef enum { + UART_STOP_BITS_1 = 0, ///< 1 Stop bit (default) + UART_STOP_BITS_2, ///< 2 Stop bits + UART_STOP_BITS_1_5, ///< 1.5 Stop bits +} csi_uart_stop_bits_t; + +/*----- UART Control Codes: Mode Parameters: Flow Control -----*/ +typedef enum { + UART_FLOWCTRL_NONE = 0, ///< none flowctrl + UART_FLOWCTRL_RTS, ///< RTS + UART_FLOWCTRL_CTS, ///< CTS + UART_FLOWCTRL_RTS_CTS ///< RTS & CTS +} csi_uart_flowctrl_t; + +/****** UART Event *****/ +typedef enum { + UART_EVENT_SEND_COMPLETE = 0, ///< Send data completed. + UART_EVENT_RECEIVE_COMPLETE, ///< Receive data completed. + UART_EVENT_RECEIVE_FIFO_READABLE, ///< Data in uart fifo, call csi_uart_receive() get the data. + UART_ENENT_BREAK_INTR, ///< the serial input,sin, is held in a logic '0' state for longer than the sum of start time+data bits+parity+stop bits. + UART_EVENT_ERROR_OVERFLOW, ///< A new data character was received before the previous data was read. + UART_EVENT_ERROR_PARITY, ///< Occur parity error in the receiver. + UART_EVENT_ERROR_FRAMING ///< the receiver does not detect a valid STOP bit in the received data. +} csi_uart_event_t; + +///< definition for uart. +typedef struct csi_uart csi_uart_t; + +struct csi_uart { + csi_dev_t dev; + void (*callback)(csi_uart_t *uart, csi_uart_event_t event, void *arg); + void *arg; + uint8_t *tx_data; + uint32_t tx_size; + uint8_t *rx_data; + uint32_t rx_size; + csi_dma_ch_t *tx_dma; + csi_dma_ch_t *rx_dma; + csi_error_t (*send)(csi_uart_t *uart, const void *data, uint32_t size); + csi_error_t (*receive)(csi_uart_t *uart, void *data, uint32_t size); + csi_state_t state; + void *priv; +}; + +/** + \brief Initializes the resources needed for the UART interface. + \param[in] uart Operate handle. + \param[in] idx The device idx. + \return Error code. +*/ +csi_error_t csi_uart_init(csi_uart_t *uart, uint32_t idx); + +/** + \brief De-initialize UART Interface. stops operation and releases the software resources used by the interface. + \param[in] uart Operate handle. + \return Error code. +*/ +void csi_uart_uninit(csi_uart_t *uart); + +/** + \brief Attach the callback handler to UART. + \param[in] uart Operate handle. + \param[in] callback Callback function. + \param[in] arg User can define it by himself as callback's param. + \return Error code. +*/ +csi_error_t csi_uart_attach_callback(csi_uart_t *uart, void *callback, void *arg); + +/** + \brief Detach the callback handler. + \param[in] uart Operate handle. +*/ +void csi_uart_detach_callback(csi_uart_t *uart); + +/** + \brief Config the baudrate. + \param[in] uart UART handle to operate. + \param[in] baud UART baudrate. + \return Error code. +*/ +csi_error_t csi_uart_baud(csi_uart_t *uart, uint32_t baud); + +/** + \brief Config the uart format. + \param[in] uart UART handle to operate. + \param[in] data_bit UART data bits. + \param[in] parity UART data parity. + \param[in] stop_bit UART stop bits. + \return Error code. +*/ +csi_error_t csi_uart_format(csi_uart_t *uart, csi_uart_data_bits_t data_bits, + csi_uart_parity_t parity, csi_uart_stop_bits_t stop_bits); + +/** + \brief Config the uart flow control. + \param[in] uart UART handle to operate. + \param[in] flowctrl UART flow control. + \return Error code. +*/ +csi_error_t csi_uart_flowctrl(csi_uart_t *uart, csi_uart_flowctrl_t flowctrl); + +/** + \brief Start send data to UART transmitter, this function is blocking. + \param[in] uart UART handle to operate. + \param[in] data Pointer to buffer with data to send to UART transmitter. + \param[in] size Number of data to send (byte). + \param[in] timeout The timeout between bytes(ms). + \return the num of data which is sent successfully or CSI_ERROR. +*/ +int32_t csi_uart_send(csi_uart_t *uart, const void *data, uint32_t size, uint32_t timeout); + +/** + \brief Start send data to UART transmitter, this function is non-blocking. + \param[in] uart UART handle to operate. + \param[in] data Pointer to buffer with data to send to UART transmitter. + \param[in] size Number of data to send (byte). + \return Error code. +*/ +csi_error_t csi_uart_send_async(csi_uart_t *uart, const void *data, uint32_t size); + +/** + \brief Query data from UART receiver FIFO, this function is blocking. + \param[in] uart UART handle to operate. + \param[out] data Pointer to buffer for data to receive from UART receiver. + \param[in] size Number of data to receive. + \param[in] timeout The timeout between bytes(ms). + \return the num of data witch is received successfully or CSI_ERROR. +*/ +int32_t csi_uart_receive(csi_uart_t *uart, void *data, uint32_t size, uint32_t timeout); + +/** + \brief Start receiving data from UART receiver, this function is non-blocking. + \param[in] uart UART handle to operate. + \param[out] data Pointer to buffer for data to receive from UART receiver. + \param[in] size Number of data to receive (byte). + \return Error code. +*/ +csi_error_t csi_uart_receive_async(csi_uart_t *uart, void *data, uint32_t size); + +/** + \brief Get character in query mode. + \param[in] uart UART handle to operate. + \return the character to get. +*/ +uint8_t csi_uart_getc(csi_uart_t *uart); + +/** + \brief Send character in query mode. + \param[in] uart UART handle to operate. + \param[in] ch The character to be send. +*/ +void csi_uart_putc(csi_uart_t *uart, uint8_t ch); + +/** + \brief Link DMA channel to uart device. + \param[in] uart UART handle to operate. + \param[in] tx_dma The DMA channel handle for send, when it is NULL means to unlink the channel. + \param[in] rx_dma The DMA channel handle for receive, when it is NULL means to unlink the channel. + \return Error code. +*/ +csi_error_t csi_uart_link_dma(csi_uart_t *uart, csi_dma_ch_t *tx_dma, csi_dma_ch_t *rx_dma); + +/** + \brief Get the state of uart device. + \param[in] uart UART handle to operate. + \param[out] state The state of uart device. + \return Error code. +*/ +csi_error_t csi_uart_get_state(csi_uart_t *uart, csi_state_t *state); + +/** + \brief Enable uart power manage. + \param[in] uart UART handle to operate. + \return Error code. +*/ +csi_error_t csi_uart_enable_pm(csi_uart_t *uart); + +/** + \brief Disable uart power manage. + \param[in] uart UART handle to operate. +*/ +void csi_uart_disable_pm(csi_uart_t *uart); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_UART_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/usi.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/usi.h new file mode 100755 index 00000000..8e8cb1d3 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/usi.h @@ -0,0 +1,42 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/usi.h + * @brief Header File for USI Driver + * @version V1.0 + * @date 02. June 2020 + * @model usi + ******************************************************************************/ + +#ifndef _DRV_USI_H_ +#define _DRV_USI_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_USI_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/usi_iic.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/usi_iic.h new file mode 100755 index 00000000..257b534a --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/usi_iic.h @@ -0,0 +1,260 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/drv_usi_iic.h + * @brief Header File for IIC driver + * @version V1.0 + * @date 02. June 2020 + * @model usi_iic + ******************************************************************************/ + +#ifndef _DRV_USI_IIC_H_ +#define _DRV_USI_IIC_H_ + +#include +#include +#include +#include +#ifdef __cplusplus +extern "C" { +#endif + +/** + \brief Init iic ctrl block. + Initializes the resources needed for the iic instance. + \param[in] iic Handle of iic instance. + \param[in] idx Index of instance. + \return \ref csi_error_t. +*/ +csi_error_t csi_usi_iic_init(csi_iic_t *iic, uint32_t idx); + +/** + \brief Uninit iic ctrl block. + Stops operation and releases the software resources used by the instance. + \param[in] iic Handle of iic instance. +*/ +void csi_usi_iic_uninit(csi_iic_t *iic); + +/** + \brief Config iic master or slave mode. + \param[in] iic Handle of iic instance. + \param[in] mode IIC mode \ref csi_iic_mode_t. + \return \ref csi_error_t. +*/ +csi_error_t csi_usi_iic_mode(csi_iic_t *iic, csi_iic_mode_t mode); + +/** + \brief Config iic addr mode. + \param[in] iic Handle of iic instance. + \param[in] addr_mode IIC addr mode \ref csi_iic_addr_mode_t. + \return \ref csi_error_t. +*/ +csi_error_t csi_usi_iic_addr_mode(csi_iic_t *iic, csi_iic_addr_mode_t addr_mode); + +/** + \brief Config iic speed. + \param[in] iic Handle of iic instance. + \param[in] speed iic speed mode \ref csi_iic_speed_t. + \return \ref csi_error_t. +*/ +csi_error_t csi_usi_iic_speed(csi_iic_t *iic, csi_iic_speed_t speed); + +/** + \brief Config iic own addr. + \param[in] iic Handle of iic instance. + \param[in] own_addr IIC set own addr at slave mode. + \return \ref csi_error_t. +*/ +csi_error_t csi_usi_iic_own_addr(csi_iic_t *iic, uint32_t own_addr); + +/** + \brief Start sending data as iic master. + This function is blocking. + \param[in] iic Handle of iic instance. + \param[in] devaddr Addrress of slave device. + \param[in] data Pointer to send data buffer. + \param[in] size Size of data items to send. + \param[in] timout Unit of time delay(ms). + \return The amount of real data sent. +*/ +int32_t csi_usi_iic_master_send(csi_iic_t *iic, uint32_t devaddr, const void *data, uint32_t size, uint32_t timeout); + +/** + \brief Start receiving data as iic master. + This function is blocking. + \param[in] iic Handle to operate. + \param[in] devaddr IIC addrress of slave device. + \param[out] data Pointer to buffer for data to receive from iic receiver. + \param[in] size Size of data items to receive. + \param[in] timeout Unit of time delay(ms). + \return The amount of real data received. +*/ +int32_t csi_usi_iic_master_receive(csi_iic_t *iic, uint32_t devaddr, void *data, uint32_t size, uint32_t timeout); + +/** + \brief Start sending data as iic master. + This function is non-blocking,\ref csi_usi_iic_event_t is signaled when transfer completes or error happens. + \param[in] iic Handle to operate. + \param[in] devaddr IIC addrress of slave device. + \param[in] data Pointer to send data buffer. + \param[in] size Size of data items to send. + \return \ref csi_error_t. +*/ +csi_error_t csi_usi_iic_master_send_async(csi_iic_t *iic, uint32_t devaddr, const void *data, uint32_t size); + +/** + \brief Start receiving data as iic master. + This function is non-blocking.\ref csi_usi_iic_event_t is signaled when transfer completes or error happens. + \param[in] iic Handle to operate. + \param[in] devaddr IIC addrress of slave device. + \param[out] data Pointer to buffer for data to receive from iic receiver. + \param[in] size Size of data items to receive. + \return \ref csi_error_t. +*/ +csi_error_t csi_usi_iic_master_receive_async(csi_iic_t *iic, uint32_t devaddr, void *data, uint32_t size); + +/** + \brief Start sending data as iic master. + This function is blocking. + \param[in] iic Handle of iic instance. + \param[in] devaddr Addrress of slave device. + \param[in] memaddr Internal addr of device. + \param[in] memaddr_size Internal addr mode of device. + \param[in] data Pointer to send data buffer. + \param[in] size Size of data items to send. + \param[in] timout Unit of time delay(ms). + \return The amount of real data sent. +*/ +int32_t csi_usi_iic_mem_send(csi_iic_t *iic, uint32_t devaddr, uint16_t memaddr, csi_iic_mem_addr_size_t memaddr_size, const void *data, uint32_t size, uint32_t timeout); + +/** + \brief Start receiving data as iic master. + This function is blocking. + \param[in] iic Handle to operate. + \param[in] devaddr IIC addrress of slave device. + \param[in] memaddr Internal addr of device. + \param[in] memaddr_mode Internal addr mode of device. + \param[out] data Pointer to buffer for data to receive from eeprom device. + \param[in] size Size of data items to receive. + \param[in] timeout Unit of time delay(ms). + \return The amount of real data received. +*/ +int32_t csi_usi_iic_mem_receive(csi_iic_t *iic, uint32_t devaddr, uint16_t memaddr, csi_iic_mem_addr_size_t memaddr_size, void *data, uint32_t size, uint32_t timeout); + +/** + \brief Start sending data as iic slave. + This function is blocking. + \param[in] iic Handle to operate. + \param[in] data Pointer to buffer with data to send to iic master. + \param[in] size Size of data items to send. + \param[in] timeout Unit of time delay(ms). + \return The amount of real data sent. +*/ +int32_t csi_usi_iic_slave_send(csi_iic_t *iic, const void *data, uint32_t size, uint32_t timeout); + +/** + \brief Start receiving data as iic slave. + This function is blocking. + \param[in] iic Handle to operate. + \param[out] data Pointer to buffer for data to receive from iic master. + \param[in] size Size of data items to receive. + \param[in] timeout Unit of time delay(ms). + \return The amount of real data received. +*/ +int32_t csi_usi_iic_slave_receive(csi_iic_t *iic, void *data, uint32_t size, uint32_t timeout); + +/** + \brief Start sending data as iic slave. + This function is non-blocking,\ref csi_usi_iic_event_t is signaled when transfer completes or error happens. + \param[in] iic Handle to operate. + \param[in] data Pointer to buffer with data to send to iic master. + \param[in] size size of data items to send. + \return \ref csi_error_t. +*/ +csi_error_t csi_usi_iic_slave_send_async(csi_iic_t *iic, const void *data, uint32_t size); + +/** + \brief Start receiving data as iic slave. + This function is non-blocking,\ref csi_usi_iic_event_t is signaled when transfer completes or error happens. + \param[in] handle IIC handle to operate. + \param[out] data Pointer to buffer for data to receive from iic master. + \param[in] size Size of data items to receive. + \return \ref csi_error_t. +*/ +csi_error_t csi_usi_iic_slave_receive_async(csi_iic_t *iic, void *data, uint32_t size); + +/** + \brief Attach callback to the iic. + \param[in] iic IIC handle to operate. + \param[in] cb Event callback function \ref csi_usi_iic_callback_t. + \param[in] arg User private param for event callback. + \return \ref csi_error_t. +*/ +csi_error_t csi_usi_iic_attach_callback(csi_iic_t *iic, void *callback, void *arg); + +/** + \brief Detach callback from the iic. + \param[in] iic IIC handle to operate. + \return \ref csi_error_t. +*/ +void csi_usi_iic_detach_callback(csi_iic_t *iic); + +/** + \brief Config iic stop to generate. + \param[in] iic IIC handle to operate. + \param[in] enable Transfer operation is pending - stop condition will not be generated. + \return \ref csi_error_t. +*/ +csi_error_t csi_usi_iic_xfer_pending(csi_iic_t *iic, bool enable); + +/** + \brief Link DMA channel to iic device. + \param[in] iic Handle to operate. + \param[in] tx_dma The DMA channel handle for send, when it is NULL means to unlink the channel. + \param[in] rx_dma The DMA channel handle for receive, when it is NULL means to unlink the channel. + \return \ref csi_error_t. +*/ +csi_error_t csi_usi_iic_link_dma(csi_iic_t *iic, csi_dma_ch_t *tx_dma, csi_dma_ch_t *rx_dma); + +/** + \brief Get iic state. + \param[in] iic Handle to operate. + \param[out] state IIC state \ref csi_state_t. + \return \ref csi_error_t. +*/ +csi_error_t csi_usi_iic_get_state(csi_iic_t *iic, csi_state_t *state); + +/** + \brief Enable iic power manage. + \param[in] iic IIC handle to operate. + \return \ref csi_error_t. +*/ +csi_error_t csi_usi_iic_enable_pm(csi_iic_t *iic); + +/** + \brief Disable iic power manage. + \param[in] iic IIC handle to operate. +*/ +void csi_usi_iic_disable_pm(csi_iic_t *iic); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_USI_IIC_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/usi_spi.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/usi_spi.h new file mode 100755 index 00000000..eaa1f3e3 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/usi_spi.h @@ -0,0 +1,229 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/usi_spi.h + * @brief Header File for SPI Driver + * @version V1.0 + * @date 02. June 2020 + * @model usi_spi + ******************************************************************************/ + +#ifndef _DRV_SPI_USI_H_ +#define _DRV_SPI_USI_H_ + +#include +#include +#include +#ifdef __cplusplus +extern "C" { +#endif + +/** + \brief Initialize SPI Interface. + Initializes the resources needed for the SPI instance + \param[in] spi SPI handle + \param[in] idx SPI instance index + \return Error code +*/ +csi_error_t csi_usi_spi_init(csi_spi_t *spi, uint32_t idx); + +/** + \brief De-initialize SPI Interface + Stops operation and releases the software resources used by the spi instance + \param[in] spi SPI handle + \return None +*/ +void csi_usi_spi_uninit(csi_spi_t *spi); + +/** + \brief Attach the callback handler to SPI + \param[in] spi Operate handle. + \param[in] callback Callback function + \param[in] arg User can define it by himself as callback's param + \return Error code +*/ +csi_error_t csi_usi_spi_attach_callback(csi_spi_t *spi, void *callback, void *arg); + +/** + \brief Detach the callback handler + \param[in] spi Operate handle. + \return None +*/ +void csi_usi_spi_detach_callback(csi_spi_t *spi); + + +/** + \brief Config spi mode (master or slave). + \param[in] spi SPI handle + \param[in] mode The mode of spi (master or slave) + \return Error code +*/ +csi_error_t csi_usi_spi_mode(csi_spi_t *spi, csi_spi_mode_t mode); + +/** + \brief Config spi cp format. + \param[in] spi SPI handle + \param[in] format SPI cp format + \return Error code +*/ +csi_error_t csi_usi_spi_cp_format(csi_spi_t *spi, csi_spi_cp_format_t format); + +/** + \brief Config spi frame len. + \param[in] spi SPI handle + \param[in] length spi frame len + \return error code +*/ +csi_error_t csi_usi_spi_frame_len(csi_spi_t *spi, csi_spi_frame_len_t length); + +/** + \brief Config spi work frequence. + \param[in] spi SPI handle + \param[in] baud SPI work baud + \return The actual config frequency +*/ +uint32_t csi_usi_spi_baud(csi_spi_t *spi, uint32_t baud); + +/** + \brief Config spi mode. + \param[in] Handle spi handle to operate. + \param[in] baud SPI baud rate. If negative, then this attribute not changed + \param[in] mode \ref spi_mode_e . If negative, then this attribute not changed + \param[in] format \ref spi_format_e . If negative, then this attribute not changed + \param[in] order \ref spi_bit_order_e . If negative, then this attribute not changed + \param[in] ss_mode \ref spi_ss_mode_t . If negative, then this attribute not changed + \param[in] bit_width SPI data bitwidth: (1 ~ SPI_DATAWIDTH_MAX) . If negative, then this attribute not changed + \return Error code +*/ +csi_error_t drv_usi_spi_config(csi_spi_t *spi, csi_spi_mode_t mode, csi_spi_frame_len_t width, csi_spi_cp_format_t format); + +/** + \brief Sending data to SPI transmitter,(received data is ignored). + Blocking mode ,return unti all data has been sent or err happened + \param[in] spi Handle to operate. + \param[in] data Pointer to buffer with data to send to SPI transmitter. + \param[in] size Number of data to send(byte) + \param[in] timeout Unit in mini-second + \return If send success, this function shall return the num of data witch is sent successful + otherwise, the function shall return error code +*/ +int32_t csi_usi_spi_send(csi_spi_t *spi, const void *data, uint32_t size, uint32_t timeout); + +/** + \brief Sending data to SPI transmitter,(received data is ignored). + non-blocking mode,transfer done event will be signaled by driver + \param[in] spi Handle to operate. + \param[in] data Pointer to buffer with data to send to SPI transmitter. + \param[in] size Number of data items to send(byte) + \return Error code +*/ +csi_error_t csi_usi_spi_send_async(csi_spi_t *spi, const void *data, uint32_t size); + +/** + \brief Receiving data from SPI receiver. + Blocking mode, return untill curtain data items are readed + \param[in] spi Handle to operate. + \param[out] data Pointer to buffer for data to receive from SPI receiver + \param[in] size Number of data items to receive(byte) + \param[in] timeout Unit in mini-second + \return If receive success, this function shall return the num of data witch is received successful + Otherwise, the function shall return error code +*/ +int32_t csi_usi_spi_receive(csi_spi_t *spi, void *data, uint32_t size, uint32_t timeout); + +/** + \brief Receiving data from SPI receiver. + Not-blocking mode, event will be signaled when receive done or err happend + \param[in] spi Handle to operate. + \param[out] data Pointer to buffer for data to receive from SPI receiver + \param[in] size Number of data items to receive(byte) + \return Error code +*/ +csi_error_t csi_usi_spi_receive_async(csi_spi_t *spi, void *data, uint32_t size); + +/** + \brief Dulplex,sending and receiving data at the same time + \ref csi_spi_event_t is signaled when operation completes or error happens. + \ref csi_spi_get_state can get operation status. + Blocking mode, this function returns after operation completes or error happens. + \param[in] Handle spi handle to operate. + \param[in] data_out Pointer to buffer with data to send to SPI transmitter + \param[out] data_in Pointer to buffer for data to receive from SPI receiver + \param[in] size Data size(byte) + \return If transfer success, this function shall return the num of data witch is transfer successful + otherwise, the function shall return error code +*/ +int32_t csi_usi_spi_send_receive(csi_spi_t *spi, const void *data_out, void *data_in, uint32_t size, uint32_t timeout); + +/** + \brief Transmit first then receive ,receive will begin after transmit is done + if non-blocking mode, this function only starts the transfer, + \ref csi_spi_event_t is signaled when operation completes or error happens. + \ref csi_spi_get_state can get operation status. + \param[in] handle spi Handle to operate. + \param[in] data_out Pointer to buffer with data to send to SPI transmitter + \param[out] data_in Pointer to buffer for data to receive from SPI receiver + \param[in] size Data size(byte) + \return Error code +*/ +csi_error_t csi_usi_spi_send_receive_async(csi_spi_t *spi, const void *data_out, void *data_in, uint32_t size); + +/* + \brief Set slave select num. Only valid for master + \param[in] Handle spi handle to operate. + \param[in] slave_num SPI slave num. + \return None + */ +void csi_usi_spi_select_slave(csi_spi_t *spi, uint32_t slave_num); + +/** + \brief Link DMA channel to spi device + \param[in] spi SPI handle to operate. + \param[in] tx_dma The DMA channel handle for send, when it is NULL means to unlink the channel + \param[in] rx_dma The DMA channel handle for receive, when it is NULL means to unlink the channel + \return Error code +*/ +csi_error_t csi_usi_spi_link_dma(csi_spi_t *spi, csi_dma_ch_t *tx_dma, csi_dma_ch_t *rx_dma); + +/** + \brief Get the state of spi device + \param[in] spi SPI handle to operate. + \param[out] state The state of spi device + \return Error code +*/ +csi_error_t csi_usi_spi_get_state(csi_spi_t *spi, csi_state_t *state); + +/** + \brief Enable spi power manage + \param[in] spi SPI handle to operate. + \return Error code +*/ +csi_error_t csi_usi_spi_enable_pm(csi_spi_t *spi); + +/** + \brief Disable spi power manage + \param[in] spi SPI handle to operate. + \return Error code +*/ +void csi_spi_disable_pm(csi_spi_t *spi); +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_SPI_USI_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/usi_usart.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/usi_usart.h new file mode 100755 index 00000000..59bfe554 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/usi_usart.h @@ -0,0 +1,192 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/usi_usart.h + * @brief Header File for USART Driver + * @version V1.0 + * @date 02. June 2020 + * @model usi_usart + ******************************************************************************/ + +#ifndef _DRV_USI_USART_H_ +#define _DRV_USI_USART_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + \brief Initialize UART Interface. 1. Initializes the resources needed for the UART interface 2.registers event callback function + \param[in] uart Operate handle. + \param[in] idx The device idx + \param[in] cb_event Event call back function \ref uart_event_cb_t + \param[in] arg User can define it by himself + \return error code +*/ +csi_error_t csi_usi_uart_init(csi_uart_t *uart, uint32_t idx); + +/** + \brief De-initialize UART Interface. stops operation and releases the software resources used by the interface + \param[in] uart Operate handle. + \return Error code +*/ +void csi_usi_uart_uninit(csi_uart_t *uart); + +/** + \brief Attach the callback handler to UART + \param[in] uart Operate handle. + \param[in] cb Callback function + \param[in] arg User can define it by himself as callback's param + \return Error code +*/ +csi_error_t csi_usi_uart_attach_callback(csi_uart_t *uart, void * cb, void *arg); + +/** + \brief Detach the callback handler + \param[in] uart Operate handle. +*/ +void csi_usi_uart_detach_callback(csi_uart_t *uart); + +/** + \brief Config the baudrate. + \param[in] uart UART handle to operate. + \param[in] baud UART baudrate + \return Error code +*/ +csi_error_t csi_usi_uart_baud(csi_uart_t *uart, uint32_t baud); + +/** + \brief Config the uart format. + \param[in] uart UART handle to operate. + \param[in] data_bit UART data bits + \param[in] parity UART data parity + \param[in] stop_bit UART stop bits + \return Error code +*/ +csi_error_t csi_usi_uart_format(csi_uart_t *uart, csi_uart_data_bits_t data_bits, + csi_uart_parity_t parity, csi_uart_stop_bits_t stop_bits); + +/** + \brief Config the uart flow control. + \param[in] uart UART handle to operate. + \param[in] flowctrl UART flow control + \return Error code +*/ +csi_error_t csi_usi_uart_flowctrl(csi_uart_t *uart, csi_uart_flowctrl_t flowctrl); + +/** + \brief Start sending data to UART transmitter. + \param[in] uart UART handle to operate. + \param[in] data Pointer to buffer with data to send to UART transmitter. data_type is : uint8_t for 5..8 data bits, uint16_t for 9 data bits + \param[in] num Number of data items to send (byte) + \param[in] Timeout is the number of queries, not time + \return The num of data witch is send successful +*/ +int32_t csi_usi_uart_send(csi_uart_t *uart, const void *data, uint32_t size, uint32_t timeout); + +/** + \brief Start sending data to UART transmitter (interrupt mode). + \param[in] uart UART handle to operate. + \param[in] data Pointer to buffer with data to send to UART transmitter. data_type is : uint8_t for 5..8 data bits, uint16_t for 9 data bits + \param[in] num Number of data items to send + \return The status of send func +*/ +csi_error_t csi_usi_uart_send_async(csi_uart_t *uart, const void *data, uint32_t size); + +/** + \brief Get the num of data in RX_FIFO. + \param[in] uart UART handle to operate. + \return The num of data in RX_FIFO +*/ +uint32_t csi_usi_uart_get_recvfifo_waiting_num(csi_uart_t *uart); + +/** + \brief Start receiving data from UART receiver. \n + This function is non-blocking,\ref uart_event_e is signaled when operation completes or error happens. + \ref csi_uart_get_status can get operation status. + \param[in] uart UART handle to operate. + \param[out] data Pointer to buffer for data to receive from UART receiver.data_type is : uint8_t for 5..8 data bits, uint16_t for 9 data bits + \param[in] num Number of data items to receive + \return Error code +*/ +csi_error_t csi_usi_uart_receive_async(csi_uart_t *uart, void *data, uint32_t size); + +/** + \brief Query data from UART receiver FIFO. + \param[in] uart UART handle to operate. + \param[out] data Pointer to buffer for data to receive from UART receiver + \param[in] num Number of data items to receive + \param[in] Timeout is the number of queries, not time + \return FIFO data num to receive +*/ +int32_t csi_usi_uart_receive(csi_uart_t *uart, void *data, uint32_t size, uint32_t timeout); + +/** + \brief Get character in query mode. + \param[in] uart UART handle to operate. + \param[out] ch The pointer to the received character. + \return Error code +*/ +uint8_t csi_usi_uart_getchar(csi_uart_t *uart); + +/** + \brief Transmit character in query mode. + \param[in] uart UART handle to operate. + \param[in] ch The input character + \return Error code +*/ +void csi_usi_uart_putchar(csi_uart_t *uart, uint8_t ch); + +/** + \brief Link DMA channel to uart device + \param[in] uart UART handle to operate. + \param[in] tx_dma The DMA channel handle for send, when it is NULL means to unlink the channel + \param[in] rx_dma The DMA channel handle for receive, when it is NULL means to unlink the channel + \return Error code +*/ +csi_error_t csi_usi_uart_link_dma(csi_uart_t *uart, csi_dma_ch_t *tx_dma, csi_dma_ch_t *rx_dma); + +/** + \brief Get the state of uart device. + \param[in] uart UART handle to operate. + \param[out] state The state of uart device. + \return Error code. +*/ +csi_error_t csi_usi_uart_get_state(csi_uart_t *uart, csi_state_t *state); + +/** + \brief Enable uart power manage. + \param[in] uart UART handle to operate. + \return Error code. +*/ +csi_error_t csi_usi_uart_enable_pm(csi_uart_t *uart); + +/** + \brief Disable uart power manage. + \param[in] uart UART handle to operate. +*/ +void csi_usi_uart_disable_pm(csi_uart_t *uart); +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_USI_USART_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/wdt.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/wdt.h new file mode 100755 index 00000000..d7a824ec --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/drv/wdt.h @@ -0,0 +1,139 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 drv/wdt.h + * @brief Header File for WDT Driver + * @version V1.0 + * @date 9. Oct 2020 + * @model wdt + ******************************************************************************/ + +#ifndef _DRV_WDT_H_ +#define _DRV_WDT_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct csi_wdt csi_wdt_t; + +struct csi_wdt { + csi_dev_t dev; + void (*callback)(csi_wdt_t *wdt, void *arg); + void *arg; + void *priv; +}; + +/** + \brief Initialize WDT interface. Initializes the resources needed for the WDT interface + \param[in] wdt Handle to operate + \param[in] idx WDT index + \return Error code \ref csi_error_t +*/ +csi_error_t csi_wdt_init(csi_wdt_t *wdt, uint32_t idx); + +/** + \brief De-initialize WDT interface. Stops operation and releases the software resources used by the interface + \param[in] wdt Handle to operate + \return None +*/ +void csi_wdt_uninit(csi_wdt_t *wdt); + +/** + \brief Set the WDT value + \param[in] wdt Handle to operate + \param[in] ms The timeout value(ms) + \return Error code \ref csi_error_t +*/ +csi_error_t csi_wdt_set_timeout(csi_wdt_t *wdt, uint32_t ms); + +/** + \brief Start the WDT + \param[in] wdt Handle to operate + \return Error code \ref csi_error_t +*/ +csi_error_t csi_wdt_start(csi_wdt_t *wdt); + +/** + \brief Stop the WDT + \param[in] wdt Handle to operate + \return None +*/ +void csi_wdt_stop(csi_wdt_t *wdt); + +/** + \brief Feed the WDT + \param[in] wdt Handle to operate + \return Error code \ref csi_error_t +*/ +csi_error_t csi_wdt_feed(csi_wdt_t *wdt); + +/** + \brief Get the remaining time to timeout + \param[in] wdt Handle to operate + \return The remaining time of WDT(ms) +*/ +uint32_t csi_wdt_get_remaining_time(csi_wdt_t *wdt); + +/** + \brief Check WDT is running + \param[in] wdt Handle to operate + \return + true - WDT is running + false - WDT is stopped +*/ +bool csi_wdt_is_running(csi_wdt_t *wdt); + +/** + \brief Attach the callback handler to WDT + \param[in] wdt Handle to operate + \param[in] callback Callback function + \param[in] arg Callback's param + \return Error code \ref csi_error_t +*/ +csi_error_t csi_wdt_attach_callback(csi_wdt_t *wdt, void *callback, void *arg); + +/** + \brief Detach the callback handler + \param[in] wdt Handle to operate + \return None +*/ +void csi_wdt_detach_callback(csi_wdt_t *wdt); + +/** + \brief Enable WDT power manage + \param[in] wdt Handle to operate + \return Error code \ref csi_error_t +*/ +csi_error_t csi_wdt_enable_pm(csi_wdt_t *wdt); + +/** + \brief Disable WDT power manage + \param[in] wdt Handle to operate + \return None +*/ +void csi_wdt_disable_pm(csi_wdt_t *wdt); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRV_WDT_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/dsp/csi_common_tables.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/dsp/csi_common_tables.h new file mode 100644 index 00000000..7d5e4028 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/dsp/csi_common_tables.h @@ -0,0 +1,316 @@ +/* + * Copyright (C) 2016-2019 C-SKY 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 csi_common_tables.h + * @brief This file has extern declaration for common tables like + * Bitreverse, reciprocal etc which are used across different functions. + * @version V1.0 + * @date 20. Dec 2016 + ******************************************************************************/ + +#ifndef _CSI_COMMON_TABLES_H +#define _CSI_COMMON_TABLES_H + +#include "csi_math.h" + +extern const uint16_t csiBitRevTable[1024]; +extern const q15_t csiRecipTableQ15[64]; +extern const q31_t csiRecipTableQ31[64]; +extern const uint32_t twiddleCoef_16[32]; +extern const uint32_t twiddleCoef_32[64]; +extern const uint32_t twiddleCoef_64[128]; +extern const uint32_t twiddleCoef_128[256]; +extern const uint32_t twiddleCoef_256[512]; +extern const uint32_t twiddleCoef_512[1024]; +extern const uint32_t twiddleCoef_1024[2048]; +extern const uint32_t twiddleCoef_2048[4096]; +extern const uint32_t twiddleCoef_4096[8192]; +extern const q31_t twiddleCoef_16_q31[24]; +extern const q31_t twiddleCoef_32_q31[48]; +extern const q31_t twiddleCoef_64_q31[96]; +extern const q31_t twiddleCoef_128_q31[192]; +extern const q31_t twiddleCoef_256_q31[384]; +extern const q31_t twiddleCoef_512_q31[768]; +extern const q31_t twiddleCoef_1024_q31[1536]; +extern const q31_t twiddleCoef_2048_q31[3072]; +extern const q31_t twiddleCoef_4096_q31[6144]; +extern const q15_t twiddleCoef_16_q15[24]; +extern const q15_t twiddleCoef_32_q15[48]; +extern const q15_t twiddleCoef_64_q15[96]; +extern const q15_t twiddleCoef_128_q15[192]; +extern const q15_t twiddleCoef_256_q15[384]; +extern const q15_t twiddleCoef_512_q15[768]; +extern const q15_t twiddleCoef_1024_q15[1536]; +extern const q15_t twiddleCoef_2048_q15[3072]; +extern const q15_t twiddleCoef_4096_q15[6144]; +extern const float32_t twiddleCoef_rfft_32[32]; +extern const float32_t twiddleCoef_rfft_64[64]; +extern const float32_t twiddleCoef_rfft_128[128]; +extern const float32_t twiddleCoef_rfft_256[256]; +extern const float32_t twiddleCoef_rfft_512[512]; +extern const float32_t twiddleCoef_rfft_1024[1024]; +extern const float32_t twiddleCoef_rfft_2048[2048]; +extern const float32_t twiddleCoef_rfft_4096[4096]; +extern const float32_t twiddleCoef_rfft_8192[8192]; + +extern const q15_t twiddleCoef_fast_16_q15[24]; +extern const q15_t twiddleCoef_fast_32_q15[56]; +extern const q15_t twiddleCoef_fast_64_q15[120]; +extern const q15_t twiddleCoef_fast_128_q15[248]; +extern const q15_t twiddleCoef_fast_256_q15[504]; +extern const q15_t twiddleCoef_fast_512_q15[1016]; +extern const q15_t twiddleCoef_fast_1024_q15[2040]; +extern const q15_t twiddleCoef_fast_2048_q15[4088]; +extern const q15_t twiddleCoef_fast_4096_q15[8184]; + +extern const q31_t twiddleCoef_fast_16_q31[24]; +extern const q31_t twiddleCoef_fast_32_q31[56]; +extern const q31_t twiddleCoef_fast_64_q31[120]; +extern const q31_t twiddleCoef_fast_128_q31[248]; +extern const q31_t twiddleCoef_fast_256_q31[504]; +extern const q31_t twiddleCoef_fast_512_q31[1016]; +extern const q31_t twiddleCoef_fast_1024_q31[2040]; +extern const q31_t twiddleCoef_fast_2048_q31[4088]; +extern const q31_t twiddleCoef_fast_4096_q31[8184]; + +extern const uint32_t twiddleCoef_fast_16[24]; +extern const uint32_t twiddleCoef_fast_32[56]; +extern const uint32_t twiddleCoef_fast_64[120]; +extern const uint32_t twiddleCoef_fast_128[248]; +extern const uint32_t twiddleCoef_fast_256[504]; +extern const uint32_t twiddleCoef_fast_512[1016]; +extern const uint32_t twiddleCoef_fast_1024[2040]; +extern const uint32_t twiddleCoef_fast_2048[4088]; +extern const uint32_t twiddleCoef_fast_4096[8184]; + +extern const q15_t realCoefAQ15_8192[8192]; +extern const q31_t realCoefAQ31_8192[8192]; +extern const q15_t realCoefBQ15_8192[8192]; +extern const q31_t realCoefBQ31_8192[8192]; + +/*Tables for RFFT.*/ +extern const q15_t ALIGN4 realCoefAQ15_32[32]; +extern const q15_t ALIGN4 realCoefAQ15_64[64]; +extern const q15_t ALIGN4 realCoefAQ15_128[128]; +extern const q15_t ALIGN4 realCoefAQ15_256[256]; +extern const q15_t ALIGN4 realCoefAQ15_512[512]; +extern const q15_t ALIGN4 realCoefAQ15_1024[1024]; +extern const q15_t ALIGN4 realCoefAQ15_2048[2048]; +extern const q15_t ALIGN4 realCoefAQ15_4096[4096]; + +extern const q15_t ALIGN4 realCoefBQ15_32[32]; +extern const q15_t ALIGN4 realCoefBQ15_64[64]; +extern const q15_t ALIGN4 realCoefBQ15_128[128]; +extern const q15_t ALIGN4 realCoefBQ15_256[256]; +extern const q15_t ALIGN4 realCoefBQ15_512[512]; +extern const q15_t ALIGN4 realCoefBQ15_1024[1024]; +extern const q15_t ALIGN4 realCoefBQ15_2048[2048]; +extern const q15_t ALIGN4 realCoefBQ15_4096[4096]; + +extern const q31_t realCoefAQ31_32[32]; +extern const q31_t realCoefAQ31_64[64]; +extern const q31_t realCoefAQ31_128[128]; +extern const q31_t realCoefAQ31_256[256]; +extern const q31_t realCoefAQ31_512[512]; +extern const q31_t realCoefAQ31_1024[1024]; +extern const q31_t realCoefAQ31_2048[2048]; +extern const q31_t realCoefAQ31_4096[4096]; + +extern const q31_t realCoefBQ31_32[32]; +extern const q31_t realCoefBQ31_64[64]; +extern const q31_t realCoefBQ31_128[128]; +extern const q31_t realCoefBQ31_256[256]; +extern const q31_t realCoefBQ31_512[512]; +extern const q31_t realCoefBQ31_1024[1024]; +extern const q31_t realCoefBQ31_2048[2048]; +extern const q31_t realCoefBQ31_4096[4096]; + + +extern const float32_t realCoefA[8192]; +extern const float32_t realCoefB[8192]; + +extern const csi_cfft_instance_q15 csi_cfft_fast_sR_q15_len16; +extern const csi_cfft_instance_q15 csi_cfft_fast_sR_q15_len32; +extern const csi_cfft_instance_q15 csi_cfft_fast_sR_q15_len64; +extern const csi_cfft_instance_q15 csi_cfft_fast_sR_q15_len128; +extern const csi_cfft_instance_q15 csi_cfft_fast_sR_q15_len256; +extern const csi_cfft_instance_q15 csi_cfft_fast_sR_q15_len512; +extern const csi_cfft_instance_q15 csi_cfft_fast_sR_q15_len1024; +extern const csi_cfft_instance_q15 csi_cfft_fast_sR_q15_len2048; +extern const csi_cfft_instance_q15 csi_cfft_fast_sR_q15_len4096; + +extern const csi_cfft_instance_q31 csi_cfft_fast_sR_q31_len16; +extern const csi_cfft_instance_q31 csi_cfft_fast_sR_q31_len32; +extern const csi_cfft_instance_q31 csi_cfft_fast_sR_q31_len64; +extern const csi_cfft_instance_q31 csi_cfft_fast_sR_q31_len128; +extern const csi_cfft_instance_q31 csi_cfft_fast_sR_q31_len256; +extern const csi_cfft_instance_q31 csi_cfft_fast_sR_q31_len512; +extern const csi_cfft_instance_q31 csi_cfft_fast_sR_q31_len1024; +extern const csi_cfft_instance_q31 csi_cfft_fast_sR_q31_len2048; +extern const csi_cfft_instance_q31 csi_cfft_fast_sR_q31_len4096; + +extern csi_rfft_fast_instance_q15 csi_rfft_fast_sR_q15_len32; +extern csi_rfft_fast_instance_q15 csi_rfft_fast_sR_q15_len64; +extern csi_rfft_fast_instance_q15 csi_rfft_fast_sR_q15_len128; +extern csi_rfft_fast_instance_q15 csi_rfft_fast_sR_q15_len256; +extern csi_rfft_fast_instance_q15 csi_rfft_fast_sR_q15_len512; +extern csi_rfft_fast_instance_q15 csi_rfft_fast_sR_q15_len1024; +extern csi_rfft_fast_instance_q15 csi_rfft_fast_sR_q15_len2048; +extern csi_rfft_fast_instance_q15 csi_rfft_fast_sR_q15_len4096; +extern csi_rfft_fast_instance_q15 csi_rfft_fast_sR_q15_len8192; + +extern csi_rfft_fast_instance_q15 csi_inv_rfft_fast_sR_q15_len32; +extern csi_rfft_fast_instance_q15 csi_inv_rfft_fast_sR_q15_len64; +extern csi_rfft_fast_instance_q15 csi_inv_rfft_fast_sR_q15_len128; +extern csi_rfft_fast_instance_q15 csi_inv_rfft_fast_sR_q15_len256; +extern csi_rfft_fast_instance_q15 csi_inv_rfft_fast_sR_q15_len512; +extern csi_rfft_fast_instance_q15 csi_inv_rfft_fast_sR_q15_len1024; +extern csi_rfft_fast_instance_q15 csi_inv_rfft_fast_sR_q15_len2048; +extern csi_rfft_fast_instance_q15 csi_inv_rfft_fast_sR_q15_len4096; +extern csi_rfft_fast_instance_q15 csi_inv_rfft_fast_sR_q15_len8192; + +extern csi_rfft_fast_instance_q31 csi_rfft_fast_sR_q31_len32; +extern csi_rfft_fast_instance_q31 csi_rfft_fast_sR_q31_len64; +extern csi_rfft_fast_instance_q31 csi_rfft_fast_sR_q31_len128; +extern csi_rfft_fast_instance_q31 csi_rfft_fast_sR_q31_len256; +extern csi_rfft_fast_instance_q31 csi_rfft_fast_sR_q31_len512; +extern csi_rfft_fast_instance_q31 csi_rfft_fast_sR_q31_len1024; +extern csi_rfft_fast_instance_q31 csi_rfft_fast_sR_q31_len2048; +extern csi_rfft_fast_instance_q31 csi_rfft_fast_sR_q31_len4096; +extern csi_rfft_fast_instance_q31 csi_rfft_fast_sR_q31_len8192; + +extern csi_rfft_fast_instance_q31 csi_inv_rfft_fast_sR_q31_len32; +extern csi_rfft_fast_instance_q31 csi_inv_rfft_fast_sR_q31_len64; +extern csi_rfft_fast_instance_q31 csi_inv_rfft_fast_sR_q31_len128; +extern csi_rfft_fast_instance_q31 csi_inv_rfft_fast_sR_q31_len256; +extern csi_rfft_fast_instance_q31 csi_inv_rfft_fast_sR_q31_len512; +extern csi_rfft_fast_instance_q31 csi_inv_rfft_fast_sR_q31_len1024; +extern csi_rfft_fast_instance_q31 csi_inv_rfft_fast_sR_q31_len2048; +extern csi_rfft_fast_instance_q31 csi_inv_rfft_fast_sR_q31_len4096; +extern csi_rfft_fast_instance_q31 csi_inv_rfft_fast_sR_q31_len8192; + +extern csi_dct4_fast_instance_q15 csi_dct4_fast_sR_q15_len128; +extern csi_dct4_fast_instance_q15 csi_dct4_fast_sR_q15_len512; +extern csi_dct4_fast_instance_q15 csi_dct4_fast_sR_q15_len2048; +extern csi_dct4_fast_instance_q15 csi_dct4_fast_sR_q15_len8192; + +extern csi_dct4_fast_instance_q31 csi_dct4_fast_sR_q31_len128; +extern csi_dct4_fast_instance_q31 csi_dct4_fast_sR_q31_len512; +extern csi_dct4_fast_instance_q31 csi_dct4_fast_sR_q31_len2048; +extern csi_dct4_fast_instance_q31 csi_dct4_fast_sR_q31_len8192; + +/*Tables for DCT4*/ +#ifndef CSI_OPT_WEIGHT +extern const q15_t ALIGN4 WeightsQ15_128[256]; +extern const q15_t ALIGN4 WeightsQ15_512[1024]; +extern const q15_t ALIGN4 WeightsQ15_2048[4096]; +extern const q15_t ALIGN4 WeightsQ15_8192[16384]; +#else +extern const q15_t ALIGN4 WeightsQ15_128[128+2]; +extern const q15_t ALIGN4 WeightsQ15_512[512+2]; +extern const q15_t ALIGN4 WeightsQ15_2048[2048+2]; +extern const q15_t ALIGN4 WeightsQ15_8192[8192+2]; +#endif +extern const q15_t ALIGN4 cos_factorsQ15_128[128]; +extern const q15_t ALIGN4 cos_factorsQ15_512[512]; +extern const q15_t ALIGN4 cos_factorsQ15_2048[2048]; +extern const q15_t ALIGN4 cos_factorsQ15_8192[8192]; + +#ifndef CSI_OPT_WEIGHT +extern const q31_t WeightsQ31_128[256]; +extern const q31_t WeightsQ31_512[1024]; +extern const q31_t WeightsQ31_2048[4096]; +extern const q31_t WeightsQ31_8192[16384]; +#else +extern const q31_t WeightsQ31_128[128+2]; +extern const q31_t WeightsQ31_512[512+2]; +extern const q31_t WeightsQ31_2048[2048+2]; +extern const q31_t WeightsQ31_8192[8192+2]; +#endif + +extern const q31_t cos_factorsQ31_128[128]; +extern const q31_t cos_factorsQ31_512[512]; +extern const q31_t cos_factorsQ31_2048[2048]; +extern const q31_t cos_factorsQ31_8192[8192]; + +#ifndef CSI_OPT_WEIGHT +extern const float32_t Weights_128[256]; +extern const float32_t Weights_512[1024]; +extern const float32_t Weights_2048[4096]; +extern const float32_t Weights_8192[16384]; + +#else +extern const float32_t Weights_128[128+2]; +extern const float32_t Weights_512[512+2]; +extern const float32_t Weights_2048[2048+2]; +extern const float32_t Weights_8192[8192+2]; +#endif +extern const float32_t cos_factors_128[128]; +extern const float32_t cos_factors_512[512]; +extern const float32_t cos_factors_2048[2048]; +extern const float32_t cos_factors_8192[8192]; + +/* floating-point bit reversal tables */ +#define CSIBITREVINDEXTABLE_16_TABLE_LENGTH ((uint16_t)20 ) +#define CSIBITREVINDEXTABLE_32_TABLE_LENGTH ((uint16_t)48 ) +#define CSIBITREVINDEXTABLE_64_TABLE_LENGTH ((uint16_t)56 ) +#define CSIBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208 ) +#define CSIBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440 ) +#define CSIBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448 ) +#define CSIBITREVINDEXTABLE_1024_TABLE_LENGTH ((uint16_t)1800) +#define CSIBITREVINDEXTABLE_2048_TABLE_LENGTH ((uint16_t)3808) +#define CSIBITREVINDEXTABLE_4096_TABLE_LENGTH ((uint16_t)4032) + +extern const uint16_t csiBitRevIndexTable16[CSIBITREVINDEXTABLE_16_TABLE_LENGTH]; +extern const uint16_t csiBitRevIndexTable32[CSIBITREVINDEXTABLE_32_TABLE_LENGTH]; +extern const uint16_t csiBitRevIndexTable64[CSIBITREVINDEXTABLE_64_TABLE_LENGTH]; +extern const uint16_t csiBitRevIndexTable128[CSIBITREVINDEXTABLE_128_TABLE_LENGTH]; +extern const uint16_t csiBitRevIndexTable256[CSIBITREVINDEXTABLE_256_TABLE_LENGTH]; +extern const uint16_t csiBitRevIndexTable512[CSIBITREVINDEXTABLE_512_TABLE_LENGTH]; +extern const uint16_t csiBitRevIndexTable1024[CSIBITREVINDEXTABLE_1024_TABLE_LENGTH]; +extern const uint16_t csiBitRevIndexTable2048[CSIBITREVINDEXTABLE_2048_TABLE_LENGTH]; +extern const uint16_t csiBitRevIndexTable4096[CSIBITREVINDEXTABLE_4096_TABLE_LENGTH]; + +/* fixed-point bit reversal tables */ +#define CSIBITREVINDEXTABLE_FIXED_16_TABLE_LENGTH ((uint16_t)12 ) +#define CSIBITREVINDEXTABLE_FIXED_32_TABLE_LENGTH ((uint16_t)24 ) +#define CSIBITREVINDEXTABLE_FIXED_64_TABLE_LENGTH ((uint16_t)56 ) +#define CSIBITREVINDEXTABLE_FIXED_128_TABLE_LENGTH ((uint16_t)112 ) +#define CSIBITREVINDEXTABLE_FIXED_256_TABLE_LENGTH ((uint16_t)240 ) +#define CSIBITREVINDEXTABLE_FIXED_512_TABLE_LENGTH ((uint16_t)480 ) +#define CSIBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH ((uint16_t)992 ) +#define CSIBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH ((uint16_t)1984) +#define CSIBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH ((uint16_t)4032) + +extern const uint16_t csiBitRevIndexTable_fixed_16[CSIBITREVINDEXTABLE_FIXED_16_TABLE_LENGTH]; +extern const uint16_t csiBitRevIndexTable_fixed_32[CSIBITREVINDEXTABLE_FIXED_32_TABLE_LENGTH]; +extern const uint16_t csiBitRevIndexTable_fixed_64[CSIBITREVINDEXTABLE_FIXED_64_TABLE_LENGTH]; +extern const uint16_t csiBitRevIndexTable_fixed_128[CSIBITREVINDEXTABLE_FIXED_128_TABLE_LENGTH]; +extern const uint16_t csiBitRevIndexTable_fixed_256[CSIBITREVINDEXTABLE_FIXED_256_TABLE_LENGTH]; +extern const uint16_t csiBitRevIndexTable_fixed_512[CSIBITREVINDEXTABLE_FIXED_512_TABLE_LENGTH]; +extern const uint16_t csiBitRevIndexTable_fixed_1024[CSIBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH]; +extern const uint16_t csiBitRevIndexTable_fixed_2048[CSIBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH]; +extern const uint16_t csiBitRevIndexTable_fixed_4096[CSIBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH]; + +/* Tables for Fast Math Sine and Cosine */ +extern const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1]; +extern const q31_t sinTable_q31[FAST_MATH_TABLE_SIZE + 1]; +extern const q15_t sinTable_q15[FAST_MATH_TABLE_SIZE + 1]; + +#endif /* CSI_COMMON_TABLES_H */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/dsp/csi_const_structs.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/dsp/csi_const_structs.h new file mode 100644 index 00000000..09f8f367 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/dsp/csi_const_structs.h @@ -0,0 +1,157 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 csi_const_structs.h + * @brief Constant structs that are initialized for user convenience. + * @version V1.0 + * @date Feb. 2020 + ******************************************************************************/ + + +#ifndef _RISCV_CONST_STRUCTS_H +#define _RISCV_CONST_STRUCTS_H + +#include "csi_math.h" +#include "csi_common_tables.h" + +extern const csi_cfft_instance_f32 csi_cfft_radix4_fast_sR_f32_len16; +extern const csi_cfft_instance_f32 csi_cfft_radix4_fast_sR_f32_len32; +extern const csi_cfft_instance_f32 csi_cfft_radix4_fast_sR_f32_len64; +extern const csi_cfft_instance_f32 csi_cfft_radix4_fast_sR_f32_len128; +extern const csi_cfft_instance_f32 csi_cfft_radix4_fast_sR_f32_len256; +extern const csi_cfft_instance_f32 csi_cfft_radix4_fast_sR_f32_len512; +extern const csi_cfft_instance_f32 csi_cfft_radix4_fast_sR_f32_len1024; +extern const csi_cfft_instance_f32 csi_cfft_radix4_fast_sR_f32_len2048; +extern const csi_cfft_instance_f32 csi_cfft_radix4_fast_sR_f32_len4096; + +extern const csi_cfft_instance_f32 csi_cfft_radix2_sR_f32_len16; +extern const csi_cfft_instance_f32 csi_cfft_radix2_sR_f32_len32; +extern const csi_cfft_instance_f32 csi_cfft_radix2_sR_f32_len64; +extern const csi_cfft_instance_f32 csi_cfft_radix2_sR_f32_len128; +extern const csi_cfft_instance_f32 csi_cfft_radix2_sR_f32_len256; +extern const csi_cfft_instance_f32 csi_cfft_radix2_sR_f32_len512; +extern const csi_cfft_instance_f32 csi_cfft_radix2_sR_f32_len1024; +extern const csi_cfft_instance_f32 csi_cfft_radix2_sR_f32_len2048; +extern const csi_cfft_instance_f32 csi_cfft_radix2_sR_f32_len4096; + +extern const csi_cfft_instance_f32 csi_cfft_radix4_sR_f32_len16; +extern const csi_cfft_instance_f32 csi_cfft_radix4_sR_f32_len32; +extern const csi_cfft_instance_f32 csi_cfft_radix4_sR_f32_len64; +extern const csi_cfft_instance_f32 csi_cfft_radix4_sR_f32_len128; +extern const csi_cfft_instance_f32 csi_cfft_radix4_sR_f32_len256; +extern const csi_cfft_instance_f32 csi_cfft_radix4_sR_f32_len512; +extern const csi_cfft_instance_f32 csi_cfft_radix4_sR_f32_len1024; +extern const csi_cfft_instance_f32 csi_cfft_radix4_sR_f32_len2048; +extern const csi_cfft_instance_f32 csi_cfft_radix4_sR_f32_len4096; + +extern const csi_cfft_instance_f32 csi_cfft_sR_f32_len16 ; +extern const csi_cfft_instance_f32 csi_cfft_sR_f32_len32 ; +extern const csi_cfft_instance_f32 csi_cfft_sR_f32_len64 ; +extern const csi_cfft_instance_f32 csi_cfft_sR_f32_len128 ; +extern const csi_cfft_instance_f32 csi_cfft_sR_f32_len256 ; +extern const csi_cfft_instance_f32 csi_cfft_sR_f32_len512 ; +extern const csi_cfft_instance_f32 csi_cfft_sR_f32_len1024 ; +extern const csi_cfft_instance_f32 csi_cfft_sR_f32_len2048 ; +extern const csi_cfft_instance_f32 csi_cfft_sR_f32_len4096 ; +extern const csi_cfft_instance_q31 csi_cfft_sR_q31_len16 ; +extern const csi_cfft_instance_q31 csi_cfft_sR_q31_len32 ; +extern const csi_cfft_instance_q31 csi_cfft_sR_q31_len64 ; +extern const csi_cfft_instance_q31 csi_cfft_sR_q31_len128 ; +extern const csi_cfft_instance_q31 csi_cfft_sR_q31_len256 ; +extern const csi_cfft_instance_q31 csi_cfft_sR_q31_len512 ; +extern const csi_cfft_instance_q31 csi_cfft_sR_q31_len1024 ; +extern const csi_cfft_instance_q31 csi_cfft_sR_q31_len2048 ; +extern const csi_cfft_instance_q31 csi_cfft_sR_q31_len4096 ; +extern const csi_cfft_instance_q15 csi_cfft_sR_q15_len16 ; +extern const csi_cfft_instance_q15 csi_cfft_sR_q15_len32 ; +extern const csi_cfft_instance_q15 csi_cfft_sR_q15_len64 ; +extern const csi_cfft_instance_q15 csi_cfft_sR_q15_len128 ; +extern const csi_cfft_instance_q15 csi_cfft_sR_q15_len256 ; +extern const csi_cfft_instance_q15 csi_cfft_sR_q15_len512 ; +extern const csi_cfft_instance_q15 csi_cfft_sR_q15_len1024 ; +extern const csi_cfft_instance_q15 csi_cfft_sR_q15_len2048 ; +extern const csi_cfft_instance_q15 csi_cfft_sR_q15_len4096 ; +extern const csi_rfft_fast_instance_f32 csi_rfft_sR_f32_len32 ; +extern const csi_rfft_fast_instance_f32 csi_rfft_sR_f32_len64 ; +extern const csi_rfft_fast_instance_f32 csi_rfft_sR_f32_len128 ; +extern const csi_rfft_fast_instance_f32 csi_rfft_sR_f32_len256 ; +extern const csi_rfft_fast_instance_f32 csi_rfft_sR_f32_len512 ; +extern const csi_rfft_fast_instance_f32 csi_rfft_sR_f32_len1024 ; +extern const csi_rfft_fast_instance_f32 csi_rfft_sR_f32_len2048 ; +extern const csi_rfft_fast_instance_f32 csi_rfft_sR_f32_len4096 ; +extern const csi_rfft_fast_instance_f32 csi_rfft_sR_f32_len8192 ; +extern const csi_rfft_instance_q31 csi_rfft_sR_q31_len32 ; +extern const csi_rfft_instance_q31 csi_rfft_sR_q31_len64 ; +extern const csi_rfft_instance_q31 csi_rfft_sR_q31_len128 ; +extern const csi_rfft_instance_q31 csi_rfft_sR_q31_len256 ; +extern const csi_rfft_instance_q31 csi_rfft_sR_q31_len512 ; +extern const csi_rfft_instance_q31 csi_rfft_sR_q31_len1024 ; +extern const csi_rfft_instance_q31 csi_rfft_sR_q31_len2048 ; +extern const csi_rfft_instance_q31 csi_rfft_sR_q31_len4096 ; +extern const csi_rfft_instance_q31 csi_rfft_sR_q31_len8192 ; +extern const csi_rfft_instance_q15 csi_rfft_sR_q15_len32 ; +extern const csi_rfft_instance_q15 csi_rfft_sR_q15_len64 ; +extern const csi_rfft_instance_q15 csi_rfft_sR_q15_len128 ; +extern const csi_rfft_instance_q15 csi_rfft_sR_q15_len256 ; +extern const csi_rfft_instance_q15 csi_rfft_sR_q15_len512 ; +extern const csi_rfft_instance_q15 csi_rfft_sR_q15_len1024 ; +extern const csi_rfft_instance_q15 csi_rfft_sR_q15_len2048 ; +extern const csi_rfft_instance_q15 csi_rfft_sR_q15_len4096 ; +extern const csi_rfft_instance_q15 csi_rfft_sR_q15_len8192 ; +extern const csi_rfft_instance_f32 csi_inv_rfft_sR_f32_len32; +extern const csi_rfft_instance_f32 csi_inv_rfft_sR_f32_len64; +extern const csi_rfft_instance_f32 csi_inv_rfft_sR_f32_len128; +extern const csi_rfft_instance_f32 csi_inv_rfft_sR_f32_len256; +extern const csi_rfft_instance_f32 csi_inv_rfft_sR_f32_len512; +extern const csi_rfft_instance_f32 csi_inv_rfft_sR_f32_len1024; +extern const csi_rfft_instance_f32 csi_inv_rfft_sR_f32_len2048; +extern const csi_rfft_instance_f32 csi_inv_rfft_sR_f32_len4096; +extern const csi_rfft_instance_f32 csi_inv_rfft_sR_f32_len8192; +extern const csi_rfft_instance_q31 csi_inv_rfft_sR_q31_len32; +extern const csi_rfft_instance_q31 csi_inv_rfft_sR_q31_len64; +extern const csi_rfft_instance_q31 csi_inv_rfft_sR_q31_len128; +extern const csi_rfft_instance_q31 csi_inv_rfft_sR_q31_len256; +extern const csi_rfft_instance_q31 csi_inv_rfft_sR_q31_len512; +extern const csi_rfft_instance_q31 csi_inv_rfft_sR_q31_len1024; +extern const csi_rfft_instance_q31 csi_inv_rfft_sR_q31_len2048; +extern const csi_rfft_instance_q31 csi_inv_rfft_sR_q31_len4096; +extern const csi_rfft_instance_q31 csi_inv_rfft_sR_q31_len8192; +extern const csi_rfft_instance_q15 csi_inv_rfft_sR_q15_len32; +extern const csi_rfft_instance_q15 csi_inv_rfft_sR_q15_len64; +extern const csi_rfft_instance_q15 csi_inv_rfft_sR_q15_len128; +extern const csi_rfft_instance_q15 csi_inv_rfft_sR_q15_len256; +extern const csi_rfft_instance_q15 csi_inv_rfft_sR_q15_len512; +extern const csi_rfft_instance_q15 csi_inv_rfft_sR_q15_len1024; +extern const csi_rfft_instance_q15 csi_inv_rfft_sR_q15_len2048; +extern const csi_rfft_instance_q15 csi_inv_rfft_sR_q15_len4096; +extern const csi_rfft_instance_q15 csi_inv_rfft_sR_q15_len8192; +extern const csi_dct4_instance_q31 csi_dct4_sR_q31_len128; +extern const csi_dct4_instance_q31 csi_dct4_sR_q31_len512; +extern const csi_dct4_instance_q31 csi_dct4_sR_q31_len2048; +extern const csi_dct4_instance_q31 csi_dct4_sR_q31_len8192; +extern const csi_dct4_instance_q15 csi_dct4_sR_q15_len128; +extern const csi_dct4_instance_q15 csi_dct4_sR_q15_len512; +extern const csi_dct4_instance_q15 csi_dct4_sR_q15_len2048; +extern const csi_dct4_instance_q15 csi_dct4_sR_q15_len8192; +extern const csi_dct4_instance_f32 csi_dct4_sR_f32_len128; +extern const csi_dct4_instance_f32 csi_dct4_sR_f32_len512; +extern const csi_dct4_instance_f32 csi_dct4_sR_f32_len2048; +extern const csi_dct4_instance_f32 csi_dct4_sR_f32_len8192; + +#endif diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/dsp/csi_instance.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/dsp/csi_instance.h new file mode 100644 index 00000000..a1aa7131 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/dsp/csi_instance.h @@ -0,0 +1,1879 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 csi_instance.h + * @brief Some common define + * @version V1.0 + * @date Feb. 2020 + ******************************************************************************/ + + +#ifndef _CSI_INSTANCE_H +#define _CSI_INSTANCE_H + +#ifdef __cplusplus +extern "C" +{ +#endif + + +#include +#include +#include +#include +#include +#ifndef __CK860__ +#include "csi_core.h" +#else +#include +#endif + +#define LOW_OPTIMIZATION_ENTER +#define LOW_OPTIMIZATION_EXIT + +#define F64_MAX ((float64_t)DBL_MAX) +#define F32_MAX ((float32_t)FLT_MAX) + +#define F64_MIN (-DBL_MAX) +#define F32_MIN (-FLT_MAX) + +#define F64_ABSMAX ((float64_t)DBL_MAX) +#define F32_ABSMAX ((float32_t)FLT_MAX) + +#define F64_ABSMIN ((float64_t)0.0) +#define F32_ABSMIN ((float32_t)0.0) + +#define Q31_MAX ((q31_t)(0x7FFFFFFFL)) +#define Q15_MAX ((q15_t)(0x7FFF)) +#define Q7_MAX ((q7_t)(0x7F)) +#define Q31_MIN ((q31_t)(0x80000000L)) +#define Q15_MIN ((q15_t)(0x8000)) +#define Q7_MIN ((q7_t)(0x80)) + +#define Q31_ABSMAX ((q31_t)(0x7FFFFFFFL)) +#define Q15_ABSMAX ((q15_t)(0x7FFF)) +#define Q7_ABSMAX ((q7_t)(0x7F)) +#define Q31_ABSMIN ((q31_t)0) +#define Q15_ABSMIN ((q15_t)0) +#define Q7_ABSMIN ((q7_t)0) + +/** + * @brief Macros required for reciprocal calculation in Normalized LMS + */ + +#define DELTA_Q31 ((q31_t)(0x100)) +#define DELTA_Q15 ((q15_t)0x5) +#define INDEX_MASK 0x0000003F +#ifndef PI +#define PI 3.14159265358979f +#endif + +#ifndef UNALIGNED_SUPPORT_DISABLE + #define ALIGN4 +#else + #define ALIGN4 __attribute__((aligned(4))) +#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */ + +/** + * @brief Macros required for SINE and COSINE Fast math approximations + */ + +#define FAST_MATH_TABLE_SIZE 512 +#define FAST_MATH_Q31_SHIFT (32 - 10) +#define FAST_MATH_Q15_SHIFT (16 - 10) +#define CONTROLLER_Q31_SHIFT (32 - 9) +#define TABLE_SPACING_Q31 0x400000 +#define TABLE_SPACING_Q15 0x80 + +#define __STATIC_FORCEINLINE static inline __attribute__((unused)) +#define CSI_NEWTON_SQRTF +#ifdef __CK860__ +#define __STATIC_INLINE static inline __attribute__((unused)) + +#define __ALWAYS_STATIC_INLINE __attribute__((always_inline)) static inline + +#endif + + +/** + * @brief Macros required for SINE and COSINE Controller functions + */ +/* 1.31(q31) Fixed value of 2/360 */ +/* -1 to +1 is divided into 360 values so total spacing is (2/360) */ +#define INPUT_SPACING 0xB60B61 + +/** + * @brief Macros for complex numbers + */ + +/* Dimension C vector space */ +#define CMPLX_DIM 2 + +/** + * @brief Error status returned by some functions in the library. + */ + +typedef enum { + CSI_MATH_SUCCESS = 0, /**< No error */ + CSI_MATH_ARGUMENT_ERROR = -1, /**< One or more arguments are incorrect */ + CSI_MATH_LENGTH_ERROR = -2, /**< Length of data buffer is incorrect */ + CSI_MATH_SIZE_MISMATCH = -3, /**< Size of matrices is not compatible with the operation */ + CSI_MATH_NANINF = -4, /**< Not-a-number (NaN) or infinity is generated */ + CSI_MATH_SINGULAR = -5, /**< Input matrix is singular and cannot be inverted */ + CSI_MATH_TEST_FAILURE = -6 /**< Test Failed */ +} csi_status; + +/** + * @brief 8-bit fractional data type in 1.7 format. + */ +typedef int8_t q7_t; + +/** + * @brief 16-bit fractional data type in 1.15 format. + */ +typedef int16_t q15_t; + +/** + * @brief 32-bit fractional data type in 1.31 format. + */ +typedef int32_t q31_t; + +/** + * @brief 64-bit fractional data type in 1.63 format. + */ +typedef int64_t q63_t; + +/** + * @brief 32-bit floating-point type definition. + */ +typedef float float32_t; + +/** + * @brief 64-bit floating-point type definition. + */ +typedef double float64_t; + +/** + @brief definition to read/write two 16 bit values. + @deprecated + */ +#define __SIMD32_TYPE int32_t +#define __SIMD32(addr) (*(__SIMD32_TYPE **) & (addr)) +#define __SIMD32_CONST(addr) ( (__SIMD32_TYPE * ) (addr)) +#define _SIMD32_OFFSET(addr) (*(__SIMD32_TYPE * ) (addr)) +#define __SIMD64(addr) (*( int64_t **) & (addr)) + +#define STEP(x) (x) <= 0 ? 0 : 1 +#define SQ(x) ((x) * (x)) + +__ALWAYS_STATIC_INLINE int32_t __SSAT_31(int32_t x) +{ + int32_t res = x; + if (x > 0x3fffffff) { + res = 0x3fffffff; + } else if (x < -1073741824) { + res = -1073741824; + } + + return res; +} + +__ALWAYS_STATIC_INLINE int32_t __SSAT_16(int32_t x) +{ + int32_t res = x; + if (x > 0x7fff) { + res = 0x7fff; + } else if (x < -32768) { + res = -32768; + } + + return res; +} + +__ALWAYS_STATIC_INLINE int32_t __SSAT_8(int32_t x) +{ + int32_t res = x; + if (x > 0x7f) { + res = 0x7f; + } else if (x < -128) { + res = -128; + } + + return res; +} + +/** + @brief Read 2 Q15 from Q15 pointer. + @param[in] pQ15 points to input value + @return Q31 value + */ +__STATIC_FORCEINLINE q31_t read_q15x2 ( + q15_t * pQ15) +{ + q31_t val; + memcpy (&val, pQ15, 4); + return (val); +} + +/** + @brief Read 2 Q15 from Q15 pointer and increment pointer afterwards. + @param[in] pQ15 points to input value + @return Q31 value + */ +__STATIC_FORCEINLINE q31_t read_q15x2_ia ( + q15_t ** pQ15) +{ + q31_t val; + memcpy (&val, *pQ15, 4); + *pQ15 += 2; + return (val); +} + +/** + @brief Read 2 Q15 from Q15 pointer and decrement pointer afterwards. + @param[in] pQ15 points to input value + @return Q31 value + */ +__STATIC_FORCEINLINE q31_t read_q15x2_da ( + q15_t ** pQ15) +{ + q31_t val; + memcpy (&val, *pQ15, 4); + *pQ15 -= 2; + return (val); +} + +/** + @brief Write 2 Q15 to Q15 pointer and increment pointer afterwards. + @param[in] pQ15 points to input value + @param[in] value Q31 value + @return none + */ +__STATIC_FORCEINLINE void write_q15x2_ia ( + q15_t ** pQ15, + q31_t value) +{ + q31_t val = value; + memcpy (*pQ15, &val, 4); + *pQ15 += 2; +} + +/** + @brief Write 2 Q15 to Q15 pointer. + @param[in] pQ15 points to input value + @param[in] value Q31 value + @return none + */ +__STATIC_FORCEINLINE void write_q15x2 ( + q15_t * pQ15, + q31_t value) +{ + q31_t val = value; + memcpy (pQ15, &val, 4); +} + + +/** + @brief Read 4 Q7 from Q7 pointer and increment pointer afterwards. + @param[in] pQ7 points to input value + @return Q31 value + */ +__STATIC_FORCEINLINE q31_t read_q7x4_ia ( + q7_t ** pQ7) +{ + q31_t val; + memcpy (&val, *pQ7, 4); + *pQ7 += 4; + return (val); +} + +/** + @brief Read 4 Q7 from Q7 pointer and decrement pointer afterwards. + @param[in] pQ7 points to input value + @return Q31 value + */ +__STATIC_FORCEINLINE q31_t read_q7x4_da ( + q7_t ** pQ7) +{ + q31_t val; + memcpy (&val, *pQ7, 4); + *pQ7 -= 4; + return (val); +} + +/** + @brief Write 4 Q7 to Q7 pointer and increment pointer afterwards. + @param[in] pQ7 points to input value + @param[in] value Q31 value + @return none + */ +__STATIC_FORCEINLINE void write_q7x4_ia ( + q7_t ** pQ7, + q31_t value) +{ + q31_t val = value; + memcpy (*pQ7, &val, 4); + *pQ7 += 4; +} + +#ifdef __CK860__ +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t data) +{ + if (data == 0U) { + return 32U; + } + + uint32_t count = 0U; + uint32_t mask = 0x80000000U; + + while ((data & mask) == 0U) { + count += 1U; + mask = mask >> 1U; + } + + return count; +} + +__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; +} + +__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 +/** + * @brief definition to pack two 16 bit values. + */ +#define __PKHBT(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0x0000FFFF) | \ + (((int32_t)(ARG2) << ARG3) & (int32_t)0xFFFF0000) ) +#define __PKHTB(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0xFFFF0000) | \ + (((int32_t)(ARG2) >> ARG3) & (int32_t)0x0000FFFF) ) + + +/** +* @brief definition to pack four 8 bit values. +*/ +#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v0) << 0) & (int32_t)0x000000FF) | \ + (((int32_t)(v1) << 8) & (int32_t)0x0000FF00) | \ + (((int32_t)(v2) << 16) & (int32_t)0x00FF0000) | \ + (((int32_t)(v3) << 24) & (int32_t)0xFF000000) ) + +/** + * @brief Clips Q63 to Q31 values. + */ +__STATIC_FORCEINLINE q31_t clip_q63_to_q31( + q63_t x) +{ + return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? + ((0x7FFFFFFF ^ ((q31_t) (x >> 63)))) : (q31_t) x; +} + +/** + * @brief Clips Q63 to Q15 values. + */ +__STATIC_FORCEINLINE q15_t clip_q63_to_q15( + q63_t x) +{ + return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? + ((0x7FFF ^ ((q15_t) (x >> 63)))) : (q15_t) (x >> 15); +} + +/** + * @brief Clips Q31 to Q7 values. + */ +__STATIC_FORCEINLINE q7_t clip_q31_to_q7( + q31_t x) +{ + return ((q31_t) (x >> 24) != ((q31_t) x >> 23)) ? + ((0x7F ^ ((q7_t) (x >> 31)))) : (q7_t) x; +} + +/** + * @brief Clips Q31 to Q15 values. + */ +__STATIC_FORCEINLINE q15_t clip_q31_to_q15( + q31_t x) +{ + return ((q31_t) (x >> 16) != ((q31_t) x >> 15)) ? + ((0x7FFF ^ ((q15_t) (x >> 31)))) : (q15_t) x; +} + +/** + * @brief Multiplies 32 X 64 and returns 32 bit result in 2.30 format. + */ +__STATIC_FORCEINLINE q63_t mult32x64( + q63_t x, + q31_t y) +{ + return ((((q63_t) (x & 0x00000000FFFFFFFF) * y) >> 32) + + (((q63_t) (x >> 32) * y) ) ); +} + +/** + * @brief Integer exponentiation + * @param[in] x value + * @param[in] nb integer exponent >= 1 + * @return x^nb + * + */ +__STATIC_INLINE float32_t csi_exponent_f32(float32_t x, int32_t nb) +{ + float32_t r = x; + nb --; + + while(nb > 0) { + r = r * x; + nb--; + } + + return(r); +} + +/** + * @brief 64-bit to 32-bit unsigned normalization + * @param[in] in is input unsigned long long value + * @param[out] normalized is the 32-bit normalized value + * @param[out] norm is norm scale + */ +__STATIC_INLINE void csi_norm_64_to_32u(uint64_t in, int32_t * normalized, int32_t *norm) +{ + int32_t n1; + int32_t hi = (int32_t) (in >> 32); + int32_t lo = (int32_t) ((in << 32) >> 32); + n1 = __CLZ(hi) - 32; + + if (!n1) { + /* + * input fits in 32-bit + */ + n1 = __CLZ(lo); + + if (!n1) { + /* + * MSB set, need to scale down by 1 + */ + *norm = -1; + *normalized = (((uint32_t) lo) >> 1); + + } else { + if (n1 == 32) { + /* + * input is zero + */ + *norm = 0; + *normalized = 0; + + } else { + /* + * 32-bit normalization + */ + *norm = n1 - 1; + *normalized = lo << *norm; + } + } + + } else { + /* + * input fits in 64-bit + */ + n1 = 1 - n1; + *norm = -n1; + /* + * 64 bit normalization + */ + *normalized = (((uint32_t) lo) >> n1) | (hi << (32 - n1)); + } +} + +__STATIC_INLINE q31_t csi_div_q63_to_q31(q63_t num, q31_t den) +{ + q31_t result; + uint64_t absNum; + int32_t normalized; + int32_t norm; + /* + * if sum fits in 32bits + * avoid costly 64-bit division + */ + absNum = num > 0 ? num : -num; + csi_norm_64_to_32u(absNum, &normalized, &norm); + + if (norm > 0) + /* + * 32-bit division + */ + result = (q31_t) num / den; + + else + /* + * 64-bit division + */ + result = (q31_t) (num / den); + + return result; +} + +/* + * @brief C custom defined intrinsic functions + */ +#ifdef __CK860__ +/* + * @brief C custom defined QADD8 + */ +__STATIC_FORCEINLINE uint32_t __QADD8( + uint32_t x, + uint32_t y) +{ + q31_t r, s, t, u; + r = __SSAT(((((q31_t)x << 24) >> 24) + (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((q31_t)x << 16) >> 24) + (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((q31_t)x << 8) >> 24) + (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((q31_t)x ) >> 24) + (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF; + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r ))); +} + + +/* + * @brief C custom defined QSUB8 + */ +__STATIC_FORCEINLINE uint32_t __QSUB8( + uint32_t x, + uint32_t y) +{ + q31_t r, s, t, u; + r = __SSAT(((((q31_t)x << 24) >> 24) - (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((q31_t)x << 16) >> 24) - (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((q31_t)x << 8) >> 24) - (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((q31_t)x ) >> 24) - (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF; + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r ))); +} + + +/* + * @brief C custom defined QADD16 + */ +__STATIC_FORCEINLINE uint32_t __QADD16( + uint32_t x, + uint32_t y) +{ + /* q31_t r, s; without initialisation 'csi_offset_q15 test' fails but 'intrinsic' tests pass! for armCC */ + q31_t r = 0, s = 0; + r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + return ((uint32_t)((s << 16) | (r ))); +} + + +/* + * @brief C custom defined SHADD16 + */ +__STATIC_FORCEINLINE uint32_t __SHADD16( + uint32_t x, + uint32_t y) +{ + q31_t r, s; + r = (((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + return ((uint32_t)((s << 16) | (r ))); +} + + +/* + * @brief C custom defined QSUB16 + */ +__STATIC_FORCEINLINE uint32_t __QSUB16( + uint32_t x, + uint32_t y) +{ + q31_t r, s; + r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + return ((uint32_t)((s << 16) | (r ))); +} + + +/* + * @brief C custom defined SHSUB16 + */ +__STATIC_FORCEINLINE uint32_t __SHSUB16( + uint32_t x, + uint32_t y) +{ + q31_t r, s; + r = (((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + return ((uint32_t)((s << 16) | (r ))); +} + + +/* + * @brief C custom defined QASX + */ +__STATIC_FORCEINLINE uint32_t __QASX( + uint32_t x, + uint32_t y) +{ + q31_t r, s; + r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + return ((uint32_t)((s << 16) | (r ))); +} + + +/* + * @brief C custom defined SHASX + */ +__STATIC_FORCEINLINE uint32_t __SHASX( + uint32_t x, + uint32_t y) +{ + q31_t r, s; + r = (((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + return ((uint32_t)((s << 16) | (r ))); +} + + +/* + * @brief C custom defined QSAX + */ +__STATIC_FORCEINLINE uint32_t __QSAX( + uint32_t x, + uint32_t y) +{ + q31_t r, s; + r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + return ((uint32_t)((s << 16) | (r ))); +} + + +/* + * @brief C custom defined SHSAX + */ +__STATIC_FORCEINLINE uint32_t __SHSAX( + uint32_t x, + uint32_t y) +{ + q31_t r, s; + r = (((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + return ((uint32_t)((s << 16) | (r ))); +} + + +/* + * @brief C custom defined SMUSDX + */ +__STATIC_FORCEINLINE uint32_t __SMUSDX( + uint32_t x, + uint32_t y) +{ + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) )); +} + +/* + * @brief C custom defined SMUADX + */ +__STATIC_FORCEINLINE uint32_t __SMUADX( + uint32_t x, + uint32_t y) +{ + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) )); +} + + +/* + * @brief C custom defined QADD + */ +__STATIC_FORCEINLINE int32_t __QADD( + int32_t x, + int32_t y) +{ + return ((int32_t)(clip_q63_to_q31((q63_t)x + (q31_t)y))); +} + + +/* + * @brief C custom defined QSUB + */ +__STATIC_FORCEINLINE int32_t __QSUB( + int32_t x, + int32_t y) +{ + return ((int32_t)(clip_q63_to_q31((q63_t)x - (q31_t)y))); +} + + +/* + * @brief C custom defined SMLAD + */ +__STATIC_FORCEINLINE uint32_t __SMLAD( + uint32_t x, + uint32_t y, + uint32_t sum) +{ + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) + + ( ((q31_t)sum ) ) )); +} + + +/* + * @brief C custom defined SMLADX + */ +__STATIC_FORCEINLINE uint32_t __SMLADX( + uint32_t x, + uint32_t y, + uint32_t sum) +{ + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q31_t)sum ) ) )); +} + + +/* + * @brief C custom defined SMLSDX + */ +__STATIC_FORCEINLINE uint32_t __SMLSDX( + uint32_t x, + uint32_t y, + uint32_t sum) +{ + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q31_t)sum ) ) )); +} + + +/* + * @brief C custom defined SMLALD + */ +__STATIC_FORCEINLINE uint64_t __SMLALD( + uint32_t x, + uint32_t y, + uint64_t sum) +{ + /* return (sum + ((q15_t) (x >> 16) * (q15_t) (y >> 16)) + ((q15_t) x * (q15_t) y)); */ + return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) + + ( ((q63_t)sum ) ) )); +} + + +/* + * @brief C custom defined SMLALDX + */ +__STATIC_FORCEINLINE uint64_t __SMLALDX( + uint32_t x, + uint32_t y, + uint64_t sum) +{ + /* return (sum + ((q15_t) (x >> 16) * (q15_t) y)) + ((q15_t) x * (q15_t) (y >> 16)); */ + return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q63_t)sum ) ) )); +} + + +/* + * @brief C custom defined SMUAD + */ +__STATIC_FORCEINLINE uint32_t __SMUAD( + uint32_t x, + uint32_t y) +{ + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) )); +} + + +/* + * @brief C custom defined SMUSD + */ +__STATIC_FORCEINLINE uint32_t __SMUSD( + uint32_t x, + uint32_t y) +{ + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) )); +} + + +/* + * @brief C custom defined SXTB16 + */ +__STATIC_FORCEINLINE uint32_t __SXTB16( + uint32_t x) +{ + return ((uint32_t)(((((q31_t)x << 24) >> 24) & (q31_t)0x0000FFFF) | + ((((q31_t)x << 8) >> 8) & (q31_t)0xFFFF0000) )); +} +/* + * @brief C custom defined SMMLA + */ +__STATIC_FORCEINLINE int32_t __SMMLA( + int32_t x, + int32_t y, + int32_t sum) +{ + return (sum + (int32_t) (((int64_t) x * y) >> 32)); +} +#endif +/** + * @brief Instance structure for the Q7 FIR filter. + */ +typedef struct { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q7_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + const q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ +} csi_fir_instance_q7; + +/** + * @brief Instance structure for the Q15 FIR filter. + */ +typedef struct { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + const q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ +} csi_fir_instance_q15; + +/** + * @brief Instance structure for the Q31 FIR filter. + */ +typedef struct { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + const q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ +} csi_fir_instance_q31; + +/** + * @brief Instance structure for the floating-point FIR filter. + */ +typedef struct { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + const float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ +} csi_fir_instance_f32; + +/** + * @brief Instance structure for the Q15 Biquad cascade filter. + */ +typedef struct { + int8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q15_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + const q15_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + int8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ +} csi_biquad_casd_df1_inst_q15; + +/** + * @brief Instance structure for the Q31 Biquad cascade filter. + */ +typedef struct { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q31_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + const q31_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ +} csi_biquad_casd_df1_inst_q31; + +/** + * @brief Instance structure for the floating-point Biquad cascade filter. + */ +typedef struct { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + const float32_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ +} csi_biquad_casd_df1_inst_f32; + +/** + * @brief Instance structure for the floating-point matrix structure. + */ +typedef struct { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + float32_t *pData; /**< points to the data of the matrix. */ +} csi_matrix_instance_f32; + + +/** + * @brief Instance structure for the floating-point matrix structure. + */ +typedef struct { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + float64_t *pData; /**< points to the data of the matrix. */ +} csi_matrix_instance_f64; + +/** + * @brief Instance structure for the Q15 matrix structure. + */ +typedef struct { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q15_t *pData; /**< points to the data of the matrix. */ +} csi_matrix_instance_q15; + +/** + * @brief Instance structure for the Q31 matrix structure. + */ +typedef struct { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q31_t *pData; /**< points to the data of the matrix. */ +} csi_matrix_instance_q31; + +/** + * @brief Instance structure for the Q15 PID Control. + */ +typedef struct { + q15_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + q15_t A1; + q15_t A2; + q15_t state[3]; /**< The state array of length 3. */ + q15_t Kp; /**< The proportional gain. */ + q15_t Ki; /**< The integral gain. */ + q15_t Kd; /**< The derivative gain. */ +} csi_pid_instance_q15; + +/** + * @brief Instance structure for the Q31 PID Control. + */ +typedef struct { + q31_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + q31_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + q31_t A2; /**< The derived gain, A2 = Kd . */ + q31_t state[3]; /**< The state array of length 3. */ + q31_t Kp; /**< The proportional gain. */ + q31_t Ki; /**< The integral gain. */ + q31_t Kd; /**< The derivative gain. */ +} csi_pid_instance_q31; + +/** + * @brief Instance structure for the floating-point PID Control. + */ +typedef struct { + float32_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + float32_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + float32_t A2; /**< The derived gain, A2 = Kd . */ + float32_t state[3]; /**< The state array of length 3. */ + float32_t Kp; /**< The proportional gain. */ + float32_t Ki; /**< The integral gain. */ + float32_t Kd; /**< The derivative gain. */ +} csi_pid_instance_f32; + +/** + * @brief Instance structure for the floating-point Linear Interpolate function. + */ +typedef struct { + uint32_t nValues; /**< nValues */ + float32_t x1; /**< x1 */ + float32_t xSpacing; /**< xSpacing */ + float32_t *pYData; /**< pointer to the table of Y values */ +} csi_linear_interp_instance_f32; + +/** + * @brief Instance structure for the floating-point bilinear interpolation function. + */ +typedef struct { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + float32_t *pData; /**< points to the data table. */ +} csi_bilinear_interp_instance_f32; + +/** +* @brief Instance structure for the Q31 bilinear interpolation function. +*/ +typedef struct { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q31_t *pData; /**< points to the data table. */ +} csi_bilinear_interp_instance_q31; + +/** +* @brief Instance structure for the Q15 bilinear interpolation function. +*/ +typedef struct { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q15_t *pData; /**< points to the data table. */ +} csi_bilinear_interp_instance_q15; + +/** +* @brief Instance structure for the Q15 bilinear interpolation function. +*/ +typedef struct { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q7_t *pData; /**< points to the data table. */ +} csi_bilinear_interp_instance_q7; + +/** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ +typedef struct { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + const q15_t *pTwiddle; /**< points to the Sin twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ +} csi_cfft_radix2_instance_q15; + +/** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ +typedef struct { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + const q15_t *pTwiddle; /**< points to the twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ +} csi_cfft_radix4_instance_q15; + +/** + * @brief Instance structure for the Radix-2 Q31 CFFT/CIFFT function. + */ +typedef struct { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + const q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ +} csi_cfft_radix2_instance_q31; + + +/** + * @brief Instance structure for the Q31 CFFT/CIFFT function. + */ +typedef struct { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + const q31_t *pTwiddle; /**< points to the twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ +} csi_cfft_radix4_instance_q31; + +/** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ +typedef struct { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + const float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ +} csi_cfft_radix2_instance_f32; + +/** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ +typedef struct { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + const float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ +} csi_cfft_radix4_instance_f32; + +/** + * @brief Instance structure for the fixed-point CFFT/CIFFT function. + */ +typedef struct { + uint16_t fftLen; /**< length of the FFT. */ + const q15_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ +} csi_cfft_instance_q15; + +/** + * @brief Instance structure for the fixed-point CFFT/CIFFT function. + */ +typedef struct { + uint16_t fftLen; /**< length of the FFT. */ + const q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ +} csi_cfft_instance_q31; + + +/** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ +typedef struct { + uint16_t fftLen; /**< length of the FFT. */ + const float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ +} csi_cfft_instance_f32; + + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + q31_t *pTwiddleAReal; /**< points to the A real twiddle factor table. */ + q31_t *pTwiddleBReal; /**< points to the B real twiddle factor table. */ + const csi_cfft_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } csi_rfft_fast_instance_q31; + + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + q15_t *pTwiddleAReal; /**< points to the A real twiddle factor table. */ + q15_t *pTwiddleBReal; /**< points to the B real twiddle factor table. */ + const csi_cfft_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } csi_rfft_fast_instance_q15; + +/** + * @brief Instance structure for the Q15 RFFT/RIFFT function. + */ +typedef struct { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + q15_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ +#if (!defined __riscv_xthead) && (defined __riscv) + q15_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ +#endif + const csi_cfft_instance_q15 *pCfft; /**< points to the complex FFT instance. */ +} csi_rfft_instance_q15; + + +/** + * @brief Instance structure for the Q31 RFFT/RIFFT function. + */ +typedef struct { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + q31_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ +#if (!defined __riscv_xthead) && (defined __riscv) + q31_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ +#endif + const csi_cfft_instance_q31 *pCfft; /**< points to the complex FFT instance. */ +} csi_rfft_instance_q31; + + +/** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ +typedef struct { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint16_t fftLenBy2; /**< length of the complex FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + float32_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + float32_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + csi_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ +} csi_rfft_instance_f32; + +/** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ +typedef struct { + csi_cfft_instance_f32 Sint; /**< Internal CFFT structure. */ + uint16_t fftLenRFFT; /**< length of the real sequence */ + const float32_t * pTwiddleRFFT; /**< Twiddle factors real stage */ +} csi_rfft_fast_instance_f32 ; + +/** + * @brief Instance structure for the floating-point DCT4/IDCT4 function. + */ +typedef struct { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + float32_t normalize; /**< normalizing factor. */ + const float32_t *pTwiddle; /**< points to the twiddle factor table. */ + const float32_t *pCosFactor; /**< points to the cosFactor table. */ + csi_rfft_fast_instance_f32 *pRfft; /**< points to the real FFT instance. */ + csi_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ +} csi_dct4_instance_f32; + + +/** + * @brief Instance structure for the Q31 DCT4/IDCT4 function. + */ +typedef struct { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q31_t normalize; /**< normalizing factor. */ + const q31_t *pTwiddle; /**< points to the twiddle factor table. */ + const q31_t *pCosFactor; /**< points to the cosFactor table. */ + csi_rfft_instance_q31 *pRfft; /**< points to the real FFT instance. */ + csi_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */ +} csi_dct4_instance_q31; + + +/** + * @brief Instance structure for the Q15 DCT4/IDCT4 function. + */ +typedef struct { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q15_t normalize; /**< normalizing factor. */ + const q15_t *pTwiddle; /**< points to the twiddle factor table. */ + const q15_t *pCosFactor; /**< points to the cosFactor table. */ + csi_rfft_instance_q15 *pRfft; /**< points to the real FFT instance. */ + csi_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */ +} csi_dct4_instance_q15; + + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q15_t normalize; /**< normalizing factor. */ + q15_t *pTwiddle; /**< points to the twiddle factor table. */ + q15_t *pCosFactor; /**< points to the cosFactor table. */ + csi_rfft_fast_instance_q15 *pRfft; /**< points to the real FFT instance. */ + csi_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } csi_dct4_fast_instance_q15; + + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q31_t normalize; /**< normalizing factor. */ + q31_t *pTwiddle; /**< points to the twiddle factor table. */ + q31_t *pCosFactor; /**< points to the cosFactor table. */ + csi_rfft_fast_instance_q31 *pRfft; /**< points to the real FFT instance. */ + csi_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } csi_dct4_fast_instance_q31; + + csi_status csi_dct4_init_q31( + csi_dct4_instance_q31 * S, + csi_rfft_instance_q31 * S_RFFT, + csi_cfft_radix4_instance_q31 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q31_t normalize); + + void csi_dct4_q31( + const csi_dct4_instance_q31 * S, + q31_t * pState, + q31_t * pInlineBuffer); + + void csi_dct4_fast_q31( + const csi_dct4_fast_instance_q31 * S, + q31_t * pState, + q31_t * pInlineBuffer); + + +/** + * @brief Instance structure for the Q15 FIR decimator. + */ +typedef struct { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + const q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ +} csi_fir_decimate_instance_q15; + +/** + * @brief Instance structure for the Q31 FIR decimator. + */ +typedef struct { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + const q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ +} csi_fir_decimate_instance_q31; + +/** + @brief Instance structure for floating-point FIR decimator. + */ +typedef struct { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + const float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ +} csi_fir_decimate_instance_f32; + +/** + * @brief Instance structure for the Q15 FIR interpolator. + */ +typedef struct { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + const q15_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q15_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ +} csi_fir_interpolate_instance_q15; + +/** + * @brief Instance structure for the Q31 FIR interpolator. + */ +typedef struct { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + const q31_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q31_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ +} csi_fir_interpolate_instance_q31; + +/** + * @brief Instance structure for the floating-point FIR interpolator. + */ +typedef struct { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + const float32_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + float32_t *pState; /**< points to the state variable array. The array is of length phaseLength+numTaps-1. */ +} csi_fir_interpolate_instance_f32; + + +/** + * @brief Instance structure for the high precision Q31 Biquad cascade filter. + */ +typedef struct { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q63_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ + const q31_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< additional shift, in bits, applied to each output sample. */ +} csi_biquad_cas_df1_32x64_ins_q31; + +/** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ +typedef struct { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ + const float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ +} csi_biquad_cascade_df2T_instance_f32; + +/** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ +typedef struct { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ + const float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ +} csi_biquad_cascade_stereo_df2T_instance_f32; + +/** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ +typedef struct { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float64_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ + float64_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ +} csi_biquad_cascade_df2T_instance_f64; + +/** + * @brief Instance structure for the Q15 FIR lattice filter. + */ +typedef struct { + uint16_t numStages; /**< number of filter stages. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages. */ + const q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ +} csi_fir_lattice_instance_q15; + +/** + * @brief Instance structure for the Q31 FIR lattice filter. + */ +typedef struct { + uint16_t numStages; /**< number of filter stages. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages. */ + const q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ +} csi_fir_lattice_instance_q31; + +/** + * @brief Instance structure for the floating-point FIR lattice filter. + */ +typedef struct { + uint16_t numStages; /**< number of filter stages. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages. */ + const float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ +} csi_fir_lattice_instance_f32; + + +/** + * @brief Instance structure for the Q15 IIR lattice filter. + */ +typedef struct { + uint16_t numStages; /**< number of stages in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q15_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q15_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ +} csi_iir_lattice_instance_q15; + +/** + * @brief Instance structure for the Q31 IIR lattice filter. + */ +typedef struct { + uint16_t numStages; /**< number of stages in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q31_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q31_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ +} csi_iir_lattice_instance_q31; + +/** + * @brief Instance structure for the floating-point IIR lattice filter. + */ +typedef struct { + uint16_t numStages; /**< number of stages in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + float32_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + float32_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ +} csi_iir_lattice_instance_f32; + + +/** + * @brief Instance structure for the floating-point LMS filter. + */ +typedef struct { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that controls filter coefficient updates. */ +} csi_lms_instance_f32; + + +/** + * @brief Instance structure for the Q15 LMS filter. + */ +typedef struct { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ +} csi_lms_instance_q15; + + +/** + * @brief Instance structure for the Q31 LMS filter. + */ +typedef struct { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ +} csi_lms_instance_q31; + + +/** + * @brief Instance structure for the floating-point normalized LMS filter. + */ +typedef struct { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that control filter coefficient updates. */ + float32_t energy; /**< saves previous frame energy. */ + float32_t x0; /**< saves previous input sample. */ +} csi_lms_norm_instance_f32; + +/** + * @brief Instance structure for the Q31 normalized LMS filter. + */ +typedef struct { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + const q31_t *recipTable; /**< points to the reciprocal initial value table. */ + q31_t energy; /**< saves previous frame energy. */ + q31_t x0; /**< saves previous input sample. */ +} csi_lms_norm_instance_q31; + + +/** + * @brief Instance structure for the Q15 normalized LMS filter. + */ +typedef struct { + uint16_t numTaps; /**< Number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + const q15_t *recipTable; /**< Points to the reciprocal initial value table. */ + q15_t energy; /**< saves previous frame energy. */ + q15_t x0; /**< saves previous input sample. */ +} csi_lms_norm_instance_q15; + +/** + * @brief Instance structure for the floating-point sparse FIR filter. + */ +typedef struct { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + float32_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + const float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ +} csi_fir_sparse_instance_f32; + +/** + * @brief Instance structure for the Q31 sparse FIR filter. + */ +typedef struct { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q31_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + const q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ +} csi_fir_sparse_instance_q31; + +/** + * @brief Instance structure for the Q15 sparse FIR filter. + */ +typedef struct { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q15_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + const q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ +} csi_fir_sparse_instance_q15; + +/** + * @brief Instance structure for the Q7 sparse FIR filter. + */ +typedef struct { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q7_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + const q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ +} csi_fir_sparse_instance_q7; + + +/** +* @brief Struct for specifying SVM Kernel +* +*/ +typedef enum { + CSI_ML_KERNEL_LINEAR = 0, + /**< Linear kernel */ + CSI_ML_KERNEL_POLYNOMIAL = 1, + /**< Polynomial kernel */ + CSI_ML_KERNEL_RBF = 2, + /**< Radial Basis Function kernel */ + CSI_ML_KERNEL_SIGMOID = 3 + /**< Sigmoid kernel */ +} csi_ml_kernel_type; + + + +/** + * @brief Instance structure for linear SVM prediction function. + */ +typedef struct { + uint32_t nbOfSupportVectors; /**< Number of support vectors */ + uint32_t vectorDimension; /**< Dimension of vector space */ + float32_t intercept; /**< Intercept */ + const float32_t *dualCoefficients; /**< Dual coefficients */ + const float32_t *supportVectors; /**< Support vectors */ + const int32_t *classes; /**< The two SVM classes */ +} csi_svm_linear_instance_f32; + + +/** + * @brief Instance structure for polynomial SVM prediction function. + */ +typedef struct { + uint32_t nbOfSupportVectors; /**< Number of support vectors */ + uint32_t vectorDimension; /**< Dimension of vector space */ + float32_t intercept; /**< Intercept */ + const float32_t *dualCoefficients; /**< Dual coefficients */ + const float32_t *supportVectors; /**< Support vectors */ + const int32_t *classes; /**< The two SVM classes */ + int32_t degree; /**< Polynomial degree */ + float32_t coef0; /**< Polynomial constant */ + float32_t gamma; /**< Gamma factor */ +} csi_svm_polynomial_instance_f32; + +/** + * @brief Instance structure for rbf SVM prediction function. + */ +typedef struct { + uint32_t nbOfSupportVectors; /**< Number of support vectors */ + uint32_t vectorDimension; /**< Dimension of vector space */ + float32_t intercept; /**< Intercept */ + const float32_t *dualCoefficients; /**< Dual coefficients */ + const float32_t *supportVectors; /**< Support vectors */ + const int32_t *classes; /**< The two SVM classes */ + float32_t gamma; /**< Gamma factor */ +} csi_svm_rbf_instance_f32; + +/** + * @brief Instance structure for sigmoid SVM prediction function. + */ +typedef struct { + uint32_t nbOfSupportVectors; /**< Number of support vectors */ + uint32_t vectorDimension; /**< Dimension of vector space */ + float32_t intercept; /**< Intercept */ + const float32_t *dualCoefficients; /**< Dual coefficients */ + const float32_t *supportVectors; /**< Support vectors */ + const int32_t *classes; /**< The two SVM classes */ + float32_t coef0; /**< Independant constant */ + float32_t gamma; /**< Gamma factor */ +} csi_svm_sigmoid_instance_f32; + +/** + * @brief Instance structure for Naive Gaussian Bayesian estimator. + */ +typedef struct { + uint32_t vectorDimension; /**< Dimension of vector space */ + uint32_t numberOfClasses; /**< Number of different classes */ + const float32_t *theta; /**< Mean values for the Gaussians */ + const float32_t *sigma; /**< Variances for the Gaussians */ + const float32_t *classPriors; /**< Class prior probabilities */ + float32_t epsilon; /**< Additive value to variances */ +} csi_gaussian_naive_bayes_instance_f32; + +#ifdef CSI_SIMD +/* SMMLAR */ +__ALWAYS_STATIC_INLINE int32_t multAcc_32x32_keep32_R(int32_t a, int32_t x, int32_t y) +{ + __ASM volatile("mula.s32.rhs %0, %1, %2\n\t" + :"=r" (a), "=r" (x), "=r" (y) : "0" (a), "1" (x), "2" (y)); + return a; +} + +/* SMMLSR */ +__ALWAYS_STATIC_INLINE int32_t multSub_32x32_keep32_R(int32_t a, int32_t x, int32_t y) +{ + __ASM volatile("muls.s32.rhs %0, %1, %2\n\t" + :"=r" (a), "=r" (x), "=r" (y): "0" (a), "1" (x), "2" (y)); + return a; +} + +/* SMMULR */ +__ALWAYS_STATIC_INLINE int32_t mult_32x32_keep32_R(int32_t x, int32_t y) +{ + int32_t a; + __ASM volatile("mul.s32.rh %0, %1, %2\n\t" + :"=r" (a), "=r" (x), "=r" (y): "1" (x), "2" (y)); + return a; +} + +/* SMMLA */ +__ALWAYS_STATIC_INLINE int32_t multAcc_32x32_keep32(int32_t a, int32_t x, int32_t y) +{ + __ASM volatile("mula.s32.hs %0, %1, %2\n\t" + :"=r" (a), "=r" (x), "=r" (y): "0" (a), "1" (x), "2" (y)); + return a; +} + +/* SMMLS */ +__ALWAYS_STATIC_INLINE int32_t multSub_32x32_keep32(int32_t a, int32_t x, int32_t y) +{ + __ASM volatile("muls.s32.hs %0, %1, %2\n\t" + :"=r" (a), "=r" (x), "=r" (y): "0" (a), "1" (x), "2" (y)); + return a; +} + +/* SMMUL */ +__ALWAYS_STATIC_INLINE int32_t mult_32x32_keep32(int32_t x, int32_t y) +{ + int32_t a; + __ASM volatile("mul.s32.h %0, %1, %2\n\t" + :"=r" (a), "=r" (x), "=r" (y): "0" (a), "1" (x), "2" (y)); + return a; +} + +__ALWAYS_STATIC_INLINE int32_t multAcc_16x16_keep32(int32_t a, int16_t x, int16_t y) +{ + __ASM volatile("mulall.s16 %0, %1, %2\n\t" + :"=r" (a), "=r" (x), "=r" (y): "0" (a), "1" (x), "2" (y)); + return a; +} + +__ALWAYS_STATIC_INLINE int64_t multAcc_16x16_keep64(int64_t a, int16_t x, int16_t y) +{ + __ASM volatile("mulall.s16.e %0, %1, %2\n\t" + :"=r" (a), "=r" (x), "=r" (y): "0" (a), "1" (x), "2" (y)); + return a; +} + +__ALWAYS_STATIC_INLINE int64_t mult_32x32_keep64(int32_t x, int32_t y) +{ + int64_t a; + __ASM volatile("mul.s32 %0, %1, %2\n\t" + :"=r" (a), "=r" (x), "=r" (y): "1" (x), "2" (y)); + return a; +} + +__ALWAYS_STATIC_INLINE int64_t multAcc_32x32_keep64(int64_t a, int32_t x, int32_t y) +{ + __ASM volatile("mula.s32 %0, %1, %2\n\t" + :"=r" (a), "=r" (x), "=r" (y): "0" (a), "1" (x), "2" (y)); + return a; +} + +__ALWAYS_STATIC_INLINE int32_t mult_32x32_dext_31(int32_t x, int32_t y) +{ + int64_t tmp1; + int32_t tmp2; + __ASM volatile("mul.s32 %0, %1, %2\n\t" + "dexti %3, %0, %R0, 31" + :"=r" (tmp1), "=r" (x), "=r" (y), "=r" (tmp2): "1" (x), "2" (y)); + return tmp2; +} + +__ALWAYS_STATIC_INLINE int32_t mult_32x32_dext_30(int32_t x, int32_t y) +{ + int64_t tmp1; + int32_t tmp2; + __ASM volatile("mul.s32 %0, %1, %2\n\t" + "dexti %3, %0, %R0, 30" + :"=r" (tmp1), "=r" (x), "=r" (y), "=r" (tmp2): "1" (x), "2" (y)); + return tmp2; +} + +__ALWAYS_STATIC_INLINE int32_t mult_32x32_dext_4(int32_t x, int32_t y) +{ + int64_t tmp1; + int32_t tmp2; + __ASM volatile("mul.s32 %0, %1, %2\n\t" + "dexti %3, %0, %R0, 4" + :"=r" (tmp1), "=r" (x), "=r" (y), "=r" (tmp2): "1" (x), "2" (y)); + return tmp2; +} + +__ALWAYS_STATIC_INLINE int32_t mult_32x32_dext_33(int32_t x, int32_t y) +{ + int64_t tmp1; + int32_t tmp2; + __ASM volatile("mul.s32 %0, %1, %2\n\t" + "asri %3, %R0, 1" + :"=r" (tmp1), "=r" (x), "=r" (y), "=r" (tmp2): "1" (x), "2" (y)); + return tmp2; +} + +__ALWAYS_STATIC_INLINE int32_t dext_31(int64_t x) +{ + int32_t tmp1; + __ASM volatile( + "dexti %0, %1, %R1, 31" + :"=r" (tmp1), "=r" (x) : "1" (x)); + return tmp1; +} + +__ALWAYS_STATIC_INLINE int32_t mult_l16xl16_keep32(int32_t x, int32_t y) +{ + int32_t a; + __ASM volatile("mulll.s16 %0, %1, %2\n\t" + :"=r" (a), "=r" (x), "=r" (y): "1" (x), "2" (y)); + return a; +} + +__ALWAYS_STATIC_INLINE int32_t mult_h16xl16_keep32(int32_t x, int32_t y) +{ + int32_t a; + __ASM volatile("mulhl.s16 %0, %1, %2\n\t" + :"=r" (a), "=r" (x), "=r" (y): "1" (x), "2" (y)); + return a; +} + +__ALWAYS_STATIC_INLINE int32_t mult_h16xh16_keep32(int32_t x, int32_t y) +{ + int32_t a; + __ASM volatile("mulhh.s16 %0, %1, %2\n\t" + :"=r" (a), "=r" (x), "=r" (y): "1" (x), "2" (y)); + return a; +} + +#else + +/* SMMLAR */ +#define multAcc_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((((q63_t) a) << 32) + ((q63_t) x * y) + 0x80000000LL ) >> 32) + +/* SMMLSR */ +#define multSub_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((((q63_t) a) << 32) - ((q63_t) x * y) + 0x80000000LL ) >> 32) + +/* SMMULR */ +#define mult_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((q63_t) x * y + 0x80000000LL ) >> 32) + +/* SMMLA */ +#define multAcc_32x32_keep32(a, x, y) \ + a += (q31_t) (((q63_t) x * y) >> 32) + +/* SMMLS */ +#define multSub_32x32_keep32(a, x, y) \ + a -= (q31_t) (((q63_t) x * y) >> 32) + +/* SMMUL */ +#define mult_32x32_keep32(a, x, y) \ + a = (q31_t) (((q63_t) x * y ) >> 32) +#endif +#ifdef __cplusplus +} +#endif + + +#endif /* _CSI_MATH_H */ + +/** + * + * End of file. + */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/dsp/csi_math.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/dsp/csi_math.h new file mode 100644 index 00000000..24eb063a --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/dsp/csi_math.h @@ -0,0 +1,5739 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 csi_math.h + * @brief Some common define + * @version V1.0 + * @date Feb. 2020 + ******************************************************************************/ + + +#ifndef _CSI_MATH_H +#define _CSI_MATH_H + +#ifdef __cplusplus +extern "C" +{ +#endif + + +#include +#include +#include +#include +#include +#include "csi_instance.h" + + +/** + * @brief Processing function for the Q7 FIR filter. + * @param[in] S points to an instance of the Q7 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ +void csi_fir_q7( + const csi_fir_instance_q7 * S, + const q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + +/** + * @brief Initialization function for the Q7 FIR filter. + * @param[in,out] S points to an instance of the Q7 FIR structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed. + */ +void csi_fir_init_q7( + csi_fir_instance_q7 * S, + uint16_t numTaps, + const q7_t * pCoeffs, + q7_t * pState, + uint32_t blockSize); + +/** + * @brief Processing function for the Q15 FIR filter. + * @param[in] S points to an instance of the Q15 FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ +void csi_fir_q15( + const csi_fir_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + +/** + * @brief Processing function for the fast Q15 FIR filter (fast version). + * @param[in] S points to an instance of the Q15 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ +void csi_fir_fast_q15( + const csi_fir_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + +/** + * @brief Initialization function for the Q15 FIR filter. + * @param[in,out] S points to an instance of the Q15 FIR filter structure. + * @param[in] numTaps Number of filter coefficients in the filter. Must be even and greater than or equal to 4. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + * @return The function returns either + * CSI_MATH_SUCCESS if initialization was successful or + * CSI_MATH_ARGUMENT_ERROR if numTaps is not a supported value. + */ +csi_status csi_fir_init_q15( + csi_fir_instance_q15 * S, + uint16_t numTaps, + const q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + +/** + * @brief Processing function for the Q31 FIR filter. + * @param[in] S points to an instance of the Q31 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ +void csi_fir_q31( + const csi_fir_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + +/** + * @brief Processing function for the fast Q31 FIR filter (fast version). + * @param[in] S points to an instance of the Q31 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ +void csi_fir_fast_q31( + const csi_fir_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + +/** + * @brief Initialization function for the Q31 FIR filter. + * @param[in,out] S points to an instance of the Q31 FIR structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + */ +void csi_fir_init_q31( + csi_fir_instance_q31 * S, + uint16_t numTaps, + const q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + +/** + * @brief Processing function for the floating-point FIR filter. + * @param[in] S points to an instance of the floating-point FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ +void csi_fir_f32( + const csi_fir_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + +/** + * @brief Initialization function for the floating-point FIR filter. + * @param[in,out] S points to an instance of the floating-point FIR filter structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + */ +void csi_fir_init_f32( + csi_fir_instance_f32 * S, + uint16_t numTaps, + const float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + +/** + * @brief Processing function for the Q15 Biquad cascade filter. + * @param[in] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ +void csi_biquad_cascade_df1_q15( + const csi_biquad_casd_df1_inst_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + +/** + * @brief Initialization function for the Q15 Biquad cascade filter. + * @param[in,out] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format + */ +void csi_biquad_cascade_df1_init_q15( + csi_biquad_casd_df1_inst_q15 * S, + uint8_t numStages, + const q15_t * pCoeffs, + q15_t * pState, + int8_t postShift); + +/** + * @brief Fast but less precise processing function for the Q15 Biquad cascade filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ +void csi_biquad_cascade_df1_fast_q15( + const csi_biquad_casd_df1_inst_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + +/** + * @brief Processing function for the Q31 Biquad cascade filter + * @param[in] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ +void csi_biquad_cascade_df1_q31( + const csi_biquad_casd_df1_inst_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + +/** + * @brief Fast but less precise processing function for the Q31 Biquad cascade filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ +void csi_biquad_cascade_df1_fast_q31( + const csi_biquad_casd_df1_inst_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + +/** + * @brief Initialization function for the Q31 Biquad cascade filter. + * @param[in,out] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format + */ +void csi_biquad_cascade_df1_init_q31( + csi_biquad_casd_df1_inst_q31 * S, + uint8_t numStages, + const q31_t * pCoeffs, + q31_t * pState, + int8_t postShift); + +/** + * @brief Processing function for the floating-point Biquad cascade filter. + * @param[in] S points to an instance of the floating-point Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ +void csi_biquad_cascade_df1_f32( + const csi_biquad_casd_df1_inst_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + +/** + * @brief Initialization function for the floating-point Biquad cascade filter. + * @param[in,out] S points to an instance of the floating-point Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ +void csi_biquad_cascade_df1_init_f32( + csi_biquad_casd_df1_inst_f32 * S, + uint8_t numStages, + const float32_t * pCoeffs, + float32_t * pState); + +/** + * @brief Floating-point matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * CSI_MATH_SIZE_MISMATCH or CSI_MATH_SUCCESS based on the outcome of size checking. + */ +csi_status csi_mat_add_f32( + const csi_matrix_instance_f32 * pSrcA, + const csi_matrix_instance_f32 * pSrcB, + csi_matrix_instance_f32 * pDst); + +/** + * @brief Q15 matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * CSI_MATH_SIZE_MISMATCH or CSI_MATH_SUCCESS based on the outcome of size checking. + */ +csi_status csi_mat_add_q15( + const csi_matrix_instance_q15 * pSrcA, + const csi_matrix_instance_q15 * pSrcB, + csi_matrix_instance_q15 * pDst); + +/** + * @brief Q31 matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * CSI_MATH_SIZE_MISMATCH or CSI_MATH_SUCCESS based on the outcome of size checking. + */ +csi_status csi_mat_add_q31( + const csi_matrix_instance_q31 * pSrcA, + const csi_matrix_instance_q31 * pSrcB, + csi_matrix_instance_q31 * pDst); + +/** + * @brief Floating-point, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * CSI_MATH_SIZE_MISMATCH or CSI_MATH_SUCCESS based on the outcome of size checking. + */ +csi_status csi_mat_cmplx_mult_f32( + const csi_matrix_instance_f32 * pSrcA, + const csi_matrix_instance_f32 * pSrcB, + csi_matrix_instance_f32 * pDst); + +/** + * @brief Q15, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * CSI_MATH_SIZE_MISMATCH or CSI_MATH_SUCCESS based on the outcome of size checking. + */ +csi_status csi_mat_cmplx_mult_q15( + const csi_matrix_instance_q15 * pSrcA, + const csi_matrix_instance_q15 * pSrcB, + csi_matrix_instance_q15 * pDst); + +void csi_mult_q15xq31_sht( + q15_t * pSrcA, + q31_t * pSrcB, + uint32_t shiftValue, + uint32_t blockSize); + +/** + * @brief Q31, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * CSI_MATH_SIZE_MISMATCH or CSI_MATH_SUCCESS based on the outcome of size checking. + */ +csi_status csi_mat_cmplx_mult_q31( + const csi_matrix_instance_q31 * pSrcA, + const csi_matrix_instance_q31 * pSrcB, + csi_matrix_instance_q31 * pDst); + +/** + * @brief Floating-point matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either CSI_MATH_SIZE_MISMATCH + * or CSI_MATH_SUCCESS based on the outcome of size checking. + */ +csi_status csi_mat_trans_f32( + const csi_matrix_instance_f32 * pSrc, + csi_matrix_instance_f32 * pDst); + +/** + * @brief Q15 matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either CSI_MATH_SIZE_MISMATCH + * or CSI_MATH_SUCCESS based on the outcome of size checking. + */ +csi_status csi_mat_trans_q15( + const csi_matrix_instance_q15 * pSrc, + csi_matrix_instance_q15 * pDst); + +/** + * @brief Q31 matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either CSI_MATH_SIZE_MISMATCH + * or CSI_MATH_SUCCESS based on the outcome of size checking. + */ +csi_status csi_mat_trans_q31( + const csi_matrix_instance_q31 * pSrc, + csi_matrix_instance_q31 * pDst); + +/** + * @brief Floating-point matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * CSI_MATH_SIZE_MISMATCH or CSI_MATH_SUCCESS based on the outcome of size checking. + */ +csi_status csi_mat_mult_f32( + const csi_matrix_instance_f32 * pSrcA, + const csi_matrix_instance_f32 * pSrcB, + csi_matrix_instance_f32 * pDst); + +/** + * @brief Q15 matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * CSI_MATH_SIZE_MISMATCH or CSI_MATH_SUCCESS based on the outcome of size checking. + */ +csi_status csi_mat_mult_q15( + const csi_matrix_instance_q15 * pSrcA, + const csi_matrix_instance_q15 * pSrcB, + csi_matrix_instance_q15 * pDst); + + csi_status csi_mat_mult_trans_q15( + const csi_matrix_instance_q15 * pSrcA, + const csi_matrix_instance_q15 * pSrcB, + csi_matrix_instance_q15 * pDst); + +/** + * @brief Q15 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @param[in] pState points to the array for storing intermediate results + * @return The function returns either + * CSI_MATH_SIZE_MISMATCH or CSI_MATH_SUCCESS based on the outcome of size checking. + */ +csi_status csi_mat_mult_fast_q15( + const csi_matrix_instance_q15 * pSrcA, + const csi_matrix_instance_q15 * pSrcB, + csi_matrix_instance_q15 * pDst); + +/** + * @brief Q31 matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * CSI_MATH_SIZE_MISMATCH or CSI_MATH_SUCCESS based on the outcome of size checking. + */ +csi_status csi_mat_mult_q31( + const csi_matrix_instance_q31 * pSrcA, + const csi_matrix_instance_q31 * pSrcB, + csi_matrix_instance_q31 * pDst); + +csi_status csi_mat_mult_trans_q31( + const csi_matrix_instance_q31 * pSrcA, + const csi_matrix_instance_q31 * pSrcB, + csi_matrix_instance_q31 * pDst); + +/** + * @brief Q31 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * CSI_MATH_SIZE_MISMATCH or CSI_MATH_SUCCESS based on the outcome of size checking. + */ +csi_status csi_mat_mult_fast_q31( + const csi_matrix_instance_q31 * pSrcA, + const csi_matrix_instance_q31 * pSrcB, + csi_matrix_instance_q31 * pDst); + +/** + * @brief Floating-point matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * CSI_MATH_SIZE_MISMATCH or CSI_MATH_SUCCESS based on the outcome of size checking. + */ +csi_status csi_mat_sub_f32( + const csi_matrix_instance_f32 * pSrcA, + const csi_matrix_instance_f32 * pSrcB, + csi_matrix_instance_f32 * pDst); + +/** + * @brief Q15 matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * CSI_MATH_SIZE_MISMATCH or CSI_MATH_SUCCESS based on the outcome of size checking. + */ +csi_status csi_mat_sub_q15( + const csi_matrix_instance_q15 * pSrcA, + const csi_matrix_instance_q15 * pSrcB, + csi_matrix_instance_q15 * pDst); + +/** + * @brief Q31 matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * CSI_MATH_SIZE_MISMATCH or CSI_MATH_SUCCESS based on the outcome of size checking. + */ +csi_status csi_mat_sub_q31( + const csi_matrix_instance_q31 * pSrcA, + const csi_matrix_instance_q31 * pSrcB, + csi_matrix_instance_q31 * pDst); + +void csi_sum_q15( + q15_t * pSrcA, + q63_t * pDst, + uint32_t blockSize); + +/** + * @brief Floating-point matrix scaling. + * @param[in] pSrc points to the input matrix + * @param[in] scale scale factor + * @param[out] pDst points to the output matrix + * @return The function returns either + * CSI_MATH_SIZE_MISMATCH or CSI_MATH_SUCCESS based on the outcome of size checking. + */ +csi_status csi_mat_scale_f32( + const csi_matrix_instance_f32 * pSrc, + float32_t scale, + csi_matrix_instance_f32 * pDst); + +/** + * @brief Q15 matrix scaling. + * @param[in] pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to output matrix + * @return The function returns either + * CSI_MATH_SIZE_MISMATCH or CSI_MATH_SUCCESS based on the outcome of size checking. + */ +csi_status csi_mat_scale_q15( + const csi_matrix_instance_q15 * pSrc, + q15_t scaleFract, + int32_t shift, + csi_matrix_instance_q15 * pDst); + +/** + * @brief Q31 matrix scaling. + * @param[in] pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to output matrix structure + * @return The function returns either + * CSI_MATH_SIZE_MISMATCH or CSI_MATH_SUCCESS based on the outcome of size checking. + */ +csi_status csi_mat_scale_q31( + const csi_matrix_instance_q31 * pSrc, + q31_t scaleFract, + int32_t shift, + csi_matrix_instance_q31 * pDst); + +/** + * @brief Q31 matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ +void csi_mat_init_q31( + csi_matrix_instance_q31 * S, + uint16_t nRows, + uint16_t nColumns, + q31_t * pData); + +/** + * @brief Q15 matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ +void csi_mat_init_q15( + csi_matrix_instance_q15 * S, + uint16_t nRows, + uint16_t nColumns, + q15_t * pData); + +/** + * @brief Floating-point matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ +void csi_mat_init_f32( + csi_matrix_instance_f32 * S, + uint16_t nRows, + uint16_t nColumns, + float32_t * pData); + + +/** + * @brief Initialization function for the floating-point PID Control. + * @param[in,out] S points to an instance of the PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ +void csi_pid_init_f32( + csi_pid_instance_f32 * S, + int32_t resetStateFlag); + + +/** + * @brief Reset function for the floating-point PID Control. + * @param[in,out] S is an instance of the floating-point PID Control structure + */ +void csi_pid_reset_f32( + csi_pid_instance_f32 * S); + + +/** + * @brief Initialization function for the Q31 PID Control. + * @param[in,out] S points to an instance of the Q15 PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ +void csi_pid_init_q31( + csi_pid_instance_q31 * S, + int32_t resetStateFlag); + + +/** + * @brief Reset function for the Q31 PID Control. + * @param[in,out] S points to an instance of the Q31 PID Control structure + */ + +void csi_pid_reset_q31( + csi_pid_instance_q31 * S); + + +/** + * @brief Initialization function for the Q15 PID Control. + * @param[in,out] S points to an instance of the Q15 PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ +void csi_pid_init_q15( + csi_pid_instance_q15 * S, + int32_t resetStateFlag); + + +/** + * @brief Reset function for the Q15 PID Control. + * @param[in,out] S points to an instance of the q15 PID Control structure + */ +void csi_pid_reset_q15( + csi_pid_instance_q15 * S); + +/** + * @brief Q7 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ +void csi_mult_q7( + const q7_t * pSrcA, + const q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + +/** + * @brief Q15 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ +void csi_mult_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + +void csi_mult_rnd_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + +/** + * @brief Q31 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ +void csi_mult_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Floating-point vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ +void csi_mult_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + +/* Deprecated */ +csi_status csi_cfft_radix2_init_q15( + csi_cfft_radix2_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ +void csi_cfft_radix2_q15( + const csi_cfft_radix2_instance_q15 * S, + q15_t * pSrc); + + +/* Deprecated */ +csi_status csi_cfft_radix4_init_q15( + csi_cfft_radix4_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ +void csi_cfft_radix4_q15( + const csi_cfft_radix4_instance_q15 * S, + q15_t * pSrc); + +/* Deprecated */ +csi_status csi_cfft_radix2_init_q31( + csi_cfft_radix2_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ +void csi_cfft_radix2_q31( + const csi_cfft_radix2_instance_q31 * S, + q31_t * pSrc); + + +/* Deprecated */ +void csi_cfft_radix4_q31( + const csi_cfft_radix4_instance_q31 * S, + q31_t * pSrc); + +/* Deprecated */ +csi_status csi_cfft_radix4_init_q31( + csi_cfft_radix4_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + +/* Deprecated */ +csi_status csi_cfft_radix2_init_f32( + csi_cfft_radix2_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void csi_cfft_radix2_f32( + const csi_cfft_instance_f32 * S, + float32_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag, + float32_t onebyfftLen); + + +/* Deprecated */ +csi_status csi_cfft_radix4_init_f32( + csi_cfft_radix4_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void csi_cfft_radix4_f32( + const csi_cfft_instance_f32 * S, + float32_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag, + float32_t onebyfftLen); + + void csi_cfft_fast_radix4_f32( + const csi_cfft_instance_f32 * S, + float32_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag, + float32_t onebyfftLen); + + +void csi_cfft_q15( + const csi_cfft_instance_q15 * S, + q15_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +void csi_cfft_fast_q15( + const csi_cfft_instance_q15 * S, + q15_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +void csi_cfft_q31( + const csi_cfft_instance_q31 * S, + q31_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +void csi_cfft_fast_q31( + const csi_cfft_instance_q31 * S, + q31_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + +void csi_cfft_f32( + const csi_cfft_instance_f32 * S, + float32_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + +csi_status csi_rfft_init_q15( + csi_rfft_instance_q15 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + +void csi_rfft_q15( + const csi_rfft_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst); + +void csi_rfft_fast_q15( + const csi_rfft_fast_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst); + + +csi_status csi_rfft_init_q31( + csi_rfft_instance_q31 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + +void csi_rfft_q31( + const csi_rfft_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst); + +void csi_rfft_fast_q31( + const csi_rfft_fast_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst); + + +csi_status csi_rfft_init_f32( + csi_rfft_instance_f32 * S, + csi_cfft_radix4_instance_f32 * S_CFFT, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + +void csi_rfft_f32( + const csi_rfft_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst); + + +csi_status csi_rfft_fast_init_f32 ( + csi_rfft_fast_instance_f32 * S, + uint16_t fftLen); + +csi_status csi_rfft_32_fast_init_f32 ( csi_rfft_fast_instance_f32 * S ); + +csi_status csi_rfft_64_fast_init_f32 ( csi_rfft_fast_instance_f32 * S ); + +csi_status csi_rfft_128_fast_init_f32 ( csi_rfft_fast_instance_f32 * S ); + +csi_status csi_rfft_256_fast_init_f32 ( csi_rfft_fast_instance_f32 * S ); + +csi_status csi_rfft_512_fast_init_f32 ( csi_rfft_fast_instance_f32 * S ); + +csi_status csi_rfft_1024_fast_init_f32 ( csi_rfft_fast_instance_f32 * S ); + +csi_status csi_rfft_2048_fast_init_f32 ( csi_rfft_fast_instance_f32 * S ); + +csi_status csi_rfft_4096_fast_init_f32 ( csi_rfft_fast_instance_f32 * S ); + + +void csi_rfft_fast_f32( + csi_rfft_fast_instance_f32 * S, + float32_t * p, float32_t * pOut, + uint8_t ifftFlag); + + +/** + * @brief Initialization function for the floating-point DCT4/IDCT4. + * @param[in,out] S points to an instance of floating-point DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of floating-point RFFT/RIFFT structure. + * @param[in] S_CFFT points to an instance of floating-point CFFT/CIFFT structure. + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return csi_status function returns CSI_MATH_SUCCESS if initialization is successful or CSI_MATH_ARGUMENT_ERROR if fftLenReal is not a supported transform length. + */ +csi_status csi_dct4_init_f32( + csi_dct4_instance_f32 * S, + csi_rfft_fast_instance_f32 * S_RFFT, + csi_cfft_radix4_instance_f32 * S_CFFT, + uint16_t N, + uint16_t Nby2, + float32_t normalize); + + +/** + * @brief Processing function for the floating-point DCT4/IDCT4. + * @param[in] S points to an instance of the floating-point DCT4/IDCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ +void csi_dct4_f32( + const csi_dct4_instance_f32 * S, + float32_t * pState, + float32_t * pInlineBuffer); + + + +/** + * @brief Initialization function for the Q31 DCT4/IDCT4. + * @param[in,out] S points to an instance of Q31 DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of Q31 RFFT/RIFFT structure + * @param[in] S_CFFT points to an instance of Q31 CFFT/CIFFT structure + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return csi_status function returns CSI_MATH_SUCCESS if initialization is successful or CSI_MATH_ARGUMENT_ERROR if N is not a supported transform length. + */ +csi_status csi_dct4_init_q31( + csi_dct4_instance_q31 * S, + csi_rfft_instance_q31 * S_RFFT, + csi_cfft_radix4_instance_q31 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q31_t normalize); + + +/** + * @brief Processing function for the Q31 DCT4/IDCT4. + * @param[in] S points to an instance of the Q31 DCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ +void csi_dct4_q31( + const csi_dct4_instance_q31 * S, + q31_t * pState, + q31_t * pInlineBuffer); + +void csi_dct4_fast_q31( + const csi_dct4_fast_instance_q31 * S, + q31_t * pState, + q31_t * pInlineBuffer); + + +/** + * @brief Initialization function for the Q15 DCT4/IDCT4. + * @param[in,out] S points to an instance of Q15 DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of Q15 RFFT/RIFFT structure. + * @param[in] S_CFFT points to an instance of Q15 CFFT/CIFFT structure. + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return csi_status function returns CSI_MATH_SUCCESS if initialization is successful or CSI_MATH_ARGUMENT_ERROR if N is not a supported transform length. + */ +csi_status csi_dct4_init_q15( + csi_dct4_instance_q15 * S, + csi_rfft_instance_q15 * S_RFFT, + csi_cfft_radix4_instance_q15 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q15_t normalize); + + +/** + * @brief Processing function for the Q15 DCT4/IDCT4. + * @param[in] S points to an instance of the Q15 DCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ +void csi_dct4_q15( + const csi_dct4_instance_q15 * S, + q15_t * pState, + q15_t * pInlineBuffer); + +void csi_dct4_fast_q15( + const csi_dct4_fast_instance_q15 * S, + q15_t * pState, + q15_t * pInlineBuffer); + + +/** + * @brief Floating-point vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ +void csi_add_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + +/** + * @brief Q7 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ +void csi_add_q7( + const q7_t * pSrcA, + const q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + +/** + * @brief Q15 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ +void csi_add_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + +/** + * @brief Q31 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ +void csi_add_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Floating-point vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ +void csi_sub_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + +/** + * @brief Q7 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ +void csi_sub_q7( + const q7_t * pSrcA, + const q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + +/** + * @brief Q15 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ +void csi_sub_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + +/** + * @brief Q31 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ +void csi_sub_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Multiplies a floating-point vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scale scale factor to be applied + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ +void csi_scale_f32( + const float32_t * pSrc, + float32_t scale, + float32_t * pDst, + uint32_t blockSize); + + +/** + * @brief Multiplies a Q7 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ +void csi_scale_q7( + const q7_t * pSrc, + q7_t scaleFract, + int8_t shift, + q7_t * pDst, + uint32_t blockSize); + + +/** + * @brief Multiplies a Q15 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ +void csi_scale_q15( + const q15_t * pSrc, + q15_t scaleFract, + int8_t shift, + q15_t * pDst, + uint32_t blockSize); + + +/** + * @brief Multiplies a Q31 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ +void csi_scale_q31( + const q31_t * pSrc, + q31_t scaleFract, + int8_t shift, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Q7 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ +void csi_abs_q7( + const q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + +/** + * @brief Floating-point vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ +void csi_abs_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + +/** + * @brief Q15 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ +void csi_abs_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + +/** + * @brief Q31 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ +void csi_abs_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + void csi_abs_max_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + void csi_abs_max_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Dot product of floating-point vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ +void csi_dot_prod_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + uint32_t blockSize, + float32_t * result); + + +/** + * @brief Dot product of Q7 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ +void csi_dot_prod_q7( + const q7_t * pSrcA, + const q7_t * pSrcB, + uint32_t blockSize, + q31_t * result); + + +/** + * @brief Dot product of Q15 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ +void csi_dot_prod_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + +/** + * @brief Dot product of Q31 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ +void csi_dot_prod_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + +/** + * @brief Shifts the elements of a Q7 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ +void csi_shift_q7( + const q7_t * pSrc, + int8_t shiftBits, + q7_t * pDst, + uint32_t blockSize); + + +/** + * @brief Shifts the elements of a Q15 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ +void csi_shift_q15( + const q15_t * pSrc, + int8_t shiftBits, + q15_t * pDst, + uint32_t blockSize); + + +/** + * @brief Shifts the elements of a Q31 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ +void csi_shift_q31( + const q31_t * pSrc, + int8_t shiftBits, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Adds a constant offset to a floating-point vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ +void csi_offset_f32( + const float32_t * pSrc, + float32_t offset, + float32_t * pDst, + uint32_t blockSize); + + +/** + * @brief Adds a constant offset to a Q7 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ +void csi_offset_q7( + const q7_t * pSrc, + q7_t offset, + q7_t * pDst, + uint32_t blockSize); + + +/** + * @brief Adds a constant offset to a Q15 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ +void csi_offset_q15( + const q15_t * pSrc, + q15_t offset, + q15_t * pDst, + uint32_t blockSize); + + +/** + * @brief Adds a constant offset to a Q31 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ +void csi_offset_q31( + const q31_t * pSrc, + q31_t offset, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Negates the elements of a floating-point vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ +void csi_negate_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + +/** + * @brief Negates the elements of a Q7 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ +void csi_negate_q7( + const q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + +/** + * @brief Negates the elements of a Q15 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ +void csi_negate_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + +/** + * @brief Negates the elements of a Q31 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ +void csi_negate_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Copies the elements of a floating-point vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ +void csi_copy_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + +/** + * @brief Copies the elements of a Q7 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ +void csi_copy_q7( + const q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + +/** + * @brief Copies the elements of a Q15 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ +void csi_copy_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + +/** + * @brief Copies the elements of a Q31 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ +void csi_copy_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Fills a constant value into a floating-point vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ +void csi_fill_f32( + float32_t value, + float32_t * pDst, + uint32_t blockSize); + + +/** + * @brief Fills a constant value into a Q7 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ +void csi_fill_q7( + q7_t value, + q7_t * pDst, + uint32_t blockSize); + + +/** + * @brief Fills a constant value into a Q15 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ +void csi_fill_q15( + q15_t value, + q15_t * pDst, + uint32_t blockSize); + + +/** + * @brief Fills a constant value into a Q31 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ +void csi_fill_q31( + q31_t value, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Convolution of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the location where the output result is written. Length srcALen+srcBLen-1. + */ +void csi_conv_f32( + const float32_t * pSrcA, + uint32_t srcALen, + const float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + +/** + * @brief Convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + */ +void csi_conv_opt_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the location where the output result is written. Length srcALen+srcBLen-1. + */ +void csi_conv_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + +/** + * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ +void csi_conv_fast_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + +/** + * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + */ +void csi_conv_fast_opt_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Convolution of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ +void csi_conv_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + +/** + * @brief Convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ +void csi_conv_fast_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + +/** +* @brief Convolution of Q7 sequences. +* @param[in] pSrcA points to the first input sequence. +* @param[in] srcALen length of the first input sequence. +* @param[in] pSrcB points to the second input sequence. +* @param[in] srcBLen length of the second input sequence. +* @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. +* @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. +* @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). +*/ +void csi_conv_opt_q7( + const q7_t * pSrcA, + uint32_t srcALen, + const q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ +void csi_conv_q7( + const q7_t * pSrcA, + uint32_t srcALen, + const q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + +/** + * @brief Partial convolution of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either CSI_MATH_SUCCESS if the function completed correctly or CSI_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ +csi_status csi_conv_partial_f32( + const float32_t * pSrcA, + uint32_t srcALen, + const float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + +/** + * @brief Partial convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return Returns either CSI_MATH_SUCCESS if the function completed correctly or CSI_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ +csi_status csi_conv_partial_opt_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Partial convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either CSI_MATH_SUCCESS if the function completed correctly or CSI_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ +csi_status csi_conv_partial_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + +/** + * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either CSI_MATH_SUCCESS if the function completed correctly or CSI_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ +csi_status csi_conv_partial_fast_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + +/** + * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return Returns either CSI_MATH_SUCCESS if the function completed correctly or CSI_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ +csi_status csi_conv_partial_fast_opt_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Partial convolution of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either CSI_MATH_SUCCESS if the function completed correctly or CSI_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ +csi_status csi_conv_partial_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + +/** + * @brief Partial convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either CSI_MATH_SUCCESS if the function completed correctly or CSI_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ +csi_status csi_conv_partial_fast_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + +/** + * @brief Partial convolution of Q7 sequences + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + * @return Returns either CSI_MATH_SUCCESS if the function completed correctly or CSI_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ +csi_status csi_conv_partial_opt_q7( + const q7_t * pSrcA, + uint32_t srcALen, + const q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Partial convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either CSI_MATH_SUCCESS if the function completed correctly or CSI_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ +csi_status csi_conv_partial_q7( + const q7_t * pSrcA, + uint32_t srcALen, + const q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + +/** + @brief Processing function for floating-point FIR decimator. + @param[in] S points to an instance of the floating-point FIR decimator structure + @param[in] pSrc points to the block of input data + @param[out] pDst points to the block of output data + @param[in] blockSize number of samples to process + */ +void csi_fir_decimate_f32( + const csi_fir_decimate_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + +/** + @brief Initialization function for the floating-point FIR decimator. + @param[in,out] S points to an instance of the floating-point FIR decimator structure + @param[in] numTaps number of coefficients in the filter + @param[in] M decimation factor + @param[in] pCoeffs points to the filter coefficients + @param[in] pState points to the state buffer + @param[in] blockSize number of input samples to process per call + @return execution status + - \ref CSI_MATH_SUCCESS : Operation successful + - \ref CSI_MATH_LENGTH_ERROR : blockSize is not a multiple of M + */ +csi_status csi_fir_decimate_init_f32( + csi_fir_decimate_instance_f32 * S, + uint16_t numTaps, + uint8_t M, + const float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + +/** + * @brief Processing function for the Q15 FIR decimator. + * @param[in] S points to an instance of the Q15 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ +void csi_fir_decimate_q15( + const csi_fir_decimate_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + +/** + * @brief Processing function for the Q15 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q15 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ +void csi_fir_decimate_fast_q15( + const csi_fir_decimate_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the Q15 FIR decimator. + * @param[in,out] S points to an instance of the Q15 FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns CSI_MATH_SUCCESS if initialization is successful or CSI_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ +csi_status csi_fir_decimate_init_q15( + csi_fir_decimate_instance_q15 * S, + uint16_t numTaps, + uint8_t M, + const q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + +/** + * @brief Processing function for the Q31 FIR decimator. + * @param[in] S points to an instance of the Q31 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ +void csi_fir_decimate_q31( + const csi_fir_decimate_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + +/** + * @brief Processing function for the Q31 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q31 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ +void csi_fir_decimate_fast_q31( + const csi_fir_decimate_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the Q31 FIR decimator. + * @param[in,out] S points to an instance of the Q31 FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns CSI_MATH_SUCCESS if initialization is successful or CSI_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ +csi_status csi_fir_decimate_init_q31( + csi_fir_decimate_instance_q31 * S, + uint16_t numTaps, + uint8_t M, + const q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + +/** + * @brief Processing function for the Q15 FIR interpolator. + * @param[in] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ +void csi_fir_interpolate_q15( + const csi_fir_interpolate_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the Q15 FIR interpolator. + * @param[in,out] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns CSI_MATH_SUCCESS if initialization is successful or CSI_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ +csi_status csi_fir_interpolate_init_q15( + csi_fir_interpolate_instance_q15 * S, + uint8_t L, + uint16_t numTaps, + const q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + +/** + * @brief Processing function for the Q31 FIR interpolator. + * @param[in] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ +void csi_fir_interpolate_q31( + const csi_fir_interpolate_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the Q31 FIR interpolator. + * @param[in,out] S points to an instance of the Q31 FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns CSI_MATH_SUCCESS if initialization is successful or CSI_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ +csi_status csi_fir_interpolate_init_q31( + csi_fir_interpolate_instance_q31 * S, + uint8_t L, + uint16_t numTaps, + const q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + +/** + * @brief Processing function for the floating-point FIR interpolator. + * @param[in] S points to an instance of the floating-point FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ +void csi_fir_interpolate_f32( + const csi_fir_interpolate_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the floating-point FIR interpolator. + * @param[in,out] S points to an instance of the floating-point FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns CSI_MATH_SUCCESS if initialization is successful or CSI_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ +csi_status csi_fir_interpolate_init_f32( + csi_fir_interpolate_instance_f32 * S, + uint8_t L, + uint16_t numTaps, + const float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + +/** + * @param[in] S points to an instance of the high precision Q31 Biquad cascade filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ +void csi_biquad_cas_df1_32x64_q31( + const csi_biquad_cas_df1_32x64_ins_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @param[in,out] S points to an instance of the high precision Q31 Biquad cascade filter structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift shift to be applied to the output. Varies according to the coefficients format + */ +void csi_biquad_cas_df1_32x64_init_q31( + csi_biquad_cas_df1_32x64_ins_q31 * S, + uint8_t numStages, + const q31_t * pCoeffs, + q63_t * pState, + uint8_t postShift); + + +/** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ +void csi_biquad_cascade_df2T_f32( + const csi_biquad_cascade_df2T_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + +/** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. 2 channels + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ +void csi_biquad_cascade_stereo_df2T_f32( + const csi_biquad_cascade_stereo_df2T_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + +/** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ +void csi_biquad_cascade_df2T_f64( + const csi_biquad_cascade_df2T_instance_f64 * S, + float64_t * pSrc, + float64_t * pDst, + uint32_t blockSize); + + +#if defined(CSI_MATH_NEON) +void csi_biquad_cascade_df2T_compute_coefs_f32( + csi_biquad_cascade_df2T_instance_f32 * S, + uint8_t numStages, + float32_t * pCoeffs); +#endif +/** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ +void csi_biquad_cascade_df2T_init_f32( + csi_biquad_cascade_df2T_instance_f32 * S, + uint8_t numStages, + const float32_t * pCoeffs, + float32_t * pState); + + +/** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ +void csi_biquad_cascade_stereo_df2T_init_f32( + csi_biquad_cascade_stereo_df2T_instance_f32 * S, + uint8_t numStages, + const float32_t * pCoeffs, + float32_t * pState); + + +/** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ +void csi_biquad_cascade_df2T_init_f64( + csi_biquad_cascade_df2T_instance_f64 * S, + uint8_t numStages, + float64_t * pCoeffs, + float64_t * pState); + + +/** + * @brief Initialization function for the Q15 FIR lattice filter. + * @param[in] S points to an instance of the Q15 FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ +void csi_fir_lattice_init_q15( + csi_fir_lattice_instance_q15 * S, + uint16_t numStages, + const q15_t * pCoeffs, + q15_t * pState); + + +/** + * @brief Processing function for the Q15 FIR lattice filter. + * @param[in] S points to an instance of the Q15 FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ +void csi_fir_lattice_q15( + const csi_fir_lattice_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the Q31 FIR lattice filter. + * @param[in] S points to an instance of the Q31 FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ +void csi_fir_lattice_init_q31( + csi_fir_lattice_instance_q31 * S, + uint16_t numStages, + const q31_t * pCoeffs, + q31_t * pState); + + +/** + * @brief Processing function for the Q31 FIR lattice filter. + * @param[in] S points to an instance of the Q31 FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ +void csi_fir_lattice_q31( + const csi_fir_lattice_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the floating-point FIR lattice filter. + * @param[in] S points to an instance of the floating-point FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ +void csi_fir_lattice_init_f32( + csi_fir_lattice_instance_f32 * S, + uint16_t numStages, + const float32_t * pCoeffs, + float32_t * pState); + + +/** + * @brief Processing function for the floating-point FIR lattice filter. + * @param[in] S points to an instance of the floating-point FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ +void csi_fir_lattice_f32( + const csi_fir_lattice_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + +/** + * @brief Processing function for the floating-point IIR lattice filter. + * @param[in] S points to an instance of the floating-point IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ +void csi_iir_lattice_f32( + const csi_iir_lattice_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the floating-point IIR lattice filter. + * @param[in] S points to an instance of the floating-point IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. + * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. + * @param[in] pState points to the state buffer. The array is of length numStages+blockSize-1. + * @param[in] blockSize number of samples to process. + */ +void csi_iir_lattice_init_f32( + csi_iir_lattice_instance_f32 * S, + uint16_t numStages, + float32_t * pkCoeffs, + float32_t * pvCoeffs, + float32_t * pState, + uint32_t blockSize); + + +/** + * @brief Processing function for the Q31 IIR lattice filter. + * @param[in] S points to an instance of the Q31 IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ +void csi_iir_lattice_q31( + const csi_iir_lattice_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the Q31 IIR lattice filter. + * @param[in] S points to an instance of the Q31 IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. + * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. + * @param[in] pState points to the state buffer. The array is of length numStages+blockSize. + * @param[in] blockSize number of samples to process. + */ +void csi_iir_lattice_init_q31( + csi_iir_lattice_instance_q31 * S, + uint16_t numStages, + q31_t * pkCoeffs, + q31_t * pvCoeffs, + q31_t * pState, + uint32_t blockSize); + + +/** + * @brief Processing function for the Q15 IIR lattice filter. + * @param[in] S points to an instance of the Q15 IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ +void csi_iir_lattice_q15( + const csi_iir_lattice_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the Q15 IIR lattice filter. + * @param[in] S points to an instance of the fixed-point Q15 IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] pkCoeffs points to reflection coefficient buffer. The array is of length numStages. + * @param[in] pvCoeffs points to ladder coefficient buffer. The array is of length numStages+1. + * @param[in] pState points to state buffer. The array is of length numStages+blockSize. + * @param[in] blockSize number of samples to process per call. + */ +void csi_iir_lattice_init_q15( + csi_iir_lattice_instance_q15 * S, + uint16_t numStages, + q15_t * pkCoeffs, + q15_t * pvCoeffs, + q15_t * pState, + uint32_t blockSize); + + +/** + * @brief Processing function for floating-point LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ +void csi_lms_f32( + const csi_lms_instance_f32 * S, + const float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + +/** + * @brief Initialization function for floating-point LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to the coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + */ +void csi_lms_init_f32( + csi_lms_instance_f32 * S, + uint16_t numTaps, + const float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + +/** + * @brief Initialization function for the Q15 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to the coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ +void csi_lms_init_q15( + csi_lms_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint32_t postShift); + + +/** + * @brief Processing function for Q15 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ +void csi_lms_q15( + const csi_lms_instance_q15 * S, + const q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + +/** + * @brief Processing function for Q31 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ +void csi_lms_q31( + const csi_lms_instance_q31 * S, + const q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + +/** + * @brief Initialization function for Q31 LMS filter. + * @param[in] S points to an instance of the Q31 LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ +void csi_lms_init_q31( + csi_lms_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint32_t postShift); + + +/** + * @brief Processing function for floating-point normalized LMS filter. + * @param[in] S points to an instance of the floating-point normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ +void csi_lms_norm_f32( + csi_lms_norm_instance_f32 * S, + const float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + +/** + * @brief Initialization function for floating-point normalized LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + */ +void csi_lms_norm_init_f32( + csi_lms_norm_instance_f32 * S, + uint16_t numTaps, + const float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + +/** + * @brief Processing function for Q31 normalized LMS filter. + * @param[in] S points to an instance of the Q31 normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ +void csi_lms_norm_q31( + csi_lms_norm_instance_q31 * S, + const q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + +/** + * @brief Initialization function for Q31 normalized LMS filter. + * @param[in] S points to an instance of the Q31 normalized LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ +void csi_lms_norm_init_q31( + csi_lms_norm_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint8_t postShift); + + +/** + * @brief Processing function for Q15 normalized LMS filter. + * @param[in] S points to an instance of the Q15 normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ +void csi_lms_norm_q15( + csi_lms_norm_instance_q15 * S, + const q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + +/** + * @brief Initialization function for Q15 normalized LMS filter. + * @param[in] S points to an instance of the Q15 normalized LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ +void csi_lms_norm_init_q15( + csi_lms_norm_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint8_t postShift); + + +/** + * @brief Correlation of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ +void csi_correlate_f32( + const float32_t * pSrcA, + uint32_t srcALen, + const float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + +/** + @brief Correlation of Q15 sequences + @param[in] pSrcA points to the first input sequence + @param[in] srcALen length of the first input sequence + @param[in] pSrcB points to the second input sequence + @param[in] srcBLen length of the second input sequence + @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. +*/ +void csi_correlate_opt_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + +/** + @brief Correlation of Q15 sequences. + @param[in] pSrcA points to the first input sequence + @param[in] srcALen length of the first input sequence + @param[in] pSrcB points to the second input sequence + @param[in] srcBLen length of the second input sequence + @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ +void csi_correlate_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + +/** + @brief Correlation of Q15 sequences (fast version). + @param[in] pSrcA points to the first input sequence + @param[in] srcALen length of the first input sequence + @param[in] pSrcB points to the second input sequence + @param[in] srcBLen length of the second input sequence + @param[out] pDst points to the location where the output result is written. Length 2 * max(srcALen, srcBLen) - 1. + @return none + */ +void csi_correlate_fast_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + +/** + @brief Correlation of Q15 sequences (fast version). + @param[in] pSrcA points to the first input sequence. + @param[in] srcALen length of the first input sequence. + @param[in] pSrcB points to the second input sequence. + @param[in] srcBLen length of the second input sequence. + @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + */ +void csi_correlate_fast_opt_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + +/** + * @brief Correlation of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ +void csi_correlate_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + +/** + @brief Correlation of Q31 sequences (fast version). + @param[in] pSrcA points to the first input sequence + @param[in] srcALen length of the first input sequence + @param[in] pSrcB points to the second input sequence + @param[in] srcBLen length of the second input sequence + @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ +void csi_correlate_fast_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + +/** + * @brief Correlation of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + */ +void csi_correlate_opt_q7( + const q7_t * pSrcA, + uint32_t srcALen, + const q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Correlation of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ +void csi_correlate_q7( + const q7_t * pSrcA, + uint32_t srcALen, + const q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + +/** + * @brief Processing function for the floating-point sparse FIR filter. + * @param[in] S points to an instance of the floating-point sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ +void csi_fir_sparse_f32( + csi_fir_sparse_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + float32_t * pScratchIn, + uint32_t blockSize); + + +/** + * @brief Initialization function for the floating-point sparse FIR filter. + * @param[in,out] S points to an instance of the floating-point sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ +void csi_fir_sparse_init_f32( + csi_fir_sparse_instance_f32 * S, + uint16_t numTaps, + const float32_t * pCoeffs, + float32_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + +/** + * @brief Processing function for the Q31 sparse FIR filter. + * @param[in] S points to an instance of the Q31 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ +void csi_fir_sparse_q31( + csi_fir_sparse_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + q31_t * pScratchIn, + uint32_t blockSize); + + +/** + * @brief Initialization function for the Q31 sparse FIR filter. + * @param[in,out] S points to an instance of the Q31 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ +void csi_fir_sparse_init_q31( + csi_fir_sparse_instance_q31 * S, + uint16_t numTaps, + const q31_t * pCoeffs, + q31_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + +/** + * @brief Processing function for the Q15 sparse FIR filter. + * @param[in] S points to an instance of the Q15 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] pScratchOut points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ +void csi_fir_sparse_q15( + csi_fir_sparse_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + q15_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + +/** + * @brief Initialization function for the Q15 sparse FIR filter. + * @param[in,out] S points to an instance of the Q15 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ +void csi_fir_sparse_init_q15( + csi_fir_sparse_instance_q15 * S, + uint16_t numTaps, + const q15_t * pCoeffs, + q15_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + +/** + * @brief Processing function for the Q7 sparse FIR filter. + * @param[in] S points to an instance of the Q7 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] pScratchOut points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ +void csi_fir_sparse_q7( + csi_fir_sparse_instance_q7 * S, + const q7_t * pSrc, + q7_t * pDst, + q7_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + +/** + * @brief Initialization function for the Q7 sparse FIR filter. + * @param[in,out] S points to an instance of the Q7 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ +void csi_fir_sparse_init_q7( + csi_fir_sparse_instance_q7 * S, + uint16_t numTaps, + const q7_t * pCoeffs, + q7_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + +/** + * @brief Floating-point sin_cos function. + * @param[in] theta input value in degrees + * @param[out] pSinVal points to the processed sine output. + * @param[out] pCosVal points to the processed cos output. + */ +void csi_sin_cos_f32( + float32_t theta, + float32_t * pSinVal, + float32_t * pCosVal); + + +/** + * @brief Q31 sin_cos function. + * @param[in] theta scaled input value in degrees + * @param[out] pSinVal points to the processed sine output. + * @param[out] pCosVal points to the processed cosine output. + */ +void csi_sin_cos_q31( + q31_t theta, + q31_t * pSinVal, + q31_t * pCosVal); + + +/** + * @brief Floating-point complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ +void csi_cmplx_conj_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + +/** + * @brief Q31 complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ +void csi_cmplx_conj_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + +/** + * @brief Q15 complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ +void csi_cmplx_conj_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + +/** + * @brief Floating-point complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ +void csi_cmplx_mag_squared_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + +/** + * @brief Q31 complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ +void csi_cmplx_mag_squared_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + +void csi_cmplx_mag_squared_q31_basic( + q31_t * pSrc, + q63_t * pDst, + uint32_t numSamples); + + +/** + * @brief Q15 complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ +void csi_cmplx_mag_squared_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + +/** + * @ingroup groupController + */ + +/** + * @defgroup PID PID Motor Control + * + * A Proportional Integral Derivative (PID) controller is a generic feedback control + * loop mechanism widely used in industrial control systems. + * A PID controller is the most commonly used type of feedback controller. + * + * This set of functions implements (PID) controllers + * for Q15, Q31, and floating-point data types. The functions operate on a single sample + * of data and each call to the function returns a single processed value. + * S points to an instance of the PID control data structure. in + * is the input sample value. The functions return the output value. + * + * \par Algorithm: + *
+ *    y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]
+ *    A0 = Kp + Ki + Kd
+ *    A1 = (-Kp ) - (2 * Kd )
+ *    A2 = Kd
+ * 
+ * + * \par + * where \c Kp is proportional constant, \c Ki is Integral constant and \c Kd is Derivative constant + * + * \par + * \image html PID.gif "Proportional Integral Derivative Controller" + * + * \par + * The PID controller calculates an "error" value as the difference between + * the measured output and the reference input. + * The controller attempts to minimize the error by adjusting the process control inputs. + * The proportional value determines the reaction to the current error, + * the integral value determines the reaction based on the sum of recent errors, + * and the derivative value determines the reaction based on the rate at which the error has been changing. + * + * \par Instance Structure + * The Gains A0, A1, A2 and state variables for a PID controller are stored together in an instance data structure. + * A separate instance structure must be defined for each PID Controller. + * There are separate instance structure declarations for each of the 3 supported data types. + * + * \par Reset Functions + * There is also an associated reset function for each data type which clears the state array. + * + * \par Initialization Functions + * There is also an associated initialization function for each data type. + * The initialization function performs the following operations: + * - Initializes the Gains A0, A1, A2 from Kp,Ki, Kd gains. + * - Zeros out the values in the state buffer. + * + * \par + * Instance structure cannot be placed into a const data section and it is recommended to use the initialization function. + * + * \par Fixed-Point Behavior + * Care must be taken when using the fixed-point versions of the PID Controller functions. + * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + +/** + * @addtogroup PID + * @{ + */ + +/** + * @brief Process function for the floating-point PID Control. + * @param[in,out] S is an instance of the floating-point PID Control structure + * @param[in] in input sample to process + * @return processed output sample. + */ +__STATIC_FORCEINLINE float32_t csi_pid_f32( + csi_pid_instance_f32 * S, + float32_t in) +{ + float32_t out; + /* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2] */ + out = (S->A0 * in) + + (S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]); + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + /* return to application */ + return (out); +} + +/** + @brief Process function for the Q31 PID Control. + @param[in,out] S points to an instance of the Q31 PID Control structure + @param[in] in input sample to process + @return processed output sample. + + \par Scaling and Overflow Behavior + The function is implemented using an internal 64-bit accumulator. + The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit. + Thus, if the accumulator result overflows it wraps around rather than clip. + In order to avoid overflows completely the input signal must be scaled down by 2 bits as there are four additions. + After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format. + */ +__STATIC_FORCEINLINE q31_t csi_pid_q31( + csi_pid_instance_q31 * S, + q31_t in) +{ + q63_t acc; + q31_t out; + /* acc = A0 * x[n] */ + acc = (q63_t) S->A0 * in; + /* acc += A1 * x[n-1] */ + acc += (q63_t) S->A1 * S->state[0]; + /* acc += A2 * x[n-2] */ + acc += (q63_t) S->A2 * S->state[1]; + /* convert output to 1.31 format to add y[n-1] */ + out = (q31_t) (acc >> 31U); + /* out += y[n-1] */ + out += S->state[2]; + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + /* return to application */ + return (out); +} + + +/** + @brief Process function for the Q15 PID Control. + @param[in,out] S points to an instance of the Q15 PID Control structure + @param[in] in input sample to process + @return processed output sample. + + \par Scaling and Overflow Behavior + The function is implemented using a 64-bit internal accumulator. + Both Gains and state variables are represented in 1.15 format and multiplications yield a 2.30 result. + The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format. + There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved. + After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits. + Lastly, the accumulator is saturated to yield a result in 1.15 format. + */ +__STATIC_FORCEINLINE q15_t csi_pid_q15( + csi_pid_instance_q15 * S, + q15_t in) +{ + q63_t acc; + q15_t out; +#if defined (CSI_MATH_DSP) + /* Implementation of PID controller */ + /* acc = A0 * x[n] */ + acc = (q31_t) __SMUAD((uint32_t)S->A0, (uint32_t)in); + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + acc = (q63_t)__SMLALD((uint32_t)S->A1, (uint32_t)read_q15x2 (S->state), (uint64_t)acc); +#else + /* acc = A0 * x[n] */ + acc = ((q31_t) S->A0) * in; + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + acc += (q31_t) S->A1 * S->state[0]; + acc += (q31_t) S->A2 * S->state[1]; +#endif + /* acc += y[n-1] */ + acc += (q31_t) S->state[2] << 15; + /* saturate the output */ + out = (q15_t) (__SSAT((q31_t)(acc >> 15), 16)); + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + /* return to application */ + return (out); +} + +/** + * @} end of PID group + */ + + +/** + * @brief Floating-point matrix inverse. + * @param[in] src points to the instance of the input floating-point matrix structure. + * @param[out] dst points to the instance of the output floating-point matrix structure. + * @return The function returns CSI_MATH_SIZE_MISMATCH, if the dimensions do not match. + * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status CSI_MATH_SINGULAR. + */ +csi_status csi_mat_inverse_f32( + const csi_matrix_instance_f32 * src, + csi_matrix_instance_f32 * dst); + + +/** + * @brief Floating-point matrix inverse. + * @param[in] src points to the instance of the input floating-point matrix structure. + * @param[out] dst points to the instance of the output floating-point matrix structure. + * @return The function returns CSI_MATH_SIZE_MISMATCH, if the dimensions do not match. + * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status CSI_MATH_SINGULAR. + */ +csi_status csi_mat_inverse_f64( + const csi_matrix_instance_f64 * src, + csi_matrix_instance_f64 * dst); + + + +/** + * @ingroup groupController + */ + +/** + * @defgroup clarke Vector Clarke Transform + * Forward Clarke transform converts the instantaneous stator phases into a two-coordinate time invariant vector. + * Generally the Clarke transform uses three-phase currents Ia, Ib and Ic to calculate currents + * in the two-phase orthogonal stator axis Ialpha and Ibeta. + * When Ialpha is superposed with Ia as shown in the figure below + * \image html clarke.gif Stator current space vector and its components in (a,b). + * and Ia + Ib + Ic = 0, in this condition Ialpha and Ibeta + * can be calculated using only Ia and Ib. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeFormula.gif + * where Ia and Ib are the instantaneous stator phases and + * pIalpha and pIbeta are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + +/** + * @addtogroup clarke + * @{ + */ + +/** + * + * @brief Floating-point Clarke transform + * @param[in] Ia input three-phase coordinate a + * @param[in] Ib input three-phase coordinate b + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + * @return none + */ +__STATIC_FORCEINLINE void csi_clarke_f32( + float32_t Ia, + float32_t Ib, + float32_t * pIalpha, + float32_t * pIbeta) +{ + /* Calculate pIalpha using the equation, pIalpha = Ia */ + *pIalpha = Ia; + /* Calculate pIbeta using the equation, pIbeta = (1/sqrt(3)) * Ia + (2/sqrt(3)) * Ib */ + *pIbeta = ((float32_t) 0.57735026919 * Ia + (float32_t) 1.15470053838 * Ib); +} + + +/** + @brief Clarke transform for Q31 version + @param[in] Ia input three-phase coordinate a + @param[in] Ib input three-phase coordinate b + @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + @param[out] pIbeta points to output two-phase orthogonal vector axis beta + @return none + + \par Scaling and Overflow Behavior + The function is implemented using an internal 32-bit accumulator. + The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + There is saturation on the addition, hence there is no risk of overflow. + */ +__STATIC_FORCEINLINE void csi_clarke_q31( + q31_t Ia, + q31_t Ib, + q31_t * pIalpha, + q31_t * pIbeta) +{ + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + /* Calculating pIalpha from Ia by equation pIalpha = Ia */ + *pIalpha = Ia; + /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) Ia * 0x24F34E8B) >> 30); + /* Intermediate product is calculated by (2/sqrt(3) * Ib) */ + product2 = (q31_t) (((q63_t) Ib * 0x49E69D16) >> 30); + /* pIbeta is calculated by adding the intermediate products */ + *pIbeta = __QADD(product1, product2); +} + +/** + * @} end of clarke group + */ + + +/** + * @ingroup groupController + */ + +/** + * @defgroup inv_clarke Vector Inverse Clarke Transform + * Inverse Clarke transform converts the two-coordinate time invariant vector into instantaneous stator phases. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeInvFormula.gif + * where pIa and pIb are the instantaneous stator phases and + * Ialpha and Ibeta are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + +/** + * @addtogroup inv_clarke + * @{ + */ + +/** +* @brief Floating-point Inverse Clarke transform +* @param[in] Ialpha input two-phase orthogonal vector axis alpha +* @param[in] Ibeta input two-phase orthogonal vector axis beta +* @param[out] pIa points to output three-phase coordinate a +* @param[out] pIb points to output three-phase coordinate b +* @return none +*/ +__STATIC_FORCEINLINE void csi_inv_clarke_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pIa, + float32_t * pIb) +{ + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + /* Calculating pIb from Ialpha and Ibeta by equation pIb = -(1/2) * Ialpha + (sqrt(3)/2) * Ibeta */ + *pIb = -0.5f * Ialpha + 0.8660254039f * Ibeta; +} + + +/** + @brief Inverse Clarke transform for Q31 version + @param[in] Ialpha input two-phase orthogonal vector axis alpha + @param[in] Ibeta input two-phase orthogonal vector axis beta + @param[out] pIa points to output three-phase coordinate a + @param[out] pIb points to output three-phase coordinate b + @return none + + \par Scaling and Overflow Behavior + The function is implemented using an internal 32-bit accumulator. + The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + There is saturation on the subtraction, hence there is no risk of overflow. + */ +__STATIC_FORCEINLINE void csi_inv_clarke_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pIa, + q31_t * pIb) +{ + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) (Ialpha) * (0x40000000)) >> 31); + /* Intermediate product is calculated by (1/sqrt(3) * pIb) */ + product2 = (q31_t) (((q63_t) (Ibeta) * (0x6ED9EBA1)) >> 31); + /* pIb is calculated by subtracting the products */ + *pIb = __QSUB(product2, product1); +} + +/** + * @} end of inv_clarke group + */ + + + +/** + * @ingroup groupController + */ + +/** + * @defgroup park Vector Park Transform + * + * Forward Park transform converts the input two-coordinate vector to flux and torque components. + * The Park transform can be used to realize the transformation of the Ialpha and the Ibeta currents + * from the stationary to the moving reference frame and control the spatial relationship between + * the stator vector current and rotor flux vector. + * If we consider the d axis aligned with the rotor flux, the diagram below shows the + * current vector and the relationship from the two reference frames: + * \image html park.gif "Stator current space vector and its component in (a,b) and in the d,q rotating reference frame" + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkFormula.gif + * where Ialpha and Ibeta are the stator vector components, + * pId and pIq are rotor vector components and cosVal and sinVal are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + +/** + * @addtogroup park + * @{ + */ + +/** + * @brief Floating-point Park transform + * @param[in] Ialpha input two-phase vector coordinate alpha + * @param[in] Ibeta input two-phase vector coordinate beta + * @param[out] pId points to output rotor reference frame d + * @param[out] pIq points to output rotor reference frame q + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * @return none + * + * The function implements the forward Park transform. + * + */ +__STATIC_FORCEINLINE void csi_park_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pId, + float32_t * pIq, + float32_t sinVal, + float32_t cosVal) +{ + /* Calculate pId using the equation, pId = Ialpha * cosVal + Ibeta * sinVal */ + *pId = Ialpha * cosVal + Ibeta * sinVal; + /* Calculate pIq using the equation, pIq = - Ialpha * sinVal + Ibeta * cosVal */ + *pIq = -Ialpha * sinVal + Ibeta * cosVal; +} + + +/** + @brief Park transform for Q31 version + @param[in] Ialpha input two-phase vector coordinate alpha + @param[in] Ibeta input two-phase vector coordinate beta + @param[out] pId points to output rotor reference frame d + @param[out] pIq points to output rotor reference frame q + @param[in] sinVal sine value of rotation angle theta + @param[in] cosVal cosine value of rotation angle theta + @return none + + \par Scaling and Overflow Behavior + The function is implemented using an internal 32-bit accumulator. + The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + There is saturation on the addition and subtraction, hence there is no risk of overflow. + */ +__STATIC_FORCEINLINE void csi_park_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pId, + q31_t * pIq, + q31_t sinVal, + q31_t cosVal) +{ +#ifdef CSI_SIMD + asm volatile( + "rmul.s32.h t0, %0, %3\n\t" + "rmul.s32.h t1, %1, %2\n\t" + "add.s32.s t0, t0, t1\n\t" + "st.w t0, (%4, 0x0)\n\t" + "rmul.s32.h t0, %0, %2\n\t" + "rmul.s32.h t1, %1, %3\n\t" + "sub.s32.s t1, t1, t0\n\t" + "st.w t1, (%5, 0x0)\n\t" + ::"r"(Ialpha),"r"(Ibeta),"r"(sinVal),"r"(cosVal),"r"(pId),"r"(pIq) + :"t0","t1", "memory"); +#else + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + /* Intermediate product is calculated by (Ialpha * cosVal) */ + product1 = (q31_t) (((q63_t) (Ialpha) * (cosVal)) >> 31); + /* Intermediate product is calculated by (Ibeta * sinVal) */ + product2 = (q31_t) (((q63_t) (Ibeta) * (sinVal)) >> 31); + /* Intermediate product is calculated by (Ialpha * sinVal) */ + product3 = (q31_t) (((q63_t) (Ialpha) * (sinVal)) >> 31); + /* Intermediate product is calculated by (Ibeta * cosVal) */ + product4 = (q31_t) (((q63_t) (Ibeta) * (cosVal)) >> 31); + /* Calculate pId by adding the two intermediate products 1 and 2 */ + *pId = __QADD(product1, product2); + /* Calculate pIq by subtracting the two intermediate products 3 from 4 */ + *pIq = __QSUB(product4, product3); +#endif +} + +/** + * @} end of park group + */ + + +/** + * @ingroup groupController + */ + +/** + * @defgroup inv_park Vector Inverse Park transform + * Inverse Park transform converts the input flux and torque components to two-coordinate vector. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkInvFormula.gif + * where pIalpha and pIbeta are the stator vector components, + * Id and Iq are rotor vector components and cosVal and sinVal are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + +/** + * @addtogroup inv_park + * @{ + */ + +/** +* @brief Floating-point Inverse Park transform +* @param[in] Id input coordinate of rotor reference frame d +* @param[in] Iq input coordinate of rotor reference frame q +* @param[out] pIalpha points to output two-phase orthogonal vector axis alpha +* @param[out] pIbeta points to output two-phase orthogonal vector axis beta +* @param[in] sinVal sine value of rotation angle theta +* @param[in] cosVal cosine value of rotation angle theta +* @return none +*/ +__STATIC_FORCEINLINE void csi_inv_park_f32( + float32_t Id, + float32_t Iq, + float32_t * pIalpha, + float32_t * pIbeta, + float32_t sinVal, + float32_t cosVal) +{ + /* Calculate pIalpha using the equation, pIalpha = Id * cosVal - Iq * sinVal */ + *pIalpha = Id * cosVal - Iq * sinVal; + /* Calculate pIbeta using the equation, pIbeta = Id * sinVal + Iq * cosVal */ + *pIbeta = Id * sinVal + Iq * cosVal; +} + + +/** + @brief Inverse Park transform for Q31 version + @param[in] Id input coordinate of rotor reference frame d + @param[in] Iq input coordinate of rotor reference frame q + @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + @param[out] pIbeta points to output two-phase orthogonal vector axis beta + @param[in] sinVal sine value of rotation angle theta + @param[in] cosVal cosine value of rotation angle theta + @return none + + @par Scaling and Overflow Behavior + The function is implemented using an internal 32-bit accumulator. + The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + There is saturation on the addition, hence there is no risk of overflow. + */ +__STATIC_FORCEINLINE void csi_inv_park_q31( + q31_t Id, + q31_t Iq, + q31_t * pIalpha, + q31_t * pIbeta, + q31_t sinVal, + q31_t cosVal) +{ +#ifdef CSI_SIMD + asm volatile( + "rmul.s32.h t0, %0, %3\n\t" + "rmul.s32.h t1, %1, %2\n\t" + "sub.s32.s t0, t0, t1\n\t" + "st.w t0, (%4, 0x0)\n\t" + "rmul.s32.h t0, %0, %2\n\t" + "rmul.s32.h t1, %1, %3\n\t" + "add.s32.s t0, t0, t1\n\t" + "st.w t0, (%5, 0x0)\n\t" + ::"r"(Id),"r"(Iq),"r"(sinVal),"r"(cosVal),"r"(pIalpha),"r"(pIbeta) + :"t0","t1", "memory"); +#else + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + /* Intermediate product is calculated by (Id * cosVal) */ + product1 = (q31_t) (((q63_t) (Id) * (cosVal)) >> 31); + /* Intermediate product is calculated by (Iq * sinVal) */ + product2 = (q31_t) (((q63_t) (Iq) * (sinVal)) >> 31); + /* Intermediate product is calculated by (Id * sinVal) */ + product3 = (q31_t) (((q63_t) (Id) * (sinVal)) >> 31); + /* Intermediate product is calculated by (Iq * cosVal) */ + product4 = (q31_t) (((q63_t) (Iq) * (cosVal)) >> 31); + /* Calculate pIalpha by using the two intermediate products 1 and 2 */ + *pIalpha = __QSUB(product1, product2); + /* Calculate pIbeta by using the two intermediate products 3 and 4 */ + *pIbeta = __QADD(product4, product3); +#endif +} + +/** + * @} end of Inverse park group + */ + + +/** + * @ingroup groupInterpolation + */ + +/** + * @defgroup LinearInterpolate Linear Interpolation + * + * Linear interpolation is a method of curve fitting using linear polynomials. + * Linear interpolation works by effectively drawing a straight line between two neighboring samples and returning the appropriate point along that line + * + * \par + * \image html LinearInterp.gif "Linear interpolation" + * + * \par + * A Linear Interpolate function calculates an output value(y), for the input(x) + * using linear interpolation of the input values x0, x1( nearest input values) and the output values y0 and y1(nearest output values) + * + * \par Algorithm: + *
+ *       y = y0 + (x - x0) * ((y1 - y0)/(x1-x0))
+ *       where x0, x1 are nearest values of input x
+ *             y0, y1 are nearest values to output y
+ * 
+ * + * \par + * This set of functions implements Linear interpolation process + * for Q7, Q15, Q31, and floating-point data types. The functions operate on a single + * sample of data and each call to the function returns a single processed value. + * S points to an instance of the Linear Interpolate function data structure. + * x is the input sample value. The functions returns the output value. + * + * \par + * if x is outside of the table boundary, Linear interpolation returns first value of the table + * if x is below input range and returns last value of table if x is above range. + */ + +/** + * @addtogroup LinearInterpolate + * @{ + */ + +/** + * @brief Process function for the floating-point Linear Interpolation Function. + * @param[in,out] S is an instance of the floating-point Linear Interpolation structure + * @param[in] x input sample to process + * @return y processed output sample. + * + */ +__STATIC_FORCEINLINE float32_t csi_linear_interp_f32( + csi_linear_interp_instance_f32 * S, + float32_t x) +{ + float32_t y; + float32_t x0, x1; /* Nearest input values */ + float32_t y0, y1; /* Nearest output values */ + float32_t xSpacing = S->xSpacing; /* spacing between input values */ + int32_t i; /* Index variable */ + float32_t *pYData = S->pYData; /* pointer to output table */ + /* Calculation of index */ + i = (int32_t) ((x - S->x1) / xSpacing); + + if (i < 0) { + /* Iniatilize output for below specified range as least output value of table */ + y = pYData[0]; + + } else if ((uint32_t)i >= (S->nValues - 1)) { + /* Iniatilize output for above specified range as last output value of table */ + y = pYData[S->nValues - 1]; + + } else { + /* Calculation of nearest input values */ + x0 = S->x1 + i * xSpacing; + x1 = S->x1 + (i + 1) * xSpacing; + /* Read of nearest output values */ + y0 = pYData[i]; + y1 = pYData[i + 1]; + /* Calculation of output */ + y = y0 + (x - x0) * ((y1 - y0) / (x1 - x0)); + } + + /* returns output value */ + return (y); +} + + +/** +* +* @brief Process function for the Q31 Linear Interpolation Function. +* @param[in] pYData pointer to Q31 Linear Interpolation table +* @param[in] x input sample to process +* @param[in] nValues number of table values +* @return y processed output sample. +* +* \par +* Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. +* This function can support maximum of table size 2^12. +* +*/ +__STATIC_FORCEINLINE q31_t csi_linear_interp_q31( + q31_t * pYData, + q31_t x, + uint32_t nValues) +{ + q31_t y; /* output */ + q31_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & (q31_t)0xFFF00000) >> 20); + + if (index >= (int32_t)(nValues - 1)) { + return (pYData[nValues - 1]); + + } else if (index < 0) { + return (pYData[0]); + + } else { + /* 20 bits for the fractional part */ + /* shift left by 11 to keep fract in 1.31 format */ + fract = (x & 0x000FFFFF) << 11; + /* Read two nearest output values from the index in 1.31(q31) format */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + /* Calculation of y0 * (1-fract) and y is in 2.30 format */ + y = ((q31_t) ((q63_t) y0 * (0x7FFFFFFF - fract) >> 32)); + /* Calculation of y0 * (1-fract) + y1 *fract and y is in 2.30 format */ + y += ((q31_t) (((q63_t) y1 * fract) >> 32)); + /* Convert y to 1.31 format */ + return (y << 1U); + } +} + + +/** + * + * @brief Process function for the Q15 Linear Interpolation Function. + * @param[in] pYData pointer to Q15 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ +__STATIC_FORCEINLINE q15_t csi_linear_interp_q15( + q15_t * pYData, + q31_t x, + uint32_t nValues) +{ + q63_t y; /* output */ + q15_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & (int32_t)0xFFF00000) >> 20); + + if (index >= (int32_t)(nValues - 1)) { + return (pYData[nValues - 1]); + + } else if (index < 0) { + return (pYData[0]); + + } else { + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + /* Read two nearest output values from the index */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + /* Calculation of y0 * (1-fract) and y is in 13.35 format */ + y = ((q63_t) y0 * (0xFFFFF - fract)); + /* Calculation of (y0 * (1-fract) + y1 * fract) and y is in 13.35 format */ + y += ((q63_t) y1 * (fract)); + /* convert y to 1.15 format */ + return (q15_t) (y >> 20); + } +} + + +/** + * + * @brief Process function for the Q7 Linear Interpolation Function. + * @param[in] pYData pointer to Q7 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + */ +__STATIC_FORCEINLINE q7_t csi_linear_interp_q7( + q7_t * pYData, + q31_t x, + uint32_t nValues) +{ + q31_t y; /* output */ + q7_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + uint32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + if (x < 0) { + return (pYData[0]); + } + + index = (x >> 20) & 0xfff; + + if (index >= (nValues - 1)) { + return (pYData[nValues - 1]); + + } else { + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + /* Read two nearest output values from the index and are in 1.7(q7) format */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + /* Calculation of y0 * (1-fract ) and y is in 13.27(q27) format */ + y = ((y0 * (0xFFFFF - fract))); + /* Calculation of y1 * fract + y0 * (1-fract) and y is in 13.27(q27) format */ + y += (y1 * fract); + /* convert y to 1.7(q7) format */ + return (q7_t) (y >> 20); + } +} + +/** + * @} end of LinearInterpolate group + */ + +/** + * @brief Fast approximation to the trigonometric sine function for floating-point data. + * @param[in] x input value in radians. + * @return sin(x). + */ +float32_t csi_sin_f32( + float32_t x); + + +/** + * @brief Fast approximation to the trigonometric sine function for Q31 data. + * @param[in] x Scaled input value in radians. + * @return sin(x). + */ +q31_t csi_sin_q31( + q31_t x); + + +/** + * @brief Fast approximation to the trigonometric sine function for Q15 data. + * @param[in] x Scaled input value in radians. + * @return sin(x). + */ +q15_t csi_sin_q15( + q15_t x); + + +/** + * @brief Fast approximation to the trigonometric cosine function for floating-point data. + * @param[in] x input value in radians. + * @return cos(x). + */ +float32_t csi_cos_f32( + float32_t x); + + +/** + * @brief Fast approximation to the trigonometric cosine function for Q31 data. + * @param[in] x Scaled input value in radians. + * @return cos(x). + */ +q31_t csi_cos_q31( + q31_t x); + + +/** + * @brief Fast approximation to the trigonometric cosine function for Q15 data. + * @param[in] x Scaled input value in radians. + * @return cos(x). + */ +q15_t csi_cos_q15( + q15_t x); + + +/** + @brief Floating-point vector of log values. + @param[in] pSrc points to the input vector + @param[out] pDst points to the output vector + @param[in] blockSize number of samples in each vector + @return none + */ +void csi_vlog_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + +/** + @brief Floating-point vector of exp values. + @param[in] pSrc points to the input vector + @param[out] pDst points to the output vector + @param[in] blockSize number of samples in each vector + @return none + */ +void csi_vexp_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + +/** + * @ingroup groupFastMath + */ + + +/** + * @defgroup SQRT Square Root + * + * Computes the square root of a number. + * There are separate functions for Q15, Q31, and floating-point data types. + * The square root function is computed using the Newton-Raphson algorithm. + * This is an iterative algorithm of the form: + *
+ *      x1 = x0 - f(x0)/f'(x0)
+ * 
+ * where x1 is the current estimate, + * x0 is the previous estimate, and + * f'(x0) is the derivative of f() evaluated at x0. + * For the square root function, the algorithm reduces to: + *
+ *     x0 = in/2                         [initial guess]
+ *     x1 = 1/2 * ( x0 + in / x0)        [each iteration]
+ * 
+ */ + + +/** + * @addtogroup SQRT + * @{ + */ + +/** + @brief Q15 square root function. + @param[in] in input value. The range of the input value is [0 +1) or 0x0000 to 0x7FFF + @param[out] pOut points to square root of input value + @return execution status + - \ref CSI_MATH_SUCCESS : input value is positive + - \ref CSI_MATH_ARGUMENT_ERROR : input value is negative; *pOut is set to 0 + */ +csi_status csi_sqrt_q15( + q15_t in, + q15_t * pOut); + +/** + @brief Floating-point square root function. + @param[in] in input value + @param[out] pOut square root of input value + @return execution status + - \ref CSI_MATH_SUCCESS : input value is positive + - \ref CSI_MATH_ARGUMENT_ERROR : input value is negative; *pOut is set to 0 + */ +#ifdef __riscv +__STATIC_FORCEINLINE csi_status csi_sqrt_f32( + float32_t in, + float32_t * pOut) +{ + if (in >= 0.0f) { +#ifdef CSI_NEWTON_SQRTF + float32_t eps = 0.000000011; + float32_t val = in / 2; + float32_t last; + + if (in <= eps) { + *pOut = 0.0f; + } else { + do { + last = val; + val = (val + in / val) / 2; + } while (fabsf(val - last) > eps); + *pOut = val; + } +#else + *pOut = sqrtf(in); +#endif + return (CSI_MATH_SUCCESS); + } else { + *pOut = 0.0f; + return (CSI_MATH_ARGUMENT_ERROR); + } +} +#else +csi_status csi_sqrt_f32( + float32_t in, + float32_t * pOut); +#endif + + +/** + @brief Q31 square root function. + @param[in] in input value. The range of the input value is [0 +1) or 0x00000000 to 0x7FFFFFFF + @param[out] pOut points to square root of input value + @return execution status + - \ref CSI_MATH_SUCCESS : input value is positive + - \ref CSI_MATH_ARGUMENT_ERROR : input value is negative; *pOut is set to 0 + */ +csi_status csi_sqrt_q31( + q31_t in, + q31_t * pOut); + +/** + * @brief Vector Floating-point square root function. + * @param[in] pIn input vector. + * @param[out] pOut vector of square roots of input elements. + * @param[in] len length of input vector. + * @return The function returns CSI_MATH_SUCCESS if input value is positive value or CSI_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ +#ifdef __csky__ + +void csi_vsqrt_f32( + float32_t * pIn, + float32_t * pOut, + uint16_t len); + + void csi_vsqrt_q15( + q15_t * pIn, + q15_t * pOut, + uint16_t len); + +void csi_vsqrt_q31( + q31_t * pIn, + q31_t * pOut, + uint16_t len); + +void csi_vsqrt_q7( + q7_t * pIn, + q7_t * pOut, + uint16_t len); + + +#else +__STATIC_FORCEINLINE void csi_vsqrt_f32( + float32_t * pIn, + float32_t * pOut, + uint16_t len) +{ + for (int i = 0; i < len; i++) { + csi_sqrt_f32(pIn[i], pOut + i); + } +} + +__STATIC_FORCEINLINE void csi_vsqrt_q15( + q15_t * pIn, + q15_t * pOut, + uint16_t len +) +{ + for (int i = 0; i < len; i++) { + csi_sqrt_q15(pIn[i], pOut + i); + } +} +__STATIC_FORCEINLINE void csi_vsqrt_q31( + q31_t * pIn, + q31_t * pOut, + uint16_t len +) +{ + for (int i = 0; i < len; i++) { + csi_sqrt_q31(pIn[i], pOut + i); + } +} +#endif +/** + * @} end of SQRT group + */ + +/** + * @brief floating-point Circular write function. + a*/ +#ifndef __csky__ +__STATIC_FORCEINLINE void csi_circularWrite_f32( + int32_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const int32_t * src, + int32_t srcInc, + uint32_t blockSize) +{ + uint32_t i = 0U; + int32_t wOffset; + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + /* Update the input pointer */ + src += srcInc; + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + + if (wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; +} + + + +/** + * @brief floating-point Circular Read function. + */ +__STATIC_FORCEINLINE void csi_circularRead_f32( + int32_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + int32_t * dst, + int32_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) +{ + uint32_t i = 0U; + int32_t rOffset; + int32_t* dst_end; + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + dst_end = dst_base + dst_length; + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + /* Update the input pointer */ + dst += dstInc; + + if (dst == dst_end) { + dst = dst_base; + } + + /* Circularly update rOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if (rOffset >= L) { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; +} +#endif +/** + * @brief Sum of the squares of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ +void csi_power_q31( + const q31_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + +void csi_power_int32( + int32_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + +/** + * @brief Sum of the squares of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ +void csi_power_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + +/** + * @brief Sum of the squares of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ +void csi_power_q15( + const q15_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + +/** + * @brief Sum of the squares of the elements of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ +void csi_power_q7( + const q7_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + +/** + * @brief Mean value of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ +void csi_mean_q7( + const q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult); + + +/** + * @brief Mean value of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ +void csi_mean_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + +/** + * @brief Mean value of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ +void csi_mean_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + +/** + * @brief Mean value of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ +void csi_mean_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + +/** + * @brief Variance of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ +void csi_var_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + +/** + * @brief Variance of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ +void csi_var_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + +/** + * @brief Variance of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ +void csi_var_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + +/** + * @brief Root Mean Square of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ +void csi_rms_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + +/** + * @brief Root Mean Square of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ +void csi_rms_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + +/** + * @brief Root Mean Square of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ +void csi_rms_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + +/** + * @brief Standard deviation of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ +void csi_std_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + +/** + * @brief Standard deviation of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ +void csi_std_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + +/** + * @brief Standard deviation of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ +void csi_std_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + +/** + * @brief Floating-point complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ +void csi_cmplx_mag_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + +/** + * @brief Q31 complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ +void csi_cmplx_mag_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + +/** + * @brief Q15 complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ +void csi_cmplx_mag_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + +/** + * @brief Q15 complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ +void csi_cmplx_dot_prod_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + uint32_t numSamples, + q31_t * realResult, + q31_t * imagResult); + + +/** + * @brief Q31 complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ +void csi_cmplx_dot_prod_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + uint32_t numSamples, + q63_t * realResult, + q63_t * imagResult); + + void csi_dot_prod_u64xu8( + uint8_t * pSrcA, + uint64_t * pSrcB, + uint32_t blockSize, + uint64_t * result); + +/** + * @brief Floating-point complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ +void csi_cmplx_dot_prod_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + uint32_t numSamples, + float32_t * realResult, + float32_t * imagResult); + + +/** + * @brief Q15 complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ +void csi_cmplx_mult_real_q15( + const q15_t * pSrcCmplx, + const q15_t * pSrcReal, + q15_t * pCmplxDst, + uint32_t numSamples); + + +/** + * @brief Q31 complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ +void csi_cmplx_mult_real_q31( + const q31_t * pSrcCmplx, + const q31_t * pSrcReal, + q31_t * pCmplxDst, + uint32_t numSamples); + + +/** + * @brief Floating-point complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ +void csi_cmplx_mult_real_f32( + const float32_t * pSrcCmplx, + const float32_t * pSrcReal, + float32_t * pCmplxDst, + uint32_t numSamples); + + +/** + * @brief Minimum value of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] result is output pointer + * @param[in] index is the array index of the minimum value in the input buffer. + */ +void csi_min_q7( + const q7_t * pSrc, + uint16_t blockSize, + q7_t * result, + uint16_t * index); + + +/** + * @brief Minimum value of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[in] pIndex is the array index of the minimum value in the input buffer. + */ +void csi_min_q15( + const q15_t * pSrc, + uint16_t blockSize, + q15_t * pResult, + uint16_t * pIndex); + + +/** + * @brief Minimum value of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[out] pIndex is the array index of the minimum value in the input buffer. + */ +void csi_min_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Minimum value of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[out] pIndex is the array index of the minimum value in the input buffer. + */ +void csi_min_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q7 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ +void csi_max_q7( + const q7_t * pSrc, + uint16_t blockSize, + q7_t * pResult, + uint16_t * pIndex); + + +/** + * @brief Maximum value of a Q15 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ +void csi_max_q15( + const q15_t * pSrc, + uint16_t blockSize, + q15_t * pResult, + uint16_t * pIndex); + + +/** + * @brief Maximum value of a Q31 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ +void csi_max_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a floating-point vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ +void csi_max_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + +/** + @brief Maximum value of a floating-point vector. + @param[in] pSrc points to the input vector + @param[in] blockSize number of samples in input vector + @param[out] pResult maximum value returned here + @return none + */ +void csi_max_no_idx_f32( + const float32_t *pSrc, + uint32_t blockSize, + float32_t *pResult); + +/** + * @brief Q15 complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ +void csi_cmplx_mult_cmplx_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + q15_t * pDst, + uint32_t numSamples); + + +/** + * @brief Q31 complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ +void csi_cmplx_mult_cmplx_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + q31_t * pDst, + uint32_t numSamples); + + +/** + * @brief Floating-point complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ +void csi_cmplx_mult_cmplx_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + float32_t * pDst, + uint32_t numSamples); + +void csi_cmplx_mult_cmplx_re_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + float32_t * pDst, + uint32_t numSamples); + + +/** + * @brief Converts the elements of the floating-point vector to Q31 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q31 output vector + * @param[in] blockSize length of the input vector + */ +void csi_float_to_q31( + const float32_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Converts the elements of the floating-point vector to Q15 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q15 output vector + * @param[in] blockSize length of the input vector + */ +void csi_float_to_q15( + const float32_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + +/** + * @brief Converts the elements of the floating-point vector to Q7 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q7 output vector + * @param[in] blockSize length of the input vector + */ +void csi_float_to_q7( + const float32_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + +/** + * @brief Converts the elements of the Q31 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ +void csi_q31_to_float( + const q31_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + +/** + * @brief Converts the elements of the Q31 vector to Q15 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ +void csi_q31_to_q15( + const q31_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + +void csi_q31_to_q7_rs( + q31_t * pSrc, + q7_t * pDst, + uint32_t shiftValue, + uint32_t blockSize); + +void csi_q63_to_q31_rs( + q63_t * pSrc, + q31_t * pDst, + uint32_t shiftValue, + uint32_t blockSize); + + +/** + * @brief Converts the elements of the Q31 vector to Q7 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ +void csi_q31_to_q7( + const q31_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + +/** + * @brief Converts the elements of the Q15 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ +void csi_q15_to_float( + const q15_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + +/** + * @brief Converts the elements of the Q15 vector to Q31 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ +void csi_q15_to_q31( + const q15_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Converts the elements of the Q15 vector to Q7 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ +void csi_q15_to_q7( + const q15_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + +/** + * @brief Converts the elements of the Q7 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ +void csi_q7_to_float( + const q7_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + +/** + * @brief Converts the elements of the Q7 vector to Q31 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ +void csi_q7_to_q31( + const q7_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Converts the elements of the Q7 vector to Q15 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ +void csi_q7_to_q15( + const q7_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + +/** + * @brief SVM linear instance init function + * @param[in] S Parameters for SVM functions + * @param[in] nbOfSupportVectors Number of support vectors + * @param[in] vectorDimension Dimension of vector space + * @param[in] intercept Intercept + * @param[in] dualCoefficients Array of dual coefficients + * @param[in] supportVectors Array of support vectors + * @param[in] classes Array of 2 classes ID + * @return none. + * + */ + + +void csi_svm_linear_init_f32(csi_svm_linear_instance_f32 *S, + uint32_t nbOfSupportVectors, + uint32_t vectorDimension, + float32_t intercept, + const float32_t *dualCoefficients, + const float32_t *supportVectors, + const int32_t *classes); + +/** + * @brief SVM linear prediction + * @param[in] S Pointer to an instance of the linear SVM structure. + * @param[in] in Pointer to input vector + * @param[out] pResult Decision value + * @return none. + * + */ + +void csi_svm_linear_predict_f32(const csi_svm_linear_instance_f32 *S, + const float32_t * in, + int32_t * pResult); + + +/** + * @brief SVM polynomial instance init function + * @param[in] S points to an instance of the polynomial SVM structure. + * @param[in] nbOfSupportVectors Number of support vectors + * @param[in] vectorDimension Dimension of vector space + * @param[in] intercept Intercept + * @param[in] dualCoefficients Array of dual coefficients + * @param[in] supportVectors Array of support vectors + * @param[in] classes Array of 2 classes ID + * @param[in] degree Polynomial degree + * @param[in] coef0 coeff0 (scikit-learn terminology) + * @param[in] gamma gamma (scikit-learn terminology) + * @return none. + * + */ + + +void csi_svm_polynomial_init_f32(csi_svm_polynomial_instance_f32 *S, + uint32_t nbOfSupportVectors, + uint32_t vectorDimension, + float32_t intercept, + const float32_t *dualCoefficients, + const float32_t *supportVectors, + const int32_t *classes, + int32_t degree, + float32_t coef0, + float32_t gamma + ); + +/** + * @brief SVM polynomial prediction + * @param[in] S Pointer to an instance of the polynomial SVM structure. + * @param[in] in Pointer to input vector + * @param[out] pResult Decision value + * @return none. + * + */ +void csi_svm_polynomial_predict_f32(const csi_svm_polynomial_instance_f32 *S, + const float32_t * in, + int32_t * pResult); + + +/** + * @brief SVM radial basis function instance init function + * @param[in] S points to an instance of the polynomial SVM structure. + * @param[in] nbOfSupportVectors Number of support vectors + * @param[in] vectorDimension Dimension of vector space + * @param[in] intercept Intercept + * @param[in] dualCoefficients Array of dual coefficients + * @param[in] supportVectors Array of support vectors + * @param[in] classes Array of 2 classes ID + * @param[in] gamma gamma (scikit-learn terminology) + * @return none. + * + */ + +void csi_svm_rbf_init_f32(csi_svm_rbf_instance_f32 *S, + uint32_t nbOfSupportVectors, + uint32_t vectorDimension, + float32_t intercept, + const float32_t *dualCoefficients, + const float32_t *supportVectors, + const int32_t *classes, + float32_t gamma + ); + +/** + * @brief SVM rbf prediction + * @param[in] S Pointer to an instance of the rbf SVM structure. + * @param[in] in Pointer to input vector + * @param[out] pResult decision value + * @return none. + * + */ +void csi_svm_rbf_predict_f32(const csi_svm_rbf_instance_f32 *S, + const float32_t * in, + int32_t * pResult); + +/** + * @brief SVM sigmoid instance init function + * @param[in] S points to an instance of the rbf SVM structure. + * @param[in] nbOfSupportVectors Number of support vectors + * @param[in] vectorDimension Dimension of vector space + * @param[in] intercept Intercept + * @param[in] dualCoefficients Array of dual coefficients + * @param[in] supportVectors Array of support vectors + * @param[in] classes Array of 2 classes ID + * @param[in] coef0 coeff0 (scikit-learn terminology) + * @param[in] gamma gamma (scikit-learn terminology) + * @return none. + * + */ + +void csi_svm_sigmoid_init_f32(csi_svm_sigmoid_instance_f32 *S, + uint32_t nbOfSupportVectors, + uint32_t vectorDimension, + float32_t intercept, + const float32_t *dualCoefficients, + const float32_t *supportVectors, + const int32_t *classes, + float32_t coef0, + float32_t gamma + ); + +/** + * @brief SVM sigmoid prediction + * @param[in] S Pointer to an instance of the rbf SVM structure. + * @param[in] in Pointer to input vector + * @param[out] pResult Decision value + * @return none. + * + */ +void csi_svm_sigmoid_predict_f32(const csi_svm_sigmoid_instance_f32 *S, + const float32_t * in, + int32_t * pResult); + + +/** + * @brief Naive Gaussian Bayesian Estimator + * + * @param[in] S points to a naive bayes instance structure + * @param[in] in points to the elements of the input vector. + * @param[in] pBuffer points to a buffer of length numberOfClasses + * @return The predicted class + * + */ + + +uint32_t csi_gaussian_naive_bayes_predict_f32(const csi_gaussian_naive_bayes_instance_f32 *S, + const float32_t * in, + float32_t *pBuffer); + +/** + * @brief Computation of the LogSumExp + * + * In probabilistic computations, the dynamic of the probability values can be very + * wide because they come from gaussian functions. + * To avoid underflow and overflow issues, the values are represented by their log. + * In this representation, multiplying the original exp values is easy : their logs are added. + * But adding the original exp values is requiring some special handling and it is the + * goal of the LogSumExp function. + * + * If the values are x1...xn, the function is computing: + * + * ln(exp(x1) + ... + exp(xn)) and the computation is done in such a way that + * rounding issues are minimised. + * + * The max xm of the values is extracted and the function is computing: + * xm + ln(exp(x1 - xm) + ... + exp(xn - xm)) + * + * @param[in] *in Pointer to an array of input values. + * @param[in] blockSize Number of samples in the input array. + * @return LogSumExp + * + */ + + +float32_t csi_logsumexp_f32(const float32_t *in, uint32_t blockSize); + +/** + * @brief Dot product with log arithmetic + * + * Vectors are containing the log of the samples + * + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[in] pTmpBuffer temporary buffer of length blockSize + * @return The log of the dot product . + * + */ + + +float32_t csi_logsumexp_dot_prod_f32(const float32_t * pSrcA, + const float32_t * pSrcB, + uint32_t blockSize, + float32_t *pTmpBuffer); + +/** + * @brief Entropy + * + * @param[in] pSrcA Array of input values. + * @param[in] blockSize Number of samples in the input array. + * @return Entropy -Sum(p ln p) + * + */ + + +float32_t csi_entropy_f32(const float32_t * pSrcA,uint32_t blockSize); + + +/** + * @brief Kullback-Leibler + * + * @param[in] pSrcA Pointer to an array of input values for probability distribution A. + * @param[in] pSrcB Pointer to an array of input values for probability distribution B. + * @param[in] blockSize Number of samples in the input array. + * @return Kullback-Leibler Divergence D(A || B) + * + */ +float32_t csi_kullback_leibler_f32(const float32_t * pSrcA + ,const float32_t * pSrcB + ,uint32_t blockSize); + + +/** + * @brief Weighted sum + * + * + * @param[in] *in Array of input values. + * @param[in] *weigths Weights + * @param[in] blockSize Number of samples in the input array. + * @return Weighted sum + * + */ +float32_t csi_weighted_sum_f32(const float32_t *in + , const float32_t *weigths + , uint32_t blockSize); + + +/** + * @brief Barycenter + * + * + * @param[in] in List of vectors + * @param[in] weights Weights of the vectors + * @param[out] out Barycenter + * @param[in] nbVectors Number of vectors + * @param[in] vecDim Dimension of space (vector dimension) + * @return None + * + */ +void csi_barycenter_f32(const float32_t *in + , const float32_t *weights + , float32_t *out + , uint32_t nbVectors + , uint32_t vecDim); + +/** + * @brief Euclidean distance between two vectors + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] blockSize vector length + * @return distance + * + */ + +float32_t csi_euclidean_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize); + +/** + * @brief Bray-Curtis distance between two vectors + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] blockSize vector length + * @return distance + * + */ +float32_t csi_braycurtis_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize); + +/** + * @brief Canberra distance between two vectors + * + * This function may divide by zero when samples pA[i] and pB[i] are both zero. + * The result of the computation will be correct. So the division per zero may be + * ignored. + * + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] blockSize vector length + * @return distance + * + */ +float32_t csi_canberra_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize); + + +/** + * @brief Chebyshev distance between two vectors + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] blockSize vector length + * @return distance + * + */ +float32_t csi_chebyshev_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize); + + +/** + * @brief Cityblock (Manhattan) distance between two vectors + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] blockSize vector length + * @return distance + * + */ +float32_t csi_cityblock_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize); + +/** + * @brief Correlation distance between two vectors + * + * The input vectors are modified in place ! + * + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] blockSize vector length + * @return distance + * + */ +float32_t csi_correlation_distance_f32(float32_t *pA,float32_t *pB, uint32_t blockSize); + +/** + * @brief Cosine distance between two vectors + * + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] blockSize vector length + * @return distance + * + */ + +float32_t csi_cosine_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize); + +/** + * @brief Jensen-Shannon distance between two vectors + * + * This function is assuming that elements of second vector are > 0 + * and 0 only when the corresponding element of first vector is 0. + * Otherwise the result of the computation does not make sense + * and for speed reasons, the cases returning NaN or Infinity are not + * managed. + * + * When the function is computing x log (x / y) with x 0 and y 0, + * it will compute the right value (0) but a division per zero will occur + * and shoudl be ignored in client code. + * + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] blockSize vector length + * @return distance + * + */ + +float32_t csi_jensenshannon_distance_f32(const float32_t *pA,const float32_t *pB,uint32_t blockSize); + +/** + * @brief Minkowski distance between two vectors + * + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] n Norm order (>= 2) + * @param[in] blockSize vector length + * @return distance + * + */ + + + +float32_t csi_minkowski_distance_f32(const float32_t *pA,const float32_t *pB, int32_t order, uint32_t blockSize); + +/** + * @brief Dice distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] order Distance order + * @param[in] blockSize Number of samples + * @return distance + * + */ + + +float32_t csi_dice_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + +/** + * @brief Hamming distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] numberOfBools Number of booleans + * @return distance + * + */ + +float32_t csi_hamming_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + +/** + * @brief Jaccard distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] numberOfBools Number of booleans + * @return distance + * + */ + +float32_t csi_jaccard_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + +/** + * @brief Kulsinski distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] numberOfBools Number of booleans + * @return distance + * + */ + +float32_t csi_kulsinski_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + +/** + * @brief Roger Stanimoto distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] numberOfBools Number of booleans + * @return distance + * + */ + +float32_t csi_rogerstanimoto_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + +/** + * @brief Russell-Rao distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] numberOfBools Number of booleans + * @return distance + * + */ + +float32_t csi_russellrao_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + +/** + * @brief Sokal-Michener distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] numberOfBools Number of booleans + * @return distance + * + */ + +float32_t csi_sokalmichener_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + +/** + * @brief Sokal-Sneath distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] numberOfBools Number of booleans + * @return distance + * + */ + +float32_t csi_sokalsneath_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + +/** + * @brief Yule distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] numberOfBools Number of booleans + * @return distance + * + */ + +float32_t csi_yule_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + + +/** + * @ingroup groupInterpolation + */ + +/** + * @defgroup BilinearInterpolate Bilinear Interpolation + * + * Bilinear interpolation is an extension of linear interpolation applied to a two dimensional grid. + * The underlying function f(x, y) is sampled on a regular grid and the interpolation process + * determines values between the grid points. + * Bilinear interpolation is equivalent to two step linear interpolation, first in the x-dimension and then in the y-dimension. + * Bilinear interpolation is often used in image processing to rescale images. + * The library provides bilinear interpolation functions for Q7, Q15, Q31, and floating-point data types. + * + * Algorithm + * \par + * The instance structure used by the bilinear interpolation functions describes a two dimensional data table. + * For floating-point, the instance structure is defined as: + *
+ *   typedef struct
+ *   {
+ *     uint16_t numRows;
+ *     uint16_t numCols;
+ *     float32_t *pData;
+ * } csi_bilinear_interp_instance_f32;
+ * 
+ * + * \par + * where numRows specifies the number of rows in the table; + * numCols specifies the number of columns in the table; + * and pData points to an array of size numRows*numCols values. + * The data table pTable is organized in row order and the supplied data values fall on integer indexes. + * That is, table element (x,y) is located at pTable[x + y*numCols] where x and y are integers. + * + * \par + * Let (x, y) specify the desired interpolation point. Then define: + *
+ *     XF = floor(x)
+ *     YF = floor(y)
+ * 
+ * \par + * The interpolated output point is computed as: + *
+ *  f(x, y) = f(XF, YF) * (1-(x-XF)) * (1-(y-YF))
+ *           + f(XF+1, YF) * (x-XF)*(1-(y-YF))
+ *           + f(XF, YF+1) * (1-(x-XF))*(y-YF)
+ *           + f(XF+1, YF+1) * (x-XF)*(y-YF)
+ * 
+ * Note that the coordinates (x, y) contain integer and fractional components. + * The integer components specify which portion of the table to use while the + * fractional components control the interpolation processor. + * + * \par + * if (x,y) are outside of the table boundary, Bilinear interpolation returns zero output. + */ + + +/** + * @addtogroup BilinearInterpolate + * @{ + */ + +/** +* @brief Floating-point bilinear interpolation. +* @param[in,out] S points to an instance of the interpolation structure. +* @param[in] X interpolation coordinate. +* @param[in] Y interpolation coordinate. +* @return out interpolated value. +*/ +__STATIC_FORCEINLINE float32_t csi_bilinear_interp_f32( + const csi_bilinear_interp_instance_f32 * S, + float32_t X, + float32_t Y) +{ + float32_t out; + float32_t f00, f01, f10, f11; + float32_t *pData = S->pData; + int32_t xIndex, yIndex, index; + float32_t xdiff, ydiff; + float32_t b1, b2, b3, b4; + xIndex = (int32_t) X; + yIndex = (int32_t) Y; + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if (xIndex < 0 || xIndex > (S->numRows - 1) || yIndex < 0 || yIndex > (S->numCols - 1)) { + return (0); + } + + /* Calculation of index for two nearest points in X-direction */ + index = (xIndex - 1) + (yIndex - 1) * S->numCols; + /* Read two nearest points in X-direction */ + f00 = pData[index]; + f01 = pData[index + 1]; + /* Calculation of index for two nearest points in Y-direction */ + index = (xIndex - 1) + (yIndex) * S->numCols; + /* Read two nearest points in Y-direction */ + f10 = pData[index]; + f11 = pData[index + 1]; + /* Calculation of intermediate values */ + b1 = f00; + b2 = f01 - f00; + b3 = f10 - f00; + b4 = f00 - f01 - f10 + f11; + /* Calculation of fractional part in X */ + xdiff = X - xIndex; + /* Calculation of fractional part in Y */ + ydiff = Y - yIndex; + /* Calculation of bi-linear interpolated output */ + out = b1 + b2 * xdiff + b3 * ydiff + b4 * xdiff * ydiff; + /* return to application */ + return (out); +} + + +/** +* @brief Q31 bilinear interpolation. +* @param[in,out] S points to an instance of the interpolation structure. +* @param[in] X interpolation coordinate in 12.20 format. +* @param[in] Y interpolation coordinate in 12.20 format. +* @return out interpolated value. +*/ +__STATIC_FORCEINLINE q31_t csi_bilinear_interp_q31( + csi_bilinear_interp_instance_q31 * S, + q31_t X, + q31_t Y) +{ + q31_t out; /* Temporary output */ + q31_t acc = 0; /* output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q31_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q31_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if (rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) { + return (0); + } + + /* 20 bits for the fractional part */ + /* shift left xfract by 11 to keep 1.31 format */ + xfract = (X & 0x000FFFFF) << 11U; + /* Read two nearest output values from the index */ + x1 = pYData[(rI) + (int32_t)nCols * (cI) ]; + x2 = pYData[(rI) + (int32_t)nCols * (cI) + 1]; + /* 20 bits for the fractional part */ + /* shift left yfract by 11 to keep 1.31 format */ + yfract = (Y & 0x000FFFFF) << 11U; + /* Read two nearest output values from the index */ + y1 = pYData[(rI) + (int32_t)nCols * (cI + 1) ]; + y2 = pYData[(rI) + (int32_t)nCols * (cI + 1) + 1]; + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 3.29(q29) format */ + out = ((q31_t) (((q63_t) x1 * (0x7FFFFFFF - xfract)) >> 32)); + acc = ((q31_t) (((q63_t) out * (0x7FFFFFFF - yfract)) >> 32)); + /* x2 * (xfract) * (1-yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) x2 * (0x7FFFFFFF - yfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (xfract) >> 32)); + /* y1 * (1 - xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y1 * (0x7FFFFFFF - xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); + /* y2 * (xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y2 * (xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); + /* Convert acc to 1.31(q31) format */ + return ((q31_t)(acc << 2)); +} + + +/** +* @brief Q15 bilinear interpolation. +* @param[in,out] S points to an instance of the interpolation structure. +* @param[in] X interpolation coordinate in 12.20 format. +* @param[in] Y interpolation coordinate in 12.20 format. +* @return out interpolated value. +*/ +__STATIC_FORCEINLINE q15_t csi_bilinear_interp_q15( + csi_bilinear_interp_instance_q15 * S, + q31_t X, + q31_t Y) +{ + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q15_t x1, x2, y1, y2; /* Nearest output values */ + q31_t xfract, yfract; /* X, Y fractional parts */ + int32_t rI, cI; /* Row and column indices */ + q15_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if (rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) { + return (0); + } + + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & 0x000FFFFF); + /* Read two nearest output values from the index */ + x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ]; + x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1]; + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & 0x000FFFFF); + /* Read two nearest output values from the index */ + y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ]; + y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1]; + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 13.51 format */ + /* x1 is in 1.15(q15), xfract in 12.20 format and out is in 13.35 format */ + /* convert 13.35 to 13.31 by right shifting and out is in 1.31 */ + out = (q31_t) (((q63_t) x1 * (0xFFFFF - xfract)) >> 4U); + acc = ((q63_t) out * (0xFFFFF - yfract)); + /* x2 * (xfract) * (1-yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) x2 * (0xFFFFF - yfract)) >> 4U); + acc += ((q63_t) out * (xfract)); + /* y1 * (1 - xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y1 * (0xFFFFF - xfract)) >> 4U); + acc += ((q63_t) out * (yfract)); + /* y2 * (xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y2 * (xfract)) >> 4U); + acc += ((q63_t) out * (yfract)); + /* acc is in 13.51 format and down shift acc by 36 times */ + /* Convert out to 1.15 format */ + return ((q15_t)(acc >> 36)); +} + + +/** +* @brief Q7 bilinear interpolation. +* @param[in,out] S points to an instance of the interpolation structure. +* @param[in] X interpolation coordinate in 12.20 format. +* @param[in] Y interpolation coordinate in 12.20 format. +* @return out interpolated value. +*/ +__STATIC_FORCEINLINE q7_t csi_bilinear_interp_q7( + csi_bilinear_interp_instance_q7 * S, + q31_t X, + q31_t Y) +{ + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q7_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q7_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if (rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) { + return (0); + } + + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & (q31_t)0x000FFFFF); + /* Read two nearest output values from the index */ + x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ]; + x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1]; + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & (q31_t)0x000FFFFF); + /* Read two nearest output values from the index */ + y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ]; + y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1]; + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 16.47 format */ + out = ((x1 * (0xFFFFF - xfract))); + acc = (((q63_t) out * (0xFFFFF - yfract))); + /* x2 * (xfract) * (1-yfract) in 2.22 and adding to acc */ + out = ((x2 * (0xFFFFF - yfract))); + acc += (((q63_t) out * (xfract))); + /* y1 * (1 - xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y1 * (0xFFFFF - xfract))); + acc += (((q63_t) out * (yfract))); + /* y2 * (xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y2 * (yfract))); + acc += (((q63_t) out * (xfract))); + /* acc in 16.47 format and down shift by 40 to convert to 1.7 format */ + return ((q7_t)(acc >> 40)); +} + +/** + * @} end of BilinearInterpolate group + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* _CSI_MATH_H */ + +/** + * + * End of file. + */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/dsp/csky_common_tables.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/dsp/csky_common_tables.h new file mode 100644 index 00000000..13a96dca --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/dsp/csky_common_tables.h @@ -0,0 +1,229 @@ +/* + * Copyright (C) 2016-2019 C-SKY 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 csky_common_tables.h + * @brief This file has extern declaration for common tables like + * Bitreverse, reciprocal etc which are used across different functions. + * @version V1.0 + * @date 20. Dec 2016 + ******************************************************************************/ + +#ifndef _CSKY_COMMON_TABLES_H +#define _CSKY_COMMON_TABLES_H + +#include "csky_math.h" + +extern const uint16_t cskyBitRevTable[1024]; +extern const q15_t cskyRecipTableQ15[64]; +extern const q31_t cskyRecipTableQ31[64]; +extern const uint32_t twiddleCoef_16[32]; +extern const uint32_t twiddleCoef_32[64]; +extern const uint32_t twiddleCoef_64[128]; +extern const uint32_t twiddleCoef_128[256]; +extern const uint32_t twiddleCoef_256[512]; +extern const uint32_t twiddleCoef_512[1024]; +extern const uint32_t twiddleCoef_1024[2048]; +extern const uint32_t twiddleCoef_2048[4096]; +extern const uint32_t twiddleCoef_4096[8192]; +extern const q31_t twiddleCoef_16_q31[24]; +extern const q31_t twiddleCoef_32_q31[48]; +extern const q31_t twiddleCoef_64_q31[96]; +extern const q31_t twiddleCoef_128_q31[192]; +extern const q31_t twiddleCoef_256_q31[384]; +extern const q31_t twiddleCoef_512_q31[768]; +extern const q31_t twiddleCoef_1024_q31[1536]; +extern const q31_t twiddleCoef_2048_q31[3072]; +extern const q31_t twiddleCoef_4096_q31[6144]; +extern const q15_t twiddleCoef_16_q15[24]; +extern const q15_t twiddleCoef_32_q15[48]; +extern const q15_t twiddleCoef_64_q15[96]; +extern const q15_t twiddleCoef_128_q15[192]; +extern const q15_t twiddleCoef_256_q15[384]; +extern const q15_t twiddleCoef_512_q15[768]; +extern const q15_t twiddleCoef_1024_q15[1536]; +extern const q15_t twiddleCoef_2048_q15[3072]; +extern const q15_t twiddleCoef_4096_q15[6144]; +extern const float32_t twiddleCoef_rfft_32[32]; +extern const float32_t twiddleCoef_rfft_64[64]; +extern const float32_t twiddleCoef_rfft_128[128]; +extern const float32_t twiddleCoef_rfft_256[256]; +extern const float32_t twiddleCoef_rfft_512[512]; +extern const float32_t twiddleCoef_rfft_1024[1024]; +extern const float32_t twiddleCoef_rfft_2048[2048]; +extern const float32_t twiddleCoef_rfft_4096[4096]; +extern const float32_t twiddleCoef_rfft_8192[8192]; + +extern const q15_t twiddleCoef_fast_16_q15[24]; +extern const q15_t twiddleCoef_fast_32_q15[56]; +extern const q15_t twiddleCoef_fast_64_q15[120]; +extern const q15_t twiddleCoef_fast_128_q15[248]; +extern const q15_t twiddleCoef_fast_256_q15[504]; +extern const q15_t twiddleCoef_fast_512_q15[1016]; +extern const q15_t twiddleCoef_fast_1024_q15[2040]; +extern const q15_t twiddleCoef_fast_2048_q15[4088]; +extern const q15_t twiddleCoef_fast_4096_q15[8184]; + +extern const q31_t twiddleCoef_fast_16_q31[24]; +extern const q31_t twiddleCoef_fast_32_q31[56]; +extern const q31_t twiddleCoef_fast_64_q31[120]; +extern const q31_t twiddleCoef_fast_128_q31[248]; +extern const q31_t twiddleCoef_fast_256_q31[504]; +extern const q31_t twiddleCoef_fast_512_q31[1016]; +extern const q31_t twiddleCoef_fast_1024_q31[2040]; +extern const q31_t twiddleCoef_fast_2048_q31[4088]; +extern const q31_t twiddleCoef_fast_4096_q31[8184]; + +extern const uint32_t twiddleCoef_fast_16[24]; +extern const uint32_t twiddleCoef_fast_32[56]; +extern const uint32_t twiddleCoef_fast_64[120]; +extern const uint32_t twiddleCoef_fast_128[248]; +extern const uint32_t twiddleCoef_fast_256[504]; +extern const uint32_t twiddleCoef_fast_512[1016]; +extern const uint32_t twiddleCoef_fast_1024[2040]; +extern const uint32_t twiddleCoef_fast_2048[4088]; +extern const uint32_t twiddleCoef_fast_4096[8184]; + +extern const q15_t realCoefAQ15_8192[8192]; +extern const q31_t realCoefAQ31_8192[8192]; +extern const q15_t realCoefBQ15_8192[8192]; +extern const q31_t realCoefBQ31_8192[8192]; + +/*Tables for RFFT.*/ +extern const q15_t ALIGN4 realCoefAQ15_32[32]; +extern const q15_t ALIGN4 realCoefAQ15_64[64]; +extern const q15_t ALIGN4 realCoefAQ15_128[128]; +extern const q15_t ALIGN4 realCoefAQ15_256[256]; +extern const q15_t ALIGN4 realCoefAQ15_512[512]; +extern const q15_t ALIGN4 realCoefAQ15_1024[1024]; +extern const q15_t ALIGN4 realCoefAQ15_2048[2048]; +extern const q15_t ALIGN4 realCoefAQ15_4096[4096]; + +extern const q15_t ALIGN4 realCoefBQ15_32[32]; +extern const q15_t ALIGN4 realCoefBQ15_64[64]; +extern const q15_t ALIGN4 realCoefBQ15_128[128]; +extern const q15_t ALIGN4 realCoefBQ15_256[256]; +extern const q15_t ALIGN4 realCoefBQ15_512[512]; +extern const q15_t ALIGN4 realCoefBQ15_1024[1024]; +extern const q15_t ALIGN4 realCoefBQ15_2048[2048]; +extern const q15_t ALIGN4 realCoefBQ15_4096[4096]; + +extern const q31_t realCoefAQ31_32[32]; +extern const q31_t realCoefAQ31_64[64]; +extern const q31_t realCoefAQ31_128[128]; +extern const q31_t realCoefAQ31_256[256]; +extern const q31_t realCoefAQ31_512[512]; +extern const q31_t realCoefAQ31_1024[1024]; +extern const q31_t realCoefAQ31_2048[2048]; +extern const q31_t realCoefAQ31_4096[4096]; + +extern const q31_t realCoefBQ31_32[32]; +extern const q31_t realCoefBQ31_64[64]; +extern const q31_t realCoefBQ31_128[128]; +extern const q31_t realCoefBQ31_256[256]; +extern const q31_t realCoefBQ31_512[512]; +extern const q31_t realCoefBQ31_1024[1024]; +extern const q31_t realCoefBQ31_2048[2048]; +extern const q31_t realCoefBQ31_4096[4096]; + + +extern const float32_t realCoefA[8192]; +extern const float32_t realCoefB[8192]; + + +/*Tables for DCT4*/ +extern const q15_t ALIGN4 WeightsQ15_128[128+2]; +extern const q15_t ALIGN4 WeightsQ15_512[512+2]; +extern const q15_t ALIGN4 WeightsQ15_2048[2048+2]; +extern const q15_t ALIGN4 WeightsQ15_8192[8192+2]; + +extern const q15_t ALIGN4 cos_factorsQ15_128[128]; +extern const q15_t ALIGN4 cos_factorsQ15_512[512]; +extern const q15_t ALIGN4 cos_factorsQ15_2048[2048]; +extern const q15_t ALIGN4 cos_factorsQ15_8192[8192]; + + +extern const q31_t WeightsQ31_128[128+2]; +extern const q31_t WeightsQ31_512[512+2]; +extern const q31_t WeightsQ31_2048[2048+2]; +extern const q31_t WeightsQ31_8192[8192+2]; + +extern const q31_t cos_factorsQ31_128[128]; +extern const q31_t cos_factorsQ31_512[512]; +extern const q31_t cos_factorsQ31_2048[2048]; +extern const q31_t cos_factorsQ31_8192[8192]; + + +extern const float32_t Weights_128[128+2]; +extern const float32_t Weights_512[512+2]; +extern const float32_t Weights_2048[2048+2]; +extern const float32_t Weights_8192[8192+2]; + +extern const float32_t cos_factors_128[128]; +extern const float32_t cos_factors_512[512]; +extern const float32_t cos_factors_2048[2048]; +extern const float32_t cos_factors_8192[8192]; + +/* floating-point bit reversal tables */ +#define CSKYBITREVINDEXTABLE__16_TABLE_LENGTH ((uint16_t)20 ) +#define CSKYBITREVINDEXTABLE__32_TABLE_LENGTH ((uint16_t)48 ) +#define CSKYBITREVINDEXTABLE__64_TABLE_LENGTH ((uint16_t)56 ) +#define CSKYBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208 ) +#define CSKYBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440 ) +#define CSKYBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448 ) +#define CSKYBITREVINDEXTABLE1024_TABLE_LENGTH ((uint16_t)1800) +#define CSKYBITREVINDEXTABLE2048_TABLE_LENGTH ((uint16_t)3808) +#define CSKYBITREVINDEXTABLE4096_TABLE_LENGTH ((uint16_t)4032) + +extern const uint16_t cskyBitRevIndexTable16[CSKYBITREVINDEXTABLE__16_TABLE_LENGTH]; +extern const uint16_t cskyBitRevIndexTable32[CSKYBITREVINDEXTABLE__32_TABLE_LENGTH]; +extern const uint16_t cskyBitRevIndexTable64[CSKYBITREVINDEXTABLE__64_TABLE_LENGTH]; +extern const uint16_t cskyBitRevIndexTable128[CSKYBITREVINDEXTABLE_128_TABLE_LENGTH]; +extern const uint16_t cskyBitRevIndexTable256[CSKYBITREVINDEXTABLE_256_TABLE_LENGTH]; +extern const uint16_t cskyBitRevIndexTable512[CSKYBITREVINDEXTABLE_512_TABLE_LENGTH]; +extern const uint16_t cskyBitRevIndexTable1024[CSKYBITREVINDEXTABLE1024_TABLE_LENGTH]; +extern const uint16_t cskyBitRevIndexTable2048[CSKYBITREVINDEXTABLE2048_TABLE_LENGTH]; +extern const uint16_t cskyBitRevIndexTable4096[CSKYBITREVINDEXTABLE4096_TABLE_LENGTH]; + +/* fixed-point bit reversal tables */ +#define CSKYBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH ((uint16_t)12 ) +#define CSKYBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH ((uint16_t)24 ) +#define CSKYBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH ((uint16_t)56 ) +#define CSKYBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH ((uint16_t)112 ) +#define CSKYBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH ((uint16_t)240 ) +#define CSKYBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH ((uint16_t)480 ) +#define CSKYBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH ((uint16_t)992 ) +#define CSKYBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH ((uint16_t)1984) +#define CSKYBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH ((uint16_t)4032) + +extern const uint16_t cskyBitRevIndexTable_fixed_16[CSKYBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH]; +extern const uint16_t cskyBitRevIndexTable_fixed_32[CSKYBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH]; +extern const uint16_t cskyBitRevIndexTable_fixed_64[CSKYBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH]; +extern const uint16_t cskyBitRevIndexTable_fixed_128[CSKYBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH]; +extern const uint16_t cskyBitRevIndexTable_fixed_256[CSKYBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH]; +extern const uint16_t cskyBitRevIndexTable_fixed_512[CSKYBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH]; +extern const uint16_t cskyBitRevIndexTable_fixed_1024[CSKYBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH]; +extern const uint16_t cskyBitRevIndexTable_fixed_2048[CSKYBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH]; +extern const uint16_t cskyBitRevIndexTable_fixed_4096[CSKYBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH]; + +/* Tables for Fast Math Sine and Cosine */ +extern const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1]; +extern const q31_t sinTable_q31[FAST_MATH_TABLE_SIZE + 1]; +extern const q15_t sinTable_q15[FAST_MATH_TABLE_SIZE + 1]; + +#endif /* CSKY_COMMON_TABLES_H */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/dsp/csky_const_structs.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/dsp/csky_const_structs.h new file mode 100644 index 00000000..1f5b5409 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/dsp/csky_const_structs.h @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2016-2019 C-SKY 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 csky_const_structs.h + * @brief This file has constant structs that are initialized for + * user convenience. For example, some can be given as + * arguments to the csky_cfft_f32() function. + * @version V1.0 + * @date 20. Dec 2016 + ******************************************************************************/ + +#ifndef _CSKY_CONST_STRUCTS_H +#define _CSKY_CONST_STRUCTS_H + +#include "csky_math.h" +#include "csky_common_tables.h" + + extern const csky_cfft_instance_f32 csky_cfft_sR_f32_len16; + extern const csky_cfft_instance_f32 csky_cfft_sR_f32_len32; + extern const csky_cfft_instance_f32 csky_cfft_sR_f32_len64; + extern const csky_cfft_instance_f32 csky_cfft_sR_f32_len128; + extern const csky_cfft_instance_f32 csky_cfft_sR_f32_len256; + extern const csky_cfft_instance_f32 csky_cfft_sR_f32_len512; + extern const csky_cfft_instance_f32 csky_cfft_sR_f32_len1024; + extern const csky_cfft_instance_f32 csky_cfft_sR_f32_len2048; + extern const csky_cfft_instance_f32 csky_cfft_sR_f32_len4096; + + extern const csky_cfft_instance_q31 csky_cfft_sR_q31_len16; + extern const csky_cfft_instance_q31 csky_cfft_sR_q31_len32; + extern const csky_cfft_instance_q31 csky_cfft_sR_q31_len64; + extern const csky_cfft_instance_q31 csky_cfft_sR_q31_len128; + extern const csky_cfft_instance_q31 csky_cfft_sR_q31_len256; + extern const csky_cfft_instance_q31 csky_cfft_sR_q31_len512; + extern const csky_cfft_instance_q31 csky_cfft_sR_q31_len1024; + extern const csky_cfft_instance_q31 csky_cfft_sR_q31_len2048; + extern const csky_cfft_instance_q31 csky_cfft_sR_q31_len4096; + + extern const csky_cfft_instance_q15 csky_cfft_sR_q15_len16; + extern const csky_cfft_instance_q15 csky_cfft_sR_q15_len32; + extern const csky_cfft_instance_q15 csky_cfft_sR_q15_len64; + extern const csky_cfft_instance_q15 csky_cfft_sR_q15_len128; + extern const csky_cfft_instance_q15 csky_cfft_sR_q15_len256; + extern const csky_cfft_instance_q15 csky_cfft_sR_q15_len512; + extern const csky_cfft_instance_q15 csky_cfft_sR_q15_len1024; + extern const csky_cfft_instance_q15 csky_cfft_sR_q15_len2048; + extern const csky_cfft_instance_q15 csky_cfft_sR_q15_len4096; + + extern csky_rfft_instance_q15 csky_rfft_sR_q15_len32; + extern csky_rfft_instance_q15 csky_rfft_sR_q15_len64; + extern csky_rfft_instance_q15 csky_rfft_sR_q15_len128; + extern csky_rfft_instance_q15 csky_rfft_sR_q15_len256; + extern csky_rfft_instance_q15 csky_rfft_sR_q15_len512; + extern csky_rfft_instance_q15 csky_rfft_sR_q15_len1024; + extern csky_rfft_instance_q15 csky_rfft_sR_q15_len2048; + extern csky_rfft_instance_q15 csky_rfft_sR_q15_len4096; + extern csky_rfft_instance_q15 csky_rfft_sR_q15_len8192; + + + extern csky_rfft_instance_q15 csky_inv_rfft_sR_q15_len32; + extern csky_rfft_instance_q15 csky_inv_rfft_sR_q15_len64; + extern csky_rfft_instance_q15 csky_inv_rfft_sR_q15_len128; + extern csky_rfft_instance_q15 csky_inv_rfft_sR_q15_len256; + extern csky_rfft_instance_q15 csky_inv_rfft_sR_q15_len512; + extern csky_rfft_instance_q15 csky_inv_rfft_sR_q15_len1024; + extern csky_rfft_instance_q15 csky_inv_rfft_sR_q15_len2048; + extern csky_rfft_instance_q15 csky_inv_rfft_sR_q15_len4096; + extern csky_rfft_instance_q15 csky_inv_rfft_sR_q15_len8192; + + + extern csky_rfft_instance_q31 csky_rfft_sR_q31_len32; + extern csky_rfft_instance_q31 csky_rfft_sR_q31_len64; + extern csky_rfft_instance_q31 csky_rfft_sR_q31_len128; + extern csky_rfft_instance_q31 csky_rfft_sR_q31_len256; + extern csky_rfft_instance_q31 csky_rfft_sR_q31_len512; + extern csky_rfft_instance_q31 csky_rfft_sR_q31_len1024; + extern csky_rfft_instance_q31 csky_rfft_sR_q31_len2048; + extern csky_rfft_instance_q31 csky_rfft_sR_q31_len4096; + extern csky_rfft_instance_q31 csky_rfft_sR_q31_len8192; + + extern csky_rfft_instance_q31 csky_inv_rfft_sR_q31_len32; + extern csky_rfft_instance_q31 csky_inv_rfft_sR_q31_len64; + extern csky_rfft_instance_q31 csky_inv_rfft_sR_q31_len128; + extern csky_rfft_instance_q31 csky_inv_rfft_sR_q31_len256; + extern csky_rfft_instance_q31 csky_inv_rfft_sR_q31_len512; + extern csky_rfft_instance_q31 csky_inv_rfft_sR_q31_len1024; + extern csky_rfft_instance_q31 csky_inv_rfft_sR_q31_len2048; + extern csky_rfft_instance_q31 csky_inv_rfft_sR_q31_len4096; + extern csky_rfft_instance_q31 csky_inv_rfft_sR_q31_len8192; + + + extern csky_rfft_fast_instance_f32 csky_rfft_sR_f32_len32; + extern csky_rfft_fast_instance_f32 csky_rfft_sR_f32_len64; + extern csky_rfft_fast_instance_f32 csky_rfft_sR_f32_len128; + extern csky_rfft_fast_instance_f32 csky_rfft_sR_f32_len256; + extern csky_rfft_fast_instance_f32 csky_rfft_sR_f32_len512; + extern csky_rfft_fast_instance_f32 csky_rfft_sR_f32_len1024; + extern csky_rfft_fast_instance_f32 csky_rfft_sR_f32_len2048; + extern csky_rfft_fast_instance_f32 csky_rfft_sR_f32_len4096; + extern csky_rfft_fast_instance_f32 csky_rfft_sR_f32_len8192; + + extern csky_dct4_instance_q15 csky_dct4_sR_q15_len128; + extern csky_dct4_instance_q15 csky_dct4_sR_q15_len512; + extern csky_dct4_instance_q15 csky_dct4_sR_q15_len2048; + extern csky_dct4_instance_q15 csky_dct4_sR_q15_len8192; + + extern csky_dct4_instance_q31 csky_dct4_sR_q31_len128; + extern csky_dct4_instance_q31 csky_dct4_sR_q31_len512; + extern csky_dct4_instance_q31 csky_dct4_sR_q31_len2048; + extern csky_dct4_instance_q31 csky_dct4_sR_q31_len8192; + + extern csky_dct4_instance_f32 csky_dct4_sR_f32_len128; + extern csky_dct4_instance_f32 csky_dct4_sR_f32_len512; + extern csky_dct4_instance_f32 csky_dct4_sR_f32_len2048; + extern csky_dct4_instance_f32 csky_dct4_sR_f32_len8192; +#endif diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/dsp/csky_math.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/dsp/csky_math.h new file mode 100644 index 00000000..d7adfecb --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/dsp/csky_math.h @@ -0,0 +1,4637 @@ +/* + * Copyright (C) 2016-2019 C-SKY 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 csky_math.h + * @brief Public header file for CSI DSP Library. + * @version V1.0 + * @date 20. Dec 2016 + ******************************************************************************/ + + +/** + * @defgroup groupMath Basic Math Functions + */ + +/** + * @defgroup groupFastMath Fast Math Functions + * This set of functions provides a fast approximation to sine, cosine, and square root. + * As compared to most of the other functions in the CSI math library, the fast math functions + * operate on individual values and not arrays. + * There are separate functions for Q15, Q31, and floating-point data. + * + */ + +/** + * @defgroup groupCmplxMath Complex Math Functions + * This set of functions operates on complex data vectors. + * The data in the complex arrays is stored in an interleaved fashion + * (real, imag, real, imag, ...). + * In the API functions, the number of samples in a complex array refers + * to the number of complex values; the array contains twice this number of + * real values. + */ + +/** + * @defgroup groupFilters Filtering Functions + */ + +/** + * @defgroup groupMatrix Matrix Functions + * + * This set of functions provides basic matrix math operations. + * The functions operate on matrix data structures. For example, + * the type + * definition for the floating-point matrix structure is shown + * below: + *
+ *     typedef struct
+ *     {
+ *       uint16_t numRows;     // number of rows of the matrix.
+ *       uint16_t numCols;     // number of columns of the matrix.
+ *       float32_t *pData;     // points to the data of the matrix.
+ *     } csky_matrix_instance_f32;
+ * 
+ * There are similar definitions for Q15 and Q31 data types. + * + * The structure specifies the size of the matrix and then points to + * an array of data. The array is of size numRows X numCols + * and the values are arranged in row order. That is, the + * matrix element (i, j) is stored at: + *
+ *     pData[i*numCols + j]
+ * 
+ * + * \par Init Functions + * There is an associated initialization function for each type of matrix + * data structure. + * The initialization function sets the values of the internal structure fields. + * Refer to the function csky_mat_init_f32(), csky_mat_init_q31() + * and csky_mat_init_q15() for floating-point, Q31 and Q15 types, respectively. + * + * \par + * Use of the initialization function is optional. However, if initialization function is used + * then the instance structure cannot be placed into a const data section. + * To place the instance structure in a const data + * section, manually initialize the data structure. For example: + *
+ * csky_matrix_instance_f32 S = {nRows, nColumns, pData};
+ * csky_matrix_instance_q31 S = {nRows, nColumns, pData};
+ * csky_matrix_instance_q15 S = {nRows, nColumns, pData};
+ * 
+ * where nRows specifies the number of rows, nColumns + * specifies the number of columns, and pData points to the + * data array. + * + * \par Size Checking + * By default all of the matrix functions perform size checking on the input and + * output matrices. For example, the matrix addition function verifies that the + * two input matrices and the output matrix all have the same number of rows and + * columns. If the size check fails the functions return: + *
+ *     CSKY_MATH_SIZE_MISMATCH
+ * 
+ * Otherwise the functions return + *
+ *     CSKY_MATH_SUCCESS
+ * 
+ * There is some overhead associated with this matrix size checking. + * The matrix size checking is enabled via the \#define + *
+ *     CSKY_MATH_MATRIX_CHECK
+ * 
+ * within the library project settings. By default this macro is defined + * and size checking is enabled. By changing the project settings and + * undefining this macro size checking is eliminated and the functions + * run a bit faster. With size checking disabled the functions always + * return CSKY_MATH_SUCCESS. + */ + +/** + * @defgroup groupTransforms Transform Functions + */ + +/** + * @defgroup groupController Controller Functions + */ + +/** + * @defgroup groupStats Statistics Functions + */ +/** + * @defgroup groupSupport Support Functions + */ + +/** + * @defgroup groupInterpolation Interpolation Functions + * These functions perform 1- and 2-dimensional interpolation of data. + * Linear interpolation is used for 1-dimensional data and + * bilinear interpolation is used for 2-dimensional data. + */ + + +/** + * @defgroup groupYunvoice Yunvoice Functions + * These functions are designed for Yunvoice project, which are modified + * according to the CEVA DSP functions. So, one can porting the software + * from CEVA to CSKY straightforwardly. + */ + +/** + * @defgroup groupExamples Examples + */ + + +#ifndef _CSKY_MATH_H +#define _CSKY_MATH_H + +#define __CSI_GENERIC /* disable NVIC and Systick functions */ + +#include "csi_core.h" + +#include +#undef __CSI_GENERIC /* enable NVIC and Systick functions */ +#include "string.h" +#include "math.h" +#ifdef __cplusplus +extern "C" +{ +#endif + + + /** + * @brief Macros required for reciprocal calculation in Normalized LMS + */ + +#define DELTA_Q31 (0x100) +#define DELTA_Q15 0x5 +#define INDEX_MASK 0x0000003F +#ifndef PI +#define PI 3.14159265358979f +#endif + + /** + * @brief Macros required for SINE and COSINE Fast math approximations + */ + +#define FAST_MATH_TABLE_SIZE 512 +#define FAST_MATH_Q31_SHIFT (32 - 10) +#define FAST_MATH_Q15_SHIFT (16 - 10) +#define CONTROLLER_Q31_SHIFT (32 - 9) +#define TABLE_SIZE 256 +#define TABLE_SPACING_Q31 0x400000 +#define TABLE_SPACING_Q15 0x80 + + /** + * @brief Macros required for SINE and COSINE Controller functions + */ + /* 1.31(q31) Fixed value of 2/360 */ + /* -1 to +1 is divided into 360 values so total spacing is (2/360) */ +#define INPUT_SPACING 0xB60B61 + + /** + * @brief Macro for Unaligned Support + */ +#ifndef UNALIGNED_SUPPORT_DISABLE + #define ALIGN4 +#else + #define ALIGN4 __attribute__((aligned(4))) +#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */ + +__ALWAYS_STATIC_INLINE int32_t __SSAT_31(int32_t x) +{ + int32_t res = x; + if (x > 0x3fffffff) { + res = 0x3fffffff; + } else if (x < -1073741824) { + res = -1073741824; + } + + return res; +} + +__ALWAYS_STATIC_INLINE int32_t __SSAT_16(int32_t x) +{ + int32_t res = x; + if (x > 0x7fff) { + res = 0x7fff; + } else if (x < -32768) { + res = -32768; + } + + return res; +} + +__ALWAYS_STATIC_INLINE int32_t __SSAT_8(int32_t x) +{ + int32_t res = x; + if (x > 0x7f) { + res = 0x7f; + } else if (x < -128) { + res = -128; + } + + return res; +} + +#ifdef CSKY_SIMD +/* SMMLAR */ +__ALWAYS_STATIC_INLINE int32_t multAcc_32x32_keep32_R(int32_t a, int32_t x, int32_t y) +{ + __ASM volatile("mula.s32.rhs %0, %1, %2\n\t" + :"=r" (a), "=r" (x), "=r" (y) : "0" (a), "1" (x), "2" (y)); + return a; +} + +/* SMMLSR */ +__ALWAYS_STATIC_INLINE int32_t multSub_32x32_keep32_R(int32_t a, int32_t x, int32_t y) +{ + __ASM volatile("muls.s32.rhs %0, %1, %2\n\t" + :"=r" (a), "=r" (x), "=r" (y): "0" (a), "1" (x), "2" (y)); + return a; +} + +/* SMMULR */ +__ALWAYS_STATIC_INLINE int32_t mult_32x32_keep32_R(int32_t x, int32_t y) +{ + int32_t a; + __ASM volatile("mul.s32.rh %0, %1, %2\n\t" + :"=r" (a), "=r" (x), "=r" (y): "1" (x), "2" (y)); + return a; +} + +/* SMMLA */ +__ALWAYS_STATIC_INLINE int32_t multAcc_32x32_keep32(int32_t a, int32_t x, int32_t y) +{ + __ASM volatile("mula.s32.hs %0, %1, %2\n\t" + :"=r" (a), "=r" (x), "=r" (y): "0" (a), "1" (x), "2" (y)); + return a; +} + +/* SMMLS */ +__ALWAYS_STATIC_INLINE int32_t multSub_32x32_keep32(int32_t a, int32_t x, int32_t y) +{ + __ASM volatile("muls.s32.hs %0, %1, %2\n\t" + :"=r" (a), "=r" (x), "=r" (y): "0" (a), "1" (x), "2" (y)); + return a; +} + +/* SMMUL */ +__ALWAYS_STATIC_INLINE int32_t mult_32x32_keep32(int32_t x, int32_t y) +{ + int32_t a; + __ASM volatile("mul.s32.h %0, %1, %2\n\t" + :"=r" (a), "=r" (x), "=r" (y): "0" (a), "1" (x), "2" (y)); + return a; +} + +__ALWAYS_STATIC_INLINE int32_t multAcc_16x16_keep32(int32_t a, int16_t x, int16_t y) +{ + __ASM volatile("mulall.s16 %0, %1, %2\n\t" + :"=r" (a), "=r" (x), "=r" (y): "0" (a), "1" (x), "2" (y)); + return a; +} + +__ALWAYS_STATIC_INLINE int64_t multAcc_16x16_keep64(int64_t a, int16_t x, int16_t y) +{ + __ASM volatile("mulall.s16.e %0, %1, %2\n\t" + :"=r" (a), "=r" (x), "=r" (y): "0" (a), "1" (x), "2" (y)); + return a; +} + +__ALWAYS_STATIC_INLINE int64_t mult_32x32_keep64(int32_t x, int32_t y) +{ + int64_t a; + __ASM volatile("mul.s32 %0, %1, %2\n\t" + :"=r" (a), "=r" (x), "=r" (y): "1" (x), "2" (y)); + return a; +} + +__ALWAYS_STATIC_INLINE int64_t multAcc_32x32_keep64(int64_t a, int32_t x, int32_t y) +{ + __ASM volatile("mula.s32 %0, %1, %2\n\t" + :"=r" (a), "=r" (x), "=r" (y): "0" (a), "1" (x), "2" (y)); + return a; +} + +__ALWAYS_STATIC_INLINE int32_t mult_32x32_dext_31(int32_t x, int32_t y) +{ + int64_t tmp1; + int32_t tmp2; + __ASM volatile("mul.s32 %0, %1, %2\n\t" + "dexti %3, %0, %R0, 31" + :"=r" (tmp1), "=r" (x), "=r" (y), "=r" (tmp2): "1" (x), "2" (y)); + return tmp2; +} + +__ALWAYS_STATIC_INLINE int32_t mult_32x32_dext_30(int32_t x, int32_t y) +{ + int64_t tmp1; + int32_t tmp2; + __ASM volatile("mul.s32 %0, %1, %2\n\t" + "dexti %3, %0, %R0, 30" + :"=r" (tmp1), "=r" (x), "=r" (y), "=r" (tmp2): "1" (x), "2" (y)); + return tmp2; +} + +__ALWAYS_STATIC_INLINE int32_t mult_32x32_dext_4(int32_t x, int32_t y) +{ + int64_t tmp1; + int32_t tmp2; + __ASM volatile("mul.s32 %0, %1, %2\n\t" + "dexti %3, %0, %R0, 4" + :"=r" (tmp1), "=r" (x), "=r" (y), "=r" (tmp2): "1" (x), "2" (y)); + return tmp2; +} + +__ALWAYS_STATIC_INLINE int32_t mult_32x32_dext_33(int32_t x, int32_t y) +{ + int64_t tmp1; + int32_t tmp2; + __ASM volatile("mul.s32 %0, %1, %2\n\t" + "asri %3, %R0, 1" + :"=r" (tmp1), "=r" (x), "=r" (y), "=r" (tmp2): "1" (x), "2" (y)); + return tmp2; +} + +__ALWAYS_STATIC_INLINE int32_t dext_31(int64_t x) +{ + int32_t tmp1; + __ASM volatile( + "dexti %0, %1, %R1, 31" + :"=r" (tmp1), "=r" (x) : "1" (x)); + return tmp1; +} + +__ALWAYS_STATIC_INLINE int32_t mult_l16xl16_keep32(int32_t x, int32_t y) +{ + int32_t a; + __ASM volatile("mulll.s16 %0, %1, %2\n\t" + :"=r" (a), "=r" (x), "=r" (y): "1" (x), "2" (y)); + return a; +} + +__ALWAYS_STATIC_INLINE int32_t mult_h16xl16_keep32(int32_t x, int32_t y) +{ + int32_t a; + __ASM volatile("mulhl.s16 %0, %1, %2\n\t" + :"=r" (a), "=r" (x), "=r" (y): "1" (x), "2" (y)); + return a; +} + +__ALWAYS_STATIC_INLINE int32_t mult_h16xh16_keep32(int32_t x, int32_t y) +{ + int32_t a; + __ASM volatile("mulhh.s16 %0, %1, %2\n\t" + :"=r" (a), "=r" (x), "=r" (y): "1" (x), "2" (y)); + return a; +} + +#endif + + + /** + * @brief Error status returned by some functions in the library. + */ + + typedef enum + { + CSKY_MATH_SUCCESS = 0, /**< No error */ + CSKY_MATH_ARGUMENT_ERROR = -1, /**< One or more arguments are incorrect */ + CSKY_MATH_LENGTH_ERROR = -2, /**< Length of data buffer is incorrect */ + CSKY_MATH_SIZE_MISMATCH = -3, /**< Size of matrices is not compatible with the operation. */ + CSKY_MATH_NANINF = -4, /**< Not-a-number (NaN) or infinity is generated */ + CSKY_MATH_SINGULAR = -5, /**< Generated by matrix inversion if the input matrix is singular and cannot be inverted. */ + CSKY_MATH_TEST_FAILURE = -6 /**< Test Failed */ + } csky_status; + + /** + * @brief 8-bit fractional data type in 1.7 format. + */ + typedef int8_t q7_t; + + /** + * @brief 16-bit fractional data type in 1.15 format. + */ + typedef int16_t q15_t; + + /** + * @brief 32-bit fractional data type in 1.31 format. + */ + typedef int32_t q31_t; + + /** + * @brief 64-bit fractional data type in 1.63 format. + */ + typedef int64_t q63_t; + + /** + * @brief 32-bit floating-point type definition. + */ + typedef float float32_t; + + /** + * @brief 64-bit floating-point type definition. + */ + typedef double float64_t; + + /** + * @brief 32-bit fractional complex data type in 1.31 format. + */ + typedef struct + { + q31_t re; + q31_t im; + } cq31_t; + /** + * @brief 16-bit fractional complex data type in 1.15 format. + */ + typedef struct + { + q15_t re; + q15_t im; + } cq15_t; + /** + * @brief definition to read/write two 16 bit values. + */ + #define __SIMD32_TYPE int32_t + #define CSI_UNUSED __attribute__((unused)) + +#define __SIMD32(addr) (*(__SIMD32_TYPE **) & (addr)) +#define __SIMD32_CONST(addr) ((__SIMD32_TYPE *)(addr)) +#define _SIMD32_OFFSET(addr) (*(__SIMD32_TYPE *) (addr)) +#define __SIMD64(addr) (*(int64_t **) & (addr)) + +#if defined (CSKY_MATH_NO_SIMD) + /** + * @brief definition to pack two 16 bit values. + */ +#define __PKHBT(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0x0000FFFF) | \ + (((int32_t)(ARG2) << ARG3) & (int32_t)0xFFFF0000) ) +#define __PKHTB(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0xFFFF0000) | \ + (((int32_t)(ARG2) >> ARG3) & (int32_t)0x0000FFFF) ) + +#endif + + + /** + * @brief definition to pack four 8 bit values. + */ +#ifndef CSKY_MATH_BIG_ENDIAN + +#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v0) << 0) & (int32_t)0x000000FF) | \ + (((int32_t)(v1) << 8) & (int32_t)0x0000FF00) | \ + (((int32_t)(v2) << 16) & (int32_t)0x00FF0000) | \ + (((int32_t)(v3) << 24) & (int32_t)0xFF000000) ) +#else + +#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v3) << 0) & (int32_t)0x000000FF) | \ + (((int32_t)(v2) << 8) & (int32_t)0x0000FF00) | \ + (((int32_t)(v1) << 16) & (int32_t)0x00FF0000) | \ + (((int32_t)(v0) << 24) & (int32_t)0xFF000000) ) + +#endif + + /** + * @brief Clips Q63 to Q31 values. + */ + static __INLINE q31_t clip_q63_to_q31( + q63_t x) + { + return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? + ((0x7FFFFFFF ^ ((q31_t) (x >> 63)))) : (q31_t) x; + } + + /** + * @brief Instance structure for the Q7 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q7_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } csky_fir_instance_q7; + + /** + * @brief Instance structure for the Q15 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } csky_fir_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } csky_fir_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } csky_fir_instance_f32; + + void csky_fir_q7( + const csky_fir_instance_q7 * S, + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + void csky_fir_init_q7( + csky_fir_instance_q7 * S, + uint16_t numTaps, + q7_t * pCoeffs, + q7_t * pState, + uint32_t blockSize); + + void csky_fir_q15( + const csky_fir_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + void csky_fir_fast_q15( + const csky_fir_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + csky_status csky_fir_init_q15( + csky_fir_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + void csky_fir_q31( + const csky_fir_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + void csky_fir_fast_q31( + const csky_fir_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + void csky_fir_init_q31( + csky_fir_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + void csky_fir_f32( + const csky_fir_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + void csky_fir_init_f32( + csky_fir_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 Biquad cascade filter. + */ + typedef struct + { + int8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q15_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + q15_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + int8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + } csky_biquad_casd_df1_inst_q15; + + /** + * @brief Instance structure for the Q31 Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q31_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + q31_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + } csky_biquad_casd_df1_inst_q31; + + /** + * @brief Instance structure for the Q31 Biquad cascade filter. + */ + + /** + * @brief Instance structure for the floating-point Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + float32_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + } csky_biquad_casd_df1_inst_f32; + + void csky_biquad_cascade_df1_q15( + const csky_biquad_casd_df1_inst_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + void csky_biquad_cascade_df1_init_q15( + csky_biquad_casd_df1_inst_q15 * S, + uint8_t numStages, + q15_t * pCoeffs, + q15_t * pState, + int8_t postShift); + + void csky_biquad_cascade_df1_fast_q15( + const csky_biquad_casd_df1_inst_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + void csky_biquad_cascade_df1_q31( + const csky_biquad_casd_df1_inst_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + void csky_biquad_cascade_df1_fast_q31( + const csky_biquad_casd_df1_inst_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + void csky_biquad_cascade_df1_init_q31( + csky_biquad_casd_df1_inst_q31 * S, + uint8_t numStages, + q31_t * pCoeffs, + q31_t * pState, + int8_t postShift); + + void csky_biquad_cascade_df1_f32( + const csky_biquad_casd_df1_inst_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + void csky_biquad_cascade_df1_init_f32( + csky_biquad_casd_df1_inst_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Instance structure for the floating-point matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + float32_t *pData; /**< points to the data of the matrix. */ + } csky_matrix_instance_f32; + + + /** + * @brief Instance structure for the floating-point matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + float64_t *pData; /**< points to the data of the matrix. */ + } csky_matrix_instance_f64; + + /** + * @brief Instance structure for the Q15 matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q15_t *pData; /**< points to the data of the matrix. */ + } csky_matrix_instance_q15; + + /** + * @brief Instance structure for the Q31 matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q31_t *pData; /**< points to the data of the matrix. */ + } csky_matrix_instance_q31; + + csky_status csky_mat_add_f32( + const csky_matrix_instance_f32 * pSrcA, + const csky_matrix_instance_f32 * pSrcB, + csky_matrix_instance_f32 * pDst); + + csky_status csky_mat_add_q15( + const csky_matrix_instance_q15 * pSrcA, + const csky_matrix_instance_q15 * pSrcB, + csky_matrix_instance_q15 * pDst); + + csky_status csky_mat_add_q31( + const csky_matrix_instance_q31 * pSrcA, + const csky_matrix_instance_q31 * pSrcB, + csky_matrix_instance_q31 * pDst); + + csky_status csky_mat_cmplx_mult_f32( + const csky_matrix_instance_f32 * pSrcA, + const csky_matrix_instance_f32 * pSrcB, + csky_matrix_instance_f32 * pDst); + + csky_status csky_mat_cmplx_mult_q15( + const csky_matrix_instance_q15 * pSrcA, + const csky_matrix_instance_q15 * pSrcB, + csky_matrix_instance_q15 * pDst); + + csky_status csky_mat_cmplx_mult_q31( + const csky_matrix_instance_q31 * pSrcA, + const csky_matrix_instance_q31 * pSrcB, + csky_matrix_instance_q31 * pDst); + + csky_status csky_mat_trans_f32( + const csky_matrix_instance_f32 * pSrc, + csky_matrix_instance_f32 * pDst); + + csky_status csky_mat_trans_q15( + const csky_matrix_instance_q15 * pSrc, + csky_matrix_instance_q15 * pDst); + + csky_status csky_mat_trans_q31( + const csky_matrix_instance_q31 * pSrc, + csky_matrix_instance_q31 * pDst); + + csky_status csky_mat_mult_f32( + const csky_matrix_instance_f32 * pSrcA, + const csky_matrix_instance_f32 * pSrcB, + csky_matrix_instance_f32 * pDst); + + csky_status csky_mat_mult_q15( + const csky_matrix_instance_q15 * pSrcA, + const csky_matrix_instance_q15 * pSrcB, + csky_matrix_instance_q15 * pDst); + + csky_status csky_mat_mult_fast_q15( + const csky_matrix_instance_q15 * pSrcA, + const csky_matrix_instance_q15 * pSrcB, + csky_matrix_instance_q15 * pDst); + + csky_status csky_mat_mult_q31( + const csky_matrix_instance_q31 * pSrcA, + const csky_matrix_instance_q31 * pSrcB, + csky_matrix_instance_q31 * pDst); + + csky_status csky_mat_mult_trans_q31( + const csky_matrix_instance_q31 * pSrcA, + const csky_matrix_instance_q31 * pSrcB, + csky_matrix_instance_q31 * pDst); + + csky_status csky_mat_mult_fast_q31( + const csky_matrix_instance_q31 * pSrcA, + const csky_matrix_instance_q31 * pSrcB, + csky_matrix_instance_q31 * pDst); + + csky_status csky_mat_sub_f32( + const csky_matrix_instance_f32 * pSrcA, + const csky_matrix_instance_f32 * pSrcB, + csky_matrix_instance_f32 * pDst); + + csky_status csky_mat_sub_q15( + const csky_matrix_instance_q15 * pSrcA, + const csky_matrix_instance_q15 * pSrcB, + csky_matrix_instance_q15 * pDst); + + csky_status csky_mat_sub_q31( + const csky_matrix_instance_q31 * pSrcA, + const csky_matrix_instance_q31 * pSrcB, + csky_matrix_instance_q31 * pDst); + + csky_status csky_mat_scale_f32( + const csky_matrix_instance_f32 * pSrc, + float32_t scale, + csky_matrix_instance_f32 * pDst); + + csky_status csky_mat_scale_q15( + const csky_matrix_instance_q15 * pSrc, + q15_t scaleFract, + int32_t shift, + csky_matrix_instance_q15 * pDst); + + csky_status csky_mat_scale_q31( + const csky_matrix_instance_q31 * pSrc, + q31_t scaleFract, + int32_t shift, + csky_matrix_instance_q31 * pDst); + + void csky_mat_init_q31( + csky_matrix_instance_q31 * S, + uint16_t nRows, + uint16_t nColumns, + q31_t * pData); + + void csky_mat_init_q15( + csky_matrix_instance_q15 * S, + uint16_t nRows, + uint16_t nColumns, + q15_t * pData); + + void csky_mat_init_f32( + csky_matrix_instance_f32 * S, + uint16_t nRows, + uint16_t nColumns, + float32_t * pData); + + /** + * @brief Instance structure for the Q15 PID Control. + */ + typedef struct + { + q15_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + q15_t A1; + q15_t A2; + q15_t state[3]; /**< The state array of length 3. */ + q15_t Kp; /**< The proportional gain. */ + q15_t Ki; /**< The integral gain. */ + q15_t Kd; /**< The derivative gain. */ + } csky_pid_instance_q15; + + /** + * @brief Instance structure for the Q31 PID Control. + */ + typedef struct + { + q31_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + q31_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + q31_t A2; /**< The derived gain, A2 = Kd . */ + q31_t state[3]; /**< The state array of length 3. */ + q31_t Kp; /**< The proportional gain. */ + q31_t Ki; /**< The integral gain. */ + q31_t Kd; /**< The derivative gain. */ + } csky_pid_instance_q31; + + /** + * @brief Instance structure for the floating-point PID Control. + */ + typedef struct + { + float32_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + float32_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + float32_t A2; /**< The derived gain, A2 = Kd . */ + float32_t state[3]; /**< The state array of length 3. */ + float32_t Kp; /**< The proportional gain. */ + float32_t Ki; /**< The integral gain. */ + float32_t Kd; /**< The derivative gain. */ + } csky_pid_instance_f32; + + void csky_pid_init_f32( + csky_pid_instance_f32 * S, + int32_t resetStateFlag); + + void csky_pid_reset_f32( + csky_pid_instance_f32 * S); + + void csky_pid_init_q31( + csky_pid_instance_q31 * S, + int32_t resetStateFlag); + + void csky_pid_reset_q31( + csky_pid_instance_q31 * S); + + void csky_pid_init_q15( + csky_pid_instance_q15 * S, + int32_t resetStateFlag); + + void csky_pid_reset_q15( + csky_pid_instance_q15 * S); + + + /** + * @brief Instance structure for the floating-point Linear Interpolate function. + */ + typedef struct + { + uint32_t nValues; /**< nValues */ + float32_t x1; /**< x1 */ + float32_t xSpacing; /**< xSpacing */ + float32_t *pYData; /**< pointer to the table of Y values */ + } csky_linear_interp_instance_f32; + + /** + * @brief Instance structure for the floating-point bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + float32_t *pData; /**< points to the data table. */ + } csky_bilinear_interp_instance_f32; + + /** + * @brief Instance structure for the Q31 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q31_t *pData; /**< points to the data table. */ + } csky_bilinear_interp_instance_q31; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q15_t *pData; /**< points to the data table. */ + } csky_bilinear_interp_instance_q15; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q7_t *pData; /**< points to the data table. */ + } csky_bilinear_interp_instance_q7; + + void csky_mult_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + void csky_mult_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + void csky_mult_rnd_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + void csky_mult_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + void csky_mult_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q15_t *pTwiddle; /**< points to the Sin twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } csky_cfft_radix2_instance_q15; + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q15_t *pTwiddle; /**< points to the twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } csky_cfft_radix4_instance_q15; + + /** + * @brief Instance structure for the Radix-2 Q31 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } csky_cfft_radix2_instance_q31; + + /** + * @brief Instance structure for the Q31 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q31_t *pTwiddle; /**< points to the twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } csky_cfft_radix4_instance_q31; + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } csky_cfft_radix2_instance_f32; + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } csky_cfft_radix4_instance_f32; + + /** + * @brief Instance structure for the fixed-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const q15_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } csky_cfft_instance_q15; + +void csky_cfft_q15( + const csky_cfft_instance_q15 * S, + q15_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the fixed-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } csky_cfft_instance_q31; + +void csky_cfft_q31( + const csky_cfft_instance_q31 * S, + q31_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } csky_cfft_instance_f32; + + void csky_cfft_f32( + const csky_cfft_instance_f32 * S, + float32_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the Q15 RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + q15_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + const csky_cfft_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } csky_rfft_instance_q15; + + csky_status csky_rfft_init_q15( + csky_rfft_instance_q15 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void csky_rfft_q15( + const csky_rfft_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst); + + /** + * @brief Instance structure for the Q31 RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + q31_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + const csky_cfft_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } csky_rfft_instance_q31; + + csky_status csky_rfft_init_q31( + csky_rfft_instance_q31 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void csky_rfft_q31( + const csky_rfft_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst); + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint16_t fftLenBy2; /**< length of the complex FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + float32_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + float32_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + csky_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } csky_rfft_instance_f32; + + csky_status csky_rfft_init_f32( + csky_rfft_instance_f32 * S, + csky_cfft_radix4_instance_f32 * S_CFFT, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void csky_rfft_f32( + const csky_rfft_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst); + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ +typedef struct + { + csky_cfft_instance_f32 Sint; /**< Internal CFFT structure. */ + uint16_t fftLenRFFT; /**< length of the real sequence */ + float32_t * pTwiddleRFFT; /**< Twiddle factors real stage */ + } csky_rfft_fast_instance_f32 ; + +csky_status csky_rfft_fast_init_f32 ( + csky_rfft_fast_instance_f32 * S, + uint16_t fftLen); + +void csky_rfft_fast_f32( + csky_rfft_fast_instance_f32 * S, + float32_t * p, float32_t * pOut, + uint8_t ifftFlag); + + /** + * @brief Instance structure for the floating-point DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + float32_t normalize; /**< normalizing factor. */ + float32_t *pTwiddle; /**< points to the twiddle factor table. */ + float32_t *pCosFactor; /**< points to the cosFactor table. */ + csky_rfft_fast_instance_f32 *pRfft; /**< points to the real FFT fast instance. */ + csky_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } csky_dct4_instance_f32; + + csky_status csky_dct4_init_f32( + csky_dct4_instance_f32 * S, + csky_rfft_fast_instance_f32 * S_RFFT, + csky_cfft_radix4_instance_f32 * S_CFFT, + uint16_t N, + uint16_t Nby2, + float32_t normalize); + + void csky_dct4_f32( + const csky_dct4_instance_f32 * S, + float32_t * pState, + float32_t * pInlineBuffer); + + + /** + * @brief Instance structure for the Q31 DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q31_t normalize; /**< normalizing factor. */ + q31_t *pTwiddle; /**< points to the twiddle factor table. */ + q31_t *pCosFactor; /**< points to the cosFactor table. */ + csky_rfft_instance_q31 *pRfft; /**< points to the real FFT instance. */ + csky_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } csky_dct4_instance_q31; + + csky_status csky_dct4_init_q31( + csky_dct4_instance_q31 * S, + csky_rfft_instance_q31 * S_RFFT, + csky_cfft_radix4_instance_q31 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q31_t normalize); + + void csky_dct4_q31( + const csky_dct4_instance_q31 * S, + q31_t * pState, + q31_t * pInlineBuffer); + + /** + * @brief Instance structure for the Q15 DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q15_t normalize; /**< normalizing factor. */ + q15_t *pTwiddle; /**< points to the twiddle factor table. */ + q15_t *pCosFactor; /**< points to the cosFactor table. */ + csky_rfft_instance_q15 *pRfft; /**< points to the real FFT instance. */ + csky_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } csky_dct4_instance_q15; + + csky_status csky_dct4_init_q15( + csky_dct4_instance_q15 * S, + csky_rfft_instance_q15 * S_RFFT, + csky_cfft_radix4_instance_q15 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q15_t normalize); + + void csky_dct4_q15( + const csky_dct4_instance_q15 * S, + q15_t * pState, + q15_t * pInlineBuffer); + + void csky_add_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + void csky_add_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + void csky_add_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + void csky_add_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + void csky_sub_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + void csky_sub_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + void csky_sub_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + void csky_sub_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + void csky_scale_f32( + float32_t * pSrc, + float32_t scale, + float32_t * pDst, + uint32_t blockSize); + + void csky_scale_q7( + q7_t * pSrc, + q7_t scaleFract, + int8_t shift, + q7_t * pDst, + uint32_t blockSize); + + void csky_scale_q15( + q15_t * pSrc, + q15_t scaleFract, + int8_t shift, + q15_t * pDst, + uint32_t blockSize); + + void csky_scale_q31( + q31_t * pSrc, + q31_t scaleFract, + int8_t shift, + q31_t * pDst, + uint32_t blockSize); + + void csky_abs_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + void csky_abs_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + void csky_abs_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + void csky_abs_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + void csky_abs_max_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + void csky_abs_max_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + void csky_dot_prod_f32( + float32_t * pSrcA, + float32_t * pSrcB, + uint32_t blockSize, + float32_t * result); + + void csky_dot_prod_q7( + q7_t * pSrcA, + q7_t * pSrcB, + uint32_t blockSize, + q31_t * result); + + void csky_dot_prod_q15( + q15_t * pSrcA, + q15_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + void csky_dot_prod_q31( + q31_t * pSrcA, + q31_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + void csky_shift_q7( + q7_t * pSrc, + int8_t shiftBits, + q7_t * pDst, + uint32_t blockSize); + + void csky_shift_q15( + q15_t * pSrc, + int8_t shiftBits, + q15_t * pDst, + uint32_t blockSize); + + void csky_shift_q31( + q31_t * pSrc, + int8_t shiftBits, + q31_t * pDst, + uint32_t blockSize); + + void csky_offset_f32( + float32_t * pSrc, + float32_t offset, + float32_t * pDst, + uint32_t blockSize); + + void csky_offset_q7( + q7_t * pSrc, + q7_t offset, + q7_t * pDst, + uint32_t blockSize); + + void csky_offset_q15( + q15_t * pSrc, + q15_t offset, + q15_t * pDst, + uint32_t blockSize); + + void csky_offset_q31( + q31_t * pSrc, + q31_t offset, + q31_t * pDst, + uint32_t blockSize); + + void csky_negate_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + void csky_negate_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + void csky_negate_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + void csky_negate_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + void csky_copy_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + void csky_copy_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + void csky_copy_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + void csky_copy_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + void csky_fill_f32( + float32_t value, + float32_t * pDst, + uint32_t blockSize); + + void csky_fill_q7( + q7_t value, + q7_t * pDst, + uint32_t blockSize); + + void csky_fill_q15( + q15_t value, + q15_t * pDst, + uint32_t blockSize); + + void csky_fill_q31( + q31_t value, + q31_t * pDst, + uint32_t blockSize); + + void csky_conv_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + void csky_conv_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + void csky_conv_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + void csky_conv_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + void csky_conv_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + void csky_conv_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + void csky_conv_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + void csky_conv_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + void csky_conv_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + csky_status csky_conv_partial_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + csky_status csky_conv_partial_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + csky_status csky_conv_partial_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + csky_status csky_conv_partial_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + csky_status csky_conv_partial_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + csky_status csky_conv_partial_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + csky_status csky_conv_partial_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + csky_status csky_conv_partial_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + csky_status csky_conv_partial_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + /** + * functions for the yunVoice functions. + */ + q15_t csky_dsp_lib_vec_max_abs16( + q15_t * A, + uint32_t N); + + q31_t csky_dsp_lib_vec_max_abs32( + q31_t * A, + uint32_t N); + + void csky_dsp_lib_vec_abs16( + q15_t * A, + uint32_t N, + q15_t * C); + + void csky_dsp_lib_vec_abs32( + q31_t * A, + uint32_t N, + q31_t * C); + + void csky_dsp_lib_vec_add16( + q15_t * A, + q15_t * B, + uint32_t N, + q15_t * C); + + void csky_dsp_lib_vec_add32( + q31_t * A, + q31_t * B, + uint32_t N, + q31_t * C); + + void csky_dsp_lib_vec_cx_conj_q15( + q15_t * A, + uint32_t N, + q15_t * B); + + void csky_dsp_lib_vec_cx_conj_q31( + q31_t * A, + uint32_t N, + q31_t * C); + + q31_t csky_dsp_lib_vec_dot_q15( + q15_t * A, + q15_t * B, + uint32_t N); + + q31_t csky_dsp_lib_vec_dot_q31( + q31_t * A, + q31_t * B, + uint32_t N); + + void csky_dsp_lib_mat_cx_add16( + cq15_t * A, + cq15_t * B, + uint32_t N, + uint32_t M, + cq15_t * C); + + void csky_dsp_lib_mat_cx_add32( + cq31_t * A, + cq31_t * B, + uint32_t N, + uint32_t M, + cq31_t * C); + + void csky_dsp_lib_mat_cx_mul_q15( + cq15_t * A, + cq15_t * B, + uint32_t N, + uint32_t M, + uint32_t L, + cq15_t * C); + + void csky_dsp_lib_mat_cx_mul_q31( + cq31_t * A, + cq31_t * B, + uint32_t N, + uint32_t M, + uint32_t L, + cq31_t * C); + + void csky_dsp_lib_mat_cx_sub16( + cq15_t * A, + cq15_t * B, + uint32_t N, + uint32_t M, + cq15_t * C); + + void csky_dsp_lib_mat_cx_sub32( + cq31_t * A, + cq31_t * B, + uint32_t N, + uint32_t M, + cq31_t * C); + + void csky_dsp_lib_vec_mul_q15( + q15_t * A, + q15_t * B, + uint32_t N, + q15_t * C); + + void csky_dsp_lib_vec_mul_q31( + q31_t * A, + q31_t * B, + uint32_t N, + q31_t * C); + + q31_t csky_dsp_lib_pow_int32( + q31_t arg_in_x, + q15_t arg_exp_in_x, + q31_t arg_in_y, + q15_t arg_exp_in_y, + q31_t *arg_exp_out); + + void csky_dsp_lib_vec_scale_q15( + q15_t * A, + q15_t scaleFract, + int8_t shift, + q15_t * B, + uint32_t N); + + void csky_dsp_lib_vec_scale_q31( + q31_t * A, + q31_t scaleFract, + int8_t shift, + q31_t * B, + uint32_t N); + + void csky_dsp_lib_vec_shf16( + q15_t * A, + int8_t shift_val, + uint32_t N, + q15_t * C); + + void csky_dsp_lib_vec_shf32( + q31_t * A, + q31_t shift_val, + uint32_t N, + q31_t * C); + + q15_t csky_dsp_lib_sqrt_int32( + q31_t x, + uint32_t rnd_flag); + + void csky_dsp_lib_vec_sub16( + q15_t * A, + q15_t * B, + uint32_t N, + q15_t * C); + + void csky_dsp_lib_vec_sub32( + q31_t * A, + q31_t * B, + uint32_t N, + q31_t * C); + + q63_t csky_dsp_lib_vec_sum16( + q15_t * A, + uint32_t N); + + q63_t csky_dsp_lib_vec_sum32( + q31_t * A, + uint32_t N); + + void csky_fft_lib_cx16_fft( + q31_t log2_buf_len, + q15_t * in_buf, + q15_t * out_buf, + const q15_t * twi_table, + const uint16_t * bitrev_tbl, + q15_t * temp_buf, + q7_t * ScaleShift, + q31_t br); + + void csky_fft_lib_cx32_fft( + q31_t log2_buf_len, + q31_t * in_buf, + q31_t * out_buf, + const q31_t * twi_table, + const uint16_t * bitrev_tbl, + q31_t * temp_buf, + q31_t br); + + void csky_fft_lib_cx16_ifft( + q31_t log2_buf_len, + q15_t * in_buf, + q15_t * out_buf, + const q15_t * twi_table, + const uint16_t * bitrev_tbl, + q15_t * temp_buf, + q7_t * ScaleShift, + q31_t br); + + void csky_fft_lib_cx32_ifft( + q31_t log2_buf_len, + q31_t * in_buf, + q31_t * out_buf, + const q31_t * twi_table, + const uint16_t * bitrev_tbl, + q31_t * temp_buf, + q31_t br); + + void csky_fft_lib_int16_fft( + q31_t log2_buf_len, + q15_t * in_buf, + q15_t * out_buf, + const q15_t * twi_table, + const q15_t * last_stage_twi_table, + const uint16_t * bitrev_tbl, + q15_t * temp_buf, + q7_t * ScaleShift, + q31_t br); + + void csky_fft_lib_int32_fft( + q31_t log2_buf_len, + q31_t * in_buf, + q31_t * out_buf, + const q31_t * twi_table, + const q31_t * last_stage_twi_table, + const uint16_t * bitrev_tbl, + q31_t * temp_buf, + q31_t br); + + void csky_fft_lib_int16_ifft( + q31_t log2_buf_len, + q15_t * in_buf, + q15_t * out_buf, + const q15_t * twi_table, + const q15_t * last_stage_twi_table, + const uint16_t * bitrev_tbl, + q15_t * temp_buf, + q7_t * ScaleShift, + q31_t br); + + void csky_fft_lib_int32_ifft( + q31_t log2_buf_len, + q31_t * in_buf, + q31_t * out_buf, + const q31_t * twi_table, + const q31_t * last_stage_twi_table, + const uint16_t * bitrev_tbl, + q31_t * temp_buf, + q31_t br); + + /** + * @brief Instance structure for the Q15 FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } csky_fir_decimate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } csky_fir_decimate_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } csky_fir_decimate_instance_f32; + + void csky_fir_decimate_f32( + const csky_fir_decimate_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + csky_status csky_fir_decimate_init_f32( + csky_fir_decimate_instance_f32 * S, + uint16_t numTaps, + uint8_t M, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + void csky_fir_decimate_q15( + const csky_fir_decimate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + void csky_fir_decimate_fast_q15( + const csky_fir_decimate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + csky_status csky_fir_decimate_init_q15( + csky_fir_decimate_instance_q15 * S, + uint16_t numTaps, + uint8_t M, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + void csky_fir_decimate_q31( + const csky_fir_decimate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + void csky_fir_decimate_fast_q31( + csky_fir_decimate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + csky_status csky_fir_decimate_init_q31( + csky_fir_decimate_instance_q31 * S, + uint16_t numTaps, + uint8_t M, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q15_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + } csky_fir_interpolate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q31_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + } csky_fir_interpolate_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + float32_t *pState; /**< points to the state variable array. The array is of length phaseLength+numTaps-1. */ + } csky_fir_interpolate_instance_f32; + + void csky_fir_interpolate_q15( + const csky_fir_interpolate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + csky_status csky_fir_interpolate_init_q15( + csky_fir_interpolate_instance_q15 * S, + uint8_t L, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + void csky_fir_interpolate_q31( + const csky_fir_interpolate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + csky_status csky_fir_interpolate_init_q31( + csky_fir_interpolate_instance_q31 * S, + uint8_t L, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + void csky_fir_interpolate_f32( + const csky_fir_interpolate_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + csky_status csky_fir_interpolate_init_f32( + csky_fir_interpolate_instance_f32 * S, + uint8_t L, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the high precision Q31 Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q63_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ + q31_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< additional shift, in bits, applied to each output sample. */ + } csky_biquad_cas_df1_32x64_ins_q31; + + void csky_biquad_cas_df1_32x64_q31( + const csky_biquad_cas_df1_32x64_ins_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + void csky_biquad_cas_df1_32x64_init_q31( + csky_biquad_cas_df1_32x64_ins_q31 * S, + uint8_t numStages, + q31_t * pCoeffs, + q63_t * pState, + uint8_t postShift); + + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ + float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } csky_biquad_cascade_df2T_instance_f32; + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ + float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } csky_biquad_cascade_stereo_df2T_instance_f32; + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float64_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ + float64_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } csky_biquad_cascade_df2T_instance_f64; + + void csky_biquad_cascade_df2T_f32( + const csky_biquad_cascade_df2T_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + void csky_biquad_cascade_stereo_df2T_f32( + const csky_biquad_cascade_stereo_df2T_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + void csky_biquad_cascade_df2T_f64( + const csky_biquad_cascade_df2T_instance_f64 * S, + float64_t * pSrc, + float64_t * pDst, + uint32_t blockSize); + + void csky_biquad_cascade_df2T_init_f32( + csky_biquad_cascade_df2T_instance_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + void csky_biquad_cascade_stereo_df2T_init_f32( + csky_biquad_cascade_stereo_df2T_instance_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + void csky_biquad_cascade_df2T_init_f64( + csky_biquad_cascade_df2T_instance_f64 * S, + uint8_t numStages, + float64_t * pCoeffs, + float64_t * pState); + + + /** + * @brief Instance structure for the Q15 FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } csky_fir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } csky_fir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } csky_fir_lattice_instance_f32; + + void csky_fir_lattice_init_q15( + csky_fir_lattice_instance_q15 * S, + uint16_t numStages, + q15_t * pCoeffs, + q15_t * pState); + + void csky_fir_lattice_q15( + const csky_fir_lattice_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + void csky_fir_lattice_init_q31( + csky_fir_lattice_instance_q31 * S, + uint16_t numStages, + q31_t * pCoeffs, + q31_t * pState); + + void csky_fir_lattice_q31( + const csky_fir_lattice_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + void csky_fir_lattice_init_f32( + csky_fir_lattice_instance_f32 * S, + uint16_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + void csky_fir_lattice_f32( + const csky_fir_lattice_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q15_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q15_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } csky_iir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q31_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q31_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } csky_iir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + float32_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + float32_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } csky_iir_lattice_instance_f32; + + void csky_iir_lattice_f32( + const csky_iir_lattice_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + void csky_iir_lattice_init_f32( + csky_iir_lattice_instance_f32 * S, + uint16_t numStages, + float32_t * pkCoeffs, + float32_t * pvCoeffs, + float32_t * pState, + uint32_t blockSize); + + void csky_iir_lattice_q31( + const csky_iir_lattice_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + void csky_iir_lattice_init_q31( + csky_iir_lattice_instance_q31 * S, + uint16_t numStages, + q31_t * pkCoeffs, + q31_t * pvCoeffs, + q31_t * pState, + uint32_t blockSize); + + void csky_iir_lattice_q15( + const csky_iir_lattice_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + void csky_iir_lattice_init_q15( + csky_iir_lattice_instance_q15 * S, + uint16_t numStages, + q15_t * pkCoeffs, + q15_t * pvCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the floating-point LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that controls filter coefficient updates. */ + } csky_lms_instance_f32; + + void csky_lms_f32( + const csky_lms_instance_f32 * S, + float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + void csky_lms_init_f32( + csky_lms_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ + } csky_lms_instance_q15; + + void csky_lms_init_q15( + csky_lms_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint32_t postShift); + + void csky_lms_q15( + const csky_lms_instance_q15 * S, + q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ + } csky_lms_instance_q31; + + void csky_lms_q31( + const csky_lms_instance_q31 * S, + q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + void csky_lms_init_q31( + csky_lms_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint32_t postShift); + + + /** + * @brief Instance structure for the floating-point normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that control filter coefficient updates. */ + float32_t energy; /**< saves previous frame energy. */ + float32_t x0; /**< saves previous input sample. */ + } csky_lms_norm_instance_f32; + + void csky_lms_norm_f32( + csky_lms_norm_instance_f32 * S, + float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + void csky_lms_norm_init_f32( + csky_lms_norm_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + q31_t *recipTable; /**< points to the reciprocal initial value table. */ + q31_t energy; /**< saves previous frame energy. */ + q31_t x0; /**< saves previous input sample. */ + } csky_lms_norm_instance_q31; + + void csky_lms_norm_q31( + csky_lms_norm_instance_q31 * S, + q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + void csky_lms_norm_init_q31( + csky_lms_norm_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint8_t postShift); + + + /** + * @brief Instance structure for the Q15 normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< Number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + q15_t *recipTable; /**< Points to the reciprocal initial value table. */ + q15_t energy; /**< saves previous frame energy. */ + q15_t x0; /**< saves previous input sample. */ + } csky_lms_norm_instance_q15; + + void csky_lms_norm_q15( + csky_lms_norm_instance_q15 * S, + q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + void csky_lms_norm_init_q15( + csky_lms_norm_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint8_t postShift); + + void csky_correlate_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + void csky_correlate_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + void csky_correlate_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + void csky_correlate_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + void csky_correlate_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + void csky_correlate_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + void csky_correlate_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + void csky_correlate_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + void csky_correlate_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + + /** + * @brief Instance structure for the floating-point sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + float32_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } csky_fir_sparse_instance_f32; + + /** + * @brief Instance structure for the Q31 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q31_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } csky_fir_sparse_instance_q31; + + /** + * @brief Instance structure for the Q15 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q15_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } csky_fir_sparse_instance_q15; + + /** + * @brief Instance structure for the Q7 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q7_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } csky_fir_sparse_instance_q7; + + void csky_fir_sparse_f32( + csky_fir_sparse_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + float32_t * pScratchIn, + uint32_t blockSize); + + void csky_fir_sparse_init_f32( + csky_fir_sparse_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + void csky_fir_sparse_q31( + csky_fir_sparse_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + q31_t * pScratchIn, + uint32_t blockSize); + + void csky_fir_sparse_init_q31( + csky_fir_sparse_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + void csky_fir_sparse_q15( + csky_fir_sparse_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + q15_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + void csky_fir_sparse_init_q15( + csky_fir_sparse_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + void csky_fir_sparse_q7( + csky_fir_sparse_instance_q7 * S, + q7_t * pSrc, + q7_t * pDst, + q7_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + void csky_fir_sparse_init_q7( + csky_fir_sparse_instance_q7 * S, + uint16_t numTaps, + q7_t * pCoeffs, + q7_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + void csky_sin_cos_f32( + float32_t theta, + float32_t * pSinVal, + float32_t * pCosVal); + + void csky_sin_cos_q31( + q31_t theta, + q31_t * pSinVal, + q31_t * pCosVal); + + void csky_cmplx_conj_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + void csky_cmplx_conj_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + void csky_cmplx_conj_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + void csky_cmplx_mag_squared_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + void csky_cmplx_mag_squared_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + void csky_cmplx_mag_squared_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + void csky_vsqrt_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + void csky_vsqrt_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + void csky_vsqrt_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t numSamples); + +/** + * @ingroup groupController + */ + +/** + * @defgroup PID PID Motor Control + * + * A Proportional Integral Derivative (PID) controller is a generic feedback control + * loop mechanism widely used in industrial control systems. + * A PID controller is the most commonly used type of feedback controller. + * + * This set of functions implements (PID) controllers + * for Q15, Q31, and floating-point data types. The functions operate on a single sample + * of data and each call to the function returns a single processed value. + * S points to an instance of the PID control data structure. in + * is the input sample value. The functions return the output value. + * + * \par Algorithm: + *
+ *    y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]
+ *    A0 = Kp + Ki + Kd
+ *    A1 = (-Kp ) - (2 * Kd )
+ *    A2 = Kd  
+ * + * \par + * where \c Kp is proportional constant, \c Ki is Integral constant and \c Kd is Derivative constant + * + * \par + * \image html PID.gif "Proportional Integral Derivative Controller" + * + * \par + * The PID controller calculates an "error" value as the difference between + * the measured output and the reference input. + * The controller attempts to minimize the error by adjusting the process control inputs. + * The proportional value determines the reaction to the current error, + * the integral value determines the reaction based on the sum of recent errors, + * and the derivative value determines the reaction based on the rate at which the error has been changing. + * + * \par Instance Structure + * The Gains A0, A1, A2 and state variables for a PID controller are stored together in an instance data structure. + * A separate instance structure must be defined for each PID Controller. + * There are separate instance structure declarations for each of the 3 supported data types. + * + * \par Reset Functions + * There is also an associated reset function for each data type which clears the state array. + * + * \par Initialization Functions + * There is also an associated initialization function for each data type. + * The initialization function performs the following operations: + * - Initializes the Gains A0, A1, A2 from Kp,Ki, Kd gains. + * - Zeros out the values in the state buffer. + * + * \par + * Instance structure cannot be placed into a const data section and it is recommended to use the initialization function. + * + * \par Fixed-Point Behavior + * Care must be taken when using the fixed-point versions of the PID Controller functions. + * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + +/** + * @addtogroup PID + * @{ + */ + +/** + * @brief Process function for the floating-point PID Control. + * @param[in,out] S is an instance of the floating-point PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + */ + __ALWAYS_STATIC_INLINE float32_t csky_pid_f32( + csky_pid_instance_f32 * S, + float32_t in) + { + float32_t out; + + /* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2] */ + out = (S->A0 * in) + + (S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]); + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + } + +/** + * @} +*/ // end of PID group + + +/** + * @addtogroup PID + * @{ + */ + +/** + * @brief Process function for the Q31 PID Control. + * @param[in,out] S points to an instance of the Q31 PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 64-bit accumulator. + * The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit. + * Thus, if the accumulator result overflows it wraps around rather than clip. + * In order to avoid overflows completely the input signal must be scaled down by 2 bits as there are four additions. + * After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format. + */ + __ALWAYS_STATIC_INLINE q31_t csky_pid_q31( + csky_pid_instance_q31 * S, + q31_t in) + { + q63_t acc; + q31_t out; + + #ifdef CSKY_SIMD + /* acc = A0 * x[n] */ + acc = mult_32x32_keep64(S->A0, in); + + /* acc += A1 * x[n-1] */ + acc = multAcc_32x32_keep64(acc, S->A1, S->state[0]); + + /* acc += A2 * x[n-2] */ + acc = multAcc_32x32_keep64(acc, S->A2, S->state[1]); + + /* convert output to 1.31 format to add y[n-1] */ + out = dext_31(acc); + #else + /* acc = A0 * x[n] */ + acc = (q63_t) S->A0 * in; + + /* acc += A1 * x[n-1] */ + acc += (q63_t) S->A1 * S->state[0]; + + /* acc += A2 * x[n-2] */ + acc += (q63_t) S->A2 * S->state[1]; + + /* convert output to 1.31 format to add y[n-1] */ + out = (q31_t) (acc >> 31u); + #endif + + /* out += y[n-1] */ + out += S->state[2]; + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + } + +/** + * @} + */ // end of PID group + +/** + * @addtogroup PID + * @{ + */ +/** + * @brief Process function for the Q15 PID Control. + * @param[in,out] S points to an instance of the Q15 PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using a 64-bit internal accumulator. + * Both Gains and state variables are represented in 1.15 format and multiplications yield a 2.30 result. + * The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format. + * There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved. + * After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits. + * Lastly, the accumulator is saturated to yield a result in 1.15 format. + */ + __ALWAYS_STATIC_INLINE q15_t csky_pid_q15( + csky_pid_instance_q15 * S, + q15_t in) + { + q63_t acc; + q15_t out; + + /* acc = A0 * x[n] */ + acc = ((q31_t) S->A0) * in; + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + acc += (q31_t) S->A1 * S->state[0]; + acc += (q31_t) S->A2 * S->state[1]; + + /* acc += y[n-1] */ + acc += (q31_t) S->state[2] << 15; + + /* saturate the output */ + out = (q15_t) (__SSAT_16((acc >> 15))); + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + } +/** + * @} + */ // end of PID group + + csky_status csky_mat_inverse_f32( + const csky_matrix_instance_f32 * src, + csky_matrix_instance_f32 * dst); + + csky_status csky_mat_inverse_f64( + const csky_matrix_instance_f64 * src, + csky_matrix_instance_f64 * dst); + +/** + * @ingroup groupController + */ + +/** + * @defgroup clarke Vector Clarke Transform + * Forward Clarke transform converts the instantaneous stator phases into a two-coordinate time invariant vector. + * Generally the Clarke transform uses three-phase currents Ia, Ib and Ic to calculate currents + * in the two-phase orthogonal stator axis Ialpha and Ibeta. + * When Ialpha is superposed with Ia as shown in the figure below + * \image html clarke.gif Stator current space vector and its components in (a,b). + * and Ia + Ib + Ic = 0, in this condition Ialpha and Ibeta + * can be calculated using only Ia and Ib. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeFormula.gif + * where Ia and Ib are the instantaneous stator phases and + * pIalpha and pIbeta are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + +/** + * @addtogroup clarke + * @{ + */ + +/** + * + * @brief Floating-point Clarke transform + * @param[in] Ia input three-phase coordinate a + * @param[in] Ib input three-phase coordinate b + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + */ + __ALWAYS_STATIC_INLINE void csky_clarke_f32( + float32_t Ia, + float32_t Ib, + float32_t * pIalpha, + float32_t * pIbeta) + { + /* Calculate pIalpha using the equation, pIalpha = Ia */ + *pIalpha = Ia; + + /* Calculate pIbeta using the equation, pIbeta = (1/sqrt(3)) * Ia + (2/sqrt(3)) * Ib */ + *pIbeta = ((float32_t) 0.57735026919 * Ia + (float32_t) 1.15470053838 * Ib); + } + +/** + * @} + */ // end of clarke group + + +/** + * @addtogroup clarke + * @{ + */ + +/** + * @brief Clarke transform for Q31 version + * @param[in] Ia input three-phase coordinate a + * @param[in] Ib input three-phase coordinate b + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition, hence there is no risk of overflow. + */ + __ALWAYS_STATIC_INLINE void csky_clarke_q31( + q31_t Ia, + q31_t Ib, + q31_t * pIalpha, + q31_t * pIbeta) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + + /* Calculating pIalpha from Ia by equation pIalpha = Ia */ + *pIalpha = Ia; + + #ifdef CSKY_SIMD + /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */ + product1 = mult_32x32_dext_30(Ia, 0x24F34E8B); + + /* Intermediate product is calculated by (2/sqrt(3) * Ib) */ + product2 = mult_32x32_dext_30(Ib, 0x49E69D16); + #else + /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) Ia * 0x24F34E8B) >> 30); + + /* Intermediate product is calculated by (2/sqrt(3) * Ib) */ + product2 = (q31_t) (((q63_t) Ib * 0x49E69D16) >> 30); + #endif + + /* pIbeta is calculated by adding the intermediate products */ + *pIbeta = __QADD(product1, product2); + } + + +/** + * @} + */ // end of clarke group + + void csky_q7_to_q31( + q7_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + +/** + * @ingroup groupController + */ +/** + * @defgroup inv_clarke Vector Inverse Clarke Transform + * Inverse Clarke transform converts the two-coordinate time invariant vector into instantaneous stator phases. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeInvFormula.gif + * where pIa and pIb are the instantaneous stator phases and + * Ialpha and Ibeta are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + +/** + * @addtogroup inv_clarke + * @{ + */ + + /** + * @brief Floating-point Inverse Clarke transform + * @param[in] Ialpha input two-phase orthogonal vector axis alpha + * @param[in] Ibeta input two-phase orthogonal vector axis beta + * @param[out] pIa points to output three-phase coordinate a + * @param[out] pIb points to output three-phase coordinate b + */ + __ALWAYS_STATIC_INLINE void csky_inv_clarke_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pIa, + float32_t * pIb) + { + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + + /* Calculating pIb from Ialpha and Ibeta by equation pIb = -(1/2) * Ialpha + (sqrt(3)/2) * Ibeta */ + *pIb = -0.5f * Ialpha + 0.8660254039f * Ibeta; + } + + +/** + * @} + */ // end of inv_clarke group + +/** + * @addtogroup inv_clarke + * @{ + */ + +/** + * @brief Inverse Clarke transform for Q31 version + * @param[in] Ialpha input two-phase orthogonal vector axis alpha + * @param[in] Ibeta input two-phase orthogonal vector axis beta + * @param[out] pIa points to output three-phase coordinate a + * @param[out] pIb points to output three-phase coordinate b + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the subtraction, hence there is no risk of overflow. + */ + __ALWAYS_STATIC_INLINE void csky_inv_clarke_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pIa, + q31_t * pIb) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + + #ifdef CSKY_SIMD + /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */ + product1 = mult_32x32_dext_31(Ialpha, 0x40000000); + + /* Intermediate product is calculated by (1/sqrt(3) * pIb) */ + product2 = mult_32x32_dext_31(Ibeta, 0x6ED9EBA1); + #else + /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) (Ialpha) * (0x40000000)) >> 31); + + /* Intermediate product is calculated by (1/sqrt(3) * pIb) */ + product2 = (q31_t) (((q63_t) (Ibeta) * (0x6ED9EBA1)) >> 31); + #endif + + /* pIb is calculated by subtracting the products */ + *pIb = __QSUB(product2, product1); + } + +/** + * @} + */ // end of inv_clarke group + + void csky_q7_to_q15( + q7_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + +/** + * @ingroup groupController + */ +/** + * @defgroup park Vector Park Transform + * + * Forward Park transform converts the input two-coordinate vector to flux and torque components. + * The Park transform can be used to realize the transformation of the Ialpha and the Ibeta currents + * from the stationary to the moving reference frame and control the spatial relationship between + * the stator vector current and rotor flux vector. + * If we consider the d axis aligned with the rotor flux, the diagram below shows the + * current vector and the relationship from the two reference frames: + * \image html park.gif "Stator current space vector and its component in (a,b) and in the d,q rotating reference frame" + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkFormula.gif + * where Ialpha and Ibeta are the stator vector components, + * pId and pIq are rotor vector components and cosVal and sinVal are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ +/** + * @addtogroup park + * @{ + */ +/** + * @brief Floating-point Park transform + * @param[in] Ialpha input two-phase vector coordinate alpha + * @param[in] Ibeta input two-phase vector coordinate beta + * @param[out] pId points to output rotor reference frame d + * @param[out] pIq points to output rotor reference frame q + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * + * The function implements the forward Park transform. + * + */ + __ALWAYS_STATIC_INLINE void csky_park_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pId, + float32_t * pIq, + float32_t sinVal, + float32_t cosVal) +{ + /* Calculate pId using the equation, pId = Ialpha * cosVal + Ibeta * sinVal */ + *pId = Ialpha * cosVal + Ibeta * sinVal; + /* Calculate pIq using the equation, pIq = - Ialpha * sinVal + Ibeta * cosVal */ + *pIq = -Ialpha * sinVal + Ibeta * cosVal; +} +/** + * @} + */ // end of park group + +/** + * @addtogroup park + * @{ + */ +/** + * @brief Park transform for Q31 version + * @param[in] Ialpha input two-phase vector coordinate alpha + * @param[in] Ibeta input two-phase vector coordinate beta + * @param[out] pId points to output rotor reference frame d + * @param[out] pIq points to output rotor reference frame q + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition and subtraction, hence there is no risk of overflow. + */ + __ALWAYS_STATIC_INLINE void csky_park_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pId, + q31_t * pIq, + q31_t sinVal, + q31_t cosVal) +{ +#ifdef CSKY_SIMD + __ASM volatile( + "rmul.s32.h t0, %0, %3\n\t" + "rmul.s32.h t1, %1, %2\n\t" + "add.s32.s t0, t0, t1\n\t" + "st.w t0, (%4, 0x0)\n\t" + "rmul.s32.h t0, %0, %2\n\t" + "rmul.s32.h t1, %1, %3\n\t" + "sub.s32.s t1, t1, t0\n\t" + "st.w t1, (%5, 0x0)\n\t" + ::"r"(Ialpha),"r"(Ibeta),"r"(sinVal),"r"(cosVal),"r"(pId),"r"(pIq) + :"t0","t1", "memory"); +#else + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + /* Intermediate product is calculated by (Ialpha * cosVal) */ + product1 = clip_q63_to_q31 (((q63_t) (Ialpha) * (cosVal)) >> 31); + /* Intermediate product is calculated by (Ibeta * sinVal) */ + product2 = clip_q63_to_q31 (((q63_t) (Ibeta) * (sinVal)) >> 31); + /* Intermediate product is calculated by (Ialpha * sinVal) */ + product3 = clip_q63_to_q31 (((q63_t) (Ialpha) * (sinVal)) >> 31); + /* Intermediate product is calculated by (Ibeta * cosVal) */ + product4 = clip_q63_to_q31 (((q63_t) (Ibeta) * (cosVal)) >> 31); + /* Calculate pId by adding the two intermediate products 1 and 2 */ + *pId = __QADD(product1, product2); + /* Calculate pIq by subtracting the two intermediate products 3 from 4 */ + *pIq = __QSUB(product4, product3); +#endif +} +/** + * @} + */ // end of park group + + void csky_q7_to_float( + q7_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + +/** + * @ingroup groupController + */ +/** + * @defgroup inv_park Vector Inverse Park transform + * Inverse Park transform converts the input flux and torque components to two-coordinate vector. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkInvFormula.gif + * where pIalpha and pIbeta are the stator vector components, + * Id and Iq are rotor vector components and cosVal and sinVal are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ +/** + * @addtogroup inv_park + * @{ + */ + /** + * @brief Floating-point Inverse Park transform + * @param[in] Id input coordinate of rotor reference frame d + * @param[in] Iq input coordinate of rotor reference frame q + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + */ + __ALWAYS_STATIC_INLINE void csky_inv_park_f32( + float32_t Id, + float32_t Iq, + float32_t * pIalpha, + float32_t * pIbeta, + float32_t sinVal, + float32_t cosVal) +{ + /* Calculate pIalpha using the equation, pIalpha = Id * cosVal - Iq * sinVal */ + *pIalpha = Id * cosVal - Iq * sinVal; + /* Calculate pIbeta using the equation, pIbeta = Id * sinVal + Iq * cosVal */ + *pIbeta = Id * sinVal + Iq * cosVal; +} +/** + * @} + */ // end of inv_park group + +/** + * @addtogroup inv_park + * @{ + */ +/** + * @brief Inverse Park transform for Q31 version + * @param[in] Id input coordinate of rotor reference frame d + * @param[in] Iq input coordinate of rotor reference frame q + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition, hence there is no risk of overflow. + */ + __ALWAYS_STATIC_INLINE void csky_inv_park_q31( + q31_t Id, + q31_t Iq, + q31_t * pIalpha, + q31_t * pIbeta, + q31_t sinVal, + q31_t cosVal) +{ +#ifdef CSKY_SIMD + __ASM volatile( + "rmul.s32.h t0, %0, %3\n\t" + "rmul.s32.h t1, %1, %2\n\t" + "sub.s32.s t0, t0, t1\n\t" + "st.w t0, (%4, 0x0)\n\t" + "rmul.s32.h t0, %0, %2\n\t" + "rmul.s32.h t1, %1, %3\n\t" + "add.s32.s t0, t0, t1\n\t" + "st.w t0, (%5, 0x0)\n\t" + ::"r"(Id),"r"(Iq),"r"(sinVal),"r"(cosVal),"r"(pIalpha),"r"(pIbeta) + :"t0","t1", "memory"); + +#else + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + /* Intermediate product is calculated by (Id * cosVal) */ + product1 = clip_q63_to_q31 (((q63_t) (Id) * (cosVal)) >> 31); + /* Intermediate product is calculated by (Iq * sinVal) */ + product2 = clip_q63_to_q31 (((q63_t) (Iq) * (sinVal)) >> 31); + /* Intermediate product is calculated by (Id * sinVal) */ + product3 = clip_q63_to_q31 (((q63_t) (Id) * (sinVal)) >> 31); + /* Intermediate product is calculated by (Iq * cosVal) */ + product4 = clip_q63_to_q31 (((q63_t) (Iq) * (cosVal)) >> 31); + /* Calculate pIalpha by using the two intermediate products 1 and 2 */ + *pIalpha = __QSUB(product1, product2); + /* Calculate pIbeta by using the two intermediate products 3 and 4 */ + *pIbeta = __QADD(product4, product3); +#endif +} + +/** + * @} + */ // end of inv_park group + + void csky_q31_to_float( + q31_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + +/** + * @ingroup groupInterpolation + */ +/** + * @defgroup LinearInterpolate Linear Interpolation + * + * Linear interpolation is a method of curve fitting using linear polynomials. + * Linear interpolation works by effectively drawing a straight line between two neighboring samples and returning the appropriate point along that line + * + * \par + * \image html LinearInterp.gif "Linear interpolation" + * + * \par + * A Linear Interpolate function calculates an output value(y), for the input(x) + * using linear interpolation of the input values x0, x1( nearest input values) and the output values y0 and y1(nearest output values) + * + * \par Algorithm: + *
+ *       y = y0 + (x - x0) * ((y1 - y0)/(x1-x0))
+ *       where x0, x1 are nearest values of input x
+ *             y0, y1 are nearest values to output y
+ * 
+ * + * \par + * This set of functions implements Linear interpolation process + * for Q7, Q15, Q31, and floating-point data types. The functions operate on a single + * sample of data and each call to the function returns a single processed value. + * S points to an instance of the Linear Interpolate function data structure. + * x is the input sample value. The functions returns the output value. + * + * \par + * if x is outside of the table boundary, Linear interpolation returns first value of the table + * if x is below input range and returns last value of table if x is above range. + */ +/** + * @addtogroup LinearInterpolate + * @{ + */ +/** + * @brief Process function for the floating-point Linear Interpolation Function. + * @param[in,out] S is an instance of the floating-point Linear Interpolation structure + * @param[in] x input sample to process + * @return y processed output sample. + * + */ +__ALWAYS_STATIC_INLINE float32_t csky_linear_interp_f32( +csky_linear_interp_instance_f32 * S, +float32_t x) +{ + float32_t y; + float32_t x0, x1; /* Nearest input values */ + float32_t y0, y1; /* Nearest output values */ + float32_t xSpacing = S->xSpacing; /* spacing between input values */ + int32_t i; /* Index variable */ + float32_t *pYData = S->pYData; /* pointer to output table */ + /* Calculation of index */ + i = (int32_t) ((x - S->x1) / xSpacing); + if(i < 0) + { + /* Iniatilize output for below specified range as least output value of table */ + y = pYData[0]; + } + else if((uint32_t)i >= S->nValues) + { + /* Iniatilize output for above specified range as last output value of table */ + y = pYData[S->nValues - 1]; + } + else + { + /* Calculation of nearest input values */ + x0 = S->x1 + i * xSpacing; + x1 = S->x1 + (i + 1) * xSpacing; + /* Read of nearest output values */ + y0 = pYData[i]; + y1 = pYData[i + 1]; + /* Calculation of output */ + y = y0 + (x - x0) * ((y1 - y0) / (x1 - x0)); + } + /* returns output value */ + return (y); +} +/** + * @} + */ // end of LinearInterpolate group + +/** + * @addtogroup LinearInterpolate + * @{ + */ + +/** + * @brief Process function for the Q31 Linear Interpolation Function. + * @param[in] pYData pointer to Q31 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ +__ALWAYS_STATIC_INLINE q31_t csky_linear_interp_q31( +q31_t * pYData, +q31_t x, +uint32_t nValues) +{ + q31_t y; /* output */ + q31_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & (q31_t)0xFFF00000) >> 20); + if(index >= (int32_t)(nValues - 1)) + { + return (pYData[nValues - 1]); + } + else if(index < 0) + { + return (pYData[0]); + } + else + { + /* 20 bits for the fractional part */ + /* shift left by 11 to keep fract in 1.31 format */ + fract = (x & 0x000FFFFF) << 11; + /* Read two nearest output values from the index in 1.31(q31) format */ + y0 = pYData[index]; + y1 = pYData[index + 1]; +#ifdef CSKY_SIMD + /* Calculation of y0 * (1-fract) and y is in 2.30 format */ + y = mult_32x32_keep32(y0, (0x7FFFFFFF - fract)); + /* Calculation of y0 * (1-fract) + y1 *fract and y is in 2.30 format */ + y = multAcc_32x32_keep32(y, y1, fract); +#else + /* Calculation of y0 * (1-fract) and y is in 2.30 format */ + y = ((q31_t) ((q63_t) y0 * (0x7FFFFFFF - fract) >> 32)); + /* Calculation of y0 * (1-fract) + y1 *fract and y is in 2.30 format */ + y += ((q31_t) (((q63_t) y1 * fract) >> 32)); +#endif + /* Convert y to 1.31 format */ + return (y << 1u); + } +} +/** + * @} + */ // end of LinearInterpolate group + +/** + * @addtogroup LinearInterpolate + * @{ + */ +/** + * + * @brief Process function for the Q15 Linear Interpolation Function. + * @param[in] pYData pointer to Q15 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ +__ALWAYS_STATIC_INLINE q15_t csky_linear_interp_q15( +q15_t * pYData, +q31_t x, +uint32_t nValues) +{ + q63_t y; /* output */ + q15_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & (int32_t)0xFFF00000) >> 20); + if(index >= (int32_t)(nValues - 1)) + { + return (pYData[nValues - 1]); + } + else if(index < 0) + { + return (pYData[0]); + } + else + { + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + /* Read two nearest output values from the index */ + y0 = pYData[index]; + y1 = pYData[index + 1]; +#ifdef CSKY_SIMD + /* Calculation of y0 * (1-fract) and y is in 13.35 format */ + y = mult_32x32_keep64(y0, (0xFFFFF - fract)); + /* Calculation of (y0 * (1-fract) + y1 * fract) and y is in 13.35 format */ + y = multAcc_32x32_keep64(y, y1, (fract)); +#else + /* Calculation of y0 * (1-fract) and y is in 13.35 format */ + y = ((q63_t) y0 * (0xFFFFF - fract)); + /* Calculation of (y0 * (1-fract) + y1 * fract) and y is in 13.35 format */ + y += ((q63_t) y1 * (fract)); +#endif + /* convert y to 1.15 format */ + return (q15_t) (y >> 20); + } +} +/** + * @} + */ // end of LinearInterpolate group + +/** + * @addtogroup LinearInterpolate + * @{ + */ +/** + * + * @brief Process function for the Q7 Linear Interpolation Function. + * @param[in] pYData pointer to Q7 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + */ +__ALWAYS_STATIC_INLINE q7_t csky_linear_interp_q7( +q7_t * pYData, +q31_t x, +uint32_t nValues) +{ + q31_t y; /* output */ + q7_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + uint32_t index; /* Index to read nearest output values */ + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + if (x < 0) + { + return (pYData[0]); + } + index = (x >> 20) & 0xfff; + if(index >= (nValues - 1)) + { + return (pYData[nValues - 1]); + } + else + { + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + /* Read two nearest output values from the index and are in 1.7(q7) format */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + /* Calculation of y0 * (1-fract ) and y is in 13.27(q27) format */ + y = ((y0 * (0xFFFFF - fract))); + /* Calculation of y1 * fract + y0 * (1-fract) and y is in 13.27(q27) format */ + y += (y1 * fract); + /* convert y to 1.7(q7) format */ + return (q7_t) (y >> 20); + } +} +/** + * @} + */ // end of LinearInterpolate group + + float32_t csky_sin_f32( + float32_t x); + + q31_t csky_sin_q31( + q31_t x); + + q15_t csky_sin_q15( + q15_t x); + + float32_t csky_cos_f32( + float32_t x); + + q31_t csky_cos_q31( + q31_t x); + + q15_t csky_cos_q15( + q15_t x); + + csky_status csky_sqrt_f32( + float32_t in, + float32_t * pOut); + + csky_status csky_sqrt_q31( + q31_t in, + q31_t * pOut); + + csky_status csky_sqrt_q15( + q15_t in, + q15_t * pOut); + + void csky_power_q31( + q31_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + void csky_power_int32( + int32_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + void csky_power_int32( + int32_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + void csky_power_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + void csky_power_q15( + q15_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + void csky_power_q7( + q7_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + void csky_mean_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult); + + void csky_mean_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + void csky_mean_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + void csky_mean_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + void csky_var_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + void csky_var_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + void csky_var_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + void csky_rms_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + void csky_rms_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + void csky_rms_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + void csky_std_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + void csky_std_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + void csky_std_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + void csky_cmplx_mag_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + void csky_cmplx_mag_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + void csky_cmplx_mag_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + void csky_cmplx_dot_prod_q15( + q15_t * pSrcA, + q15_t * pSrcB, + uint32_t numSamples, + q31_t * realResult, + q31_t * imagResult); + + void csky_cmplx_dot_prod_q31( + q31_t * pSrcA, + q31_t * pSrcB, + uint32_t numSamples, + q63_t * realResult, + q63_t * imagResult); + + void csky_cmplx_dot_prod_f32( + float32_t * pSrcA, + float32_t * pSrcB, + uint32_t numSamples, + float32_t * realResult, + float32_t * imagResult); + + void csky_cmplx_mult_real_q15( + q15_t * pSrcCmplx, + q15_t * pSrcReal, + q15_t * pCmplxDst, + uint32_t numSamples); + + void csky_cmplx_mult_real_q31( + q31_t * pSrcCmplx, + q31_t * pSrcReal, + q31_t * pCmplxDst, + uint32_t numSamples); + + void csky_cmplx_mult_real_f32( + float32_t * pSrcCmplx, + float32_t * pSrcReal, + float32_t * pCmplxDst, + uint32_t numSamples); + + void csky_min_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * result, + uint32_t * index); + + void csky_min_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + + void csky_min_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + + void csky_min_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + + void csky_max_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult, + uint32_t * pIndex); + + void csky_max_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + + void csky_max_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + + void csky_max_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + + void csky_cmplx_mult_cmplx_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t numSamples); + + void csky_cmplx_mult_cmplx_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t numSamples); + + void csky_cmplx_mult_cmplx_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t numSamples); + + void csky_cmplx_mult_cmplx_re_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t numSamples); + + void csky_cmplx_mult_cmplx_re_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t numSamples); + + void csky_cmplx_mult_cmplx_re_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t numSamples); + + + void csky_float_to_q31( + float32_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + void csky_float_to_q15( + float32_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + void csky_float_to_q7( + float32_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + void csky_q31_to_q15( + q31_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + void csky_q31_to_q7( + q31_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + void csky_q15_to_float( + q15_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + void csky_q15_to_q31( + q15_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + void csky_q15_to_q7( + q15_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + +/** + * @ingroup groupInterpolation + */ +/** + * @defgroup BilinearInterpolate Bilinear Interpolation + * + * Bilinear interpolation is an extension of linear interpolation applied to a two dimensional grid. + * The underlying function f(x, y) is sampled on a regular grid and the interpolation process + * determines values between the grid points. + * Bilinear interpolation is equivalent to two step linear interpolation, first in the x-dimension and then in the y-dimension. + * Bilinear interpolation is often used in image processing to rescale images. + * The CSI DSP library provides bilinear interpolation functions for Q7, Q15, Q31, and floating-point data types. + * + * Algorithm + * \par + * The instance structure used by the bilinear interpolation functions describes a two dimensional data table. + * For floating-point, the instance structure is defined as: + *
+ *   typedef struct
+ *   {
+ *     uint16_t numRows;
+ *     uint16_t numCols;
+ *     float32_t *pData;
+ * } csky_bilinear_interp_instance_f32;
+ * 
+ * + * \par + * where numRows specifies the number of rows in the table; + * numCols specifies the number of columns in the table; + * and pData points to an array of size numRows*numCols values. + * The data table pTable is organized in row order and the supplied data values fall on integer indexes. + * That is, table element (x,y) is located at pTable[x + y*numCols] where x and y are integers. + * + * \par + * Let (x, y) specify the desired interpolation point. Then define: + *
+ *     XF = floor(x)
+ *     YF = floor(y)
+ * 
+ * \par + * The interpolated output point is computed as: + *
+ *  f(x, y) = f(XF, YF) * (1-(x-XF)) * (1-(y-YF))
+ *           + f(XF+1, YF) * (x-XF)*(1-(y-YF))
+ *           + f(XF, YF+1) * (1-(x-XF))*(y-YF)
+ *           + f(XF+1, YF+1) * (x-XF)*(y-YF)
+ * 
+ * Note that the coordinates (x, y) contain integer and fractional components. + * The integer components specify which portion of the table to use while the + * fractional components control the interpolation processor. + * + * \par + * if (x,y) are outside of the table boundary, Bilinear interpolation returns zero output. + */ +/** + * @addtogroup BilinearInterpolate + * @{ + */ +/** +* +* @brief Floating-point bilinear interpolation. +* @param[in,out] S points to an instance of the interpolation structure. +* @param[in] X interpolation coordinate. +* @param[in] Y interpolation coordinate. +* @return out interpolated value. +*/ +__ALWAYS_STATIC_INLINE float32_t csky_bilinear_interp_f32( +const csky_bilinear_interp_instance_f32 * S, +float32_t X, +float32_t Y) +{ + float32_t out; + float32_t f00, f01, f10, f11; + float32_t *pData = S->pData; + int32_t xIndex, yIndex, index; + float32_t xdiff, ydiff; + float32_t b1, b2, b3, b4; + xIndex = (int32_t) X; + yIndex = (int32_t) Y; + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if(xIndex < 0 || xIndex > (S->numRows - 1) || yIndex < 0 || yIndex > (S->numCols - 1)) + { + return (0); + } + /* Calculation of index for two nearest points in X-direction */ + index = (xIndex - 1) + (yIndex - 1) * S->numCols; + /* Read two nearest points in X-direction */ + f00 = pData[index]; + f01 = pData[index + 1]; + /* Calculation of index for two nearest points in Y-direction */ + index = (xIndex - 1) + (yIndex) * S->numCols; + /* Read two nearest points in Y-direction */ + f10 = pData[index]; + f11 = pData[index + 1]; + /* Calculation of intermediate values */ + b1 = f00; + b2 = f01 - f00; + b3 = f10 - f00; + b4 = f00 - f01 - f10 + f11; + /* Calculation of fractional part in X */ + xdiff = X - xIndex; + /* Calculation of fractional part in Y */ + ydiff = Y - yIndex; + /* Calculation of bi-linear interpolated output */ + out = b1 + b2 * xdiff + b3 * ydiff + b4 * xdiff * ydiff; + /* return to application */ + return (out); +} +/** + * @} + */ // end of BilinearInterpolate group + +/** + * @addtogroup BilinearInterpolate + * @{ + */ +/** +* +* @brief Q31 bilinear interpolation. +* @param[in,out] S points to an instance of the interpolation structure. +* @param[in] X interpolation coordinate in 12.20 format. +* @param[in] Y interpolation coordinate in 12.20 format. +* @return out interpolated value. +*/ +__ALWAYS_STATIC_INLINE q31_t csky_bilinear_interp_q31( +csky_bilinear_interp_instance_q31 * S, +q31_t X, +q31_t Y) +{ + q31_t out; /* Temporary output */ + q31_t acc = 0; /* output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q31_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q31_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + return (0); + } + /* 20 bits for the fractional part */ + /* shift left xfract by 11 to keep 1.31 format */ + xfract = (X & 0x000FFFFF) << 11u; + /* Read two nearest output values from the index */ + x1 = pYData[(rI) + (int32_t)nCols * (cI) ]; + x2 = pYData[(rI) + (int32_t)nCols * (cI) + 1]; + /* 20 bits for the fractional part */ + /* shift left yfract by 11 to keep 1.31 format */ + yfract = (Y & 0x000FFFFF) << 11u; + /* Read two nearest output values from the index */ + y1 = pYData[(rI) + (int32_t)nCols * (cI + 1) ]; + y2 = pYData[(rI) + (int32_t)nCols * (cI + 1) + 1]; +#ifdef CSKY_SIMD + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 3.29(q29) format */ + out = mult_32x32_keep32(x1, (0x7FFFFFFF - xfract)); + acc = mult_32x32_keep32(out, (0x7FFFFFFF - yfract)); + /* x2 * (xfract) * (1-yfract) in 3.29(q29) and adding to acc */ + out = mult_32x32_keep32(x2, (0x7FFFFFFF - yfract)); + acc = multAcc_32x32_keep32(acc, out, xfract); + /* y1 * (1 - xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = mult_32x32_keep32(y1, (0x7FFFFFFF - xfract)); + acc = multAcc_32x32_keep32(acc, out, yfract); + /* y2 * (xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = mult_32x32_keep32(y2, xfract); + acc = multAcc_32x32_keep32(acc, out, yfract); +#else + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 3.29(q29) format */ + out = ((q31_t) (((q63_t) x1 * (0x7FFFFFFF - xfract)) >> 32)); + acc = ((q31_t) (((q63_t) out * (0x7FFFFFFF - yfract)) >> 32)); + /* x2 * (xfract) * (1-yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) x2 * (0x7FFFFFFF - yfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (xfract) >> 32)); + /* y1 * (1 - xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y1 * (0x7FFFFFFF - xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); + /* y2 * (xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y2 * (xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); +#endif + /* Convert acc to 1.31(q31) format */ + return ((q31_t)(acc << 2)); +} +/** + * @} + */ // end of BilinearInterpolate group + +/** + * @addtogroup BilinearInterpolate + * @{ + */ +/** +* @brief Q15 bilinear interpolation. +* @param[in,out] S points to an instance of the interpolation structure. +* @param[in] X interpolation coordinate in 12.20 format. +* @param[in] Y interpolation coordinate in 12.20 format. +* @return out interpolated value. +*/ +__ALWAYS_STATIC_INLINE q15_t csky_bilinear_interp_q15( +csky_bilinear_interp_instance_q15 * S, +q31_t X, +q31_t Y) +{ + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q15_t x1, x2, y1, y2; /* Nearest output values */ + q31_t xfract, yfract; /* X, Y fractional parts */ + int32_t rI, cI; /* Row and column indices */ + q15_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + return (0); + } + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & 0x000FFFFF); + /* Read two nearest output values from the index */ + x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ]; + x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1]; + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & 0x000FFFFF); + /* Read two nearest output values from the index */ + y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ]; + y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1]; + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 13.51 format */ + /* x1 is in 1.15(q15), xfract in 12.20 format and out is in 13.35 format */ + /* convert 13.35 to 13.31 by right shifting and out is in 1.31 */ +#ifdef CSKY_SIMD + out = mult_32x32_dext_4(x1, (0xFFFFF - xfract)); + acc = mult_32x32_keep64(out, (0xFFFFF - yfract)); + /* x2 * (xfract) * (1-yfract) in 1.51 and adding to acc */ + out = mult_32x32_dext_4(x2, (0xFFFFF - yfract)); + acc = multAcc_32x32_keep64(acc, out, (xfract)); + /* y1 * (1 - xfract) * (yfract) in 1.51 and adding to acc */ + out = mult_32x32_dext_4(y1, (0xFFFFF - xfract)); + acc = multAcc_32x32_keep64(acc, out, (yfract)); + /* y2 * (xfract) * (yfract) in 1.51 and adding to acc */ + out = mult_32x32_dext_4(y2, (xfract)); + acc = multAcc_32x32_keep64(acc, out, (yfract)); +#else + out = (q31_t) (((q63_t) x1 * (0xFFFFF - xfract)) >> 4u); + acc = ((q63_t) out * (0xFFFFF - yfract)); + /* x2 * (xfract) * (1-yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) x2 * (0xFFFFF - yfract)) >> 4u); + acc += ((q63_t) out * (xfract)); + /* y1 * (1 - xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y1 * (0xFFFFF - xfract)) >> 4u); + acc += ((q63_t) out * (yfract)); + /* y2 * (xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y2 * (xfract)) >> 4u); + acc += ((q63_t) out * (yfract)); +#endif + /* acc is in 13.51 format and down shift acc by 36 times */ + /* Convert out to 1.15 format */ + return ((q15_t)(acc >> 36)); +} +/** + * @} + */ // end of BilinearInterpolate group + +/** + * @addtogroup BilinearInterpolate + * @{ + */ +/** +* @brief Q7 bilinear interpolation. +* @param[in,out] S points to an instance of the interpolation structure. +* @param[in] X interpolation coordinate in 12.20 format. +* @param[in] Y interpolation coordinate in 12.20 format. +* @return out interpolated value. +*/ +__ALWAYS_STATIC_INLINE q7_t csky_bilinear_interp_q7( +csky_bilinear_interp_instance_q7 * S, +q31_t X, +q31_t Y) +{ + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q7_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q7_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + return (0); + } + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & (q31_t)0x000FFFFF); + /* Read two nearest output values from the index */ + x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ]; + x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1]; + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & (q31_t)0x000FFFFF); + /* Read two nearest output values from the index */ + y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ]; + y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1]; + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 16.47 format */ + out = ((x1 * (0xFFFFF - xfract))); +#ifdef CSKY_SIMD + acc = multAcc_32x32_keep64(acc, out, (0xFFFFF - yfract)); + /* x2 * (xfract) * (1-yfract) in 2.22 and adding to acc */ + out = ((x2 * (0xFFFFF - yfract))); + acc = multAcc_32x32_keep64(acc, out, xfract); + /* y1 * (1 - xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y1 * (0xFFFFF - xfract))); + acc = multAcc_32x32_keep64(acc, out, yfract); + /* y2 * (xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y2 * (yfract))); + acc = multAcc_32x32_keep64(acc, out, xfract); +#else + acc = (((q63_t) out * (0xFFFFF - yfract))); + /* x2 * (xfract) * (1-yfract) in 2.22 and adding to acc */ + out = ((x2 * (0xFFFFF - yfract))); + acc += (((q63_t) out * (xfract))); + /* y1 * (1 - xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y1 * (0xFFFFF - xfract))); + acc += (((q63_t) out * (yfract))); + /* y2 * (xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y2 * (yfract))); + acc += (((q63_t) out * (xfract))); +#endif + /* acc in 16.47 format and down shift by 40 to convert to 1.7 format */ + return ((q7_t)(acc >> 40)); +} +/** + * @} + */ // end of BilinearInterpolate group + +/** + * @ingroup groupMath + */ + +/** + * @defgroup ShiftRight Right Shift + * + * Shift the input value to right with appointed bits, its basic format is: + *
+ *     a = (a) >> (shift),   1 =< shift <= bitof(a) - 1.
+ * 
+ * The basic format is only designed for q31. + * + * and the extended format should be rounding to +inf: + *
+ *     a = (a + (1<<(shift - 1)) >> (shift),   1 =< shift <= bitof(a) - 1.
+ * 
+ * + * which are designed for q31, q31 positive and q63. + */ + +/** + * @addtogroup ShiftRight + * @{ + */ +/** + * @brief right shift Q31 version + * @param[in] a input value to be shift. + * @param[in] shift input positive value, the number of bits to be shift. + * @param[out] result the shifted a. + * + * Scaling and Overflow Behavior: + * \par + * The function is only used for right shift. So, the value of shift is + * between[1,31]. + */ + __ALWAYS_STATIC_INLINE q31_t csky_shr_q31( + q31_t a, + q31_t shift) +{ + q31_t res; +#ifdef CSKY_SIMD + __ASM volatile( + "asr %0, %1, %2\n\t" + :"=r"(res), "=r"(a),"=r"(shift):"0"(res), "1"(a), "2"(shift)); +#else + res = ((a) >> (shift)); +#endif + return res; +} + +#define SHR(a, shift) csky_shr_q31(a, shift) + +/** + * @} + */ // end of ShiftRight group + + +/** + * @addtogroup ShiftRight + * @{ + */ +/** + * @brief right shift Q31 version + * @param[in] a input value to be shift. + * @param[in] shift input positive value, the number of bits to be shift. + * @param[out] result the shifted a. + * + * Scaling and Overflow Behavior: + * \par + * The function is only used for right shift. So, the value of shift is + * between[1,31]. And the output value is rounding to +inf. + */ + __ALWAYS_STATIC_INLINE q31_t csky_pshr_q31( + q31_t a, + q31_t shift) +{ + q31_t res; +#ifdef CSKY_SIMD + __ASM volatile( + "asr.s32.r %0, %1, %2\n\t" + :"=r"(res), "=r"(a),"=r"(shift):"0"(res), "1"(a), "2"(shift)); +#else + res = (a >= 0?(SHR((a) + (1<<(shift - 1)), shift))\ + :(SHR((a) + ((1<>1) -1, shift))); +#endif + return res; +} + +/** + * @} + */ // end of ShiftRight group + + +/** + * @addtogroup ShiftRight + * @{ + */ +/** + * @brief right shift Q31 version + * @param[in] a input positive value to be shift. + * @param[in] shift input positive value, the number of bits to be shift. + * @param[out] result the shifted a. + * + * Scaling and Overflow Behavior: + * \par + * The function is only used for right shift. So, the value of shift is + * between[1,31]. And the output value is rounding to +inf. + */ + __ALWAYS_STATIC_INLINE q31_t csky_pshr_pos_q31( + q31_t a, + q31_t shift) +{ + q31_t res; +#ifdef CSKY_SIMD + __ASM volatile( + "asr.s32.r %0, %1, %2\n\t" + :"=r"(res), "=r"(a),"=r"(shift):"0"(res), "1"(a), "2"(shift)); +#else + res = SHR((a) + (1<<(shift - 1)), shift); +#endif + return res; +} + +/** + * @} + */ // end of ShiftRight group + + +/** + * @addtogroup ShiftRight + * @{ + */ +/** + * @brief right shift Q63 version + * @param[in] a input value to be shift. + * @param[in] shift input positive value, the number of bits to be shift. + * @param[out] result the shifted a. + * + * Scaling and Overflow Behavior: + * \par + * The function is only used for right shift. So, the value of shift is + * between[1,63]. And the output value is rounding to +inf. + */ + __ALWAYS_STATIC_INLINE q63_t csky_pshr_q63( + q63_t a, + q31_t shift) +{ + q63_t res; +#ifdef CSKY_SIMD + __ASM volatile( + "subi t0, %2, 1\n\t" + "cmphsi t0, 32\n\t" + "bt 1f\n\t" + "movi t1, 1\n\t" + "lsl t0, t1, t0\n\t" + "movi t1, 0\n\t" + "add.s64.s %1, %1, t0\n\t" + "dext %0, %1, %R1, %2\n\t" + "asr %R0, %R1, %2\n\t" + "br 2f\n\t" + "1:\n\t" + "subi %2, %2, 32\n\t" + "subi t0, t0, 32\n\t" + "movi t1, 1\n\t" + "lsl t1, t1, t0\n\t" + "add.s32.s %R1, %R1, t1\n\t" + "asr %0, %R1, %2\n\t" + "asri %R0, %R1, 31\n\t" + "2:\n\t" + :"=r"(res), "=r"(a),"=r"(shift):"0"(res), "1"(a), "2"(shift):"t0", "t1"); +#else + res = (a >= 0?(SHR((a) + ((q63_t)1<<(shift - 1)), shift))\ + :(SHR((a) + (((q63_t)1<>1) -1, shift))); +#endif + return res; +} + +/** + * @} + */ // end of ShiftRight group + +//#define SHR(a, shift) csky_shr_q31(a, shift) +#define PSHR(a, shift) csky_pshr_q31(a, shift) +#define PSHR_POSITIVE(a, shift) csky_pshr_pos_q31(a, shift) +#define PSHR64(a, shift) csky_pshr_q63(a, shift) + + +#ifdef CSKY_SIMD +#else +/* SMMLAR */ +#define multAcc_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((((q63_t) a) << 32) + ((q63_t) x * y) + 0x80000000LL ) >> 32) + +/* SMMLSR */ +#define multSub_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((((q63_t) a) << 32) - ((q63_t) x * y) + 0x80000000LL ) >> 32) + +/* SMMULR */ +#define mult_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((q63_t) x * y + 0x80000000LL ) >> 32) + +/* SMMLA */ +#define multAcc_32x32_keep32(a, x, y) \ + a += (q31_t) (((q63_t) x * y) >> 32) + +/* SMMLS */ +#define multSub_32x32_keep32(a, x, y) \ + a -= (q31_t) (((q63_t) x * y) >> 32) + +/* SMMUL */ +#define mult_32x32_keep32(a, x, y) \ + a = (q31_t) (((q63_t) x * y ) >> 32) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _CSKY_MATH_H */ + +/** + * + * End of file. + */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/dsp/csky_vdsp2_const_structs.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/dsp/csky_vdsp2_const_structs.h new file mode 100644 index 00000000..618f5f92 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/dsp/csky_vdsp2_const_structs.h @@ -0,0 +1,232 @@ +/* + * Copyright (C) 2016-2019 C-SKY 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 csky_vdsp2_const_structs.h + * @brief This file has constant structs that are initialized for + * user convenience. For example, some can be given as + * arguments to the csky_vdsp2_cfft_f32() function. + * @version V1.0 + * @date 20. Dec 2016 + ******************************************************************************/ + +#ifndef _CSKY_CONST_STRUCTS_H +#define _CSKY_CONST_STRUCTS_H + +#include "csky_vdsp2_math.h" +#include "csky_common_tables.h" + + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_sR_f32_len16; + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_sR_f32_len32; + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_sR_f32_len64; + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_sR_f32_len128; + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_sR_f32_len256; + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_sR_f32_len512; + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_sR_f32_len1024; + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_sR_f32_len2048; + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_sR_f32_len4096; + + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_radix4_sR_f32_len16; + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_radix4_sR_f32_len32; + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_radix4_sR_f32_len64; + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_radix4_sR_f32_len128; + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_radix4_sR_f32_len256; + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_radix4_sR_f32_len512; + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_radix4_sR_f32_len1024; + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_radix4_sR_f32_len2048; + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_radix4_sR_f32_len4096; + + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_radix4_fast_sR_f32_len16; + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_radix4_fast_sR_f32_len32; + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_radix4_fast_sR_f32_len64; + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_radix4_fast_sR_f32_len128; + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_radix4_fast_sR_f32_len256; + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_radix4_fast_sR_f32_len512; + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_radix4_fast_sR_f32_len1024; + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_radix4_fast_sR_f32_len2048; + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_radix4_fast_sR_f32_len4096; + + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_radix2_sR_f32_len16; + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_radix2_sR_f32_len32; + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_radix2_sR_f32_len64; + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_radix2_sR_f32_len128; + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_radix2_sR_f32_len256; + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_radix2_sR_f32_len512; + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_radix2_sR_f32_len1024; + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_radix2_sR_f32_len2048; + extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_radix2_sR_f32_len4096; + + extern const csky_vdsp2_cfft_instance_q31 csky_vdsp2_cfft_sR_q31_len16; + extern const csky_vdsp2_cfft_instance_q31 csky_vdsp2_cfft_sR_q31_len32; + extern const csky_vdsp2_cfft_instance_q31 csky_vdsp2_cfft_sR_q31_len64; + extern const csky_vdsp2_cfft_instance_q31 csky_vdsp2_cfft_sR_q31_len128; + extern const csky_vdsp2_cfft_instance_q31 csky_vdsp2_cfft_sR_q31_len256; + extern const csky_vdsp2_cfft_instance_q31 csky_vdsp2_cfft_sR_q31_len512; + extern const csky_vdsp2_cfft_instance_q31 csky_vdsp2_cfft_sR_q31_len1024; + extern const csky_vdsp2_cfft_instance_q31 csky_vdsp2_cfft_sR_q31_len2048; + extern const csky_vdsp2_cfft_instance_q31 csky_vdsp2_cfft_sR_q31_len4096; + + extern const csky_vdsp2_cfft_instance_q15 csky_vdsp2_cfft_sR_q15_len16; + extern const csky_vdsp2_cfft_instance_q15 csky_vdsp2_cfft_sR_q15_len32; + extern const csky_vdsp2_cfft_instance_q15 csky_vdsp2_cfft_sR_q15_len64; + extern const csky_vdsp2_cfft_instance_q15 csky_vdsp2_cfft_sR_q15_len128; + extern const csky_vdsp2_cfft_instance_q15 csky_vdsp2_cfft_sR_q15_len256; + extern const csky_vdsp2_cfft_instance_q15 csky_vdsp2_cfft_sR_q15_len512; + extern const csky_vdsp2_cfft_instance_q15 csky_vdsp2_cfft_sR_q15_len1024; + extern const csky_vdsp2_cfft_instance_q15 csky_vdsp2_cfft_sR_q15_len2048; + extern const csky_vdsp2_cfft_instance_q15 csky_vdsp2_cfft_sR_q15_len4096; + + extern const csky_vdsp2_cfft_instance_q15 csky_vdsp2_cfft_fast_sR_q15_len16; + extern const csky_vdsp2_cfft_instance_q15 csky_vdsp2_cfft_fast_sR_q15_len32; + extern const csky_vdsp2_cfft_instance_q15 csky_vdsp2_cfft_fast_sR_q15_len64; + extern const csky_vdsp2_cfft_instance_q15 csky_vdsp2_cfft_fast_sR_q15_len128; + extern const csky_vdsp2_cfft_instance_q15 csky_vdsp2_cfft_fast_sR_q15_len256; + extern const csky_vdsp2_cfft_instance_q15 csky_vdsp2_cfft_fast_sR_q15_len512; + extern const csky_vdsp2_cfft_instance_q15 csky_vdsp2_cfft_fast_sR_q15_len1024; + extern const csky_vdsp2_cfft_instance_q15 csky_vdsp2_cfft_fast_sR_q15_len2048; + extern const csky_vdsp2_cfft_instance_q15 csky_vdsp2_cfft_fast_sR_q15_len4096; + + extern const csky_vdsp2_cfft_instance_q31 csky_vdsp2_cfft_fast_sR_q31_len16; + extern const csky_vdsp2_cfft_instance_q31 csky_vdsp2_cfft_fast_sR_q31_len32; + extern const csky_vdsp2_cfft_instance_q31 csky_vdsp2_cfft_fast_sR_q31_len64; + extern const csky_vdsp2_cfft_instance_q31 csky_vdsp2_cfft_fast_sR_q31_len128; + extern const csky_vdsp2_cfft_instance_q31 csky_vdsp2_cfft_fast_sR_q31_len256; + extern const csky_vdsp2_cfft_instance_q31 csky_vdsp2_cfft_fast_sR_q31_len512; + extern const csky_vdsp2_cfft_instance_q31 csky_vdsp2_cfft_fast_sR_q31_len1024; + extern const csky_vdsp2_cfft_instance_q31 csky_vdsp2_cfft_fast_sR_q31_len2048; + extern const csky_vdsp2_cfft_instance_q31 csky_vdsp2_cfft_fast_sR_q31_len4096; + + extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_rfft_sR_q15_len32; + extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_rfft_sR_q15_len64; + extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_rfft_sR_q15_len128; + extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_rfft_sR_q15_len256; + extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_rfft_sR_q15_len512; + extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_rfft_sR_q15_len1024; + extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_rfft_sR_q15_len2048; + extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_rfft_sR_q15_len4096; + extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_rfft_sR_q15_len8192; + + + extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_inv_rfft_sR_q15_len32; + extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_inv_rfft_sR_q15_len64; + extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_inv_rfft_sR_q15_len128; + extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_inv_rfft_sR_q15_len256; + extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_inv_rfft_sR_q15_len512; + extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_inv_rfft_sR_q15_len1024; + extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_inv_rfft_sR_q15_len2048; + extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_inv_rfft_sR_q15_len4096; + extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_inv_rfft_sR_q15_len8192; + + extern csky_vdsp2_rfft_fast_instance_q15 csky_vdsp2_rfft_fast_sR_q15_len32; + extern csky_vdsp2_rfft_fast_instance_q15 csky_vdsp2_rfft_fast_sR_q15_len64; + extern csky_vdsp2_rfft_fast_instance_q15 csky_vdsp2_rfft_fast_sR_q15_len128; + extern csky_vdsp2_rfft_fast_instance_q15 csky_vdsp2_rfft_fast_sR_q15_len256; + extern csky_vdsp2_rfft_fast_instance_q15 csky_vdsp2_rfft_fast_sR_q15_len512; + extern csky_vdsp2_rfft_fast_instance_q15 csky_vdsp2_rfft_fast_sR_q15_len1024; + extern csky_vdsp2_rfft_fast_instance_q15 csky_vdsp2_rfft_fast_sR_q15_len2048; + extern csky_vdsp2_rfft_fast_instance_q15 csky_vdsp2_rfft_fast_sR_q15_len4096; + extern csky_vdsp2_rfft_fast_instance_q15 csky_vdsp2_rfft_fast_sR_q15_len8192; + + + extern csky_vdsp2_rfft_fast_instance_q15 csky_vdsp2_inv_rfft_fast_sR_q15_len32; + extern csky_vdsp2_rfft_fast_instance_q15 csky_vdsp2_inv_rfft_fast_sR_q15_len64; + extern csky_vdsp2_rfft_fast_instance_q15 csky_vdsp2_inv_rfft_fast_sR_q15_len128; + extern csky_vdsp2_rfft_fast_instance_q15 csky_vdsp2_inv_rfft_fast_sR_q15_len256; + extern csky_vdsp2_rfft_fast_instance_q15 csky_vdsp2_inv_rfft_fast_sR_q15_len512; + extern csky_vdsp2_rfft_fast_instance_q15 csky_vdsp2_inv_rfft_fast_sR_q15_len1024; + extern csky_vdsp2_rfft_fast_instance_q15 csky_vdsp2_inv_rfft_fast_sR_q15_len2048; + extern csky_vdsp2_rfft_fast_instance_q15 csky_vdsp2_inv_rfft_fast_sR_q15_len4096; + extern csky_vdsp2_rfft_fast_instance_q15 csky_vdsp2_inv_rfft_fast_sR_q15_len8192; + + + extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_rfft_sR_q31_len32; + extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_rfft_sR_q31_len64; + extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_rfft_sR_q31_len128; + extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_rfft_sR_q31_len256; + extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_rfft_sR_q31_len512; + extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_rfft_sR_q31_len1024; + extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_rfft_sR_q31_len2048; + extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_rfft_sR_q31_len4096; + extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_rfft_sR_q31_len8192; + + extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_inv_rfft_sR_q31_len32; + extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_inv_rfft_sR_q31_len64; + extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_inv_rfft_sR_q31_len128; + extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_inv_rfft_sR_q31_len256; + extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_inv_rfft_sR_q31_len512; + extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_inv_rfft_sR_q31_len1024; + extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_inv_rfft_sR_q31_len2048; + extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_inv_rfft_sR_q31_len4096; + extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_inv_rfft_sR_q31_len8192; + + extern csky_vdsp2_rfft_fast_instance_q31 csky_vdsp2_rfft_fast_sR_q31_len32; + extern csky_vdsp2_rfft_fast_instance_q31 csky_vdsp2_rfft_fast_sR_q31_len64; + extern csky_vdsp2_rfft_fast_instance_q31 csky_vdsp2_rfft_fast_sR_q31_len128; + extern csky_vdsp2_rfft_fast_instance_q31 csky_vdsp2_rfft_fast_sR_q31_len256; + extern csky_vdsp2_rfft_fast_instance_q31 csky_vdsp2_rfft_fast_sR_q31_len512; + extern csky_vdsp2_rfft_fast_instance_q31 csky_vdsp2_rfft_fast_sR_q31_len1024; + extern csky_vdsp2_rfft_fast_instance_q31 csky_vdsp2_rfft_fast_sR_q31_len2048; + extern csky_vdsp2_rfft_fast_instance_q31 csky_vdsp2_rfft_fast_sR_q31_len4096; + extern csky_vdsp2_rfft_fast_instance_q31 csky_vdsp2_rfft_fast_sR_q31_len8192; + + extern csky_vdsp2_rfft_fast_instance_q31 csky_vdsp2_inv_rfft_fast_sR_q31_len32; + extern csky_vdsp2_rfft_fast_instance_q31 csky_vdsp2_inv_rfft_fast_sR_q31_len64; + extern csky_vdsp2_rfft_fast_instance_q31 csky_vdsp2_inv_rfft_fast_sR_q31_len128; + extern csky_vdsp2_rfft_fast_instance_q31 csky_vdsp2_inv_rfft_fast_sR_q31_len256; + extern csky_vdsp2_rfft_fast_instance_q31 csky_vdsp2_inv_rfft_fast_sR_q31_len512; + extern csky_vdsp2_rfft_fast_instance_q31 csky_vdsp2_inv_rfft_fast_sR_q31_len1024; + extern csky_vdsp2_rfft_fast_instance_q31 csky_vdsp2_inv_rfft_fast_sR_q31_len2048; + extern csky_vdsp2_rfft_fast_instance_q31 csky_vdsp2_inv_rfft_fast_sR_q31_len4096; + extern csky_vdsp2_rfft_fast_instance_q31 csky_vdsp2_inv_rfft_fast_sR_q31_len8192; + + + extern csky_vdsp2_rfft_fast_instance_f32 csky_vdsp2_rfft_sR_f32_len32; + extern csky_vdsp2_rfft_fast_instance_f32 csky_vdsp2_rfft_sR_f32_len64; + extern csky_vdsp2_rfft_fast_instance_f32 csky_vdsp2_rfft_sR_f32_len128; + extern csky_vdsp2_rfft_fast_instance_f32 csky_vdsp2_rfft_sR_f32_len256; + extern csky_vdsp2_rfft_fast_instance_f32 csky_vdsp2_rfft_sR_f32_len512; + extern csky_vdsp2_rfft_fast_instance_f32 csky_vdsp2_rfft_sR_f32_len1024; + extern csky_vdsp2_rfft_fast_instance_f32 csky_vdsp2_rfft_sR_f32_len2048; + extern csky_vdsp2_rfft_fast_instance_f32 csky_vdsp2_rfft_sR_f32_len4096; + extern csky_vdsp2_rfft_fast_instance_f32 csky_vdsp2_rfft_sR_f32_len8192; + + extern csky_vdsp2_dct4_instance_q15 csky_vdsp2_dct4_sR_q15_len128; + extern csky_vdsp2_dct4_instance_q15 csky_vdsp2_dct4_sR_q15_len512; + extern csky_vdsp2_dct4_instance_q15 csky_vdsp2_dct4_sR_q15_len2048; + extern csky_vdsp2_dct4_instance_q15 csky_vdsp2_dct4_sR_q15_len8192; + + extern csky_vdsp2_dct4_instance_q31 csky_vdsp2_dct4_sR_q31_len128; + extern csky_vdsp2_dct4_instance_q31 csky_vdsp2_dct4_sR_q31_len512; + extern csky_vdsp2_dct4_instance_q31 csky_vdsp2_dct4_sR_q31_len2048; + extern csky_vdsp2_dct4_instance_q31 csky_vdsp2_dct4_sR_q31_len8192; + + extern csky_vdsp2_dct4_fast_instance_q15 csky_vdsp2_dct4_fast_sR_q15_len128; + extern csky_vdsp2_dct4_fast_instance_q15 csky_vdsp2_dct4_fast_sR_q15_len512; + extern csky_vdsp2_dct4_fast_instance_q15 csky_vdsp2_dct4_fast_sR_q15_len2048; + extern csky_vdsp2_dct4_fast_instance_q15 csky_vdsp2_dct4_fast_sR_q15_len8192; + + extern csky_vdsp2_dct4_fast_instance_q31 csky_vdsp2_dct4_fast_sR_q31_len128; + extern csky_vdsp2_dct4_fast_instance_q31 csky_vdsp2_dct4_fast_sR_q31_len512; + extern csky_vdsp2_dct4_fast_instance_q31 csky_vdsp2_dct4_fast_sR_q31_len2048; + extern csky_vdsp2_dct4_fast_instance_q31 csky_vdsp2_dct4_fast_sR_q31_len8192; + + extern csky_vdsp2_dct4_instance_f32 csky_vdsp2_dct4_sR_f32_len128; + extern csky_vdsp2_dct4_instance_f32 csky_vdsp2_dct4_sR_f32_len512; + extern csky_vdsp2_dct4_instance_f32 csky_vdsp2_dct4_sR_f32_len2048; + extern csky_vdsp2_dct4_instance_f32 csky_vdsp2_dct4_sR_f32_len8192; +#endif diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/dsp/csky_vdsp2_math.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/dsp/csky_vdsp2_math.h new file mode 100644 index 00000000..55ced0f4 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/dsp/csky_vdsp2_math.h @@ -0,0 +1,2378 @@ +/* + * Copyright (C) 2016-2019 C-SKY 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 csky_vdsp2_math.h + * @brief Public header file for CSI DSP Library. + * @version V1.0 + * @date 20. Dec 2016 + ******************************************************************************/ + +#ifndef _CSKY_VDSP2_MATH_H +#define _CSKY_VDSP2_MATH_H + +#include +#include + +#ifdef CSKY_VDSP2_MATH_DSP +#include "csi_core.h" +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + /** + * @brief 8-bit fractional data type in 1.7 format. + */ + typedef int8_t q7_t; + + /** + * @brief 16-bit fractional data type in 1.15 format. + */ + typedef int16_t q15_t; + + /** + * @brief 32-bit fractional data type in 1.31 format. + */ + typedef int32_t q31_t; + + /** + * @brief 64-bit fractional data type in 1.63 format. + */ + typedef int64_t q63_t; + + /** + * @brief 32-bit floating-point type definition. + */ + typedef float float32_t; + + /** + * @brief Error status returned by some functions in the library. + */ + + typedef enum + { + CSKY_VDSP2_MATH_SUCCESS = 0, /**< No error */ + CSKY_VDSP2_MATH_ARGUMENT_ERROR = -1, /**< One or more arguments are incorrect */ + CSKY_VDSP2_MATH_LENGTH_ERROR = -2, /**< Length of data buffer is incorrect */ + CSKY_VDSP2_MATH_SIZE_MISMATCH = -3, /**< Size of matrices is not compatible with the operation. */ + CSKY_VDSP2_MATH_NANINF = -4, /**< Not-a-number (NaN) or infinity is generated */ + CSKY_VDSP2_MATH_SINGULAR = -5, /**< Generated by matrix inversion if the input matrix is singular and cannot be inverted. */ + CSKY_VDSP2_MATH_TEST_FAILURE = -6 /**< Test Failed */ + } csky_vdsp2_status; + + /** + * @brief Instance structure for the Q7 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q7_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } csky_vdsp2_fir_instance_q7; + + /** + * @brief Instance structure for the Q15 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } csky_vdsp2_fir_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } csky_vdsp2_fir_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } csky_vdsp2_fir_instance_f32; + + void csky_vdsp2_fir_q7( + const csky_vdsp2_fir_instance_q7 * S, + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_fir_init_q7( + csky_vdsp2_fir_instance_q7 * S, + uint16_t numTaps, + q7_t * pCoeffs, + q7_t * pState, + uint32_t blockSize); + + void csky_vdsp2_fir_q15( + const csky_vdsp2_fir_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_fir_fast_q15( + const csky_vdsp2_fir_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + csky_vdsp2_status csky_vdsp2_fir_init_q15( + csky_vdsp2_fir_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + void csky_vdsp2_fir_q31( + const csky_vdsp2_fir_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_fir_fast_q31( + const csky_vdsp2_fir_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_fir_init_q31( + csky_vdsp2_fir_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + void csky_vdsp2_fir_f32( + const csky_vdsp2_fir_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_fir_init_f32( + csky_vdsp2_fir_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 Biquad cascade filter. + */ + typedef struct + { + int8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q15_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + q15_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + int8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + } csky_vdsp2_biquad_casd_df1_inst_q15; + + /** + * @brief Instance structure for the Q31 Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q31_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + q31_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + } csky_vdsp2_biquad_casd_df1_inst_q31; + + /** + * @brief Instance structure for the Q31 Biquad cascade filter. + */ + + /** + * @brief Instance structure for the floating-point Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + float32_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + } csky_vdsp2_biquad_casd_df1_inst_f32; + + void csky_vdsp2_biquad_cascade_df1_q15( + const csky_vdsp2_biquad_casd_df1_inst_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_biquad_cascade_df1_init_q15( + csky_vdsp2_biquad_casd_df1_inst_q15 * S, + uint8_t numStages, + q15_t * pCoeffs, + q15_t * pState, + int8_t postShift); + + void csky_vdsp2_biquad_cascade_df1_fast_q15( + const csky_vdsp2_biquad_casd_df1_inst_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_biquad_cascade_df1_q31( + const csky_vdsp2_biquad_casd_df1_inst_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_biquad_cascade_df1_fast_q31( + const csky_vdsp2_biquad_casd_df1_inst_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_biquad_cascade_df1_init_q31( + csky_vdsp2_biquad_casd_df1_inst_q31 * S, + uint8_t numStages, + q31_t * pCoeffs, + q31_t * pState, + int8_t postShift); + + void csky_vdsp2_biquad_cascade_df1_f32( + const csky_vdsp2_biquad_casd_df1_inst_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_biquad_cascade_df1_init_f32( + csky_vdsp2_biquad_casd_df1_inst_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Instance structure for the floating-point matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + float32_t *pData; /**< points to the data of the matrix. */ + } csky_vdsp2_matrix_instance_f32; + + /** + * @brief Instance structure for the Q15 matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q15_t *pData; /**< points to the data of the matrix. */ + } csky_vdsp2_matrix_instance_q15; + + /** + * @brief Instance structure for the Q31 matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q31_t *pData; /**< points to the data of the matrix. */ + } csky_vdsp2_matrix_instance_q31; + + csky_vdsp2_status csky_vdsp2_mat_add_f32( + const csky_vdsp2_matrix_instance_f32 * pSrcA, + const csky_vdsp2_matrix_instance_f32 * pSrcB, + csky_vdsp2_matrix_instance_f32 * pDst); + + csky_vdsp2_status csky_vdsp2_mat_add_q15( + const csky_vdsp2_matrix_instance_q15 * pSrcA, + const csky_vdsp2_matrix_instance_q15 * pSrcB, + csky_vdsp2_matrix_instance_q15 * pDst); + + csky_vdsp2_status csky_vdsp2_mat_add_q31( + const csky_vdsp2_matrix_instance_q31 * pSrcA, + const csky_vdsp2_matrix_instance_q31 * pSrcB, + csky_vdsp2_matrix_instance_q31 * pDst); + + csky_vdsp2_status csky_vdsp2_mat_cmplx_mult_f32( + const csky_vdsp2_matrix_instance_f32 * pSrcA, + const csky_vdsp2_matrix_instance_f32 * pSrcB, + csky_vdsp2_matrix_instance_f32 * pDst); + + csky_vdsp2_status csky_vdsp2_mat_cmplx_mult_q15( + const csky_vdsp2_matrix_instance_q15 * pSrcA, + const csky_vdsp2_matrix_instance_q15 * pSrcB, + csky_vdsp2_matrix_instance_q15 * pDst); + + csky_vdsp2_status csky_vdsp2_mat_cmplx_mult_q31( + const csky_vdsp2_matrix_instance_q31 * pSrcA, + const csky_vdsp2_matrix_instance_q31 * pSrcB, + csky_vdsp2_matrix_instance_q31 * pDst); + + csky_vdsp2_status csky_vdsp2_mat_trans_f32( + const csky_vdsp2_matrix_instance_f32 * pSrc, + csky_vdsp2_matrix_instance_f32 * pDst); + + csky_vdsp2_status csky_vdsp2_mat_trans_q15( + const csky_vdsp2_matrix_instance_q15 * pSrc, + csky_vdsp2_matrix_instance_q15 * pDst); + + csky_vdsp2_status csky_vdsp2_mat_trans_q31( + const csky_vdsp2_matrix_instance_q31 * pSrc, + csky_vdsp2_matrix_instance_q31 * pDst); + + csky_vdsp2_status csky_vdsp2_mat_mult_f32( + const csky_vdsp2_matrix_instance_f32 * pSrcA, + const csky_vdsp2_matrix_instance_f32 * pSrcB, + csky_vdsp2_matrix_instance_f32 * pDst); + + csky_vdsp2_status csky_vdsp2_mat_mult_trans_f32( + const csky_vdsp2_matrix_instance_f32 * pSrcA, + const csky_vdsp2_matrix_instance_f32 * pSrcB, + csky_vdsp2_matrix_instance_f32 * pDst); + + csky_vdsp2_status csky_vdsp2_mat_mult_q15( + const csky_vdsp2_matrix_instance_q15 * pSrcA, + const csky_vdsp2_matrix_instance_q15 * pSrcB, + csky_vdsp2_matrix_instance_q15 * pDst); + + csky_vdsp2_status csky_vdsp2_mat_mult_trans_q15( + const csky_vdsp2_matrix_instance_q15 * pSrcA, + const csky_vdsp2_matrix_instance_q15 * pSrcB, + csky_vdsp2_matrix_instance_q15 * pDst); + + csky_vdsp2_status csky_vdsp2_mat_mult_q31( + const csky_vdsp2_matrix_instance_q31 * pSrcA, + const csky_vdsp2_matrix_instance_q31 * pSrcB, + csky_vdsp2_matrix_instance_q31 * pDst); + + csky_vdsp2_status csky_vdsp2_mat_mult_trans_q31( + const csky_vdsp2_matrix_instance_q31 * pSrcA, + const csky_vdsp2_matrix_instance_q31 * pSrcB, + csky_vdsp2_matrix_instance_q31 * pDst); + + csky_vdsp2_status csky_vdsp2_mat_sub_f32( + const csky_vdsp2_matrix_instance_f32 * pSrcA, + const csky_vdsp2_matrix_instance_f32 * pSrcB, + csky_vdsp2_matrix_instance_f32 * pDst); + + csky_vdsp2_status csky_vdsp2_mat_sub_q15( + const csky_vdsp2_matrix_instance_q15 * pSrcA, + const csky_vdsp2_matrix_instance_q15 * pSrcB, + csky_vdsp2_matrix_instance_q15 * pDst); + + csky_vdsp2_status csky_vdsp2_mat_sub_q31( + const csky_vdsp2_matrix_instance_q31 * pSrcA, + const csky_vdsp2_matrix_instance_q31 * pSrcB, + csky_vdsp2_matrix_instance_q31 * pDst); + + csky_vdsp2_status csky_vdsp2_mat_scale_f32( + const csky_vdsp2_matrix_instance_f32 * pSrc, + float32_t scale, + csky_vdsp2_matrix_instance_f32 * pDst); + + csky_vdsp2_status csky_vdsp2_mat_scale_q15( + const csky_vdsp2_matrix_instance_q15 * pSrc, + q15_t scaleFract, + int32_t shift, + csky_vdsp2_matrix_instance_q15 * pDst); + + csky_vdsp2_status csky_vdsp2_mat_scale_q31( + const csky_vdsp2_matrix_instance_q31 * pSrc, + q31_t scaleFract, + int32_t shift, + csky_vdsp2_matrix_instance_q31 * pDst); + + void csky_vdsp2_mat_init_q31( + csky_vdsp2_matrix_instance_q31 * S, + uint16_t nRows, + uint16_t nColumns, + q31_t * pData); + + void csky_vdsp2_mat_init_q15( + csky_vdsp2_matrix_instance_q15 * S, + uint16_t nRows, + uint16_t nColumns, + q15_t * pData); + + void csky_vdsp2_mat_init_f32( + csky_vdsp2_matrix_instance_f32 * S, + uint16_t nRows, + uint16_t nColumns, + float32_t * pData); + + void csky_vdsp2_mult_q15xq31_sht( + q15_t * pSrcA, + q31_t * pSrcB, + uint32_t shiftValue, + uint32_t blockSize); + + void csky_vdsp2_mult_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_mult_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_mult_rnd_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_mult_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_mult_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q15_t *pTwiddle; /**< points to the Sin twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } csky_vdsp2_cfft_radix2_instance_q15; + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q15_t *pTwiddle; /**< points to the twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } csky_vdsp2_cfft_radix4_instance_q15; + + /** + * @brief Instance structure for the Radix-2 Q31 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } csky_vdsp2_cfft_radix2_instance_q31; + + /** + * @brief Instance structure for the Q31 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q31_t *pTwiddle; /**< points to the twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } csky_vdsp2_cfft_radix4_instance_q31; + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } csky_vdsp2_cfft_radix2_instance_f32; + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } csky_vdsp2_cfft_radix4_instance_f32; + + /** + * @brief Instance structure for the fixed-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const q15_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } csky_vdsp2_cfft_instance_q15; + +void csky_vdsp2_cfft_q15( + const csky_vdsp2_cfft_instance_q15 * S, + q15_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +void csky_vdsp2_cfft_fast_q15( + const csky_vdsp2_cfft_instance_q15 * S, + q15_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the fixed-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } csky_vdsp2_cfft_instance_q31; + +void csky_vdsp2_cfft_q31( + const csky_vdsp2_cfft_instance_q31 * S, + q31_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +void csky_vdsp2_cfft_fast_q31( + const csky_vdsp2_cfft_instance_q31 * S, + q31_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } csky_vdsp2_cfft_instance_f32; + + void csky_vdsp2_cfft_f32( + const csky_vdsp2_cfft_instance_f32 * S, + float32_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the Q15 RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + q15_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + const csky_vdsp2_cfft_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } csky_vdsp2_rfft_instance_q15; + + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + q15_t *pTwiddleAReal; /**< points to the A real twiddle factor table. */ + q15_t *pTwiddleBReal; /**< points to the B real twiddle factor table. */ + const csky_vdsp2_cfft_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } csky_vdsp2_rfft_fast_instance_q15; + + csky_vdsp2_status csky_vdsp2_rfft_init_q15( + csky_vdsp2_rfft_instance_q15 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void csky_vdsp2_rfft_q15( + const csky_vdsp2_rfft_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst); + + void csky_vdsp2_rfft_fast_q15( + const csky_vdsp2_rfft_fast_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst); + + /** + * @brief Instance structure for the Q31 RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + q31_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + const csky_vdsp2_cfft_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } csky_vdsp2_rfft_instance_q31; + + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + q31_t *pTwiddleAReal; /**< points to the A real twiddle factor table. */ + q31_t *pTwiddleBReal; /**< points to the B real twiddle factor table. */ + const csky_vdsp2_cfft_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } csky_vdsp2_rfft_fast_instance_q31; + + csky_vdsp2_status csky_vdsp2_rfft_init_q31( + csky_vdsp2_rfft_instance_q31 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void csky_vdsp2_rfft_q31( + const csky_vdsp2_rfft_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst); + + void csky_vdsp2_rfft_fast_q31( + const csky_vdsp2_rfft_fast_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst); + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint16_t fftLenBy2; /**< length of the complex FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + float32_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + float32_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + csky_vdsp2_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } csky_vdsp2_rfft_instance_f32; + + csky_vdsp2_status csky_vdsp2_rfft_init_f32( + csky_vdsp2_rfft_instance_f32 * S, + csky_vdsp2_cfft_radix4_instance_f32 * S_CFFT, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void csky_vdsp2_cfft_radix4_f32( + const csky_vdsp2_cfft_instance_f32 * S, + float32_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag, + float32_t onebyfftLen); + + void csky_vdsp2_cfft_fast_radix4_f32( + const csky_vdsp2_cfft_instance_f32 * S, + float32_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag, + float32_t onebyfftLen); + + void csky_vdsp2_cfft_radix2_f32( + const csky_vdsp2_cfft_instance_f32 * S, + float32_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag, + float32_t onebyfftLen); + + void csky_vdsp2_rfft_f32( + const csky_vdsp2_rfft_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst); + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ +typedef struct + { + csky_vdsp2_cfft_instance_f32 Sint; /**< Internal CFFT structure. */ + uint16_t fftLenRFFT; /**< length of the real sequence */ + float32_t * pTwiddleRFFT; /**< Twiddle factors real stage */ + } csky_vdsp2_rfft_fast_instance_f32 ; + +csky_vdsp2_status csky_vdsp2_rfft_fast_init_f32 ( + csky_vdsp2_rfft_fast_instance_f32 * S, + uint16_t fftLen); + +void csky_vdsp2_rfft_fast_f32( + csky_vdsp2_rfft_fast_instance_f32 * S, + float32_t * p, float32_t * pOut, + uint8_t ifftFlag); + + /** + * @brief Instance structure for the floating-point DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + float32_t normalize; /**< normalizing factor. */ + float32_t *pTwiddle; /**< points to the twiddle factor table. */ + float32_t *pCosFactor; /**< points to the cosFactor table. */ + csky_vdsp2_rfft_fast_instance_f32 *pRfft; /**< points to the real FFT fast instance. */ + csky_vdsp2_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } csky_vdsp2_dct4_instance_f32; + + csky_vdsp2_status csky_vdsp2_dct4_init_f32( + csky_vdsp2_dct4_instance_f32 * S, + csky_vdsp2_rfft_fast_instance_f32 * S_RFFT, + csky_vdsp2_cfft_radix4_instance_f32 * S_CFFT, + uint16_t N, + uint16_t Nby2, + float32_t normalize); + + void csky_vdsp2_dct4_f32( + const csky_vdsp2_dct4_instance_f32 * S, + float32_t * pState, + float32_t * pInlineBuffer); + + + /** + * @brief Instance structure for the Q31 DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q31_t normalize; /**< normalizing factor. */ + q31_t *pTwiddle; /**< points to the twiddle factor table. */ + q31_t *pCosFactor; /**< points to the cosFactor table. */ + csky_vdsp2_rfft_instance_q31 *pRfft; /**< points to the real FFT instance. */ + csky_vdsp2_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } csky_vdsp2_dct4_instance_q31; + + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q31_t normalize; /**< normalizing factor. */ + q31_t *pTwiddle; /**< points to the twiddle factor table. */ + q31_t *pCosFactor; /**< points to the cosFactor table. */ + csky_vdsp2_rfft_fast_instance_q31 *pRfft; /**< points to the real FFT instance. */ + csky_vdsp2_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } csky_vdsp2_dct4_fast_instance_q31; + + csky_vdsp2_status csky_vdsp2_dct4_init_q31( + csky_vdsp2_dct4_instance_q31 * S, + csky_vdsp2_rfft_instance_q31 * S_RFFT, + csky_vdsp2_cfft_radix4_instance_q31 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q31_t normalize); + + void csky_vdsp2_dct4_q31( + const csky_vdsp2_dct4_instance_q31 * S, + q31_t * pState, + q31_t * pInlineBuffer); + + void csky_vdsp2_dct4_fast_q31( + const csky_vdsp2_dct4_fast_instance_q31 * S, + q31_t * pState, + q31_t * pInlineBuffer); + + /** + * @brief Instance structure for the Q15 DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q15_t normalize; /**< normalizing factor. */ + q15_t *pTwiddle; /**< points to the twiddle factor table. */ + q15_t *pCosFactor; /**< points to the cosFactor table. */ + csky_vdsp2_rfft_instance_q15 *pRfft; /**< points to the real FFT instance. */ + csky_vdsp2_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } csky_vdsp2_dct4_instance_q15; + + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q15_t normalize; /**< normalizing factor. */ + q15_t *pTwiddle; /**< points to the twiddle factor table. */ + q15_t *pCosFactor; /**< points to the cosFactor table. */ + csky_vdsp2_rfft_fast_instance_q15 *pRfft; /**< points to the real FFT instance. */ + csky_vdsp2_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } csky_vdsp2_dct4_fast_instance_q15; + + csky_vdsp2_status csky_vdsp2_dct4_init_q15( + csky_vdsp2_dct4_instance_q15 * S, + csky_vdsp2_rfft_instance_q15 * S_RFFT, + csky_vdsp2_cfft_radix4_instance_q15 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q15_t normalize); + + void csky_vdsp2_dct4_q15( + const csky_vdsp2_dct4_instance_q15 * S, + q15_t * pState, + q15_t * pInlineBuffer); + + void csky_vdsp2_dct4_fast_q15( + const csky_vdsp2_dct4_fast_instance_q15 * S, + q15_t * pState, + q15_t * pInlineBuffer); + + void csky_vdsp2_add_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_add_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_add_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_add_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_sub_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_sub_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_sub_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_sub_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_sum_q15( + q15_t * pSrcA, + q63_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_scale_f32( + float32_t * pSrc, + float32_t scale, + float32_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_scale_q7( + q7_t * pSrc, + q7_t scaleFract, + int8_t shift, + q7_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_scale_q15( + q15_t * pSrc, + q15_t scaleFract, + int8_t shift, + q15_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_scale_q31( + q31_t * pSrc, + q31_t scaleFract, + int8_t shift, + q31_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_abs_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_abs_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_abs_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_abs_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_abs_max_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_abs_max_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + void csky_vdsp2_dot_prod_f32( + float32_t * pSrcA, + float32_t * pSrcB, + uint32_t blockSize, + float32_t * result); + + void csky_vdsp2_dot_prod_q7( + q7_t * pSrcA, + q7_t * pSrcB, + uint32_t blockSize, + q31_t * result); + + void csky_vdsp2_dot_prod_q15( + q15_t * pSrcA, + q15_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + void csky_vdsp2_dot_prod_q31( + q31_t * pSrcA, + q31_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + void csky_vdsp2_dot_prod_u64xu8( + uint8_t * pSrcA, + uint64_t * pSrcB, + uint32_t blockSize, + uint64_t * result); + + void csky_vdsp2_shift_q7( + q7_t * pSrc, + int8_t shiftBits, + q7_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_shift_q15( + q15_t * pSrc, + int8_t shiftBits, + q15_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_shift_q31( + q31_t * pSrc, + int8_t shiftBits, + q31_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_offset_f32( + float32_t * pSrc, + float32_t offset, + float32_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_offset_q7( + q7_t * pSrc, + q7_t offset, + q7_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_offset_q15( + q15_t * pSrc, + q15_t offset, + q15_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_offset_q31( + q31_t * pSrc, + q31_t offset, + q31_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_negate_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_negate_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_negate_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_negate_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_copy_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_copy_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_copy_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_copy_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_fill_f32( + float32_t value, + float32_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_fill_q7( + q7_t value, + q7_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_fill_q15( + q15_t value, + q15_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_fill_q31( + q31_t value, + q31_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_conv_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + void csky_vdsp2_conv_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + void csky_vdsp2_conv_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + void csky_vdsp2_conv_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + void csky_vdsp2_conv_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + void csky_vdsp2_conv_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + void csky_vdsp2_conv_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + void csky_vdsp2_conv_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + void csky_vdsp2_conv_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + csky_vdsp2_status csky_vdsp2_conv_partial_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + csky_vdsp2_status csky_vdsp2_conv_partial_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + csky_vdsp2_status csky_vdsp2_conv_partial_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + csky_vdsp2_status csky_vdsp2_conv_partial_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + csky_vdsp2_status csky_vdsp2_conv_partial_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + csky_vdsp2_status csky_vdsp2_conv_partial_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + csky_vdsp2_status csky_vdsp2_conv_partial_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + csky_vdsp2_status csky_vdsp2_conv_partial_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + csky_vdsp2_status csky_vdsp2_conv_partial_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + /** + * @brief Instance structure for the Q15 FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } csky_vdsp2_fir_decimate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } csky_vdsp2_fir_decimate_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } csky_vdsp2_fir_decimate_instance_f32; + + void csky_vdsp2_fir_decimate_f32( + const csky_vdsp2_fir_decimate_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + csky_vdsp2_status csky_vdsp2_fir_decimate_init_f32( + csky_vdsp2_fir_decimate_instance_f32 * S, + uint16_t numTaps, + uint8_t M, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + void csky_vdsp2_fir_decimate_q15( + const csky_vdsp2_fir_decimate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_fir_decimate_fast_q15( + const csky_vdsp2_fir_decimate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + csky_vdsp2_status csky_vdsp2_fir_decimate_init_q15( + csky_vdsp2_fir_decimate_instance_q15 * S, + uint16_t numTaps, + uint8_t M, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + void csky_vdsp2_fir_decimate_q31( + const csky_vdsp2_fir_decimate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_fir_decimate_fast_q31( + csky_vdsp2_fir_decimate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + csky_vdsp2_status csky_vdsp2_fir_decimate_init_q31( + csky_vdsp2_fir_decimate_instance_q31 * S, + uint16_t numTaps, + uint8_t M, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q15_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + } csky_vdsp2_fir_interpolate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q31_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + } csky_vdsp2_fir_interpolate_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + float32_t *pState; /**< points to the state variable array. The array is of length phaseLength+numTaps-1. */ + } csky_vdsp2_fir_interpolate_instance_f32; + + void csky_vdsp2_fir_interpolate_q15( + const csky_vdsp2_fir_interpolate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + csky_vdsp2_status csky_vdsp2_fir_interpolate_init_q15( + csky_vdsp2_fir_interpolate_instance_q15 * S, + uint8_t L, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + void csky_vdsp2_fir_interpolate_q31( + const csky_vdsp2_fir_interpolate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + csky_vdsp2_status csky_vdsp2_fir_interpolate_init_q31( + csky_vdsp2_fir_interpolate_instance_q31 * S, + uint8_t L, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + void csky_vdsp2_fir_interpolate_f32( + const csky_vdsp2_fir_interpolate_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + csky_vdsp2_status csky_vdsp2_fir_interpolate_init_f32( + csky_vdsp2_fir_interpolate_instance_f32 * S, + uint8_t L, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ + float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } csky_vdsp2_biquad_cascade_df2T_instance_f32; + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ + float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } csky_vdsp2_biquad_cascade_stereo_df2T_instance_f32; + + void csky_vdsp2_biquad_cascade_df2T_f32( + const csky_vdsp2_biquad_cascade_df2T_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_biquad_cascade_stereo_df2T_f32( + const csky_vdsp2_biquad_cascade_stereo_df2T_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_biquad_cascade_df2T_init_f32( + csky_vdsp2_biquad_cascade_df2T_instance_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + void csky_vdsp2_biquad_cascade_stereo_df2T_init_f32( + csky_vdsp2_biquad_cascade_stereo_df2T_instance_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + /** + * @brief Instance structure for the Q15 FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } csky_vdsp2_fir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } csky_vdsp2_fir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } csky_vdsp2_fir_lattice_instance_f32; + + void csky_vdsp2_fir_lattice_init_q15( + csky_vdsp2_fir_lattice_instance_q15 * S, + uint16_t numStages, + q15_t * pCoeffs, + q15_t * pState); + + void csky_vdsp2_fir_lattice_q15( + const csky_vdsp2_fir_lattice_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_fir_lattice_init_q31( + csky_vdsp2_fir_lattice_instance_q31 * S, + uint16_t numStages, + q31_t * pCoeffs, + q31_t * pState); + + void csky_vdsp2_fir_lattice_q31( + const csky_vdsp2_fir_lattice_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_fir_lattice_init_f32( + csky_vdsp2_fir_lattice_instance_f32 * S, + uint16_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + void csky_vdsp2_fir_lattice_f32( + const csky_vdsp2_fir_lattice_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q15_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q15_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } csky_vdsp2_iir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q31_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q31_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } csky_vdsp2_iir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + float32_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + float32_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } csky_vdsp2_iir_lattice_instance_f32; + + void csky_vdsp2_iir_lattice_f32( + const csky_vdsp2_iir_lattice_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_iir_lattice_init_f32( + csky_vdsp2_iir_lattice_instance_f32 * S, + uint16_t numStages, + float32_t * pkCoeffs, + float32_t * pvCoeffs, + float32_t * pState, + uint32_t blockSize); + + void csky_vdsp2_iir_lattice_q31( + const csky_vdsp2_iir_lattice_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_iir_lattice_init_q31( + csky_vdsp2_iir_lattice_instance_q31 * S, + uint16_t numStages, + q31_t * pkCoeffs, + q31_t * pvCoeffs, + q31_t * pState, + uint32_t blockSize); + + void csky_vdsp2_iir_lattice_q15( + const csky_vdsp2_iir_lattice_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_iir_lattice_init_q15( + csky_vdsp2_iir_lattice_instance_q15 * S, + uint16_t numStages, + q15_t * pkCoeffs, + q15_t * pvCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the floating-point LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that controls filter coefficient updates. */ + } csky_vdsp2_lms_instance_f32; + + void csky_vdsp2_lms_f32( + const csky_vdsp2_lms_instance_f32 * S, + float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + void csky_vdsp2_lms_init_f32( + csky_vdsp2_lms_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ + } csky_vdsp2_lms_instance_q15; + + void csky_vdsp2_lms_init_q15( + csky_vdsp2_lms_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint32_t postShift); + + void csky_vdsp2_lms_q15( + const csky_vdsp2_lms_instance_q15 * S, + q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ + } csky_vdsp2_lms_instance_q31; + + void csky_vdsp2_lms_q31( + const csky_vdsp2_lms_instance_q31 * S, + q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + void csky_vdsp2_lms_init_q31( + csky_vdsp2_lms_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint32_t postShift); + + + /** + * @brief Instance structure for the floating-point normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that control filter coefficient updates. */ + float32_t energy; /**< saves previous frame energy. */ + float32_t x0; /**< saves previous input sample. */ + } csky_vdsp2_lms_norm_instance_f32; + + void csky_vdsp2_lms_norm_f32( + csky_vdsp2_lms_norm_instance_f32 * S, + float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + void csky_vdsp2_lms_norm_init_f32( + csky_vdsp2_lms_norm_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + q31_t *recipTable; /**< points to the reciprocal initial value table. */ + q31_t energy; /**< saves previous frame energy. */ + q31_t x0; /**< saves previous input sample. */ + } csky_vdsp2_lms_norm_instance_q31; + + void csky_vdsp2_lms_norm_q31( + csky_vdsp2_lms_norm_instance_q31 * S, + q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + void csky_vdsp2_lms_norm_init_q31( + csky_vdsp2_lms_norm_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint8_t postShift); + + + /** + * @brief Instance structure for the Q15 normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< Number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + q15_t *recipTable; /**< Points to the reciprocal initial value table. */ + q15_t energy; /**< saves previous frame energy. */ + q15_t x0; /**< saves previous input sample. */ + } csky_vdsp2_lms_norm_instance_q15; + + void csky_vdsp2_lms_norm_q15( + csky_vdsp2_lms_norm_instance_q15 * S, + q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + void csky_vdsp2_lms_norm_init_q15( + csky_vdsp2_lms_norm_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint8_t postShift); + + void csky_vdsp2_correlate_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + void csky_vdsp2_correlate_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + void csky_vdsp2_correlate_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + void csky_vdsp2_correlate_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + void csky_vdsp2_correlate_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + void csky_vdsp2_correlate_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + void csky_vdsp2_correlate_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + void csky_vdsp2_correlate_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + void csky_vdsp2_correlate_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + + /** + * @brief Instance structure for the floating-point sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + float32_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } csky_vdsp2_fir_sparse_instance_f32; + + /** + * @brief Instance structure for the Q31 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q31_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } csky_vdsp2_fir_sparse_instance_q31; + + /** + * @brief Instance structure for the Q15 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q15_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } csky_vdsp2_fir_sparse_instance_q15; + + /** + * @brief Instance structure for the Q7 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q7_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } csky_vdsp2_fir_sparse_instance_q7; + + void csky_vdsp2_fir_sparse_f32( + csky_vdsp2_fir_sparse_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + float32_t * pScratchIn, + uint32_t blockSize); + + void csky_vdsp2_fir_sparse_init_f32( + csky_vdsp2_fir_sparse_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + void csky_vdsp2_fir_sparse_q31( + csky_vdsp2_fir_sparse_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + q31_t * pScratchIn, + uint32_t blockSize); + + void csky_vdsp2_fir_sparse_init_q31( + csky_vdsp2_fir_sparse_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + void csky_vdsp2_fir_sparse_q15( + csky_vdsp2_fir_sparse_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + q15_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + void csky_vdsp2_fir_sparse_init_q15( + csky_vdsp2_fir_sparse_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + void csky_vdsp2_fir_sparse_q7( + csky_vdsp2_fir_sparse_instance_q7 * S, + q7_t * pSrc, + q7_t * pDst, + q7_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + void csky_vdsp2_fir_sparse_init_q7( + csky_vdsp2_fir_sparse_instance_q7 * S, + uint16_t numTaps, + q7_t * pCoeffs, + q7_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + void csky_vdsp2_sin_cos_f32( + float32_t theta, + float32_t * pSinVal, + float32_t * pCosVal); + + void csky_vdsp2_sin_cos_q31( + q31_t theta, + q31_t * pSinVal, + q31_t * pCosVal); + + void csky_vdsp2_cmplx_conj_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + void csky_vdsp2_cmplx_conj_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + void csky_vdsp2_cmplx_conj_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + void csky_vdsp2_cmplx_mag_squared_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + void csky_vdsp2_cmplx_mag_squared_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + void csky_vdsp2_cmplx_mag_squared_q31_basic( + q31_t * pSrc, + q63_t * pDst, + uint32_t numSamples); + + void csky_vdsp2_cmplx_mag_squared_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + void csky_vdsp2_vsqrt_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + void csky_vdsp2_vsqrt_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + void csky_vdsp2_vsqrt_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + void csky_vdsp2_vsqrt_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t numSamples); + + void csky_vdsp2_q7_to_q31( + q7_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_q7_to_q15( + q7_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_q7_to_float( + q7_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_q31_to_float( + q31_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + csky_vdsp2_status csky_vdsp2_sqrt_f32( + float32_t in, + float32_t * pOut); + + csky_vdsp2_status csky_vdsp2_sqrt_q31( + q31_t in, + q31_t * pOut); + + csky_vdsp2_status csky_vdsp2_sqrt_q15( + q15_t in, + q15_t * pOut); + + void csky_vdsp2_power_q31( + q31_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + void csky_vdsp2_power_int32( + int32_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + void csky_vdsp2_power_int32( + int32_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + void csky_vdsp2_power_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + void csky_vdsp2_power_q15( + q15_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + void csky_vdsp2_power_q7( + q7_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + void csky_vdsp2_mean_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult); + + void csky_vdsp2_mean_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + void csky_vdsp2_mean_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + void csky_vdsp2_mean_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + void csky_vdsp2_var_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + void csky_vdsp2_var_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + void csky_vdsp2_var_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + void csky_vdsp2_rms_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + void csky_vdsp2_rms_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + void csky_vdsp2_rms_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + void csky_vdsp2_std_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + void csky_vdsp2_std_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + void csky_vdsp2_std_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + void csky_vdsp2_cmplx_mag_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + void csky_vdsp2_cmplx_mag_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + void csky_vdsp2_cmplx_mag_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + void csky_vdsp2_cmplx_dot_prod_q15( + q15_t * pSrcA, + q15_t * pSrcB, + uint32_t numSamples, + q31_t * realResult, + q31_t * imagResult); + + void csky_vdsp2_cmplx_dot_prod_q31( + q31_t * pSrcA, + q31_t * pSrcB, + uint32_t numSamples, + q63_t * realResult, + q63_t * imagResult); + + void csky_vdsp2_cmplx_dot_prod_f32( + float32_t * pSrcA, + float32_t * pSrcB, + uint32_t numSamples, + float32_t * realResult, + float32_t * imagResult); + + void csky_vdsp2_cmplx_mult_real_q15( + q15_t * pSrcCmplx, + q15_t * pSrcReal, + q15_t * pCmplxDst, + uint32_t numSamples); + + void csky_vdsp2_cmplx_mult_real_q31( + q31_t * pSrcCmplx, + q31_t * pSrcReal, + q31_t * pCmplxDst, + uint32_t numSamples); + + void csky_vdsp2_cmplx_mult_real_f32( + float32_t * pSrcCmplx, + float32_t * pSrcReal, + float32_t * pCmplxDst, + uint32_t numSamples); + + void csky_vdsp2_min_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * result, + uint32_t * index); + + void csky_vdsp2_min_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + + void csky_vdsp2_min_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + + void csky_vdsp2_min_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + + void csky_vdsp2_max_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult, + uint32_t * pIndex); + + void csky_vdsp2_max_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + + void csky_vdsp2_max_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + + void csky_vdsp2_max_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + + void csky_vdsp2_cmplx_mult_cmplx_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t numSamples); + + void csky_vdsp2_cmplx_mult_cmplx_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t numSamples); + + void csky_vdsp2_cmplx_mult_cmplx_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t numSamples); + + void csky_vdsp2_cmplx_mult_cmplx_re_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t numSamples); + + void csky_vdsp2_cmplx_mult_cmplx_re_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t numSamples); + + void csky_vdsp2_cmplx_mult_cmplx_re_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t numSamples); + + + void csky_vdsp2_float_to_q31( + float32_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_float_to_q15( + float32_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_float_to_q7( + float32_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_q31_to_q15( + q31_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_q31_to_q7( + q31_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_q31_to_q7_rs( + q31_t * pSrc, + q7_t * pDst, + uint32_t shiftValue, + uint32_t blockSize); + + void csky_vdsp2_q63_to_q31_rs( + q63_t * pSrc, + q31_t * pDst, + uint32_t shiftValue, + uint32_t blockSize); + + void csky_vdsp2_q15_to_float( + q15_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_q15_to_q31( + q15_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + void csky_vdsp2_q15_to_q7( + q15_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + +#ifdef __cplusplus +} +#endif +#endif /* _CSKY_VDSP2_MATH_H */ + +/** + * + * End of file. + */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/syslog.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/syslog.h new file mode 100755 index 00000000..063649c8 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/include/syslog.h @@ -0,0 +1,121 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 syslog.h + * @brief Defines syslog APIs and usage + * @version V1.1 + * @date 14. February 2019 + * @usage Add 3 lines codes below at head of source code file + * // 0: Err; 1: Err&Warn; 2: Err&Warn&Info; 3: Err&Warn&Info&Debug + * #define LOG_LEVEL 3 + * #include + ******************************************************************************/ +#include + +#ifndef _SYSLOG_H_ +#define _SYSLOG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef LOG_LEVEL +#if (LOG_LEVEL >= 3) && \ + (defined CONFIG_SYSLOG_LEVEL_DEBUG) +#define LOG_ENABLE_D +#endif + +#if (LOG_LEVEL >= 2) && \ + (defined CONFIG_SYSLOG_LEVEL_DEBUG || \ + defined CONFIG_SYSLOG_LEVEL_INFO) +#define LOG_ENABLE_I +#endif + +#if (LOG_LEVEL >= 1) && \ + (defined CONFIG_SYSLOG_LEVEL_DEBUG || \ + defined CONFIG_SYSLOG_LEVEL_INFO || \ + defined CONFIG_SYSLOG_LEVEL_WARN) +#define LOG_ENABLE_W +#endif + +#if (LOG_LEVEL >= 0) && \ + (defined CONFIG_SYSLOG_LEVEL_DEBUG || \ + defined CONFIG_SYSLOG_LEVEL_INFO || \ + defined CONFIG_SYSLOG_LEVEL_WARN || \ + defined CONFIG_SYSLOG_LEVEL_ERROR) +#define LOG_ENABLE_E +#endif +#endif /* #ifdef LOG_LEVEL */ + +/* [LogLevel:FileName:Function:Line] */ +extern const char *PFORMAT_D; +extern const char *PFORMAT_I; +extern const char *PFORMAT_W; +extern const char *PFORMAT_E; + +#define LOG_E_BASE_ARGS __FUNCTION__, __LINE__ +#define LOG_W_BASE_ARGS __FUNCTION__, __LINE__ +#define LOG_I_BASE_ARGS __FUNCTION__, __LINE__ +#define LOG_D_BASE_ARGS __FUNCTION__, __LINE__ + +/* Log in freely format without prefix */ +#define LOG_F(fmt, args...) printf(fmt,##args) + +/* Log debug */ +#ifdef LOG_ENABLE_D +#define LOG_D(fmt, args...) \ + do {printf(PFORMAT_D,LOG_D_BASE_ARGS); printf(fmt,##args);} while(0) +#else +#define LOG_D(fmt, args...) +#endif + +/* Log information */ +#ifdef LOG_ENABLE_I +#define LOG_I(fmt, args...) \ + do {printf(PFORMAT_I ,LOG_I_BASE_ARGS); printf(fmt,##args);} while(0) +#else +#define LOG_I(fmt, args...) +#endif + +/* Log warning */ +#ifdef LOG_ENABLE_W +#define LOG_W(fmt, args...) \ + do {printf(PFORMAT_W,LOG_W_BASE_ARGS); printf(fmt,##args);} while(0) +#else +#define LOG_W(fmt, args...) +#endif + +/* Log error */ +#ifdef LOG_ENABLE_E +#define LOG_E(fmt, args...) \ + do {printf(PFORMAT_E,LOG_E_BASE_ARGS); printf(fmt,##args);} while(0) +#else +#define LOG_E(fmt, args...) +#endif + +#define ENTER() LOG_D("Enter\n") +#define EXIT_VOID() do { LOG_D("Exit\n"); return;} while(0) +#define EXIT_INT(val) do { LOG_D("Exit, return val=%d\n", (int)val); return val;} while(0) +#define EXIT_PTR(ptr) do { LOG_D("Exit, return ptr=%p\n", (void*)ptr); return ptr;} while(0) + +#ifdef __cplusplus +} +#endif + +#endif /* _SYSLOG_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/src/csi_misc.c b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/src/csi_misc.c new file mode 100644 index 00000000..f9fd6ee2 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/src/csi_misc.c @@ -0,0 +1,25 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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. + */ + +#include +#include +#include +#include + +/* used by csi_mmu_set_mode(If there are multiple mmu modes) */ +int g_mmu_mode = 0; diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/src/csi_ringbuf.c b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/src/csi_ringbuf.c new file mode 100644 index 00000000..364b682c --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/csi/csi2/src/csi_ringbuf.c @@ -0,0 +1,184 @@ +#include +#include +#include +#include +#include "drv/ringbuf.h" + +#define min(a, b) (((a) < (b)) ? (a) : (b)) + +/** + * \brief Removes the entire FIFO contents. + * \param [in] fifo: The fifo to be emptied. + * \return None. + */ +void csi_ringbuf_reset(csi_ringbuf_t *fifo) +{ + uint32_t stat = csi_irq_save(); + fifo->write = fifo->read = 0; + fifo->data_len = 0; + csi_irq_restore(stat); +} + +/** + * \brief Returns the size of the FIFO in bytes. + * \param [in] fifo: The fifo to be used. + * \return The size of the FIFO. + */ +static inline uint32_t csi_ringbuf_size(csi_ringbuf_t *fifo) +{ + return fifo->size; +} + +/** + * \brief Returns the number of used bytes in the FIFO. + * \param [in] fifo: The fifo to be used. + * \return The number of used bytes. + */ +uint32_t csi_ringbuf_len(csi_ringbuf_t *fifo) +{ + return fifo->data_len; +} + +/** + * \brief Returns the number of bytes available in the FIFO. + * \param [in] fifo: The fifo to be used. + * \return The number of bytes available. + */ +uint32_t csi_ringbuf_avail(csi_ringbuf_t *fifo) +{ + return csi_ringbuf_size(fifo) - csi_ringbuf_len(fifo); +} + +/** + * \brief Is the FIFO empty? + * \param [in] fifo: The fifo to be used. + * \retval true: Yes. + * \retval false: No. + */ +bool csi_ringbuf_is_empty(csi_ringbuf_t *fifo) +{ + return csi_ringbuf_len(fifo) == 0; +} + +/** + * \brief Is the FIFO full? + * \param [in] fifo: The fifo to be used. + * \retval true: Yes. + * \retval false: No. + */ +bool csi_ringbuf_is_full(csi_ringbuf_t *fifo) +{ + return csi_ringbuf_avail(fifo) == 0; +} + +/** + * \brief Puts some data into the FIFO. + * \param [in] fifo: The fifo to be used. + * \param [in] in: The data to be added. + * \param [in] len: The length of the data to be added. + * \return The number of bytes copied. + * \note This function copies at most @len bytes from the @in into + * the FIFO depending on the free space, and returns the number + * of bytes copied. + */ +uint32_t csi_ringbuf_in(csi_ringbuf_t *fifo, const void *datptr, uint32_t len) +{ + uint32_t writelen = 0, tmplen = 0; + + if(csi_ringbuf_is_full(fifo)) + return 0; + + tmplen = fifo->size - fifo->data_len; + writelen = tmplen > len ? len : tmplen; + + if(fifo->write < fifo->read) { + memcpy((void*)&fifo->buffer[fifo->write], (void*)datptr, writelen); + } else { + tmplen = fifo->size - fifo->write; + if(writelen <= tmplen) { + memcpy((void*)&fifo->buffer[fifo->write], (void*)datptr, writelen); + } else { + memcpy((void*)&fifo->buffer[fifo->write], (void*)datptr, tmplen); + memcpy((void*)fifo->buffer, (uint8_t*)datptr + tmplen, writelen - tmplen); + } + } + + uint32_t stat = csi_irq_save(); + fifo->write = (fifo->write + writelen) % fifo->size; + fifo->data_len += writelen; + csi_irq_restore(stat); + + return writelen; +} + +/** + * \brief Gets some data from the FIFO. + * \param [in] fifo: The fifo to be used. + * \param [in] out: Where the data must be copied. + * \param [in] len: The size of the destination buffer. + * \return The number of copied bytes. + * \note This function copies at most @len bytes from the FIFO into + * the @out and returns the number of copied bytes. + */ +uint32_t csi_ringbuf_out(csi_ringbuf_t *fifo, void *outbuf, uint32_t len) +{ + uint32_t readlen = 0, tmplen = 0; + if(csi_ringbuf_is_empty(fifo)) + return 0; + + uint32_t data_len = fifo->data_len; + readlen = len > data_len ? data_len : len; + tmplen = fifo->size - fifo->read; + + if(NULL != outbuf) { + if(readlen <= tmplen) { + memcpy((void*)outbuf, (void*)&fifo->buffer[fifo->read], readlen); + } else { + memcpy((void*)outbuf,(void*)&fifo->buffer[fifo->read], tmplen); + memcpy((uint8_t*)outbuf + tmplen,(void*)fifo->buffer,readlen - tmplen); + } + } + + uint32_t stat = csi_irq_save(); + fifo->read = (fifo->read + readlen) % fifo->size; + fifo->data_len -= readlen; + csi_irq_restore(stat); + + return readlen; +} + +/** + * \brief Move FIFO buffer to another FIFO. + * \param [in] fifo_in: The fifo to be used. + * \param [in] fifo_out: The fifo to be used. + * \return The number of copied bytes. + * \note This function copies at most @len bytes from the FIFO into + * the @out and returns the number of copied bytes. + */ +uint32_t csi_ringbuf_move(csi_ringbuf_t *fifo_in, csi_ringbuf_t *fifo_out) +{ + uint32_t readlen = 0, tmplen_out = 0; + if(csi_ringbuf_is_empty(fifo_out)) + return 0; + + uint32_t len = csi_ringbuf_avail(fifo_in); + + uint32_t data_len = fifo_out->data_len; + readlen = len > data_len ? data_len : len; + tmplen_out = fifo_out->size - fifo_out->read; + + if(readlen <= tmplen_out) { + csi_ringbuf_in(fifo_in, (void*)&fifo_out->buffer[fifo_out->read], readlen); + } else { + csi_ringbuf_in(fifo_in, (void*)&fifo_out->buffer[fifo_out->read], tmplen_out); + csi_ringbuf_in(fifo_in, (void*)fifo_out->buffer, readlen - tmplen_out); + } + + uint32_t stat = csi_irq_save(); + fifo_out->read = (fifo_out->read + readlen) % fifo_out->size; + fifo_out->data_len -= readlen; + csi_irq_restore(stat); + + return readlen; +} + diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/compilers/gcc/sys/ioctl.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/compilers/gcc/sys/ioctl.h new file mode 100644 index 00000000..8ab7ef9a --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/compilers/gcc/sys/ioctl.h @@ -0,0 +1,46 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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. + */ + +#ifndef __INCLUDE_SYS_IOCTL_H +#define __INCLUDE_SYS_IOCTL_H +#ifdef __cplusplus +extern "C" { +#endif + + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +int ioctl(int fd, int req, ...); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __INCLUDE_SYS_IOCTL_H */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/compilers/gcc/sys/termios.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/compilers/gcc/sys/termios.h new file mode 100644 index 00000000..137d937c --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/compilers/gcc/sys/termios.h @@ -0,0 +1,291 @@ +/* + * Copyright (C) 2020-2021 Alibaba Group Holding Limited + * A modified version of termios in Haiku OS + * Distributed under the terms of the MIT License. + */ + +#ifndef _SYS_TERMIOS_H_ +#define _SYS_TERMIOS_H_ + +#include + +typedef unsigned long tcflag_t; +typedef unsigned long speed_t; +typedef unsigned char cc_t; + +#define NCCS 12 /* number of control characters */ + +struct termios { + tcflag_t c_iflag; /* input modes */ + tcflag_t c_oflag; /* output modes */ + tcflag_t c_cflag; /* control modes */ + tcflag_t c_lflag; /* local modes */ + cc_t c_cc[NCCS]; /* control characters */ +}; + +/* control characters */ +#define VINTR 0 +#define VQUIT 1 +#define VERASE 2 +#define VKILL 3 +#define VEOF 4 +#define VEOL 5 +#define VMIN 6 +#define VTIME 7 +#define VEOL2 8 +#define VSTART 9 +#define VSTOP 10 +#define VSUSP 11 + +/* c_iflag - input control modes */ +#define IGNBRK 0x0001 /* ignore break condition */ +#define BRKINT 0x0002 /* break sends interrupt */ +#define IGNPAR 0x0004 /* ignore characters with parity errors */ +#define PARMRK 0x0008 /* mark parity errors */ +#define INPCK 0x0010 /* enable input parity checking */ +#define ISTRIP 0x0020 /* strip high bit from characters */ +#define INLCR 0x0040 /* maps newline to CR on input */ +#define IGNCR 0x0080 /* ignore carriage returns */ +#define ICRNL 0x0100 /* map CR to newline on input */ +#define IUCLC 0x0200 /* map all upper case to lower */ +#define IXON 0x0400 /* enable input SW flow control */ +#define IXANY 0x0800 /* any character will restart input */ +#define IXOFF 0x1000 /* enable output SW flow control */ + +/* c_oflag - output control modes */ +#define OPOST 0x0001 /* enable postprocessing of output */ +#define OLCUC 0x0002 /* map lowercase to uppercase */ +#define ONLCR 0x0004 /* map NL to CR-NL on output */ +#define OCRNL 0x0008 /* map CR to NL on output */ +#define ONOCR 0x0010 /* no CR output when at column 0 */ +#define ONLRET 0x0020 /* newline performs CR function */ +#define OFILL 0x0040 /* use fill characters for delays */ +#define OFDEL 0x0080 /* Fills are DEL, otherwise NUL */ +#define NLDLY 0x0100 /* Newline delays: */ +#define NL0 0x0000 +#define NL1 0x0100 +#define CRDLY 0x0600 /* Carriage return delays: */ +#define CR0 0x0000 +#define CR1 0x0200 +#define CR2 0x0400 +#define CR3 0x0600 +#define TABDLY 0x1800 /* Tab delays: */ +#define TAB0 0x0000 +#define TAB1 0x0800 +#define TAB2 0x1000 +#define TAB3 0x1800 +#define BSDLY 0x2000 /* Backspace delays: */ +#define BS0 0x0000 +#define BS1 0x2000 +#define VTDLY 0x4000 /* Vertical tab delays: */ +#define VT0 0x0000 +#define VT1 0x4000 +#define FFDLY 0x8000 /* Form feed delays: */ +#define FF0 0x0000 +#define FF1 0x8000 + +/* c_cflag - control modes */ +#define CBAUD 0x1000F /* line speed definitions */ +#define B0 0x00 /* hang up */ +#define B50 0x01 /* 50 baud */ +#define B75 0x02 +#define B110 0x03 +#define B134 0x04 +#define B150 0x05 +#define B200 0x06 +#define B300 0x07 +#define B600 0x08 +#define B1200 0x09 +#define B1800 0x0A +#define B2400 0x0B +#define B4800 0x0C +#define B9600 0x0D +#define B19200 0x0E +#define B38400 0x0F +#define CBAUDEX 0x10000 +#define B57600 0x10001 +#define B115200 0x10002 +#define B230400 0x10003 +#define B460800 0x10004 +#define B500000 0x10005 +#define B576000 0x10006 +#define B921600 0x10007 +#define B1000000 0x10008 +#define B1152000 0x10009 +#define B1500000 0x1000A +#define B2000000 0x1000B +#define B2500000 0x1000C +#define B3000000 0x1000D +#define B3500000 0x1000E +#define B4000000 0x1000F +#define CSIZE 0x0030 /* character size */ +#define CS5 0x0000 +#define CS6 0x0010 +#define CS7 0x0020 +#define CS8 0x0030 +#define CSTOPB 0x0040 /* send 2 stop bits, not 1 */ +#define CREAD 0x0080 /* enable receiver */ +#define PARENB 0x0100 /* parity enable */ +#define PARODD 0x0200 /* odd parity, else even */ +#define HUPCL 0x0400 /* hangs up on last close */ +#define CLOCAL 0x0800 /* indicates local line */ +#define XLOBLK 0x1000 /* block layer output? */ +#define CTSFLOW 0x2000 /* enable CTS flow */ +#define RTSFLOW 0x4000 /* enable RTS flow */ +#define CRTSCTS (RTSFLOW | CTSFLOW) + +/* c_lflag - local modes */ +#define ISIG 0x0001 /* enable signals */ +#define ICANON 0x0002 /* Canonical input */ +#define XCASE 0x0004 /* Canonical u/l case */ +#define ECHO 0x0008 /* Enable echo */ +#define ECHOE 0x0010 /* Echo erase as bs-sp-bs */ +#define ECHOK 0x0020 /* Echo nl after kill */ +#define ECHONL 0x0040 /* Echo nl */ +#define NOFLSH 0x0080 /* Disable flush after int or quit */ +#define TOSTOP 0x0100 /* stop bg processes that write to tty */ +#define IEXTEN 0x0200 /* implementation defined extensions */ +#define ECHOCTL 0x0400 +#define ECHOPRT 0x0800 +#define ECHOKE 0x1000 +#define FLUSHO 0x2000 +#define PENDIN 0x4000 + +/* options to tcsetattr() */ +#define TCSANOW 0x01 /* make change immediate */ +#define TCSADRAIN 0x02 /* drain output, then change */ +#define TCSAFLUSH 0x04 /* drain output, flush input */ + +/* actions for tcflow() */ +#define TCOOFF 0x01 /* suspend output */ +#define TCOON 0x02 /* restart output */ +#define TCIOFF 0x04 /* transmit STOP character, intended to stop input data */ +#define TCION 0x08 /* transmit START character, intended to resume input data */ + +/* values for tcflush() */ +#define TCIFLUSH 0x01 /* flush pending input */ +#define TCOFLUSH 0x02 /* flush untransmitted output */ +#define TCIOFLUSH 0x03 /* flush both */ + +#define cfmakeraw(termios) \ + do { \ + (termios)->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | \ + INLCR | IGNCR | ICRNL | IXON); \ + (termios)->c_oflag &= ~OPOST; \ + (termios)->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); \ + (termios)->c_cflag &= ~(CSIZE | PARENB); \ + (termios)->c_cflag |= CS8; \ + } while (0) + +#define cfsetspeed(termios, speed) \ + ({ \ + tcflag_t flag; \ + int ret = 0; \ + switch (speed) { \ + case 0: \ + flag = B0; \ + break; \ + case 50: \ + flag = B50; \ + break; \ + case 75: \ + flag = B75; \ + break; \ + case 110: \ + flag = B110; \ + break; \ + case 134: \ + flag = B134; \ + break; \ + case 150: \ + flag = B150; \ + break; \ + case 200: \ + flag = B200; \ + break; \ + case 300: \ + flag = B300; \ + break; \ + case 600: \ + flag = B600; \ + break; \ + case 1200: \ + flag = B1200; \ + break; \ + case 1800: \ + flag = B1800; \ + break; \ + case 2400: \ + flag = B2400; \ + break; \ + case 4800: \ + flag = B4800; \ + break; \ + case 9600: \ + flag = B9600; \ + break; \ + case 19200: \ + flag = B19200; \ + break; \ + case 38400: \ + flag = B38400; \ + break; \ + case 57600: \ + flag = B57600; \ + break; \ + case 115200: \ + flag = B115200; \ + break; \ + case 230400: \ + flag = B230400; \ + break; \ + case 460800: \ + flag = B460800; \ + break; \ + case 500000: \ + flag = B500000; \ + break; \ + case 576000: \ + flag = B576000; \ + break; \ + case 921600: \ + flag = B921600; \ + break; \ + case 1000000: \ + flag = B1000000; \ + break; \ + case 1152000: \ + flag = B1152000; \ + break; \ + case 1500000: \ + flag = B1500000; \ + break; \ + case 2000000: \ + flag = B2000000; \ + break; \ + case 2500000: \ + flag = B2500000; \ + break; \ + case 3000000: \ + flag = B3000000; \ + break; \ + case 3500000: \ + flag = B3500000; \ + break; \ + case 4000000: \ + flag = B4000000; \ + break; \ + default: \ + ret = -1; \ + break; \ + } \ + if (ret) { \ + errno = EINVAL; \ + } else { \ + (termios)->c_cflag &= ~CBAUD; \ + (termios)->c_cflag |= flag; \ + } \ + ret; \ + }) + +#endif /* _SYS_TERMIOS_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/compilers/gcc/time.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/compilers/gcc/time.h new file mode 100644 index 00000000..febb819e --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/compilers/gcc/time.h @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * 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. + */ + +#ifndef __INCLUDE_TIME_H +#define __INCLUDE_TIME_H + +/******************************************************************************** + * Included Files + ********************************************************************************/ +#include +#include +#include +#include +#include + +/******************************************************************************** + * Pre-processor Definitions + ********************************************************************************/ + +/* Clock tick of the system (frequency Hz). + * + * NOTE: This symbolic name CLK_TCK has been removed from the standard. It is + * replaced with CLOCKS_PER_SEC. Both are defined here. + * + * The default value is 100Hz + */ +# define CLK_TCK (1000000) +# define CLOCKS_PER_SEC (1000000) + +#define NSEC_PER_SEC 1000000000 +#define USEC_PER_SEC 1000000 +#define NSEC_PER_USEC 1000 +#define USEC_PER_MSEC 1000 +#define MSEC_PER_SEC 1000 +#define NSEC_PER_MSEC 1000000 +#define TICK2MSEC(tick) ((tick)* (1000 / CLOCKS_PER_SEC)) + +extern long timezone; + +/* CLOCK_REALTIME refers to the standard time source. For most + * implementations, the standard time source is the system timer interrupt. + * However, if the platform supports an RTC, then the standard time source + * will be the RTC for the clock_gettime() and clock_settime() interfaces + * (the system timer is still the time source for all of the interfaces). + * + * CLOCK_REALTIME represents the machine's best-guess as to the current + * wall-clock, time-of-day time. This means that CLOCK_REALTIME can jump + * forward and backward as the system time-of-day clock is changed. + */ + +#define CLOCK_REALTIME 0 + +/* Clock that cannot be set and represents monotonic time since some + * unspecified starting point. It is not affected by changes in the + * system time-of-day clock. + */ +#define CLOCK_MONOTONIC 1 + +/* This is a flag that may be passed to the timer_settime() function */ + +#define TIMER_ABSTIME 1 + +/* Local time is the same as gmtime in this implementation */ +// # define localtime(c) gmtime(c) +// # define localtime_r(c,r) gmtime_r(c,r) + +/******************************************************************************** + * Public Types + ********************************************************************************/ +/* Scalar types */ + +// #ifndef _TIME_T_DECLARED +// #define _TIME_T_DECLARED +// typedef int32_t time_t; /* Holds time in seconds */ +// #endif + + +// #ifndef _CLOCK_T_DECLARED +// #define _CLOCK_T_DECLARED +// typedef uint32_t clock_t; +// #endif + +/* struct tm is the standard representation for "broken out" time. + * + * REVISIT: This structure could be packed better using uint8_t's and + * uint16_t's. The standard definition does, however, call out type int for + * all of the members. NOTE: Any changes to this structure must be also be + * reflected in struct rtc_time defined in include/nuttx/timers/rtc.h; these + * two structures must be cast compatible. + */ + +struct tm +{ + int tm_sec; /* Seconds (0-61, allows for leap seconds) */ + int tm_min; /* Minutes (0-59) */ + int tm_hour; /* Hours (0-23) */ + int tm_mday; /* Day of the month (1-31) */ + int tm_mon; /* Month (0-11) */ + int tm_year; /* Years since 1900 */ + int tm_wday; /* Day of the week (0-6) */ + int tm_yday; /* Day of the year (0-365) */ + int tm_isdst; /* Non-0 if daylight savings time is in effect */ +}; + +/* forward reference (defined in signal.h) */ + +struct sigevent; + +/******************************************************************************** + * Public Data + ********************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/******************************************************************************** + * Public Function Prototypes + ********************************************************************************/ +int clock_settime(clockid_t clockid, const struct timespec *tp); +int clock_gettime(clockid_t clockid, struct timespec *tp); + +time_t mktime(struct tm *tp); +struct tm *gmtime(const time_t *timep); +struct tm *gmtime_r(const time_t *timep, struct tm *result); +struct tm *localtime (const time_t *timep); +struct tm *localtime_r(const time_t *timep, struct tm *result); + +size_t strftime( char *s, size_t max, const char *format, + const struct tm *tm); + +char *ctime( const time_t *timep); + +time_t time( time_t *timep); + +clock_t clock(void); + +double difftime(time_t tim1, time_t tim2); +char *asctime(const struct tm *tim_p); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __INCLUDE_TIME_H */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/include/errno.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/include/errno.h new file mode 100644 index 00000000..0c280ce2 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/include/errno.h @@ -0,0 +1,193 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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 errno.h + * @brief header file for error num + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#ifndef __ERRNO_H__ +#define __ERRNO_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/**************************************************************************** + * Error Number Definitions + ****************************************************************************/ +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Argument list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No child processes */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* Out of memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Math argument out of domain of func */ +#define ERANGE 34 /* Math result not representable */ +#define EDEADLK 35 /* Resource deadlock would occur */ +#define ENAMETOOLONG 36 /* File name too long */ +#define ENOLCK 37 /* No record locks available */ + +/* + * This error code is special: arch syscall entry code will return + * -ENOSYS if users try to call a syscall that doesn't exist. To keep + * failures of syscalls that really do exist distinguishable from + * failures due to attempts to use a nonexistent syscall, syscall + * implementations should refrain from returning -ENOSYS. + */ +#define ENOSYS 38 /* Invalid system call number */ + +#define ENOTEMPTY 39 /* Directory not empty */ +#define ELOOP 40 /* Too many symbolic links encountered */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ +#define ENOMSG 42 /* No message of desired type */ +#define EIDRM 43 /* Identifier removed */ +#define ECHRNG 44 /* Channel number out of range */ +#define EL2NSYNC 45 /* Level 2 not synchronized */ +#define EL3HLT 46 /* Level 3 halted */ +#define EL3RST 47 /* Level 3 reset */ +#define ELNRNG 48 /* Link number out of range */ +#define EUNATCH 49 /* Protocol driver not attached */ +#define ENOCSI 50 /* No CSI structure available */ +#define EL2HLT 51 /* Level 2 halted */ +#define EBADE 52 /* Invalid exchange */ +#define EBADR 53 /* Invalid request descriptor */ +#define EXFULL 54 /* Exchange full */ +#define ENOANO 55 /* No anode */ +#define EBADRQC 56 /* Invalid request code */ +#define EBADSLT 57 /* Invalid slot */ + +#define EDEADLOCK EDEADLK + +#define EBFONT 59 /* Bad font file format */ +#define ENOSTR 60 /* Device not a stream */ +#define ENODATA 61 /* No data available */ +#define ETIME 62 /* Timer expired */ +#define ENOSR 63 /* Out of streams resources */ +#define ENONET 64 /* Machine is not on the network */ +#define ENOPKG 65 /* Package not installed */ +#define EREMOTE 66 /* Object is remote */ +#define ENOLINK 67 /* Link has been severed */ +#define EADV 68 /* Advertise error */ +#define ESRMNT 69 /* Srmount error */ +#define ECOMM 70 /* Communication error on send */ +#define EPROTO 71 /* Protocol error */ +#define EMULTIHOP 72 /* Multihop attempted */ +#define EDOTDOT 73 /* RFS specific error */ +#define EBADMSG 74 /* Not a data message */ +#define EOVERFLOW 75 /* Value too large for defined data type */ +#define ENOTUNIQ 76 /* Name not unique on network */ +#define EBADFD 77 /* File descriptor in bad state */ +#define EREMCHG 78 /* Remote address changed */ +#define ELIBACC 79 /* Can not access a needed shared library */ +#define ELIBBAD 80 /* Accessing a corrupted shared library */ +#define ELIBSCN 81 /* .lib section in a.out corrupted */ +#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ +#define ELIBEXEC 83 /* Cannot exec a shared library directly */ +#define EILSEQ 84 /* Illegal byte sequence */ +#define ERESTART 85 /* Interrupted system call should be restarted */ +#define ESTRPIPE 86 /* Streams pipe error */ +#define EUSERS 87 /* Too many users */ +#define ENOTSOCK 88 /* Socket operation on non-socket */ +#define EDESTADDRREQ 89 /* Destination address required */ +#define EMSGSIZE 90 /* Message too long */ +#define EPROTOTYPE 91 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 92 /* Protocol not available */ +#define EPROTONOSUPPORT 93 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 94 /* Socket type not supported */ +#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define EPFNOSUPPORT 96 /* Protocol family not supported */ +#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ +#define EADDRINUSE 98 /* Address already in use */ +#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ +#define ENETDOWN 100 /* Network is down */ +#define ENETUNREACH 101 /* Network is unreachable */ +#define ENETRESET 102 /* Network dropped connection because of reset */ +#define ECONNABORTED 103 /* Software caused connection abort */ +#define ECONNRESET 104 /* Connection reset by peer */ +#define ENOBUFS 105 /* No buffer space available */ +#define EISCONN 106 /* Transport endpoint is already connected */ +#define ENOTCONN 107 /* Transport endpoint is not connected */ +#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ +#define ETOOMANYREFS 109 /* Too many references: cannot splice */ +#define ETIMEDOUT 110 /* Connection timed out */ +#define ECONNREFUSED 111 /* Connection refused */ +#define EHOSTDOWN 112 /* Host is down */ +#define EHOSTUNREACH 113 /* No route to host */ +#define EALREADY 114 /* Operation already in progress */ +#define EINPROGRESS 115 /* Operation now in progress */ +#define ESTALE 116 /* Stale file handle */ +#define EUCLEAN 117 /* Structure needs cleaning */ +#define ENOTNAM 118 /* Not a XENIX named type file */ +#define ENAVAIL 119 /* No XENIX semaphores available */ +#define EISNAM 120 /* Is a named type file */ +#define EREMOTEIO 121 /* Remote I/O error */ +#define EDQUOT 122 /* Quota exceeded */ + +#define ENOMEDIUM 123 /* No medium found */ +#define EMEDIUMTYPE 124 /* Wrong medium type */ +#define ECANCELED 125 /* Operation Canceled */ +#define ENOKEY 126 /* Required key not available */ +#define EKEYEXPIRED 127 /* Key has expired */ +#define EKEYREVOKED 128 /* Key has been revoked */ +#define EKEYREJECTED 129 /* Key was rejected by service */ + +/* for robust mutexes */ +#define EOWNERDEAD 130 /* Owner died */ +#define ENOTRECOVERABLE 131 /* State not recoverable */ + +#define ERFKILL 132 /* Operation not possible due to RF-kill */ + +#define EHWPOISON 133 /* Memory page has hardware error */ + +#define ENOTSUP 134 /* Not supported */ + +extern int errno; + +#ifdef __cplusplus +} +#endif + +#endif /* __ERRNO_H__ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/include/inttypes.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/include/inttypes.h new file mode 100644 index 00000000..cd8b619a --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/include/inttypes.h @@ -0,0 +1,57 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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. + */ + +#ifndef _PRIV_INTTYPES_H_ +#define _PRIV_INTTYPES_H_ +#ifdef __cplusplus +extern "C" { +#endif + +#include_next + +#undef PRId32 +#undef PRIi32 +#undef PRIo32 +#undef PRIu32 +#undef PRIx32 +#undef PRIX32 + +#undef SCNd32 +#undef SCNi32 +#undef SCNo32 +#undef SCNu32 +#undef SCNx32 + +#define PRId32 __STRINGIFY(d) +#define PRIi32 __STRINGIFY(i) +#define PRIo32 __STRINGIFY(o) +#define PRIu32 __STRINGIFY(u) +#define PRIx32 __STRINGIFY(x) +#define PRIX32 __STRINGIFY(X) + +#define SCNd32 __STRINGIFY(d) +#define SCNi32 __STRINGIFY(i) +#define SCNo32 __STRINGIFY(o) +#define SCNu32 __STRINGIFY(u) +#define SCNx32 __STRINGIFY(x) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/include/serf/minilibc_stdio.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/include/serf/minilibc_stdio.h new file mode 100644 index 00000000..67b6bb40 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/include/serf/minilibc_stdio.h @@ -0,0 +1,85 @@ +/* + * minilibc stdio + * + * Copyright (C): 2012 Hangzhou C-SKY Microsystem Co.,LTD. + * Author: Junshan Hu (junshan_hu@c-sky.com) + * Contrbutior: Chunqiang Li + * Date: 2012-5-4 + */ + +#ifndef _MINILIBC_STDIO_H_ +#define _MINILIBC_STDIO_H_ + +#include + +#define BUFSIZE 2048 + +struct __stdio_file { + int fd; + int flags; + unsigned int bs; /* read: bytes in buffer */ + unsigned int bm; /* position in buffer */ +// unsigned int buflen; /* length of buf */ +// char *buf; + struct __stdio_file *next; /* for fflush */ + unsigned char ungetbuf; + char ungotten; + unsigned int lock; +}; + +#define ERRORINDICATOR 1 +#define EOFINDICATOR 2 +#define BUFINPUT 4 +#define BUFLINEWISE 8 +#define NOBUF 16 +#define STATICBUF 32 +#define FDPIPE 64 +#define CANREAD 128 +#define CANWRITE 256 + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*fmt_out_fn)(char * strbuf, int len); +typedef int (*fmt_in_fn)(void); +extern fmt_out_fn g_current_outputs; +extern fmt_in_fn g_current_inputs; +#define print_current_out_set(fn) do{g_current_outputs = fn;}while(0) +#define print_current_in_set(fn) do{g_current_inputs = fn;}while(0) +static inline int is_normal_outputs(void) +{ + if(g_current_inputs) + return 0; + return 1; +} + +/* ..scanf */ +struct arg_scanf { + void *data; + int (*getch)(void*); + int (*putch)(int,void*); +}; + +int __v_scanf(struct arg_scanf* fn, const char *format, va_list arg_ptr); + +struct arg_printf { + void *data; + int (*put)(void*,size_t,void*); +}; + +int yoc__v_printf(struct arg_printf* fn, const char *format, va_list arg_ptr); +int __isinf(double d); +int __isnan(double d); +int __dtostr(double d,char *buf,unsigned int maxlen,unsigned int prec,unsigned int prec2); +int __lltostr(char *s, int size, unsigned long long i, int base, char UpCase); +int __ltostr(char *s, unsigned int size, unsigned long i, unsigned int base, int UpCase); + + +#ifdef __cplusplus +} +#endif + +#endif /* _MINILIBC_STDIO_H_ */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/include/sys/_stdint.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/include/sys/_stdint.h new file mode 100644 index 00000000..88d8fe4d --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/include/sys/_stdint.h @@ -0,0 +1,45 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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. + */ + +#ifndef _PRIV_STDINT_H_ +#define _PRIV_STDINT_H_ +#ifdef __cplusplus +extern "C" { +#endif + +#if __STDC_HOSTED__ +/* For newlib and minilibc utint32_t are not same */ +#undef _UINT32_T_DECLARED +#define _UINT32_T_DECLARED +typedef unsigned int uint32_t; + +#undef _INT32_T_DECLARED +#define _INT32_T_DECLARED +typedef signed int int32_t; + +#endif /* __STDC_HOSTED__ */ + +#define IN_ADDR_T_DEFINED + +#include_next + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/include/sys/random.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/include/sys/random.h new file mode 100644 index 00000000..bce4b7f7 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/include/sys/random.h @@ -0,0 +1,34 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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. + */ + +#ifndef __SYS_RANDOM__ +#define __SYS_RANDOM__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +ssize_t getrandom(void *buf, size_t buflen, unsigned int flags); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif //__SYS_RANDOM__ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/include/sys/select.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/include/sys/select.h new file mode 100644 index 00000000..56f479c3 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/include/sys/select.h @@ -0,0 +1,52 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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. + */ + +#ifndef __SYS_SELECT_H +#define __SYS_SELECT_H + +#include + +#ifndef FD_SETSIZE +#define FD_SETSIZE 1024 +#endif + +typedef unsigned long fd_mask; +typedef struct { + unsigned long fds_bits[FD_SETSIZE / 8 / sizeof(long)]; +} fd_set; + +#define FD_ZERO(s) memset((void*)(s), 0, sizeof(*(s))) +#define FD_SET(d, s) ((s)->fds_bits[(d) / (8 * sizeof(long))] |= (1UL << ((d) % (8 * sizeof(long))))) +#define FD_CLR(d, s) ((s)->fds_bits[(d) / (8 * sizeof(long))] &= ~(1UL << ((d) % (8 * sizeof(long))))) +#define FD_ISSET(d, s) (!!((s)->fds_bits[(d) / (8 * sizeof(long))] & (1UL << ((d) % (8 * sizeof(long)))))) + +#ifdef __cplusplus +extern "C" { +#endif + +int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, + struct timeval *timeout); + +extern int select2(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, + struct timeval *timeout, void *semaphore); + +#ifdef __cplusplus +} +#endif + +#endif /*__SYS_SELECT_H*/ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/include/sys/time.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/include/sys/time.h new file mode 100644 index 00000000..0e4ed9d5 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/include/sys/time.h @@ -0,0 +1,134 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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. + */ + +#ifndef __INCLUDE_SYS_TIME_H +#define __INCLUDE_SYS_TIME_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _TIME_T_DECLARED +#define _TIME_T_DECLARED +typedef int32_t time_t; +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Type Definitions + ****************************************************************************/ +#ifndef _TIMEVAL_DEFINED +#define _TIMEVAL_DEFINED +/* struct timeval represents time as seconds plus microseconds */ + +struct timeval +{ + time_t tv_sec; /* Seconds */ + long tv_usec; /* Microseconds */ +}; +#endif + +/* The use of the struct timezone is obsolete; the tz argument should + * normally be specified as NULL (and is ignored in any event). + */ + +struct timezone +{ + int tz_minuteswest; /* Minutes west of Greenwich */ + int tz_dsttime; /* Type of DST correction */ +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: gettimeofday + * + * Description: + * Get the current time + * + * Conforming to SVr4, 4.3BSD. POSIX.1-2001 describes gettimeofday(). + * POSIX.1-2008 marks gettimeofday() as obsolete, recommending the use of + * clock_gettime(2) instead. + * + * NuttX implements gettimeofday() as a thin layer around clock_gettime(); + * + * Input Parameters: + * tv - The location to return the current time + * tz - Ignored + * + * Returned value: + * Zero (OK) on success; -1 is returned on failure with the errno variable + * set appropriately. + * + ****************************************************************************/ + +int gettimeofday( struct timeval *tv, struct timezone *tz); + +/**************************************************************************** + * Name: settimeofday + * + * Description: + * Set the current time + * + * Conforming to SVr4, 4.3BSD. POSIX.1-2001 describes gettimeofday() but + * not settimeofday(). + * + * NuttX implements settimeofday() as a thin layer around clock_settime(); + * + * Input Parameters: + * tv - The net to time to be set + * tz - Ignored + * + * Returned value: + * Zero (OK) on success; -1 is returned on failure with the errno variable + * set appropriately. + * + ****************************************************************************/ + +int settimeofday( const struct timeval *tv, const struct timezone *tz); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __INCLUDE_SYS_TIME_H */ diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/mini_printf.c b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/mini_printf.c new file mode 100644 index 00000000..e1aea6e6 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/mini_printf.c @@ -0,0 +1,947 @@ +/////////////////////////////////////////////////////////////////////////////// +// \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). +// +/////////////////////////////////////////////////////////////////////////////// + +#if CONFIG_LIBC_MINI_PRINTF_SUPPORT +#include +#include +#include + +#include +#include +#include +#include +#include + + +// 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 + + +// '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 + +extern csi_uart_t g_console_handle; + +static void _putchar(char character) +{ + if (character == '\n') { + csi_uart_putc(&g_console_handle, '\r'); + } + + csi_uart_putc(&g_console_handle, character); +} + +// 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 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 fprintf(FILE *stream, 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 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 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 vprintf(const char* format, va_list va) +{ + char buffer[1]; + return _vsnprintf(_out_char, buffer, (size_t)-1, format, va); +} + + +int 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; +} +#endif + diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/newlib_stub.c b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/newlib_stub.c new file mode 100644 index 00000000..593d8572 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/components/libc_threadx/newlib_stub.c @@ -0,0 +1,317 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern csi_uart_t g_console_handle; + +int _execve_r(struct _reent *ptr, const char *name, char *const *argv, + char *const *env) +{ + ptr->_errno = ENOSYS; + return -1; +} + +int _fcntl_r(struct _reent *ptr, int fd, int cmd, int arg) +{ + ptr->_errno = EBADF; + return -1; +} + +int _fork_r(struct _reent *ptr) +{ + ptr->_errno = ENOSYS; + return -1; +} + +int _getpid_r(struct _reent *ptr) +{ + ptr->_errno = ENOSYS; + return 0; +} + +int _isatty_r(struct _reent *ptr, int fd) +{ + if (fd >= 0 && fd < 3) { + return 1; + } + + ptr->_errno = ENOTTY; + return 0; +} + +int _kill_r(struct _reent *ptr, int pid, int sig) +{ + ptr->_errno = ENOSYS; + return -1; +} + +_off_t _lseek_r(struct _reent *ptr, int fd, _off_t pos, int whence) +{ + ptr->_errno = ENOSYS; + return -1; +} + +int _mkdir_r(struct _reent *ptr, const char *name, int mode) +{ + ptr->_errno = ENOSYS; + return -1; +} + +int _open_r(struct _reent *ptr, const char *file, int flags, int mode) +{ + ptr->_errno = ENOSYS; + return -1; +} + +int _close_r(struct _reent *ptr, int fd) +{ + ptr->_errno = EBADF; + return -1; +} + +_ssize_t _read_r(struct _reent *ptr, int fd, void *buf, size_t nbytes) +{ + ptr->_errno = EBADF; + return -1; +} + +int fputc(int ch, FILE *stream) +{ + if (ch == '\n') { + csi_uart_putc(&g_console_handle, '\r'); + } + + csi_uart_putc(&g_console_handle, ch); + return 0; +} + +int fgetc(FILE *stream) +{ + (void)stream; + + return csi_uart_getc(&g_console_handle); +} + +int putc(int c, FILE *stream) +{ + return fputc(c, stream); +} + +int puts(const char *s) +{ + while(*s !='\0') { + fputc(*s, (void *)-1); + s++; + } + fputc('\n', (void *)-1); + return 0; +} + +static void _putchar(char character) +{ + if (character == '\n') { + csi_uart_putc(&g_console_handle, '\r'); + } + + csi_uart_putc(&g_console_handle, character); + +} + +int putchar(int c) +{ + _putchar(c); + return 0; +} + +_ssize_t _write_r(struct _reent *ptr, int fd, const void *buf, size_t nbytes) +{ + if ((fd == STDOUT_FILENO) || (fd == STDERR_FILENO)) { + for (int i = 0; i < nbytes; i++) + _putchar((*((char*)buf + i))); + return nbytes; + } else { + return -1; + } +} + +int ioctl(int fildes, int request, ... /* arg */) +{ + return -1; +} + +int _rename_r(struct _reent *ptr, const char *oldname, const char *newname) +{ + ptr->_errno = ENOSYS; + return -1; +} + +void *_sbrk_r(struct _reent *ptr, ptrdiff_t incr) +{ + ptr->_errno = ENOSYS; + return NULL; +} + +int _stat_r(struct _reent *ptr, const char *file, struct stat *pstat) +{ + ptr->_errno = ENOSYS; + return -1; +} + +int _fstat_r(struct _reent *ptr, int fd, struct stat *buf) +{ + ptr->_errno = EBADF; + return -1; +} + +_CLOCK_T_ _times_r(struct _reent *ptr, struct tms *ptms) +{ + ptr->_errno = ENOSYS; + return -1; +} + +int _link_r(struct _reent *ptr, const char *oldpath, const char *newpath) +{ + ptr->_errno = ENOSYS; + return -1; +} + +int _unlink_r(struct _reent *ptr, const char *file) +{ + ptr->_errno = ENOSYS; + return -1; +} + +int _wait_r(struct _reent *ptr, int *status) +{ + ptr->_errno = ENOSYS; + return -1; +} + +int _gettimeofday_r(struct _reent *ptr, struct timeval *tv, void *__tzp) +{ + return 0; +} + +long timezone = 8; /* default CTS */ + +struct tm* localtime_r(const time_t* t, struct tm* r) +{ + time_t time_tmp; + time_tmp = *t + timezone * 3600; + return gmtime_r(&time_tmp, r); +} + +struct tm* localtime(const time_t* t) +{ + struct tm* timeinfo; + static struct tm tm_tmp; + + timeinfo = localtime_r(t, &tm_tmp); + + return timeinfo; +} + +extern TX_BYTE_POOL tx_byte_pool_0; +void *_malloc_r(struct _reent *ptr, size_t size) +{ + UINT ret; + void *p; + + ret = tx_byte_allocate(&tx_byte_pool_0, &p, size, TX_NO_WAIT); + if(ret != TX_SUCCESS) { + return NULL; + } + return p; +} + +void *_realloc_r(struct _reent *ptr, void *old, size_t newlen) +{ + return NULL; +} + +void *_calloc_r(struct _reent *ptr, size_t size, size_t len) +{ + UINT ret; + void *p; + + ret = tx_byte_allocate(&tx_byte_pool_0, &p, size * len, TX_NO_WAIT); + if(ret != TX_SUCCESS) { + return NULL; + } + memset(p, 0, size * len); + + return p; +} + +void *_memalign_r(struct _reent *ptr, size_t alignment, size_t size) +{ + return NULL; +} + +void _free_r(struct _reent *ptr, void *addr) +{ + if (!addr) + return; + tx_byte_release(addr); +} + +void _exit(int status) +{ + while (1) + ; +} + +void exit(int status) +{ + __builtin_unreachable(); // fix noreturn warning +} + +__attribute__((weak)) void _fini() +{ +} + +void _system(const char *s) +{ + return; +} + +void abort(void) +{ + __builtin_unreachable(); // fix noreturn warning +} + +int isatty(int fd) +{ + if (fd == fileno(stdin) || fd == fileno(stdout) || fd == fileno(stderr)) { + return -1; + } + return 0; +} + diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/demo_threadx.c b/ports/xuantie/e906/gnu/example_build/smartl_fpga/demo_threadx.c new file mode 100644 index 00000000..5f17f954 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/demo_threadx.c @@ -0,0 +1,372 @@ +/* This is a small demo of the high-performance ThreadX kernel. It includes examples of eight + threads of different priorities, using a message queue, semaphore, mutex, event flags group, + byte pool, and block pool. */ + +#include +#include "tx_api.h" + +#define DEMO_STACK_SIZE 1024 +#define DEMO_BYTE_POOL_SIZE 9120 +#define DEMO_BLOCK_POOL_SIZE 100 +#define DEMO_QUEUE_SIZE 100 + + +/* Define the ThreadX object control blocks... */ + +TX_THREAD thread_0; +TX_THREAD thread_1; +TX_THREAD thread_2; +TX_THREAD thread_3; +TX_THREAD thread_4; +TX_THREAD thread_5; +TX_THREAD thread_6; +TX_THREAD thread_7; +TX_QUEUE queue_0; +TX_SEMAPHORE semaphore_0; +TX_MUTEX mutex_0; +TX_EVENT_FLAGS_GROUP event_flags_0; +TX_BYTE_POOL byte_pool_0; +TX_BLOCK_POOL block_pool_0; +UCHAR memory_area[DEMO_BYTE_POOL_SIZE]; + + +/* Define the counters used in the demo application... */ + +ULONG thread_0_counter; +ULONG thread_1_counter; +ULONG thread_1_messages_sent; +ULONG thread_2_counter; +ULONG thread_2_messages_received; +ULONG thread_3_counter; +ULONG thread_4_counter; +ULONG thread_5_counter; +ULONG thread_6_counter; +ULONG thread_7_counter; + + +/* Define thread prototypes. */ + +void thread_0_entry(ULONG thread_input); +void thread_1_entry(ULONG thread_input); +void thread_2_entry(ULONG thread_input); +void thread_3_and_4_entry(ULONG thread_input); +void thread_5_entry(ULONG thread_input); +void thread_6_and_7_entry(ULONG thread_input); + + +/* Define main entry point. */ + +int main() +{ + + /* Enter the ThreadX kernel. */ + tx_kernel_enter(); +} + + +/* Define what the initial system looks like. */ + +void tx_application_define(void *first_unused_memory) +{ + +CHAR *pointer = TX_NULL; + + + /* Create a byte memory pool from which to allocate the thread stacks. */ + tx_byte_pool_create(&byte_pool_0, "byte pool 0", memory_area, DEMO_BYTE_POOL_SIZE); + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + /* Allocate the stack for thread 0. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 1, 1, TX_NO_TIME_SLICE, TX_AUTO_START); + + + /* Allocate the stack for thread 1. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); + + /* Create threads 1 and 2. These threads pass information through a ThreadX + message queue. It is also interesting to note that these threads have a time + slice. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, DEMO_STACK_SIZE, + 16, 16, 4, TX_AUTO_START); + + /* Allocate the stack for thread 2. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); + + tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, DEMO_STACK_SIZE, + 16, 16, 4, TX_AUTO_START); + + /* Allocate the stack for thread 3. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); + + /* Create threads 3 and 4. These threads compete for a ThreadX counting semaphore. + An interesting thing here is that both threads share the same instruction area. */ + tx_thread_create(&thread_3, "thread 3", thread_3_and_4_entry, 3, + pointer, DEMO_STACK_SIZE, + 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Allocate the stack for thread 4. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); + + tx_thread_create(&thread_4, "thread 4", thread_3_and_4_entry, 4, + pointer, DEMO_STACK_SIZE, + 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Allocate the stack for thread 5. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); + + /* Create thread 5. This thread simply pends on an event flag which will be set + by thread_0. */ + tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Allocate the stack for thread 6. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); + + /* Create threads 6 and 7. These threads compete for a ThreadX mutex. */ + tx_thread_create(&thread_6, "thread 6", thread_6_and_7_entry, 6, + pointer, DEMO_STACK_SIZE, + 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Allocate the stack for thread 7. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); + + tx_thread_create(&thread_7, "thread 7", thread_6_and_7_entry, 7, + pointer, DEMO_STACK_SIZE, + 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Allocate the message queue. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_QUEUE_SIZE*sizeof(ULONG), TX_NO_WAIT); + + /* Create the message queue shared by threads 1 and 2. */ + tx_queue_create(&queue_0, "queue 0", TX_1_ULONG, pointer, DEMO_QUEUE_SIZE*sizeof(ULONG)); + + /* Create the semaphore used by threads 3 and 4. */ + tx_semaphore_create(&semaphore_0, "semaphore 0", 1); + + /* Create the event flags group used by threads 1 and 5. */ + tx_event_flags_create(&event_flags_0, "event flags 0"); + + /* Create the mutex used by thread 6 and 7 without priority inheritance. */ + tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT); + + /* Allocate the memory for a small block pool. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_BLOCK_POOL_SIZE, TX_NO_WAIT); + + /* Create a block memory pool to allocate a message buffer from. */ + tx_block_pool_create(&block_pool_0, "block pool 0", sizeof(ULONG), pointer, DEMO_BLOCK_POOL_SIZE); + + /* Allocate a block and release the block memory. */ + tx_block_allocate(&block_pool_0, (VOID **) &pointer, TX_NO_WAIT); + + /* Release the block back to the pool. */ + tx_block_release(pointer); +} + + + +/* Define the test threads. */ + +void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* This thread simply sits in while-forever-sleep loop. */ + while(1) + { + puts("[Thread] : thread_0_entry is here!"); + /* Increment the thread counter. */ + thread_0_counter++; + + /* Sleep for 10 ticks. */ + tx_thread_sleep(10); + + /* Set event flag 0 to wakeup thread 5. */ + status = tx_event_flags_set(&event_flags_0, 0x1, TX_OR); + + /* Check status. */ + if (status != TX_SUCCESS) + break; + } +} + + +void thread_1_entry(ULONG thread_input) +{ + +UINT status; + + + /* This thread simply sends messages to a queue shared by thread 2. */ + while(1) + { + puts("[Thread] : thread_1_entry is here!"); + /* Increment the thread counter. */ + thread_1_counter++; + + /* Send message to queue 0. */ + status = tx_queue_send(&queue_0, &thread_1_messages_sent, TX_WAIT_FOREVER); + + /* Check completion status. */ + if (status != TX_SUCCESS) + break; + + /* Increment the message sent. */ + thread_1_messages_sent++; + } +} + + +void thread_2_entry(ULONG thread_input) +{ + +ULONG received_message; +UINT status; + + /* This thread retrieves messages placed on the queue by thread 1. */ + while(1) + { + puts("[Thread] : thread_2_entry is here!"); + /* Increment the thread counter. */ + thread_2_counter++; + + /* Retrieve a message from the queue. */ + status = tx_queue_receive(&queue_0, &received_message, TX_WAIT_FOREVER); + + /* Check completion status and make sure the message is what we + expected. */ + if ((status != TX_SUCCESS) || (received_message != thread_2_messages_received)) + break; + + /* Otherwise, all is okay. Increment the received message count. */ + thread_2_messages_received++; + } +} + + +void thread_3_and_4_entry(ULONG thread_input) +{ + +UINT status; + + + /* This function is executed from thread 3 and thread 4. As the loop + below shows, these function compete for ownership of semaphore_0. */ + while(1) + { + puts("[Thread] : thread_3_and_4_entry is here!"); + + /* Increment the thread counter. */ + if (thread_input == 3) + thread_3_counter++; + else + thread_4_counter++; + + /* Get the semaphore with suspension. */ + status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != TX_SUCCESS) + break; + + /* Sleep for 2 ticks to hold the semaphore. */ + tx_thread_sleep(2); + + /* Release the semaphore. */ + status = tx_semaphore_put(&semaphore_0); + + /* Check status. */ + if (status != TX_SUCCESS) + break; + } +} + + +void thread_5_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_flags; + + + /* This thread simply waits for an event in a forever loop. */ + while(1) + { + puts("[Thread] : thread_5_entry is here!"); + /* Increment the thread counter. */ + thread_5_counter++; + + /* Wait for event flag 0. */ + status = tx_event_flags_get(&event_flags_0, 0x1, TX_OR_CLEAR, + &actual_flags, TX_WAIT_FOREVER); + + /* Check status. */ + if ((status != TX_SUCCESS) || (actual_flags != 0x1)) + break; + } +} + + +void thread_6_and_7_entry(ULONG thread_input) +{ + +UINT status; + + + /* This function is executed from thread 6 and thread 7. As the loop + below shows, these function compete for ownership of mutex_0. */ + while(1) + { + puts("[Thread] : thread_6_and_7_entry is here!"); + /* Increment the thread counter. */ + if (thread_input == 6) + thread_6_counter++; + else + thread_7_counter++; + + /* Get the mutex with suspension. */ + status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != TX_SUCCESS) + break; + + /* Get the mutex again with suspension. This shows + that an owning thread may retrieve the mutex it + owns multiple times. */ + status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != TX_SUCCESS) + break; + + /* Sleep for 2 ticks to hold the mutex. */ + tx_thread_sleep(2); + + /* Release the mutex. */ + status = tx_mutex_put(&mutex_0); + + /* Check status. */ + if (status != TX_SUCCESS) + break; + + /* Release the mutex again. This will actually + release ownership since it was obtained twice. */ + status = tx_mutex_put(&mutex_0); + + /* Check status. */ + if (status != TX_SUCCESS) + break; + } +} diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/gdbinit b/ports/xuantie/e906/gnu/example_build/smartl_fpga/gdbinit new file mode 100644 index 00000000..1042ec78 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/gdbinit @@ -0,0 +1 @@ +target remote localhost:1234 \ No newline at end of file diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/pre_main.c b/ports/xuantie/e906/gnu/example_build/smartl_fpga/pre_main.c new file mode 100644 index 00000000..7227633d --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/pre_main.c @@ -0,0 +1,27 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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. + */ + +#include + +extern int main(); + +void pre_main(void) +{ + board_init(); + main(); +} \ No newline at end of file diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/tx_user.h b/ports/xuantie/e906/gnu/example_build/smartl_fpga/tx_user.h new file mode 100644 index 00000000..896e2233 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/tx_user.h @@ -0,0 +1,370 @@ +/*************************************************************************** + * Copyright (c) 2024 Microsoft Corporation + * + * This program and the accompanying materials are made available under the + * terms of the MIT License which is available at + * https://opensource.org/licenses/MIT. + * + * SPDX-License-Identifier: MIT + **************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** ThreadX Component */ +/** */ +/** User Specific */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + +/**************************************************************************/ +/* */ +/* PORT SPECIFIC C INFORMATION RELEASE */ +/* */ +/* tx_user.h PORTABLE C */ +/* 6.3.0 */ +/* */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains user defines for configuring ThreadX in specific */ +/* ways. This file will have an effect only if the application and */ +/* ThreadX library are built with TX_INCLUDE_USER_DEFINE_FILE defined. */ +/* Note that all the defines in this file may also be made on the */ +/* command line when building ThreadX library and application objects. */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 05-19-2020 William E. Lamie Initial Version 6.0 */ +/* 09-30-2020 Yuxin Zhou Modified comment(s), */ +/* resulting in version 6.1 */ +/* 03-02-2021 Scott Larson Modified comment(s), */ +/* added option to remove */ +/* FileX pointer, */ +/* resulting in version 6.1.5 */ +/* 06-02-2021 Scott Larson Added options for multiple */ +/* block pool search & delay, */ +/* resulting in version 6.1.7 */ +/* 10-15-2021 Yuxin Zhou Modified comment(s), added */ +/* user-configurable symbol */ +/* TX_TIMER_TICKS_PER_SECOND */ +/* resulting in version 6.1.9 */ +/* 04-25-2022 Wenhui Xie Modified comment(s), */ +/* optimized the definition of */ +/* TX_TIMER_TICKS_PER_SECOND, */ +/* resulting in version 6.1.11 */ +/* 10-31-2023 Xiuwen Cai Modified comment(s), */ +/* added option for random */ +/* number stack filling, */ +/* resulting in version 6.3.0 */ +/* */ +/**************************************************************************/ + +#ifndef TX_USER_H +#define TX_USER_H + +#ifndef __ASSEMBLY__ +/* define extra stack size */ +#if __riscv_matrix || __riscv_xtheadmatrix +static inline int _csi_xmlenb_get_value(void) +{ + int result; + __asm volatile("csrr %0, xmlenb" : "=r"(result) : : "memory"); + return result; +} +#define STACK_M_EXTRAL_SIZE (_csi_xmlenb_get_value() * 8 + 24) +#else +#define STACK_M_EXTRAL_SIZE 0 +#endif /* __riscv_matrix || __riscv_xtheadmatrix */ + +#ifdef __riscv_vector +static inline int _csi_vlenb_get_value(void) +{ + int result; + __asm volatile("csrr %0, vlenb" : "=r"(result) : : "memory"); + return result; +} + +#define STACK_V_EXTRAL_SIZE (_csi_vlenb_get_value() * 32 + 40) +#else +#define STACK_V_EXTRAL_SIZE 0 +#endif /* __riscv_vector */ + +#ifdef __riscv_flen +#define STACK_F_EXTRAL_SIZE (__riscv_flen / 8 * 32 + 8) +#else +#define STACK_F_EXTRAL_SIZE 0 +#endif /*__riscv_flen*/ + +#define CSK_CPU_STACK_EXTRAL (STACK_M_EXTRAL_SIZE + STACK_V_EXTRAL_SIZE + STACK_F_EXTRAL_SIZE) + +#ifndef STATIC_CSK_CPU_STACK_EXTRAL +#if defined(__riscv_matrix) || defined(__riscv_xtheadmatrix) || defined(__riscv_vector) +/* FIXME: for static allocate stack */ +#define STATIC_CSK_CPU_STACK_EXTRAL (8192) +#else +#define STATIC_CSK_CPU_STACK_EXTRAL (0) +#endif +#endif /* STATIC_CSK_CPU_STACK_EXTRAL */ + +#endif /* __ASSEMBLY__ */ + +/* Define various build options for the ThreadX port. The application should either make changes + here by commenting or un-commenting the conditional compilation defined OR supply the defines + though the compiler's equivalent of the -D option. + + For maximum speed, the following should be defined: + + TX_MAX_PRIORITIES 32 + TX_DISABLE_PREEMPTION_THRESHOLD + TX_DISABLE_REDUNDANT_CLEARING + TX_DISABLE_NOTIFY_CALLBACKS + TX_NOT_INTERRUPTABLE + TX_TIMER_PROCESS_IN_ISR + TX_REACTIVATE_INLINE + TX_DISABLE_STACK_FILLING + TX_INLINE_THREAD_RESUME_SUSPEND + + For minimum size, the following should be defined: + + TX_MAX_PRIORITIES 32 + TX_DISABLE_PREEMPTION_THRESHOLD + TX_DISABLE_REDUNDANT_CLEARING + TX_DISABLE_NOTIFY_CALLBACKS + TX_NO_FILEX_POINTER + TX_NOT_INTERRUPTABLE + TX_TIMER_PROCESS_IN_ISR + + Of course, many of these defines reduce functionality and/or change the behavior of the + system in ways that may not be worth the trade-off. For example, the TX_TIMER_PROCESS_IN_ISR + results in faster and smaller code, however, it increases the amount of processing in the ISR. + In addition, some services that are available in timers are not available from ISRs and will + therefore return an error if this option is used. This may or may not be desirable for a + given application. */ + + +/* Override various options with default values already assigned in tx_port.h. Please also refer + to tx_port.h for descriptions on each of these options. */ + +#define TX_MAX_PRIORITIES 32 +#define TX_MINIMUM_STACK (512 + CSK_CPU_STACK_EXTRAL) +#define TX_TIMER_THREAD_STACK_SIZE (512 + STATIC_CSK_CPU_STACK_EXTRAL) +/* +#define TX_MAX_PRIORITIES 32 +#define TX_MINIMUM_STACK ???? +#define TX_THREAD_USER_EXTENSION ???? +#define TX_TIMER_THREAD_STACK_SIZE ???? +#define TX_TIMER_THREAD_PRIORITY ???? +*/ + +/* Define the common timer tick reference for use by other middleware components. The default + value is 10ms (i.e. 100 ticks, defined in tx_api.h), but may be replaced by a port-specific + version in tx_port.h or here. + Note: the actual hardware timer value may need to be changed (usually in tx_initialize_low_level). */ + +#ifdef CONFIG_SYSTICK_HZ +#define TX_TIMER_TICKS_PER_SECOND CONFIG_SYSTICK_HZ +#else +#define TX_TIMER_TICKS_PER_SECOND 100 +#endif +/* +#define TX_TIMER_TICKS_PER_SECOND (100UL) +*/ + +/* Determine if there is a FileX pointer in the thread control block. + By default, the pointer is there for legacy/backwards compatibility. + The pointer must also be there for applications using FileX. + Define this to save space in the thread control block. +*/ + +/* +#define TX_NO_FILEX_POINTER +*/ + +/* Determine if timer expirations (application timers, timeouts, and tx_thread_sleep calls + should be processed within the a system timer thread or directly in the timer ISR. + By default, the timer thread is used. When the following is defined, the timer expiration + processing is done directly from the timer ISR, thereby eliminating the timer thread control + block, stack, and context switching to activate it. */ + +/* +#define TX_TIMER_PROCESS_IN_ISR +*/ + +/* Determine if in-line timer reactivation should be used within the timer expiration processing. + By default, this is disabled and a function call is used. When the following is defined, + reactivating is performed in-line resulting in faster timer processing but slightly larger + code size. */ + +/* +#define TX_REACTIVATE_INLINE +*/ + +/* Determine is stack filling is enabled. By default, ThreadX stack filling is enabled, + which places an 0xEF pattern in each byte of each thread's stack. This is used by + debuggers with ThreadX-awareness and by the ThreadX run-time stack checking feature. */ + +/* +#define TX_DISABLE_STACK_FILLING +*/ + +/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is + disabled. When the following is defined, ThreadX thread stack checking is enabled. If stack + checking is enabled (TX_ENABLE_STACK_CHECKING is defined), the TX_DISABLE_STACK_FILLING + define is negated, thereby forcing the stack fill which is necessary for the stack checking + logic. */ + +/* +#define TX_ENABLE_STACK_CHECKING +*/ + +/* Determine if random number is used for stack filling. By default, ThreadX uses a fixed + pattern for stack filling. When the following is defined, ThreadX uses a random number + for stack filling. This is effective only when TX_ENABLE_STACK_CHECKING is defined. */ + +/* +#define TX_ENABLE_RANDOM_NUMBER_STACK_FILLING +*/ + +/* Determine if preemption-threshold should be disabled. By default, preemption-threshold is + enabled. If the application does not use preemption-threshold, it may be disabled to reduce + code size and improve performance. */ + +/* +#define TX_DISABLE_PREEMPTION_THRESHOLD +*/ + +/* Determine if global ThreadX variables should be cleared. If the compiler startup code clears + the .bss section prior to ThreadX running, the define can be used to eliminate unnecessary + clearing of ThreadX global variables. */ + +/* +#define TX_DISABLE_REDUNDANT_CLEARING +*/ + +/* Determine if no timer processing is required. This option will help eliminate the timer + processing when not needed. The user will also have to comment out the call to + tx_timer_interrupt, which is typically made from assembly language in + tx_initialize_low_level. Note: if TX_NO_TIMER is used, the define TX_TIMER_PROCESS_IN_ISR + must also be used and tx_timer_initialize must be removed from ThreadX library. */ + +/* +#define TX_NO_TIMER +#ifndef TX_TIMER_PROCESS_IN_ISR +#define TX_TIMER_PROCESS_IN_ISR +#endif +*/ + +/* Determine if the notify callback option should be disabled. By default, notify callbacks are + enabled. If the application does not use notify callbacks, they may be disabled to reduce + code size and improve performance. */ + +/* +#define TX_DISABLE_NOTIFY_CALLBACKS +*/ + + +/* Determine if the tx_thread_resume and tx_thread_suspend services should have their internal + code in-line. This results in a larger image, but improves the performance of the thread + resume and suspend services. */ + +/* +#define TX_INLINE_THREAD_RESUME_SUSPEND +*/ + + +/* Determine if the internal ThreadX code is non-interruptable. This results in smaller code + size and less processing overhead, but increases the interrupt lockout time. */ + +/* +#define TX_NOT_INTERRUPTABLE +*/ + + +/* Determine if the trace event logging code should be enabled. This causes slight increases in + code size and overhead, but provides the ability to generate system trace information which + is available for viewing in TraceX. */ + +/* +#define TX_ENABLE_EVENT_TRACE +*/ + + +/* Determine if block pool performance gathering is required by the application. When the following is + defined, ThreadX gathers various block pool performance information. */ + +/* +#define TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO +*/ + +/* Determine if byte pool performance gathering is required by the application. When the following is + defined, ThreadX gathers various byte pool performance information. */ + +/* +#define TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO +*/ + +/* Determine if event flags performance gathering is required by the application. When the following is + defined, ThreadX gathers various event flags performance information. */ + +/* +#define TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO +*/ + +/* Determine if mutex performance gathering is required by the application. When the following is + defined, ThreadX gathers various mutex performance information. */ + +/* +#define TX_MUTEX_ENABLE_PERFORMANCE_INFO +*/ + +/* Determine if queue performance gathering is required by the application. When the following is + defined, ThreadX gathers various queue performance information. */ + +/* +#define TX_QUEUE_ENABLE_PERFORMANCE_INFO +*/ + +/* Determine if semaphore performance gathering is required by the application. When the following is + defined, ThreadX gathers various semaphore performance information. */ + +/* +#define TX_SEMAPHORE_ENABLE_PERFORMANCE_INFO +*/ + +/* Determine if thread performance gathering is required by the application. When the following is + defined, ThreadX gathers various thread performance information. */ + +/* +#define TX_THREAD_ENABLE_PERFORMANCE_INFO +*/ + +/* Determine if timer performance gathering is required by the application. When the following is + defined, ThreadX gathers various timer performance information. */ + +/* +#define TX_TIMER_ENABLE_PERFORMANCE_INFO +*/ + +/* Override options for byte pool searches of multiple blocks. */ + +/* +#define TX_BYTE_POOL_MULTIPLE_BLOCK_SEARCH 20 +*/ + +/* Override options for byte pool search delay to avoid thrashing. */ + +/* +#define TX_BYTE_POOL_DELAY_VALUE 3 +*/ + +#endif + diff --git a/ports/xuantie/e906/gnu/example_build/smartl_fpga/xuantie_e906_gnu.cmake b/ports/xuantie/e906/gnu/example_build/smartl_fpga/xuantie_e906_gnu.cmake new file mode 100644 index 00000000..2f6e9d91 --- /dev/null +++ b/ports/xuantie/e906/gnu/example_build/smartl_fpga/xuantie_e906_gnu.cmake @@ -0,0 +1,15 @@ +# Name of the target +set(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_SYSTEM_PROCESSOR xuantie_e906) + +set(THREADX_ARCH "xuantie_e906") +set(THREADX_TOOLCHAIN "gnu") +set(ARCH_FLAGS "-g -mcpu=e906fdp -mcmodel=medlow") +set(CFLAGS "${ARCH_FLAGS}") +set(ASFLAGS "${ARCH_FLAGS}") +set(LDFLAGS "${ARCH_FLAGS}") + +set(TX_USER_FILE ${CMAKE_CURRENT_LIST_DIR}/tx_user.h) +set(THREADX_CUSTOM_PORT ${CMAKE_CURRENT_LIST_DIR}/../../) + +include(${CMAKE_CURRENT_LIST_DIR}/../../../../../../cmake/riscv64-unknown-elf.cmake) \ No newline at end of file diff --git a/ports/xuantie/e906/gnu/inc/tx_port.h b/ports/xuantie/e906/gnu/inc/tx_port.h new file mode 100644 index 00000000..50f87587 --- /dev/null +++ b/ports/xuantie/e906/gnu/inc/tx_port.h @@ -0,0 +1,361 @@ +/*************************************************************************** + * Copyright (c) 2024 Microsoft Corporation + * + * This program and the accompanying materials are made available under the + * terms of the MIT License which is available at + * https://opensource.org/licenses/MIT. + * + * SPDX-License-Identifier: MIT + **************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** ThreadX Component */ +/** */ +/** Port Specific */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + +/**************************************************************************/ +/* */ +/* PORT SPECIFIC C INFORMATION RELEASE */ +/* */ +/* tx_port.h RISC-V64/GNU */ +/* 6.2.1 */ +/* */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains data type definitions that make the ThreadX */ +/* real-time kernel function identically on a variety of different */ +/* processor architectures. For example, the size or number of bits */ +/* in an "int" data type vary between microprocessor architectures and */ +/* even C compilers for the same microprocessor. ThreadX does not */ +/* directly use native C data types. Instead, ThreadX creates its */ +/* own special types that can be mapped to actual data types by this */ +/* file to guarantee consistency in the interface and functionality. */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 03-08-2023 Scott Larson Initial Version 6.2.1 */ +/* */ +/**************************************************************************/ + +#ifndef TX_PORT_H +#define TX_PORT_H + +#include +#include + +/* Determine if the optional ThreadX user define file should be used. */ + +#ifdef TX_INCLUDE_USER_DEFINE_FILE + + +/* Yes, include the user defines in tx_user.h. The defines in this file may + alternately be defined on the command line. */ + +#include "tx_user.h" +#endif + + +/* Define compiler library include files. */ + + +/* Define ThreadX basic types for this port. */ + +#define VOID void +typedef char CHAR; +typedef unsigned char UCHAR; +typedef int INT; +typedef unsigned int UINT; +typedef long LONG; +typedef unsigned long ULONG; +typedef unsigned long long ULONG64; +typedef short SHORT; +typedef unsigned short USHORT; +#define ULONG64_DEFINED + +#define ALIGN_TYPE_DEFINED +#define ALIGN_TYPE ULONG + + +typedef struct thread_stack_frame { + unsigned long epc; /* epc - epc - program counter */ + unsigned long ra; /* x1 - ra - return address for jumps */ + unsigned long t0; /* x5 - t0 - temporary register 0 */ + unsigned long t1; /* x6 - t1 - temporary register 1 */ + unsigned long t2; /* x7 - t2 - temporary register 2 */ + unsigned long s0_fp; /* x8 - s0/fp - saved register 0 or frame pointer */ + unsigned long s1; /* x9 - s1 - saved register 1 */ + unsigned long a0; /* x10 - a0 - return value or function argument 0 */ + unsigned long a1; /* x11 - a1 - return value or function argument 1 */ + unsigned long a2; /* x12 - a2 - function argument 2 */ + unsigned long a3; /* x13 - a3 - function argument 3 */ + unsigned long a4; /* x14 - a4 - function argument 4 */ + unsigned long a5; /* x15 - a5 - function argument 5 */ + unsigned long a6; /* x16 - a6 - function argument 6 */ + unsigned long a7; /* x17 - s7 - function argument 7 */ + unsigned long s2; /* x18 - s2 - saved register 2 */ + unsigned long s3; /* x19 - s3 - saved register 3 */ + unsigned long s4; /* x20 - s4 - saved register 4 */ + unsigned long s5; /* x21 - s5 - saved register 5 */ + unsigned long s6; /* x22 - s6 - saved register 6 */ + unsigned long s7; /* x23 - s7 - saved register 7 */ + unsigned long s8; /* x24 - s8 - saved register 8 */ + unsigned long s9; /* x25 - s9 - saved register 9 */ + unsigned long s10; /* x26 - s10 - saved register 10 */ + unsigned long s11; /* x27 - s11 - saved register 11 */ + unsigned long t3; /* x28 - t3 - temporary register 3 */ + unsigned long t4; /* x29 - t4 - temporary register 4 */ + unsigned long t5; /* x30 - t5 - temporary register 5 */ + unsigned long t6; /* x31 - t6 - temporary register 6 */ + unsigned long mstatus; /* - machine status register */ +} tx_stack_frame_t; + +typedef struct __attribute__((packed)) { + unsigned long fcsr; +#if __riscv_float_abi_single + unsigned long f[32]; /* f0~f31 */ +#elif __riscv_float_abi_double + unsigned long long f[32]; /* f0~f31 */ +#endif +} tx_stack_f_frame_t; + +typedef struct { + unsigned long vxsat; +} tx_stack_p_frame_t; + +/* Define the priority levels for ThreadX. Legal values range + from 32 to 1024 and MUST be evenly divisible by 32. */ + +#ifndef TX_MAX_PRIORITIES +#define TX_MAX_PRIORITIES 32 +#endif + + +/* Define the minimum stack for a ThreadX thread on this processor. If the size supplied during + thread creation is less than this value, the thread create call will return an error. */ + +#ifndef TX_MINIMUM_STACK +#define TX_MINIMUM_STACK 1024 /* Minimum stack size for this port */ +#endif + + +/* Define the system timer thread's default stack size and priority. These are only applicable + if TX_TIMER_PROCESS_IN_ISR is not defined. */ + +#ifndef TX_TIMER_THREAD_STACK_SIZE +#define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */ +#endif + +#ifndef TX_TIMER_THREAD_PRIORITY +#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */ +#endif + + +/* Define various constants for the ThreadX RISC-V port. */ + +#define TX_INT_DISABLE 0x00000000 /* Disable interrupts value */ +#define TX_INT_ENABLE 0x00000008 /* Enable interrupt value */ + + +/* Define the clock source for trace event entry time stamp. The following two item are port specific. + For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock + source constants would be: + +#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024) +#define TX_TRACE_TIME_MASK 0x0000FFFFUL + +*/ + +#ifndef TX_TRACE_TIME_SOURCE +#define TX_TRACE_TIME_SOURCE ++_tx_trace_simulated_time +#endif +#ifndef TX_TRACE_TIME_MASK +#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL +#endif + + +/* Define the port specific options for the _tx_build_options variable. This variable indicates + how the ThreadX library was built. */ + +#define TX_PORT_SPECIFIC_BUILD_OPTIONS 0 + + +/* Define the in-line initialization constant so that modules with in-line + initialization capabilities can prevent their initialization from being + a function call. */ + +#define TX_INLINE_INITIALIZATION + + +/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is + disabled. When the following is defined, ThreadX thread stack checking is enabled. If stack + checking is enabled (TX_ENABLE_STACK_CHECKING is defined), the TX_DISABLE_STACK_FILLING + define is negated, thereby forcing the stack fill which is necessary for the stack checking + logic. */ + +#ifdef TX_ENABLE_STACK_CHECKING +#undef TX_DISABLE_STACK_FILLING +#endif + + + +/* Define the TX_THREAD control block extensions for this port. The main reason + for the multiple macros is so that backward compatibility can be maintained with + existing ThreadX kernel awareness modules. */ + +#define TX_THREAD_EXTENSION_0 +#define TX_THREAD_EXTENSION_1 +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \ + VOID *tx_thread_module_entry_info_ptr; \ + ULONG tx_thread_module_current_user_mode; \ + ULONG tx_thread_module_user_mode; \ + ULONG tx_thread_module_saved_lr; \ + VOID *tx_thread_module_kernel_stack_start; \ + VOID *tx_thread_module_kernel_stack_end; \ + ULONG tx_thread_module_kernel_stack_size; \ + VOID *tx_thread_module_stack_ptr; \ + VOID *tx_thread_module_stack_start; \ + VOID *tx_thread_module_stack_end; \ + ULONG tx_thread_module_stack_size; \ + VOID *tx_thread_module_reserved; \ + VOID *tx_thread_iar_tls_pointer; +#else +#define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \ + VOID *tx_thread_module_entry_info_ptr; \ + ULONG tx_thread_module_current_user_mode; \ + ULONG tx_thread_module_user_mode; \ + ULONG tx_thread_module_saved_lr; \ + VOID *tx_thread_module_kernel_stack_start; \ + VOID *tx_thread_module_kernel_stack_end; \ + ULONG tx_thread_module_kernel_stack_size; \ + VOID *tx_thread_module_stack_ptr; \ + VOID *tx_thread_module_stack_start; \ + VOID *tx_thread_module_stack_end; \ + ULONG tx_thread_module_stack_size; \ + VOID *tx_thread_module_reserved; +#endif +#ifndef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +#define TX_THREAD_EXTENSION_3 +#else +#define TX_THREAD_EXTENSION_3 unsigned long long tx_thread_execution_time_total; \ + unsigned long long tx_thread_execution_time_last_start; +#endif + + +/* Define the port extensions of the remaining ThreadX objects. */ + +#define TX_BLOCK_POOL_EXTENSION +#define TX_BYTE_POOL_EXTENSION +#define TX_MUTEX_EXTENSION +#define TX_EVENT_FLAGS_GROUP_EXTENSION VOID *tx_event_flags_group_module_instance; \ + VOID (*tx_event_flags_group_set_module_notify)(struct TX_EVENT_FLAGS_GROUP_STRUCT *group_ptr); + +#define TX_QUEUE_EXTENSION VOID *tx_queue_module_instance; \ + VOID (*tx_queue_send_module_notify)(struct TX_QUEUE_STRUCT *queue_ptr); + +#define TX_SEMAPHORE_EXTENSION VOID *tx_semaphore_module_instance; \ + VOID (*tx_semaphore_put_module_notify)(struct TX_SEMAPHORE_STRUCT *semaphore_ptr); + +#define TX_TIMER_EXTENSION VOID *tx_timer_module_instance; \ + VOID (*tx_timer_module_expiration_function)(ULONG id); + + +/* Define the user extension field of the thread control block. Nothing + additional is needed for this port so it is defined as white space. */ + +#ifndef TX_THREAD_USER_EXTENSION +#define TX_THREAD_USER_EXTENSION +#endif + + + +/* Define the macros for processing extensions in tx_thread_create, tx_thread_delete, + tx_thread_shell_entry, and tx_thread_terminate. */ + +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) + + +/* Define the ThreadX object creation extensions for the remaining objects. */ + +#define TX_BLOCK_POOL_CREATE_EXTENSION(pool_ptr) +#define TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr) +#define TX_EVENT_FLAGS_GROUP_CREATE_EXTENSION(group_ptr) +#define TX_MUTEX_CREATE_EXTENSION(mutex_ptr) +#define TX_QUEUE_CREATE_EXTENSION(queue_ptr) +#define TX_SEMAPHORE_CREATE_EXTENSION(semaphore_ptr) +#define TX_TIMER_CREATE_EXTENSION(timer_ptr) + + +/* Define the ThreadX object deletion extensions for the remaining objects. */ + +#define TX_BLOCK_POOL_DELETE_EXTENSION(pool_ptr) +#define TX_BYTE_POOL_DELETE_EXTENSION(pool_ptr) +#define TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr) +#define TX_MUTEX_DELETE_EXTENSION(mutex_ptr) +#define TX_QUEUE_DELETE_EXTENSION(queue_ptr) +#define TX_SEMAPHORE_DELETE_EXTENSION(semaphore_ptr) +#define TX_TIMER_DELETE_EXTENSION(timer_ptr) + + +/* Define ThreadX interrupt lockout and restore macros for protection on + access of critical kernel information. The restore interrupt macro must + restore the interrupt posture of the running thread prior to the value + present prior to the disable macro. In most cases, the save area macro + is used to define a local function save area for the disable and restore + macros. */ + +#ifdef TX_DISABLE_INLINE + +#define TX_INTERRUPT_SAVE_AREA register ULONG interrupt_save; + +#define TX_DISABLE interrupt_save = _tx_thread_interrupt_control(TX_INT_DISABLE); +#define TX_RESTORE _tx_thread_interrupt_control(interrupt_save); + +#else + +#define TX_INTERRUPT_SAVE_AREA ULONG interrupt_save; +/* Atomically read mstatus into interrupt_save and clear bit 3 of mstatus. */ +#define TX_DISABLE {__asm__ volatile ("csrrci %0, mstatus, 0x08" : "=r" (interrupt_save) : : "memory");}; +/* We only care about mstatus.mie (bit 3), so mask interrupt_save and write to mstatus. */ +#define TX_RESTORE {register ULONG __tempmask = interrupt_save & 0x08; \ + __asm__ volatile ("csrrs x0, mstatus, %0 \n\t" : : "r" (__tempmask) : "memory");}; + +#endif + + +/* Define the interrupt lockout macros for each ThreadX object. */ + +#define TX_BLOCK_POOL_DISABLE TX_DISABLE +#define TX_BYTE_POOL_DISABLE TX_DISABLE +#define TX_EVENT_FLAGS_GROUP_DISABLE TX_DISABLE +#define TX_MUTEX_DISABLE TX_DISABLE +#define TX_QUEUE_DISABLE TX_DISABLE +#define TX_SEMAPHORE_DISABLE TX_DISABLE + + +/* Define the version ID of ThreadX. This may be utilized by the application. */ + +#ifdef TX_THREAD_INIT +CHAR _tx_version_id[] = + "Copyright (c) 2024 Microsoft Corporation. * ThreadX RISC-V32/GNU Version 6.4.2 *"; +#else +extern CHAR _tx_version_id[]; +#endif + +#endif diff --git a/ports/xuantie/e906/gnu/readme_threadx.txt b/ports/xuantie/e906/gnu/readme_threadx.txt new file mode 100644 index 00000000..56189b6e --- /dev/null +++ b/ports/xuantie/e906/gnu/readme_threadx.txt @@ -0,0 +1,334 @@ + Eclipse Foundation's RTOS, ThreadX for XuanTie E906 + + Using the GNU Tools + +The XuanTie E906 is a fully synthesizable, middle-end, microcontroller-class processor that is compatible to the RISC-V RV32IMA[F][D]C[P] ISA. It +delivers considerable integer and enhanced, energy-efficient floating-point compute performance especially the double precision. + +1. Building the ThreadX run-time Library + +Prerequisites +- Install a XuanTie bare-metal GNU toolchain with riscv64-unknown-elf prefix +- Download URL: https://www.xrvm.cn/community/download?versionId=4460156621967921152 +- Toolchain archive name: XuanTie-900-gcc-elf-newlib-x86_64-V3.2.0-20250627.tar.gz + +Verify the toolchain: + riscv64-unknown-elf-gcc --version + riscv64-unknown-elf-objdump --version + +Library build script + ports/xuantie/e906/gnu/example_build/smartl_fpga/build_libthreadx.sh + +Example build script + +The example demonstration contains a build script. See: + + ports/xuantie/e906/gnu/example_build/smartl_fpga/build_threadx_sample.sh + +This script builds the library and the demo application demo_threadx.elf. + + +2. Demonstration System (QEMU) + +Prerequisites +- Install a XuanTie QEMU +- Download URL: https://www.xrvm.cn/community/download?versionId=4468398114511851520 +- QEMU archive name: XuanTie-qemu-x86_64-Ubuntu-20.04-V5.2.8-B20250721-0303.tar.gz + +The provided example is targeted at XuanTie QEMU's smartl platform. After building the +example, the produced demo_threadx.elf can be executed in QEMU: + + qemu-system-riscv32 -nographic -machine smartl -cpu e906fdp -kernel demo_threadx.elf + +Typical QEMU features used: +- Single-core CPU +- UART serial console +- CLIC (Core-Local Interrupt Controller) + +3. System Initialization + +Entry Point + +The example startup code begins at the Reset_Handler label in startup.S. This startup +code performs hardware initialization including: +- Initialize gp register +- Set up the entry for interrupt and exception handler +- Set up initial stack pointer +- Jump to SystemInit() for initialize CLIC、Clear BSS、Cache、System Clock、System Tick +- Jump to pre_main() + +In pre_main(), the following initialization is performed: +Board Initialization (board_init.c) +- Initialize UART + +Then jump to main(). + +4. Register Usage and Stack Frames + +The RISC-V32 ABI defines t0-t6 and a0-a7 as caller-saved (temporary) registers. +All other registers used by a function must be preserved by the function. + +Stack Layout for Task Frame (with FP double and P-extension enabled): + + Index Offset Register Description + ───────────────────────────────────────────────── + 0 0x00 mepc machine exception PC + 1 0x04 ra return address + 2 0x08 t0 temporary register 0 + 3 0x0C t1 temporary register 1 + 4 0x10 t2 temporary register 2 + 5 0x14 s0 saved register 0 or frame pointer + 6 0x18 s1 saved register 1 + 7 0x1C a0 argument register 0 + 8 0x20 a1 argument register 1 + 9 0x24 a2 argument register 2 + 10 0x28 a3 argument register 3 + 11 0x2C a4 argument register 4 + 12 0x30 a5 argument register 5 + 13 0x34 a6 argument register 6 + 14 0x38 a7 argument register 7 + 15 0x3C s2 saved register 2 + 16 0x40 s3 saved register 3 + 17 0x44 s4 saved register 4 + 18 0x48 s5 saved register 5 + 19 0x4C s6 saved register 6 + 20 0x50 s7 saved register 7 + 21 0x54 s8 saved register 8 + 22 0x58 s9 saved register 9 + 23 0x5C s10 saved register 10 + 24 0x60 s11 saved register 11 + 25 0x64 t3 temporary register 3 + 26 0x68 t4 temporary register 4 + 27 0x6C t5 temporary register 5 + 28 0x70 t6 temporary register 6 + 29 0x74 mstatus machine status register + + 30 0x78 fcsr FP control/status register + 31 0x7C ft0 FP temporary register 0 + 32 0x84 ft1 FP temporary register 1 + 33 0x8C ft2 FP temporary register 2 + 34 0x94 ft3 FP temporary register 3 + 35 0x9C ft4 FP temporary register 4 + 36 0xA4 ft5 FP temporary register 5 + 37 0xAC ft6 FP temporary register 6 + 38 0xB4 ft7 FP temporary register 7 + 39 0xBC fs0 FP saved register 0 + 40 0xC4 fs1 FP saved register 1 + 41 0xCC fa0 FP argument register 0 + 42 0xD4 fa1 FP argument register 1 + 43 0xDC fa2 FP argument register 2 + 44 0xE4 fa3 FP argument register 3 + 45 0xEC fa4 FP argument register 4 + 46 0xF4 fa5 FP argument register 5 + 47 0xFC fa6 FP argument register 6 + 48 0x104 fa7 FP argument register 7 + 49 0x10C fs2 FP saved register 2 + 50 0x114 fs3 FP saved register 3 + 51 0x11C fs4 FP saved register 4 + 52 0x124 fs5 FP saved register 5 + 53 0x12C fs6 FP saved register 6 + 54 0x134 fs7 FP saved register 7 + 55 0x13C fs8 FP saved register 8 + 56 0x144 fs9 FP saved register 9 + 57 0x14C fs10 FP saved register 10 + 58 0x154 fs11 FP saved register 11 + 59 0x15C ft8 FP temporary register 8 + 60 0x164 ft9 FP temporary register 9 + 61 0x16C ft10 FP temporary register 10 + 62 0x174 ft11 FP temporary register 11 + + 63 0x17C vxsat fixed-point saturation flag register + ───────────────────────────────────────────────── + + +5. Interrupt Handling + +Machine Mode Operation + +ThreadX operates in machine mode (M-mode), the highest privilege level. +All interrupts and exceptions trap to machine mode. + +Interrupt Sources + +1. Machine Timer Interrupt (MTI): + - Triggered by CLINT when mtime >= mtimecmp + - Handled by _tx_timer_interrupt (src/tx_timer_interrupt.c) + - Called from tick_irq_handler() in example_build/smartl_fpga/components/chip_riscv_dummy/src/sys/tick.c + +2. External Interrupts (MEI): + - Routed through CLIC + - Handled by do_irq() in example_build/smartl_fpga/components/chip_riscv_dummy/src/sys/irq.c + +3. Software Interrupts (MSI): + - Routed through CLIC + - Handled by tspend_handler() in src/tx_thread_context.S + +Interrupt Control Macros + +TX_DISABLE and TX_RESTORE macros atomically manage the MIE bit in mstatus: + + TX_DISABLE: Saves and clears MIE bit via csrrci (CSR read-clear immediate) + TX_RESTORE: Restores only MIE bit via csrrs (CSR read-set) + Other mstatus bits remain unchanged + +These are defined in ports/xuantie/e906/gnu/inc/tx_port.h and use the +_tx_thread_interrupt_control() function. + + +6. Thread Scheduling and Context Switching + +Fist Thread Switch (src/tx_thread_schedule.S) +1. Enables interrupts while waiting a thread +2. Spins until _tx_thread_execute_ptr becomes non-NULL +3. Disables interrupts (critical section) +4. Sets _tx_thread_current_ptr = _tx_thread_execute_ptr +5. Increments thread's run count +6. Switches to thread's stack +7. Restores the thread's context, then returns via mret + +Thread Scheduler (src/tx_thread_system_return.S, src/tx_thread_context.S) +1. Set a software interrupt to trigger context switch +2. Come to software interrupt handler (tspend_handler) +3. Save previous thread's context +4. Check and waiting for _tx_thread_execute_ptr != NULL +5. Switch thread sp to _tx_thread_execute_ptr +6. Restores the thread's context, then returns via mret + +Initial Thread Stack Frame (src/tx_thread_stack_build.S) + +New threads start with a fake interrupt frame containing: +- All registers initialized to 0 +- ra (x1) = _tx_thread_exit +- mepc = entry function pointer +- mstatus = mstatus.FS=1 | mstatus.MPP=3 | mstatus.MPIE=1 +- Floating-point registers initialized based on ABI + + +7. Port Configuration and Macros + +Default Configurations (in ports/risc-v64/gnu/inc/tx_port.h): + + TX_MINIMUM_STACK 1024 /* Minimum thread stack size */ + TX_TIMER_THREAD_STACK_SIZE 1024 /* Timer thread stack size */ + TX_TIMER_THREAD_PRIORITY 0 /* Timer thread priority */ + TX_MAX_PRIORITIES 32 /* Must be multiple of 32 */ + +These can be overridden in tx_user.h or on the compiler command line. + + +8. Build Configuration + +CMake Toolchain File: example_build/smartl_fpga/xuantie_e906_gnu.cmake + +Compiler Flags: + -mcpu=e906fdp RISC-V RV32IMA[F][D]C[P] + -mcmodel=medlow ±2GB addressability + -D__ASSEMBLER__ For assembly files + + +9. File Organization + +Port-specific files (ports/risc-v64/gnu/): + +Core assembly files (src/): + - tx_port.c Initial setup and system state, Build initial stack frame for new thread + - tx_thread_context.S Thread context switch by software interrupt + - tx_thread_schedule.S Fist Thread scheduler + - tx_thread_system_return.S Trigger a software interrupt for voluntary yield + - tx_thread_interrupt_control.S Interrupt enable/disable control + - tx_timer_interrupt.S Timer interrupt handler + +Header file (inc/): + - tx_port.h Port-specific defines and macros + +Example files (example_build/smartl_fpga/): + - components/chip_riscv_dummy/src/arch/e906fdp Startup code, Interrupt handlers + - components/chip_riscv_dummy/src/drivers The basic peripheral drivers for the platform + - components/chip_riscv_dummy/src/sys System initialization + - components/chip_riscv_dummy/gcc_flash_smartl.ld Linker script for QEMU smartl + - components/csi CPU core and peripheral API + - components/libc_threadx Minimum printf and malloc implementation + - boards/board_riscv_dummy/src Bsp initialization + - pre_main.c Call main function + - tx_user.h ThreadX user defines + - build_libthreadx.sh Build script + + +10. Linker Script Requirements + +The linker script must provide: + +1. Entry point: + ENTRY(Reset_Handler) + +2. Memory layout: + - .text section (code) + - .rodata section (read-only data) + - .data section (initialized data) + - .bss section (uninitialized data) + +3. Symbols: + - __data_start__, __data_end__: For data copy from Flash when executed in DRAM + - __bss_start__, __bss_end__: For zero initialization + - __heap_start, __heap_end: For ThreadX allocation memory + +4. Alignment: + - 4-byte alignment throughout + +11. Performance and Debugging + +Performance Optimization + +Build optimizations: +- Use -O2 or -O3 for production (example uses -O0 for debugging) +- Enable -Wl,--gc-sections to remove unused code +- Define TX_DISABLE_ERROR_CHECKING to remove parameter checks +- Consider -flto for link-time optimization + +Debugging with QEMU and GDB + +Start QEMU in debug mode: + qemu-system-riscv32 -nographic -machine smartl -cpu e906fdp -kernel demo_threadx.elf -s -S + + -s: Enable GDB server on TCP port 1234 + -S: Pause at startup waiting for GDB + +Connect GDB: + riscv64-unknown-elf-gdb demo_threadx.elf + (gdb) target remote :1234 + (gdb) break main + (gdb) continue + +Useful GDB commands: + (gdb) info registers # View general registers + (gdb) info all-registers # Include CSR and FP registers + (gdb) p/x $mstatus # View machine status register + (gdb) x/32gx $sp # Examine stack memory + (gdb) p *_tx_thread_current_ptr # View current thread control block + + +12. Platform-Specific Notes (QEMU smartl) +See https://www.xrvm.com/soft-tools/tools/QEMU + +Timer frequency is platform-dependent (example uses 100MHz). + + +13. Revision History + +For generic code revision information, refer to ports/risc-v64/gnu/readme_threadx.txt. + +The following details the revision history for this xuantie/e906 GNU port: + +12-02-2026 Steven Lin Support XuanTie E906 + +01-26-2026 Akif Ejaz Comprehensive rewrite with accurate + technical details matching implementation, + register naming per RISC-V ABI, and + complete interrupt flow documentation + +03-08-2023 Scott Larson Initial Version 6.2.1 + + +Copyright (c) 1996-2026 Microsoft Corporation + +https://azure.com/rtos diff --git a/ports/xuantie/e906/gnu/src/tx_port.c b/ports/xuantie/e906/gnu/src/tx_port.c new file mode 100644 index 00000000..1fee892a --- /dev/null +++ b/ports/xuantie/e906/gnu/src/tx_port.c @@ -0,0 +1,110 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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. + */ + +#include "tx_api.h" +#include "tx_timer.h" +#include "tx_thread.h" +#include "tx_initialize.h" + +void thread_switch_ext(void) +{ +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY + _tx_execution_thread_exit(); +#endif + + if(!_tx_thread_execute_ptr) { + unsigned long mcause; + __asm__ volatile( + "csrr %0, mcause\n\t" + "csrsi mstatus, 0x8" + : "=r"(mcause) + : + : "memory" + ); + while (!_tx_thread_execute_ptr) { + __asm__ volatile("wfi"); + } + __asm__ volatile( + "csrci mstatus, 0x8\n\t" + "csrw mcause, %0" + : + : "r"(mcause) + : "memory" + ); + } + /* Determine if the time-slice is active. */ + if (_tx_timer_time_slice && _tx_thread_current_ptr) { + /* Preserve current remaining time-slice for the thread and clear the current time-slice. */ + _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice; + _tx_timer_time_slice = 0; + } + _tx_thread_current_ptr = _tx_thread_execute_ptr; +} + +VOID _tx_initialize_low_level(VOID) +{ + _tx_initialize_unused_memory = NULL; + _tx_thread_interrupt_control(0); +} + +VOID _tx_thread_exit(VOID) +{ + while (1) { + __asm__ volatile("wfi"); + } +} + +VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) +{ + int i; + uint8_t *stk; + tx_stack_frame_t *frame; + + stk = thread_ptr -> tx_thread_stack_end; + stk = (uint8_t *)(((unsigned long)stk) & (~(unsigned long)(sizeof(ALIGN_TYPE) - 1))); + stk -= sizeof(tx_stack_frame_t); + + frame = (tx_stack_frame_t *)stk; + + for (i = 0; i < sizeof(tx_stack_frame_t) / sizeof(unsigned long); i++) { + ((unsigned long*)frame)[i] = 0; + } + + frame->epc = (unsigned long)function_ptr; + frame->ra = (unsigned long)_tx_thread_exit; + frame->mstatus = (3UL << 11) | (1UL << 7); // mstatus.MPP=3, MPIE=1 + +#if __riscv_flen + frame->mstatus |= (1UL << 13); // mstatus.FS=1 + stk -= sizeof(tx_stack_f_frame_t); + tx_stack_f_frame_t *f_frame = (tx_stack_f_frame_t *)stk; + f_frame->fcsr = 0; + for (int i = 0; i < 32; i++) { + f_frame->f[i] = 0; + } +#endif + +#if __riscv_dsp + stk -= sizeof(tx_stack_p_frame_t); + tx_stack_p_frame_t *p_frame = (tx_stack_p_frame_t *)stk; + p_frame->vxsat = 0; +#endif + + thread_ptr -> tx_thread_stack_ptr = stk; +} + diff --git a/ports/xuantie/e906/gnu/src/tx_thread_context.S b/ports/xuantie/e906/gnu/src/tx_thread_context.S new file mode 100644 index 00000000..220520bb --- /dev/null +++ b/ports/xuantie/e906/gnu/src/tx_thread_context.S @@ -0,0 +1,283 @@ + /* + * Copyright (C) 2017-2024 Alibaba Group Holding Limited + * + * 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. + */ +.section .text + + .align 3 + .global tspend_handler + .type tspend_handler, @function +tspend_handler: + addi sp, sp, -(30 * 4) + sw x1, 1 * 4(sp) /* RA */ + sw x5, 2 * 4(sp) + sw x6, 3 * 4(sp) + sw x7, 4 * 4(sp) + sw x8, 5 * 4(sp) + sw x9, 6 * 4(sp) + sw x10, 7 * 4(sp) + sw x11, 8 * 4(sp) + sw x12, 9 * 4(sp) + sw x13, 10 * 4(sp) + sw x14, 11 * 4(sp) + sw x15, 12 * 4(sp) + sw x16, 13 * 4(sp) + sw x17, 14 * 4(sp) + sw x18, 15 * 4(sp) + sw x19, 16 * 4(sp) + sw x20, 17 * 4(sp) + sw x21, 18 * 4(sp) + sw x22, 19 * 4(sp) + sw x23, 20 * 4(sp) + sw x24, 21 * 4(sp) + sw x25, 22 * 4(sp) + sw x26, 23 * 4(sp) + sw x27, 24 * 4(sp) + sw x28, 25 * 4(sp) + sw x29, 26 * 4(sp) + sw x30, 27 * 4(sp) + sw x31, 28 * 4(sp) + + csrr t0, mepc + sw t0, 0(sp) + + csrr t3, mstatus + sw t3, 29 * 4(sp) + +#if __riscv_flen + addi sp, sp, -4 + frcsr t0 + sw t0, 0(sp) +#if __riscv_float_abi_single + addi sp, sp, -(32 * 4) + fsw f0, 0 * 4(sp) + fsw f1, 1 * 4(sp) + fsw f2, 2 * 4(sp) + fsw f3, 3 * 4(sp) + fsw f4, 4 * 4(sp) + fsw f5, 5 * 4(sp) + fsw f6, 6 * 4(sp) + fsw f7, 7 * 4(sp) + fsw f8, 8 * 4(sp) + fsw f9, 9 * 4(sp) + fsw f10, 10 * 4(sp) + fsw f11, 11 * 4(sp) + fsw f12, 12 * 4(sp) + fsw f13, 13 * 4(sp) + fsw f14, 14 * 4(sp) + fsw f15, 15 * 4(sp) + fsw f16, 16 * 4(sp) + fsw f17, 17 * 4(sp) + fsw f18, 18 * 4(sp) + fsw f19, 19 * 4(sp) + fsw f20, 20 * 4(sp) + fsw f21, 21 * 4(sp) + fsw f22, 22 * 4(sp) + fsw f23, 23 * 4(sp) + fsw f24, 24 * 4(sp) + fsw f25, 25 * 4(sp) + fsw f26, 26 * 4(sp) + fsw f27, 27 * 4(sp) + fsw f28, 28 * 4(sp) + fsw f29, 29 * 4(sp) + fsw f30, 30 * 4(sp) + fsw f31, 31 * 4(sp) +#elif __riscv_float_abi_double + addi sp, sp, -(32 * 8) + fsw f0, 0 * 8(sp) + fsw f1, 1 * 8(sp) + fsw f2, 2 * 8(sp) + fsw f3, 3 * 8(sp) + fsw f4, 4 * 8(sp) + fsw f5, 5 * 8(sp) + fsw f6, 6 * 8(sp) + fsw f7, 7 * 8(sp) + fsw f8, 8 * 8(sp) + fsw f9, 9 * 8(sp) + fsw f10, 10 * 8(sp) + fsw f11, 11 * 8(sp) + fsw f12, 12 * 8(sp) + fsw f13, 13 * 8(sp) + fsw f14, 14 * 8(sp) + fsw f15, 15 * 8(sp) + fsw f16, 16 * 8(sp) + fsw f17, 17 * 8(sp) + fsw f18, 18 * 8(sp) + fsw f19, 19 * 8(sp) + fsw f20, 20 * 8(sp) + fsw f21, 21 * 8(sp) + fsw f22, 22 * 8(sp) + fsw f23, 23 * 8(sp) + fsw f24, 24 * 8(sp) + fsw f25, 25 * 8(sp) + fsw f26, 26 * 8(sp) + fsw f27, 27 * 8(sp) + fsw f28, 28 * 8(sp) + fsw f29, 29 * 8(sp) + fsw f30, 30 * 8(sp) + fsw f31, 31 * 8(sp) +#endif +#endif /* __riscv_flen */ + +#if __riscv_dsp + addi sp, sp, -4 + csrr t0, vxsat + sw t0, 0(sp) +#endif /*__riscv_dsp */ + + /* If _tx_thread_current_ptr is null, no sp need to be saved */ + la t0, _tx_thread_current_ptr + lw t0, 0(t0) + beqz t0, _tx_thread_switch + /* Store sp to task stack to _tx_thread_current_ptr -> tx_thread_stack_ptr */ + sw sp, 2 * 4(t0) + +_tx_thread_switch: + jal thread_switch_ext + /*clear software interrupt*/ + /* Edge-triggered vector interrupts do not require software to clear the pending bit. */ + + /* Switch task context to _tx_thread_execute_ptr */ + la t0, _tx_thread_execute_ptr + lw t0, 0(t0) + lw sp, 2 * 4(t0) + + /* Pop additional registers */ +#if __riscv_dsp + lw t0, 0(sp) + csrw vxsat, t0 + addi sp, sp, 4 +#endif /*__riscv_dsp */ + +#if __riscv_flen +#if __riscv_float_abi_single + flw f0, 0 * 4(sp) + flw f1, 1 * 4(sp) + flw f2, 2 * 4(sp) + flw f3, 3 * 4(sp) + flw f4, 4 * 4(sp) + flw f5, 5 * 4(sp) + flw f6, 6 * 4(sp) + flw f7, 7 * 4(sp) + flw f8, 8 * 4(sp) + flw f9, 9 * 4(sp) + flw f10, 10 * 4(sp) + flw f11, 11 * 4(sp) + flw f12, 12 * 4(sp) + flw f13, 13 * 4(sp) + flw f14, 14 * 4(sp) + flw f15, 15 * 4(sp) + flw f16, 16 * 4(sp) + flw f17, 17 * 4(sp) + flw f18, 18 * 4(sp) + flw f19, 19 * 4(sp) + flw f20, 20 * 4(sp) + flw f21, 21 * 4(sp) + flw f22, 22 * 4(sp) + flw f23, 23 * 4(sp) + flw f24, 24 * 4(sp) + flw f25, 25 * 4(sp) + flw f26, 26 * 4(sp) + flw f27, 27 * 4(sp) + flw f28, 28 * 4(sp) + flw f29, 29 * 4(sp) + flw f30, 30 * 4(sp) + flw f31, 31 * 4(sp) + addi sp, sp, (32 * 4) +#elif __riscv_float_abi_double + flw f0, 0 * 8(sp) + flw f1, 1 * 8(sp) + flw f2, 2 * 8(sp) + flw f3, 3 * 8(sp) + flw f4, 4 * 8(sp) + flw f5, 5 * 8(sp) + flw f6, 6 * 8(sp) + flw f7, 7 * 8(sp) + flw f8, 8 * 8(sp) + flw f9, 9 * 8(sp) + flw f10, 10 * 8(sp) + flw f11, 11 * 8(sp) + flw f12, 12 * 8(sp) + flw f13, 13 * 8(sp) + flw f14, 14 * 8(sp) + flw f15, 15 * 8(sp) + flw f16, 16 * 8(sp) + flw f17, 17 * 8(sp) + flw f18, 18 * 8(sp) + flw f19, 19 * 8(sp) + flw f20, 20 * 8(sp) + flw f21, 21 * 8(sp) + flw f22, 22 * 8(sp) + flw f23, 23 * 8(sp) + flw f24, 24 * 8(sp) + flw f25, 25 * 8(sp) + flw f26, 26 * 8(sp) + flw f27, 27 * 8(sp) + flw f28, 28 * 8(sp) + flw f29, 29 * 8(sp) + flw f30, 30 * 8(sp) + flw f31, 31 * 8(sp) + addi sp, sp, (32 * 8) +#endif + + lw t0, 0(sp) + fscsr t0 + addi sp, sp, 4 +#endif /* __riscv_flen */ + + /* Pop PC from stack and set MEPC */ + lw t0, 0 * 4(sp) + csrw mepc, t0 + + /* Pop mstatus from stack and set it */ + lw t0, 29 * 4(sp) + csrw mstatus, t0 + + /* Interrupt still disable here */ + /* Restore Registers from Stack */ + lw x1, 1 * 4(sp) /* RA */ + lw x5, 2 * 4(sp) + lw x6, 3 * 4(sp) + lw x7, 4 * 4(sp) + lw x8, 5 * 4(sp) + lw x9, 6 * 4(sp) + lw x10, 7 * 4(sp) + lw x11, 8 * 4(sp) + lw x12, 9 * 4(sp) + lw x13, 10 * 4(sp) + lw x14, 11 * 4(sp) + lw x15, 12 * 4(sp) + lw x16, 13 * 4(sp) + lw x17, 14 * 4(sp) + lw x18, 15 * 4(sp) + lw x19, 16 * 4(sp) + lw x20, 17 * 4(sp) + lw x21, 18 * 4(sp) + lw x22, 19 * 4(sp) + lw x23, 20 * 4(sp) + lw x24, 21 * 4(sp) + lw x25, 22 * 4(sp) + lw x26, 23 * 4(sp) + lw x27, 24 * 4(sp) + lw x28, 25 * 4(sp) + lw x29, 26 * 4(sp) + lw x30, 27 * 4(sp) + lw x31, 28 * 4(sp) + addi sp, sp, (30 * 4) + + mret + + .size tspend_handler, . - tspend_handler diff --git a/ports/xuantie/e906/gnu/src/tx_thread_interrupt_control.S b/ports/xuantie/e906/gnu/src/tx_thread_interrupt_control.S new file mode 100644 index 00000000..f5b538e8 --- /dev/null +++ b/ports/xuantie/e906/gnu/src/tx_thread_interrupt_control.S @@ -0,0 +1,83 @@ +/*************************************************************************** + * Copyright (c) 2024 Microsoft Corporation + * + * This program and the accompanying materials are made available under the + * terms of the MIT License which is available at + * https://opensource.org/licenses/MIT. + * + * SPDX-License-Identifier: MIT + **************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** ThreadX Component */ +/** */ +/** Thread */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + + .section .text +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_control RISC-V64/GNU */ +/* 6.2.1 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for changing the interrupt lockout */ +/* posture of the system. */ +/* */ +/* INPUT */ +/* */ +/* new_posture New interrupt lockout posture */ +/* */ +/* OUTPUT */ +/* */ +/* old_posture Old interrupt lockout posture */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 03-08-2023 Scott Larson Initial Version 6.2.1 */ +/* */ +/**************************************************************************/ +/* UINT _tx_thread_interrupt_control(UINT new_posture) +{ */ + .global _tx_thread_interrupt_control +_tx_thread_interrupt_control: + /* Pickup current interrupt lockout posture. */ + /* old_mstatus = mstatus; */ + + csrr t0, mstatus + mv t1, t0 // Save original mstatus for return + + /* Apply the new interrupt posture while preserving unrelated mstatus bits. */ + /* Only modify the MIE bit (bit 3) */ + /* mstatus = (mstatus & ~MIE) | (new_posture & MIE); */ + + li t2, ~0x08 // Build mask to clear MIE + and t0, t0, t2 // Clear MIE bit + and a0, a0, 0x08 // Mask incoming to only MIE bit + or t0, t0, a0 // Set requested MIE state + csrw mstatus, t0 + andi a0, t1, 0x08 // Return original MIE bit + ret +/* } */ diff --git a/ports/xuantie/e906/gnu/src/tx_thread_schedule.S b/ports/xuantie/e906/gnu/src/tx_thread_schedule.S new file mode 100644 index 00000000..09d67ec2 --- /dev/null +++ b/ports/xuantie/e906/gnu/src/tx_thread_schedule.S @@ -0,0 +1,234 @@ +/*************************************************************************** + * Copyright (c) 2024 Microsoft Corporation + * + * This program and the accompanying materials are made available under the + * terms of the MIT License which is available at + * https://opensource.org/licenses/MIT. + * + * SPDX-License-Identifier: MIT + **************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** ThreadX Component */ +/** */ +/** Thread */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + .section .text +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_schedule RISC-V64/GNU */ +/* 6.2.1 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function waits for a thread control block pointer to appear in */ +/* the _tx_thread_execute_ptr variable. Once a thread pointer appears */ +/* in the variable, the corresponding thread is resumed. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* _tx_initialize_kernel_enter ThreadX entry function */ +/* _tx_thread_system_return Return to system from thread */ +/* _tx_thread_context_restore Restore thread's context */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 03-08-2023 Scott Larson Initial Version 6.2.1 */ +/* */ +/**************************************************************************/ +/* VOID _tx_thread_schedule(VOID) +{ */ + .align 3 + .global _tx_thread_schedule + .type _tx_thread_schedule, @function +_tx_thread_schedule: + /* Enable interrupts. */ + csrsi mstatus, 0x08 // Enable interrupts + + /* Wait for a thread to execute. */ + /* do + { */ + la t0, _tx_thread_execute_ptr // Pickup address of execute ptr +_tx_thread_schedule_loop: + lw t1, 0(t0) // Pickup next thread to execute + beqz t1, _tx_thread_schedule_loop // If NULL, wait for thread to execute + /* } + while(_tx_thread_execute_ptr == TX_NULL); */ + + /* Yes! We have a thread to execute. Lockout interrupts and + transfer control to it. */ + csrci mstatus, 0x08 // Lockout interrupts + + /* Setup the current thread pointer. */ + /* _tx_thread_current_ptr = _tx_thread_execute_ptr; */ + la t0, _tx_thread_current_ptr // Pickup current thread pointer address + sw t1, 0(t0) // Set current thread pointer + + /* Increment the run count for this thread. */ + /* _tx_thread_current_ptr -> tx_thread_run_count++; */ + lw t2, 1 * 4(t1) // Pickup run count + lw t3, 6 * 4(t1) // Pickup time slice value + addi t2, t2, 1 // Increment run count + sw t2, 1 * 4(t1) // Store new run count + + /* Setup time-slice, if present. */ + /* _tx_timer_time_slice = _tx_thread_current_ptr -> tx_thread_time_slice; */ + la t2, _tx_timer_time_slice // Pickup time-slice variable address + + /* Switch to the thread's stack. */ + /* SP = _tx_thread_execute_ptr -> tx_thread_stack_ptr; */ + lw sp, 2 * 4(t1) // Switch to thread's stack + sw t3, 0(t2) // Store new time-slice*/ + +#if __riscv_dsp + lw t0, 0(sp) + csrw vxsat, t0 + addi sp, sp, 4 +#endif /*__riscv_dsp */ + +#if __riscv_flen +#if __riscv_float_abi_single + flw f0, 0 * 4(sp) + flw f1, 1 * 4(sp) + flw f2, 2 * 4(sp) + flw f3, 3 * 4(sp) + flw f4, 4 * 4(sp) + flw f5, 5 * 4(sp) + flw f6, 6 * 4(sp) + flw f7, 7 * 4(sp) + flw f8, 8 * 4(sp) + flw f9, 9 * 4(sp) + flw f10, 10 * 4(sp) + flw f11, 11 * 4(sp) + flw f12, 12 * 4(sp) + flw f13, 13 * 4(sp) + flw f14, 14 * 4(sp) + flw f15, 15 * 4(sp) + flw f16, 16 * 4(sp) + flw f17, 17 * 4(sp) + flw f18, 18 * 4(sp) + flw f19, 19 * 4(sp) + flw f20, 20 * 4(sp) + flw f21, 21 * 4(sp) + flw f22, 22 * 4(sp) + flw f23, 23 * 4(sp) + flw f24, 24 * 4(sp) + flw f25, 25 * 4(sp) + flw f26, 26 * 4(sp) + flw f27, 27 * 4(sp) + flw f28, 28 * 4(sp) + flw f29, 29 * 4(sp) + flw f30, 30 * 4(sp) + flw f31, 31 * 4(sp) + addi sp, sp, (32 * 4) +#elif __riscv_float_abi_double + flw f0, 0 * 8(sp) + flw f1, 1 * 8(sp) + flw f2, 2 * 8(sp) + flw f3, 3 * 8(sp) + flw f4, 4 * 8(sp) + flw f5, 5 * 8(sp) + flw f6, 6 * 8(sp) + flw f7, 7 * 8(sp) + flw f8, 8 * 8(sp) + flw f9, 9 * 8(sp) + flw f10, 10 * 8(sp) + flw f11, 11 * 8(sp) + flw f12, 12 * 8(sp) + flw f13, 13 * 8(sp) + flw f14, 14 * 8(sp) + flw f15, 15 * 8(sp) + flw f16, 16 * 8(sp) + flw f17, 17 * 8(sp) + flw f18, 18 * 8(sp) + flw f19, 19 * 8(sp) + flw f20, 20 * 8(sp) + flw f21, 21 * 8(sp) + flw f22, 22 * 8(sp) + flw f23, 23 * 8(sp) + flw f24, 24 * 8(sp) + flw f25, 25 * 8(sp) + flw f26, 26 * 8(sp) + flw f27, 27 * 8(sp) + flw f28, 28 * 8(sp) + flw f29, 29 * 8(sp) + flw f30, 30 * 8(sp) + flw f31, 31 * 8(sp) + addi sp, sp, (32 * 8) +#endif + + lw t0, 0(sp) + fscsr t0 + addi sp, sp, 4 +#endif /* __riscv_flen */ + + /* Pop PC from stack and set MEPC */ + lw t0, 0 * 4(sp) + csrw mepc, t0 + + /* Pop mstatus from stack and set it */ + lw t0, 29 * 4(sp) + csrw mstatus, t0 + + /* Interrupt still disable here */ + /* Restore Registers from Stack */ + lw x1, 1 * 4(sp) /* RA */ + lw x5, 2 * 4(sp) + lw x6, 3 * 4(sp) + lw x7, 4 * 4(sp) + lw x8, 5 * 4(sp) + lw x9, 6 * 4(sp) + lw x10, 7 * 4(sp) + lw x11, 8 * 4(sp) + lw x12, 9 * 4(sp) + lw x13, 10 * 4(sp) + lw x14, 11 * 4(sp) + lw x15, 12 * 4(sp) + lw x16, 13 * 4(sp) + lw x17, 14 * 4(sp) + lw x18, 15 * 4(sp) + lw x19, 16 * 4(sp) + lw x20, 17 * 4(sp) + lw x21, 18 * 4(sp) + lw x22, 19 * 4(sp) + lw x23, 20 * 4(sp) + lw x24, 21 * 4(sp) + lw x25, 22 * 4(sp) + lw x26, 23 * 4(sp) + lw x27, 24 * 4(sp) + lw x28, 25 * 4(sp) + lw x29, 26 * 4(sp) + lw x30, 27 * 4(sp) + lw x31, 28 * 4(sp) + addi sp, sp, (30 * 4) + + mret + + .size _tx_thread_schedule, . - _tx_thread_schedule + +/* } */ diff --git a/ports/xuantie/e906/gnu/src/tx_thread_system_return.S b/ports/xuantie/e906/gnu/src/tx_thread_system_return.S new file mode 100644 index 00000000..598bc283 --- /dev/null +++ b/ports/xuantie/e906/gnu/src/tx_thread_system_return.S @@ -0,0 +1,78 @@ +/*************************************************************************** + * Copyright (c) 2024 Microsoft Corporation + * + * This program and the accompanying materials are made available under the + * terms of the MIT License which is available at + * https://opensource.org/licenses/MIT. + * + * SPDX-License-Identifier: MIT + **************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** ThreadX Component */ +/** */ +/** Thread */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + .section .text +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_system_return RISC-V64/GNU */ +/* 6.2.1 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is target processor specific. It is used to transfer */ +/* control from a thread back to the system. Only a minimal context */ +/* is saved since the compiler assumes temp registers are going to get */ +/* slicked by a function call anyway. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* _tx_thread_schedule Thread scheduling loop */ +/* */ +/* CALLED BY */ +/* */ +/* ThreadX components */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 03-08-2023 Scott Larson Initial Version 6.2.1 */ +/* */ +/**************************************************************************/ +/* VOID _tx_thread_system_return(VOID) +{ */ + .align 3 + .global _tx_thread_system_return + .type _tx_thread_system_return, @function +_tx_thread_system_return: + li t0, 0xE080100C + lb t1, (t0) + li t2, 0x01 + or t1, t1, t2 + sb t1, (t0) + + fence + ret + .size _tx_thread_system_return, . - _tx_thread_system_return + +/* } */ diff --git a/ports/xuantie/e906/gnu/src/tx_timer_interrupt.c b/ports/xuantie/e906/gnu/src/tx_timer_interrupt.c new file mode 100644 index 00000000..aea1119b --- /dev/null +++ b/ports/xuantie/e906/gnu/src/tx_timer_interrupt.c @@ -0,0 +1,125 @@ +/*************************************************************************** + * Copyright (c) 2024 Microsoft Corporation + * + * This program and the accompanying materials are made available under the + * terms of the MIT License which is available at + * https://opensource.org/licenses/MIT. + * + * SPDX-License-Identifier: MIT + **************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** ThreadX Component */ +/** */ +/** Timer */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +#define TX_SOURCE_CODE + +/* Include necessary system files. */ + +#include "tx_api.h" +#include "tx_timer.h" +#include "tx_thread.h" + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_timer_interrupt RISC-V64/GNU */ +/* 6.2.1 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function processes the hardware timer interrupt. This */ +/* processing includes incrementing the system clock and checking for */ +/* time slice and/or timer expiration. If either is found, the */ +/* interrupt context save/restore functions are called along with the */ +/* expiration functions. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* _tx_timer_expiration_process Timer expiration processing */ +/* _tx_thread_time_slice Time slice interrupted thread */ +/* */ +/* CALLED BY */ +/* */ +/* interrupt vector */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 03-08-2023 Scott Larson Initial Version 6.2.1 */ +/* */ +/**************************************************************************/ +VOID _tx_timer_interrupt(VOID) +{ + /* Increment system clock. */ + _tx_timer_system_clock++; + + /* Test for time-slice expiration. */ + if (_tx_timer_time_slice) + { + /* Decrement the time_slice. */ + _tx_timer_time_slice--; + /* Check for expiration. */ + if (_tx_timer_time_slice == 0) + { + /* Set the time-slice expired flag. */ + _tx_timer_expired_time_slice = TX_TRUE; + } + } + + /* Test for timer expiration. */ + if (*_tx_timer_current_ptr) + { + /* Set expiration flag. */ + _tx_timer_expired = TX_TRUE; + } + else + { + /* No timer expired, increment the timer pointer. */ + _tx_timer_current_ptr++; + /* Check for wrap-around. */ + if (_tx_timer_current_ptr == _tx_timer_list_end) + { + /* Wrap to beginning of list. */ + _tx_timer_current_ptr = _tx_timer_list_start; + } + } + + /* See if anything has expired. */ + if ((_tx_timer_expired_time_slice) || (_tx_timer_expired)) + { + /* Did a timer expire? */ + if (_tx_timer_expired) + { + /* Process timer expiration. */ + _tx_timer_expiration_process(); + } + + /* Did time slice expire? */ + if (_tx_timer_expired_time_slice) + { + /* Time slice interrupted thread. */ + _tx_thread_time_slice(); + } + } +}