Add ch569w arch and board codes, support for uart
This commit is contained in:
parent
0fa8ff5368
commit
5e331e4c7c
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES := core_riscv.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -17,7 +17,7 @@
|
|||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include "CH56xSFR.H"
|
||||
#include "CH56xSFR.h"
|
||||
|
||||
/* IO definitions */
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES := ch56x_it.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -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();
|
||||
}
|
|
@ -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 */
|
||||
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
|
@ -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();
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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();
|
||||
}
|
|
@ -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"
|
||||
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
SRC_FILES := board.c
|
||||
|
||||
SRC_DIR := third_party_driver
|
||||
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,78 @@
|
|||
# 1. 简介
|
||||
|
||||
| 硬件 | 描述 |
|
||||
| --------- | ----------------------------------------- |
|
||||
| 芯片型号 | CH569W |
|
||||
| CPU | 单核RISC-V3A |
|
||||
| 主频 | 120MHz |
|
||||
| 片内SRAM | 32/64/96KB 可配置的 128 位宽 SRAM(RAMX) |
|
||||
| 片内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-gcc(xpack-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. 启动
|
||||
|
||||
烧录完成后,并且将串口连接至电脑。
|
||||
|
||||
将评估板上电重新,即可看到操作系统启动的信息,如下:
|
||||
|
||||

|
|
@ -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");
|
||||
}
|
|
@ -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__ */
|
|
@ -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 |
|
@ -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
|
||||
}
|
|
@ -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
|
|
@ -0,0 +1,7 @@
|
|||
SRC_DIR := Peripheral
|
||||
|
||||
ifeq ($(CONFIG_BSP_USING_UART),y)
|
||||
SRC_DIR += uart
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,3 @@
|
|||
SRC_DIR := src
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,4 @@
|
|||
SRC_FILES := connect_uart.c
|
||||
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -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;
|
||||
}
|
|
@ -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 \
|
||||
|
|
Loading…
Reference in New Issue