Merge pull request #500 from goodnorning/feature/support_xuantie_e906

Added support for the XuanTie E906 CPU.
This commit is contained in:
Frédéric Desbiens
2026-03-04 08:34:59 +01:00
committed by GitHub
70 changed files with 24644 additions and 0 deletions

View File

@@ -0,0 +1,77 @@
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/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 $<TARGET_FILE:${PROJECT_NAME}> > ${PROJECT_NAME}.asm
COMMENT "Generating ASM disassembly files"
)

View File

@@ -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 Component, New Board should follow the macro defines.
*/
#ifndef __BOARD_H__
#define __BOARD_H__
#include <soc.h>
#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 described 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 means No uart support.
the BOARD_UART<x>_XXX, x in range 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>, 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__ */

View File

@@ -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__ */

View File

@@ -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 <stdlib.h>
#include <stdio.h>
#include <board.h>
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 <tx_api.h>
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

View File

@@ -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 <stdlib.h>
#include <stdio.h>
#include <board.h>
#if CONFIG_DEVICES_RVM_HAL
#include <devices/devicelist.h>
#else
#include <drv/uart.h>
#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

View File

@@ -0,0 +1,7 @@
#!/bin/bash
pushd ../../../../../
rm -rf build
cmake -Bbuild -GNinja -DCMAKE_TOOLCHAIN_FILE=ports/risc-v32/gnu/example_build/xuantie_smartl_fpga/xuantie_e906_gnu.cmake .
cmake --build ./build/
popd

View File

@@ -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/

View File

@@ -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
}

View File

@@ -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__ */

View File

@@ -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 <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <drv/list.h>
#include <csi_config.h>
#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_ */

View File

@@ -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 <stdio.h>
#include <soc.h>
#include <csi_core.h>
#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_ */

View File

@@ -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 <stdio.h>
#include <csi_config.h>
#include <soc.h>
#include <csi_core.h>
#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_ */

View File

@@ -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 <stdint.h>
#include <csi_core.h>
#include <sys_clk.h>
#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_ */

View File

@@ -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 <stdint.h>
#include <soc.h>
#include <drv/clk.h>
#include <drv/porting.h>
#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_ */

View File

@@ -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 <csi_config.h>
#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

View File

@@ -0,0 +1,119 @@
/*
* 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 <csi_config.h>
#include <soc.h>
#include <csi_core.h>
#include <drv/irq.h>
#include <drv/dma.h>
#include <drv/tick.h>
#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();
}

View File

@@ -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 <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <csi_core.h>
#if defined(AOS_COMP_DEBUG) && (AOS_COMP_DEBUG > 0)
#include <debug/dbg.h>
#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);
}

View File

@@ -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 <dw_uart_ll.h>
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;
}

View File

@@ -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 <stdio.h>
#include <csi_config.h>
#include <soc.h>
#include <drv/uart.h>
#include <drv/timer.h>
#include <drv/dma.h>
// #include <drv/iic.h>
// #include <drv/rtc.h>
// #include <drv/spi.h>
// #include <drv/adc.h>
#include <drv/gpio.h>
#include <drv/irq.h>
#include <drv/pin.h>
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},
};

View File

@@ -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 <csi_core.h>
// 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;
}
}

View File

@@ -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 <stdint.h>
#include <soc.h>
#include <csi_core.h>
#include <csi_config.h>
#include <drv/common.h>
extern uint32_t soc_irq_get_irq_num(void);
extern void soc_irq_end(uint32_t irq_num);
#if CONFIG_AOS_OSAL
#include <aos/kernel.h>
#include <dbg.h>
#define CSI_INTRPT_ENTER() aos_kernel_intrpt_enter()
#define CSI_INTRPT_EXIT() aos_kernel_intrpt_exit()
#else
#ifdef CONFIG_KERNEL_FREERTOS
#include <FreeRTOS.h>
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 <rtthread.h>
#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
}

View File

@@ -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 <csi_config.h>
#include <stdbool.h>
#include <csi_core.h>
#include <soc.h>
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 */
}

View File

@@ -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 <csi_config.h>
#include <soc.h>
#include <board.h>
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();
}

View File

@@ -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 <stdint.h>
#include <soc.h>
#include <sys_clk.h>
// #include <drv/io.h>
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;
}

View File

@@ -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 <stdint.h>
#include <soc.h>
#include <csi_core.h>
#include <csi_config.h>
#include <drv/common.h>
#include <drv/pin.h>
#include <drv/dma.h>
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;
}

View File

@@ -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 <soc.h>
#include <csi_core.h>
#include <csi_config.h>
#include <sys_clk.h>
#include <drv/common.h>
#include <drv/irq.h>
#include <drv/tick.h>
#include <drv/porting.h>
#include <drv/timer.h>
#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();
}
}

View File

@@ -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 <csi_config.h>
#include <soc.h>
#include <csi_core.h>
__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;
}

View File

@@ -0,0 +1 @@
Just include csi_core.h!

View File

@@ -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 <stdlib.h>
#include <stdint.h>
#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__ */

View File

@@ -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 <stdint.h>
#if defined(__csky__)
#if defined(__CK801__) || defined(__E801__)
#include <core/core_801.h>
#elif defined(__CK802__) || defined(__E802__) || defined(__E802T__) || defined(__S802__) || defined(__S802T__)
#include <core/core_802.h>
#elif defined(__CK804__) || defined(__E804D__) || defined(__E804DT__) || defined(__E804F__) || defined(__E804FT__) || defined (__E804DF__) || defined(__E804DFT__)
#include <core/core_804.h>
#elif defined(__CK803__) || defined(__E803__) || defined(__E803T__) || defined(__S803__) || defined(__S803T__)
#include <core/core_803.h>
#elif defined(__CK805__) || defined(__I805__) || defined(__I805F__)
#include <core/core_805.h>
#elif defined(__CK610__)
#include <core/core_ck610.h>
#elif defined(__CK810__) || defined(__C810__) || defined(__C810T__) || defined(__C810V__) || defined(__C810VT__)
#include <core/core_810.h>
#elif defined(__CK807__) || defined(__C807__) || defined(__C807F__) || defined(__C807FV__) || defined(__R807__)
#include <core/core_807.h>
#endif
#include <core/csi_gcc.h>
#elif defined(__riscv)
#include <core/csi_rv_encoding.h>
#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 <core/core_rv32.h>
#include <core/csi_rv32_gcc.h>
#else
#include <core/core_rv64.h>
#include <core/csi_rv64_gcc.h>
#endif /* end exx */
#endif /* __csky__ */
#ifdef __arm__
#include <csi_core_cmsis.h>
#endif
#ifdef __ARM_ARCH_ISA_A64
#include <core/csi_arm64_gcc.h>
#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_ */

View File

@@ -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 <stdint.h>
#include <drv/common.h>
#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_ */

View File

@@ -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 <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <drv/list.h>
#include <drv/dev_tag.h>
#include <csi_config.h>
#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 <drv/pm.h>
#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_ */

View File

@@ -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 <stdint.h>
#include <stdio.h>
#include <drv/common.h>
#include <drv/list.h>
#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_ */

View File

@@ -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 <stdint.h>
#include <stdbool.h>
#include <drv/common.h>
#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_ */

View File

@@ -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 <soc.h>
#include <csi_core.h>
#include <stdint.h>
#include <drv/common.h>
#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_ */

View File

@@ -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 */

View File

@@ -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 <soc.h>
#include <csi_core.h>
#include <drv/common.h>
#include <drv/gpio.h>
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_ */

View File

@@ -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 <stdint.h>
#include <stdbool.h>
#include <drv/common.h>
#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_ */

View File

@@ -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 <stdint.h>
#include <stdint.h>
#include <drv/common.h>
#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_*/

View File

@@ -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 <drv/common.h>
#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_ */

View File

@@ -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 <drv/common.h>
#include <drv/dma.h>
#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_ */

Some files were not shown because too many files have changed in this diff Show More