Add ch569w arch and board codes, support for uart

This commit is contained in:
songyanguang 2025-04-07 18:18:51 +08:00
parent 0fa8ff5368
commit 5e331e4c7c
36 changed files with 2281 additions and 3 deletions

View File

@ -5,7 +5,7 @@ MAKEFLAGS += --no-print-directory
.PHONY:COMPILE_APP COMPILE_KERNEL
riscv_support := kd233 maix-go hifive1-rev-B gapuino gd32vf103-rvstar rv32m1-vega aiit-riscv64-board xidatong-riscv64 edu-riscv64 ch32v307vct6 ch32v208rbt6
riscv_support := kd233 maix-go hifive1-rev-B gapuino gd32vf103-rvstar rv32m1-vega aiit-riscv64-board xidatong-riscv64 edu-riscv64 ch32v307vct6 ch32v208rbt6 ch569w
arm_support += stm32f407-st-discovery stm32f407zgt6 stm32f103-nano nuvoton-m2354 ok1052-c imxrt1176-sbc aiit-arm32-board xidatong-arm32 xiwangtong-arm32 edu-arm32 xishutong-arm32 rzv2l-m33 rzg2ul-m33 imx8mp
emulator_support += hifive1-emulator k210-emulator cortex-m0-emulator cortex-m3-emulator cortex-m4-emulator cortex-m7-emulator

View File

@ -45,6 +45,10 @@ ifeq ($(CONFIG_BOARD_CH32V208RBT6), y)
SRC_DIR := ch32v208rbt6
endif
ifeq ($(CONFIG_BOARD_CH569W), y)
SRC_DIR := ch569w
endif
ifeq ($(CONFIG_BOARD_RV32M1_VEGA),y)
SRC_DIR +=rv32m1-vega
endif

View File

@ -0,0 +1,4 @@
SRC_FILES := boot.S interrupt.c prepare_rhwstack.c interrupt_switch.S switch.S tick.c
SRC_DIR := RVMSIS User
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,3 @@
SRC_FILES := core_riscv.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -17,7 +17,7 @@
#endif
#include <stdint.h>
#include "CH56xSFR.H"
#include "CH56xSFR.h"
/* IO definitions */
#ifdef __cplusplus

View File

@ -0,0 +1,3 @@
SRC_FILES := ch56x_it.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,62 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : ch32v20x_it.c
* Author : WCH
* Version : V1.0.0
* Date : 2023/12/29
* Description : Main Interrupt Service Routines.
*********************************************************************************
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
#include "core_riscv.h"
#include "ch56x_it.h"
#include "board.h"
#include <xs_isr.h>
void NMI_Handler(void) __attribute__((interrupt()));
void HardFault_Handler(void) __attribute__((interrupt()));
/*********************************************************************
* @fn NMI_Handler
*
* @brief This function handles NMI exception.
*
* @return none
*/
void NMI_Handler(void)
{
GET_INT_SP();
isrManager.done->incCounter();
KPrintf("NMI_Handler.\n");
isrManager.done->decCounter();
FREE_INT_SP();
}
/*********************************************************************
* @fn HardFault_Handler
*
* @brief This function handles Hard Fault exception.
*
* @return none
*/
void HardFault_Handler(void)
{
GET_INT_SP();
isrManager.done->incCounter();
KPrintf("HardFault_Handler.\n");
KPrintf("mepc :%08x\r\n", __get_MEPC());
KPrintf("mcause:%08x\r\n", __get_MCAUSE());
KPrintf("mtval :%08x\r\n", __get_MTVAL());
extern void ShowTask(void);
extern void ShowMemory(void);
ShowTask();
ShowMemory();
while (1)
;
isrManager.done->decCounter();
FREE_INT_SP();
}

View File

@ -0,0 +1,20 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : ch32v20x_it.h
* Author : WCH
* Version : V1.0.0
* Date : 2021/06/06
* Description : This file contains the headers of the interrupt handlers.
*********************************************************************************
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
#ifndef __CH56x_IT_H
#define __CH56x_IT_H
#define GET_INT_SP() asm("csrrw sp,mscratch,sp")
#define FREE_INT_SP() asm("csrrw sp,mscratch,sp")
#endif /* __CH32V20x_IT_H */

View File

@ -0,0 +1,13 @@
#ifndef ARCH_INTERRUPT_H__
#define ARCH_INTERRUPT_H__
#include "stdio.h"
#include <xizi.h>
#define ARCH_MAX_IRQ_NUM 36
#define ARCH_IRQ_NUM_OFFSET 0
int ArchEnableHwIrq(uint32_t irq_num);
int ArchDisableHwIrq(uint32_t irq_num);
#endif

View File

@ -0,0 +1,173 @@
;/********************************** (C) COPYRIGHT *******************************
;* File Name : startup_CH56x.s
;* Author : WCH
;* Version : V1.1
;* Date : 2023/11/11
;* Description : CH56x vector table for eclipse toolchain.
;*********************************************************************************
;* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
;* Attention: This software (modified or not) and binary are used for
;* microcontroller manufactured by Nanjing Qinheng Microelectronics.
;*******************************************************************************/
.section .init,"ax",@progbits
.global _start
.align 1
_start:
j handle_reset
.section .vector,"ax",@progbits
.align 1
_vector_base:
.option norvc;
.word 0
.word 0
j NMI_Handler /* NMI Handler */
j HardFault_Handler /* Hard Fault Handler */
.word 0xf7f9bf11
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
j SysTick_Handler /* SysTick Handler */
.word 0
j SW_Handler /* SW Handler */
.word 0
/* External Interrupts */
j WDOG_IRQHandler /* WDOG */
j TMR0_IRQHandler /* TMR0 */
j GPIO_IRQHandler /* GPIO */
j SPI0_IRQHandler /* SPI0 */
j USBSS_IRQHandler /* USBSS */
j LINK_IRQHandler /* LINK */
j TMR1_IRQHandler /* TMR1 */
j TMR2_IRQHandler /* TMR2 */
j UART0_IRQHandler /* UART0 */
j USBHS_IRQHandler /* USBHS */
j EMMC_IRQHandler /* EMMC */
j DVP_IRQHandler /* DVP */
j HSPI_IRQHandler /* HSPI */
j SPI1_IRQHandler /* SPI1 */
j UART1_IRQHandler /* UART1 */
j UART2_IRQHandler /* UART2 */
j UART3_IRQHandler /* UART3 */
j SERDES_IRQHandler /* SERDES */
j ETH_IRQHandler /* ETH */
j PMT_IRQHandler /* PMT */
j ECDC_IRQHandler /* ECDC */
.option rvc;
.section .text.vector_handler, "ax", @progbits
.weak NMI_Handler
.weak HardFault_Handler
.weak SysTick_Handler
.weak SW_Handler
.weak WDOG_IRQHandler
.weak TMR0_IRQHandler
.weak GPIO_IRQHandler
.weak SPI0_IRQHandler
.weak USBSS_IRQHandler
.weak LINK_IRQHandler
.weak TMR1_IRQHandler
.weak TMR2_IRQHandler
.weak UART0_IRQHandler
.weak USBHS_IRQHandler
.weak EMMC_IRQHandler
.weak DVP_IRQHandler
.weak HSPI_IRQHandler
.weak SPI1_IRQHandler
.weak UART1_IRQHandler
.weak UART2_IRQHandler
.weak UART3_IRQHandler
.weak SERDES_IRQHandler
.weak ETH_IRQHandler
.weak PMT_IRQHandler
.weak ECDC_IRQHandler
NMI_Handler:
HardFault_Handler:
SysTick_Handler:
SW_Handler:
WDOG_IRQHandler:
TMR0_IRQHandler:
GPIO_IRQHandler:
SPI0_IRQHandler:
USBSS_IRQHandler:
LINK_IRQHandler:
TMR1_IRQHandler:
TMR2_IRQHandler:
UART0_IRQHandler:
USBHS_IRQHandler:
EMMC_IRQHandler:
DVP_IRQHandler:
HSPI_IRQHandler:
SPI1_IRQHandler:
UART1_IRQHandler:
UART2_IRQHandler:
UART3_IRQHandler:
SERDES_IRQHandler:
ETH_IRQHandler:
PMT_IRQHandler:
ECDC_IRQHandler:
1:
j 1b
.section .text.handle_reset,"ax",@progbits
.weak handle_reset
.align 1
handle_reset:
.option push
.option norelax
la gp, __global_pointer$
.option pop
1:
la sp, _eusrstack
2:
/* Load data section from flash to RAM */
la a0, _data_lma
la a1, _data_vma
la a2, _edata
bgeu a1, a2, 2f
1:
lw t0, (a0)
sw t0, (a1)
addi a0, a0, 4
addi a1, a1, 4
bltu a1, a2, 1b
2:
/* Clear bss section */
la a0, _sbss
la a1, _ebss
bgeu a0, a1, 2f
1:
sw zero, (a0)
addi a0, a0, 4
bltu a0, a1, 1b
2:
/* Clear dmadata section */
/*
la a0, _dmadata_start
la a1, _dmadata_end
bgeu a0, a1, 2f
1:
sw zero, (a0)
addi a0, a0, 4
bltu a0, a1, 1b
2:
*/
/* leave all interrupt disabled */
li t0, 0x1800
csrw mstatus, t0
/* Configure entry address mode */
la t0, _vector_base
ori t0, t0, 1
csrw mtvec, t0
la t0, entry
csrw mepc, t0
mret

View File

@ -0,0 +1,61 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-09-09 WCH the first version
*/
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#ifndef CPUPORT_H__
#define CPUPORT_H__
/* bytes of register width */
//#define ARCH_RISCV_FPU
#define ARCH_RISCV_FPU_S
#ifdef ARCH_CPU_64BIT
#define STORE sd
#define LOAD ld
#define StoreDS "sd"
#define LoadDS "ld"
#define REGBYTES 8
#define RegLength 8
#define RegLengthS "8"
#else
#define STORE sw
#define LOAD lw
#define StoreDS "sw"
#define LoadDS "lw"
#define RegLength 4
#define REGBYTES 4
#define RegLengthS "4"
#endif
/* FPU */
#ifdef ARCH_RISCV_FPU
#ifdef ARCH_RISCV_FPU_D
#define FSTORE fsd
#define FLOAD fld
#define FREGBYTES 8
#endif
#ifdef ARCH_RISCV_FPU_S
#define FSTORE fsw
#define FLOAD flw
#define FREGBYTES 4
#endif
#endif
#endif

View File

@ -0,0 +1,139 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#include <xs_assign.h>
#include <xs_base.h>
#include <xs_isr.h>
#include <xs_ktask.h>
#include "core_riscv.h"
#ifdef TASK_ISOLATION
#include <xs_service.h>
#endif
extern x_ubase interrupt_from_sp;
extern x_ubase interrupt_to_sp;
extern x_ubase interrupt_new_task;
void sw_setpend(void)
{
PFIC_SetPendingIRQ(SWI_IRQn);
}
void sw_clearpend(void)
{
PFIC_ClearPendingIRQ(SWI_IRQn);
}
x_base DisableLocalInterrupt()
{
x_base level;
asm volatile ("csrrci %0, mstatus, 8" : "=r"(level));
return level;
}
void EnableLocalInterrupt(x_base level)
{
asm volatile ("csrw mstatus, %0" :: "r"(level));
}
int ArchEnableHwIrq(uint32_t irq_num)
{
PFIC_SetPriority(irq_num, 1);
PFIC_EnableIRQ(irq_num);
}
int ArchDisableHwIrq(uint32_t irq_num)
{
PFIC_DisableIRQ(irq_num);
}
struct ExceptionStackFrame
{
uint64_t x1;
uint64_t x2;
uint64_t x3;
uint64_t x4;
uint64_t x5;
uint64_t x6;
uint64_t x7;
uint64_t x8;
uint64_t x9;
uint64_t x10;
uint64_t x11;
uint64_t x12;
uint64_t x13;
uint64_t x14;
uint64_t x15;
uint64_t x16;
uint64_t x17;
uint64_t x18;
uint64_t x19;
uint64_t x20;
uint64_t x21;
uint64_t x22;
uint64_t x23;
uint64_t x24;
uint64_t x25;
uint64_t x26;
uint64_t x27;
uint64_t x28;
uint64_t x29;
uint64_t x30;
uint64_t x31;
};
void PrintStackFrame(uintptr_t * sp)
{
struct ExceptionStackFrame * esf = (struct ExceptionStackFrame *)(sp+1);
KPrintf("\n=================================================================\n");
KPrintf("x1 (ra : Return address ) ==> 0x%08x%08x\n", esf->x1 >> 32 , esf->x1 & UINT32_MAX);
KPrintf("x2 (sp : Stack pointer ) ==> 0x%08x%08x\n", esf->x2 >> 32 , esf->x2 & UINT32_MAX);
KPrintf("x3 (gp : Global pointer ) ==> 0x%08x%08x\n", esf->x3 >> 32 , esf->x3 & UINT32_MAX);
KPrintf("x4 (tp : Task pointer ) ==> 0x%08x%08x\n", esf->x4 >> 32 , esf->x4 & UINT32_MAX);
KPrintf("x5 (t0 : Temporary ) ==> 0x%08x%08x\n", esf->x5 >> 32 , esf->x5 & UINT32_MAX);
KPrintf("x6 (t1 : Temporary ) ==> 0x%08x%08x\n", esf->x6 >> 32 , esf->x6 & UINT32_MAX);
KPrintf("x7 (t2 : Temporary ) ==> 0x%08x%08x\n", esf->x7 >> 32 , esf->x7 & UINT32_MAX);
KPrintf("x8 (s0/fp: Save register,frame pointer ) ==> 0x%08x%08x\n", esf->x8 >> 32 , esf->x8 & UINT32_MAX);
KPrintf("x9 (s1 : Save register ) ==> 0x%08x%08x\n", esf->x9 >> 32 , esf->x9 & UINT32_MAX);
KPrintf("x10(a0 : Function argument,return value) ==> 0x%08x%08x\n", esf->x10 >> 32 , esf->x10 & UINT32_MAX);
KPrintf("x11(a1 : Function argument,return value) ==> 0x%08x%08x\n", esf->x11 >> 32 , esf->x11 & UINT32_MAX);
KPrintf("x12(a2 : Function argument ) ==> 0x%08x%08x\n", esf->x12 >> 32 , esf->x12 & UINT32_MAX);
KPrintf("x13(a3 : Function argument ) ==> 0x%08x%08x\n", esf->x13 >> 32 , esf->x13 & UINT32_MAX);
KPrintf("x14(a4 : Function argument ) ==> 0x%08x%08x\n", esf->x14 >> 32 , esf->x14 & UINT32_MAX);
KPrintf("x15(a5 : Function argument ) ==> 0x%08x%08x\n", esf->x15 >> 32 , esf->x15 & UINT32_MAX);
KPrintf("x16(a6 : Function argument ) ==> 0x%08x%08x\n", esf->x16 >> 32 , esf->x16 & UINT32_MAX);
KPrintf("x17(a7 : Function argument ) ==> 0x%08x%08x\n", esf->x17 >> 32 , esf->x17 & UINT32_MAX);
KPrintf("x18(s2 : Save register ) ==> 0x%08x%08x\n", esf->x18 >> 32 , esf->x18 & UINT32_MAX);
KPrintf("x19(s3 : Save register ) ==> 0x%08x%08x\n", esf->x19 >> 32 , esf->x19 & UINT32_MAX);
KPrintf("x20(s4 : Save register ) ==> 0x%08x%08x\n", esf->x20 >> 32 , esf->x20 & UINT32_MAX);
KPrintf("x21(s5 : Save register ) ==> 0x%08x%08x\n", esf->x21 >> 32 , esf->x21 & UINT32_MAX);
KPrintf("x22(s6 : Save register ) ==> 0x%08x%08x\n", esf->x22 >> 32 , esf->x22 & UINT32_MAX);
KPrintf("x23(s7 : Save register ) ==> 0x%08x%08x\n", esf->x23 >> 32 , esf->x23 & UINT32_MAX);
KPrintf("x24(s8 : Save register ) ==> 0x%08x%08x\n", esf->x24 >> 32 , esf->x24 & UINT32_MAX);
KPrintf("x25(s9 : Save register ) ==> 0x%08x%08x\n", esf->x25 >> 32 , esf->x25 & UINT32_MAX);
KPrintf("x26(s10 : Save register ) ==> 0x%08x%08x\n", esf->x26 >> 32 , esf->x26 & UINT32_MAX);
KPrintf("x27(s11 : Save register ) ==> 0x%08x%08x\n", esf->x27 >> 32 , esf->x27 & UINT32_MAX);
KPrintf("x28(t3 : Temporary ) ==> 0x%08x%08x\n", esf->x28 >> 32 , esf->x28 & UINT32_MAX);
KPrintf("x29(t4 : Temporary ) ==> 0x%08x%08x\n", esf->x29 >> 32 , esf->x29 & UINT32_MAX);
KPrintf("x30(t5 : Temporary ) ==> 0x%08x%08x\n", esf->x30 >> 32 , esf->x30 & UINT32_MAX);
KPrintf("x31(t6 : Temporary ) ==> 0x%08x%08x\n", esf->x31 >> 32 , esf->x31 & UINT32_MAX);
KPrintf("=================================================================\n");
}
void HwInterruptcontextSwitch(x_ubase from_sp, x_ubase to_sp, struct TaskDescriptor* new_task, void* context) {
interrupt_from_sp = (x_ubase)from_sp;
interrupt_to_sp = (x_ubase)to_sp;
interrupt_new_task = (x_ubase)new_task;
sw_setpend();
}

View File

@ -0,0 +1,208 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023/01/17 WangShun The first version
* 2023/03/19 Flyingcys Add riscv_32e support
* 2023/08/09 HPMicro Fix the issue t0 was modified unexpectedly before being saved
*/
#define __ASSEMBLY__
#include "cpuport.h"
.section .text.entry, "ax"
#if defined(SOC_SERIES_GD32VF103V)
.align 6
#else
.align 2
#endif
.global SW_Handler
SW_Handler:
csrci mstatus, 0x8
#ifdef ARCH_RISCV_FPU
addi sp, sp, -32 * FREGBYTES
FSTORE f0, 0 * FREGBYTES(sp)
FSTORE f1, 1 * FREGBYTES(sp)
FSTORE f2, 2 * FREGBYTES(sp)
FSTORE f3, 3 * FREGBYTES(sp)
FSTORE f4, 4 * FREGBYTES(sp)
FSTORE f5, 5 * FREGBYTES(sp)
FSTORE f6, 6 * FREGBYTES(sp)
FSTORE f7, 7 * FREGBYTES(sp)
FSTORE f8, 8 * FREGBYTES(sp)
FSTORE f9, 9 * FREGBYTES(sp)
FSTORE f10, 10 * FREGBYTES(sp)
FSTORE f11, 11 * FREGBYTES(sp)
FSTORE f12, 12 * FREGBYTES(sp)
FSTORE f13, 13 * FREGBYTES(sp)
FSTORE f14, 14 * FREGBYTES(sp)
FSTORE f15, 15 * FREGBYTES(sp)
FSTORE f16, 16 * FREGBYTES(sp)
FSTORE f17, 17 * FREGBYTES(sp)
FSTORE f18, 18 * FREGBYTES(sp)
FSTORE f19, 19 * FREGBYTES(sp)
FSTORE f20, 20 * FREGBYTES(sp)
FSTORE f21, 21 * FREGBYTES(sp)
FSTORE f22, 22 * FREGBYTES(sp)
FSTORE f23, 23 * FREGBYTES(sp)
FSTORE f24, 24 * FREGBYTES(sp)
FSTORE f25, 25 * FREGBYTES(sp)
FSTORE f26, 26 * FREGBYTES(sp)
FSTORE f27, 27 * FREGBYTES(sp)
FSTORE f28, 28 * FREGBYTES(sp)
FSTORE f29, 29 * FREGBYTES(sp)
FSTORE f30, 30 * FREGBYTES(sp)
FSTORE f31, 31 * FREGBYTES(sp)
#endif
/* save all from thread context */
#ifndef __riscv_32e
addi sp, sp, -32 * REGBYTES
#else
addi sp, sp, -16 * REGBYTES
#endif
STORE x5, 5 * REGBYTES(sp)
STORE x1, 1 * REGBYTES(sp)
/* Mandatory set the MPIE of mstatus */
li t0, 0x80
STORE t0, 2 * REGBYTES(sp)
STORE x4, 4 * REGBYTES(sp)
STORE x6, 6 * REGBYTES(sp)
STORE x7, 7 * REGBYTES(sp)
STORE x8, 8 * REGBYTES(sp)
STORE x9, 9 * REGBYTES(sp)
STORE x10, 10 * REGBYTES(sp)
STORE x11, 11 * REGBYTES(sp)
STORE x12, 12 * REGBYTES(sp)
STORE x13, 13 * REGBYTES(sp)
STORE x14, 14 * REGBYTES(sp)
STORE x15, 15 * REGBYTES(sp)
#ifndef __riscv_32e
STORE x16, 16 * REGBYTES(sp)
STORE x17, 17 * REGBYTES(sp)
STORE x18, 18 * REGBYTES(sp)
STORE x19, 19 * REGBYTES(sp)
STORE x20, 20 * REGBYTES(sp)
STORE x21, 21 * REGBYTES(sp)
STORE x22, 22 * REGBYTES(sp)
STORE x23, 23 * REGBYTES(sp)
STORE x24, 24 * REGBYTES(sp)
STORE x25, 25 * REGBYTES(sp)
STORE x26, 26 * REGBYTES(sp)
STORE x27, 27 * REGBYTES(sp)
STORE x28, 28 * REGBYTES(sp)
STORE x29, 29 * REGBYTES(sp)
STORE x30, 30 * REGBYTES(sp)
STORE x31, 31 * REGBYTES(sp)
#endif
csrr a0, mepc
STORE a0, 0 * REGBYTES(sp)
/* switch to interrupt stack */
csrrw sp,mscratch,sp
/* clear interrupt */
jal sw_clearpend
/* switch to from thread stack */
csrrw sp,mscratch,sp
csrr a0, mepc
STORE a0, 0 * REGBYTES(sp)
la t0, interrupt_from_sp
LOAD t1, 0(t0)
STORE sp, 0(t1)
la t0, interrupt_to_sp
LOAD t1, 0(t0)
LOAD sp, 0(t1)
LOAD a0, 0 * REGBYTES(sp)
csrw mepc, a0
1:
LOAD x1, 1 * REGBYTES(sp)
/* Set the mode after MRET */
li t0, 0x1800
csrs mstatus, t0
LOAD t0, 2 * REGBYTES(sp)
csrs mstatus, t0
LOAD x4, 4 * REGBYTES(sp)
LOAD x5, 5 * REGBYTES(sp)
LOAD x6, 6 * REGBYTES(sp)
LOAD x7, 7 * REGBYTES(sp)
LOAD x8, 8 * REGBYTES(sp)
LOAD x9, 9 * REGBYTES(sp)
LOAD x10, 10 * REGBYTES(sp)
LOAD x11, 11 * REGBYTES(sp)
LOAD x12, 12 * REGBYTES(sp)
LOAD x13, 13 * REGBYTES(sp)
LOAD x14, 14 * REGBYTES(sp)
LOAD x15, 15 * REGBYTES(sp)
#ifndef __riscv_32e
LOAD x16, 16 * REGBYTES(sp)
LOAD x17, 17 * REGBYTES(sp)
LOAD x18, 18 * REGBYTES(sp)
LOAD x19, 19 * REGBYTES(sp)
LOAD x20, 20 * REGBYTES(sp)
LOAD x21, 21 * REGBYTES(sp)
LOAD x22, 22 * REGBYTES(sp)
LOAD x23, 23 * REGBYTES(sp)
LOAD x24, 24 * REGBYTES(sp)
LOAD x25, 25 * REGBYTES(sp)
LOAD x26, 26 * REGBYTES(sp)
LOAD x27, 27 * REGBYTES(sp)
LOAD x28, 28 * REGBYTES(sp)
LOAD x29, 29 * REGBYTES(sp)
LOAD x30, 30 * REGBYTES(sp)
LOAD x31, 31 * REGBYTES(sp)
addi sp, sp, 32 * REGBYTES
#else
addi sp, sp, 16 * REGBYTES
#endif
#ifdef ARCH_RISCV_FPU
FLOAD f0, 0 * FREGBYTES(sp)
FLOAD f1, 1 * FREGBYTES(sp)
FLOAD f2, 2 * FREGBYTES(sp)
FLOAD f3, 3 * FREGBYTES(sp)
FLOAD f4, 4 * FREGBYTES(sp)
FLOAD f5, 5 * FREGBYTES(sp)
FLOAD f6, 6 * FREGBYTES(sp)
FLOAD f7, 7 * FREGBYTES(sp)
FLOAD f8, 8 * FREGBYTES(sp)
FLOAD f9, 9 * FREGBYTES(sp)
FLOAD f10, 10 * FREGBYTES(sp)
FLOAD f11, 11 * FREGBYTES(sp)
FLOAD f12, 12 * FREGBYTES(sp)
FLOAD f13, 13 * FREGBYTES(sp)
FLOAD f14, 14 * FREGBYTES(sp)
FLOAD f15, 15 * FREGBYTES(sp)
FLOAD f16, 16 * FREGBYTES(sp)
FLOAD f17, 17 * FREGBYTES(sp)
FLOAD f18, 18 * FREGBYTES(sp)
FLOAD f19, 19 * FREGBYTES(sp)
FLOAD f20, 20 * FREGBYTES(sp)
FLOAD f21, 21 * FREGBYTES(sp)
FLOAD f22, 22 * FREGBYTES(sp)
FLOAD f23, 23 * FREGBYTES(sp)
FLOAD f24, 24 * FREGBYTES(sp)
FLOAD f25, 25 * FREGBYTES(sp)
FLOAD f26, 26 * FREGBYTES(sp)
FLOAD f27, 27 * FREGBYTES(sp)
FLOAD f28, 28 * FREGBYTES(sp)
FLOAD f29, 29 * FREGBYTES(sp)
FLOAD f30, 30 * FREGBYTES(sp)
FLOAD f31, 31 * FREGBYTES(sp)
addi sp, sp, 32 * FREGBYTES
#endif
mret

View File

@ -0,0 +1,156 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#include "cpuport.h"
#include <board.h>
#include <xs_base.h>
#include <xs_ktask.h>
#include <xs_isr.h>
#ifdef TASK_ISOLATION
#include "encoding.h"
#include <stdint.h>
#include <xs_isolation.h>
#endif
volatile x_ubase interrupt_from_sp = 0;
volatile x_ubase interrupt_to_sp = 0;
volatile x_ubase interrupt_new_task = 0;
struct StackRegisterContext
{
x_ubase epc;
x_ubase ra;
x_ubase mstatus;
x_ubase gp;
x_ubase tp;
x_ubase t0;
x_ubase t1;
x_ubase t2;
x_ubase s0_fp;
x_ubase s1;
x_ubase a0;
x_ubase a1;
x_ubase a2;
x_ubase a3;
x_ubase a4;
x_ubase a5;
x_ubase a6;
x_ubase a7;
x_ubase s2;
x_ubase s3;
x_ubase s4;
x_ubase s5;
x_ubase s6;
x_ubase s7;
x_ubase s8;
x_ubase s9;
x_ubase s10;
x_ubase s11;
x_ubase t3;
x_ubase t4;
x_ubase t5;
x_ubase t6;
/* float register */
#ifdef ARCH_RISCV_FPU
x_ubase f0; /* f0 */
x_ubase f1; /* f1 */
x_ubase f2; /* f2 */
x_ubase f3; /* f3 */
x_ubase f4; /* f4 */
x_ubase f5; /* f5 */
x_ubase f6; /* f6 */
x_ubase f7; /* f7 */
x_ubase f8; /* f8 */
x_ubase f9; /* f9 */
x_ubase f10; /* f10 */
x_ubase f11; /* f11 */
x_ubase f12; /* f12 */
x_ubase f13; /* f13 */
x_ubase f14; /* f14 */
x_ubase f15; /* f15 */
x_ubase f16; /* f16 */
x_ubase f17; /* f17 */
x_ubase f18; /* f18 */
x_ubase f19; /* f19 */
x_ubase f20; /* f20 */
x_ubase f21; /* f21 */
x_ubase f22; /* f22 */
x_ubase f23; /* f23 */
x_ubase f24; /* f24 */
x_ubase f25; /* f25 */
x_ubase f26; /* f26 */
x_ubase f27; /* f27 */
x_ubase f28; /* f28 */
x_ubase f29; /* f29 */
x_ubase f30; /* f30 */
x_ubase f31; /* f31 */
#endif
};
uint8 KTaskStackSetup(struct TaskDescriptor *task)
{
struct StackRegisterContext *stack_contex;
int i;
task->stack_point = (uint8 *)ALIGN_MEN_DOWN((x_ubase)(task->task_base_info.stack_start + task->task_base_info.stack_depth), RegLength);
task->stack_point -= sizeof(struct StackRegisterContext);
stack_contex = (struct StackRegisterContext *)task->stack_point;
for (i = 0; i < sizeof(struct StackRegisterContext) / sizeof(x_ubase); i++)
((x_ubase *)stack_contex)[i] = 0xfadeface;
#ifdef SEPARATE_COMPILE
if (task->task_dync_sched_member.isolation_flag == 1) {
stack_contex->ra = (unsigned long)USERSPACE->us_taskquit;
} else {
stack_contex->ra = (x_ubase)KTaskQuit;
}
#else
stack_contex->ra = (x_ubase)KTaskQuit;
#endif
stack_contex->a0 = (x_ubase)task->task_base_info.func_param;
stack_contex->epc = (x_ubase)task->task_base_info.func_entry;
#ifdef TASK_ISOLATION
stack_contex->tp = (x_ubase)task;
if(task->task_dync_sched_member.isolation_flag == 1)
stack_contex->mstatus = 0x00006080;
else
#endif
/* force to machine mode(MPP=11) and set MPIE to 1 */
#ifdef ARCH_RISCV_FPU
stack_contex->mstatus = 0x7880;
#else
stack_contex->mstatus = 0x1880;
#endif
return EOK;
}
#ifdef TASK_ISOLATION
void RestoreMstatus(uintptr_t *sp)
{
struct TaskDescriptor *tid;
tid = (struct TaskDescriptor *)(sp[4]);
if(tid->task_dync_sched_member.isolation_flag == 1 && tid->task_dync_sched_member.isolation_status == 0){
CLEAR_CSR(mstatus, (MSTATUS_MPP));
#ifdef MOMERY_PROTECT_ENABLE
mem_access.Load(tid->task_dync_sched_member.isolation);
#endif
}else{
SET_CSR(mstatus, MSTATUS_MPP);
}
}
#endif

View File

@ -0,0 +1,310 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018/10/28 Bernard The unify RISC-V porting implementation
* 2018/12/27 Jesven Add SMP support
* 2020/11/20 BalanceTWK Add FPU support
* 2022/12/28 WangShun Add macro to distinguish whether FPU is supported
* 2023/03/19 Flyingcys Add riscv_32e support
*/
#define __ASSEMBLY__
#include "cpuport.h"
#ifdef RT_USING_SMP
#define rt_hw_interrupt_disable rt_hw_local_irq_disable
#define rt_hw_interrupt_enable rt_hw_local_irq_enable
#endif
/*
* rt_base_t rt_hw_interrupt_disable(void);
*/
.globl hw_interrupt_disable
hw_interrupt_disable:
csrrci a0, mstatus, 8
ret
/*
* void rt_hw_interrupt_enable(rt_base_t level);
*/
.globl hw_interrupt_enable
hw_interrupt_enable:
csrw mstatus, a0
ret
/*
* #ifdef RT_USING_SMP
* void rt_hw_context_switch_to(rt_ubase_t to, stuct rt_thread *to_thread);
* #else
* void rt_hw_context_switch_to(rt_ubase_t to);
* #endif
* a0 --> to
* a1 --> to_thread
*/
.global SwitchKtaskContextTo
SwitchKtaskContextTo:
la t0, _eusrstack
//#ifdef SOC_RISCV_FAMILY_CH32
addi t0, t0, -512 // for ch32
//#endif /* SOC_RISCV_FAMILY_CH32 */
csrw mscratch,t0
LOAD sp, (a0)
//#ifdef RT_USING_SMP
mv a0, a1
call RestoreCpusLockStatus
//#endif
LOAD a0, 2 * REGBYTES(sp)
csrw mstatus, a0
j SwitchKTaskContextExit
/*
* #ifdef RT_USING_SMP
* void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to, struct rt_thread *to_thread);
* #else
* void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to);
* #endif
*
* a0 --> from
* a1 --> to
* a2 --> to_thread
*/
.globl SwitchKtaskContext
SwitchKtaskContext:
/* saved from thread context
* x1/ra -> sp(0)
* x1/ra -> sp(1)
* mstatus.mie -> sp(2)
* x(i) -> sp(i-4)
*/
#ifdef ARCH_RISCV_FPU
addi sp, sp, -32 * FREGBYTES
FSTORE f0, 0 * FREGBYTES(sp)
FSTORE f1, 1 * FREGBYTES(sp)
FSTORE f2, 2 * FREGBYTES(sp)
FSTORE f3, 3 * FREGBYTES(sp)
FSTORE f4, 4 * FREGBYTES(sp)
FSTORE f5, 5 * FREGBYTES(sp)
FSTORE f6, 6 * FREGBYTES(sp)
FSTORE f7, 7 * FREGBYTES(sp)
FSTORE f8, 8 * FREGBYTES(sp)
FSTORE f9, 9 * FREGBYTES(sp)
FSTORE f10, 10 * FREGBYTES(sp)
FSTORE f11, 11 * FREGBYTES(sp)
FSTORE f12, 12 * FREGBYTES(sp)
FSTORE f13, 13 * FREGBYTES(sp)
FSTORE f14, 14 * FREGBYTES(sp)
FSTORE f15, 15 * FREGBYTES(sp)
FSTORE f16, 16 * FREGBYTES(sp)
FSTORE f17, 17 * FREGBYTES(sp)
FSTORE f18, 18 * FREGBYTES(sp)
FSTORE f19, 19 * FREGBYTES(sp)
FSTORE f20, 20 * FREGBYTES(sp)
FSTORE f21, 21 * FREGBYTES(sp)
FSTORE f22, 22 * FREGBYTES(sp)
FSTORE f23, 23 * FREGBYTES(sp)
FSTORE f24, 24 * FREGBYTES(sp)
FSTORE f25, 25 * FREGBYTES(sp)
FSTORE f26, 26 * FREGBYTES(sp)
FSTORE f27, 27 * FREGBYTES(sp)
FSTORE f28, 28 * FREGBYTES(sp)
FSTORE f29, 29 * FREGBYTES(sp)
FSTORE f30, 30 * FREGBYTES(sp)
FSTORE f31, 31 * FREGBYTES(sp)
#endif
#ifndef __riscv_32e
addi sp, sp, -32 * REGBYTES
#else
addi sp, sp, -16 * REGBYTES
#endif
STORE sp, (a0)
STORE x1, 0 * REGBYTES(sp)
STORE x1, 1 * REGBYTES(sp)
csrr a0, mstatus
andi a0, a0, 8
beqz a0, save_mpie
li a0, 0x80
save_mpie:
STORE a0, 2 * REGBYTES(sp)
STORE x4, 4 * REGBYTES(sp)
STORE x5, 5 * REGBYTES(sp)
STORE x6, 6 * REGBYTES(sp)
STORE x7, 7 * REGBYTES(sp)
STORE x8, 8 * REGBYTES(sp)
STORE x9, 9 * REGBYTES(sp)
STORE x10, 10 * REGBYTES(sp)
STORE x11, 11 * REGBYTES(sp)
STORE x12, 12 * REGBYTES(sp)
STORE x13, 13 * REGBYTES(sp)
STORE x14, 14 * REGBYTES(sp)
STORE x15, 15 * REGBYTES(sp)
#ifndef __riscv_32e
STORE x16, 16 * REGBYTES(sp)
STORE x17, 17 * REGBYTES(sp)
STORE x18, 18 * REGBYTES(sp)
STORE x19, 19 * REGBYTES(sp)
STORE x20, 20 * REGBYTES(sp)
STORE x21, 21 * REGBYTES(sp)
STORE x22, 22 * REGBYTES(sp)
STORE x23, 23 * REGBYTES(sp)
STORE x24, 24 * REGBYTES(sp)
STORE x25, 25 * REGBYTES(sp)
STORE x26, 26 * REGBYTES(sp)
STORE x27, 27 * REGBYTES(sp)
STORE x28, 28 * REGBYTES(sp)
STORE x29, 29 * REGBYTES(sp)
STORE x30, 30 * REGBYTES(sp)
STORE x31, 31 * REGBYTES(sp)
#endif
/* restore to thread context
* sp(0) -> epc;
* sp(1) -> ra;
* sp(i) -> x(i+2)
*/
LOAD sp, (a1)
#ifdef RT_USING_SMP
mv a0, a2
call rt_cpus_lock_status_restore
#endif /*RT_USING_SMP*/
j SwitchKTaskContextExit
#ifdef RT_USING_SMP
/*
* void rt_hw_context_switch_interrupt(void *context, rt_ubase_t from, rt_ubase_t to, struct rt_thread *to_thread);
*
* a0 --> context
* a1 --> from
* a2 --> to
* a3 --> to_thread
*/
.globl rt_hw_context_switch_interrupt
rt_hw_context_switch_interrupt:
STORE a0, 0(a1)
LOAD sp, 0(a2)
move a0, a3
call rt_cpus_lock_status_restore
j rt_hw_context_switch_exit
#endif
.global SwitchKTaskContextExit
SwitchKTaskContextExit:
#ifdef RT_USING_SMP
#ifdef RT_USING_SIGNALS
mv a0, sp
csrr t0, mhartid
/* switch interrupt stack of current cpu */
la sp, __stack_start__
addi t1, t0, 1
li t2, __STACKSIZE__
mul t1, t1, t2
add sp, sp, t1 /* sp = (cpuid + 1) * __STACKSIZE__ + __stack_start__ */
call rt_signal_check
mv sp, a0
#endif
#endif
/* resw ra to mepc */
LOAD a0, 0 * REGBYTES(sp)
csrw mepc, a0
LOAD x1, 1 * REGBYTES(sp)
#ifdef ARCH_RISCV_FPU
li t0, 0x7800
#else
li t0, 0x1800
#endif
csrw mstatus, t0
LOAD a0, 2 * REGBYTES(sp)
csrs mstatus, a0
LOAD x4, 4 * REGBYTES(sp)
LOAD x5, 5 * REGBYTES(sp)
LOAD x6, 6 * REGBYTES(sp)
LOAD x7, 7 * REGBYTES(sp)
LOAD x8, 8 * REGBYTES(sp)
LOAD x9, 9 * REGBYTES(sp)
LOAD x10, 10 * REGBYTES(sp)
LOAD x11, 11 * REGBYTES(sp)
LOAD x12, 12 * REGBYTES(sp)
LOAD x13, 13 * REGBYTES(sp)
LOAD x14, 14 * REGBYTES(sp)
LOAD x15, 15 * REGBYTES(sp)
#ifndef __riscv_32e
LOAD x16, 16 * REGBYTES(sp)
LOAD x17, 17 * REGBYTES(sp)
LOAD x18, 18 * REGBYTES(sp)
LOAD x19, 19 * REGBYTES(sp)
LOAD x20, 20 * REGBYTES(sp)
LOAD x21, 21 * REGBYTES(sp)
LOAD x22, 22 * REGBYTES(sp)
LOAD x23, 23 * REGBYTES(sp)
LOAD x24, 24 * REGBYTES(sp)
LOAD x25, 25 * REGBYTES(sp)
LOAD x26, 26 * REGBYTES(sp)
LOAD x27, 27 * REGBYTES(sp)
LOAD x28, 28 * REGBYTES(sp)
LOAD x29, 29 * REGBYTES(sp)
LOAD x30, 30 * REGBYTES(sp)
LOAD x31, 31 * REGBYTES(sp)
addi sp, sp, 32 * REGBYTES
#else
addi sp, sp, 16 * REGBYTES
#endif
#ifdef ARCH_RISCV_FPU
FLOAD f0, 0 * FREGBYTES(sp)
FLOAD f1, 1 * FREGBYTES(sp)
FLOAD f2, 2 * FREGBYTES(sp)
FLOAD f3, 3 * FREGBYTES(sp)
FLOAD f4, 4 * FREGBYTES(sp)
FLOAD f5, 5 * FREGBYTES(sp)
FLOAD f6, 6 * FREGBYTES(sp)
FLOAD f7, 7 * FREGBYTES(sp)
FLOAD f8, 8 * FREGBYTES(sp)
FLOAD f9, 9 * FREGBYTES(sp)
FLOAD f10, 10 * FREGBYTES(sp)
FLOAD f11, 11 * FREGBYTES(sp)
FLOAD f12, 12 * FREGBYTES(sp)
FLOAD f13, 13 * FREGBYTES(sp)
FLOAD f14, 14 * FREGBYTES(sp)
FLOAD f15, 15 * FREGBYTES(sp)
FLOAD f16, 16 * FREGBYTES(sp)
FLOAD f17, 17 * FREGBYTES(sp)
FLOAD f18, 18 * FREGBYTES(sp)
FLOAD f19, 19 * FREGBYTES(sp)
FLOAD f20, 20 * FREGBYTES(sp)
FLOAD f21, 21 * FREGBYTES(sp)
FLOAD f22, 22 * FREGBYTES(sp)
FLOAD f23, 23 * FREGBYTES(sp)
FLOAD f24, 24 * FREGBYTES(sp)
FLOAD f25, 25 * FREGBYTES(sp)
FLOAD f26, 26 * FREGBYTES(sp)
FLOAD f27, 27 * FREGBYTES(sp)
FLOAD f28, 28 * FREGBYTES(sp)
FLOAD f29, 29 * FREGBYTES(sp)
FLOAD f30, 30 * FREGBYTES(sp)
FLOAD f31, 31 * FREGBYTES(sp)
addi sp, sp, 32 * FREGBYTES
#endif
mret

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#include <xs_ktick.h>
#include <xs_isr.h>
#include <xs_assign.h>
#include "core_riscv.h"
#include "CH56x_common.h"
#include "ch56x_it.h"
extern void KTaskOsAssignAfterIrq(void *);
void SysTick_Handler(void) __attribute__((interrupt()));
void SysTick_Handler(void)
{
GET_INT_SP();
/* enter interrupt */
x_base level;
level = DisableLocalInterrupt();
isrManager.done->incCounter();
EnableLocalInterrupt(level);
SysTick->CNTFG &= ~(1 << 1);
TickAndTaskTimesliceUpdate();
KTaskOsAssignAfterIrq(NONE);
/* leave interrupt */
level = DisableLocalInterrupt();
isrManager.done->decCounter();
EnableLocalInterrupt(level);
FREE_INT_SP();
}

View File

@ -0,0 +1,31 @@
mainmenu "XiZi_IIoT Project Configuration"
config BSP_DIR
string
option env="BSP_ROOT"
default "."
config KERNEL_DIR
string
option env="KERNEL_ROOT"
default "../.."
config BOARD_CH569W
bool
select ARCH_RISCV
default y
source "$KERNEL_DIR/arch/Kconfig"
menu "ch569w feature"
source "$BSP_DIR/third_party_driver/Kconfig"
endmenu
menu "Hardware feature"
source "$KERNEL_DIR/resources/Kconfig"
endmenu
source "$KERNEL_DIR/Kconfig"

View File

@ -0,0 +1,6 @@
SRC_FILES := board.c
SRC_DIR := third_party_driver
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,78 @@
# 1. 简介
| 硬件 | 描述 |
| --------- | ----------------------------------------- |
| 芯片型号 | CH569W |
| CPU | 单核RISC-V3A |
| 主频 | 120MHz |
| 片内SRAM | 32/64/96KB 可配置的 128 位宽 SRAMRAMX |
| 片内FLASH | 448KB 用户应用程序存储区 CodeFlash |
| 外设 | UART等 |
# 2. 克隆代码
将XiUOS的源代码克隆下来
```bash
git clone https://gitlink.org.cn/xuos/xiuos.git
```
# 3. 下载编译工具链
编译环境Ubuntu 20.04.6 LTS
编译工具链riscv-none-embed-gccxpack-riscv-none-embed-gcc-8.2.0-3.1
编译工具链可到Github进行下载https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack/releases/download/v8.2.0-3.1/xpack-riscv-none-embed-gcc-8.2.0-3.1-linux-x64.tgz
下载完成后将其移动到`/opt`目录下,并进行解压:
```bash
sudo tar -xvzf xpack-riscv-none-embed-gcc-8.2.0-3.1-linux-x64.tgz
```
# 4. 编译
## 方式1推荐
可以在`Ubiquitous/XiZi_IIoT`目录下创建文件`script.sh`,内容如下:
```sh
#! /bin/env sh
export CROSS_COMPILE=/opt/xPacks/riscv-none-embed-gcc/8.2.0-3.1/bin/riscv-none-embed-
make BOARD=ch569w distclean # 将之前的编译生成文件清空
make BOARD=ch569w menuconfig
make BOARD=ch569w
```
创建之后,在命令行移动到`XiZi-IIOT`目录下,键入`./script`运行该脚本。
经过Kconfig配置、编译后即可在`Ubiquitous/XiZi_IIoT/build`目录中生成`XiZi-ch569w.bin`文件将该文件拷贝至Windows侧待下一步进行烧录。
> [!CAUTION]
>
> 如果`make BOARD=ch569w menuconfig`显示【无法找到`kconfig-mconf`】,需要先安装`ncurses-devel`和`kconfig-mconf`,如下:
>
> ```bash
> sudo apt install libncurses5-dev kconfig-frontends
# 5. 烧录
1. 沁恒微电子官网下载 WCHISPTool.exe 工具进行 bin 文件下载到芯片 flash 的操作。CH569W 芯片需要进入下载模式才能使用 ISP 工具下载代码,一般使用 USB 方式下载代码最为方便。
2. 将 CH569W 评估板使用 USB 插头对插头线和计算机连接起来。如图,打开 ISP 下载工具,芯片信号选择 CH569下载方式选择 USB将 CH569W 评估板断电,然后将下载配置脚(出厂默认为 PA5原理图上的HD0接地后对评估板上电此时 ISP 工具的 USB 设备列表中将显示新连上来的 CH569W 芯片。最后点击“下载”,即可使程序下载到评估版上的主芯片。
<img src="imgs/image_shaolukaifabanpaizhao.jpg" alt="image_shaolukaifabanpaizhao" style="zoom:30%;" />
<img src="imgs/image_shaoluruanjianjietu.png" alt="image_shaoluruanjianjietu" style="zoom:50%;" />
# 6. 启动
烧录完成后,并且将串口连接至电脑。
将评估板上电重新,即可看到操作系统启动的信息,如下:
![image_xitongqidongrizhi](imgs/image_xitongqidongrizhi.png)

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file board.c
* @brief support ch569 init configure and start-up
* @version 1.0
* @author AIIT XUOS Lab
* @date 2025-04-07
*/
#include <device.h>
#include <stdint.h>
#include <xizi.h>
#include "CH56x_common.h"
#include "connect_uart.h"
#include "board.h"
void InitBoardHardware()
{
SystemInit(FREQ_SYS);
Delay_Init(FREQ_SYS);
SysTick_Config(FREQ_SYS / 8 / TICK_PER_SECOND);
PFIC_EnableIRQ(SWI_IRQn);
/* initialize memory system */
InitBoardMemory(MEMORY_START_ADDRESS, (void *)MEMORY_END_ADDRESS);
#ifdef BSP_USING_UART
InitHwUart();
InstallConsole("uart1", SERIAL_DRV_NAME_1, SERIAL_1_DEVICE_NAME_0);
KPrintf("\nconsole init completed.\n");
#endif
KPrintf("memory address range: [0x%08x - 0x%08x] ssize: %x\n", (x_ubase)MEMORY_START_ADDRESS,
(x_ubase)MEMORY_END_ADDRESS, MEMORY_STACK_SIZE);
KPrintf("board init done.\n");
KPrintf("start kernel...\n");
}

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file board.h
* @brief define ch569 init configure and start-up function
* @version 1.0
* @author AIIT XUOS Lab
* @date 2025-04-07
*/
#ifndef __BOARD_H__
#define __BOARD_H__
#include <stdint.h>
#include "CH56xSFR.h"
extern uint32_t _ebss;
extern uint32_t __stack_size;
#define MEMORY_START_ADDRESS ((void *)&_ebss)
//#define MEMORY_END_ADDRESS ((void *)(BA_RAM) + (SZ_RAM))
#define MEMORY_END_ADDRESS ((void *)(BA_RAMX) + (SZ_RAMX))
#define MEMORY_STACK_SIZE (&__stack_size)
void InitBoardHardware(void);
#endif /* __BOARD_H__ */

View File

@ -0,0 +1,18 @@
export MARCH := rv32imac
# export CFLAGS := -march=$(MARCH) -mabi=ilp32 -msmall-data-limit=8 -msave-restore -Os -g
export CFLAGS := -march=rv32imac -mabi=ilp32 -msmall-data-limit=8 -mno-save-restore -Os -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -g -std=gnu99
export AFLAGS := -march=$(MARCH) -mabi=ilp32 -x assembler-with-cpp -ggdb
export LFLAGS := -march=$(MARCH) -mabi=ilp32 -nostartfiles -Wl,--gc-sections,-Map=XiZi-ch569w.map,-cref,-u,_start -T $(BSP_ROOT)/link.ld
export APPLFLAGS := -nostartfiles -Wl,--gc-sections,-Map=XiZi-app.map,-cref,-u, -T $(BSP_ROOT)/link_userspace.lds
export CXXFLAGS := -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -fno-common # -std=gnu99
export DEFINES := -DDEBUG=1
export ARCH = risc-v
export MCU = CH569W

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -0,0 +1,209 @@
ENTRY( _start )
__stack_size = 2048;
PROVIDE( _stack_size = __stack_size );
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 448K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 16K
RAMX (xrw) : ORIGIN = 0x20020000, LENGTH = 96K
}
SECTIONS
{
.init :
{
_sinit = .;
. = ALIGN(4);
KEEP(*(SORT_NONE(.init)))
. = ALIGN(4);
_einit = .;
} >FLASH AT>FLASH
.vector :
{
*(.vector);
. = ALIGN(64);
} >FLASH AT>FLASH
.hclib :
{
. = ALIGN(4);
*ISPEM569.o(*)
. = ALIGN(4);
}
.text :
{
. = ALIGN(4);
*(.text)
*(.text.*)
*(.rodata)
*(.rodata*)
*(.glue_7)
*(.glue_7t)
*(.gnu.linkonce.t.*)
. = ALIGN(4);
/* section information for shell */
. = ALIGN(4);
_shell_command_start = .;
KEEP (*(shellCommand))
_shell_command_end = .;
. = ALIGN(4);
PROVIDE(__ctors_start__ = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
PROVIDE(__ctors_end__ = .);
. = ALIGN(4);
__isrtbl_idx_start = .;
KEEP(*(.isrtbl.idx))
__isrtbl_start = .;
KEEP(*(.isrtbl))
__isrtbl_end = .;
. = ALIGN(4);
PROVIDE(g_service_table_start = ABSOLUTE(.));
KEEP(*(.g_service_table))
PROVIDE(g_service_table_end = ABSOLUTE(.));
*(.gnu.linkonce.t.*)
} >FLASH AT>FLASH
.fini :
{
KEEP(*(SORT_NONE(.fini)))
. = ALIGN(4);
} >FLASH AT>FLASH
PROVIDE( _etext = . );
PROVIDE( _eitcm = . );
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH AT>FLASH
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
} >FLASH AT>FLASH
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH AT>FLASH
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
} >FLASH AT>FLASH
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
} >FLASH AT>FLASH
.dalign :
{
. = ALIGN(4);
PROVIDE(_data_vma = .);
} >RAMX AT>FLASH
.dlalign :
{
. = ALIGN(4);
PROVIDE(_data_lma = .);
} >FLASH AT>FLASH
.data :
{
*(.gnu.linkonce.r.*)
*(.data .data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
PROVIDE( __global_pointer$ = . + 0x800 );
*(.sdata .sdata.*)
*(.sdata2.*)
*(.gnu.linkonce.s.*)
. = ALIGN(8);
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
. = ALIGN(4);
PROVIDE( _edata = .);
} >RAMX AT>FLASH
.bss :
{
. = ALIGN(4);
PROVIDE( _sbss = .);
*(.sbss*)
*(.gnu.linkonce.sb.*)
*(.bss*)
*(.gnu.linkonce.b.*)
*(COMMON*)
. = ALIGN(4);
PROVIDE( _ebss = .);
} >RAMX AT>FLASH
PROVIDE( _end = _ebss);
PROVIDE( end = . );
/*
.DMADATA :
{
. = ALIGN(16);
PROVIDE( _dmadata_start = .);
*(.dmadata*)
*(.dmadata.*)
. = ALIGN(16);
PROVIDE( _dmadata_end = .);
} >RAMX AT>FLASH
*/
.stack ORIGIN(RAMX) + LENGTH(RAMX) - __stack_size :
{
. = ALIGN(4);
PROVIDE(_susrstack = . );
. = . + __stack_size;
PROVIDE( _eusrstack = .);
} >RAMX
}

View File

@ -0,0 +1,7 @@
menuconfig BSP_USING_UART
bool "Using UART device"
default y
select RESOURCES_SERIAL
if BSP_USING_UART
source "$BSP_DIR/third_party_driver/uart/Kconfig"
endif

View File

@ -0,0 +1,7 @@
SRC_DIR := Peripheral
ifeq ($(CONFIG_BSP_USING_UART),y)
SRC_DIR += uart
endif
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,3 @@
SRC_DIR := src
include $(KERNEL_ROOT)/compiler.mk

View File

@ -254,7 +254,7 @@ extern "C" {
#define RB_SOFTWARE_RESET 0x01 // WA/WZ, global software reset, high action, auto clear
#define RB_WDOG_RST_EN 0x02 // RWA, enable watch-dog reset if watch-dog timer overflow: 0=as timer only, 1=enable reset if timer overflow
#define RB_WDOG_INT_EN 0x04 // RWA, watch-dog interrupt enable or INT_ID_WDOG interrupt source selection: 0=software interrupt, 1=from watch-dog timer overflow
#define RB_WDOG_INT_FLAG 0x10 // RW1, watch-dog timer overflow interrupt flag, cleared by RW1 or reload watch-dog count
#define RB_WDOG_INT_FLAG 0x08 // RW1, watch-dog timer overflow interrupt flag, cleared by RW1 or reload watch-dog count
#define R8_GLOB_RESET_KEEP (*((PUINT8V)0x40001007)) // RW, value keeper during global reset
/* System: clock configuration register */

View File

@ -0,0 +1,17 @@
SRC_FILES := \
CH56x_bus8.c \
CH56x_clk.c \
CH56x_dvp.c \
CH56x_ecdc.c \
CH56x_emmc.c \
CH56x_eth.c \
CH56x_gpio.c \
CH56x_hspi.c \
CH56x_pwm.c \
CH56x_pwr.c \
CH56x_spi.c \
CH56x_sys.c \
CH56x_timer.c \
CH56x_uart.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,178 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file connect_uart.h
* @brief define rvstar uart function
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-08-01
*/
#ifndef CONNECT_UART_H
#define CONNECT_UART_H
#include <device.h>
#ifdef __cplusplus
extern "C" {
#endif
union _uart_mcr
{
uint8_t reg;
struct
{
uint8_t dtr : 1; // B.0 : RW, DTR output (UART0 only)
uint8_t rts : 1; // B.1 : RW, RTS output (UART0 only)
uint8_t out1 : 1; // B.2 : RW, user defined modem control (UART0 only)
uint8_t int_oe : 1; // B.3 : RW, interrupt output enable / OUT2
uint8_t loop : 1; // B.4 : RW, enable internal loop test (UART0 only)
uint8_t au_flow_en : 1; // B.5 : RW, enable CTS/RTS autoflow control
uint8_t tnow : 1; // B.6 : RW, enable DTR TNOW output (UART0 only)
uint8_t half : 1; // B.7 : RW, enable half-duplex mode (UART0 only)
};
};
union _uart_ier
{
uint8_t reg;
struct
{
uint8_t recv_rdy : 1; // B.0 : RW, enable rx data ready intr
uint8_t thr_empty : 1; // B.1 : RW, enable THR empty intr
uint8_t line_stat : 1; // B.2 : RW, enable rx line status intr
uint8_t modem_chg : 1; // B.3 : RW, enable modem status change intr (UART0 only)
uint8_t dtr_en : 1; // B.4 : RW, DTR/TNOW output pin enable (UART0 only)
uint8_t rts_en : 1; // B.5 : RW, RTS output pin enable (UART0 only)
uint8_t txd_en : 1; // B.6 : RW, TXD pin enable
uint8_t reset : 1; // B.7 : WZ, software reset control, active high, auto clear
};
};
union _uart_fcr
{
uint8_t reg;
struct
{
uint8_t fifo_en : 1; // B.0 : RW, FIFO enable
uint8_t rx_fifo_clr : 1; // B.1 : WZ, write 1 to clear rx FIFO, auto clear
uint8_t tx_fifo_clr : 1; // B.2 : WZ, write 1 to clear tx FIFO, auto clear
uint8_t resv_3 : 3;
uint8_t fifo_trig : 2; // B.7-6 : RW, rx FIFO trigger level, 1/2/4/7 bytes
};
};
union _uart_lcr
{
uint8_t reg;
struct
{
uint8_t word_sz : 2; // B.1-0 : RW, word bit length, 5/6/7/8 bits
uint8_t stop_bit : 1; // B.2 : RW, stop bit length, 1/2 bits
uint8_t par_en : 1; // B.3 : RW, parity enable
uint8_t par_mod : 2; // B.5-4 : RW, parity mode, odd/even/mark/space
uint8_t break_en : 1; // B.6 : RW, force BREAK line condition
uint8_t dlab : 1; // B.7 : RW, user defined general purpose bit
};
};
#define LCR_DATA_BITS_5 0
#define LCR_DATA_BITS_6 1
#define LCR_DATA_BITS_7 2
#define LCR_DATA_BITS_8 3
#define LCR_STOP_BITS_1 0
#define LCR_STOP_BITS_2 1
#define LCR_PARITY_ODD 0
#define LCR_PARITY_EVEN 1
#define LCR_PARITY_MARK 2
#define LCR_PARITY_SPACE 3
union _uart_iir
{
uint8_t reg;
struct
{
uint8_t int_mask : 4; // B.3-0 : RO, interrupt mask (intr if B.0 is 0)
uint8_t resv_4 : 2;
uint8_t fifo_id : 2; // B.7-6 : RO, FIFO enabled flag
};
};
union _uart_lsr
{
uint8_t reg;
struct
{
uint8_t data_rdy : 1; // B.0 : RO, rx FIFO data ready
uint8_t over_err : 1; // B.1 : RZ, rx FIFO data overrun
uint8_t par_err : 1; // B.2 : RZ, rx parity error
uint8_t frame_err : 1; // B.3 : RZ, rx frame error
uint8_t break_err : 1; // B.4 : RZ, rx BREAK detected
uint8_t tx_fifo_emp : 1; // B.5 : RO, tx FIFO empty
uint8_t tx_all_emp : 1; // B.6 : RO, THR/TSR all empty
uint8_t err_rx_fifo : 1; // B.7 : RO, PAR/FRAME/BREAK ERR in rx FIFO
};
};
union _uart_msr
{
uint8_t reg;
struct
{
uint8_t cts_chg : 1; // B.0 : RZ, CTS input changed
uint8_t dsr_chg : 1; // B.1 : RZ, DSR input changed
uint8_t ri_chg : 1; // B.2 : RZ, RI input changed
uint8_t dcd_chg : 1; // B.3 : RZ, DCD input changed
uint8_t cts : 1; // B.4 : RO, CTS action status
uint8_t dsr : 1; // B.5 : RO, DSR action status
uint8_t ri : 1; // B.6 : RO, RI action status
uint8_t dcd : 1; // B.7 : RO, DCD action status
};
};
struct uart_registers
{
union _uart_mcr MCR;
union _uart_ier IER;
union _uart_fcr FCR;
union _uart_lcr LCR;
union _uart_iir IIR;
union _uart_lsr LSR;
union _uart_lsr MSR;
uint8_t resv_7;
union
{
uint8_t RBR;
uint8_t THR;
};
uint8_t resv_9;
uint8_t RFC;
uint8_t TFC;
uint16_t DL;
uint8_t DIV;
uint8_t ADR;
} __packed;
int InitHwUart(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,14 @@
menuconfig BSP_USING_UART1
bool "Enable UART1"
default y
if BSP_USING_UART1
config SERIAL_BUS_NAME_1
string "serial bus name"
default "uart1"
config SERIAL_DRV_NAME_1
string "serial bus driver name"
default "uart1_drv"
config SERIAL_1_DEVICE_NAME_0
string "serial bus device name"
default "uart1_dev1"
endif

View File

@ -0,0 +1,4 @@
SRC_FILES := connect_uart.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,404 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan
* PSL v2. You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY
* KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
* NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the
* Mulan PSL v2 for more details.
*/
/**
* @file connect_usart.c
* @brief support ch569 uart function and register to bus framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2025-04-07
*/
#include <xizi.h>
#include "xsconfig.h"
#include "CH56x_common.h"
#include "ch56x_it.h"
#include "board.h"
#include "connect_uart.h"
/* uart driver */
static void SerialCfgParamCheck(struct SerialCfgParam *serial_cfg_default, struct SerialCfgParam *serial_cfg_new) {
struct SerialDataCfg *data_cfg_default = &serial_cfg_default->data_cfg;
struct SerialDataCfg *data_cfg_new = &serial_cfg_new->data_cfg;
if ((data_cfg_default->serial_baud_rate != data_cfg_new->serial_baud_rate) && (data_cfg_new->serial_baud_rate)) {
data_cfg_default->serial_baud_rate = data_cfg_new->serial_baud_rate;
}
if ((data_cfg_default->serial_bit_order != data_cfg_new->serial_bit_order) && (data_cfg_new->serial_bit_order)) {
data_cfg_default->serial_bit_order = data_cfg_new->serial_bit_order;
}
if ((data_cfg_default->serial_buffer_size != data_cfg_new->serial_buffer_size) &&
(data_cfg_new->serial_buffer_size)) {
data_cfg_default->serial_buffer_size = data_cfg_new->serial_buffer_size;
}
if ((data_cfg_default->serial_data_bits != data_cfg_new->serial_data_bits) && (data_cfg_new->serial_data_bits)) {
data_cfg_default->serial_data_bits = data_cfg_new->serial_data_bits;
}
if ((data_cfg_default->serial_invert_mode != data_cfg_new->serial_invert_mode) &&
(data_cfg_new->serial_invert_mode)) {
data_cfg_default->serial_invert_mode = data_cfg_new->serial_invert_mode;
}
if ((data_cfg_default->serial_parity_mode != data_cfg_new->serial_parity_mode) &&
(data_cfg_new->serial_parity_mode)) {
data_cfg_default->serial_parity_mode = data_cfg_new->serial_parity_mode;
}
if ((data_cfg_default->serial_stop_bits != data_cfg_new->serial_stop_bits) && (data_cfg_new->serial_stop_bits)) {
data_cfg_default->serial_stop_bits = data_cfg_new->serial_stop_bits;
}
if ((data_cfg_default->serial_timeout != data_cfg_new->serial_timeout) && (data_cfg_new->serial_timeout)) {
data_cfg_default->serial_timeout = data_cfg_new->serial_timeout;
}
}
static void UartIsr(struct SerialDriver *serial_drv, struct SerialHardwareDevice *serial_dev) {
struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_dev->private_data;
struct uart_registers *uxreg = (struct uart_registers *)serial_cfg->hw_cfg.serial_register_base;
if (UART_II_RECV_RDY == uxreg->IIR.int_mask) {
SerialSetIsr(serial_dev, SERIAL_EVENT_RX_IND);
PFIC_ClearPendingIRQ(serial_cfg->hw_cfg.serial_irq_interrupt);
}
}
static uint32 SerialInit(struct SerialDriver *serial_drv, struct BusConfigureInfo *configure_info) {
NULL_PARAM_CHECK(serial_drv);
struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_drv->private_data;
struct SerialHardwareDevice *serial_dev = (struct SerialHardwareDevice *)serial_drv->driver.owner_bus->owner_haldev;
struct SerialDevParam *dev_param = (struct SerialDevParam *)serial_dev->haldev.private_data;
if (configure_info->private_data) {
struct SerialCfgParam *serial_cfg_new = (struct SerialCfgParam *)configure_info->private_data;
SerialCfgParamCheck(serial_cfg, serial_cfg_new);
if (serial_cfg_new->data_cfg.dev_recv_callback) {
BusDevRecvCallback(&(serial_dev->haldev), serial_cfg_new->data_cfg.dev_recv_callback);
}
}
// config serial receive sem timeout
dev_param->serial_timeout = serial_cfg->data_cfg.serial_timeout;
#if 1
struct uart_registers *uxreg = (struct uart_registers *)serial_cfg->hw_cfg.serial_register_base;
union _uart_fcr fcr;
union _uart_lcr lcr;
uint32_t x;
uint32_t t = FREQ_SYS;
// x = 10 * sys_hclk_get() / 8 / serial_cfg->data_cfg.serial_baud_rate;
x = 10 * t / 8 / serial_cfg->data_cfg.serial_baud_rate;
x = (x + 5) / 10;
uxreg->DL = x;
uxreg->DIV = 1;
lcr.reg = 0;
switch (serial_cfg->data_cfg.serial_data_bits)
{
case DATA_BITS_5:
lcr.word_sz = LCR_DATA_BITS_5;
break;
case DATA_BITS_6:
lcr.word_sz = LCR_DATA_BITS_6;
break;
case DATA_BITS_7:
lcr.word_sz = LCR_DATA_BITS_7;
break;
case DATA_BITS_8:
default:
lcr.word_sz = LCR_DATA_BITS_8;
break;
}
switch (serial_cfg->data_cfg.serial_stop_bits)
{
case STOP_BITS_2:
lcr.stop_bit = LCR_STOP_BITS_2;
break;
case STOP_BITS_1:
default:
lcr.stop_bit = LCR_STOP_BITS_1;
break;
}
switch (serial_cfg->data_cfg.serial_parity_mode)
{
case PARITY_ODD:
lcr.par_mod = LCR_PARITY_ODD;
lcr.par_en = 1;
break;
case PARITY_EVEN:
lcr.par_mod = LCR_PARITY_EVEN;
lcr.par_en = 1;
break;
case PARITY_NONE:
default:
lcr.par_en = 0;
break;
}
uxreg->LCR.reg = lcr.reg;
fcr.reg = RB_FCR_FIFO_EN | RB_FCR_RX_FIFO_CLR | RB_FCR_TX_FIFO_CLR;
fcr.fifo_trig = UART_1BYTE_TRIG;
uxreg->FCR.reg = fcr.reg;
/* TXD pin output enable */
uxreg->IER.txd_en = 1;
#endif
return EOK;
}
static uint32 SerialConfigure(struct SerialDriver *serial_drv, int serial_operation_cmd) {
NULL_PARAM_CHECK(serial_drv);
struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_drv->private_data;
struct uart_registers *uxreg = (struct uart_registers *)serial_cfg->hw_cfg.serial_register_base;
switch (serial_operation_cmd) {
case OPER_CLR_INT:
uxreg->IER.recv_rdy = 0;
uxreg->IER.line_stat = 0;
uxreg->IER.thr_empty = 0;
PFIC_DisableIRQ(serial_cfg->hw_cfg.serial_irq_interrupt);
break;
case OPER_SET_INT:
uxreg->FCR.fifo_trig = UART_1BYTE_TRIG;
uxreg->MCR.int_oe = 1;
uxreg->IER.recv_rdy = 1;
uxreg->IER.line_stat = 1;
uxreg->IER.thr_empty = 1;
PFIC_EnableIRQ(serial_cfg->hw_cfg.serial_irq_interrupt);
break;
}
return EOK;
}
static uint32 SerialDrvConfigure(void *drv, struct BusConfigureInfo *configure_info) {
NULL_PARAM_CHECK(drv);
NULL_PARAM_CHECK(configure_info);
x_err_t ret = EOK;
int serial_operation_cmd;
struct SerialDriver *serial_drv = (struct SerialDriver *)drv;
switch (configure_info->configure_cmd) {
case OPE_INT:
ret = SerialInit(serial_drv, configure_info);
break;
case OPE_CFG:
serial_operation_cmd = *(int *)configure_info->private_data;
ret = SerialConfigure(serial_drv, serial_operation_cmd);
break;
default:
break;
}
return ret;
}
static int SerialPutChar(struct SerialHardwareDevice *serial_dev, char ch) {
struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_dev->private_data;
volatile struct uart_registers *uxreg = (struct uart_registers *)serial_cfg->hw_cfg.serial_register_base;
if (uxreg->TFC >= UART_FIFO_SIZE) {
return -1;
}
while (1 != uxreg->LSR.tx_fifo_emp);
uxreg->THR = ch;
return 1;
}
static int SerialGetChar(struct SerialHardwareDevice *serial_dev) {
int ch = -1;
struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_dev->private_data;
if ( (UART1_GetLinSTA() & RB_LSR_DATA_RDY) == RB_LSR_DATA_RDY) {
ch = UART1_RecvByte();
}
#if 0
if (RESET != USART_GetFlagStatus((USART_TypeDef *)serial_cfg->hw_cfg.serial_register_base, USART_FLAG_RXNE)) {
ch = USART_ReceiveData((USART_TypeDef *)serial_cfg->hw_cfg.serial_register_base) & 0xff;
}
#endif
return ch;
}
static const struct SerialDataCfg data_cfg_init = {
.serial_baud_rate = BAUD_RATE_115200,
.serial_data_bits = DATA_BITS_8,
.serial_stop_bits = STOP_BITS_1,
.serial_parity_mode = PARITY_NONE,
.serial_bit_order = BIT_ORDER_LSB,
.serial_invert_mode = NRZ_NORMAL,
.serial_buffer_size = SERIAL_RB_BUFSZ,
.serial_timeout = WAITING_FOREVER,
};
/*manage the serial device operations*/
static const struct SerialDrvDone drv_done = {
.init = SerialInit,
.configure = SerialConfigure,
};
/*manage the serial device hal operations*/
static struct SerialHwDevDone hwdev_done = {
.put_char = SerialPutChar,
.get_char = SerialGetChar,
};
static int BoardSerialBusInit(struct SerialBus *serial_bus, struct SerialDriver *serial_driver, const char *bus_name,
const char *drv_name) {
x_err_t ret = EOK;
/*Init the serial bus */
ret = SerialBusInit(serial_bus, bus_name);
if (EOK != ret) {
KPrintf("InitHwUart SerialBusInit error %d\n", ret);
return ERROR;
}
/*Init the serial driver*/
ret = SerialDriverInit(serial_driver, drv_name);
if (EOK != ret) {
KPrintf("InitHwUart SerialDriverInit error %d\n", ret);
return ERROR;
}
/*Attach the serial driver to the serial bus*/
ret = SerialDriverAttachToBus(drv_name, bus_name);
if (EOK != ret) {
KPrintf("InitHwUart SerialDriverAttachToBus error %d\n", ret);
return ERROR;
}
return ret;
}
/*Attach the serial device to the serial bus*/
static int BoardSerialDevBend(struct SerialHardwareDevice *serial_device, void *serial_param, const char *bus_name,
const char *dev_name) {
x_err_t ret = EOK;
ret = SerialDeviceRegister(serial_device, serial_param, dev_name);
if (EOK != ret) {
KPrintf("InitHwUart SerialDeviceInit device %s error %d\n", dev_name, ret);
return ERROR;
}
ret = SerialDeviceAttachToBus(dev_name, bus_name);
if (EOK != ret) {
KPrintf("InitHwUart SerialDeviceAttachToBus device %s error %d\n", dev_name, ret);
return ERROR;
}
return ret;
}
#ifdef BSP_USING_UART1
struct SerialDriver serial_driver_1;
struct SerialHardwareDevice serial_device_1;
void UART1_IRQHandler(void) __attribute__((interrupt()));
void UART1_IRQHandler(void) {
#if 1
GET_INT_SP();
//isr_sp_enter();
x_base level;
level = DisableLocalInterrupt();
isrManager.done->incCounter();
EnableLocalInterrupt(level);
UartIsr(&serial_driver_1, &serial_device_1);
level = DisableLocalInterrupt();
isrManager.done->decCounter();
EnableLocalInterrupt(level);
FREE_INT_SP();
//isr_sp_leave();
#endif
}
#endif
int InitHwUart(void) {
x_err_t ret = EOK;
#ifdef BSP_USING_UART1
static struct SerialBus serial_bus;
memset(&serial_bus, 0, sizeof(struct SerialBus));
memset(&serial_driver_1, 0, sizeof(struct SerialDriver));
memset(&serial_device_1, 0, sizeof(struct SerialHardwareDevice));
static struct SerialCfgParam serial_cfg;
memset(&serial_cfg, 0, sizeof(struct SerialCfgParam));
static struct SerialDevParam serial_dev_param;
memset(&serial_dev_param, 0, sizeof(struct SerialDevParam));
serial_driver_1.drv_done = &drv_done;
serial_driver_1.configure = &SerialDrvConfigure;
serial_device_1.hwdev_done = &hwdev_done;
serial_cfg.data_cfg = data_cfg_init;
serial_cfg.hw_cfg.serial_register_base = (uint32)BA_UART1;
serial_cfg.hw_cfg.serial_irq_interrupt = UART1_IRQn;
serial_driver_1.private_data = (void *)&serial_cfg;
serial_dev_param.serial_work_mode = SIGN_OPER_INT_RX;
serial_device_1.haldev.private_data = (void *)&serial_dev_param;
ret = BoardSerialBusInit(&serial_bus, &serial_driver_1, SERIAL_BUS_NAME_1, SERIAL_DRV_NAME_1);
if (EOK != ret) {
KPrintf("InitHwUart uarths error ret %u\n", ret);
return ERROR;
}
ret = BoardSerialDevBend(&serial_device_1, (void *)&serial_cfg, SERIAL_BUS_NAME_1, SERIAL_1_DEVICE_NAME_0);
if (EOK != ret) {
KPrintf("InitHwUart uarths error ret %u\n", ret);
return ERROR;
}
/* Configure the serial port */
GPIOA_SetBits(GPIO_Pin_8);
GPIOA_ModeCfg(GPIO_Pin_7, GPIO_ModeIN_PU_NSMT); // RXD-pull-up input
GPIOA_ModeCfg(GPIO_Pin_8, GPIO_Slowascent_PP_8mA); // TXD-push-pull output
// UART1_DefInit();
/*
//Interrupt method
UART1_ByteTrigCfg( UART_1BYTE_TRIG );
UART1_INTCfg( ENABLE, RB_IER_RECV_RDY|RB_IER_LINE_STAT );
PFIC_EnableIRQ( UART1_IRQn );
*/
#endif
return ret;
}

View File

@ -307,6 +307,17 @@ KERNELPATHS += \
-I$(KERNEL_ROOT)/include #
endif
ifeq ($(BSP_ROOT),$(KERNEL_ROOT)/board/ch569w)
KERNELPATHS += \
-I$(KERNEL_ROOT)/arch/risc-v/ch569w \
-I$(KERNEL_ROOT)/arch/risc-v/ch569w/RVMSIS \
-I$(KERNEL_ROOT)/arch/risc-v/ch569w/User \
-I$(BSP_ROOT)/third_party_driver/include \
-I$(BSP_ROOT)/third_party_driver/Peripheral/inc \
-I$(BSP_ROOT)/include \
-I$(KERNEL_ROOT)/include #
endif
ifeq ($(BSP_ROOT),$(KERNEL_ROOT)/board/rv32m1-vega)
KERNELPATHS += \
-I$(KERNEL_ROOT)/arch/risc-v/rv32m1-vega \