fit XiUOS to board ch32v307.

This commit is contained in:
TXuian
2022-08-08 03:17:26 -07:00
parent 906398da9f
commit 92a33bff87
101 changed files with 43808 additions and 8 deletions
+31
View File
@@ -0,0 +1,31 @@
mainmenu "XiZi Project Configuration"
config BSP_DIR
string
option env="BSP_ROOT"
default "."
config KERNEL_DIR
string
option env="KERNEL_ROOT"
default "../.."
config BOARD_CH32V307VCT6
bool
select ARCH_RISCV
default y
source "$KERNEL_DIR/arch/Kconfig"
menu "ch32v307vct6 feature"
source "$BSP_DIR/third_party_driver/Kconfig"
endmenu
menu "Hardware feature"
source "$KERNEL_DIR/resources/Kconfig"
endmenu
source "$KERNEL_DIR/Kconfig"
+6
View File
@@ -0,0 +1,6 @@
SRC_FILES := board.c
SRC_DIR := third_party_driver
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,79 @@
/*
* Copyright (c) 2006-2019, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2017-07-24 Tanek the first version
* 2018-11-12 Ernest Chen modify copyright
*/
/*
* 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 ch32v307 init configure and start-up
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-08-08
*/
#include <board.h>
#include <xizi.h>
#include <stdint.h>
#include <device.h>
#include "xsconfig.h"
#include "ch32v30x.h"
#include "core_riscv.h"
// #include <system_ch32v30x.h>
// core clock.
extern uint32_t SystemCoreClock;
static uint32_t _SysTick_Config(uint32_t ticks)
{
NVIC_SetPriority(SysTicK_IRQn,0xf0);
NVIC_SetPriority(Software_IRQn,0xf0);
NVIC_EnableIRQ(SysTicK_IRQn);
NVIC_EnableIRQ(Software_IRQn);
SysTick->CTLR=0;
SysTick->SR=0;
SysTick->CNT=0;
SysTick->CMP=ticks-1;
SysTick->CTLR=0xF;
return 0;
}
/**
* This function will initial your board.
*/
void InitBoardHardware()
{
/* System Tick Configuration */
_SysTick_Config(SystemCoreClock / TICK_PER_SECOND);
/* initialize memory system */
InitBoardMemory(MEMORY_START_ADDRESS, (void*)MEMORY_END_ADDRESS);
InitHwUart();
InstallConsole("uart1", "uart1_drv", "uart1_dev1");
KPrintf("consle init completed.\n");
KPrintf("board initialization......\n");
// KPrintf("memory address range: [0x%08x - 0x%08x], size: %d\n", (x_ubase) MEMORY_START_ADDRESS, (x_ubase) MEMORY_END_ADDRESS, gd32vf103_SRAM_SIZE);
/* initialize memory system */
KPrintf("board init done.\n");
KPrintf("start okernel...\n");
}
@@ -0,0 +1,50 @@
/*
* 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 rvstar-board init configure and start-up function
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-09-02
*/
/*************************************************
File name: board.h
Description: define ch32v307-board init configure and start-up function
Others:
History:
1. Date: 2022-08-08
Author: AIIT XUOS Lab
Modification:
1. define rvstar-board InitBoardHardware
2. define rvstar-board data and bss struct
*************************************************/
#ifndef __BOARD_H__
#define __BOARD_H__
#include "ch32v30x.h"
#include <xsconfig.h>
#define CH32V30X_PIN_NUMBERS 100
/* board configuration */
#define SRAM_SIZE 64
#define SRAM_END (0x20000000 + SRAM_SIZE * 1024)
extern int _ebss;
extern int __stack_size;
#define MEMORY_START_ADDRESS ((void *)&_ebss)
#define MEMORY_END_ADDRESS (SRAM_END-__stack_size)
void InitBoardHardware(void);
#endif /* __BOARD_H__ */
+22
View File
@@ -0,0 +1,22 @@
export CFLAGS := -march=rv32imac -mabi=ilp32 -msmall-data-limit=8 -msave-restore -Os -g
export AFLAGS := -march=rv32imac -mabi=ilp32 -x assembler-with-cpp -ggdb
export LFLAGS := -march=rv32imac -mabi=ilp32 -nostartfiles -Wl,--gc-sections,-Map=XiZi-ch32v307vct6.map,-cref,-u,_start -T $(BSP_ROOT)/link.ld
# export CFLAGS := -march=rv32imacxw -mabi=ilp32 -msmall-data-limit=8 -msave-restore -Os -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -fno-common -g -std=gnu99
# export AFLAGS := -march=rv32imac -mabi=ilp32 -x assembler-with-cpp -ggdb
# export LFLAGS := -march=rv32imacxw -mabi=ilp32 -msmall-data-limit=8 -msave-restore -Os -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -fno-common -g -T $(BSP_ROOT)/link.ld -nostartfiles -Xlinker --gc-sections -Wl,-Map,"XiZi-ch32v307vct6.map" --specs=nano.specs --specs=nosys.specs
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 CROSS_COMPILE ?=/opt/riscv-embedded-gcc/bin/riscv-none-embed-
export DEFINES := -DHAVE_CCONFIG_H -DHAVE_SIGINFO
export ARCH = risc-v
export MCU = GH32V307
+194
View File
@@ -0,0 +1,194 @@
ENTRY( _start)
__stack_size = 3072;
PROVIDE( _stack_size = __stack_size );
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K
}
SECTIONS
{
.init :
{
_sinit = .;
. = ALIGN(4);
KEEP(*(SORT_NONE(.init)))
. = ALIGN(4);
_einit = .;
} >FLASH AT>FLASH
.vector :
{
*(.vector);
. = ALIGN(64);
} >FLASH AT>FLASH
.text :
{
. = ALIGN(4);
*(.text)
*(.text.*)
*(.rodata)
*(.rodata*)
*(.glue_7)
*(.glue_7t)
*(.gnu.linkonce.t.*)
/* 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 = .);
} >RAM 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 = .);
} >RAM AT>FLASH
.bss :
{
. = ALIGN(4);
PROVIDE( _sbss = .);
*(.sbss*)
*(.gnu.linkonce.sb.*)
*(.bss*)
*(.gnu.linkonce.b.*)
*(COMMON*)
. = ALIGN(4);
PROVIDE( _ebss = .);
} >RAM AT>FLASH
PROVIDE( _end = _ebss);
PROVIDE( end = . );
.stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size :
{
PROVIDE( _heap_end = . );
. = ALIGN(4);
PROVIDE(_susrstack = . );
. = . + __stack_size;
PROVIDE( _eusrstack = .);
} >RAM
}
@@ -0,0 +1,18 @@
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
menuconfig BSP_USING_GPIO
bool "Using GPIO"
default y
select RESOURCES_SERIAL
if BSP_USING_GPIO
source "$BSP_DIR/third_party_driver/gpio/Kconfig"
endif
@@ -0,0 +1,12 @@
SRC_FILES :=
SRC_DIR :=
ifeq ($(CONFIG_BSP_USING_UART),y)
SRC_DIR += uart
endif
ifeq ($(CONFIG_BSP_USING_GPIO),y)
SRC_DIR += gpio
endif
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,11 @@
config PIN_BUS_NAME
string "pin bus name"
default "pin"
config PIN_DRIVER_NAME
string "pin driver name"
default "pin_drv"
config PIN_DEVICE_NAME
string "pin device name"
default "pin_dev"
@@ -0,0 +1,3 @@
SRC_FILES :=
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,195 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : ch32v30x_usart.h
* Author : WCH
* Version : V1.0.0
* Date : 2021/06/06
* Description : This file contains all the functions prototypes for the
* USART firmware library.
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#ifndef __CH32V30x_USART_H
#define __CH32V30x_USART_H
#ifdef __cplusplus
extern "C" {
#endif
#include "ch32v30x.h"
/* USART Init Structure definition */
typedef struct
{
uint32_t USART_BaudRate; /* This member configures the USART communication baud rate.
The baud rate is computed using the following formula:
- IntegerDivider = ((PCLKx) / (16 * (USART_InitStruct->USART_BaudRate)))
- FractionalDivider = ((IntegerDivider - ((u32) IntegerDivider)) * 16) + 0.5 */
uint16_t USART_WordLength; /* Specifies the number of data bits transmitted or received in a frame.
This parameter can be a value of @ref USART_Word_Length */
uint16_t USART_StopBits; /* Specifies the number of stop bits transmitted.
This parameter can be a value of @ref USART_Stop_Bits */
uint16_t USART_Parity; /* Specifies the parity mode.
This parameter can be a value of @ref USART_Parity
@note When parity is enabled, the computed parity is inserted
at the MSB position of the transmitted data (9th bit when
the word length is set to 9 data bits; 8th bit when the
word length is set to 8 data bits). */
uint16_t USART_Mode; /* Specifies wether the Receive or Transmit mode is enabled or disabled.
This parameter can be a value of @ref USART_Mode */
uint16_t USART_HardwareFlowControl; /* Specifies wether the hardware flow control mode is enabled
or disabled.
This parameter can be a value of @ref USART_Hardware_Flow_Control */
} USART_InitTypeDef;
/* USART Clock Init Structure definition */
typedef struct
{
uint16_t USART_Clock; /* Specifies whether the USART clock is enabled or disabled.
This parameter can be a value of @ref USART_Clock */
uint16_t USART_CPOL; /* Specifies the steady state value of the serial clock.
This parameter can be a value of @ref USART_Clock_Polarity */
uint16_t USART_CPHA; /* Specifies the clock transition on which the bit capture is made.
This parameter can be a value of @ref USART_Clock_Phase */
uint16_t USART_LastBit; /* Specifies whether the clock pulse corresponding to the last transmitted
data bit (MSB) has to be output on the SCLK pin in synchronous mode.
This parameter can be a value of @ref USART_Last_Bit */
} USART_ClockInitTypeDef;
/* USART_Word_Length */
#define USART_WordLength_8b ((uint16_t)0x0000)
#define USART_WordLength_9b ((uint16_t)0x1000)
/* USART_Stop_Bits */
#define USART_StopBits_1 ((uint16_t)0x0000)
#define USART_StopBits_0_5 ((uint16_t)0x1000)
#define USART_StopBits_2 ((uint16_t)0x2000)
#define USART_StopBits_1_5 ((uint16_t)0x3000)
/* USART_Parity */
#define USART_Parity_No ((uint16_t)0x0000)
#define USART_Parity_Even ((uint16_t)0x0400)
#define USART_Parity_Odd ((uint16_t)0x0600)
/* USART_Mode */
#define USART_Mode_Rx ((uint16_t)0x0004)
#define USART_Mode_Tx ((uint16_t)0x0008)
/* USART_Hardware_Flow_Control */
#define USART_HardwareFlowControl_None ((uint16_t)0x0000)
#define USART_HardwareFlowControl_RTS ((uint16_t)0x0100)
#define USART_HardwareFlowControl_CTS ((uint16_t)0x0200)
#define USART_HardwareFlowControl_RTS_CTS ((uint16_t)0x0300)
/* USART_Clock */
#define USART_Clock_Disable ((uint16_t)0x0000)
#define USART_Clock_Enable ((uint16_t)0x0800)
/* USART_Clock_Polarity */
#define USART_CPOL_Low ((uint16_t)0x0000)
#define USART_CPOL_High ((uint16_t)0x0400)
/* USART_Clock_Phase */
#define USART_CPHA_1Edge ((uint16_t)0x0000)
#define USART_CPHA_2Edge ((uint16_t)0x0200)
/* USART_Last_Bit */
#define USART_LastBit_Disable ((uint16_t)0x0000)
#define USART_LastBit_Enable ((uint16_t)0x0100)
/* USART_Interrupt_definition */
#define USART_IT_PE ((uint16_t)0x0028)
#define USART_IT_TXE ((uint16_t)0x0727)
#define USART_IT_TC ((uint16_t)0x0626)
#define USART_IT_RXNE ((uint16_t)0x0525)
#define USART_IT_ORE_RX ((uint16_t)0x0325)
#define USART_IT_IDLE ((uint16_t)0x0424)
#define USART_IT_LBD ((uint16_t)0x0846)
#define USART_IT_CTS ((uint16_t)0x096A)
#define USART_IT_ERR ((uint16_t)0x0060)
#define USART_IT_ORE_ER ((uint16_t)0x0360)
#define USART_IT_NE ((uint16_t)0x0260)
#define USART_IT_FE ((uint16_t)0x0160)
#define USART_IT_ORE USART_IT_ORE_ER
/* USART_DMA_Requests */
#define USART_DMAReq_Tx ((uint16_t)0x0080)
#define USART_DMAReq_Rx ((uint16_t)0x0040)
/* USART_WakeUp_methods */
#define USART_WakeUp_IdleLine ((uint16_t)0x0000)
#define USART_WakeUp_AddressMark ((uint16_t)0x0800)
/* USART_LIN_Break_Detection_Length */
#define USART_LINBreakDetectLength_10b ((uint16_t)0x0000)
#define USART_LINBreakDetectLength_11b ((uint16_t)0x0020)
/* USART_IrDA_Low_Power */
#define USART_IrDAMode_LowPower ((uint16_t)0x0004)
#define USART_IrDAMode_Normal ((uint16_t)0x0000)
/* USART_Flags */
#define USART_FLAG_CTS ((uint16_t)0x0200)
#define USART_FLAG_LBD ((uint16_t)0x0100)
#define USART_FLAG_TXE ((uint16_t)0x0080)
#define USART_FLAG_TC ((uint16_t)0x0040)
#define USART_FLAG_RXNE ((uint16_t)0x0020)
#define USART_FLAG_IDLE ((uint16_t)0x0010)
#define USART_FLAG_ORE ((uint16_t)0x0008)
#define USART_FLAG_NE ((uint16_t)0x0004)
#define USART_FLAG_FE ((uint16_t)0x0002)
#define USART_FLAG_PE ((uint16_t)0x0001)
void USART_DeInit(USART_TypeDef* USARTx);
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);
void USART_StructInit(USART_InitTypeDef* USART_InitStruct);
void USART_ClockInit(USART_TypeDef* USARTx, USART_ClockInitTypeDef* USART_ClockInitStruct);
void USART_ClockStructInit(USART_ClockInitTypeDef* USART_ClockInitStruct);
void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState);
void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState);
void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState);
void USART_SetAddress(USART_TypeDef* USARTx, uint8_t USART_Address);
void USART_WakeUpConfig(USART_TypeDef* USARTx, uint16_t USART_WakeUp);
void USART_ReceiverWakeUpCmd(USART_TypeDef* USARTx, FunctionalState NewState);
void USART_LINBreakDetectLengthConfig(USART_TypeDef* USARTx, uint16_t USART_LINBreakDetectLength);
void USART_LINCmd(USART_TypeDef* USARTx, FunctionalState NewState);
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
uint16_t USART_ReceiveData(USART_TypeDef* USARTx);
void USART_SendBreak(USART_TypeDef* USARTx);
void USART_SetGuardTime(USART_TypeDef* USARTx, uint8_t USART_GuardTime);
void USART_SetPrescaler(USART_TypeDef* USARTx, uint8_t USART_Prescaler);
void USART_SmartCardCmd(USART_TypeDef* USARTx, FunctionalState NewState);
void USART_SmartCardNACKCmd(USART_TypeDef* USARTx, FunctionalState NewState);
void USART_HalfDuplexCmd(USART_TypeDef* USARTx, FunctionalState NewState);
void USART_OverSampling8Cmd(USART_TypeDef* USARTx, FunctionalState NewState);
void USART_OneBitMethodCmd(USART_TypeDef* USARTx, FunctionalState NewState);
void USART_IrDAConfig(USART_TypeDef* USARTx, uint16_t USART_IrDAMode);
void USART_IrDACmd(USART_TypeDef* USARTx, FunctionalState NewState);
FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG);
ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT);
void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);
#ifdef __cplusplus
}
#endif
#endif
@@ -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 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
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,396 @@
/*
* 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 supportrvstar-board uart function and register to bus framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-08-01
*/
#include <xizi.h>
#include "ch32v30x.h"
#include "connect_uart.h"
#include "ch32v30x_usart.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_drv->private_data;
if (RESET != USART_GetITStatus((USART_TypeDef *)serial_cfg->hw_cfg.serial_register_base, USART_IT_RXNE))
{
SerialSetIsr(serial_dev, SERIAL_EVENT_RX_IND);
USART_ClearITPendingBit((USART_TypeDef *)serial_cfg->hw_cfg.serial_register_base, USART_IT_RXNE);
}
}
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 UsartHwCfg *serial_hw_cfg = (struct UsartHwCfg *)serial_cfg->hw_cfg.private_data;
if (configure_info->private_data) {
struct SerialCfgParam *serial_cfg_new = (struct SerialCfgParam *)configure_info->private_data;
SerialCfgParamCheck(serial_cfg, serial_cfg_new);
}
struct SerialHardwareDevice *serial_dev = (struct SerialHardwareDevice *)serial_drv->driver.owner_bus->owner_haldev;
struct SerialDevParam *dev_param = (struct SerialDevParam *)serial_dev->haldev.private_data;
// config serial receive sem timeout
dev_param->serial_timeout = serial_cfg->data_cfg.serial_timeout;
// init usart type def
// USART_DeInit((USART_TypeDef *)serial_cfg->hw_cfg.serial_register_base);
USART_InitTypeDef usart_init_struct;
usart_init_struct.USART_BaudRate = serial_cfg->data_cfg.serial_baud_rate;
switch (serial_cfg->data_cfg.serial_data_bits)
{
case DATA_BITS_8:
usart_init_struct.USART_WordLength = USART_WordLength_8b;
break;
case DATA_BITS_9:
usart_init_struct.USART_WordLength = USART_WordLength_9b;
break;
default:
usart_init_struct.USART_WordLength = USART_WordLength_8b;
break;
}
switch (serial_cfg->data_cfg.serial_stop_bits)
{
case STOP_BITS_1:
usart_init_struct.USART_StopBits = USART_StopBits_1;
break;
case STOP_BITS_2:
usart_init_struct.USART_StopBits = USART_StopBits_2;
break;
default:
usart_init_struct.USART_StopBits = USART_StopBits_1;
break;
}
switch (serial_cfg->data_cfg.serial_parity_mode)
{
case PARITY_NONE:
usart_init_struct.USART_Parity = USART_Parity_No;
break;
case PARITY_ODD:
usart_init_struct.USART_Parity = USART_Parity_Odd;
break;
case PARITY_EVEN:
usart_init_struct.USART_Parity = USART_Parity_Even;
break;
default:
usart_init_struct.USART_Parity = USART_Parity_No;
break;
}
usart_init_struct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
if (serial_cfg->hw_cfg.serial_register_base == USART1) {
// GPIO_InitTypeDef gpio_init_struct;
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
// gpio_init_struct.GPIO_Pin = GPIO_Pin_9;
// gpio_init_struct.GPIO_Speed = GPIO_Speed_50MHz;
// gpio_init_struct.GPIO_Mode = GPIO_Mode_AF_PP;
// GPIO_Init(GPIOA, &gpio_init_struct);
// gpio_init_struct.GPIO_Pin = GPIO_Pin_10;
// gpio_init_struct.GPIO_Speed = GPIO_Speed_50MHz;
// gpio_init_struct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
// GPIO_Init(GPIOA, &gpio_init_struct);
// USART_Init((USART_TypeDef*)serial_cfg->hw_cfg.serial_register_base, &usart_init_struct);
// USART_Cmd(serial_cfg->hw_cfg.serial_register_base, ENABLE);
}
// usart_hardware_flow_rts_config(serial_cfg->hw_cfg.serial_register_base, USART_RTS_DISABLE);
// usart_hardware_flow_cts_config(serial_cfg->hw_cfg.serial_register_base, USART_CTS_DISABLE);
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;
switch (serial_operation_cmd)
{
case OPER_CLR_INT:
NVIC_DisableIRQ(serial_cfg->hw_cfg.serial_irq_interrupt);
USART_ITConfig((USART_TypeDef *)serial_cfg->hw_cfg.serial_register_base, USART_IT_RXNE, DISABLE);
break;
case OPER_SET_INT:
NVIC_EnableIRQ(serial_cfg->hw_cfg.serial_irq_interrupt);
/* enable USART0 receive interrupt */
USART_ITConfig((USART_TypeDef *)serial_cfg->hw_cfg.serial_register_base, USART_IT_RXNE, ENABLE);
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 c)
{
struct SerialCfgParam* serial_cfg = (struct SerialCfgParam*)serial_dev->private_data;
while (USART_GetFlagStatus((USART_TypeDef *)serial_cfg->hw_cfg.serial_register_base, USART_FLAG_TXE) == RESET);
USART_SendData((USART_TypeDef *)serial_cfg->hw_cfg.serial_register_base, (uint8_t) c);
return 0;
}
static int SerialGetChar(struct SerialHardwareDevice *serial_dev)
{
int ch = -1;
struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_dev->private_data;
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;
}
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 USART1_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void USART1_IRQHandler(void)
{
GET_INT_SP();
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();
}
#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 = USART1;
serial_cfg.hw_cfg.serial_irq_interrupt = USART1_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;
}
GPIO_InitTypeDef gpio_init_struct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
gpio_init_struct.GPIO_Pin = GPIO_Pin_9;
gpio_init_struct.GPIO_Speed = GPIO_Speed_50MHz;
gpio_init_struct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &gpio_init_struct);
gpio_init_struct.GPIO_Pin = GPIO_Pin_10;
gpio_init_struct.GPIO_Speed = GPIO_Speed_50MHz;
gpio_init_struct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &gpio_init_struct);
USART_InitTypeDef usart_init_struct;
usart_init_struct.USART_BaudRate = 115200;
usart_init_struct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
usart_init_struct.USART_Mode = USART_Mode_Tx|USART_Mode_Rx;
usart_init_struct.USART_WordLength = USART_WordLength_8b;
usart_init_struct.USART_StopBits = USART_StopBits_1;
usart_init_struct.USART_Parity = USART_Parity_No;
USART_Init((USART_TypeDef *)serial_cfg.hw_cfg.serial_register_base, &usart_init_struct);
USART_Cmd((USART_TypeDef *)serial_cfg.hw_cfg.serial_register_base, ENABLE);
#endif
return ret;
}