it is OK from Song_yanguang
[ch569w]Add ch569w arch and board codes, support for uart debug
This commit is contained in:
commit
d5afd37e1d
|
@ -5,7 +5,7 @@ MAKEFLAGS += --no-print-directory
|
||||||
.PHONY:COMPILE_APP COMPILE_KERNEL
|
.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
|
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
|
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
|
SRC_DIR := ch32v208rbt6
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_BOARD_CH569W), y)
|
||||||
|
SRC_DIR := ch569w
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_BOARD_RV32M1_VEGA),y)
|
ifeq ($(CONFIG_BOARD_RV32M1_VEGA),y)
|
||||||
SRC_DIR +=rv32m1-vega
|
SRC_DIR +=rv32m1-vega
|
||||||
endif
|
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
|
|
@ -0,0 +1,334 @@
|
||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : core_riscv.c
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0.1
|
||||||
|
* Date : 2023/11/11
|
||||||
|
* Description : RISC-V V3 Core Peripheral Access Layer Source File for CH56x
|
||||||
|
*********************************************************************************
|
||||||
|
* 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 <stdint.h>
|
||||||
|
|
||||||
|
/* define compiler specific symbols */
|
||||||
|
#if defined ( __CC_ARM )
|
||||||
|
#define __ASM __asm /*!< asm keyword for ARM Compiler */
|
||||||
|
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
|
||||||
|
|
||||||
|
#elif defined ( __ICCARM__ )
|
||||||
|
#define __ASM __asm /*!< asm keyword for IAR Compiler */
|
||||||
|
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */
|
||||||
|
|
||||||
|
#elif defined ( __GNUC__ )
|
||||||
|
#define __ASM __asm /*!< asm keyword for GNU Compiler */
|
||||||
|
#define __INLINE inline /*!< inline keyword for GNU Compiler */
|
||||||
|
|
||||||
|
#elif defined ( __TASKING__ )
|
||||||
|
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
|
||||||
|
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __get_MSTATUS
|
||||||
|
*
|
||||||
|
* @brief Return the Machine Status Register
|
||||||
|
*
|
||||||
|
* @return mstatus value
|
||||||
|
*/
|
||||||
|
uint32_t __get_MSTATUS(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ( "csrr %0," "mstatus" : "=r" (result) );
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __set_MSTATUS
|
||||||
|
*
|
||||||
|
* @brief Set the Machine Status Register
|
||||||
|
*
|
||||||
|
* @param value - set mstatus value
|
||||||
|
*
|
||||||
|
* @return none
|
||||||
|
*/
|
||||||
|
void __set_MSTATUS(uint32_t value)
|
||||||
|
{
|
||||||
|
__ASM volatile ("csrw mstatus, %0" : : "r" (value) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __get_MISA
|
||||||
|
*
|
||||||
|
* @brief Return the Machine ISA Register
|
||||||
|
*
|
||||||
|
* @return misa value
|
||||||
|
*/
|
||||||
|
uint32_t __get_MISA(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ( "csrr %0," "misa" : "=r" (result) );
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __set_MISA
|
||||||
|
*
|
||||||
|
* @brief Set the Machine ISA Register
|
||||||
|
*
|
||||||
|
* @param value - set misa value
|
||||||
|
*
|
||||||
|
* @return none
|
||||||
|
*/
|
||||||
|
void __set_MISA(uint32_t value)
|
||||||
|
{
|
||||||
|
__ASM volatile ("csrw misa, %0" : : "r" (value) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __get_MIE
|
||||||
|
*
|
||||||
|
* @brief Return the Machine Interrupt Enable Register
|
||||||
|
*
|
||||||
|
* @return mie value
|
||||||
|
*/
|
||||||
|
uint32_t __get_MIE(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ( "csrr %0," "mie" : "=r" (result) );
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __set_MISA
|
||||||
|
*
|
||||||
|
* @brief Set the Machine ISA Register
|
||||||
|
*
|
||||||
|
* @param value - set mie value
|
||||||
|
*
|
||||||
|
* @return none
|
||||||
|
*/
|
||||||
|
void __set_MIE(uint32_t value)
|
||||||
|
{
|
||||||
|
__ASM volatile ("csrw mie, %0" : : "r" (value) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __get_MTVEC
|
||||||
|
*
|
||||||
|
* @brief Return the Machine Trap-Vector Base-Address Register
|
||||||
|
*
|
||||||
|
* @return mtvec value
|
||||||
|
*/
|
||||||
|
uint32_t __get_MTVEC(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ( "csrr %0," "mtvec" : "=r" (result) );
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __set_MTVEC
|
||||||
|
*
|
||||||
|
* @brief Set the Machine Trap-Vector Base-Address Register
|
||||||
|
*
|
||||||
|
* @param value - set mtvec value
|
||||||
|
*
|
||||||
|
* @return none
|
||||||
|
*/
|
||||||
|
void __set_MTVEC(uint32_t value)
|
||||||
|
{
|
||||||
|
__ASM volatile ("csrw mtvec, %0" : : "r" (value) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __get_MSCRATCH
|
||||||
|
*
|
||||||
|
* @brief Return the Machine Seratch Register
|
||||||
|
*
|
||||||
|
* @return mscratch value
|
||||||
|
*/
|
||||||
|
uint32_t __get_MSCRATCH(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ( "csrr %0," "mscratch" : "=r" (result) );
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __set_MSCRATCH
|
||||||
|
*
|
||||||
|
* @brief Set the Machine Seratch Register
|
||||||
|
*
|
||||||
|
* @param value - set mscratch value
|
||||||
|
*
|
||||||
|
* @return none
|
||||||
|
*/
|
||||||
|
void __set_MSCRATCH(uint32_t value)
|
||||||
|
{
|
||||||
|
__ASM volatile ("csrw mscratch, %0" : : "r" (value) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __get_MEPC
|
||||||
|
*
|
||||||
|
* @brief Return the Machine Exception Program Register
|
||||||
|
*
|
||||||
|
* @return mepc value
|
||||||
|
*/
|
||||||
|
uint32_t __get_MEPC(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ( "csrr %0," "mepc" : "=r" (result) );
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __set_MEPC
|
||||||
|
*
|
||||||
|
* @brief Set the Machine Exception Program Register
|
||||||
|
*
|
||||||
|
* @return mepc value
|
||||||
|
*/
|
||||||
|
void __set_MEPC(uint32_t value)
|
||||||
|
{
|
||||||
|
__ASM volatile ("csrw mepc, %0" : : "r" (value) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __get_MCAUSE
|
||||||
|
*
|
||||||
|
* @brief Return the Machine Cause Register
|
||||||
|
*
|
||||||
|
* @return mcause value
|
||||||
|
*/
|
||||||
|
uint32_t __get_MCAUSE(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ( "csrr %0," "mcause" : "=r" (result) );
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __set_MEPC
|
||||||
|
*
|
||||||
|
* @brief Set the Machine Cause Register
|
||||||
|
*
|
||||||
|
* @return mcause value
|
||||||
|
*/
|
||||||
|
void __set_MCAUSE(uint32_t value)
|
||||||
|
{
|
||||||
|
__ASM volatile ("csrw mcause, %0" : : "r" (value) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __get_MTVAL
|
||||||
|
*
|
||||||
|
* @brief Return the Machine Trap Value Register
|
||||||
|
*
|
||||||
|
* @return mtval value
|
||||||
|
*/
|
||||||
|
uint32_t __get_MTVAL(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ( "csrr %0," "mtval" : "=r" (result) );
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __set_MTVAL
|
||||||
|
*
|
||||||
|
* @brief Set the Machine Trap Value Register
|
||||||
|
*
|
||||||
|
* @return mtval value
|
||||||
|
*/
|
||||||
|
void __set_MTVAL(uint32_t value)
|
||||||
|
{
|
||||||
|
__ASM volatile ("csrw mtval, %0" : : "r" (value) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __get_MVENDORID
|
||||||
|
*
|
||||||
|
* @brief Return Vendor ID Register
|
||||||
|
*
|
||||||
|
* @return mvendorid value
|
||||||
|
*/
|
||||||
|
uint32_t __get_MVENDORID(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ( "csrr %0," "mvendorid" : "=r" (result) );
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __get_MARCHID
|
||||||
|
*
|
||||||
|
* @brief Return Machine Architecture ID Register
|
||||||
|
*
|
||||||
|
* @return marchid value
|
||||||
|
*/
|
||||||
|
uint32_t __get_MARCHID(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ( "csrr %0," "marchid" : "=r" (result) );
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __get_MIMPID
|
||||||
|
*
|
||||||
|
* @brief Return Machine Implementation ID Register
|
||||||
|
*
|
||||||
|
* @return mimpid value
|
||||||
|
*/
|
||||||
|
uint32_t __get_MIMPID(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ( "csrr %0," "mimpid" : "=r" (result) );
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __get_MHARTID
|
||||||
|
*
|
||||||
|
* @brief Return Hart ID Register
|
||||||
|
*
|
||||||
|
* @return mhartid value
|
||||||
|
*/
|
||||||
|
uint32_t __get_MHARTID(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ( "csrr %0," "mhartid" : "=r" (result) );
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __get_SP
|
||||||
|
*
|
||||||
|
* @brief Return SP Register
|
||||||
|
*
|
||||||
|
* @return SP value
|
||||||
|
*/
|
||||||
|
uint32_t __get_SP(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
asm volatile ( "mv %0," "sp" : "=r"(result) : );
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,591 @@
|
||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : core_riscv.h
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0.1
|
||||||
|
* Date : 2023/11/11
|
||||||
|
* Description : RISC-V V3 Core Peripheral Access Layer Header File for CH56x
|
||||||
|
*********************************************************************************
|
||||||
|
* 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 __CORE_RISCV_H__
|
||||||
|
#define __CORE_RISCV_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "CH56xSFR.h"
|
||||||
|
|
||||||
|
/* IO definitions */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define __I volatile /*!< defines 'read only' permissions */
|
||||||
|
#else
|
||||||
|
#define __I volatile const /*!< defines 'read only' permissions */
|
||||||
|
#endif
|
||||||
|
#define __O volatile /*!< defines 'write only' permissions */
|
||||||
|
#define __IO volatile /*!< defines 'read / write' permissions */
|
||||||
|
#define RV_STATIC_INLINE static inline
|
||||||
|
|
||||||
|
typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;
|
||||||
|
typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus;
|
||||||
|
|
||||||
|
/* memory mapped structure for Program Fast Interrupt Controller (PFIC) */
|
||||||
|
typedef struct __attribute__((packed)) {
|
||||||
|
__I UINT32 ISR[8];
|
||||||
|
__I UINT32 IPR[8];
|
||||||
|
__IO UINT32 ITHRESDR;
|
||||||
|
__IO UINT32 VTFBADDRR;
|
||||||
|
__IO UINT32 CFGR;
|
||||||
|
__I UINT32 GISR;
|
||||||
|
UINT8 RESERVED0[0x10];
|
||||||
|
__IO UINT32 VTFADDRR[4];
|
||||||
|
UINT8 RESERVED1[0x90];
|
||||||
|
__O UINT32 IENR[8];
|
||||||
|
UINT8 RESERVED2[0x60];
|
||||||
|
__O UINT32 IRER[8];
|
||||||
|
UINT8 RESERVED3[0x60];
|
||||||
|
__O UINT32 IPSR[8];
|
||||||
|
UINT8 RESERVED4[0x60];
|
||||||
|
__O UINT32 IPRR[8];
|
||||||
|
UINT8 RESERVED5[0x60];
|
||||||
|
__IO UINT32 IACTR[8];
|
||||||
|
UINT8 RESERVED6[0xE0];
|
||||||
|
__IO UINT8 IPRIOR[256];
|
||||||
|
UINT8 RESERVED7[0x810];
|
||||||
|
__IO UINT32 SCTLR;
|
||||||
|
}PFIC_Type;
|
||||||
|
|
||||||
|
#define FIBADDRR VTFBADDRR
|
||||||
|
#define FIOFADDRR VTFADDRR
|
||||||
|
|
||||||
|
|
||||||
|
/* memory mapped structure for SysTick */
|
||||||
|
typedef struct __attribute__((packed))
|
||||||
|
{
|
||||||
|
__IO UINT32 CTLR;
|
||||||
|
__IO UINT64 CNT;
|
||||||
|
__IO UINT64 CMP;
|
||||||
|
__IO UINT32 CNTFG;
|
||||||
|
}SysTick_Type;
|
||||||
|
|
||||||
|
|
||||||
|
#define PFIC ((PFIC_Type *) 0xE000E000 )
|
||||||
|
#define SysTick ((SysTick_Type *) 0xE000F000)
|
||||||
|
|
||||||
|
#define PFIC_KEY1 ((UINT32)0xFA050000)
|
||||||
|
#define PFIC_KEY2 ((UINT32)0xBCAF0000)
|
||||||
|
#define PFIC_KEY3 ((UINT32)0xBEEF0000)
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __enable_irq
|
||||||
|
* This function is only used for Machine mode.
|
||||||
|
*
|
||||||
|
* @brief Enable Global Interrupt
|
||||||
|
*
|
||||||
|
* @return none
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __enable_irq()
|
||||||
|
{
|
||||||
|
__asm volatile ("csrs mstatus, %0" : : "r" (0x88) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __disable_irq
|
||||||
|
* This function is only used for Machine mode.
|
||||||
|
*
|
||||||
|
* @brief Disable Global Interrupt
|
||||||
|
*
|
||||||
|
* @return none
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __disable_irq()
|
||||||
|
{
|
||||||
|
__asm volatile ("csrc mstatus, %0" : : "r" (0x88) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __NOP
|
||||||
|
*
|
||||||
|
* @brief nop
|
||||||
|
*
|
||||||
|
* @return none
|
||||||
|
*/
|
||||||
|
RV_STATIC_INLINE void __NOP()
|
||||||
|
{
|
||||||
|
__asm volatile ("nop");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn PFIC_EnableIRQ
|
||||||
|
*
|
||||||
|
* @brief Enable Interrupt
|
||||||
|
*
|
||||||
|
* @param IRQn - Interrupt Numbers
|
||||||
|
*
|
||||||
|
* @return none
|
||||||
|
*/
|
||||||
|
RV_STATIC_INLINE void PFIC_EnableIRQ(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
PFIC->IENR[((UINT32)(IRQn) >> 5)] = (1 << ((UINT32)(IRQn) & 0x1F));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn PFIC_DisableIRQ
|
||||||
|
*
|
||||||
|
* @brief Disable Interrupt
|
||||||
|
*
|
||||||
|
* @param IRQn - Interrupt Numbers
|
||||||
|
*
|
||||||
|
* @return none
|
||||||
|
*/
|
||||||
|
RV_STATIC_INLINE void PFIC_DisableIRQ(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
UINT32 t;
|
||||||
|
|
||||||
|
t = PFIC->ITHRESDR;
|
||||||
|
PFIC->ITHRESDR = 0x10;
|
||||||
|
PFIC->IRER[((UINT32)(IRQn) >> 5)] = (1 << ((UINT32)(IRQn) & 0x1F));
|
||||||
|
PFIC->ITHRESDR = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn PFIC_GetStatusIRQ
|
||||||
|
*
|
||||||
|
* @brief Get Interrupt Enable State
|
||||||
|
*
|
||||||
|
* @param IRQn - Interrupt Numbers
|
||||||
|
*
|
||||||
|
* @return 1 - Interrupt Enable
|
||||||
|
* 0 - Interrupt Disable
|
||||||
|
*/
|
||||||
|
RV_STATIC_INLINE UINT32 PFIC_GetStatusIRQ(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
return((UINT32) ((PFIC->ISR[(UINT32)(IRQn) >> 5] & (1 << ((UINT32)(IRQn) & 0x1F)))?1:0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn PFIC_GetPendingIRQ
|
||||||
|
*
|
||||||
|
* @brief Get Interrupt Pending State
|
||||||
|
*
|
||||||
|
* @param IRQn - Interrupt Numbers
|
||||||
|
*
|
||||||
|
* @return 1 - Interrupt Pending Enable
|
||||||
|
* 0 - Interrupt Pending Disable
|
||||||
|
*/
|
||||||
|
RV_STATIC_INLINE UINT32 PFIC_GetPendingIRQ(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
return((UINT32) ((PFIC->IPR[(UINT32)(IRQn) >> 5] & (1 << ((UINT32)(IRQn) & 0x1F)))?1:0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn PFIC_SetPendingIRQ
|
||||||
|
*
|
||||||
|
* @brief Set Interrupt Pending
|
||||||
|
*
|
||||||
|
* @param IRQn - Interrupt Numbers
|
||||||
|
*
|
||||||
|
* @return none
|
||||||
|
*/
|
||||||
|
RV_STATIC_INLINE void PFIC_SetPendingIRQ(IRQn_Type IRQn){
|
||||||
|
PFIC->IPSR[((UINT32)(IRQn) >> 5)] = (1 << ((UINT32)(IRQn) & 0x1F));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn PFIC_ClearPendingIRQ
|
||||||
|
*
|
||||||
|
* @brief Clear Interrupt Pending
|
||||||
|
*
|
||||||
|
* @param IRQn - Interrupt Numbers
|
||||||
|
*
|
||||||
|
* @return none
|
||||||
|
*/
|
||||||
|
RV_STATIC_INLINE void PFIC_ClearPendingIRQ(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
PFIC->IPRR[((UINT32)(IRQn) >> 5)] = (1 << ((UINT32)(IRQn) & 0x1F));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn PFIC_GetActive
|
||||||
|
*
|
||||||
|
* @brief Get Interrupt Active State
|
||||||
|
*
|
||||||
|
* @param IRQn - Interrupt Numbers
|
||||||
|
*
|
||||||
|
* @return 1 - Interrupt Active
|
||||||
|
* 0 - Interrupt No Active
|
||||||
|
*/
|
||||||
|
RV_STATIC_INLINE UINT32 PFIC_GetActive(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
return((UINT32)((PFIC->IACTR[(UINT32)(IRQn) >> 5] & (1 << ((UINT32)(IRQn) & 0x1F)))?1:0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn PFIC_SetPriority
|
||||||
|
*
|
||||||
|
* @brief Set Interrupt Priority
|
||||||
|
*
|
||||||
|
* @param IRQn - Interrupt Numbers
|
||||||
|
* interrupt nesting enable(PFIC->CFGR bit1 = 0)
|
||||||
|
* priority - bit[7] - Preemption Priority
|
||||||
|
* bit[6:4] - Sub priority
|
||||||
|
* bit[3:0] - Reserve
|
||||||
|
* interrupt nesting disable(PFIC->CFGR bit1 = 1)
|
||||||
|
* priority - bit[7:4] - Sub priority
|
||||||
|
* bit[3:0] - Reserve
|
||||||
|
* @return none
|
||||||
|
*/
|
||||||
|
RV_STATIC_INLINE void PFIC_SetPriority(IRQn_Type IRQn, UINT8 priority)
|
||||||
|
{
|
||||||
|
PFIC->IPRIOR[(UINT32)(IRQn)] = priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __WFI
|
||||||
|
*
|
||||||
|
* @brief Wait for Interrupt
|
||||||
|
*
|
||||||
|
* @return none
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFI(void)
|
||||||
|
{
|
||||||
|
PFIC->SCTLR &= ~(1<<3); // wfi
|
||||||
|
asm volatile ("wfi");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn _SEV
|
||||||
|
*
|
||||||
|
* @brief Set Event
|
||||||
|
*
|
||||||
|
* @return none
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void _SEV(void)
|
||||||
|
{
|
||||||
|
PFIC->SCTLR |= (1<<3)|(1<<5);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn _WFE
|
||||||
|
*
|
||||||
|
* @brief Wait for Events
|
||||||
|
*
|
||||||
|
* @return none
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void _WFE(void)
|
||||||
|
{
|
||||||
|
PFIC->SCTLR |= (1<<3);
|
||||||
|
asm volatile ("wfi");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __WFE
|
||||||
|
*
|
||||||
|
* @brief Wait for Events
|
||||||
|
*
|
||||||
|
* @return none
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFE(void)
|
||||||
|
{
|
||||||
|
_SEV();
|
||||||
|
_WFE();
|
||||||
|
_WFE();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn PFIC_SetFastIRQ
|
||||||
|
*
|
||||||
|
* @brief Set VTF Interrupt
|
||||||
|
*
|
||||||
|
* @param add - VTF interrupt service function base address.
|
||||||
|
* IRQn - Interrupt Numbers
|
||||||
|
* num - VTF Interrupt Numbers
|
||||||
|
*
|
||||||
|
* @return none
|
||||||
|
*/
|
||||||
|
RV_STATIC_INLINE void PFIC_SetFastIRQ(UINT32 addr, IRQn_Type IRQn, UINT8 num){
|
||||||
|
if(num > 3) return ;
|
||||||
|
PFIC->VTFBADDRR = addr;
|
||||||
|
PFIC->VTFADDRR[num] = ((UINT32)IRQn<<24)|(addr&0xfffff);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn PFIC_SystemReset
|
||||||
|
*
|
||||||
|
* @brief Initiate a system reset request
|
||||||
|
*
|
||||||
|
* @return none
|
||||||
|
*/
|
||||||
|
RV_STATIC_INLINE void PFIC_SystemReset(void){
|
||||||
|
PFIC->CFGR = PFIC_KEY3|(1<<7);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn PFIC_HaltPushCfg
|
||||||
|
*
|
||||||
|
* @brief Enable Hardware Stack
|
||||||
|
*
|
||||||
|
* @param NewState - DISABLE or ENABLE
|
||||||
|
|
||||||
|
* @return none
|
||||||
|
*/
|
||||||
|
RV_STATIC_INLINE void PFIC_HaltPushCfg(FunctionalState NewState)
|
||||||
|
{
|
||||||
|
if (NewState != DISABLE)
|
||||||
|
{
|
||||||
|
PFIC->CFGR = PFIC_KEY1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PFIC->CFGR = PFIC_KEY1|(1<<0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn PFIC_INTNestCfg
|
||||||
|
*
|
||||||
|
* @brief Enable Interrupt Nesting
|
||||||
|
*
|
||||||
|
* @param NewState - DISABLE or ENABLE
|
||||||
|
|
||||||
|
* @return none
|
||||||
|
*/
|
||||||
|
RV_STATIC_INLINE void PFIC_INTNestCfg(FunctionalState NewState)
|
||||||
|
{
|
||||||
|
if (NewState != DISABLE)
|
||||||
|
{
|
||||||
|
PFIC->CFGR = PFIC_KEY1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PFIC->CFGR = PFIC_KEY1|(1<<1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __AMOADD_W
|
||||||
|
*
|
||||||
|
* @brief Atomic Add with 32bit value
|
||||||
|
* Atomically ADD 32bit value with value in memory using amoadd.d.
|
||||||
|
* addr - Address pointer to data, address need to be 4byte aligned
|
||||||
|
* value - value to be ADDed
|
||||||
|
*
|
||||||
|
* @return return memory value + add value
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOADD_W(volatile int32_t *addr, int32_t value)
|
||||||
|
{
|
||||||
|
int32_t result;
|
||||||
|
|
||||||
|
__asm volatile ("amoadd.w %0, %2, %1" : \
|
||||||
|
"=r"(result), "+A"(*addr) : "r"(value) : "memory");
|
||||||
|
return *addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __AMOAND_W
|
||||||
|
*
|
||||||
|
* @brief Atomic And with 32bit value
|
||||||
|
* Atomically AND 32bit value with value in memory using amoand.d.
|
||||||
|
* addr - Address pointer to data, address need to be 4byte aligned
|
||||||
|
* value - value to be ANDed
|
||||||
|
*
|
||||||
|
* @return return memory value & and value
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOAND_W(volatile int32_t *addr, int32_t value)
|
||||||
|
{
|
||||||
|
int32_t result;
|
||||||
|
|
||||||
|
__asm volatile ("amoand.w %0, %2, %1" : \
|
||||||
|
"=r"(result), "+A"(*addr) : "r"(value) : "memory");
|
||||||
|
return *addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __AMOMAX_W
|
||||||
|
*
|
||||||
|
* @brief Atomic signed MAX with 32bit value
|
||||||
|
* Atomically signed max compare 32bit value with value in memory using amomax.d.
|
||||||
|
* addr - Address pointer to data, address need to be 4byte aligned
|
||||||
|
* value - value to be compared
|
||||||
|
*
|
||||||
|
* @return the bigger value
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOMAX_W(volatile int32_t *addr, int32_t value)
|
||||||
|
{
|
||||||
|
int32_t result;
|
||||||
|
|
||||||
|
__asm volatile ("amomax.w %0, %2, %1" : \
|
||||||
|
"=r"(result), "+A"(*addr) : "r"(value) : "memory");
|
||||||
|
return *addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __AMOMAXU_W
|
||||||
|
*
|
||||||
|
* @brief Atomic unsigned MAX with 32bit value
|
||||||
|
* Atomically unsigned max compare 32bit value with value in memory using amomaxu.d.
|
||||||
|
* addr - Address pointer to data, address need to be 4byte aligned
|
||||||
|
* value - value to be compared
|
||||||
|
*
|
||||||
|
* @return return the bigger value
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t __AMOMAXU_W(volatile uint32_t *addr, uint32_t value)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__asm volatile ("amomaxu.w %0, %2, %1" : \
|
||||||
|
"=r"(result), "+A"(*addr) : "r"(value) : "memory");
|
||||||
|
return *addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __AMOMIN_W
|
||||||
|
*
|
||||||
|
* @brief Atomic signed MIN with 32bit value
|
||||||
|
* Atomically signed min compare 32bit value with value in memory using amomin.d.
|
||||||
|
* addr - Address pointer to data, address need to be 4byte aligned
|
||||||
|
* value - value to be compared
|
||||||
|
*
|
||||||
|
* @return the smaller value
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOMIN_W(volatile int32_t *addr, int32_t value)
|
||||||
|
{
|
||||||
|
int32_t result;
|
||||||
|
|
||||||
|
__asm volatile ("amomin.w %0, %2, %1" : \
|
||||||
|
"=r"(result), "+A"(*addr) : "r"(value) : "memory");
|
||||||
|
return *addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __AMOMINU_W
|
||||||
|
*
|
||||||
|
* @brief Atomic unsigned MIN with 32bit value
|
||||||
|
* Atomically unsigned min compare 32bit value with value in memory using amominu.d.
|
||||||
|
* addr - Address pointer to data, address need to be 4byte aligned
|
||||||
|
* value - value to be compared
|
||||||
|
*
|
||||||
|
* @return the smaller value
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t __AMOMINU_W(volatile uint32_t *addr, uint32_t value)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__asm volatile ("amominu.w %0, %2, %1" : \
|
||||||
|
"=r"(result), "+A"(*addr) : "r"(value) : "memory");
|
||||||
|
return *addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __AMOOR_W
|
||||||
|
*
|
||||||
|
* @brief Atomic OR with 32bit value
|
||||||
|
* Atomically OR 32bit value with value in memory using amoor.d.
|
||||||
|
* addr - Address pointer to data, address need to be 4byte aligned
|
||||||
|
* value - value to be ORed
|
||||||
|
*
|
||||||
|
* @return return memory value | and value
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOOR_W(volatile int32_t *addr, int32_t value)
|
||||||
|
{
|
||||||
|
int32_t result;
|
||||||
|
|
||||||
|
__asm volatile ("amoor.w %0, %2, %1" : \
|
||||||
|
"=r"(result), "+A"(*addr) : "r"(value) : "memory");
|
||||||
|
return *addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __AMOSWAP_W
|
||||||
|
*
|
||||||
|
* @brief Atomically swap new 32bit value into memory using amoswap.d.
|
||||||
|
* addr - Address pointer to data, address need to be 4byte aligned
|
||||||
|
* newval - New value to be stored into the address
|
||||||
|
*
|
||||||
|
* @return return the original value in memory
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t __AMOSWAP_W(volatile uint32_t *addr, uint32_t newval)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__asm volatile ("amoswap.w %0, %2, %1" : \
|
||||||
|
"=r"(result), "+A"(*addr) : "r"(newval) : "memory");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn __AMOXOR_W
|
||||||
|
*
|
||||||
|
* @brief Atomic XOR with 32bit value
|
||||||
|
* Atomically XOR 32bit value with value in memory using amoxor.d.
|
||||||
|
* addr - Address pointer to data, address need to be 4byte aligned
|
||||||
|
* value - value to be XORed
|
||||||
|
*
|
||||||
|
* @return return memory value ^ and value
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOXOR_W(volatile int32_t *addr, int32_t value)
|
||||||
|
{
|
||||||
|
int32_t result;
|
||||||
|
|
||||||
|
__asm volatile ("amoxor.w %0, %2, %1" : \
|
||||||
|
"=r"(result), "+A"(*addr) : "r"(value) : "memory");
|
||||||
|
return *addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFFFFFFFFFFF)
|
||||||
|
#define SysTick_CTRL_RELOAD_Msk (1 << 8)
|
||||||
|
#define SysTick_CTRL_CLKSOURCE_Msk (1 << 2)
|
||||||
|
#define SysTick_CTRL_TICKINT_Msk (1 << 1)
|
||||||
|
#define SysTick_CTRL_ENABLE_Msk (1 << 0)
|
||||||
|
|
||||||
|
|
||||||
|
RV_STATIC_INLINE uint32_t SysTick_Config( UINT64 ticks )
|
||||||
|
{
|
||||||
|
if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
|
||||||
|
|
||||||
|
SysTick->CMP = ticks - 1; /* set reload register */
|
||||||
|
PFIC_EnableIRQ( SysTick_IRQn );
|
||||||
|
SysTick->CTLR = SysTick_CTRL_RELOAD_Msk |
|
||||||
|
SysTick_CTRL_CLKSOURCE_Msk |
|
||||||
|
SysTick_CTRL_TICKINT_Msk |
|
||||||
|
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
|
||||||
|
return (0); /* Function successful */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Core_Exported_Functions */
|
||||||
|
extern uint32_t __get_MSTATUS(void);
|
||||||
|
extern void __set_MSTATUS(uint32_t value);
|
||||||
|
extern uint32_t __get_MISA(void);
|
||||||
|
extern void __set_MISA(uint32_t value);
|
||||||
|
extern uint32_t __get_MIE(void);
|
||||||
|
extern void __set_MIE(uint32_t value);
|
||||||
|
extern uint32_t __get_MTVEC(void);
|
||||||
|
extern void __set_MTVEC(uint32_t value);
|
||||||
|
extern uint32_t __get_MSCRATCH(void);
|
||||||
|
extern void __set_MSCRATCH(uint32_t value);
|
||||||
|
extern uint32_t __get_MEPC(void);
|
||||||
|
extern void __set_MEPC(uint32_t value);
|
||||||
|
extern uint32_t __get_MCAUSE(void);
|
||||||
|
extern void __set_MCAUSE(uint32_t value);
|
||||||
|
extern uint32_t __get_MTVAL(void);
|
||||||
|
extern void __set_MTVAL(uint32_t value);
|
||||||
|
extern uint32_t __get_MVENDORID(void);
|
||||||
|
extern uint32_t __get_MARCHID(void);
|
||||||
|
extern uint32_t __get_MIMPID(void);
|
||||||
|
extern uint32_t __get_MHARTID(void);
|
||||||
|
extern uint32_t __get_SP(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
{
|
||||||
|
SysTick->CNTFG |= (1 << 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sw_clearpend(void)
|
||||||
|
{
|
||||||
|
SysTick->CNTFG &= ~(1 << 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 / 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
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,48 @@
|
||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : CH56x_bus8.h
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0
|
||||||
|
* Date : 2020/07/31
|
||||||
|
* Description :
|
||||||
|
*********************************************************************************
|
||||||
|
* 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_BUS8_H__
|
||||||
|
#define __CH56x_BUS8_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define ADDR_NONE 0x00
|
||||||
|
#define ADDR_6 0x04
|
||||||
|
#define ADDR_10 0x08
|
||||||
|
#define ADDR_15 0x0c
|
||||||
|
|
||||||
|
#define WIDTH_3 0x00
|
||||||
|
#define WIDTH_5 0x10
|
||||||
|
#define WIDTH_9 0x20
|
||||||
|
#define WIDTH_16 0x30
|
||||||
|
|
||||||
|
#define HOLD_2 0x00
|
||||||
|
#define HOLD_3 0x40
|
||||||
|
|
||||||
|
#define SETUP_2 0x00
|
||||||
|
#define SETUP_3 0x80
|
||||||
|
|
||||||
|
|
||||||
|
void BUS8_Init(UINT8 addroe, UINT8 width, UINT8 hold, UINT8 setup);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __CH56x_BUS8_H__
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : CH56x_clk.h
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0
|
||||||
|
* Date : 2020/07/31
|
||||||
|
* Description :
|
||||||
|
*********************************************************************************
|
||||||
|
* 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_CLK_H__
|
||||||
|
#define __CH56x_CLK_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
CLK_SOURCE_PLL_15MHz = 15, //Power-on default
|
||||||
|
CLK_SOURCE_PLL_30MHz = 30,
|
||||||
|
CLK_SOURCE_PLL_60MHz = 60,
|
||||||
|
CLK_SOURCE_PLL_80MHz = 80,
|
||||||
|
CLK_SOURCE_PLL_96MHz = 96,
|
||||||
|
CLK_SOURCE_PLL_120MHz = 120,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void SystemInit(uint32_t systemclck); /* System clock initialization */
|
||||||
|
UINT32 GetSysClock( void ); /* Get the current system clock */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __CH56x_CLK_H__
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : CH56x_COMM.h
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0
|
||||||
|
* Date : 2020/07/31
|
||||||
|
* Description :
|
||||||
|
*********************************************************************************
|
||||||
|
* 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_COMM_H__
|
||||||
|
#define __CH56x_COMM_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "stdio.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "core_riscv.h"
|
||||||
|
#include "CH56x_sys.h"
|
||||||
|
#include "CH56x_clk.h"
|
||||||
|
#include "CH56x_uart.h"
|
||||||
|
#include "CH56x_gpio.h"
|
||||||
|
#include "CH56x_pwm.h"
|
||||||
|
#include "CH56x_timer.h"
|
||||||
|
#include "CH56x_spi.h"
|
||||||
|
#include "CH56x_hspi.h"
|
||||||
|
#include "CH56x_dvp.h"
|
||||||
|
#include "CH56x_bus8.h"
|
||||||
|
#include "CH56x_ecdc.h"
|
||||||
|
#include "CH56x_pwr.h"
|
||||||
|
#include "CH56x_emmc.h"
|
||||||
|
#include "CH56x_eth.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* UART Printf Definition */
|
||||||
|
#define Debug_UART0 0
|
||||||
|
#define Debug_UART1 1
|
||||||
|
#define Debug_UART2 2
|
||||||
|
#define Debug_UART3 3
|
||||||
|
|
||||||
|
/* SystemCoreClock */
|
||||||
|
#ifndef FREQ_SYS
|
||||||
|
#define FREQ_SYS 80000000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define DelayMs(x) mDelaymS(x)
|
||||||
|
#define DelayUs(x) mDelayuS(x)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __CH56x_COMM_H__
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : CH56x_dvp.c
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0
|
||||||
|
* Date : 2020/07/31
|
||||||
|
* Description :
|
||||||
|
*********************************************************************************
|
||||||
|
* 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_DVP_H__
|
||||||
|
#define __CH56x_DVP_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief DVP Data Mode
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
Video_Mode = 0,
|
||||||
|
JPEG_Mode,
|
||||||
|
}DVP_Data_ModeTypeDef;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief DVP DMA
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
DVP_DMA_Disable = 0,
|
||||||
|
DVP_DMA_Enable,
|
||||||
|
}DVP_DMATypeDef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief DVP FLAG and FIFO Reset
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
DVP_FLAG_FIFO_RESET_Disable = 0,
|
||||||
|
DVP_FLAG_FIFO_RESET_Enable,
|
||||||
|
}DVP_FLAG_FIFO_RESETTypeDef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief DVP RX Reset
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
DVP_RX_RESET_Disable = 0,
|
||||||
|
DVP_RX_RESET_Enable,
|
||||||
|
}DVP_RX_RESETTypeDef;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void DVP_INTCfg( UINT8 s, UINT8 i );
|
||||||
|
void DVP_Mode( UINT8 s, DVP_Data_ModeTypeDef i);
|
||||||
|
void DVP_Cfg( DVP_DMATypeDef s, DVP_FLAG_FIFO_RESETTypeDef i, DVP_RX_RESETTypeDef j);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __CH56x_DVP_H__
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : CH56x_ecdc.h
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0
|
||||||
|
* Date : 2020/07/31
|
||||||
|
* Description :
|
||||||
|
*********************************************************************************
|
||||||
|
* 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_ECDC_H__
|
||||||
|
#define __CH56x_ECDC_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Encryption and decryption mode */
|
||||||
|
#define MODE_SM4_ECB 0
|
||||||
|
#define MODE_AES_ECB 1
|
||||||
|
#define MODE_SM4_CTR 2
|
||||||
|
#define MODE_AES_CTR 3
|
||||||
|
|
||||||
|
/* endian mode */
|
||||||
|
#define MODE_BIG_ENDIAN 1
|
||||||
|
#define MODE_LITTLE_ENDIAN 0
|
||||||
|
|
||||||
|
/* key length */
|
||||||
|
#define KEYLENGTH_128BIT 0
|
||||||
|
#define KEYLENGTH_192BIT 1
|
||||||
|
#define KEYLENGTH_256BIT 2
|
||||||
|
|
||||||
|
/* Encryption and decryption speed */
|
||||||
|
#define ECDCCLK_DISABLE 1
|
||||||
|
#define ECDCCLK_240MHZ 2
|
||||||
|
#define ECDCCLK_160MHZ 3
|
||||||
|
|
||||||
|
/* direction and mode */
|
||||||
|
#define SELFDMA_ENCRY 0x84
|
||||||
|
#define SELFDMA_DECRY 0x8c
|
||||||
|
#define SINGLEREGISTER_ENCRY PERIPHERAL_TO_RAM_ENCRY
|
||||||
|
#define SINGLEREGISTER_DECRY PERIPHERAL_TO_RAM_DECRY
|
||||||
|
#define PERIPHERAL_TO_RAM_ENCRY 0x02
|
||||||
|
#define PERIPHERAL_TO_RAM_DECRY 0x0a
|
||||||
|
#define RAM_TO_PERIPHERAL_ENCRY 0x04
|
||||||
|
#define RAM_TO_PERIPHERAL_DECRY 0x0c
|
||||||
|
|
||||||
|
void ECDC_Init( UINT8 ecdcmode, UINT8 clkmode, UINT8 keylen, PUINT32 pkey, PUINT32 pcount );
|
||||||
|
void ECDC_SetKey( PUINT32 pkey, UINT8 keylen );
|
||||||
|
void ECDC_SetCount( PUINT32 pcount );
|
||||||
|
void ECDC_Excute( UINT8 excutemode, UINT8 endianmode );
|
||||||
|
void ECDC_SingleRegister( PUINT32 pWdatbuff, PUINT32 pRdatbuff );
|
||||||
|
void ECDC_SelfDMA( UINT32 ram_addr, UINT32 ram_len );
|
||||||
|
void ECDC_RloadCount( UINT8 excutemode, UINT8 endianmode, PUINT32 pcount );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __CH56x_ECDC_H__
|
||||||
|
|
|
@ -0,0 +1,147 @@
|
||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : CH56x_emmc.h
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0
|
||||||
|
* Date : 2020/07/31
|
||||||
|
* Description :
|
||||||
|
*********************************************************************************
|
||||||
|
* 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_EMMC_H__
|
||||||
|
#define __CH56x_EMMC_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* CMD code */
|
||||||
|
#define EMMC_CMD0 0 /* rsp:none */
|
||||||
|
#define EMMC_CMD1 1 /* rsp:R3 SEND_OP_COND */
|
||||||
|
#define EMMC_CMD2 2 /* rsp:R2 ALL_SEND_CID */
|
||||||
|
#define EMMC_CMD3 3 /* rsp:R6 SEND_RELATIVE_ADDR */
|
||||||
|
#define EMMC_CMD6 6 /* rsp: */
|
||||||
|
#define EMMC_CMD7 7 /* rsp:Rb1 */
|
||||||
|
#define EMMC_CMD8 8 /* rsp:R7 */
|
||||||
|
#define EMMC_CMD9 9 /* rsp: */
|
||||||
|
#define EMMC_CMD11 11 /* rsp: */
|
||||||
|
#define EMMC_CMD12 12 /* rsp: */
|
||||||
|
#define EMMC_CMD13 13
|
||||||
|
#define EMMC_CMD17 17 /* rsp: READ_SINGLE_BLOCK */
|
||||||
|
#define EMMC_CMD18 18 /* rsp: READ_MULTIPLE_BLOCK */
|
||||||
|
#define EMMC_CMD24 24 /* rsp: WRITE_BLOCK */
|
||||||
|
#define EMMC_CMD25 25 /* rsp: WRITE_MILTIPLE_BLOCK */
|
||||||
|
#define EMMC_CMD41 41 /* rsp: */
|
||||||
|
#define EMMC_CMD55 55 /* rsp: */
|
||||||
|
|
||||||
|
/* operation status */
|
||||||
|
#define CMD_NULL 0x00
|
||||||
|
#define CMD_SUCCESS 0x01
|
||||||
|
#define CMD_FAILED 0x02
|
||||||
|
#define OP_SUCCESS CMD_SUCCESS
|
||||||
|
#define OP_FAILED CMD_FAILED
|
||||||
|
#define OP_INVALID_ADD 0x21 //invalid address
|
||||||
|
|
||||||
|
/* connection status*/
|
||||||
|
#define EMMCDisconnect 0
|
||||||
|
#define EMMCConnect 1
|
||||||
|
|
||||||
|
|
||||||
|
/* operation on EMMC */
|
||||||
|
#define EMMCCardSatus_Idle 0 /* EMMC on free */
|
||||||
|
#define EMMCCardSatus_SendSingleReadCmd 1 /* send command:read single */
|
||||||
|
#define EMMCCardSatus_SendMultReadCmd 2 /* send command:read multiple */
|
||||||
|
#define EMMCCardSatus_SendSingleWriteCmd 3 /* send command:write single */
|
||||||
|
#define EMMCCardSatus_SendMultWriteCmd 4 /* send command:write multiple */
|
||||||
|
#define EMMCCardSatus_SingleReadData 5 /* on reading single */
|
||||||
|
#define EMMCCardSatus_MultReadData 6 /* on reading multiple */
|
||||||
|
#define EMMCCardSatus_SingleWriteData 7 /* on writing single */
|
||||||
|
#define EMMCCardSatus_MultWriteData 8 /* on writing multiple */
|
||||||
|
#define EMMCCardSatus_SingleReadComp 9 /* read single done */
|
||||||
|
#define EMMCCardSatus_MultReadComp 10 /* read multiple done */
|
||||||
|
#define EMMCCardSatus_SingleWriteComp 11 /* write single done */
|
||||||
|
#define EMMCCardSatus_MultWriteComp 12 /* write multiple done */
|
||||||
|
|
||||||
|
/* EMMC type */
|
||||||
|
#define EMMCIO_CAPACITY_SD_CARD_V1_1 0
|
||||||
|
#define EMMCIO_CAPACITY_SD_CARD_V2_0 1
|
||||||
|
#define EMMCIO_HIGH_CAPACITY_SD_CARD 2
|
||||||
|
/* EMMC useful voltage type */
|
||||||
|
#define EMMCCardVolt_3_3 (1<<0)
|
||||||
|
#define EMMCCardVolt_1_8 (1<<1)
|
||||||
|
|
||||||
|
#define EMMCPLUGIN (1<<12)
|
||||||
|
|
||||||
|
/* EMMC information */
|
||||||
|
typedef struct _EMMC_PARAMETER{
|
||||||
|
UINT8 EMMCLinkSatus; // connecting type
|
||||||
|
UINT8 EMMCCardSatus; // EMMC operation status
|
||||||
|
UINT8 EMMCType; // EMMC type
|
||||||
|
UINT8 EMMCVoltageMode; // EMMC useful voltage type bit0:3.3v bit1:1.8v
|
||||||
|
UINT32 EMMC_CID[4];
|
||||||
|
UINT32 EMMC_CSD[4];
|
||||||
|
UINT16 EMMC_RCA; // relative address
|
||||||
|
UINT16 EMMCSecSize; // single section capacity
|
||||||
|
UINT32 EMMCSecNum; // capacity of section
|
||||||
|
|
||||||
|
UINT8 EMMCOpErr; // latest error status
|
||||||
|
|
||||||
|
}EMMC_PARAMETER, *PSD_PARAMETER;
|
||||||
|
|
||||||
|
|
||||||
|
//#define RESP_TYPE_48 (0<<8)
|
||||||
|
#define RESP_TYPE_136 (1<<8)
|
||||||
|
#define RESP_TYPE_48 (2<<8)
|
||||||
|
#define RESP_TYPE_R1b (3<<8)
|
||||||
|
|
||||||
|
|
||||||
|
/* EMMC CLK SET */
|
||||||
|
#define EMMCCLK_48 10
|
||||||
|
#define EMMCCLK_60 8
|
||||||
|
#define EMMCCLK_80 6
|
||||||
|
#define EMMCCLK_96 5
|
||||||
|
#define LOWEMMCCLK 0x1F
|
||||||
|
#define DEFAULTSDCLK EMMCCLK_48
|
||||||
|
#define HIGHEMMCCLK EMMCCLK_96
|
||||||
|
|
||||||
|
/* EMMCIO power */
|
||||||
|
#define EMMCIOSetPower_3_3 (R32_PA_CLR |= (1<<3)) /* PA3=0 SDIO power = 3.3v */
|
||||||
|
#define EMMCIOSetPower_1_8 (R32_PA_OUT |= (1<<3)) /* PA3=1 SDIO EMMC*/
|
||||||
|
|
||||||
|
|
||||||
|
#define EMMCSendCmd(a, b) {R32_EMMC_ARGUMENT = a; R16_EMMC_CMD_SET = b;}
|
||||||
|
#define EMMCDat0Sta (R32_EMMC_STATUS&(1<<17)) /* EMMC data0 status */
|
||||||
|
|
||||||
|
extern UINT8 EMMCIO0Init( void );
|
||||||
|
extern UINT8 CheckCMDComp( PSD_PARAMETER pEMMCPara );
|
||||||
|
extern void EMMCResetIdle( PSD_PARAMETER pEMMCPara );
|
||||||
|
extern UINT8 EMMCReadOCR( PSD_PARAMETER pEMMCPara);
|
||||||
|
extern UINT8 EMMCReadCID( PSD_PARAMETER pEMMCPara );
|
||||||
|
extern UINT8 EMMCSetRCA( PSD_PARAMETER pEMMCPara );
|
||||||
|
extern UINT8 EMMCReadCSD( PSD_PARAMETER pEMMCPara );
|
||||||
|
extern UINT8 SelectEMMCCard(PSD_PARAMETER pEMMCPara);
|
||||||
|
extern UINT8 ReadEMMCStatus(PSD_PARAMETER pEMMCPara);
|
||||||
|
extern UINT8 EMMCSetBusWidth(PSD_PARAMETER pEMMCPara, UINT8 bus_mode);
|
||||||
|
extern UINT8 EMMCSetHighSpeed(PSD_PARAMETER pEMMCPara);
|
||||||
|
extern UINT8 EMMCCardConfig( PSD_PARAMETER pEMMCPara );
|
||||||
|
extern UINT8 EMMCIOTransErrorDeal( PSD_PARAMETER pEMMCPara );
|
||||||
|
extern UINT8 EMMCCardReadEXCSD( PSD_PARAMETER pEMMCPara, PUINT8 pRdatbuf );
|
||||||
|
extern UINT8 AES_EMMCWriteMulSec( PSD_PARAMETER pEMMCPara, PUINT32 pReqnum, PUINT32 pWdatbuf, UINT32 Lbaaddr, UINT8 excutemode, UINT8 endianmode, PUINT32 pcount);
|
||||||
|
extern UINT8 AES_EMMCReadMulSec( PSD_PARAMETER pEMMCPara, PUINT32 pReqnum, PUINT32 pRdatbuf, UINT32 Lbaaddr, UINT8 excutemode, UINT8 endianmode, PUINT32 pcount);
|
||||||
|
UINT8 EMMCCardReadOneSec( PSD_PARAMETER pEMMCPara, PUINT8 pRdatbuf, UINT32 Lbaaddr );
|
||||||
|
UINT8 EMMCCardReadMulSec( PSD_PARAMETER pEMMCPara, PUINT16 pReqnum, PUINT8 pRdatbuf, UINT32 Lbaaddr );
|
||||||
|
UINT8 EMMCCardWriteMulSec( PSD_PARAMETER pEMMCPara, PUINT16 pReqnum, PUINT8 pWdatbuf, UINT32 Lbaaddr );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif //__CH56X_EMMC_H__
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,144 @@
|
||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : CH56x_gpio.h
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0
|
||||||
|
* Date : 2020/07/31
|
||||||
|
* Description :
|
||||||
|
*********************************************************************************
|
||||||
|
* 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_GPIO_H__
|
||||||
|
#define __CH56x_GPIO_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define GPIO_Pin_0 (0x00000001) /*!< Pin 0 selected */
|
||||||
|
#define GPIO_Pin_1 (0x00000002) /*!< Pin 1 selected */
|
||||||
|
#define GPIO_Pin_2 (0x00000004) /*!< Pin 2 selected */
|
||||||
|
#define GPIO_Pin_3 (0x00000008) /*!< Pin 3 selected */
|
||||||
|
#define GPIO_Pin_4 (0x00000010) /*!< Pin 4 selected */
|
||||||
|
#define GPIO_Pin_5 (0x00000020) /*!< Pin 5 selected */
|
||||||
|
#define GPIO_Pin_6 (0x00000040) /*!< Pin 6 selected */
|
||||||
|
#define GPIO_Pin_7 (0x00000080) /*!< Pin 7 selected */
|
||||||
|
#define GPIO_Pin_8 (0x00000100) /*!< Pin 8 selected */
|
||||||
|
#define GPIO_Pin_9 (0x00000200) /*!< Pin 9 selected */
|
||||||
|
#define GPIO_Pin_10 (0x00000400) /*!< Pin 10 selected */
|
||||||
|
#define GPIO_Pin_11 (0x00000800) /*!< Pin 11 selected */
|
||||||
|
#define GPIO_Pin_12 (0x00001000) /*!< Pin 12 selected */
|
||||||
|
#define GPIO_Pin_13 (0x00002000) /*!< Pin 13 selected */
|
||||||
|
#define GPIO_Pin_14 (0x00004000) /*!< Pin 14 selected */
|
||||||
|
#define GPIO_Pin_15 (0x00008000) /*!< Pin 15 selected */
|
||||||
|
#define GPIO_Pin_16 (0x00010000) /*!< Pin 16 selected */
|
||||||
|
#define GPIO_Pin_17 (0x00020000) /*!< Pin 17 selected */
|
||||||
|
#define GPIO_Pin_18 (0x00040000) /*!< Pin 18 selected */
|
||||||
|
#define GPIO_Pin_19 (0x00080000) /*!< Pin 19 selected */
|
||||||
|
#define GPIO_Pin_20 (0x00100000) /*!< Pin 20 selected */
|
||||||
|
#define GPIO_Pin_21 (0x00200000) /*!< Pin 21 selected */
|
||||||
|
#define GPIO_Pin_22 (0x00400000) /*!< Pin 22 selected */
|
||||||
|
#define GPIO_Pin_23 (0x00800000) /*!< Pin 23 selected */
|
||||||
|
#define GPIO_Pin_24 (0x01000000) /*!< PinB23 selected */
|
||||||
|
#define GPIO_Pin_All (0xFFFFFFFF) /*!< All pins selected */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief GPIO mode structure configuration
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GPIO_ModeIN_Floating, //floating input
|
||||||
|
GPIO_ModeIN_PU_NSMT,
|
||||||
|
GPIO_ModeIN_PD_NSMT,
|
||||||
|
GPIO_ModeIN_PU_SMT,
|
||||||
|
GPIO_ModeIN_PD_SMT,
|
||||||
|
GPIO_Slowascent_PP_8mA,
|
||||||
|
GPIO_Slowascent_PP_16mA,
|
||||||
|
GPIO_Highspeed_PP_8mA,
|
||||||
|
GPIO_Highspeed_PP_16mA,
|
||||||
|
GPIO_ModeOut_OP_8mA,
|
||||||
|
GPIO_ModeOut_OP_16mA,
|
||||||
|
}GPIOModeTypeDef;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief GPIO interrupt structure configuration
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GPIO_ITMode_LowLevel, //Low level trigger
|
||||||
|
GPIO_ITMode_HighLevel, //High level trigger
|
||||||
|
GPIO_ITMode_FallEdge, //Falling edge trigger
|
||||||
|
GPIO_ITMode_RiseEdge, //Rising edge trigger
|
||||||
|
|
||||||
|
}GPIOITModeTpDef;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief GPIO MCO structure configuration
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
MCO_125 = 0,
|
||||||
|
MCO_25 = 4,
|
||||||
|
MCO_2d5 = 0xC,
|
||||||
|
}MCOMode;
|
||||||
|
|
||||||
|
void GPIOA_ModeCfg( UINT32 pin, GPIOModeTypeDef mode ); /* GPIOA port pin mode configuration */
|
||||||
|
void GPIOB_ModeCfg( UINT32 pin, GPIOModeTypeDef mode ); /* GPIOB port pin mode configuration */
|
||||||
|
#define GPIOA_ResetBits( pin ) (R32_PA_CLR |= pin) /* GPIOA port pin output set low */
|
||||||
|
#define GPIOA_SetBits( pin ) (R32_PA_OUT |= pin) /* GPIOA port pin output set high */
|
||||||
|
#define GPIOB_ResetBits( pin ) (R32_PB_CLR |= pin) /* GPIOB port pin output set low */
|
||||||
|
#define GPIOB_SetBits( pin ) (R32_PB_OUT |= pin) /* GPIOB port pin output set high */
|
||||||
|
#define GPIOA_InverseBits( pin ) (R32_PA_OUT ^= pin) /* GPIOA port pin output level flip */
|
||||||
|
#define GPIOB_InverseBits( pin ) (R32_PB_OUT ^= pin) /* GPIOB port pin output level flip */
|
||||||
|
#define GPIOA_ReadPort() (R32_PA_PIN) /* The 32-bit data returned by the GPIOA port, the lower 16 bits are valid */
|
||||||
|
#define GPIOB_ReadPort() (R32_PB_PIN) /* The 32-bit data returned by the GPIOB port, the lower 24 bits are valid */
|
||||||
|
#define GPIOA_ReadPortPin( pin ) (R32_PA_PIN&pin) /* GPIOA port pin status, 0-pin low level, (!0)-pin high level */
|
||||||
|
#define GPIOB_ReadPortPin( pin ) (R32_PB_PIN&pin) /* GPIOB port pin status, 0-pin low level, (!0)-pin high level */
|
||||||
|
|
||||||
|
void GPIOA_ITModeCfg( UINT32 pin, GPIOITModeTpDef mode ); /* GPIOA pin interrupt mode configuration */
|
||||||
|
void GPIOB_ITModeCfg( UINT32 pin, GPIOITModeTpDef mode ); /* GPIOB pin interrupt mode configuration */
|
||||||
|
#define GPIOA_ReadITFlagPort() (R8_GPIO_INT_FLAG) /* Read GPIOA port interrupt flag status */
|
||||||
|
#define GPIOB_ReadITFlagPort() (R8_GPIO_INT_FLAG) /* Read GPIOB port interrupt flag status */
|
||||||
|
|
||||||
|
/*************************************Read Interrupt Bit Flag************************************/
|
||||||
|
#define GPIOA_2_ReadITFlagBit( ) (R8_GPIO_INT_FLAG & 0x01) /* Read GPIOA port pin interrupt flag status */
|
||||||
|
#define GPIOA_3_ReadITFlagBit( ) (R8_GPIO_INT_FLAG & 0x02)
|
||||||
|
#define GPIOA_4_ReadITFlagBit( ) (R8_GPIO_INT_FLAG & 0x04)
|
||||||
|
|
||||||
|
#define GPIOB_3_ReadITFlagBit( ) (R8_GPIO_INT_FLAG & 0x08) /* Read GPIOB port pin interrupt flag status */
|
||||||
|
#define GPIOB_4_ReadITFlagBit( ) (R8_GPIO_INT_FLAG & 0x10)
|
||||||
|
#define GPIOB_11_ReadITFlagBit( ) (R8_GPIO_INT_FLAG & 0x20)
|
||||||
|
#define GPIOB_12_ReadITFlagBit( ) (R8_GPIO_INT_FLAG & 0x40)
|
||||||
|
#define GPIOB_15_ReadITFlagBit( ) (R8_GPIO_INT_FLAG & 0x80)
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************Clear Interrupt Bit Flag************************************/
|
||||||
|
#define GPIOA_2_ClearITFlagBit( ) (R8_GPIO_INT_FLAG = 0x01) /* Clear the GPIOA port pin interrupt flag status */
|
||||||
|
#define GPIOA_3_ClearITFlagBit( ) (R8_GPIO_INT_FLAG = 0x02)
|
||||||
|
#define GPIOA_4_ClearITFlagBit( ) (R8_GPIO_INT_FLAG = 0x04)
|
||||||
|
|
||||||
|
#define GPIOB_3_ClearITFlagBit( ) (R8_GPIO_INT_FLAG = 0x08) /* Clear the GPIOB port pin interrupt flag status */
|
||||||
|
#define GPIOB_4_ClearITFlagBit( ) (R8_GPIO_INT_FLAG = 0x10)
|
||||||
|
#define GPIOB_11_ClearITFlagBit( ) (R8_GPIO_INT_FLAG = 0x20)
|
||||||
|
#define GPIOB_12_ClearITFlagBit( ) (R8_GPIO_INT_FLAG = 0x40)
|
||||||
|
#define GPIOB_15_ClearITFlagBit( ) (R8_GPIO_INT_FLAG = 0x80)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void GPIOPinRemap( UINT8 s, UINT16 perph ); /* Peripheral Function Pin Mapping */
|
||||||
|
void GPIOMco( UINT8 s, UINT16 freq ); /* MCO function */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __CH56x_GPIO_H__
|
|
@ -0,0 +1,43 @@
|
||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : CH56x_hspi.h
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0
|
||||||
|
* Date : 2020/07/31
|
||||||
|
* Description :
|
||||||
|
*********************************************************************************
|
||||||
|
* 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_HSPI_H__
|
||||||
|
#define __CH56x_HSPI_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief HSPI Mode
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
DOWN_Mode = 0,
|
||||||
|
UP_Mode,
|
||||||
|
}HSPI_ModeTypeDef;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void HSPI_Mode( UINT8 s, HSPI_ModeTypeDef i);
|
||||||
|
void HSPI_INTCfg( UINT8 s, UINT8 i );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __CH56x_HSPI_H__
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : CH56x_pwm.h
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0
|
||||||
|
* Date : 2020/07/31
|
||||||
|
* Description :
|
||||||
|
*********************************************************************************
|
||||||
|
* 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_PWM_H__
|
||||||
|
#define __CH56x_PWM_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief channel of PWM define
|
||||||
|
*/
|
||||||
|
#define CH_PWM0 0x01 // PWM0 channel
|
||||||
|
#define CH_PWM1 0x02 // PWM1 channel
|
||||||
|
#define CH_PWM2 0x04 // PWM2 channel
|
||||||
|
#define CH_PWM3 0x08 // PWM3 channel
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief channel of PWM define
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
High_Level = 0, //Default low level, high level is active
|
||||||
|
Low_Level, //Default high level, low level active
|
||||||
|
}PWMX_PolarTypeDef;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configuration PWM0_3 Cycle size
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
PWMX_Cycle_256 = 0, //256 PWMX cycles
|
||||||
|
PWMX_Cycle_255, //255 PWMX cycles
|
||||||
|
|
||||||
|
}PWMX_CycleTypeDef;
|
||||||
|
|
||||||
|
|
||||||
|
#define PWMX_CLKCfg( d ) (R8_PWM_CLOCK_DIV=d) //PWM Reference Clock Configuration
|
||||||
|
void PWMX_CycleCfg( PWMX_CycleTypeDef cyc ); //PWM output waveform period configuration
|
||||||
|
|
||||||
|
#define PWM0_ActDataWidth( d ) (R8_PWM0_DATA = d) //PWM0 effective data pulse width
|
||||||
|
#define PWM1_ActDataWidth( d ) (R8_PWM1_DATA = d) //PWM1 effective data pulse width
|
||||||
|
#define PWM2_ActDataWidth( d ) (R8_PWM2_DATA = d) //PWM2 effective data pulse width
|
||||||
|
#define PWM3_ActDataWidth( d ) (R8_PWM3_DATA = d) //PWM3 effective data pulse width
|
||||||
|
|
||||||
|
//Duty cycle = data valid width/waveform period
|
||||||
|
void PWMX_ACTOUT( UINT8 ch, UINT8 da, PWMX_PolarTypeDef pr, UINT8 s); //PWM0-3 output waveform configuration
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __CH56x_PWM_H__
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : CH56x_pwr.h
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0
|
||||||
|
* Date : 2020/07/31
|
||||||
|
* Description :
|
||||||
|
*********************************************************************************
|
||||||
|
* 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_PWR_H__
|
||||||
|
#define __CH56x_PWR_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Peripher CLK control bit define
|
||||||
|
*/
|
||||||
|
#define BIT_SLP_CLK_TMR0 RB_SLP_CLK_TMR0 /*!< TMR0 peripher clk bit */
|
||||||
|
#define BIT_SLP_CLK_TMR1 RB_SLP_CLK_TMR1 /*!< TMR1 peripher clk bit */
|
||||||
|
#define BIT_SLP_CLK_TMR2 RB_SLP_CLK_TMR2 /*!< TMR2 peripher clk bit */
|
||||||
|
#define BIT_SLP_CLK_PWMX RB_SLP_CLK_PWMX /*!< PWMX peripher clk bit */
|
||||||
|
#define BIT_SLP_CLK_UART0 RB_SLP_CLK_UART0 /*!< UART0 peripher clk bit */
|
||||||
|
#define BIT_SLP_CLK_UART1 RB_SLP_CLK_UART1 /*!< UART1 peripher clk bit */
|
||||||
|
#define BIT_SLP_CLK_UART2 RB_SLP_CLK_UART2 /*!< UART2 peripher clk bit */
|
||||||
|
#define BIT_SLP_CLK_UART3 RB_SLP_CLK_UART3 /*!< UART3 peripher clk bit */
|
||||||
|
#define BIT_SLP_CLK_SPI0 RB_SLP_CLK_SPI0 /*!< SPI0 peripher clk bit */
|
||||||
|
#define BIT_SLP_CLK_SPI1 RB_SLP_CLK_SPI1 /*!< SPI1 peripher clk bit */
|
||||||
|
#define BIT_SLP_CLK_EMMC RB_SLP_CLK_EMMC /*!< EMMC peripher clk bit */
|
||||||
|
#define BIT_SLP_CLK_HSPI RB_SLP_CLK_HSPI /*!< HSPI peripher clk bit */
|
||||||
|
#define BIT_SLP_CLK_USBHS RB_SLP_CLK_USBHS /*!< USBHS peripher clk bit */
|
||||||
|
#define BIT_SLP_CLK_USBSS RB_SLP_CLK_USBSS /*!< USBSS peripher clk bit */
|
||||||
|
#define BIT_SLP_CLK_SERD RB_SLP_CLK_SERD /*!< SERD peripher clk bit */
|
||||||
|
#define BIT_SLP_CLK_DVP RB_SLP_CLK_DVP /*!< DVP peripher clk bit */
|
||||||
|
#define BIT_SLP_CLK_ETH RB_SLP_CLK_ETH /*!< ETH peripher clk bit */
|
||||||
|
#define BIT_SLP_CLK_ECDC RB_SLP_CLK_ECDC /*!< ECDC peripher clk bit */
|
||||||
|
|
||||||
|
|
||||||
|
void PWR_PeriphClkCfg( UINT8 s, UINT16 perph ); /* Peripheral Clock Control Bits */
|
||||||
|
void PWR_PeriphWakeUpCfg( UINT8 s, UINT16 perph ); /* Sleep wakeup source configuration */
|
||||||
|
void LowPower_Idle( void ); /* Low power consumption - IDLE mode Execute WFI*/
|
||||||
|
void LowPower_Idle_WFE( void ); /* Low power consumption - IDLE mode Execute WFE*/
|
||||||
|
void LowPower_Halt( void ); /* Low power consumption - Halt mode Execute WFI*/
|
||||||
|
void LowPower_Halt_WFE( void ); /* Low power consumption - Halt mode Execute WFE*/
|
||||||
|
void LowPower_Sleep( void ); /* Low power consumption - Sleep mode Execute WFI*/
|
||||||
|
void LowPower_Sleep_WFE( void ); /* Low power consumption - Sleep mode Execute WFE*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __CH56x_PWR_H__
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : CH56x_spi.h
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0
|
||||||
|
* Date : 2020/07/31
|
||||||
|
* Description :
|
||||||
|
*********************************************************************************
|
||||||
|
* 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_SPI_H__
|
||||||
|
#define __CH56x_SPI_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SPI0 interrupt bit define
|
||||||
|
*/
|
||||||
|
#define SPI0_IT_FST_BYTE RB_SPI_IE_FST_BYTE
|
||||||
|
#define SPI0_IT_FIFO_OV RB_SPI_IE_FIFO_OV
|
||||||
|
#define SPI0_IT_DMA_END RB_SPI_IE_DMA_END
|
||||||
|
#define SPI0_IT_FIFO_HF RB_SPI_IE_FIFO_HF
|
||||||
|
#define SPI0_IT_BYTE_END RB_SPI_IE_BYTE_END
|
||||||
|
#define SPI0_IT_CNT_END RB_SPI_IE_CNT_END
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configuration data mode
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
Mode0_LowBitINFront = 0,
|
||||||
|
Mode0_HighBitINFront,
|
||||||
|
Mode3_LowBitINFront,
|
||||||
|
Mode3_HighBitINFront,
|
||||||
|
}ModeBitOrderTypeDef;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configuration SPI slave mode
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
Mode_DataStream = 0,
|
||||||
|
Mose_FirstCmd,
|
||||||
|
}Slave_ModeTypeDef;
|
||||||
|
|
||||||
|
|
||||||
|
/**************** SPI0 */
|
||||||
|
void SPI0_MasterDefInit( void );
|
||||||
|
void SPI0_DataMode( ModeBitOrderTypeDef m );
|
||||||
|
|
||||||
|
void SPI0_MasterSendByte( UINT8 d );
|
||||||
|
UINT8 SPI0_MasterRecvByte( void );
|
||||||
|
|
||||||
|
void SPI0_MasterTrans( UINT8 *pbuf, UINT16 len );
|
||||||
|
void SPI0_MasterRecv( UINT8 *pbuf, UINT16 len );
|
||||||
|
|
||||||
|
void SPI0_MasterDMATrans( PUINT8 pbuf, UINT16 len);
|
||||||
|
void SPI0_MasterDMARecv( PUINT8 pbuf, UINT16 len);
|
||||||
|
|
||||||
|
|
||||||
|
void SPI0_SlaveInit( void );
|
||||||
|
#define SetFirst0Data(d) (R8_SPI0_SLAVE_PRE = d)
|
||||||
|
void SPI0_SlaveSendByte( UINT8 d );
|
||||||
|
UINT8 SPI0_SlaveRecvByte( void );
|
||||||
|
|
||||||
|
void SPI0_SlaveTrans( UINT8 *pbuf, UINT16 len );
|
||||||
|
void SPI0_SlaveRecv( PUINT8 pbuf, UINT16 len );
|
||||||
|
|
||||||
|
// refer to SPI0 interrupt bit define
|
||||||
|
#define SPI0_ITCfg(s,f) ((s)?(R8_SPI0_INTER_EN|=f):(R8_SPI0_INTER_EN&=~f))
|
||||||
|
#define SPI0_GetITFlag(f) (R8_SPI0_INT_FLAG&f)
|
||||||
|
#define SPI0_ClearITFlag(f) (R8_SPI0_INT_FLAG = f)
|
||||||
|
|
||||||
|
|
||||||
|
/**************** SPI1 */
|
||||||
|
void SPI1_MasterDefInit( void );
|
||||||
|
void SPI1_DataMode( ModeBitOrderTypeDef m );
|
||||||
|
|
||||||
|
void SPI1_MasterSendByte( UINT8 d );
|
||||||
|
UINT8 SPI1_MasterRecvByte( void );
|
||||||
|
|
||||||
|
void SPI1_MasterTrans( UINT8 *pbuf, UINT16 len );
|
||||||
|
void SPI1_MasterRecv( UINT8 *pbuf, UINT16 len );
|
||||||
|
|
||||||
|
void SPI1_MasterDMATrans( PUINT8 pbuf, UINT16 len);
|
||||||
|
void SPI1_MasterDMARecv( PUINT8 pbuf, UINT16 len);
|
||||||
|
|
||||||
|
void SPI1_SlaveInit( void );
|
||||||
|
#define SetFirst1Data(d) (R8_SPI1_SLAVE_PRE = d)
|
||||||
|
void SPI1_SlaveSendByte( UINT8 d );
|
||||||
|
UINT8 SPI1_SlaveRecvByte( void );
|
||||||
|
|
||||||
|
void SPI1_SlaveTrans( UINT8 *pbuf, UINT16 len );
|
||||||
|
void SPI1_SlaveRecv( PUINT8 pbuf, UINT16 len );
|
||||||
|
|
||||||
|
// refer to SPI1 interrupt bit define
|
||||||
|
#define SPI1_ITCfg(s,f) ((s)?(R8_SPI1_INTER_EN|=f):(R8_SPI1_INTER_EN&=~f))
|
||||||
|
#define SPI1_GetITFlag(f) (R8_SPI1_INT_FLAG&f)
|
||||||
|
#define SPI1_ClearITFlag(f) (R8_SPI1_INT_FLAG = f)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __CH56x_SPI_H__
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : CH56x_sys.h
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0
|
||||||
|
* Date : 2020/07/31
|
||||||
|
* Description : This file contains all the functions prototypes for
|
||||||
|
* SystemCoreClock, UART Printf , Delay functions .
|
||||||
|
*********************************************************************************
|
||||||
|
* 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_SYS_H__
|
||||||
|
#define __CH56x_SYS_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "CH56xSFR.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SYSTEM Information State
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
INFO_RESET_EN = 2, // RST# Whether the external manual reset input function is enabled
|
||||||
|
INFO_BOOT_EN, // Whether the system boot program BootLoader is enabled
|
||||||
|
INFO_DEBUG_EN, // Whether the system simulation debugging interface is enabled
|
||||||
|
INFO_LOADER, // Whether the current system is in the Bootloader area
|
||||||
|
}SYS_InfoStaTypeDef;
|
||||||
|
|
||||||
|
|
||||||
|
#define SYS_GetChipID() R8_CHIP_ID /* Get the chip ID class, generally a fixed value */
|
||||||
|
#define SYS_GetAccessID() R8_SAFE_ACCESS_ID /* Get the security access ID, usually a fixed value */
|
||||||
|
UINT8 SYS_GetInfoSta( SYS_InfoStaTypeDef i ); /* Get the current system information status */
|
||||||
|
|
||||||
|
void Delay_Init(uint32_t systemclck);
|
||||||
|
void mDelayuS(uint32_t n);
|
||||||
|
void mDelaymS(uint32_t n);
|
||||||
|
|
||||||
|
//refer to SYS_ResetStaTypeDef
|
||||||
|
#define SYS_GetLastResetSta() (R8_RST_BOOT_STAT&RB_RESET_FLAG) /* Get the last reset status of the system */
|
||||||
|
void SYS_ResetExecute( void ); /* Perform a system software reset */
|
||||||
|
#define SYS_ResetKeepBuf( d ) (R8_GLOB_RESET_KEEP = d) /* Not affected by manual reset, software reset, watchdog reset or normal wake-up reset */
|
||||||
|
|
||||||
|
//WWDG
|
||||||
|
#define WWDG_SetCounter( c ) (R8_WDOG_COUNT = c) /* Load the initial value of the watchdog count, incremental */
|
||||||
|
void WWDG_ITCfg( UINT8 s ); /* Watchdog overflow interrupt enable */
|
||||||
|
void WWDG_ResetCfg( UINT8 s ); /* Watchdog time-out reset enable */
|
||||||
|
#define WWDG_GetFlowFlag() (R8_RST_WDOG_CTRL&RB_WDOG_INT_FLAG) /* Get the current watchdog timer overflow flag */
|
||||||
|
void WWDG_ClearFlag(void); /* Clear watchdog interrupt flag, reload count value can also be cleared */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __CH56x_SYS_H__
|
||||||
|
|
|
@ -0,0 +1,155 @@
|
||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : CH56x_timer.ch
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0
|
||||||
|
* Date : 2020/07/31
|
||||||
|
* Description :
|
||||||
|
*********************************************************************************
|
||||||
|
* 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_TIMER_H__
|
||||||
|
#define __CH56x_TIMER_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Pulse Width Modulation Effective Output Words
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
PWM_Times_1 = 0, // PWM effective output repeats 1 times
|
||||||
|
PWM_Times_4 = 1, // PWM effective output repeats 4 times
|
||||||
|
PWM_Times_8 = 2, // PWM effective output repeats 8 times
|
||||||
|
PWM_Times_16 = 3, // PWM effective output repeats 16 times
|
||||||
|
}PWM_RepeatTsTypeDef;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Input Capture Edge Mode
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
CAP_NULL = 0, // not capture
|
||||||
|
Edge_To_Edge = 1, // between any edge
|
||||||
|
FallEdge_To_FallEdge = 2, // falling edge to falling edge
|
||||||
|
RiseEdge_To_RiseEdge = 3, // rising edge to rising edge
|
||||||
|
}CapModeTypeDef;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Direct access memory loop mode
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
Mode_Single = 0, // single mode
|
||||||
|
Mode_LOOP = 1, // cycle mode
|
||||||
|
}DMAModeTypeDef;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PWM output polarity
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
high_on_low = 0, // Default low level, high level is active
|
||||||
|
low_on_high = 1, // Default high level, low level active
|
||||||
|
}PWM_PolarTypeDef;
|
||||||
|
|
||||||
|
|
||||||
|
/****************** TMR0 */
|
||||||
|
// Timing and counting
|
||||||
|
void TMR0_TimerInit( UINT32 t ); /* Timing function initialization */
|
||||||
|
void TMR0_EXTSignalCounterInit( UINT32 c ); /* External signal counting function initialization */
|
||||||
|
#define TMR0_GetCurrentCount() R32_TMR0_COUNT /* Get the current count value, 67108864 */
|
||||||
|
|
||||||
|
// Pulse Width Modulation Function
|
||||||
|
#define TMR0_PWMCycleCfg( cyc ) (R32_TMR0_CNT_END=cyc) /* PWM0 channel output waveform period configuration, maximum 67108864 */
|
||||||
|
void TMR0_PWMInit( PWM_PolarTypeDef pr, PWM_RepeatTsTypeDef ts ); /* PWM0 output initialization */
|
||||||
|
#define TMR0_PWMActDataWidth( d ) (R32_TMR0_FIFO = d) /* PWM0 effective data pulse width, maximum 67108864 */
|
||||||
|
|
||||||
|
// Catch pulse width
|
||||||
|
#define TMR0_CAPTimeoutCfg( cyc ) (R32_TMR0_CNT_END=cyc) /* CAP0 capture level timeout configuration, maximum 33554432 */
|
||||||
|
void TMR0_CapInit( CapModeTypeDef cap ); /* External signal capture function initialization */
|
||||||
|
#define TMR0_CAPGetData() R32_TMR0_FIFO /* Get pulse data */
|
||||||
|
#define TMR0_CAPDataCounter() R8_TMR0_FIFO_COUNT /* Get the number of currently captured data */
|
||||||
|
|
||||||
|
#define TMR0_Disable() (R8_TMR0_CTRL_MOD &= ~RB_TMR_COUNT_EN) /* Close TMR0 */
|
||||||
|
// refer to TMR0 interrupt bit define
|
||||||
|
#define TMR0_ITCfg(s,f) ((s)?(R8_TMR0_INTER_EN|=f):(R8_TMR0_INTER_EN&=~f)) /* TMR0 corresponding interrupt bit on and off */
|
||||||
|
// refer to TMR0 interrupt bit define
|
||||||
|
#define TMR0_ClearITFlag(f) (R8_TMR0_INT_FLAG = f) /* Clear interrupt flag */
|
||||||
|
#define TMR0_GetITFlag(f) (R8_TMR0_INT_FLAG&f) /* Query interrupt flag status */
|
||||||
|
|
||||||
|
|
||||||
|
/****************** TMR1 */
|
||||||
|
// Timing and counting
|
||||||
|
void TMR1_TimerInit( UINT32 t ); /* Timing function initialization */
|
||||||
|
void TMR1_EXTSignalCounterInit( UINT32 c ); /* External signal counting function initialization */
|
||||||
|
#define TMR1_GetCurrentCount() R32_TMR1_COUNT /* Get the current count value, 67108864 */
|
||||||
|
|
||||||
|
// Pulse Width Modulation Function
|
||||||
|
#define TMR1_PWMCycleCfg( cyc ) (R32_TMR1_CNT_END=cyc) /* PWM1 channel output waveform period configuration, maximum 67108864 */
|
||||||
|
void TMR1_PWMInit( PWM_PolarTypeDef pr, PWM_RepeatTsTypeDef ts ); /* PWM1 output initialization */
|
||||||
|
#define TMR1_PWMActDataWidth( d ) (R32_TMR1_FIFO = d) /* PWM1 effective data pulse width, maximum 67108864 */
|
||||||
|
|
||||||
|
// Catch pulse width
|
||||||
|
#define TMR1_CAPTimeoutCfg( cyc ) (R32_TMR1_CNT_END=cyc) /* CAP1 capture level timeout configuration, maximum 33554432 */
|
||||||
|
void TMR1_CapInit( CapModeTypeDef cap ); /* External signal capture function initialization */
|
||||||
|
#define TMR1_CAPGetData() R32_TMR1_FIFO /* Get pulse data */
|
||||||
|
#define TMR1_CAPDataCounter() R8_TMR1_FIFO_COUNT /* Get the number of currently captured data */
|
||||||
|
|
||||||
|
void TMR1_DMACfg( UINT8 s, UINT16 startAddr, UINT16 endAddr, DMAModeTypeDef m ); /* DMA configuration */
|
||||||
|
|
||||||
|
#define TMR1_Disable() (R8_TMR1_CTRL_MOD &= ~RB_TMR_COUNT_EN) /* Close TMR1 */
|
||||||
|
// refer to TMR1 interrupt bit define
|
||||||
|
#define TMR1_ITCfg(s,f) ((s)?(R8_TMR1_INTER_EN|=f):(R8_TMR1_INTER_EN&=~f)) /* TMR1 corresponding interrupt bit on and off */
|
||||||
|
// refer to TMR1 interrupt bit define
|
||||||
|
#define TMR1_ClearITFlag(f) (R8_TMR1_INT_FLAG = f) /* Clear interrupt flag */
|
||||||
|
#define TMR1_GetITFlag(f) (R8_TMR1_INT_FLAG&f) /* Query interrupt flag status */
|
||||||
|
|
||||||
|
|
||||||
|
/****************** TMR2 */
|
||||||
|
// Timing and counting
|
||||||
|
void TMR2_TimerInit( UINT32 t ); /* Timing function initialization */
|
||||||
|
void TMR2_EXTSignalCounterInit( UINT32 c ); /* External signal counting function initialization */
|
||||||
|
#define TMR2_GetCurrentCount() R32_TMR2_COUNT /* Get the current count value, 67108864 */
|
||||||
|
|
||||||
|
// Pulse Width Modulation Function
|
||||||
|
#define TMR2_PWMCycleCfg( cyc ) (R32_TMR2_CNT_END=cyc) /* PWM2 channel output waveform period configuration, maximum 67108864 */
|
||||||
|
void TMR2_PWMInit( PWM_PolarTypeDef pr, PWM_RepeatTsTypeDef ts ); /* PWM2 output initialization */
|
||||||
|
#define TMR2_PWMActDataWidth( d ) (R32_TMR2_FIFO = d) /* PWM2 effective data pulse width, maximum 67108864 */
|
||||||
|
|
||||||
|
// Catch pulse width
|
||||||
|
#define TMR2_CAPTimeoutCfg( cyc ) (R32_TMR2_CNT_END=cyc) /* CAP2 capture level timeout configuration, maximum 33554432 */
|
||||||
|
void TMR2_CapInit( CapModeTypeDef cap ); /* External signal capture function initialization */
|
||||||
|
#define TMR2_CAPGetData() R32_TMR2_FIFO /* Get pulse data */
|
||||||
|
#define TMR2_CAPDataCounter() R8_TMR2_FIFO_COUNT /* Get the number of currently captured data */
|
||||||
|
|
||||||
|
void TMR2_DMACfg( UINT8 s, UINT16 startAddr, UINT16 endAddr, DMAModeTypeDef m ); /* DMA configuration */
|
||||||
|
|
||||||
|
#define TMR2_Disable() (R8_TMR2_CTRL_MOD &= ~RB_TMR_COUNT_EN) /* Close TMR2 */
|
||||||
|
// refer to TMR2 interrupt bit define
|
||||||
|
#define TMR2_ITCfg(s,f) ((s)?(R8_TMR2_INTER_EN|=f):(R8_TMR2_INTER_EN&=~f)) /* TMR2 corresponding interrupt bit on and off */
|
||||||
|
// refer to TMR2 interrupt bit define
|
||||||
|
#define TMR2_ClearITFlag(f) (R8_TMR2_INT_FLAG = f) /* Clear interrupt flag */
|
||||||
|
#define TMR2_GetITFlag(f) (R8_TMR2_INT_FLAG & f) /* Query interrupt flag status */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __CH56x_TIMER_H__
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,136 @@
|
||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : CH56x_uart.h
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0
|
||||||
|
* Date : 2020/07/31
|
||||||
|
* Description :
|
||||||
|
*********************************************************************************
|
||||||
|
* 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_UART_H__
|
||||||
|
#define __CH56x_UART_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Line Error Status Definition
|
||||||
|
*/
|
||||||
|
#define STA_ERR_BREAK RB_LSR_BREAK_ERR // Data Interval Error
|
||||||
|
#define STA_ERR_FRAME RB_LSR_FRAME_ERR // DataFrame error
|
||||||
|
#define STA_ERR_PAR RB_LSR_PAR_ERR // Parity bit error
|
||||||
|
#define STA_ERR_FIFOOV RB_LSR_OVER_ERR // Receive Data Overflow
|
||||||
|
|
||||||
|
#define STA_TXFIFO_EMP RB_LSR_TX_FIFO_EMP // The current send FIFO is empty, you can continue to fill the send data
|
||||||
|
#define STA_TXALL_EMP RB_LSR_TX_ALL_EMP // All currently sent data has been sent
|
||||||
|
#define STA_RECV_DATA RB_LSR_DATA_RDY // Data is currently received
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Serial port byte trigger configuration
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
UART_1BYTE_TRIG = 0, // 1 byte trigger
|
||||||
|
UART_2BYTE_TRIG = 1, // 2 byte trigger
|
||||||
|
UART_4BYTE_TRIG = 2, // 4 byte trigger
|
||||||
|
UART_7BYTE_TRIG = 3 , // 7 byte trigger
|
||||||
|
|
||||||
|
}UARTByteTRIGTypeDef;
|
||||||
|
|
||||||
|
|
||||||
|
/****************** UART0 */
|
||||||
|
void UART0_DefInit( void ); /* Serial port default initialization configuration */
|
||||||
|
void UART0_BaudRateCfg( UINT32 baudrate ); /* Serial port baud rate configuration */
|
||||||
|
void UART0_ByteTrigCfg( UARTByteTRIGTypeDef b ); /* Serial byte trigger interrupt configuration */
|
||||||
|
void UART0_INTCfg( UINT8 s, UINT8 i ); /* Serial port interrupt configuration */
|
||||||
|
void UART0_Reset( void ); /* Serial port software reset */
|
||||||
|
|
||||||
|
#define UART0_CLR_RXFIFO() (R8_UART0_FCR |= RB_FCR_RX_FIFO_CLR) /* Clear the current receive FIFO */
|
||||||
|
#define UART0_CLR_TXFIFO() (R8_UART0_FCR |= RB_FCR_TX_FIFO_CLR) /* Clear the current transmit FIFO */
|
||||||
|
|
||||||
|
#define UART0_GetITFlag() (R8_UART0_IIR & RB_IIR_INT_MASK) /* Get the current interrupt flag */
|
||||||
|
// please refer to LINE error and status define
|
||||||
|
#define UART0_GetLinSTA() (R8_UART0_LSR) /* Get the current communication status */
|
||||||
|
#define UART0_GetMSRSTA() (R8_UART0_MSR) /* Get the current flow control status, only applicable to UART0 */
|
||||||
|
|
||||||
|
#define UART0_SendByte(b) (R8_UART0_THR = b) /* Serial port single byte transmission */
|
||||||
|
void UART0_SendString( PUINT8 buf, UINT16 l ); /* Serial multi-byte transmission */
|
||||||
|
#define UART0_RecvByte() ( R8_UART0_RBR ) /* Serial port read single byte */
|
||||||
|
UINT16 UART0_RecvString( PUINT8 buf ); /* Serial port read multibyte */
|
||||||
|
|
||||||
|
|
||||||
|
/****************** UART1 */
|
||||||
|
void UART1_DefInit( void ); /* Serial port default initialization configuration */
|
||||||
|
void UART1_BaudRateCfg( UINT32 baudrate ); /* Serial port baud rate configuration */
|
||||||
|
void UART1_ByteTrigCfg( UARTByteTRIGTypeDef b ); /* Serial byte trigger interrupt configuration */
|
||||||
|
void UART1_INTCfg( UINT8 s, UINT8 i ); /* Serial port interrupt configuration */
|
||||||
|
void UART1_Reset( void ); /* Serial port software reset */
|
||||||
|
|
||||||
|
#define UART1_CLR_RXFIFO() (R8_UART1_FCR |= RB_FCR_RX_FIFO_CLR) /* Clear the current receive FIFO */
|
||||||
|
#define UART1_CLR_TXFIFO() (R8_UART1_FCR |= RB_FCR_TX_FIFO_CLR) /* Clear the current transmit FIFO */
|
||||||
|
|
||||||
|
#define UART1_GetITFlag() (R8_UART1_IIR&RB_IIR_INT_MASK) /* Get the current interrupt flag */
|
||||||
|
// please refer to LINE error and status define
|
||||||
|
#define UART1_GetLinSTA() (R8_UART1_LSR) /* Get the current communication status */
|
||||||
|
|
||||||
|
#define UART1_SendByte(b) (R8_UART1_THR = b) /* Serial port single byte transmission */
|
||||||
|
void UART1_SendString( PUINT8 buf, UINT16 l ); /* Serial multi-byte transmission */
|
||||||
|
#define UART1_RecvByte() ( R8_UART1_RBR ) /* Serial port read single byte */
|
||||||
|
UINT16 UART1_RecvString( PUINT8 buf ); /* Serial port read multibyte */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/****************** UART2 */
|
||||||
|
void UART2_DefInit( void ); /* Serial port default initialization configuration */
|
||||||
|
void UART2_BaudRateCfg( UINT32 baudrate ); /* Serial port baud rate configuration */
|
||||||
|
void UART2_ByteTrigCfg( UARTByteTRIGTypeDef b ); /* Serial byte trigger interrupt configuration */
|
||||||
|
void UART2_INTCfg( UINT8 s, UINT8 i ); /* Serial port interrupt configuration */
|
||||||
|
void UART2_Reset( void ); /* Serial port software reset */
|
||||||
|
|
||||||
|
#define UART2_CLR_RXFIFO() (R8_UART2_FCR |= RB_FCR_RX_FIFO_CLR) /* Clear the current receive FIFO */
|
||||||
|
#define UART2_CLR_TXFIFO() (R8_UART2_FCR |= RB_FCR_TX_FIFO_CLR) /* Clear the current transmit FIFO */
|
||||||
|
|
||||||
|
#define UART2_GetITFlag() (R8_UART2_IIR&RB_IIR_INT_MASK) /* Get the current interrupt flag */
|
||||||
|
// please refer to LINE error and status define
|
||||||
|
#define UART2_GetLinSTA() (R8_UART2_LSR) /* Get the current communication status */
|
||||||
|
|
||||||
|
#define UART2_SendByte(b) (R8_UART2_THR = b) /* Serial port single byte transmission */
|
||||||
|
void UART2_SendString( PUINT8 buf, UINT16 l ); /* Serial multi-byte transmission */
|
||||||
|
#define UART2_RecvByte() ( R8_UART2_RBR ) /* Serial port read single byte */
|
||||||
|
UINT16 UART2_RecvString( PUINT8 buf ); /* Serial port read multibyte */
|
||||||
|
|
||||||
|
|
||||||
|
/****************** UART3 */
|
||||||
|
void UART3_DefInit( void ); /* Serial port default initialization configuration */
|
||||||
|
void UART3_BaudRateCfg( UINT32 baudrate ); /* Serial port baud rate configuration */
|
||||||
|
void UART3_ByteTrigCfg( UARTByteTRIGTypeDef b ); /* Serial byte trigger interrupt configuration */
|
||||||
|
void UART3_INTCfg( UINT8 s, UINT8 i ); /* Serial port interrupt configuration */
|
||||||
|
void UART3_Reset( void ); /* Serial port software reset */
|
||||||
|
|
||||||
|
#define UART3_CLR_RXFIFO() (R8_UART3_FCR |= RB_FCR_RX_FIFO_CLR) /* Clear the current receive FIFO */
|
||||||
|
#define UART3_CLR_TXFIFO() (R8_UART3_FCR |= RB_FCR_TX_FIFO_CLR) /* Clear the current transmit FIFO */
|
||||||
|
|
||||||
|
#define UART3_GetITFlag() (R8_UART3_IIR&RB_IIR_INT_MASK) /* Get the current interrupt flag */
|
||||||
|
// please refer to LINE error and status define
|
||||||
|
#define UART3_GetLinSTA() (R8_UART3_LSR) /* Get the current communication status */
|
||||||
|
|
||||||
|
#define UART3_SendByte(b) (R8_UART3_THR = b) /* Serial port single byte transmission */
|
||||||
|
void UART3_SendString( PUINT8 buf, UINT16 l ); /* Serial multi-byte transmission */
|
||||||
|
#define UART3_RecvByte() ( R8_UART3_RBR ) /* Serial port read single byte */
|
||||||
|
UINT16 UART3_RecvString( PUINT8 buf ); /* Serial port read multibyte */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __CH56x_UART_H__
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : CH56x_bus8.c
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0
|
||||||
|
* Date : 2020/07/31
|
||||||
|
* Description :
|
||||||
|
*********************************************************************************
|
||||||
|
* 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 "CH56x_common.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn BUS8_GPIO_Init
|
||||||
|
*
|
||||||
|
* @brief BUS8 GPIO initialization
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void BUS8_GPIO_Init(void)
|
||||||
|
{
|
||||||
|
R32_PA_DIR = 0;
|
||||||
|
R32_PA_PU = 0xff;
|
||||||
|
R32_PA_SMT = 0xffffffff;
|
||||||
|
R32_PA_DIR |= bBUSRD | bBUSWR; //R/W signal GPIO
|
||||||
|
R32_PB_DIR |= 0x7fff;
|
||||||
|
R32_PB_SMT |= 0x7fff;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn BUS8_Init
|
||||||
|
*
|
||||||
|
* @brief BUS8 initialization
|
||||||
|
*
|
||||||
|
* @param addroe:0x00-none;0x04-[5:0];0x08-[9:0];0x0c-[14:0];
|
||||||
|
* width: 0x00-3;0x10-5;0x20-9;0x30-16;
|
||||||
|
* hold: 0x00-2;0x40-3;
|
||||||
|
* setup: 0x00-2;0x80-3;
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void BUS8_Init(UINT8 addroe, UINT8 width, UINT8 hold, UINT8 setup)
|
||||||
|
{
|
||||||
|
R8_XBUS_CONFIG = addroe | width | hold | setup;
|
||||||
|
R8_XBUS_CONFIG |= RB_XBUS_ENABLE; //Enable
|
||||||
|
BUS8_GPIO_Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : CH56x_clk.c
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0
|
||||||
|
* Date : 2020/07/31
|
||||||
|
* Description :
|
||||||
|
*********************************************************************************
|
||||||
|
* 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 "CH56x_common.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn SystemInit
|
||||||
|
*
|
||||||
|
* @brief System clock initialization
|
||||||
|
*
|
||||||
|
* @param systemclck: system clock Hz
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void SystemInit(uint32_t systemclck)
|
||||||
|
{
|
||||||
|
uint8_t sc;
|
||||||
|
|
||||||
|
sc = systemclck/1000000;
|
||||||
|
|
||||||
|
switch( sc )
|
||||||
|
{
|
||||||
|
case CLK_SOURCE_PLL_15MHz:
|
||||||
|
R8_SAFE_ACCESS_SIG = 0x57; // enable safe access mode
|
||||||
|
R8_SAFE_ACCESS_SIG = 0xa8;
|
||||||
|
R8_CLK_PLL_DIV = 0x40 | 0x02;
|
||||||
|
R8_CLK_CFG_CTRL = 0x80 ;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case CLK_SOURCE_PLL_30MHz:
|
||||||
|
R8_SAFE_ACCESS_SIG = 0x57; // enable safe access mode
|
||||||
|
R8_SAFE_ACCESS_SIG = 0xa8;
|
||||||
|
R8_CLK_PLL_DIV = 0x40;
|
||||||
|
R8_CLK_CFG_CTRL = 0x80 | RB_CLK_SEL_PLL;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case CLK_SOURCE_PLL_60MHz:
|
||||||
|
R8_SAFE_ACCESS_SIG = 0x57; // enable safe access mode
|
||||||
|
R8_SAFE_ACCESS_SIG = 0xa8;
|
||||||
|
R8_CLK_PLL_DIV = 0x40 | 0x08;
|
||||||
|
R8_CLK_CFG_CTRL = 0x80 | RB_CLK_SEL_PLL;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case CLK_SOURCE_PLL_80MHz:
|
||||||
|
R8_SAFE_ACCESS_SIG = 0x57; // enable safe access mode
|
||||||
|
R8_SAFE_ACCESS_SIG = 0xa8;
|
||||||
|
R8_CLK_PLL_DIV = 0x40 | 0x06;
|
||||||
|
R8_CLK_CFG_CTRL = 0x80 | RB_CLK_SEL_PLL;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case CLK_SOURCE_PLL_96MHz:
|
||||||
|
R8_SAFE_ACCESS_SIG = 0x57; // enable safe access mode
|
||||||
|
R8_SAFE_ACCESS_SIG = 0xa8;
|
||||||
|
R8_CLK_PLL_DIV = 0x40 | 0x05;
|
||||||
|
R8_CLK_CFG_CTRL = 0x80 | RB_CLK_SEL_PLL;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case CLK_SOURCE_PLL_120MHz:
|
||||||
|
R8_SAFE_ACCESS_SIG = 0x57; // enable safe access mode
|
||||||
|
R8_SAFE_ACCESS_SIG = 0xa8;
|
||||||
|
R8_CLK_PLL_DIV = 0x40 | 0x04;
|
||||||
|
R8_CLK_CFG_CTRL = 0x80 | RB_CLK_SEL_PLL;
|
||||||
|
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
R8_SAFE_ACCESS_SIG = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn GetSysClock
|
||||||
|
*
|
||||||
|
* @brief Get the current system clock
|
||||||
|
*
|
||||||
|
* @param None
|
||||||
|
*
|
||||||
|
* @return Hz
|
||||||
|
*/
|
||||||
|
UINT32 GetSysClock( void )
|
||||||
|
{
|
||||||
|
UINT8 rev;
|
||||||
|
|
||||||
|
rev = R8_CLK_PLL_DIV & 0x0F;
|
||||||
|
|
||||||
|
if(R8_CLK_CFG_CTRL & RB_CLK_SEL_PLL){ //The system clock source comes from the 480M provided by the USB PHY
|
||||||
|
if(rev == 0){
|
||||||
|
return (30000000);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return (480000000/R8_CLK_PLL_DIV);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{ //The system clock source comes from an external crystal oscillator 30M
|
||||||
|
if(rev == 0){
|
||||||
|
return (2000000);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return (30000000/R8_CLK_PLL_DIV);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,132 @@
|
||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : CH56x_dvp.c
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0
|
||||||
|
* Date : 2020/07/31
|
||||||
|
* Description :
|
||||||
|
*********************************************************************************
|
||||||
|
* 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 "CH56x_common.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn DVP_INTCfg
|
||||||
|
*
|
||||||
|
* @brief DVP interrupt configuration
|
||||||
|
*
|
||||||
|
* @param s: interrupt control status
|
||||||
|
ENABLE - Enables the corresponding interrupt
|
||||||
|
DISABLE - disables the corresponding interrupt
|
||||||
|
i: interrupt type
|
||||||
|
RB_DVP_IE_STP_FRM - end of frame interrupt
|
||||||
|
RB_DVP_IE_FIFO_OV - Receive FIFO overflow interrupt
|
||||||
|
RB_DVP_IE_FRM_DONE - end of frame interrupt
|
||||||
|
RB_DVP_IE_ROW_DONE - end of line break
|
||||||
|
RB_DVP_IE_STR_FRM - start of frame interrupt
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
**/
|
||||||
|
void DVP_INTCfg( UINT8 s, UINT8 i )
|
||||||
|
{
|
||||||
|
if(s){
|
||||||
|
R8_DVP_INT_EN |= i;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
R8_DVP_INT_EN &= ~i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn DVP_Mode
|
||||||
|
*
|
||||||
|
* @brief DVP mode
|
||||||
|
*
|
||||||
|
* @param s: data width
|
||||||
|
RB_DVP_D8_MOD - 8-bit mode
|
||||||
|
RB_DVP_D10_MOD - 10-bit mode
|
||||||
|
RB_DVP_D12_MOD - 12-bit mode
|
||||||
|
i: Compressed Data Mode
|
||||||
|
Video_Mode - enable video mode
|
||||||
|
JPEG_Mode - Enable JPEG mode
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void DVP_Mode( UINT8 s, DVP_Data_ModeTypeDef i)
|
||||||
|
{
|
||||||
|
R8_DVP_CR0 &= ~RB_DVP_MSK_DAT_MOD; //Restore default mode 8bit mode
|
||||||
|
|
||||||
|
if(s){
|
||||||
|
R8_DVP_CR0 |= s;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
R8_DVP_CR0 &= ~(3<<4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(i){
|
||||||
|
R8_DVP_CR0 |= RB_DVP_JPEG;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
R8_DVP_CR0 &= ~RB_DVP_JPEG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn DVP_Cfg
|
||||||
|
*
|
||||||
|
* @brief DVP configuration
|
||||||
|
*
|
||||||
|
* @param s: DMA enable control
|
||||||
|
DVP_DMA_Enable - DMA enable
|
||||||
|
DVP_DMA_Disable - DMA disable
|
||||||
|
i: Flag and FIFO Clear Control
|
||||||
|
DVP_FLAG_FIFO_RESET_Enable - Reset flag and FIFO
|
||||||
|
DVP_FLAG_FIFO_RESET_Disable - cancel reset operation
|
||||||
|
j: Receive Logic Reset Control
|
||||||
|
DVP_RX_RESET_Enable - reset receiver logic
|
||||||
|
DVP_RX_RESET_Disable - cancel reset operation
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void DVP_Cfg( DVP_DMATypeDef s, DVP_FLAG_FIFO_RESETTypeDef i, DVP_RX_RESETTypeDef j)
|
||||||
|
{
|
||||||
|
switch( s )
|
||||||
|
{
|
||||||
|
case DVP_DMA_Enable:
|
||||||
|
R8_DVP_CR1 |= RB_DVP_DMA_EN;
|
||||||
|
break;
|
||||||
|
case DVP_DMA_Disable:
|
||||||
|
R8_DVP_CR1 &= ~RB_DVP_DMA_EN;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( i )
|
||||||
|
{
|
||||||
|
case DVP_RX_RESET_Enable:
|
||||||
|
R8_DVP_CR1 |= RB_DVP_ALL_CLR;
|
||||||
|
break;
|
||||||
|
case DVP_RX_RESET_Disable:
|
||||||
|
R8_DVP_CR1 &= ~RB_DVP_ALL_CLR;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( j )
|
||||||
|
{
|
||||||
|
case DVP_RX_RESET_Enable:
|
||||||
|
R8_DVP_CR1 |= RB_DVP_RCV_CLR;
|
||||||
|
break;
|
||||||
|
case DVP_RX_RESET_Disable:
|
||||||
|
R8_DVP_CR1 &= ~RB_DVP_RCV_CLR;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,182 @@
|
||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : CH56x_ecdc.c
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0
|
||||||
|
* Date : 2020/07/31
|
||||||
|
* Description :
|
||||||
|
*********************************************************************************
|
||||||
|
* 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 "CH56x_common.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn ECDC_Init
|
||||||
|
*
|
||||||
|
* @brief initialization
|
||||||
|
*
|
||||||
|
* @param ecdcmode - 0-SM4&ECB 1-AES&ECB 2-SM4&CTR 3-AES&CTR
|
||||||
|
* clkmode - 1-closure 2-240M 3-160M
|
||||||
|
* keylen - 0-128bit 1-192bit 2-256bit
|
||||||
|
* pkey - key value pointer
|
||||||
|
* pcount - counter value pointer
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void ECDC_Init( UINT8 ecdcmode, UINT8 clkmode, UINT8 keylen, PUINT32 pkey, PUINT32 pcount )
|
||||||
|
{
|
||||||
|
R8_ECDC_INT_FG |= 0xFF;
|
||||||
|
R16_ECEC_CTRL = 0;
|
||||||
|
|
||||||
|
R16_ECEC_CTRL |= (ecdcmode&0x03)<<8; //Working mode selection
|
||||||
|
R16_ECEC_CTRL |= (keylen&0x03)<<10; //key length setting
|
||||||
|
R16_ECEC_CTRL |= (clkmode&0x03)<<4; //Encryption and decryption clock frequency division factor, aes encryption and decryption works at 240Mhz
|
||||||
|
ECDC_SetKey(pkey, keylen);
|
||||||
|
|
||||||
|
if(R16_ECEC_CTRL & RB_ECDC_CIPHER_MOD) //Execute only in CTR mode, the only difference between CTR and ECB mode programming
|
||||||
|
ECDC_SetCount(pcount);
|
||||||
|
|
||||||
|
R8_ECDC_INT_FG |= RB_ECDC_IF_EKDONE;
|
||||||
|
R16_ECEC_CTRL |= RB_ECDC_KEYEX_EN;
|
||||||
|
R16_ECEC_CTRL &= ~RB_ECDC_KEYEX_EN;
|
||||||
|
|
||||||
|
while(!(R8_ECDC_INT_FG & RB_ECDC_IF_EKDONE));
|
||||||
|
R8_ECDC_INT_FG |= RB_ECDC_IF_EKDONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn ECDC_SetKey
|
||||||
|
*
|
||||||
|
* @brief set key
|
||||||
|
*
|
||||||
|
* @param pkey - key value pointer
|
||||||
|
* keylen - 0-128bit 1-192bit 2-256bit
|
||||||
|
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void ECDC_SetKey( PUINT32 pkey, UINT8 keylen )
|
||||||
|
{
|
||||||
|
keylen = keylen&0x03;
|
||||||
|
|
||||||
|
R32_ECDC_KEY_31T0 = *pkey++;
|
||||||
|
R32_ECDC_KEY_63T32 = *pkey++;
|
||||||
|
R32_ECDC_KEY_95T64 = *pkey++;
|
||||||
|
R32_ECDC_KEY_127T96 = *pkey++;
|
||||||
|
|
||||||
|
if(keylen){
|
||||||
|
R32_ECDC_KEY_159T128 = *pkey++;
|
||||||
|
R32_ECDC_KEY_191T160 = *pkey++;
|
||||||
|
}
|
||||||
|
if(keylen>1){
|
||||||
|
R32_ECDC_KEY_223T192 = *pkey++;
|
||||||
|
R32_ECDC_KEY_255T224 = *pkey++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn ECDC_SetCount
|
||||||
|
*
|
||||||
|
* @brief set counter
|
||||||
|
*
|
||||||
|
* @param pcount - counter value pointer
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void ECDC_SetCount( PUINT32 pcount )
|
||||||
|
{
|
||||||
|
R32_ECDC_IV_31T0 = *pcount++;
|
||||||
|
R32_ECDC_IV_63T32 = *pcount++;
|
||||||
|
R32_ECDC_IV_95T64 = *pcount++;
|
||||||
|
R32_ECDC_IV_127T96 = *pcount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn ECDC_Excute
|
||||||
|
*
|
||||||
|
* @brief Set direction and mode
|
||||||
|
*
|
||||||
|
* @param excutemode - RAMX encryption -0x84
|
||||||
|
* RAMX decryption -0x8c
|
||||||
|
* 128bits data single encryption -0x02
|
||||||
|
* 128bits data single decryption -0x0a
|
||||||
|
* Peripheral to RAMX encryption -0x02
|
||||||
|
* Peripheral to RAMX decryption -0x0a
|
||||||
|
* RAMX to Peripheral encryption -0x04
|
||||||
|
* RAMX to Peripheral decryption -0x0c
|
||||||
|
* endianmode - big_endian-1 little_endian-0
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void ECDC_Excute( UINT8 excutemode, UINT8 endianmode )
|
||||||
|
{
|
||||||
|
R16_ECEC_CTRL &= 0xDF71;
|
||||||
|
R16_ECEC_CTRL |= excutemode;
|
||||||
|
if(endianmode)
|
||||||
|
R16_ECEC_CTRL |= RB_ECDC_DAT_MOD;
|
||||||
|
else
|
||||||
|
R16_ECEC_CTRL &= ~RB_ECDC_DAT_MOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn ECDC_SingleRegister
|
||||||
|
*
|
||||||
|
* @brief Single register encryption and decryption
|
||||||
|
*
|
||||||
|
* @param pWdatbuff - Write data first address
|
||||||
|
* pRdatbuff - Read data first address
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void ECDC_SingleRegister( PUINT32 pWdatbuff, PUINT32 pRdatbuff )
|
||||||
|
{
|
||||||
|
R32_ECDC_SGSD_127T96 = pWdatbuff[3]; //low address
|
||||||
|
R32_ECDC_SGSD_95T64 = pWdatbuff[2];
|
||||||
|
R32_ECDC_SGSD_63T32 = pWdatbuff[1];
|
||||||
|
R32_ECDC_SGSD_31T0 = pWdatbuff[0]; //high address
|
||||||
|
|
||||||
|
while(!(R8_ECDC_INT_FG & RB_ECDC_IF_SINGLE));
|
||||||
|
R8_ECDC_INT_FG |= RB_ECDC_IF_SINGLE;
|
||||||
|
|
||||||
|
pRdatbuff[3] = R32_ECDC_SGRT_127T96;
|
||||||
|
pRdatbuff[2] = R32_ECDC_SGRT_95T64;
|
||||||
|
pRdatbuff[1] = R32_ECDC_SGRT_63T32;
|
||||||
|
pRdatbuff[0] = R32_ECDC_SGRT_31T0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn ECDC_RAMX
|
||||||
|
*
|
||||||
|
* @brief RAMX encryption and decryption
|
||||||
|
*
|
||||||
|
* @param ram_add - first address
|
||||||
|
* ram_len - length
|
||||||
|
* @return None
|
||||||
|
**/
|
||||||
|
void ECDC_SelfDMA( UINT32 ram_addr, UINT32 ram_len )
|
||||||
|
{
|
||||||
|
R32_ECDC_SRAM_ADDR = ram_addr;
|
||||||
|
R32_ECDC_SRAM_LEN = ram_len; //start converting
|
||||||
|
|
||||||
|
while(!(R8_ECDC_INT_FG & RB_ECDC_IF_WRSRAM)); //Completion flag
|
||||||
|
R8_ECDC_INT_FG |= RB_ECDC_IF_WRSRAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn ECDC_RloadCount
|
||||||
|
*
|
||||||
|
* @brief In CTR mode, every time a block is encrypted/decrypted, the counter value is reloaded
|
||||||
|
*
|
||||||
|
* @param pcount - counter value pointer
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void ECDC_RloadCount( UINT8 excutemode, UINT8 endianmode, PUINT32 pcount )
|
||||||
|
{
|
||||||
|
R16_ECEC_CTRL &= 0xDFF9; //second position third position 0
|
||||||
|
ECDC_SetCount(pcount);
|
||||||
|
ECDC_Excute(excutemode, endianmode);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,870 @@
|
||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : CH56x_emmc.c
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0
|
||||||
|
* Date : 2020/07/31
|
||||||
|
* Description :
|
||||||
|
*********************************************************************************
|
||||||
|
* 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 "CH56x_common.h"
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn EMMCIO0Init
|
||||||
|
*
|
||||||
|
* @brief EMMC Controller Initializtion
|
||||||
|
*
|
||||||
|
* @return OP_SUCCESS
|
||||||
|
*/
|
||||||
|
UINT8 EMMCIO0Init( void )
|
||||||
|
{
|
||||||
|
/* GPIO configuration */
|
||||||
|
R32_PB_DRV |= bSDCMD; //Command Line
|
||||||
|
R32_PB_PU |= bSDCMD;
|
||||||
|
|
||||||
|
R32_PB_DIR |= bSDCK; //CLK Line
|
||||||
|
R32_PB_DRV |= bSDCK;
|
||||||
|
|
||||||
|
R32_PB_PU |= (0x1f<<17); //Data Line
|
||||||
|
R32_PA_PU |= (7<<0);
|
||||||
|
|
||||||
|
R32_PA_DRV |= (7<<0); // Drive Capacity
|
||||||
|
R32_PB_DRV |= (0x1f<<17); // Drive Capacity
|
||||||
|
|
||||||
|
|
||||||
|
/* Controller Register */
|
||||||
|
R8_EMMC_CONTROL = RB_EMMC_ALL_CLR | RB_EMMC_RST_LGC ; // reset all register
|
||||||
|
R8_EMMC_CONTROL = RB_EMMC_NEGSMP | RB_EMMC_DMAEN ; // Enable EMMCcard
|
||||||
|
R32_PB_DIR |= bSDCK;
|
||||||
|
R16_EMMC_CLK_DIV = RB_EMMC_CLKOE | LOWEMMCCLK|RB_EMMC_PHASEINV;
|
||||||
|
|
||||||
|
/* Enable Interruption */
|
||||||
|
R16_EMMC_INT_FG = 0xffff;
|
||||||
|
R16_EMMC_INT_EN = RB_EMMC_IE_FIFO_OV | //Enable error Interruption
|
||||||
|
RB_EMMC_IE_TRANERR |
|
||||||
|
RB_EMMC_IE_DATTMO |
|
||||||
|
RB_EMMC_IE_REIDX_ER |
|
||||||
|
RB_EMMC_IE_RECRC_WR |
|
||||||
|
RB_EMMC_IE_RE_TMOUT;
|
||||||
|
|
||||||
|
/* Overtime */
|
||||||
|
R8_EMMC_TIMEOUT = 35; // calculating overtime
|
||||||
|
return OP_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn CheckCMDComp
|
||||||
|
*
|
||||||
|
* @brief Estimate the end of Command
|
||||||
|
*
|
||||||
|
* @param pEMMCPara
|
||||||
|
*
|
||||||
|
* @return CMD_NULL
|
||||||
|
**/
|
||||||
|
UINT8 CheckCMDComp( PSD_PARAMETER pEMMCPara )
|
||||||
|
{
|
||||||
|
if(R16_EMMC_INT_FG & RB_EMMC_IF_CMDDONE)
|
||||||
|
{
|
||||||
|
R16_EMMC_INT_FG = RB_EMMC_IF_CMDDONE;
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
if( pEMMCPara->EMMCOpErr ) return CMD_FAILED;
|
||||||
|
return CMD_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn EMMCResetIdle
|
||||||
|
*
|
||||||
|
* @brief when EMMC waiting status,do the OCR analysis
|
||||||
|
*
|
||||||
|
* @param pEMMCPara
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void EMMCResetIdle( PSD_PARAMETER pEMMCPara )
|
||||||
|
{
|
||||||
|
UINT32 cmd_arg_val;
|
||||||
|
UINT16 cmd_set_val;
|
||||||
|
|
||||||
|
cmd_arg_val = 0x0;
|
||||||
|
cmd_set_val = 0x0|EMMC_CMD0;
|
||||||
|
EMMCSendCmd(cmd_arg_val, cmd_set_val);
|
||||||
|
while( CheckCMDComp( pEMMCPara ) == CMD_NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn EMMCReadOCR
|
||||||
|
*
|
||||||
|
* @brief when EMMC waiting status,do the OCR analysis
|
||||||
|
*
|
||||||
|
* @param pEMMCPara
|
||||||
|
*
|
||||||
|
* @return CMD_SUCCESS
|
||||||
|
*/
|
||||||
|
UINT8 EMMCReadOCR( PSD_PARAMETER pEMMCPara )
|
||||||
|
{
|
||||||
|
UINT8 i;
|
||||||
|
UINT32 cmd_arg_val;
|
||||||
|
UINT16 cmd_set_val;
|
||||||
|
UINT8 sta = 0;
|
||||||
|
UINT32 cmd_rsp_val; //command returned value
|
||||||
|
|
||||||
|
for(i=0; i<100; i++)
|
||||||
|
{
|
||||||
|
cmd_arg_val = 0x40FF0080; //request switching voltage
|
||||||
|
// cmd_arg_val = 0x40000800; //request switching voltage
|
||||||
|
cmd_set_val = 0 | //ACK's index
|
||||||
|
0 | //CRC
|
||||||
|
RESP_TYPE_48 | //ACK type
|
||||||
|
EMMC_CMD1; //command's index this moment
|
||||||
|
mDelaymS(10);
|
||||||
|
EMMCSendCmd(cmd_arg_val, cmd_set_val);
|
||||||
|
mDelayuS(2);
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
sta = CheckCMDComp( pEMMCPara );
|
||||||
|
if( sta!= CMD_NULL )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sta == CMD_SUCCESS)
|
||||||
|
{
|
||||||
|
cmd_rsp_val = R32_EMMC_RESPONSE3;
|
||||||
|
if(cmd_rsp_val & (1<<31))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mDelaymS(50);
|
||||||
|
}
|
||||||
|
if(i == 100) return OP_FAILED;
|
||||||
|
|
||||||
|
return sta;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn EMMCReadCID
|
||||||
|
*
|
||||||
|
* @brief acquire 128bit CID parameter
|
||||||
|
*
|
||||||
|
* @param pEMMCPara
|
||||||
|
*
|
||||||
|
* @return OP_SUCCESS
|
||||||
|
**/
|
||||||
|
UINT8 EMMCReadCID( PSD_PARAMETER pEMMCPara )
|
||||||
|
{
|
||||||
|
UINT32 cmd_arg_val;
|
||||||
|
UINT16 cmd_set_val;
|
||||||
|
UINT8 sta;
|
||||||
|
|
||||||
|
cmd_arg_val = 0;
|
||||||
|
cmd_set_val = 0 |
|
||||||
|
0 |
|
||||||
|
RESP_TYPE_136 |
|
||||||
|
EMMC_CMD2;
|
||||||
|
EMMCSendCmd( cmd_arg_val, cmd_set_val);
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
sta = CheckCMDComp( pEMMCPara );
|
||||||
|
if( sta != CMD_NULL ) break;
|
||||||
|
}
|
||||||
|
if(sta == CMD_SUCCESS)
|
||||||
|
{
|
||||||
|
pEMMCPara->EMMC_CID[0] = R32_EMMC_RESPONSE0;
|
||||||
|
pEMMCPara->EMMC_CID[1] = R32_EMMC_RESPONSE1;
|
||||||
|
pEMMCPara->EMMC_CID[2] = R32_EMMC_RESPONSE2;
|
||||||
|
pEMMCPara->EMMC_CID[3] = R32_EMMC_RESPONSE3;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sta;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn EMMCSetRCA
|
||||||
|
*
|
||||||
|
* @brief assign relative address to deviceARC 16bit
|
||||||
|
*
|
||||||
|
* @param pEMMCPara
|
||||||
|
*
|
||||||
|
* @return OP_SUCCESS
|
||||||
|
*/
|
||||||
|
UINT8 EMMCSetRCA( PSD_PARAMETER pEMMCPara )
|
||||||
|
{
|
||||||
|
UINT32 cmd_arg_val;
|
||||||
|
UINT16 cmd_set_val;
|
||||||
|
UINT8 sta;
|
||||||
|
|
||||||
|
cmd_arg_val = 0xAAAA0000;
|
||||||
|
cmd_set_val = RB_EMMC_CKIDX |
|
||||||
|
RB_EMMC_CKCRC |
|
||||||
|
RESP_TYPE_48 |
|
||||||
|
EMMC_CMD3;
|
||||||
|
mDelaymS(10);
|
||||||
|
EMMCSendCmd(cmd_arg_val,cmd_set_val);
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
sta = CheckCMDComp( pEMMCPara );
|
||||||
|
if( sta != CMD_NULL ) break;
|
||||||
|
}
|
||||||
|
if(sta == CMD_SUCCESS)
|
||||||
|
{
|
||||||
|
pEMMCPara->EMMC_RCA = 0xAAAA;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sta;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn EMMCReadCSD
|
||||||
|
*
|
||||||
|
* @brief acquire 128bit CSD parameter and get it analyzed
|
||||||
|
*
|
||||||
|
* @param pEMMCPara
|
||||||
|
*
|
||||||
|
* @return OP_SUCCESS
|
||||||
|
*/
|
||||||
|
UINT8 EMMCReadCSD( PSD_PARAMETER pEMMCPara )
|
||||||
|
{
|
||||||
|
UINT32 cmd_arg_val;
|
||||||
|
UINT16 cmd_set_val;
|
||||||
|
UINT8 sta;
|
||||||
|
UINT32 disk_block_num = 0;
|
||||||
|
|
||||||
|
cmd_arg_val = pEMMCPara->EMMC_RCA<<16;
|
||||||
|
cmd_set_val = 0 |
|
||||||
|
0 |
|
||||||
|
RESP_TYPE_136 |
|
||||||
|
EMMC_CMD9;
|
||||||
|
EMMCSendCmd(cmd_arg_val, cmd_set_val);
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
sta = CheckCMDComp( pEMMCPara );
|
||||||
|
if( sta != CMD_NULL ) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sta == CMD_SUCCESS)
|
||||||
|
{
|
||||||
|
pEMMCPara->EMMC_CSD[0] = R32_EMMC_RESPONSE0;
|
||||||
|
pEMMCPara->EMMC_CSD[1] = R32_EMMC_RESPONSE1;
|
||||||
|
pEMMCPara->EMMC_CSD[2] = R32_EMMC_RESPONSE2;
|
||||||
|
pEMMCPara->EMMC_CSD[3] = R32_EMMC_RESPONSE3;
|
||||||
|
|
||||||
|
|
||||||
|
disk_block_num = (((pEMMCPara->EMMC_CSD[2]&0x3ff)<<2) | ((pEMMCPara->EMMC_CSD[1])>>30));
|
||||||
|
if(disk_block_num == 0xFFF)
|
||||||
|
{
|
||||||
|
pEMMCPara->EMMCSecNum = 0xFFF;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pEMMCPara->EMMCType = EMMCIO_CAPACITY_SD_CARD_V2_0;
|
||||||
|
/* memory capacity = BLOCKNR*BLOCK_LEN = (C_SIZE+1)<<(C_SIZE_MULT+2)<<(READ_BL_LEN) */
|
||||||
|
disk_block_num = ( (((pEMMCPara->EMMC_CSD[2]&0x3ff)<<2) | (pEMMCPara->EMMC_CSD[1]>>30)) + 1 );
|
||||||
|
disk_block_num = ( (disk_block_num) << (((pEMMCPara->EMMC_CSD[1]>>15)&0x07) + 2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pEMMCPara->EMMCSecSize = 1<<((pEMMCPara->EMMC_CSD[2]>>16)&0x000f);
|
||||||
|
return sta;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn SelectEMMCCard
|
||||||
|
*
|
||||||
|
* @brief select card
|
||||||
|
*
|
||||||
|
* @param pEMMCPara
|
||||||
|
*
|
||||||
|
* @return OP_SUCCESS
|
||||||
|
*/
|
||||||
|
UINT8 SelectEMMCCard(PSD_PARAMETER pEMMCPara)
|
||||||
|
{
|
||||||
|
UINT32 cmd_arg_val;
|
||||||
|
UINT16 cmd_set_val;
|
||||||
|
UINT8 sta;
|
||||||
|
|
||||||
|
cmd_arg_val = pEMMCPara->EMMC_RCA<<16;
|
||||||
|
cmd_set_val = RB_EMMC_CKIDX |
|
||||||
|
RB_EMMC_CKCRC |
|
||||||
|
RESP_TYPE_48 |
|
||||||
|
EMMC_CMD7;
|
||||||
|
EMMCSendCmd(cmd_arg_val, cmd_set_val);
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
sta = CheckCMDComp( pEMMCPara );
|
||||||
|
if( sta != CMD_NULL ) break;
|
||||||
|
}
|
||||||
|
return sta;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT8 ReadEMMCStatus(PSD_PARAMETER pEMMCPara)
|
||||||
|
{
|
||||||
|
UINT32 cmd_arg_val;
|
||||||
|
UINT16 cmd_set_val;
|
||||||
|
UINT8 sta;
|
||||||
|
|
||||||
|
cmd_arg_val = pEMMCPara->EMMC_RCA<<16;
|
||||||
|
cmd_set_val = RB_EMMC_CKIDX |
|
||||||
|
RB_EMMC_CKCRC |
|
||||||
|
RESP_TYPE_48 |
|
||||||
|
EMMC_CMD13;
|
||||||
|
EMMCSendCmd(cmd_arg_val, cmd_set_val);
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
sta = CheckCMDComp( pEMMCPara );
|
||||||
|
if( sta != CMD_NULL ) break;
|
||||||
|
}
|
||||||
|
return sta;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn SwitchEMMCIOBusType
|
||||||
|
*
|
||||||
|
* @brief set the IO bus_mode
|
||||||
|
*
|
||||||
|
* @param pEMMCPara -
|
||||||
|
* bus_mode -
|
||||||
|
*
|
||||||
|
* @return OP_SUCCESS
|
||||||
|
*/
|
||||||
|
UINT8 EMMCSetBusWidth(PSD_PARAMETER pEMMCPara, UINT8 bus_mode)
|
||||||
|
{
|
||||||
|
UINT32 cmd_arg_val;
|
||||||
|
UINT16 cmd_set_val;
|
||||||
|
UINT8 sta;
|
||||||
|
|
||||||
|
if(bus_mode == 0) cmd_arg_val = 0x03B70100;
|
||||||
|
else cmd_arg_val = 0x03B70200;
|
||||||
|
cmd_set_val = RB_EMMC_CKIDX |
|
||||||
|
RB_EMMC_CKCRC |
|
||||||
|
RESP_TYPE_48 |
|
||||||
|
EMMC_CMD6;
|
||||||
|
EMMCSendCmd(cmd_arg_val, cmd_set_val);
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
sta = CheckCMDComp( pEMMCPara );
|
||||||
|
if( sta != CMD_NULL ) break;
|
||||||
|
}
|
||||||
|
return sta;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT8 EMMCSetHighSpeed(PSD_PARAMETER pEMMCPara)
|
||||||
|
{
|
||||||
|
UINT32 cmd_arg_val;
|
||||||
|
UINT16 cmd_set_val;
|
||||||
|
UINT8 sta;
|
||||||
|
|
||||||
|
cmd_arg_val = 0x03B90100;
|
||||||
|
cmd_set_val = RB_EMMC_CKIDX |
|
||||||
|
RB_EMMC_CKCRC |
|
||||||
|
RESP_TYPE_R1b |
|
||||||
|
EMMC_CMD6;
|
||||||
|
EMMCSendCmd(cmd_arg_val, cmd_set_val);
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
sta = CheckCMDComp( pEMMCPara );
|
||||||
|
if( sta != CMD_NULL ) break;
|
||||||
|
}
|
||||||
|
return sta;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn ConfigAllSD
|
||||||
|
*
|
||||||
|
* @brief EMMC Information
|
||||||
|
*
|
||||||
|
* @param pEMMCPara
|
||||||
|
*
|
||||||
|
* @return OP_SUCCESS
|
||||||
|
**/
|
||||||
|
#define SD2CMD EMMCSendCmd
|
||||||
|
__attribute__ ((aligned(8))) UINT8 buf[512] __attribute__((section(".DMADATA")));
|
||||||
|
UINT8 EMMCCardConfig( PSD_PARAMETER pEMMCPara )
|
||||||
|
{
|
||||||
|
UINT8 sta;
|
||||||
|
//cmd0
|
||||||
|
EMMCResetIdle( pEMMCPara );
|
||||||
|
mDelaymS(30);
|
||||||
|
sta = EMMCReadOCR( pEMMCPara );
|
||||||
|
if(sta!=CMD_SUCCESS) return OP_FAILED;
|
||||||
|
//cmd2
|
||||||
|
sta = EMMCReadCID( pEMMCPara );
|
||||||
|
if(sta!=CMD_SUCCESS) return OP_FAILED;
|
||||||
|
//cmd3
|
||||||
|
mDelaymS(30);
|
||||||
|
sta = EMMCSetRCA( pEMMCPara );
|
||||||
|
if(sta!=CMD_SUCCESS) return OP_FAILED;
|
||||||
|
//cmd9
|
||||||
|
sta = EMMCReadCSD( pEMMCPara );
|
||||||
|
if(sta!=CMD_SUCCESS) return OP_FAILED;
|
||||||
|
//cmd7;
|
||||||
|
mDelaymS(30);
|
||||||
|
sta = SelectEMMCCard( pEMMCPara );
|
||||||
|
if(sta!=CMD_SUCCESS) return OP_FAILED;
|
||||||
|
mDelaymS(30);
|
||||||
|
if(pEMMCPara->EMMCSecNum == 0xFFF)
|
||||||
|
{
|
||||||
|
sta = EMMCCardReadEXCSD( pEMMCPara, buf );
|
||||||
|
if(sta!=OP_SUCCESS) return OP_FAILED;
|
||||||
|
pEMMCPara->EMMCSecNum = *((PUINT32)&buf[212]); // SEC_COUNT [215:212] MSB-LSB
|
||||||
|
}
|
||||||
|
//cmd6
|
||||||
|
sta = EMMCSetBusWidth(pEMMCPara, 1);
|
||||||
|
if(sta!=CMD_SUCCESS) return OP_FAILED;
|
||||||
|
R8_EMMC_CONTROL = (R8_EMMC_CONTROL&~RB_EMMC_LW_MASK) | bLW_OP_DAT8; // 8line_mode
|
||||||
|
mDelaymS(30);
|
||||||
|
//configure high clock rate
|
||||||
|
EMMCSetHighSpeed(pEMMCPara);
|
||||||
|
//cmd13
|
||||||
|
mDelaymS(30);
|
||||||
|
sta = ReadEMMCStatus( pEMMCPara );
|
||||||
|
if(sta!=CMD_SUCCESS) return OP_FAILED;
|
||||||
|
mDelaymS(30);
|
||||||
|
// R8_EMMC_CONTROL |= RB_EMMC_NEGSMP;
|
||||||
|
R16_EMMC_CLK_DIV = RB_EMMC_CLKMode|
|
||||||
|
RB_EMMC_PHASEINV|
|
||||||
|
RB_EMMC_CLKOE |
|
||||||
|
8;
|
||||||
|
return OP_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT8 EMMCCardConfig_N( PSD_PARAMETER pEMMCPara )
|
||||||
|
{
|
||||||
|
UINT8 sta;
|
||||||
|
|
||||||
|
EMMCResetIdle( pEMMCPara );
|
||||||
|
mDelaymS(30);
|
||||||
|
sta = EMMCReadOCR( pEMMCPara );
|
||||||
|
if(sta!=CMD_SUCCESS)
|
||||||
|
{
|
||||||
|
return OP_FAILED;
|
||||||
|
}
|
||||||
|
sta = EMMCReadCID( pEMMCPara );
|
||||||
|
if(sta!=CMD_SUCCESS)
|
||||||
|
{
|
||||||
|
return OP_FAILED;
|
||||||
|
}
|
||||||
|
mDelaymS(30);
|
||||||
|
sta = EMMCSetRCA( pEMMCPara );
|
||||||
|
if(sta!=CMD_SUCCESS)
|
||||||
|
{
|
||||||
|
return OP_FAILED;
|
||||||
|
}
|
||||||
|
sta = EMMCReadCSD( pEMMCPara );
|
||||||
|
if(sta!=CMD_SUCCESS)
|
||||||
|
{
|
||||||
|
return OP_FAILED;
|
||||||
|
}
|
||||||
|
mDelaymS(30);
|
||||||
|
sta = SelectEMMCCard( pEMMCPara );
|
||||||
|
if(sta!=CMD_SUCCESS)
|
||||||
|
{
|
||||||
|
return OP_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
R16_EMMC_CLK_DIV = RB_EMMC_CLKMode|
|
||||||
|
RB_EMMC_CLKOE |
|
||||||
|
LOWEMMCCLK;
|
||||||
|
sta = ReadEMMCStatus( pEMMCPara );
|
||||||
|
if(sta!=CMD_SUCCESS)
|
||||||
|
{
|
||||||
|
return OP_FAILED;
|
||||||
|
}
|
||||||
|
if(pEMMCPara->EMMCSecNum == 0xFFF)
|
||||||
|
{
|
||||||
|
sta = EMMCCardReadEXCSD( pEMMCPara, buf );
|
||||||
|
if(sta!=OP_SUCCESS) return OP_FAILED;
|
||||||
|
pEMMCPara->EMMCSecNum = *((PUINT32)&buf[212]); // SEC_COUNT [215:212] MSB-LSB
|
||||||
|
}
|
||||||
|
sta = EMMCSetBusWidth(pEMMCPara, 1);
|
||||||
|
if(sta!=CMD_SUCCESS) return OP_FAILED;
|
||||||
|
R8_EMMC_CONTROL = (R8_EMMC_CONTROL&~RB_EMMC_LW_MASK) | bLW_OP_DAT8; // 8line_mode
|
||||||
|
|
||||||
|
//switching frequency
|
||||||
|
while(!(R32_EMMC_STATUS & (1<<17)));
|
||||||
|
sta = EMMCSetHighSpeed(pEMMCPara);
|
||||||
|
if(sta!=CMD_SUCCESS) return OP_FAILED;
|
||||||
|
while(!(R32_EMMC_STATUS & (1<<17)));
|
||||||
|
//configure higher clock rate
|
||||||
|
R16_EMMC_CLK_DIV = RB_EMMC_CLKMode|
|
||||||
|
RB_EMMC_CLKOE |
|
||||||
|
4|RB_EMMC_PHASEINV;
|
||||||
|
return OP_SUCCESS;
|
||||||
|
}
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn EMMCIOTransErrorDeal
|
||||||
|
*
|
||||||
|
* @brief error processing
|
||||||
|
*
|
||||||
|
* @return OP_SUCCESS
|
||||||
|
*******************************************************************************/
|
||||||
|
UINT8 EMMCIOTransErrorDeal( PSD_PARAMETER pEMMCPara )
|
||||||
|
{
|
||||||
|
pEMMCPara->EMMCOpErr = R16_EMMC_INT_FG;
|
||||||
|
R16_EMMC_INT_FG = 0xffff;
|
||||||
|
|
||||||
|
return OP_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn EMMCCardReadEXCSD
|
||||||
|
*
|
||||||
|
* @brief read single section
|
||||||
|
*
|
||||||
|
* @param pEMMCPara
|
||||||
|
* Lbaaddr - section first address
|
||||||
|
*
|
||||||
|
* @return OP_SUCCESS
|
||||||
|
**/
|
||||||
|
UINT8 EMMCCardReadEXCSD( PSD_PARAMETER pEMMCPara, PUINT8 pRdatbuf )
|
||||||
|
{
|
||||||
|
UINT32 cmd_arg_val;
|
||||||
|
UINT16 cmd_set_val;
|
||||||
|
|
||||||
|
R32_EMMC_DMA_BEG1 = (UINT32)pRdatbuf;
|
||||||
|
R32_EMMC_TRAN_MODE = 0;
|
||||||
|
R32_EMMC_BLOCK_CFG = 512<<16 | 1;
|
||||||
|
|
||||||
|
cmd_arg_val = 0;
|
||||||
|
cmd_set_val = RB_EMMC_CKIDX |
|
||||||
|
RB_EMMC_CKCRC |
|
||||||
|
RESP_TYPE_48 |
|
||||||
|
EMMC_CMD8;
|
||||||
|
EMMCSendCmd(cmd_arg_val, cmd_set_val);
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
if(R16_EMMC_INT_FG & RB_EMMC_IF_TRANDONE) break;
|
||||||
|
if( pEMMCPara->EMMCOpErr ) return CMD_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
R16_EMMC_INT_FG = 0xffff;
|
||||||
|
|
||||||
|
return OP_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn EMMCCardReadOneSec
|
||||||
|
*
|
||||||
|
* @brief read single section
|
||||||
|
*
|
||||||
|
* @param pEMMCPara
|
||||||
|
* pRdatbuf -- read buffer address
|
||||||
|
* Lbaaddr
|
||||||
|
*
|
||||||
|
* @return OP_SUCCESS
|
||||||
|
**/
|
||||||
|
UINT8 EMMCCardReadOneSec( PSD_PARAMETER pEMMCPara, PUINT8 pRdatbuf, UINT32 Lbaaddr )
|
||||||
|
{
|
||||||
|
UINT32 cmd_arg_val;
|
||||||
|
UINT16 cmd_set_val;
|
||||||
|
|
||||||
|
if(Lbaaddr > (pEMMCPara->EMMCSecNum)) return OP_INVALID_ADD;
|
||||||
|
|
||||||
|
R32_EMMC_DMA_BEG1 = (UINT32)pRdatbuf;
|
||||||
|
R32_EMMC_TRAN_MODE = 0;
|
||||||
|
R32_EMMC_BLOCK_CFG = (pEMMCPara->EMMCSecSize)<<16 | 1;
|
||||||
|
|
||||||
|
cmd_arg_val = Lbaaddr;
|
||||||
|
cmd_set_val = RB_EMMC_CKIDX |
|
||||||
|
RB_EMMC_CKCRC |
|
||||||
|
RESP_TYPE_48 |
|
||||||
|
EMMC_CMD17;
|
||||||
|
EMMCSendCmd(cmd_arg_val, cmd_set_val);
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
if(R16_EMMC_INT_FG & RB_EMMC_IF_TRANDONE) break;
|
||||||
|
if( pEMMCPara->EMMCOpErr ) return CMD_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
R16_EMMC_INT_FG = 0xffff;
|
||||||
|
|
||||||
|
return OP_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn EMMCCardReadMulSec
|
||||||
|
*
|
||||||
|
* @brief read continuous multiple sections
|
||||||
|
*
|
||||||
|
* @param pEMMCPara -
|
||||||
|
* pReqnum - request continuous sections address
|
||||||
|
* pRdatbuf -
|
||||||
|
* Lbaaddr -
|
||||||
|
*
|
||||||
|
* @return OP_SUCCESS
|
||||||
|
*/
|
||||||
|
UINT8 EMMCCardReadMulSec( PSD_PARAMETER pEMMCPara, PUINT16 pReqnum, PUINT8 pRdatbuf, UINT32 Lbaaddr )
|
||||||
|
{
|
||||||
|
UINT32 cmd_arg_val;
|
||||||
|
UINT16 cmd_set_val;
|
||||||
|
UINT8 sta;
|
||||||
|
|
||||||
|
if(Lbaaddr > (pEMMCPara->EMMCSecNum)) return OP_INVALID_ADD;
|
||||||
|
|
||||||
|
R32_EMMC_DMA_BEG1 = (UINT32)pRdatbuf; //data buffer address
|
||||||
|
R32_EMMC_TRAN_MODE = 0; //EMMC to controller
|
||||||
|
R32_EMMC_BLOCK_CFG = (pEMMCPara->EMMCSecSize)<<16 | (*pReqnum);
|
||||||
|
|
||||||
|
//cmd18
|
||||||
|
cmd_arg_val = Lbaaddr;
|
||||||
|
cmd_set_val = RB_EMMC_CKIDX |
|
||||||
|
RB_EMMC_CKCRC |
|
||||||
|
RESP_TYPE_48 |
|
||||||
|
EMMC_CMD18;
|
||||||
|
EMMCSendCmd(cmd_arg_val, cmd_set_val);
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
if(R16_EMMC_INT_FG & RB_EMMC_IF_TRANDONE)
|
||||||
|
{
|
||||||
|
R16_EMMC_INT_FG = RB_EMMC_IF_CMDDONE;
|
||||||
|
//cmd12
|
||||||
|
cmd_arg_val = 0;
|
||||||
|
cmd_set_val = RB_EMMC_CKIDX |
|
||||||
|
RB_EMMC_CKCRC |
|
||||||
|
RESP_TYPE_R1b |
|
||||||
|
EMMC_CMD12;
|
||||||
|
EMMCSendCmd(cmd_arg_val, cmd_set_val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if( pEMMCPara->EMMCOpErr ) return CMD_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
sta = CheckCMDComp( pEMMCPara );
|
||||||
|
if( sta != CMD_NULL ) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
R16_EMMC_INT_FG = 0xffff;
|
||||||
|
*pReqnum = (UINT16)R32_EMMC_STATUS; // successfully transferred sections
|
||||||
|
|
||||||
|
return sta;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn EMMCCardWriteMulSec
|
||||||
|
* @brief write continuous multiple sections
|
||||||
|
* @param pSDPara -
|
||||||
|
* pReqnum -
|
||||||
|
* pWdatbuf -
|
||||||
|
* Lbaaddr -
|
||||||
|
* @return OP_SUCCESS
|
||||||
|
**/
|
||||||
|
UINT8 EMMCCardWriteMulSec( PSD_PARAMETER pEMMCPara, PUINT16 pReqnum, PUINT8 pWdatbuf, UINT32 Lbaaddr )
|
||||||
|
{
|
||||||
|
UINT32 cmd_arg_val;
|
||||||
|
UINT16 cmd_set_val;
|
||||||
|
UINT8 sta;
|
||||||
|
|
||||||
|
if(Lbaaddr > (pEMMCPara->EMMCSecNum)) return OP_INVALID_ADD;
|
||||||
|
|
||||||
|
//cmd25
|
||||||
|
cmd_arg_val = Lbaaddr;
|
||||||
|
cmd_set_val = RB_EMMC_CKIDX |
|
||||||
|
RB_EMMC_CKCRC |
|
||||||
|
RESP_TYPE_48 |
|
||||||
|
EMMC_CMD25;
|
||||||
|
EMMCSendCmd(cmd_arg_val, cmd_set_val);
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
sta = CheckCMDComp( pEMMCPara );
|
||||||
|
if( sta != CMD_NULL ) break;
|
||||||
|
}
|
||||||
|
if( sta == CMD_FAILED ) return OP_FAILED;
|
||||||
|
|
||||||
|
//DAT
|
||||||
|
|
||||||
|
R32_EMMC_TRAN_MODE = RB_EMMC_DMA_DIR;
|
||||||
|
R32_EMMC_DMA_BEG1 = (UINT32)pWdatbuf;
|
||||||
|
R32_EMMC_BLOCK_CFG = (pEMMCPara->EMMCSecSize)<<16 | (*pReqnum);
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
if(R16_EMMC_INT_FG & RB_EMMC_IF_BKGAP)
|
||||||
|
{
|
||||||
|
R32_EMMC_RESPONSE3 = 0;
|
||||||
|
R16_EMMC_INT_FG = RB_EMMC_IF_BKGAP;
|
||||||
|
}
|
||||||
|
else if(R16_EMMC_INT_FG & RB_EMMC_IF_TRANDONE)
|
||||||
|
{
|
||||||
|
R16_EMMC_INT_FG = RB_EMMC_IF_CMDDONE;
|
||||||
|
//cmd12
|
||||||
|
cmd_arg_val = 0;
|
||||||
|
cmd_set_val = RB_EMMC_CKIDX |
|
||||||
|
RB_EMMC_CKCRC |
|
||||||
|
RESP_TYPE_R1b |
|
||||||
|
EMMC_CMD12;
|
||||||
|
EMMCSendCmd(cmd_arg_val, cmd_set_val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if( pEMMCPara->EMMCOpErr ) return CMD_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
sta = CheckCMDComp( pEMMCPara );
|
||||||
|
if( sta != CMD_NULL ) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
R16_EMMC_INT_FG = 0xffff;
|
||||||
|
*pReqnum = (UINT16)R32_EMMC_STATUS;
|
||||||
|
|
||||||
|
return sta;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn AES_EMMCWriteMulSec
|
||||||
|
*
|
||||||
|
* @brief Write continuous multiple sections
|
||||||
|
*
|
||||||
|
* @param pEMMCPara - SD information structure pointer
|
||||||
|
* pReqnum - Request to the sector number variable address consecutively
|
||||||
|
* pWdatbuf - Write to the data cache address
|
||||||
|
* Lbaaddr - Write the sector head address continuously
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
***/
|
||||||
|
UINT8 AES_EMMCWriteMulSec( PSD_PARAMETER pEMMCPara, PUINT32 pReqnum, PUINT32 pWdatbuf, UINT32 Lbaaddr, UINT8 excutemode, UINT8 endianmode, PUINT32 pcount)
|
||||||
|
{
|
||||||
|
UINT32 cmd_arg_val;
|
||||||
|
UINT16 cmd_set_val;
|
||||||
|
UINT8 sta;
|
||||||
|
|
||||||
|
if(Lbaaddr > (pEMMCPara->EMMCSecNum)) return OP_INVALID_ADD;
|
||||||
|
|
||||||
|
//cmd25
|
||||||
|
cmd_arg_val = Lbaaddr;
|
||||||
|
cmd_set_val = RB_EMMC_CKIDX |
|
||||||
|
RB_EMMC_CKCRC |
|
||||||
|
RESP_TYPE_48 |
|
||||||
|
EMMC_CMD25;
|
||||||
|
EMMCSendCmd(cmd_arg_val, cmd_set_val);
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
sta = CheckCMDComp( pEMMCPara );
|
||||||
|
if( sta != CMD_NULL ) break;
|
||||||
|
}
|
||||||
|
if( sta == CMD_FAILED ) return OP_FAILED;
|
||||||
|
|
||||||
|
//DAT
|
||||||
|
|
||||||
|
ECDC_Excute(excutemode, endianmode);
|
||||||
|
|
||||||
|
R32_EMMC_TRAN_MODE |= RB_EMMC_DMA_DIR;
|
||||||
|
R32_EMMC_DMA_BEG1 = (UINT32)pWdatbuf;
|
||||||
|
R32_EMMC_BLOCK_CFG = (pEMMCPara->EMMCSecSize)<<16 | (*pReqnum);
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
if(R16_EMMC_INT_FG & RB_EMMC_IF_BKGAP)
|
||||||
|
{
|
||||||
|
///////////////////////////////////////////////CTR mode
|
||||||
|
if(R16_ECEC_CTRL & RB_ECDC_CIPHER_MOD)
|
||||||
|
ECDC_RloadCount( excutemode, endianmode, pcount );
|
||||||
|
|
||||||
|
R32_EMMC_RESPONSE3 = 0; //start transform
|
||||||
|
R16_EMMC_INT_FG |= RB_EMMC_IF_BKGAP;
|
||||||
|
}
|
||||||
|
else if(R16_EMMC_INT_FG & RB_EMMC_IF_TRANDONE)
|
||||||
|
{
|
||||||
|
R16_EMMC_INT_FG = RB_EMMC_IF_CMDDONE;
|
||||||
|
//cmd12
|
||||||
|
cmd_arg_val = 0;
|
||||||
|
cmd_set_val = RB_EMMC_CKIDX |
|
||||||
|
RB_EMMC_CKCRC |
|
||||||
|
RESP_TYPE_R1b |
|
||||||
|
EMMC_CMD12;
|
||||||
|
EMMCSendCmd(cmd_arg_val, cmd_set_val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if( pEMMCPara->EMMCOpErr ) return CMD_FAILED;
|
||||||
|
}
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
sta = CheckCMDComp( pEMMCPara );
|
||||||
|
if( sta != CMD_NULL ) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
R16_EMMC_INT_FG = 0xffff;
|
||||||
|
*pReqnum = (UINT16)R32_EMMC_STATUS; //the number of blocks transferred successfully
|
||||||
|
|
||||||
|
return sta;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn AES_EMMCReadMulSec
|
||||||
|
*
|
||||||
|
* @brief Read continuous multiple sections
|
||||||
|
*
|
||||||
|
* @param pEMMCPara - SD information structure pointer
|
||||||
|
* pReqnum - Request to the sector number variable address consecutively
|
||||||
|
* pWdatbuf - Write to the data cache address
|
||||||
|
* Lbaaddr - Write the sector head address continuously
|
||||||
|
*
|
||||||
|
* @return OP_SUCCESS - suc
|
||||||
|
* other - err
|
||||||
|
**/
|
||||||
|
UINT8 AES_EMMCReadMulSec( PSD_PARAMETER pEMMCPara, PUINT32 pReqnum, PUINT32 pRdatbuf, UINT32 Lbaaddr, UINT8 excutemode, UINT8 endianmode, PUINT32 pcount)
|
||||||
|
{
|
||||||
|
UINT32 cmd_arg_val;
|
||||||
|
UINT16 cmd_set_val;
|
||||||
|
|
||||||
|
if(Lbaaddr > (pEMMCPara->EMMCSecNum)) return OP_INVALID_ADD;
|
||||||
|
|
||||||
|
//CTR mode.Once the transmission is completed ,turn off the clock.
|
||||||
|
if(R16_ECEC_CTRL & RB_ECDC_CIPHER_MOD)
|
||||||
|
{
|
||||||
|
R16_ECEC_CTRL &= 0xFFF9; //bit2 and bit3 set 0
|
||||||
|
ECDC_SetCount(pcount);
|
||||||
|
R32_EMMC_TRAN_MODE |= RB_EMMC_AUTOGAPSTOP | RB_EMMC_GAP_STOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
ECDC_Excute(excutemode, endianmode);
|
||||||
|
|
||||||
|
R32_EMMC_DMA_BEG1 = (UINT32)pRdatbuf;
|
||||||
|
R32_EMMC_TRAN_MODE &= ~RB_EMMC_DMA_DIR;
|
||||||
|
R32_EMMC_BLOCK_CFG = (pEMMCPara->EMMCSecSize)<<16 | (*pReqnum);
|
||||||
|
|
||||||
|
//cmd18
|
||||||
|
cmd_arg_val = Lbaaddr;
|
||||||
|
cmd_set_val = RB_EMMC_CKIDX |
|
||||||
|
RB_EMMC_CKCRC |
|
||||||
|
RESP_TYPE_48 |
|
||||||
|
EMMC_CMD18;
|
||||||
|
EMMCSendCmd(cmd_arg_val, cmd_set_val);
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
if(R16_ECEC_CTRL & RB_ECDC_CIPHER_MOD)
|
||||||
|
{
|
||||||
|
if(R16_EMMC_INT_FG & RB_EMMC_IF_BKGAP)
|
||||||
|
{
|
||||||
|
/* CTR mode */
|
||||||
|
if(R16_ECEC_CTRL & RB_ECDC_CIPHER_MOD)
|
||||||
|
ECDC_RloadCount( excutemode, endianmode, pcount );
|
||||||
|
|
||||||
|
R32_EMMC_TRAN_MODE &= ~RB_EMMC_GAP_STOP;
|
||||||
|
R16_EMMC_INT_FG |= RB_EMMC_IF_BKGAP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(R16_EMMC_INT_FG & RB_EMMC_IF_TRANDONE) break;
|
||||||
|
if( pEMMCPara->EMMCOpErr ) return CMD_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
R16_EMMC_INT_FG = 0xffff;
|
||||||
|
*pReqnum = (UINT16)R32_EMMC_STATUS; //the number of blocks transferred successfully
|
||||||
|
|
||||||
|
return OP_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,315 @@
|
||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : CH56x_eth.c
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0
|
||||||
|
* Date : 2023/03/03
|
||||||
|
* Description : This file provides all the ETH firmware functions.
|
||||||
|
*********************************************************************************
|
||||||
|
* 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 "CH56x_common.h"
|
||||||
|
|
||||||
|
ETH_DMADESCTypeDef *DMATxDescToSet;
|
||||||
|
ETH_DMADESCTypeDef *DMARxDescToGet;
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn ETH_StructInit
|
||||||
|
*
|
||||||
|
* @brief Fills each ETH_InitStruct member with its default value.
|
||||||
|
*
|
||||||
|
* @param ETH_InitStruct - pointer to a ETH_InitTypeDef structure
|
||||||
|
* which will be initialized.
|
||||||
|
*
|
||||||
|
* @return none
|
||||||
|
*/
|
||||||
|
void ETH_StructInit(ETH_InitTypeDef *ETH_InitStruct)
|
||||||
|
{
|
||||||
|
/*------------------------ MAC -----------------------------------*/
|
||||||
|
ETH_InitStruct->ETH_AutoNegotiation = ETH_AutoNegotiation_Disable;
|
||||||
|
ETH_InitStruct->ETH_Watchdog = ETH_Watchdog_Enable;
|
||||||
|
ETH_InitStruct->ETH_Jabber = ETH_Jabber_Enable;
|
||||||
|
ETH_InitStruct->ETH_InterFrameGap = ETH_InterFrameGap_96Bit;
|
||||||
|
ETH_InitStruct->ETH_CarrierSense = ETH_CarrierSense_Enable;
|
||||||
|
ETH_InitStruct->ETH_Speed = ETH_Speed_10M;
|
||||||
|
ETH_InitStruct->ETH_ReceiveOwn = ETH_ReceiveOwn_Enable;
|
||||||
|
ETH_InitStruct->ETH_LoopbackMode = ETH_LoopbackMode_Disable;
|
||||||
|
ETH_InitStruct->ETH_Mode = ETH_Mode_HalfDuplex;
|
||||||
|
ETH_InitStruct->ETH_ChecksumOffload = ETH_ChecksumOffload_Disable;
|
||||||
|
ETH_InitStruct->ETH_RetryTransmission = ETH_RetryTransmission_Enable;
|
||||||
|
ETH_InitStruct->ETH_AutomaticPadCRCStrip = ETH_AutomaticPadCRCStrip_Disable;
|
||||||
|
ETH_InitStruct->ETH_BackOffLimit = ETH_BackOffLimit_10;
|
||||||
|
ETH_InitStruct->ETH_DeferralCheck = ETH_DeferralCheck_Disable;
|
||||||
|
ETH_InitStruct->ETH_ReceiveAll = ETH_ReceiveAll_Disable;
|
||||||
|
ETH_InitStruct->ETH_SourceAddrFilter = ETH_SourceAddrFilter_Disable;
|
||||||
|
ETH_InitStruct->ETH_PassControlFrames = ETH_PassControlFrames_BlockAll;
|
||||||
|
ETH_InitStruct->ETH_BroadcastFramesReception = ETH_BroadcastFramesReception_Disable;
|
||||||
|
ETH_InitStruct->ETH_DestinationAddrFilter = ETH_DestinationAddrFilter_Normal;
|
||||||
|
ETH_InitStruct->ETH_PromiscuousMode = ETH_PromiscuousMode_Disable;
|
||||||
|
ETH_InitStruct->ETH_MulticastFramesFilter = ETH_MulticastFramesFilter_Perfect;
|
||||||
|
ETH_InitStruct->ETH_UnicastFramesFilter = ETH_UnicastFramesFilter_Perfect;
|
||||||
|
ETH_InitStruct->ETH_HashTableHigh = 0x0;
|
||||||
|
ETH_InitStruct->ETH_HashTableLow = 0x0;
|
||||||
|
ETH_InitStruct->ETH_PauseTime = 0x0;
|
||||||
|
ETH_InitStruct->ETH_ZeroQuantaPause = ETH_ZeroQuantaPause_Disable;
|
||||||
|
ETH_InitStruct->ETH_PauseLowThreshold = ETH_PauseLowThreshold_Minus4;
|
||||||
|
ETH_InitStruct->ETH_UnicastPauseFrameDetect = ETH_UnicastPauseFrameDetect_Disable;
|
||||||
|
ETH_InitStruct->ETH_ReceiveFlowControl = ETH_ReceiveFlowControl_Disable;
|
||||||
|
ETH_InitStruct->ETH_TransmitFlowControl = ETH_TransmitFlowControl_Disable;
|
||||||
|
ETH_InitStruct->ETH_VLANTagComparison = ETH_VLANTagComparison_16Bit;
|
||||||
|
ETH_InitStruct->ETH_VLANTagIdentifier = 0x0;
|
||||||
|
/*------------------------ DMA -----------------------------------*/
|
||||||
|
ETH_InitStruct->ETH_DropTCPIPChecksumErrorFrame = ETH_DropTCPIPChecksumErrorFrame_Disable;
|
||||||
|
ETH_InitStruct->ETH_ReceiveStoreForward = ETH_ReceiveStoreForward_Enable;
|
||||||
|
ETH_InitStruct->ETH_FlushReceivedFrame = ETH_FlushReceivedFrame_Enable;
|
||||||
|
ETH_InitStruct->ETH_TransmitStoreForward = ETH_TransmitStoreForward_Enable;
|
||||||
|
ETH_InitStruct->ETH_TransmitThresholdControl = ETH_TransmitThresholdControl_64Bytes;
|
||||||
|
ETH_InitStruct->ETH_ForwardErrorFrames = ETH_ForwardErrorFrames_Disable;
|
||||||
|
ETH_InitStruct->ETH_ForwardUndersizedGoodFrames = ETH_ForwardUndersizedGoodFrames_Disable;
|
||||||
|
ETH_InitStruct->ETH_ReceiveThresholdControl = ETH_ReceiveThresholdControl_64Bytes;
|
||||||
|
ETH_InitStruct->ETH_SecondFrameOperate = ETH_SecondFrameOperate_Disable;
|
||||||
|
ETH_InitStruct->ETH_AddressAlignedBeats = ETH_AddressAlignedBeats_Enable;
|
||||||
|
ETH_InitStruct->ETH_FixedBurst = ETH_FixedBurst_Disable;
|
||||||
|
ETH_InitStruct->ETH_RxDMABurstLength = ETH_RxDMABurstLength_1Beat;
|
||||||
|
ETH_InitStruct->ETH_TxDMABurstLength = ETH_TxDMABurstLength_1Beat;
|
||||||
|
ETH_InitStruct->ETH_DescriptorSkipLength = 0x0;
|
||||||
|
ETH_InitStruct->ETH_DMAArbitration = ETH_DMAArbitration_RoundRobin_RxTx_1_1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn ETH_SoftwareReset
|
||||||
|
*
|
||||||
|
* @brief ETH software reset
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void ETH_SoftwareReset(void)
|
||||||
|
{
|
||||||
|
/* Set the SWR bit: resets all MAC subsystem internal registers and logic */
|
||||||
|
/* After reset all the registers holds their respective reset values */
|
||||||
|
ETH->DMABMR |= ETH_DMABMR_SR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn RGMII_TXC_Delay
|
||||||
|
*
|
||||||
|
* @brief ETH send clock polarity and timing adjustment
|
||||||
|
*
|
||||||
|
* @param clock_polarity - send clock polarity
|
||||||
|
* delay_time - delay time(unit - half nanosecond)
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void RGMII_TXC_Delay(uint8_t clock_polarity,uint8_t delay_time)
|
||||||
|
{
|
||||||
|
if(clock_polarity)
|
||||||
|
ETH->MACCR |= (uint32_t)(1<<1);
|
||||||
|
else
|
||||||
|
ETH->MACCR &= ~(uint32_t)(1<<1);
|
||||||
|
|
||||||
|
if(delay_time <= 7)
|
||||||
|
ETH->MACCR |= (uint32_t)(delay_time<<29);
|
||||||
|
else
|
||||||
|
printf("Error:delay_time is out of range!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn ETH_ReadPHYRegister
|
||||||
|
*
|
||||||
|
* @brief Read PHY register
|
||||||
|
*
|
||||||
|
* @param PHYAddress - PHY address
|
||||||
|
* PHYReg - PHY register address
|
||||||
|
*
|
||||||
|
* @return Value of PHY register
|
||||||
|
*/
|
||||||
|
uint16_t ETH_ReadPHYRegister(uint16_t PHYAddress, uint16_t PHYReg)
|
||||||
|
{
|
||||||
|
uint32_t tmpreg = 0;
|
||||||
|
uint32_t timeout = 0;
|
||||||
|
|
||||||
|
/* Get the ETHERNET MACMIIAR value */
|
||||||
|
tmpreg = ETH->MACMIIAR;
|
||||||
|
/* Keep only the CSR Clock Range CR[2:0] bits value */
|
||||||
|
tmpreg &= ~MACMIIAR_CR_MASK;
|
||||||
|
/* Prepare the MII address register value */
|
||||||
|
tmpreg |= (((uint32_t)PHYAddress<<11) & ETH_MACMIIAR_PA); /* Set the PHY device address */
|
||||||
|
tmpreg |= (((uint32_t)PHYReg<<6) & ETH_MACMIIAR_MR); /* Set the PHY register address */
|
||||||
|
tmpreg &= ~ETH_MACMIIAR_MW; /* Set the read mode */
|
||||||
|
tmpreg |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */
|
||||||
|
/* Write the result value into the MII Address register */
|
||||||
|
ETH->MACMIIAR = tmpreg;
|
||||||
|
/* Check for the Busy flag */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
timeout++;
|
||||||
|
tmpreg = ETH->MACMIIAR;
|
||||||
|
} while ((tmpreg & ETH_MACMIIAR_MB) && (timeout < (uint32_t)PHY_READ_TO));
|
||||||
|
/* Return ERROR in case of timeout */
|
||||||
|
if(timeout == PHY_READ_TO)
|
||||||
|
{
|
||||||
|
return (uint16_t)ETH_ERROR;
|
||||||
|
}
|
||||||
|
/* Return data register value */
|
||||||
|
return (uint16_t)(ETH->MACMIIDR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn ETH_WritePHYRegister
|
||||||
|
*
|
||||||
|
* @brief Write PHY register
|
||||||
|
*
|
||||||
|
* @param PHYAddress - PHY address
|
||||||
|
* PHYReg - PHY register address
|
||||||
|
* PHYValue - Value will be written of PHY register
|
||||||
|
*
|
||||||
|
* @return Execution status
|
||||||
|
*/
|
||||||
|
uint32_t ETH_WritePHYRegister(uint16_t PHYAddress, uint16_t PHYReg, uint16_t PHYValue)
|
||||||
|
{
|
||||||
|
uint32_t tmpreg = 0;
|
||||||
|
uint32_t timeout = 0;
|
||||||
|
|
||||||
|
/* Get the ETHERNET MACMIIAR value */
|
||||||
|
tmpreg = ETH->MACMIIAR;
|
||||||
|
/* Keep only the CSR Clock Range CR[2:0] bits value */
|
||||||
|
tmpreg &= ~MACMIIAR_CR_MASK;
|
||||||
|
/* Prepare the MII register address value */
|
||||||
|
tmpreg |= (((uint32_t)PHYAddress<<11) & ETH_MACMIIAR_PA); /* Set the PHY device address */
|
||||||
|
tmpreg |= (((uint32_t)PHYReg<<6) & ETH_MACMIIAR_MR); /* Set the PHY register address */
|
||||||
|
tmpreg |= ETH_MACMIIAR_MW; /* Set the write mode */
|
||||||
|
tmpreg |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */
|
||||||
|
/* Give the value to the MII data register */
|
||||||
|
ETH->MACMIIDR = PHYValue;
|
||||||
|
/* Write the result value into the MII Address register */
|
||||||
|
ETH->MACMIIAR = tmpreg;
|
||||||
|
/* Check for the Busy flag */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
timeout++;
|
||||||
|
tmpreg = ETH->MACMIIAR;
|
||||||
|
} while ((tmpreg & ETH_MACMIIAR_MB) && (timeout < (uint32_t)PHY_WRITE_TO));
|
||||||
|
/* Return ERROR in case of timeout */
|
||||||
|
if(timeout == PHY_WRITE_TO)
|
||||||
|
{
|
||||||
|
return ETH_ERROR;
|
||||||
|
}
|
||||||
|
/* Return SUCCESS */
|
||||||
|
return ETH_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn ETH_DMAITConfig
|
||||||
|
*
|
||||||
|
* @brief Configuration DMA interrupt
|
||||||
|
*
|
||||||
|
* @param ETH_DMA_IT - Type of DMA interrupt
|
||||||
|
* NewState - Enable DMA interrupt or Disable DMA interrupt
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void ETH_DMAITConfig(uint32_t ETH_DMA_IT, FunctionalState NewState)
|
||||||
|
{
|
||||||
|
if (NewState != DISABLE)
|
||||||
|
{
|
||||||
|
/* Enable the selected ETHERNET DMA interrupts */
|
||||||
|
ETH->DMAIER |= ETH_DMA_IT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Disable the selected ETHERNET DMA interrupts */
|
||||||
|
ETH->DMAIER &= ~(uint32_t)ETH_DMA_IT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn ETH_DMAClearITPendingBit
|
||||||
|
*
|
||||||
|
* @brief Clear DMA interrupt flag
|
||||||
|
*
|
||||||
|
* @param ETH_DMA_IT - Type of DMA interrupt
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void ETH_DMAClearITPendingBit(uint32_t ETH_DMA_IT)
|
||||||
|
{
|
||||||
|
/* Clear the selected ETHERNET DMA IT */
|
||||||
|
ETH->DMASR = (uint32_t) ETH_DMA_IT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn ETH_DMATxDescChainInit
|
||||||
|
*
|
||||||
|
* @brief transmit descriptor initialization
|
||||||
|
*
|
||||||
|
* @param DMARxDescTab - pointer to the transmit descriptor table
|
||||||
|
* RxBuff - pointer to the transmit buffer (transmit queue)
|
||||||
|
* RxBuffCount - Number of transmit descriptor or transmit queue
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void ETH_DMATxDescChainInit(ETH_DMADESCTypeDef *DMATxDescTab, uint8_t* TxBuff, uint32_t TxBuffCount)
|
||||||
|
{
|
||||||
|
uint8_t i = 0;
|
||||||
|
ETH_DMADESCTypeDef *DMATxDesc;
|
||||||
|
|
||||||
|
DMATxDescToSet = DMATxDescTab;
|
||||||
|
|
||||||
|
for(i = 0; i < TxBuffCount; i++)
|
||||||
|
{
|
||||||
|
DMATxDesc = DMATxDescTab + i;
|
||||||
|
DMATxDesc->Status = ETH_DMATxDesc_TCH | ETH_DMATxDesc_IC;
|
||||||
|
DMATxDesc->Buffer1Addr = (uint32_t)(&TxBuff[i * ETH_MAX_PACKET_SIZE]);
|
||||||
|
|
||||||
|
if(i < (TxBuffCount - 1))
|
||||||
|
{
|
||||||
|
DMATxDesc->Buffer2NextDescAddr = (uint32_t)(DMATxDescTab + i + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DMATxDesc->Buffer2NextDescAddr = (uint32_t)DMATxDescTab;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ETH->DMATDLAR = (uint32_t)DMATxDescTab;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn ETH_DMARxDescChainInit
|
||||||
|
*
|
||||||
|
* @brief Receive descriptor initialization
|
||||||
|
*
|
||||||
|
* @param DMARxDescTab - pointer to the receive descriptor table
|
||||||
|
* RxBuff - pointer to the receive buffer (receive queue)
|
||||||
|
* RxBuffCount - Number of receive descriptor or receive queue
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
**/
|
||||||
|
void ETH_DMARxDescChainInit(ETH_DMADESCTypeDef *DMARxDescTab, uint8_t *RxBuff, uint32_t RxBuffCount)
|
||||||
|
{
|
||||||
|
uint8_t i = 0;
|
||||||
|
ETH_DMADESCTypeDef *DMARxDesc;
|
||||||
|
|
||||||
|
DMARxDescToGet = DMARxDescTab;
|
||||||
|
|
||||||
|
for(i = 0; i < RxBuffCount; i++)
|
||||||
|
{
|
||||||
|
DMARxDesc = DMARxDescTab + i;
|
||||||
|
DMARxDesc->Status = ETH_DMARxDesc_OWN;
|
||||||
|
DMARxDesc->ControlBufferSize = (uint32_t)ETH_MAX_PACKET_SIZE;
|
||||||
|
DMARxDesc->Buffer1Addr = (uint32_t)(&RxBuff[i * ETH_MAX_PACKET_SIZE]);
|
||||||
|
|
||||||
|
if(i < (RxBuffCount - 1))
|
||||||
|
{
|
||||||
|
DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab + i + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ETH->DMARDLAR = (uint32_t)DMARxDescTab;
|
||||||
|
}
|
|
@ -0,0 +1,523 @@
|
||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : CH56x_gpio.c
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0
|
||||||
|
* Date : 2020/07/31
|
||||||
|
* Description :
|
||||||
|
*********************************************************************************
|
||||||
|
* 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 "CH56x_common.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn GPIOA_ModeCfg
|
||||||
|
*
|
||||||
|
* @brief GPIOA port pin mode configuration
|
||||||
|
*
|
||||||
|
* @param pin - PA0-PA15
|
||||||
|
* GPIO_Pin_0 - GPIO_Pin_15
|
||||||
|
* mode -
|
||||||
|
* GPIO_ModeIN_Floating - Floating input/high impedance input
|
||||||
|
* GPIO_ModeIN_PU_NSMT - Input with pull-up resistor
|
||||||
|
* GPIO_ModeIN_PD_NSMT - Input with pull-down resistor
|
||||||
|
* GPIO_ModeIN_PU_SMT - Schmitt input with pull-up resistor
|
||||||
|
* GPIO_ModeIN_PD_SMT - Schmitt input with pull-down resistor
|
||||||
|
* GPIO_Slowascent_PP_8mA - Low slope push-pull output, drive capability 8mA level
|
||||||
|
* GPIO_Slowascent_PP_16mA - Low slope push-pull output, drive capability 16mA level
|
||||||
|
* GPIO_Highspeed_PP_8mA - Fast push-pull output, drive capability 8mA level
|
||||||
|
* GPIO_Highspeed_PP_16mA - Fast push-pull output, drive capability 16mA level
|
||||||
|
* GPIO_ModeOut_OP_8mA - Push-pull output up to 8mA
|
||||||
|
* GPIO_ModeOut_OP_16mA - Push-pull output up to 16mA
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void GPIOA_ModeCfg( UINT32 pin, GPIOModeTypeDef mode )
|
||||||
|
{
|
||||||
|
switch(mode)
|
||||||
|
{
|
||||||
|
case GPIO_ModeIN_Floating:
|
||||||
|
R32_PA_PD &= ~pin;
|
||||||
|
R32_PA_PU &= ~pin;
|
||||||
|
R32_PA_DIR &= ~pin;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GPIO_ModeIN_PU_NSMT:
|
||||||
|
R32_PA_SMT &=~ pin;
|
||||||
|
R32_PA_PD &= ~pin;
|
||||||
|
R32_PA_PU |= pin;
|
||||||
|
R32_PA_DIR &= ~pin;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GPIO_ModeIN_PD_NSMT:
|
||||||
|
R32_PA_SMT &=~ pin;
|
||||||
|
R32_PA_PD |= pin;
|
||||||
|
R32_PA_PU &= ~pin;
|
||||||
|
R32_PA_DIR &= ~pin;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GPIO_ModeIN_PU_SMT:
|
||||||
|
R32_PA_SMT |= pin;
|
||||||
|
R32_PA_PD &= ~pin;
|
||||||
|
R32_PA_PU |= pin;
|
||||||
|
R32_PA_DIR &= ~pin;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GPIO_ModeIN_PD_SMT:
|
||||||
|
R32_PA_SMT |= pin;
|
||||||
|
R32_PA_PD |= pin;
|
||||||
|
R32_PA_PU &= ~pin;
|
||||||
|
R32_PA_DIR &= ~pin;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GPIO_Slowascent_PP_8mA:
|
||||||
|
R32_PA_SMT |= pin;
|
||||||
|
R32_PA_DRV &= ~pin;
|
||||||
|
R32_PA_PD &= ~pin;
|
||||||
|
R32_PA_DIR |= pin;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GPIO_Slowascent_PP_16mA:
|
||||||
|
R32_PA_SMT |= pin;
|
||||||
|
R32_PA_DRV |= pin;
|
||||||
|
R32_PA_PD &= ~pin;
|
||||||
|
R32_PA_DIR |= pin;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GPIO_Highspeed_PP_8mA:
|
||||||
|
R32_PA_SMT &= ~pin;
|
||||||
|
R32_PA_DRV &= ~pin;
|
||||||
|
R32_PA_PD &= ~pin;
|
||||||
|
R32_PA_DIR |= pin;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GPIO_Highspeed_PP_16mA:
|
||||||
|
R32_PA_SMT &= ~pin;
|
||||||
|
R32_PA_DRV |= pin;
|
||||||
|
R32_PA_PD &= ~pin;
|
||||||
|
R32_PA_DIR |= pin;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GPIO_ModeOut_OP_8mA:
|
||||||
|
R32_PA_DRV &= ~pin;
|
||||||
|
R32_PA_PD |= pin;
|
||||||
|
R32_PA_DIR |= pin;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GPIO_ModeOut_OP_16mA:
|
||||||
|
R32_PA_DRV |= pin;
|
||||||
|
R32_PA_PD |= pin;
|
||||||
|
R32_PA_DIR |= pin;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn GPIOB_ModeCfg
|
||||||
|
*
|
||||||
|
* @brief GPIOB port pin mode configuration
|
||||||
|
*
|
||||||
|
* @param pin - PB0-PB15
|
||||||
|
* GPIO_Pin_0 - GPIO_Pin_15
|
||||||
|
* mode -
|
||||||
|
* GPIO_ModeIN_Floating - Floating input/high impedance input
|
||||||
|
* GPIO_ModeIN_PU_NSMT - Input with pull-up resistor
|
||||||
|
* GPIO_ModeIN_PD_NSMT - Input with pull-down resistor
|
||||||
|
* GPIO_ModeIN_PU_SMT - Schmitt input with pull-up resistor
|
||||||
|
* GPIO_ModeIN_PD_SMT - Schmitt input with pull-down resistor
|
||||||
|
* GPIO_Slowascent_PP_8mA - Low slope push-pull output, drive capability 8mA level
|
||||||
|
* GPIO_Slowascent_PP_16mA - Low slope push-pull output, drive capability 16mA level
|
||||||
|
* GPIO_Highspeed_PP_8mA - Fast push-pull output, drive capability 8mA level
|
||||||
|
* GPIO_Highspeed_PP_16mA - Fast push-pull output, drive capability 16mA level
|
||||||
|
* GPIO_ModeOut_OP_8mA - Push-pull output up to 8mA
|
||||||
|
* GPIO_ModeOut_OP_16mA - Push-pull output up to 16mA
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
|
||||||
|
void GPIOB_ModeCfg( UINT32 pin, GPIOModeTypeDef mode )
|
||||||
|
{
|
||||||
|
switch(mode)
|
||||||
|
{
|
||||||
|
case GPIO_ModeIN_Floating:
|
||||||
|
R32_PB_PD &= ~pin;
|
||||||
|
R32_PB_PU &= ~pin;
|
||||||
|
R32_PB_DIR &= ~pin;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GPIO_ModeIN_PU_NSMT:
|
||||||
|
R32_PB_SMT &=~ pin;
|
||||||
|
R32_PB_PD &= ~pin;
|
||||||
|
R32_PB_PU |= pin;
|
||||||
|
R32_PB_DIR &= ~pin;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GPIO_ModeIN_PD_NSMT:
|
||||||
|
R32_PB_SMT &=~ pin;
|
||||||
|
R32_PB_PD |= pin;
|
||||||
|
R32_PB_PU &= ~pin;
|
||||||
|
R32_PB_DIR &= ~pin;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GPIO_ModeIN_PU_SMT:
|
||||||
|
R32_PB_SMT |= pin;
|
||||||
|
R32_PB_PD &= ~pin;
|
||||||
|
R32_PB_PU |= pin;
|
||||||
|
R32_PB_DIR &= ~pin;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GPIO_ModeIN_PD_SMT:
|
||||||
|
R32_PB_SMT |= pin;
|
||||||
|
R32_PB_PD |= pin;
|
||||||
|
R32_PB_PU &= ~pin;
|
||||||
|
R32_PB_DIR &= ~pin;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GPIO_Slowascent_PP_8mA:
|
||||||
|
R32_PB_SMT |= pin;
|
||||||
|
R32_PB_DRV &= ~pin;
|
||||||
|
R32_PB_PD &= ~pin;
|
||||||
|
R32_PB_DIR |= pin;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GPIO_Slowascent_PP_16mA:
|
||||||
|
R32_PB_SMT |= pin;
|
||||||
|
R32_PB_DRV |= pin;
|
||||||
|
R32_PB_PD &= ~pin;
|
||||||
|
R32_PB_DIR |= pin;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GPIO_Highspeed_PP_8mA:
|
||||||
|
R32_PB_SMT &= ~pin;
|
||||||
|
R32_PB_DRV &= ~pin;
|
||||||
|
R32_PB_PD &= ~pin;
|
||||||
|
R32_PB_DIR |= pin;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GPIO_Highspeed_PP_16mA:
|
||||||
|
R32_PB_SMT &= ~pin;
|
||||||
|
R32_PB_DRV |= pin;
|
||||||
|
R32_PB_PD &= ~pin;
|
||||||
|
R32_PB_DIR |= pin;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GPIO_ModeOut_OP_8mA:
|
||||||
|
R32_PB_DRV &= ~pin;
|
||||||
|
R32_PB_PD |= pin;
|
||||||
|
R32_PB_DIR |= pin;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GPIO_ModeOut_OP_16mA:
|
||||||
|
R32_PB_DRV |= pin;
|
||||||
|
R32_PB_PD |= pin;
|
||||||
|
R32_PB_DIR |= pin;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn GPIOA_ITModeCfg
|
||||||
|
*
|
||||||
|
* @brief GPIOA pin interrupt mode configuration
|
||||||
|
*
|
||||||
|
* @param pin - PA2-PA4
|
||||||
|
* mode -
|
||||||
|
* GPIO_ITMode_LowLevel - Low level trigger
|
||||||
|
* GPIO_ITMode_HighLevel - High level trigger
|
||||||
|
* GPIO_ITMode_FallEdge - Falling edge trigger
|
||||||
|
* GPIO_ITMode_RiseEdge - Rising edge trigger
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void GPIOA_ITModeCfg( UINT32 pin, GPIOITModeTpDef mode )
|
||||||
|
{
|
||||||
|
switch( mode )
|
||||||
|
{
|
||||||
|
case GPIO_ITMode_LowLevel: // Low level trigger
|
||||||
|
R32_PA_DIR &= ~pin;
|
||||||
|
R8_GPIO_INT_MODE &= ~(pin>>2);
|
||||||
|
R8_GPIO_INT_POLAR &= ~(pin>>2);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GPIO_ITMode_HighLevel: // High level trigger
|
||||||
|
R32_PA_DIR &= ~pin;
|
||||||
|
R8_GPIO_INT_MODE &= ~(pin>>2);
|
||||||
|
R8_GPIO_INT_POLAR |= (pin>>2);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GPIO_ITMode_FallEdge: // Falling edge trigger
|
||||||
|
R32_PA_DIR &= ~pin;
|
||||||
|
R8_GPIO_INT_MODE |= (pin>>2);
|
||||||
|
R8_GPIO_INT_POLAR &= ~(pin>>2);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GPIO_ITMode_RiseEdge: // Rising edge trigger
|
||||||
|
R32_PA_DIR &= ~pin;
|
||||||
|
R8_GPIO_INT_MODE |= (pin>>2);
|
||||||
|
R8_GPIO_INT_POLAR |= (pin>>2);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default :
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
R8_GPIO_INT_FLAG = (pin>>2);
|
||||||
|
R8_GPIO_INT_ENABLE |= (pin>>2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn GPIOB_ITModeCfg
|
||||||
|
*
|
||||||
|
* @brief GPIOB pin interrupt mode configuration
|
||||||
|
*
|
||||||
|
* @param pin - PB3-PB4-PB11-PB12-PB15
|
||||||
|
* mode -
|
||||||
|
* GPIO_ITMode_LowLevel - Low level trigger
|
||||||
|
* GPIO_ITMode_HighLevel - High level trigger
|
||||||
|
* GPIO_ITMode_FallEdge - Falling edge trigger
|
||||||
|
* GPIO_ITMode_RiseEdge - Rising edge trigger
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
|
||||||
|
void GPIOB_ITModeCfg( UINT32 pin, GPIOITModeTpDef mode )
|
||||||
|
{
|
||||||
|
switch( mode )
|
||||||
|
{
|
||||||
|
case GPIO_ITMode_LowLevel: // Low level trigger
|
||||||
|
if(pin==GPIO_Pin_3)
|
||||||
|
{
|
||||||
|
R32_PB_DIR &= ~(1<<3);
|
||||||
|
R8_GPIO_INT_MODE &= ~(1<<3);
|
||||||
|
R8_GPIO_INT_POLAR &= ~(1<<3);
|
||||||
|
R8_GPIO_INT_FLAG = (1<<3);
|
||||||
|
R8_GPIO_INT_ENABLE |= (1<<3);
|
||||||
|
}
|
||||||
|
else if(pin==GPIO_Pin_4)
|
||||||
|
{
|
||||||
|
R32_PB_DIR &= ~(1<<4);
|
||||||
|
R8_GPIO_INT_MODE &= ~(1<<4);
|
||||||
|
R8_GPIO_INT_POLAR &= ~(1<<4);
|
||||||
|
R8_GPIO_INT_FLAG = (1<<4);
|
||||||
|
R8_GPIO_INT_ENABLE |= (1<<4);
|
||||||
|
}
|
||||||
|
else if(pin==GPIO_Pin_11)
|
||||||
|
{
|
||||||
|
R32_PB_DIR &= ~(1<<11);
|
||||||
|
R8_GPIO_INT_MODE &= ~(1<<5);
|
||||||
|
R8_GPIO_INT_POLAR &= ~(1<<5);
|
||||||
|
R8_GPIO_INT_FLAG = (1<<5);
|
||||||
|
R8_GPIO_INT_ENABLE |= (1<<5);
|
||||||
|
}
|
||||||
|
else if(pin==GPIO_Pin_12)
|
||||||
|
{
|
||||||
|
R32_PB_DIR &= ~(1<<12);
|
||||||
|
R8_GPIO_INT_MODE &= ~(1<<6);
|
||||||
|
R8_GPIO_INT_POLAR &= ~(1<<6);
|
||||||
|
R8_GPIO_INT_FLAG = (1<<6);
|
||||||
|
R8_GPIO_INT_ENABLE |= (1<<6);
|
||||||
|
}
|
||||||
|
else if(pin==GPIO_Pin_15)
|
||||||
|
{
|
||||||
|
R32_PB_DIR &= ~(1<<15);
|
||||||
|
R8_GPIO_INT_MODE &= ~(1<<7);
|
||||||
|
R8_GPIO_INT_POLAR &= ~(1<<7);
|
||||||
|
R8_GPIO_INT_FLAG = (1<<7);
|
||||||
|
R8_GPIO_INT_ENABLE |= (1<<7);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GPIO_ITMode_HighLevel: // High level trigger
|
||||||
|
if(pin==GPIO_Pin_3)
|
||||||
|
{
|
||||||
|
R32_PB_DIR &= ~(1<<3);
|
||||||
|
R8_GPIO_INT_MODE &= ~(1<<3);
|
||||||
|
R8_GPIO_INT_POLAR |= (1<<3);
|
||||||
|
R8_GPIO_INT_FLAG = (1<<3);
|
||||||
|
R8_GPIO_INT_ENABLE |= (1<<3);
|
||||||
|
}
|
||||||
|
else if(pin==GPIO_Pin_4)
|
||||||
|
{
|
||||||
|
R32_PB_DIR &= ~(1<<4);
|
||||||
|
R8_GPIO_INT_MODE &= ~(1<<4);
|
||||||
|
R8_GPIO_INT_POLAR |= (1<<4);
|
||||||
|
R8_GPIO_INT_FLAG = (1<<4);
|
||||||
|
R8_GPIO_INT_ENABLE |= (1<<4);
|
||||||
|
}
|
||||||
|
else if(pin==GPIO_Pin_11)
|
||||||
|
{
|
||||||
|
R32_PB_DIR &= ~(1<<11);
|
||||||
|
R8_GPIO_INT_MODE &= ~(1<<5);
|
||||||
|
R8_GPIO_INT_POLAR |= (1<<5);
|
||||||
|
R8_GPIO_INT_FLAG = (1<<5);
|
||||||
|
R8_GPIO_INT_ENABLE |= (1<<5);
|
||||||
|
}
|
||||||
|
else if(pin==GPIO_Pin_12)
|
||||||
|
{
|
||||||
|
R32_PB_DIR &= ~(1<<12);
|
||||||
|
R8_GPIO_INT_MODE &= ~(1<<6);
|
||||||
|
R8_GPIO_INT_POLAR |= (1<<6);
|
||||||
|
R8_GPIO_INT_FLAG = (1<<6);
|
||||||
|
R8_GPIO_INT_ENABLE |= (1<<6);
|
||||||
|
}
|
||||||
|
else if(pin==GPIO_Pin_15)
|
||||||
|
{
|
||||||
|
R32_PB_DIR &= ~(1<<15);
|
||||||
|
R8_GPIO_INT_MODE &= ~(1<<7);
|
||||||
|
R8_GPIO_INT_POLAR |= (1<<7);
|
||||||
|
R8_GPIO_INT_FLAG = (1<<7);
|
||||||
|
R8_GPIO_INT_ENABLE |= (1<<7);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GPIO_ITMode_FallEdge: // Falling edge trigger
|
||||||
|
if(pin==GPIO_Pin_3)
|
||||||
|
{
|
||||||
|
R32_PB_DIR &= ~(1<<3);
|
||||||
|
R8_GPIO_INT_MODE |= (1<<3);
|
||||||
|
R8_GPIO_INT_POLAR &= ~(1<<3);
|
||||||
|
R8_GPIO_INT_FLAG = (1<<3);
|
||||||
|
R8_GPIO_INT_ENABLE |= (1<<3);
|
||||||
|
}
|
||||||
|
else if(pin==GPIO_Pin_4)
|
||||||
|
{
|
||||||
|
R32_PB_DIR &= ~(1<<4);
|
||||||
|
R8_GPIO_INT_MODE |= (1<<4);
|
||||||
|
R8_GPIO_INT_POLAR &= ~(1<<4);
|
||||||
|
R8_GPIO_INT_FLAG = (1<<4);
|
||||||
|
R8_GPIO_INT_ENABLE |= (1<<4);
|
||||||
|
}
|
||||||
|
else if(pin==GPIO_Pin_11)
|
||||||
|
{
|
||||||
|
R32_PB_DIR &= ~(1<<11);
|
||||||
|
R8_GPIO_INT_MODE |= (1<<5);
|
||||||
|
R8_GPIO_INT_POLAR &= ~(1<<5);
|
||||||
|
R8_GPIO_INT_FLAG = (1<<5);
|
||||||
|
R8_GPIO_INT_ENABLE |= (1<<5);
|
||||||
|
}
|
||||||
|
else if(pin==GPIO_Pin_12)
|
||||||
|
{
|
||||||
|
R32_PB_DIR &= ~(1<<12);
|
||||||
|
R8_GPIO_INT_MODE |= (1<<6);
|
||||||
|
R8_GPIO_INT_POLAR &= ~(1<<6);
|
||||||
|
R8_GPIO_INT_FLAG = (1<<6);
|
||||||
|
R8_GPIO_INT_ENABLE |= (1<<6);
|
||||||
|
}
|
||||||
|
else if(pin==GPIO_Pin_15)
|
||||||
|
{
|
||||||
|
R32_PB_DIR &= ~(1<<15);
|
||||||
|
R8_GPIO_INT_MODE |= (1<<7);
|
||||||
|
R8_GPIO_INT_POLAR &= ~(1<<7);
|
||||||
|
R8_GPIO_INT_FLAG = (1<<7);
|
||||||
|
R8_GPIO_INT_ENABLE |= (1<<7);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case GPIO_ITMode_RiseEdge: // Rising edge trigger
|
||||||
|
if(pin==GPIO_Pin_3)
|
||||||
|
{
|
||||||
|
R32_PB_DIR &= ~(1<<3);
|
||||||
|
R8_GPIO_INT_MODE |= (1<<3);
|
||||||
|
R8_GPIO_INT_POLAR |= (1<<3);
|
||||||
|
R8_GPIO_INT_FLAG = (1<<3);
|
||||||
|
R8_GPIO_INT_ENABLE |= (1<<3);
|
||||||
|
}
|
||||||
|
else if(pin==GPIO_Pin_4)
|
||||||
|
{
|
||||||
|
R32_PB_DIR &= ~(1<<4);
|
||||||
|
R8_GPIO_INT_MODE |= (1<<4);
|
||||||
|
R8_GPIO_INT_POLAR |= (1<<4);
|
||||||
|
R8_GPIO_INT_FLAG = (1<<4);
|
||||||
|
R8_GPIO_INT_ENABLE |= (1<<4);
|
||||||
|
}
|
||||||
|
else if(pin==GPIO_Pin_11)
|
||||||
|
{
|
||||||
|
R32_PB_DIR &= ~(1<<11);
|
||||||
|
R8_GPIO_INT_MODE |= (1<<5);
|
||||||
|
R8_GPIO_INT_POLAR |= (1<<5);
|
||||||
|
R8_GPIO_INT_FLAG = (1<<5);
|
||||||
|
R8_GPIO_INT_ENABLE |= (1<<5);
|
||||||
|
}
|
||||||
|
else if(pin==GPIO_Pin_12)
|
||||||
|
{
|
||||||
|
R32_PB_DIR &= ~(1<<12);
|
||||||
|
R8_GPIO_INT_MODE |= (1<<6);
|
||||||
|
R8_GPIO_INT_POLAR |= (1<<6);
|
||||||
|
R8_GPIO_INT_FLAG = (1<<6);
|
||||||
|
R8_GPIO_INT_ENABLE |= (1<<6);
|
||||||
|
}
|
||||||
|
else if(pin==GPIO_Pin_15)
|
||||||
|
{
|
||||||
|
R32_PB_DIR &= ~(1<<15);
|
||||||
|
R8_GPIO_INT_MODE |= (1<<7);
|
||||||
|
R8_GPIO_INT_POLAR |= (1<<7);
|
||||||
|
R8_GPIO_INT_FLAG = (1<<7);
|
||||||
|
R8_GPIO_INT_ENABLE |= (1<<7);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default :
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn GPIOPinRemap
|
||||||
|
*
|
||||||
|
* @brief Peripheral Function Pin Mapping
|
||||||
|
*
|
||||||
|
* @param s -
|
||||||
|
* ENABLE - pin map
|
||||||
|
* DISABLE - default pin
|
||||||
|
* perph -
|
||||||
|
* RB_PIN_UART0 - RXD0 - PB5 -> PA5
|
||||||
|
* - TXD0 - PB6 -> PA6
|
||||||
|
* RB_PIN_TMR2 - TMR2/PWM6/CAP2 - PA4 -> PB3
|
||||||
|
* RB_PIN_TMR1 - TMR1/PWM5/CAP1 - PB15 -> PB0
|
||||||
|
* RB_PIN_MII - Ethernet - RMII -> RGMII
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void GPIOPinRemap( UINT8 s, UINT16 perph )
|
||||||
|
{
|
||||||
|
if( s ) R8_PIN_ALTERNATE |= perph;
|
||||||
|
else R8_PIN_ALTERNATE &= ~perph;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn GPIOMco
|
||||||
|
*
|
||||||
|
* @brief GPIO MCO mode configuration
|
||||||
|
*
|
||||||
|
* @param s - ENABLE\DISABLE
|
||||||
|
* mode-
|
||||||
|
* MCO_125,
|
||||||
|
* MCO_25,
|
||||||
|
* MCO_2d5,
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void GPIOMco( UINT8 s, UINT16 freq )
|
||||||
|
{
|
||||||
|
if(s)
|
||||||
|
{
|
||||||
|
R8_SAFE_ACCESS_SIG = 0x57;
|
||||||
|
R8_SAFE_ACCESS_SIG = 0xa8;
|
||||||
|
|
||||||
|
R8_CLK_MOD_AUX = 0x10;
|
||||||
|
R8_CLK_MOD_AUX |=0x01;
|
||||||
|
R8_CLK_MOD_AUX |= freq;
|
||||||
|
}
|
||||||
|
else R8_CLK_MOD_AUX &= ~(1<<4);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : CH56x_hspi.c
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0
|
||||||
|
* Date : 2020/07/31
|
||||||
|
* Description :
|
||||||
|
*********************************************************************************
|
||||||
|
* 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 "CH56x_common.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn HSPI_Mode
|
||||||
|
*
|
||||||
|
* @brief DVP mode
|
||||||
|
*
|
||||||
|
* @param s - data width
|
||||||
|
* RB_HPIF_DAT8_MOD - 8-bit mode
|
||||||
|
* RB_HPIF_DAT16_MOD - 16-bit mode
|
||||||
|
* RB_HPIF_DAT32_MOD - 32-bit mode
|
||||||
|
* i - Operating mode
|
||||||
|
* UP_Mode - Enable upper mode
|
||||||
|
* DOWN_Mode - Enable downside mode
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void HSPI_Mode( UINT8 s, HSPI_ModeTypeDef i)
|
||||||
|
{
|
||||||
|
R8_HSPI_CFG &= ~RB_HSPI_MSK_SIZE; //Restore default mode 8bit mode
|
||||||
|
|
||||||
|
if(s){
|
||||||
|
R8_HSPI_CFG |= s;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
R8_HSPI_CFG &= ~RB_HSPI_MSK_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(i){
|
||||||
|
R8_HSPI_CFG |= RB_HSPI_MODE;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
R8_HSPI_CFG &= ~RB_HSPI_MODE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn HSPI_INTCfg
|
||||||
|
*
|
||||||
|
* @brief HSPI interrupt configuration
|
||||||
|
*
|
||||||
|
* @param s - interrupt control status
|
||||||
|
* ENABLE - Enable corresponding interrupt
|
||||||
|
* DISABLE - Disable the corresponding interrupt
|
||||||
|
* i - interrupt type
|
||||||
|
* RB_HSPI_IE_T_DONE - Burst Sequence Transmit Complete Interrupt
|
||||||
|
* RB_HSPI_IE_R_DONE - Receive FIFO overflow interrupt
|
||||||
|
* RB_HSPI_IE_FIFO_OV - Single packet receive complete interrupt
|
||||||
|
* RB_HSPI_IE_B_DONE - Guaranteed Send Complete Interrupt
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void HSPI_INTCfg( UINT8 s, UINT8 i )
|
||||||
|
{
|
||||||
|
if(s){
|
||||||
|
R8_HSPI_INT_EN |= i;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
R8_HSPI_INT_EN &= ~i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : CH56x_pwm.c
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0
|
||||||
|
* Date : 2020/07/31
|
||||||
|
* Description :
|
||||||
|
*********************************************************************************
|
||||||
|
* 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 "CH56x_common.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn PWMX_CycleCfg
|
||||||
|
*
|
||||||
|
* @brief PWM0-PWM3 reference clock configuration
|
||||||
|
*
|
||||||
|
* @param cyc -
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void PWMX_CycleCfg( PWMX_CycleTypeDef cyc )
|
||||||
|
{
|
||||||
|
switch( cyc )
|
||||||
|
{
|
||||||
|
case PWMX_Cycle_256:
|
||||||
|
R8_PWM_CTRL_CFG &= ~RB_PWM_CYCLE_SEL; //PWM configuration control register, clock cycle selection
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PWMX_Cycle_255:
|
||||||
|
R8_PWM_CTRL_CFG |= RB_PWM_CYCLE_SEL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default :
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn PWMX_ACTOUT
|
||||||
|
*
|
||||||
|
* @brief PWM0-PWM3 channel output waveform configuration
|
||||||
|
*
|
||||||
|
* @param ch - select channel of pwm
|
||||||
|
* refer to channel of PWM define
|
||||||
|
* da - effective pulse width
|
||||||
|
* pr - select wave polar
|
||||||
|
* refer to PWMX_PolarTypeDef
|
||||||
|
* s - control pwmx function
|
||||||
|
* ENABLE - Output PWM
|
||||||
|
* DISABLE - turn off PWM
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void PWMX_ACTOUT( UINT8 ch, UINT8 da, PWMX_PolarTypeDef pr, UINT8 s)
|
||||||
|
{
|
||||||
|
UINT8 i;
|
||||||
|
|
||||||
|
if(s == DISABLE) R8_PWM_CTRL_MOD &= ~(ch); //Determine whether the PWM output is enabled
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
(pr)?(R8_PWM_CTRL_MOD|=(ch<<4)):(R8_PWM_CTRL_MOD&=~(ch<<4)); //PWM output polarity control 1: Default high level, low active; 0: Default low level, high active
|
||||||
|
for(i=0; i<4; i++){
|
||||||
|
if((ch>>i)&1) *((PUINT8V)((&R8_PWM0_DATA)+i)) = da;
|
||||||
|
}
|
||||||
|
R8_PWM_CTRL_MOD |= (ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,173 @@
|
||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : CH56x_pwr.c
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0
|
||||||
|
* Date : 2020/07/31
|
||||||
|
* Description :
|
||||||
|
*********************************************************************************
|
||||||
|
* 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 "CH56x_common.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn PWR_PeriphClkCfg
|
||||||
|
*
|
||||||
|
* @brief Peripheral Clock Control Bits
|
||||||
|
* @param s -
|
||||||
|
* ENABLE - Turn on the peripheral clock
|
||||||
|
* DISABLE - Turn off peripheral clock
|
||||||
|
* perph -
|
||||||
|
* please refer to Peripher CLK control bit define
|
||||||
|
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void PWR_PeriphClkCfg( UINT8 s, UINT16 perph )
|
||||||
|
{
|
||||||
|
if( s == DISABLE )
|
||||||
|
{
|
||||||
|
R8_SAFE_ACCESS_SIG = 0x57;
|
||||||
|
R8_SAFE_ACCESS_SIG = 0xA8;
|
||||||
|
R32_SLEEP_CONTROL |= perph;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
R8_SAFE_ACCESS_SIG = 0x57;
|
||||||
|
R8_SAFE_ACCESS_SIG = 0xA8;
|
||||||
|
R32_SLEEP_CONTROL &= ~perph;
|
||||||
|
}
|
||||||
|
R8_SAFE_ACCESS_SIG = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn PWR_PeriphWakeUpCfg
|
||||||
|
*
|
||||||
|
* @brief Sleep wakeup source configuration
|
||||||
|
*
|
||||||
|
* @param s -
|
||||||
|
* ENABLE - Turn on this peripheral's wake-from-sleep feature
|
||||||
|
* DISABLE - Turn off this peripheral sleep wake function
|
||||||
|
* perph -
|
||||||
|
* RB_SLP_USBHS_WAKE - USB2.0 is the wake-up source
|
||||||
|
* RB_SLP_USBSS_WAKE - USB3.0 is the wake-up source
|
||||||
|
* RB_SLP_GPIO_WAKE - GPIO is the wake-up source
|
||||||
|
* RB_SLP_ETH_WAKE - ETH is the wakeup source
|
||||||
|
* ALL - all of above
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void PWR_PeriphWakeUpCfg( UINT8 s, UINT16 perph )
|
||||||
|
{
|
||||||
|
if( s == DISABLE )
|
||||||
|
{
|
||||||
|
R8_SAFE_ACCESS_SIG = 0x57;
|
||||||
|
R8_SAFE_ACCESS_SIG = 0xA8;
|
||||||
|
R8_SLP_WAKE_CTRL &= ~perph;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
R8_SAFE_ACCESS_SIG = 0x57;
|
||||||
|
R8_SAFE_ACCESS_SIG = 0xA8;
|
||||||
|
R8_SLP_WAKE_CTRL |= perph;
|
||||||
|
}
|
||||||
|
R8_SAFE_ACCESS_SIG = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn LowPower_Idle
|
||||||
|
*
|
||||||
|
* @brief Low power consumption - Enter Idle mode with WFI instruction
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void LowPower_Idle( void )
|
||||||
|
{
|
||||||
|
PFIC->SCTLR &= ~1<<2; // Set the SleepDeep field of the core PFIC SCTLR register to 0
|
||||||
|
__WFI(); // Execute __WFI() after setting the wake-up condition
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn LowPower_Idle_WFE
|
||||||
|
*
|
||||||
|
* @brief Low power consumption - Enter Idle mode with WFE instruction
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void LowPower_Idle_WFE( void )
|
||||||
|
{
|
||||||
|
PFIC->SCTLR &= ~1<<2; // Set the SleepDeep field of the core PFIC SCTLR register to 0
|
||||||
|
__WFE(); // Execute __WFE() after setting the wake-up condition
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn LowPower_Halt
|
||||||
|
*
|
||||||
|
* @brief Low power consumption - Enter Halt mode with WFI instruction
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void LowPower_Halt( void )
|
||||||
|
{
|
||||||
|
R8_SAFE_ACCESS_SIG = 0x57;
|
||||||
|
R8_SAFE_ACCESS_SIG = 0xA8;
|
||||||
|
R8_SLP_POWER_CTRL |= RB_SLP_USBHS_PWRDN; // Set RB_SLP_USBHS_PWRDN to 1
|
||||||
|
R8_SAFE_ACCESS_SIG = 0x00;
|
||||||
|
PFIC->SCTLR |= 1<<2; // Set the SleepDeep field of the core PFIC SCTLR register to 1
|
||||||
|
__WFI(); // Execute __WFI() after setting the wake-up condition
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn LowPower_Halt
|
||||||
|
*
|
||||||
|
* @brief Low power consumption - Enter Halt mode with WFE instruction
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void LowPower_Halt_WFE( void )
|
||||||
|
{
|
||||||
|
R8_SAFE_ACCESS_SIG = 0x57;
|
||||||
|
R8_SAFE_ACCESS_SIG = 0xA8;
|
||||||
|
R8_SLP_POWER_CTRL |= RB_SLP_USBHS_PWRDN; // Set RB_SLP_USBHS_PWRDN to 1
|
||||||
|
R8_SAFE_ACCESS_SIG = 0x00;
|
||||||
|
PFIC->SCTLR |= 1<<2; // Set the SleepDeep field of the core PFIC SCTLR register to 1
|
||||||
|
__WFE(); // Execute __WFE() after setting the wake-up condition
|
||||||
|
}
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn LowPower_Sleep
|
||||||
|
*
|
||||||
|
* @brief Low power consumption - Enter Sleep mode with WFI instruction
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void LowPower_Sleep( void )
|
||||||
|
{
|
||||||
|
R8_SAFE_ACCESS_SIG = 0x57;
|
||||||
|
R8_SAFE_ACCESS_SIG = 0xA8;
|
||||||
|
USBSS->LINK_CFG &= ~(0x1 << 12); // This bit should be set to 0 when USB3.0 enters low-power consumption
|
||||||
|
USBSS->LINK_CFG &= ~(0x1 << 3); // Cancel USB PHY RESET
|
||||||
|
R8_SLP_POWER_CTRL |= RB_SLP_USBHS_PWRDN; // Set RB_SLP_USBHS_PWRDN to 1
|
||||||
|
R8_SAFE_ACCESS_SIG = 0x00;
|
||||||
|
PFIC->SCTLR |= 1<<2; // Set the SleepDeep field of the core PFIC SCTLR register to 1
|
||||||
|
__WFI(); // Execute __WFI() after setting the wake-up condition
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn LowPower_Sleep
|
||||||
|
*
|
||||||
|
* @brief Low power consumption - Enter Sleep mode with WFE instruction
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void LowPower_Sleep_WFE( void )
|
||||||
|
{
|
||||||
|
R8_SAFE_ACCESS_SIG = 0x57;
|
||||||
|
R8_SAFE_ACCESS_SIG = 0xA8;
|
||||||
|
USBSS->LINK_CFG &= ~(0x1 << 12); // This bit should be set to 0 when USB3.0 enters low-power consumption
|
||||||
|
USBSS->LINK_CFG &= ~(0x1 << 3); // Cancel USB PHY RESET
|
||||||
|
R8_SLP_POWER_CTRL |= RB_SLP_USBHS_PWRDN; // Set RB_SLP_USBHS_PWRDN to 1
|
||||||
|
R8_SAFE_ACCESS_SIG = 0x00;
|
||||||
|
PFIC->SCTLR |= 1<<2; // Set the SleepDeep field of the core PFIC SCTLR register to 1
|
||||||
|
__WFE(); // Execute __WFE() after setting the wake-up condition
|
||||||
|
}
|
|
@ -0,0 +1,579 @@
|
||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : CH56x_spi.c
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0
|
||||||
|
* Date : 2020/07/31
|
||||||
|
* Description :
|
||||||
|
*********************************************************************************
|
||||||
|
* 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 "CH56x_common.h"
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn SPI0_MasterDefInit
|
||||||
|
*
|
||||||
|
* @brief Host mode default initialization
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void SPI0_MasterDefInit( void )
|
||||||
|
{
|
||||||
|
R8_SPI0_CLOCK_DIV = 4; //Main frequency clock divided by 4
|
||||||
|
R8_SPI0_CTRL_MOD = RB_SPI_ALL_CLEAR; //FIFO/counter/interrupt flag register is cleared to 0, write 1 to force clear or clear
|
||||||
|
R8_SPI0_CTRL_MOD = RB_SPI_MOSI_OE | RB_SPI_SCK_OE ; //MOSI pin and SCK pin output enable
|
||||||
|
R8_SPI0_CTRL_CFG |= RB_SPI_AUTO_IF; //Enable access to BUFFER/FIFO to automatically clear the flag
|
||||||
|
R8_SPI0_CTRL_CFG &= ~RB_SPI_DMA_ENABLE; //Do not start DMA mode
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn SPI0_DataMode
|
||||||
|
*
|
||||||
|
* @brief Set data flow mode
|
||||||
|
*
|
||||||
|
* @param m - data flow mode
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void SPI0_DataMode( ModeBitOrderTypeDef m )
|
||||||
|
{
|
||||||
|
switch( m )
|
||||||
|
{
|
||||||
|
case Mode0_LowBitINFront: //Mode 0, low order first
|
||||||
|
R8_SPI0_CTRL_MOD &= ~RB_SPI_MST_SCK_MOD;
|
||||||
|
R8_SPI0_CTRL_CFG |= RB_SPI_BIT_ORDER;
|
||||||
|
break;
|
||||||
|
case Mode0_HighBitINFront: //Mode 0, high bit first
|
||||||
|
R8_SPI0_CTRL_MOD &= ~RB_SPI_MST_SCK_MOD;
|
||||||
|
R8_SPI0_CTRL_CFG &= ~RB_SPI_BIT_ORDER;
|
||||||
|
break;
|
||||||
|
case Mode3_LowBitINFront: //Mode 3, low bit first
|
||||||
|
R8_SPI0_CTRL_MOD |= RB_SPI_MST_SCK_MOD;
|
||||||
|
R8_SPI0_CTRL_CFG |= RB_SPI_BIT_ORDER;
|
||||||
|
break;
|
||||||
|
case Mode3_HighBitINFront: //Mode 3, high bit first
|
||||||
|
R8_SPI0_CTRL_MOD |= RB_SPI_MST_SCK_MOD;
|
||||||
|
R8_SPI0_CTRL_CFG &= ~RB_SPI_BIT_ORDER;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn SPI0_MasterSendByte
|
||||||
|
*
|
||||||
|
* @brief Send a single byte (buffer)
|
||||||
|
*
|
||||||
|
* @param d - send bytes
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void SPI0_MasterSendByte( UINT8 d )
|
||||||
|
{
|
||||||
|
R8_SPI0_CTRL_MOD &= ~RB_SPI_FIFO_DIR;
|
||||||
|
R8_SPI0_BUFFER = d;
|
||||||
|
while( !(R8_SPI0_INT_FLAG & RB_SPI_FREE) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn SPI0_MasterRecvByte
|
||||||
|
*
|
||||||
|
* @brief Receive a single byte (buffer)
|
||||||
|
*
|
||||||
|
* @return bytes received
|
||||||
|
*/
|
||||||
|
UINT8 SPI0_MasterRecvByte( void )
|
||||||
|
{
|
||||||
|
R8_SPI0_CTRL_MOD &= ~RB_SPI_FIFO_DIR;
|
||||||
|
R8_SPI0_BUFFER = 0xFF; //start transfer
|
||||||
|
while( !(R8_SPI0_INT_FLAG & RB_SPI_FREE) );
|
||||||
|
return ( R8_SPI0_BUFFER );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn SPI0_MasterTrans
|
||||||
|
*
|
||||||
|
* @brief Continuously send multiple bytes using FIFO
|
||||||
|
*
|
||||||
|
* @param pbuf: The first address of the data content to be sent
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void SPI0_MasterTrans( UINT8 *pbuf, UINT16 len )
|
||||||
|
{
|
||||||
|
UINT16 sendlen;
|
||||||
|
|
||||||
|
sendlen = len;
|
||||||
|
R8_SPI0_CTRL_MOD &= ~RB_SPI_FIFO_DIR; //Set data direction to output
|
||||||
|
R16_SPI0_TOTAL_CNT = sendlen; //Set the length of the data to be sent
|
||||||
|
R8_SPI0_INT_FLAG = RB_SPI_IF_CNT_END;
|
||||||
|
while( sendlen )
|
||||||
|
{
|
||||||
|
if( R8_SPI0_FIFO_COUNT < SPI_FIFO_SIZE )
|
||||||
|
{
|
||||||
|
R8_SPI0_FIFO = *pbuf;
|
||||||
|
pbuf++;
|
||||||
|
sendlen--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while( R8_SPI0_FIFO_COUNT != 0 ); //Wait for all the data in the FIFO to be sent
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn SPI0_MasterRecv
|
||||||
|
*
|
||||||
|
* @brief Receive multiple bytes continuously using FIFO
|
||||||
|
*
|
||||||
|
* @param pbuf: The first address of the data content to be sent
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
**/
|
||||||
|
void SPI0_MasterRecv( UINT8 *pbuf, UINT16 len )
|
||||||
|
{
|
||||||
|
UINT16 readlen;
|
||||||
|
|
||||||
|
readlen = len;
|
||||||
|
R8_SPI0_CTRL_MOD |= RB_SPI_FIFO_DIR; //Set data direction to input
|
||||||
|
R16_SPI0_TOTAL_CNT = len; //Set the length of the data to be received, the FIFO direction will start the transmission if the input length is not 0
|
||||||
|
R8_SPI0_INT_FLAG = RB_SPI_IF_CNT_END;
|
||||||
|
while( readlen )
|
||||||
|
{
|
||||||
|
if( R8_SPI0_FIFO_COUNT )
|
||||||
|
{
|
||||||
|
*pbuf = R8_SPI0_FIFO;
|
||||||
|
pbuf++;
|
||||||
|
readlen--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn SPI0_MasterDMATrans
|
||||||
|
*
|
||||||
|
* @brief Continuously send data in DMA mode
|
||||||
|
*
|
||||||
|
* @param pbuf: The starting address of the data to be sent
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void SPI0_MasterDMATrans( PUINT8 pbuf, UINT16 len)
|
||||||
|
{
|
||||||
|
R8_SPI0_CTRL_MOD &= ~RB_SPI_FIFO_DIR;
|
||||||
|
R32_SPI0_DMA_BEG = (UINT32)pbuf;
|
||||||
|
R32_SPI0_DMA_END = (UINT32)(pbuf + len);
|
||||||
|
R16_SPI0_TOTAL_CNT = len;
|
||||||
|
R8_SPI0_INT_FLAG = RB_SPI_IF_CNT_END|RB_SPI_IF_DMA_END;
|
||||||
|
R8_SPI0_CTRL_CFG |= RB_SPI_DMA_ENABLE;
|
||||||
|
while(!(R8_SPI0_INT_FLAG & RB_SPI_IF_CNT_END));
|
||||||
|
R8_SPI0_CTRL_CFG &= ~RB_SPI_DMA_ENABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn SPI0_MasterDMARecv
|
||||||
|
*
|
||||||
|
* @brief Receive data continuously in DMA mode
|
||||||
|
*
|
||||||
|
* @param pbuf: The starting address for storing the data to be received
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
**/
|
||||||
|
void SPI0_MasterDMARecv( PUINT8 pbuf, UINT16 len)
|
||||||
|
{
|
||||||
|
R8_SPI0_CTRL_MOD |= RB_SPI_FIFO_DIR;
|
||||||
|
R32_SPI0_DMA_BEG = (UINT32)pbuf;
|
||||||
|
R32_SPI0_DMA_END = (UINT32)(pbuf + len);
|
||||||
|
R16_SPI0_TOTAL_CNT = len;
|
||||||
|
R8_SPI0_INT_FLAG = RB_SPI_IF_CNT_END|RB_SPI_IF_DMA_END;
|
||||||
|
R8_SPI0_CTRL_CFG |= RB_SPI_DMA_ENABLE;
|
||||||
|
while(!(R8_SPI0_INT_FLAG & RB_SPI_IF_CNT_END));
|
||||||
|
R8_SPI0_CTRL_CFG &= ~RB_SPI_DMA_ENABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn SPI0_SlaveInit
|
||||||
|
*
|
||||||
|
* @brief Device mode default initialization
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void SPI0_SlaveInit( void )
|
||||||
|
{
|
||||||
|
R8_SPI0_CTRL_MOD = RB_SPI_ALL_CLEAR; //FIFO/counter/interrupt flag register is cleared to 0, write 1 to force clear or clear
|
||||||
|
R8_SPI0_CTRL_MOD = RB_SPI_MISO_OE | RB_SPI_MODE_SLAVE;
|
||||||
|
R8_SPI0_CTRL_CFG |= RB_SPI_AUTO_IF; //Enable access to BUFFER/FIFO to automatically clear the flag
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn SPI0_SlaveRecvByte
|
||||||
|
*
|
||||||
|
* @brief Slave mode, receive one byte of data
|
||||||
|
*
|
||||||
|
* @return received data
|
||||||
|
*/
|
||||||
|
UINT8 SPI0_SlaveRecvByte( void )
|
||||||
|
{
|
||||||
|
R8_SPI0_CTRL_MOD |= RB_SPI_FIFO_DIR; //Set to input mode, receive data
|
||||||
|
while( R8_SPI0_FIFO_COUNT == 0 );
|
||||||
|
return R8_SPI0_FIFO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn SPI0_SlaveRecvByte
|
||||||
|
*
|
||||||
|
* @brief Slave mode, send one byte of data
|
||||||
|
*
|
||||||
|
* @return received data
|
||||||
|
**/
|
||||||
|
void SPI0_SlaveSendByte( UINT8 d )
|
||||||
|
{
|
||||||
|
R8_SPI0_CTRL_MOD &= ~RB_SPI_FIFO_DIR; //Set data direction to output
|
||||||
|
R8_SPI0_FIFO = d;
|
||||||
|
while( R8_SPI0_FIFO_COUNT != 0 ); //Wait for the send to complete
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn SPI0_SlaveRecv
|
||||||
|
*
|
||||||
|
* @brief Slave mode, receive multi-byte data
|
||||||
|
*
|
||||||
|
* @param pbuf: Receive data storage starting address
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
**/
|
||||||
|
void SPI0_SlaveRecv( PUINT8 pbuf, UINT16 len )
|
||||||
|
{
|
||||||
|
UINT16 revlen;
|
||||||
|
|
||||||
|
revlen = len;
|
||||||
|
R8_SPI0_CTRL_MOD |= RB_SPI_FIFO_DIR; //Set to input mode, receive data
|
||||||
|
R16_SPI0_TOTAL_CNT = revlen; //Assign a value to the SPI send and receive data total length register
|
||||||
|
R8_SPI0_INT_FLAG = RB_SPI_IF_CNT_END; //SPI interrupt flag register All bytes transfer complete flag, write 1 to clear 0
|
||||||
|
while( revlen )
|
||||||
|
{
|
||||||
|
if( R8_SPI0_FIFO_COUNT ) //Byte count in the current FIFO
|
||||||
|
{
|
||||||
|
*pbuf = R8_SPI0_FIFO;
|
||||||
|
pbuf++;
|
||||||
|
revlen--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn SPI0_SlaveTrans
|
||||||
|
*
|
||||||
|
* @brief Slave mode, send multi-byte data
|
||||||
|
*
|
||||||
|
* @param pbuf: The first address of the data content to be sent
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void SPI0_SlaveTrans( UINT8 *pbuf, UINT16 len )
|
||||||
|
{
|
||||||
|
UINT16 sendlen;
|
||||||
|
|
||||||
|
sendlen = len;
|
||||||
|
R8_SPI0_CTRL_MOD &= ~RB_SPI_FIFO_DIR; //Set data direction to output
|
||||||
|
R16_SPI0_TOTAL_CNT = sendlen; //Set the length of the data to be sent
|
||||||
|
R8_SPI0_INT_FLAG = RB_SPI_IF_CNT_END; //SPI interrupt flag register All bytes transfer complete flag, write 1 to clear 0
|
||||||
|
while( sendlen )
|
||||||
|
{
|
||||||
|
if( R8_SPI0_FIFO_COUNT < SPI_FIFO_SIZE ) //Compare the byte count size in the current FIFO
|
||||||
|
{
|
||||||
|
R8_SPI0_FIFO = *pbuf;
|
||||||
|
pbuf++;
|
||||||
|
sendlen--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while( R8_SPI0_FIFO_COUNT != 0 ); //Wait for all the data in the FIFO to be sent
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn SPI1_MasterDefInit
|
||||||
|
*
|
||||||
|
* @brief Host mode default initialization
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void SPI1_MasterDefInit( void )
|
||||||
|
{
|
||||||
|
R8_SPI1_CLOCK_DIV = 4; //Main frequency clock divided by 4
|
||||||
|
R8_SPI1_CTRL_MOD = RB_SPI_ALL_CLEAR;
|
||||||
|
R8_SPI1_CTRL_MOD = RB_SPI_MOSI_OE | RB_SPI_SCK_OE ;
|
||||||
|
R8_SPI1_CTRL_CFG |= RB_SPI_AUTO_IF;
|
||||||
|
R8_SPI1_CTRL_CFG &= ~RB_SPI_DMA_ENABLE; //Do not start DMA mode
|
||||||
|
//R8_SPI1_CTRL_CFG |= RB_SPI_DMA_ENABLE; //Start DMA mode
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn SPI1_DataMode
|
||||||
|
*
|
||||||
|
* @brief Set data flow mode
|
||||||
|
*
|
||||||
|
* @param m: data flow mode
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
***/
|
||||||
|
void SPI1_DataMode( ModeBitOrderTypeDef m )
|
||||||
|
{
|
||||||
|
switch( m )
|
||||||
|
{
|
||||||
|
case Mode0_LowBitINFront:
|
||||||
|
R8_SPI1_CTRL_MOD &= ~RB_SPI_MST_SCK_MOD;
|
||||||
|
R8_SPI1_CTRL_CFG |= RB_SPI_BIT_ORDER;
|
||||||
|
break;
|
||||||
|
case Mode0_HighBitINFront:
|
||||||
|
R8_SPI1_CTRL_MOD &= ~RB_SPI_MST_SCK_MOD;
|
||||||
|
R8_SPI1_CTRL_CFG &= ~RB_SPI_BIT_ORDER;
|
||||||
|
break;
|
||||||
|
case Mode3_LowBitINFront:
|
||||||
|
R8_SPI1_CTRL_MOD |= RB_SPI_MST_SCK_MOD;
|
||||||
|
R8_SPI1_CTRL_CFG |= RB_SPI_BIT_ORDER;
|
||||||
|
break;
|
||||||
|
case Mode3_HighBitINFront:
|
||||||
|
R8_SPI1_CTRL_MOD |= RB_SPI_MST_SCK_MOD;
|
||||||
|
R8_SPI1_CTRL_CFG &= ~RB_SPI_BIT_ORDER;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn SPI1_MasterSendByte
|
||||||
|
*
|
||||||
|
* @brief Send a single byte (buffer)
|
||||||
|
*
|
||||||
|
* @param d - send bytes
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void SPI1_MasterSendByte( UINT8 d )
|
||||||
|
{
|
||||||
|
R8_SPI1_CTRL_MOD &= ~RB_SPI_FIFO_DIR;
|
||||||
|
R8_SPI1_BUFFER = d;
|
||||||
|
while( !(R8_SPI1_INT_FLAG & RB_SPI_FREE) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn SPI1_MasterRecvByte
|
||||||
|
*
|
||||||
|
* @brief Receive a single byte (buffer)
|
||||||
|
*
|
||||||
|
* @return bytes received
|
||||||
|
*/
|
||||||
|
UINT8 SPI1_MasterRecvByte( void )
|
||||||
|
{
|
||||||
|
R8_SPI1_CTRL_MOD &= ~RB_SPI_FIFO_DIR;
|
||||||
|
R8_SPI1_BUFFER = 0xFF; //start transfer
|
||||||
|
while( !(R8_SPI1_INT_FLAG & RB_SPI_FREE) );
|
||||||
|
return ( R8_SPI1_BUFFER );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn SPI1_MasterTrans
|
||||||
|
*
|
||||||
|
* @brief Continuously send multiple bytes using FIFO
|
||||||
|
*
|
||||||
|
* @param pbuf - The first address of the data content to be sent
|
||||||
|
* len - The length of the data sent by the request, the maximum is 4095
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void SPI1_MasterTrans( UINT8 *pbuf, UINT16 len )
|
||||||
|
{
|
||||||
|
UINT16 sendlen;
|
||||||
|
|
||||||
|
sendlen = len;
|
||||||
|
R8_SPI1_CTRL_MOD &= ~RB_SPI_FIFO_DIR; //Set data direction to output
|
||||||
|
R16_SPI1_TOTAL_CNT = sendlen; //Set the length of the data to be sent
|
||||||
|
R8_SPI1_INT_FLAG = RB_SPI_IF_CNT_END;
|
||||||
|
while( sendlen )
|
||||||
|
{
|
||||||
|
if( R8_SPI1_FIFO_COUNT < SPI_FIFO_SIZE )
|
||||||
|
{
|
||||||
|
R8_SPI1_FIFO = *pbuf;
|
||||||
|
pbuf++;
|
||||||
|
sendlen--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while( R8_SPI1_FIFO_COUNT != 0 ); //Wait for all the data in the FIFO to be sent
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn SPI1_MasterRecv
|
||||||
|
*
|
||||||
|
* @brief Receive multiple bytes continuously using FIFO
|
||||||
|
*
|
||||||
|
* @param pbuf - The first address of the data content to be sent
|
||||||
|
* len - The length of the data sent by the request, the maximum is 4095
|
||||||
|
* @return None
|
||||||
|
**/
|
||||||
|
void SPI1_MasterRecv( UINT8 *pbuf, UINT16 len )
|
||||||
|
{
|
||||||
|
UINT16 readlen;
|
||||||
|
|
||||||
|
readlen = len;
|
||||||
|
R8_SPI1_CTRL_MOD |= RB_SPI_FIFO_DIR; //Set data direction to input
|
||||||
|
R16_SPI1_TOTAL_CNT = len; //Set the length of the data to be received, the FIFO direction will start the transmission if the input length is not 0
|
||||||
|
R8_SPI1_INT_FLAG = RB_SPI_IF_CNT_END;
|
||||||
|
while( readlen )
|
||||||
|
{
|
||||||
|
if( R8_SPI1_FIFO_COUNT )
|
||||||
|
{
|
||||||
|
*pbuf = R8_SPI1_FIFO;
|
||||||
|
pbuf++;
|
||||||
|
readlen--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn SPI1_MasterDMATrans
|
||||||
|
*
|
||||||
|
* @brief Continuously send data in DMA mode
|
||||||
|
*
|
||||||
|
* @param pbuf - The starting address of the data to be sent
|
||||||
|
* len - With send data length
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void SPI1_MasterDMATrans( PUINT8 pbuf, UINT16 len)
|
||||||
|
{
|
||||||
|
R8_SPI1_CTRL_MOD &= ~RB_SPI_FIFO_DIR;
|
||||||
|
R32_SPI1_DMA_BEG = (UINT32)pbuf;
|
||||||
|
R32_SPI1_DMA_END = (UINT32)(pbuf + len);
|
||||||
|
R16_SPI1_TOTAL_CNT = len;
|
||||||
|
R8_SPI1_INT_FLAG = RB_SPI_IF_CNT_END|RB_SPI_IF_DMA_END;
|
||||||
|
R8_SPI1_CTRL_CFG |= RB_SPI_DMA_ENABLE;
|
||||||
|
while(!(R8_SPI1_INT_FLAG & RB_SPI_IF_CNT_END));
|
||||||
|
R8_SPI1_CTRL_CFG &= ~RB_SPI_DMA_ENABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn SPI1_MasterDMARecv
|
||||||
|
*
|
||||||
|
* @brief Receive data continuously in DMA mode
|
||||||
|
*
|
||||||
|
* @param pbuf - The starting address for storing the data to be received
|
||||||
|
* len - Data length to be received
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void SPI1_MasterDMARecv( PUINT8 pbuf, UINT16 len)
|
||||||
|
{
|
||||||
|
R8_SPI1_CTRL_MOD |= RB_SPI_FIFO_DIR;
|
||||||
|
R32_SPI1_DMA_BEG = (UINT32)pbuf;
|
||||||
|
R32_SPI1_DMA_END = (UINT32)(pbuf + len);
|
||||||
|
R16_SPI1_TOTAL_CNT = len;
|
||||||
|
R8_SPI1_INT_FLAG = RB_SPI_IF_CNT_END|RB_SPI_IF_DMA_END;
|
||||||
|
R8_SPI1_CTRL_CFG |= RB_SPI_DMA_ENABLE;
|
||||||
|
while(!(R8_SPI0_INT_FLAG & RB_SPI_IF_CNT_END));
|
||||||
|
R8_SPI1_CTRL_CFG &= ~RB_SPI_DMA_ENABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn SPI1_SlaveInit
|
||||||
|
*
|
||||||
|
* @brief Device mode default initialization
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void SPI1_SlaveInit( void )
|
||||||
|
{
|
||||||
|
R8_SPI1_CTRL_MOD = RB_SPI_ALL_CLEAR;
|
||||||
|
R8_SPI1_CTRL_MOD = RB_SPI_MISO_OE | RB_SPI_MODE_SLAVE;
|
||||||
|
R8_SPI1_CTRL_CFG |= RB_SPI_AUTO_IF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn SPI1_SlaveRecvByte
|
||||||
|
*
|
||||||
|
* @brief Slave mode, receive one byte of data
|
||||||
|
*
|
||||||
|
* @return received data
|
||||||
|
*/
|
||||||
|
UINT8 SPI1_SlaveRecvByte( void )
|
||||||
|
{
|
||||||
|
R8_SPI1_CTRL_MOD |= RB_SPI_FIFO_DIR;
|
||||||
|
while( R8_SPI1_FIFO_COUNT == 0 );
|
||||||
|
return R8_SPI1_FIFO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn SPI1_SlaveRecvByte
|
||||||
|
*
|
||||||
|
* @brief Slave mode, receive one byte of data
|
||||||
|
*
|
||||||
|
* @return received data
|
||||||
|
*/
|
||||||
|
void SPI1_SlaveSendByte( UINT8 d )
|
||||||
|
{
|
||||||
|
R8_SPI1_CTRL_MOD &= ~RB_SPI_FIFO_DIR;
|
||||||
|
R8_SPI1_FIFO = d;
|
||||||
|
while( R8_SPI1_FIFO_COUNT != 0 ); //Wait for the send to complete
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn SPI1_SlaveRecv
|
||||||
|
* @brief Slave mode, receive multi-byte data
|
||||||
|
* @param pbuf - Receive data storage starting address
|
||||||
|
* len - Request to receive data length
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void SPI1_SlaveRecv( PUINT8 pbuf, UINT16 len )
|
||||||
|
{
|
||||||
|
UINT16 revlen;
|
||||||
|
|
||||||
|
revlen = len;
|
||||||
|
R8_SPI1_CTRL_MOD |= RB_SPI_FIFO_DIR;
|
||||||
|
R16_SPI1_TOTAL_CNT = revlen;
|
||||||
|
R8_SPI1_INT_FLAG = RB_SPI_IF_CNT_END;
|
||||||
|
while( revlen )
|
||||||
|
{
|
||||||
|
if( R8_SPI1_FIFO_COUNT )
|
||||||
|
{
|
||||||
|
*pbuf = R8_SPI1_FIFO;
|
||||||
|
pbuf++;
|
||||||
|
revlen--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn SPI1_SlaveTrans
|
||||||
|
*
|
||||||
|
* @brief Slave mode, send multi-byte data
|
||||||
|
*
|
||||||
|
* @param pbuf - The first address of the data content to be sent
|
||||||
|
* len - The length of the data sent by the request, the maximum is 4095
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void SPI1_SlaveTrans( UINT8 *pbuf, UINT16 len )
|
||||||
|
{
|
||||||
|
UINT16 sendlen;
|
||||||
|
|
||||||
|
sendlen = len;
|
||||||
|
R8_SPI1_CTRL_MOD &= ~RB_SPI_FIFO_DIR; //Set data direction to output
|
||||||
|
R16_SPI1_TOTAL_CNT = sendlen; //Set the length of the data to be sent
|
||||||
|
R8_SPI1_INT_FLAG = RB_SPI_IF_CNT_END;
|
||||||
|
while( sendlen )
|
||||||
|
{
|
||||||
|
if( R8_SPI1_FIFO_COUNT < SPI_FIFO_SIZE )
|
||||||
|
{
|
||||||
|
R8_SPI1_FIFO = *pbuf;
|
||||||
|
pbuf++;
|
||||||
|
sendlen--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while( R8_SPI1_FIFO_COUNT != 0 ); //Wait for all the data in the FIFO to be sent
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,198 @@
|
||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : CH56x_sys.c
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0
|
||||||
|
* Date : 2024/01/14
|
||||||
|
* Description : This file contains all the functions prototypes for
|
||||||
|
* SystemCoreClock, UART Printf , Delay functions .
|
||||||
|
*********************************************************************************
|
||||||
|
* 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 "CH56x_common.h"
|
||||||
|
|
||||||
|
static uint8_t p_us = 0;
|
||||||
|
static uint16_t p_ms = 0;
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn Delay_Init
|
||||||
|
*
|
||||||
|
* @brief Initializes Delay Funcation.
|
||||||
|
*
|
||||||
|
* @param systemclck - system clock Hz
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
**/
|
||||||
|
void Delay_Init(uint32_t systemclck)
|
||||||
|
{
|
||||||
|
p_us = systemclck / 8000000;
|
||||||
|
p_ms = (uint16_t)p_us * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn mDelayuS
|
||||||
|
*
|
||||||
|
* @brief Microsecond Delay Time.
|
||||||
|
*
|
||||||
|
* @param n - Microsecond number.
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
**/
|
||||||
|
void mDelayuS(uint32_t n)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
SysTick->CNTFG &= ~(1 << 1);
|
||||||
|
|
||||||
|
i = (uint32_t)n * p_us;
|
||||||
|
|
||||||
|
SysTick->CMP = i;
|
||||||
|
SysTick->CTLR = (1 << 8) | (1 << 0);
|
||||||
|
|
||||||
|
while ((SysTick->CNTFG & (1 << 1)) != (1 << 1));
|
||||||
|
SysTick->CTLR = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn mDelaymS
|
||||||
|
*
|
||||||
|
* @brief Millisecond Delay Time.
|
||||||
|
*
|
||||||
|
* @param n - Millisecond number.
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
**/
|
||||||
|
void mDelaymS(uint32_t n)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
SysTick->CNTFG &= ~(1 << 1);
|
||||||
|
|
||||||
|
i = (uint32_t)n * p_ms;
|
||||||
|
|
||||||
|
SysTick->CMP = i;
|
||||||
|
SysTick->CTLR = (1 << 8) | (1 << 0);
|
||||||
|
|
||||||
|
while ((SysTick->CNTFG & (1 << 1)) != (1 << 1));
|
||||||
|
SysTick->CTLR = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn SYS_GetInfoSta
|
||||||
|
*
|
||||||
|
* @brief Get the current system information status
|
||||||
|
*
|
||||||
|
* @param i -
|
||||||
|
* @return stat
|
||||||
|
**/
|
||||||
|
UINT8 SYS_GetInfoSta(SYS_InfoStaTypeDef i)
|
||||||
|
{
|
||||||
|
return (R8_RST_BOOT_STAT & (1 << i));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn SYS_ResetExecute
|
||||||
|
*
|
||||||
|
* @brief Perform a system software reset
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
**/
|
||||||
|
void SYS_ResetExecute(void)
|
||||||
|
{
|
||||||
|
R8_SAFE_ACCESS_SIG = 0x57; // enable safe access mode
|
||||||
|
R8_SAFE_ACCESS_SIG = 0xa8;
|
||||||
|
R8_RST_WDOG_CTRL |= RB_SOFTWARE_RESET | 0x40;
|
||||||
|
R8_SAFE_ACCESS_SIG = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn WWDG_ITCfg
|
||||||
|
*
|
||||||
|
* @brief Watchdog timer overflow interrupt enable
|
||||||
|
*
|
||||||
|
* @param s -
|
||||||
|
* DISABLE - Overflow without interruption
|
||||||
|
* ENABLE - Overflow interrupt
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
**/
|
||||||
|
void WWDG_ITCfg(UINT8 s)
|
||||||
|
{
|
||||||
|
R8_SAFE_ACCESS_SIG = 0x57; // enable safe access mode
|
||||||
|
R8_SAFE_ACCESS_SIG = 0xa8;
|
||||||
|
if (s == DISABLE) R8_RST_WDOG_CTRL = (R8_RST_WDOG_CTRL & (~RB_WDOG_INT_EN)) | 0x40;
|
||||||
|
else R8_RST_WDOG_CTRL |= RB_WDOG_INT_EN | 0x40;
|
||||||
|
R8_SAFE_ACCESS_SIG = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn WWDG_ResetCfg
|
||||||
|
*
|
||||||
|
* @brief Watchdog timer reset function
|
||||||
|
*
|
||||||
|
* @param s -
|
||||||
|
* DISABLE - Overflow does not reset
|
||||||
|
* ENABLE - Overflow system reset
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
**/
|
||||||
|
void WWDG_ResetCfg(UINT8 s)
|
||||||
|
{
|
||||||
|
R8_SAFE_ACCESS_SIG = 0x57; // enable safe access mode
|
||||||
|
R8_SAFE_ACCESS_SIG = 0xa8;
|
||||||
|
if (s == DISABLE) R8_RST_WDOG_CTRL = (R8_RST_WDOG_CTRL & (~RB_WDOG_RST_EN)) | 0x40;
|
||||||
|
else R8_RST_WDOG_CTRL |= RB_WDOG_RST_EN | 0x40;
|
||||||
|
R8_SAFE_ACCESS_SIG = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn WWDG_ClearFlag
|
||||||
|
* @brief Clear watchdog interrupt flag, reload count value can also be cleared
|
||||||
|
* @param None
|
||||||
|
* @return None
|
||||||
|
**/
|
||||||
|
void WWDG_ClearFlag(void)
|
||||||
|
{
|
||||||
|
R8_SAFE_ACCESS_SIG = 0x57; // enable safe access mode
|
||||||
|
R8_SAFE_ACCESS_SIG = 0xa8;
|
||||||
|
R8_RST_WDOG_CTRL |= RB_WDOG_INT_FLAG | 0x40;
|
||||||
|
R8_SAFE_ACCESS_SIG = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (defined DEBUG)
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn _write
|
||||||
|
*
|
||||||
|
* @brief Support Printf Function
|
||||||
|
*
|
||||||
|
* @param *buf: UART send Data.
|
||||||
|
* size - Data length
|
||||||
|
*
|
||||||
|
* @return size - Data length
|
||||||
|
**/
|
||||||
|
__attribute__((used)) int _write(int fd, char *buf, int size)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
#if DEBUG == Debug_UART0
|
||||||
|
while (R8_UART0_TFC == UART_FIFO_SIZE);
|
||||||
|
R8_UART0_THR = *buf++;
|
||||||
|
#elif DEBUG == Debug_UART1
|
||||||
|
while (R8_UART1_TFC == UART_FIFO_SIZE);
|
||||||
|
R8_UART1_THR = *buf++;
|
||||||
|
#elif DEBUG == Debug_UART2
|
||||||
|
while (R8_UART2_TFC == UART_FIFO_SIZE);
|
||||||
|
R8_UART2_THR = *buf++;
|
||||||
|
#elif DEBUG == Debug_UART3
|
||||||
|
while (R8_UART3_TFC == UART_FIFO_SIZE);
|
||||||
|
R8_UART3_THR = *buf++;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,269 @@
|
||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : CH56x_timer.c
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0
|
||||||
|
* Date : 2020/07/31
|
||||||
|
* Description :
|
||||||
|
*********************************************************************************
|
||||||
|
* 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 "CH56x_common.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn TMR0_TimerInit
|
||||||
|
*
|
||||||
|
* @brief Counting Function on TIM PeriPheral
|
||||||
|
*
|
||||||
|
* @param t - the Most End Value counting to
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void TMR0_TimerInit( UINT32 t )
|
||||||
|
{
|
||||||
|
R32_TMR0_CNT_END = t;
|
||||||
|
R8_TMR0_CTRL_MOD = RB_TMR_ALL_CLEAR;
|
||||||
|
R8_TMR0_CTRL_MOD = RB_TMR_COUNT_EN | RB_TMR_CAP_COUNT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn TMR1_TimerInit
|
||||||
|
*
|
||||||
|
* @brief Counting Function on TIM PeriPheral
|
||||||
|
*
|
||||||
|
* @param t - the Most End Value counting to
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void TMR1_TimerInit( UINT32 t )
|
||||||
|
{
|
||||||
|
R32_TMR1_CNT_END = t;
|
||||||
|
R8_TMR1_CTRL_MOD = RB_TMR_ALL_CLEAR;
|
||||||
|
R8_TMR1_CTRL_MOD = RB_TMR_COUNT_EN | RB_TMR_CAP_COUNT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn TMR2_TimerInit
|
||||||
|
*
|
||||||
|
* @brief Counting Function on TIM PeriPheral
|
||||||
|
*
|
||||||
|
* @param t - the Most End Value counting to
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void TMR2_TimerInit( UINT32 t )
|
||||||
|
{
|
||||||
|
R32_TMR2_CNT_END = t;
|
||||||
|
R8_TMR2_CTRL_MOD = RB_TMR_ALL_CLEAR;
|
||||||
|
R8_TMR2_CTRL_MOD = RB_TMR_COUNT_EN | RB_TMR_CAP_COUNT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn TMR0_EXTSignalCounterInit
|
||||||
|
*
|
||||||
|
* @brief external signal count
|
||||||
|
*
|
||||||
|
* @param c
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void TMR0_EXTSignalCounterInit( UINT32 c )
|
||||||
|
{
|
||||||
|
R32_TMR0_CNT_END = c;
|
||||||
|
R8_TMR0_CTRL_MOD = RB_TMR_ALL_CLEAR;
|
||||||
|
R8_TMR0_CTRL_MOD = RB_TMR_CAP_COUNT|RB_TMR_MODE_IN|RB_TMR_COUNT_EN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn TMR1_EXTSignalCounterInit
|
||||||
|
*
|
||||||
|
* @brief external signal count
|
||||||
|
*
|
||||||
|
* @param c
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void TMR1_EXTSignalCounterInit( UINT32 c )
|
||||||
|
{
|
||||||
|
R32_TMR1_CNT_END = c;
|
||||||
|
R8_TMR1_CTRL_MOD = RB_TMR_ALL_CLEAR;
|
||||||
|
R8_TMR1_CTRL_MOD = RB_TMR_CAP_COUNT|RB_TMR_MODE_IN|RB_TMR_COUNT_EN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn TMR2_EXTSignalCounterInit
|
||||||
|
*
|
||||||
|
* @brief external signal count
|
||||||
|
*
|
||||||
|
* @param c
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void TMR2_EXTSignalCounterInit( UINT32 c )
|
||||||
|
{
|
||||||
|
R32_TMR2_CNT_END = c;
|
||||||
|
R8_TMR2_CTRL_MOD = RB_TMR_ALL_CLEAR;
|
||||||
|
R8_TMR2_CTRL_MOD = RB_TMR_CAP_COUNT|RB_TMR_MODE_IN|RB_TMR_COUNT_EN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn TMR0_PWMInit
|
||||||
|
*
|
||||||
|
* @brief PWM Output Init
|
||||||
|
*
|
||||||
|
* @param pr-
|
||||||
|
* ts-
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void TMR0_PWMInit( PWM_PolarTypeDef pr, PWM_RepeatTsTypeDef ts )
|
||||||
|
{
|
||||||
|
R8_TMR0_CTRL_MOD = RB_TMR_ALL_CLEAR;
|
||||||
|
R8_TMR0_CTRL_MOD = RB_TMR_COUNT_EN
|
||||||
|
|RB_TMR_OUT_EN
|
||||||
|
|(pr<<4)
|
||||||
|
|(ts<<6);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn TMR1_PWMInit
|
||||||
|
*
|
||||||
|
* @brief PWM Output Init
|
||||||
|
*
|
||||||
|
* @param pr-
|
||||||
|
* ts-
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void TMR1_PWMInit( PWM_PolarTypeDef pr, PWM_RepeatTsTypeDef ts )
|
||||||
|
{
|
||||||
|
R8_TMR1_CTRL_MOD = RB_TMR_ALL_CLEAR;
|
||||||
|
R8_TMR1_CTRL_MOD = RB_TMR_COUNT_EN
|
||||||
|
|RB_TMR_OUT_EN
|
||||||
|
|(pr<<4)
|
||||||
|
|(ts<<6);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn TMR2_PWMInit
|
||||||
|
*
|
||||||
|
* @brief PWM Output Init
|
||||||
|
*
|
||||||
|
* @param pr-
|
||||||
|
* ts-
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void TMR2_PWMInit( PWM_PolarTypeDef pr, PWM_RepeatTsTypeDef ts )
|
||||||
|
{
|
||||||
|
R8_TMR2_CTRL_MOD = RB_TMR_ALL_CLEAR;
|
||||||
|
R8_TMR2_CTRL_MOD = RB_TMR_COUNT_EN
|
||||||
|
|RB_TMR_OUT_EN
|
||||||
|
|(pr<<4)
|
||||||
|
|(ts<<6);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn TMR0_CapInit
|
||||||
|
*
|
||||||
|
* @brief cap
|
||||||
|
*
|
||||||
|
* @param CapModeTypeDef
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void TMR0_CapInit( CapModeTypeDef cap )
|
||||||
|
{
|
||||||
|
R8_TMR0_CTRL_MOD = RB_TMR_ALL_CLEAR;
|
||||||
|
R8_TMR0_CTRL_MOD = RB_TMR_COUNT_EN \
|
||||||
|
|RB_TMR_MODE_IN \
|
||||||
|
|(cap<<6);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn TMR1_CapInit
|
||||||
|
*
|
||||||
|
* @brief cap
|
||||||
|
*
|
||||||
|
* @param CapModeTypeDef
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void TMR1_CapInit( CapModeTypeDef cap )
|
||||||
|
{
|
||||||
|
R8_TMR1_CTRL_MOD = RB_TMR_ALL_CLEAR;
|
||||||
|
R8_TMR1_CTRL_MOD = RB_TMR_COUNT_EN \
|
||||||
|
|RB_TMR_MODE_IN \
|
||||||
|
|(cap<<6);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn TMR2_CapInit
|
||||||
|
*
|
||||||
|
* @brief cap
|
||||||
|
*
|
||||||
|
* @param CapModeTypeDef
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void TMR2_CapInit( CapModeTypeDef cap )
|
||||||
|
{
|
||||||
|
R8_TMR2_CTRL_MOD = RB_TMR_ALL_CLEAR;
|
||||||
|
R8_TMR2_CTRL_MOD = RB_TMR_COUNT_EN \
|
||||||
|
|RB_TMR_MODE_IN \
|
||||||
|
|(cap<<6);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn TMR1_DMACfd
|
||||||
|
*
|
||||||
|
* @brief TMR DMA Configuration
|
||||||
|
*
|
||||||
|
* @param ENABLE/DISABLE
|
||||||
|
* startAddr
|
||||||
|
* endAddr
|
||||||
|
* DMAModeTypeDef
|
||||||
|
* @return None
|
||||||
|
**/
|
||||||
|
void TMR1_DMACfg( UINT8 s, UINT16 startAddr, UINT16 endAddr, DMAModeTypeDef m )
|
||||||
|
{
|
||||||
|
if(s == DISABLE){
|
||||||
|
R8_TMR1_CTRL_DMA = 0;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
if(m) R8_TMR1_CTRL_DMA = RB_TMR_DMA_LOOP|RB_TMR_DMA_ENABLE;
|
||||||
|
else R8_TMR1_CTRL_DMA = RB_TMR_DMA_ENABLE;
|
||||||
|
R32_TMR1_DMA_BEG = startAddr;
|
||||||
|
R32_TMR1_DMA_END = endAddr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn TMR2_DMACfd
|
||||||
|
*
|
||||||
|
* @brief TMR DMA Configuration
|
||||||
|
*
|
||||||
|
* @param ENABLE/DISABLE
|
||||||
|
* startAddr
|
||||||
|
* endAddr
|
||||||
|
* DMAModeTypeDef
|
||||||
|
* @return None
|
||||||
|
**/
|
||||||
|
|
||||||
|
void TMR2_DMACfg( UINT8 s, UINT16 startAddr, UINT16 endAddr, DMAModeTypeDef m )
|
||||||
|
{
|
||||||
|
if(s == DISABLE){
|
||||||
|
R8_TMR2_CTRL_DMA = 0;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
if(m) R8_TMR2_CTRL_DMA = RB_TMR_DMA_LOOP|RB_TMR_DMA_ENABLE;
|
||||||
|
else R8_TMR2_CTRL_DMA = RB_TMR_DMA_ENABLE;
|
||||||
|
R32_TMR2_DMA_BEG = startAddr;
|
||||||
|
R32_TMR2_DMA_END = endAddr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,548 @@
|
||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : CH56x_uart.c
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0
|
||||||
|
* Date : 2020/07/31
|
||||||
|
* Description :
|
||||||
|
*********************************************************************************
|
||||||
|
* 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 "CH56x_common.h"
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* @fn UART0_DefInit
|
||||||
|
*
|
||||||
|
* @brief Serial port default initialization configuration: FIFO enabled, trigger point byte count, serial port data
|
||||||
|
* length setting, baud rate and frequency division coefficient
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void UART0_DefInit(void)
|
||||||
|
{
|
||||||
|
R8_UART0_DIV = 1;
|
||||||
|
UART0_BaudRateCfg(115200);
|
||||||
|
R8_UART0_FCR =
|
||||||
|
(2 << 6) | RB_FCR_TX_FIFO_CLR | RB_FCR_RX_FIFO_CLR | RB_FCR_FIFO_EN; // FIFO open, trigger point 4 bytes
|
||||||
|
R8_UART0_LCR = RB_LCR_WORD_SZ;
|
||||||
|
R8_UART0_IER = RB_IER_TXD_EN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn UART1_DefInit
|
||||||
|
*
|
||||||
|
* @brief Serial port default initialization configuration: FIFO enabled, trigger point byte count, serial port data
|
||||||
|
*length setting, baud rate and frequency division coefficient
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
**/
|
||||||
|
void UART1_DefInit(void)
|
||||||
|
{
|
||||||
|
R8_UART1_DIV = 1;
|
||||||
|
UART1_BaudRateCfg(115200);
|
||||||
|
R8_UART1_FCR =
|
||||||
|
(2 << 6) | RB_FCR_TX_FIFO_CLR | RB_FCR_RX_FIFO_CLR | RB_FCR_FIFO_EN; // FIFO open, trigger point 4 bytes
|
||||||
|
R8_UART1_LCR = RB_LCR_WORD_SZ;
|
||||||
|
R8_UART1_IER = RB_IER_TXD_EN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn UART2_DefInit
|
||||||
|
*
|
||||||
|
* @brief Serial port default initialization configuration: FIFO enabled, trigger point byte count, serial port data
|
||||||
|
* length setting, baud rate and frequency division coefficient
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void UART2_DefInit(void)
|
||||||
|
{
|
||||||
|
R8_UART2_DIV = 1;
|
||||||
|
UART2_BaudRateCfg(115200);
|
||||||
|
R8_UART2_FCR =
|
||||||
|
(2 << 6) | RB_FCR_TX_FIFO_CLR | RB_FCR_RX_FIFO_CLR | RB_FCR_FIFO_EN; // FIFO open, trigger point 4 bytes
|
||||||
|
R8_UART2_LCR = RB_LCR_WORD_SZ;
|
||||||
|
R8_UART2_IER = RB_IER_TXD_EN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn UART3_DefInit
|
||||||
|
*
|
||||||
|
* @brief Serial port default initialization configuration: FIFO enabled, trigger point byte count, serial port data
|
||||||
|
* length setting, baud rate and frequency division coefficient
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void UART3_DefInit(void)
|
||||||
|
{
|
||||||
|
R8_UART3_DIV = 1;
|
||||||
|
UART3_BaudRateCfg(115200);
|
||||||
|
R8_UART3_FCR =
|
||||||
|
(2 << 6) | RB_FCR_TX_FIFO_CLR | RB_FCR_RX_FIFO_CLR | RB_FCR_FIFO_EN; // FIFO open, trigger point 4 bytes
|
||||||
|
R8_UART3_LCR = RB_LCR_WORD_SZ;
|
||||||
|
R8_UART3_IER = RB_IER_TXD_EN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn UART0_BaudRateCfg
|
||||||
|
*
|
||||||
|
* @brief Serial port baud rate configuration
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void UART0_BaudRateCfg(UINT32 baudrate)
|
||||||
|
{
|
||||||
|
UINT32 x;
|
||||||
|
|
||||||
|
x = 10 * (FREQ_SYS * 2 / R8_UART0_DIV) / 16 / baudrate;
|
||||||
|
x = (x + 5) / 10;
|
||||||
|
R16_UART0_DL = (UINT16)x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn UART1_BaudRateCfg
|
||||||
|
*
|
||||||
|
* @brief Serial port baud rate configuration
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void UART1_BaudRateCfg(UINT32 baudrate)
|
||||||
|
{
|
||||||
|
UINT32 x;
|
||||||
|
|
||||||
|
x = 10 * (FREQ_SYS * 2 / R8_UART1_DIV) / 16 / baudrate;
|
||||||
|
x = (x + 5) / 10;
|
||||||
|
R16_UART1_DL = (UINT16)x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn UART2_BaudRateCfg
|
||||||
|
*
|
||||||
|
* @brief Serial port baud rate configuration
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void UART2_BaudRateCfg(UINT32 baudrate)
|
||||||
|
{
|
||||||
|
UINT32 x;
|
||||||
|
|
||||||
|
x = 10 * (FREQ_SYS * 2 / R8_UART2_DIV) / 16 / baudrate;
|
||||||
|
x = (x + 5) / 10;
|
||||||
|
R16_UART2_DL = (UINT16)x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn UART3_BaudRateCfg
|
||||||
|
*
|
||||||
|
* @brief Serial port baud rate configuration
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void UART3_BaudRateCfg(UINT32 baudrate)
|
||||||
|
{
|
||||||
|
UINT32 x;
|
||||||
|
|
||||||
|
x = 10 * (FREQ_SYS * 2 / R8_UART3_DIV) / 16 / baudrate;
|
||||||
|
x = (x + 5) / 10;
|
||||||
|
R16_UART3_DL = (UINT16)x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn UART0_ByteTrigCfg
|
||||||
|
*
|
||||||
|
* @brief Serial byte trigger interrupt configuration
|
||||||
|
*
|
||||||
|
* @param b - trigger bytes
|
||||||
|
* refer to UARTByteTRIGTypeDef
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void UART0_ByteTrigCfg(UARTByteTRIGTypeDef b)
|
||||||
|
{
|
||||||
|
R8_UART0_FCR = (R8_UART0_FCR & ~RB_FCR_FIFO_TRIG) | (b << 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn UART1_ByteTrigCfg
|
||||||
|
*
|
||||||
|
* @brief Serial byte trigger interrupt configuration
|
||||||
|
*
|
||||||
|
* @param b - trigger bytes
|
||||||
|
* refer to UARTByteTRIGTypeDef
|
||||||
|
* @return None
|
||||||
|
**/
|
||||||
|
void UART1_ByteTrigCfg(UARTByteTRIGTypeDef b)
|
||||||
|
{
|
||||||
|
R8_UART1_FCR = (R8_UART1_FCR & ~RB_FCR_FIFO_TRIG) | (b << 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn UART2_ByteTrigCfg
|
||||||
|
*
|
||||||
|
* @brief Serial byte trigger interrupt configuration
|
||||||
|
*
|
||||||
|
* @param b - trigger bytes
|
||||||
|
* refer to UARTByteTRIGTypeDef
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void UART2_ByteTrigCfg(UARTByteTRIGTypeDef b)
|
||||||
|
{
|
||||||
|
R8_UART2_FCR = (R8_UART2_FCR & ~RB_FCR_FIFO_TRIG) | (b << 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn UART3_ByteTrigCfg
|
||||||
|
*
|
||||||
|
* @brief Serial byte trigger interrupt configuration
|
||||||
|
*
|
||||||
|
* @param b - trigger bytes
|
||||||
|
* refer to UARTByteTRIGTypeDef
|
||||||
|
* @return None
|
||||||
|
***/
|
||||||
|
void UART3_ByteTrigCfg(UARTByteTRIGTypeDef b)
|
||||||
|
{
|
||||||
|
R8_UART3_FCR = (R8_UART3_FCR & ~RB_FCR_FIFO_TRIG) | (b << 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn UART0_INTCfg
|
||||||
|
*
|
||||||
|
* @brief Serial port interrupt configuration
|
||||||
|
*
|
||||||
|
* @param s - interrupt control status
|
||||||
|
* ENABLE - Enable the corresponding interrupt
|
||||||
|
* DISABLE - Disable the corresponding interrupt
|
||||||
|
* i - interrupt type
|
||||||
|
* RB_IER_MODEM_CHG - Modem input status change interrupt enable bit (supported on UART0 only)
|
||||||
|
* RB_IER_LINE_STAT - Receive Line Status Interrupt
|
||||||
|
* RB_IER_THR_EMPTY - Send Holding Register Empty Interrupt
|
||||||
|
* RB_IER_RECV_RDY - receive data interrupt
|
||||||
|
* @return None
|
||||||
|
**/
|
||||||
|
void UART0_INTCfg(UINT8 s, UINT8 i)
|
||||||
|
{
|
||||||
|
if (s)
|
||||||
|
{
|
||||||
|
R8_UART0_IER |= i;
|
||||||
|
R8_UART0_MCR |= RB_MCR_INT_OE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
R8_UART0_IER &= ~i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn UART1_INTCfg
|
||||||
|
*
|
||||||
|
* @brief Serial port interrupt configuration
|
||||||
|
*
|
||||||
|
* @param s - interrupt control status
|
||||||
|
* ENABLE - Enable the corresponding interrupt
|
||||||
|
* DISABLE - Disable the corresponding interrupt
|
||||||
|
* i - interrupt type
|
||||||
|
* RB_IER_MODEM_CHG - Modem input status change interrupt enable bit (supported on UART0 only)
|
||||||
|
* RB_IER_LINE_STAT - Receive Line Status Interrupt
|
||||||
|
* RB_IER_THR_EMPTY - Send Holding Register Empty Interrupt
|
||||||
|
* RB_IER_RECV_RDY - receive data interrupt
|
||||||
|
* @return None
|
||||||
|
**/
|
||||||
|
void UART1_INTCfg(UINT8 s, UINT8 i)
|
||||||
|
{
|
||||||
|
if (s)
|
||||||
|
{
|
||||||
|
R8_UART1_IER |= i;
|
||||||
|
R8_UART1_MCR |= RB_MCR_INT_OE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
R8_UART1_IER &= ~i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn UART2_INTCfg
|
||||||
|
*
|
||||||
|
* @brief Serial port interrupt configuration
|
||||||
|
*
|
||||||
|
* @param s - interrupt control status
|
||||||
|
* ENABLE - Enable the corresponding interrupt
|
||||||
|
* DISABLE - Disable the corresponding interrupt
|
||||||
|
* i - interrupt type
|
||||||
|
* RB_IER_MODEM_CHG - Modem input status change interrupt enable bit (supported on UART0 only)
|
||||||
|
* RB_IER_LINE_STAT - Receive Line Status Interrupt
|
||||||
|
* RB_IER_THR_EMPTY - Send Holding Register Empty Interrupt
|
||||||
|
* RB_IER_RECV_RDY - receive data interrupt
|
||||||
|
* @return None
|
||||||
|
**/
|
||||||
|
void UART2_INTCfg(UINT8 s, UINT8 i)
|
||||||
|
{
|
||||||
|
if (s)
|
||||||
|
{
|
||||||
|
R8_UART2_IER |= i;
|
||||||
|
R8_UART2_MCR |= RB_MCR_INT_OE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
R8_UART2_IER &= ~i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn UART3_INTCfg
|
||||||
|
*
|
||||||
|
* @brief Serial port interrupt configuration
|
||||||
|
*
|
||||||
|
* @param s - interrupt control status
|
||||||
|
* ENABLE - Enable the corresponding interrupt
|
||||||
|
* DISABLE - Disable the corresponding interrupt
|
||||||
|
* i - interrupt type
|
||||||
|
* RB_IER_MODEM_CHG - Modem input status change interrupt enable bit (supported on UART0 only)
|
||||||
|
* RB_IER_LINE_STAT - Receive Line Status Interrupt
|
||||||
|
* RB_IER_THR_EMPTY - Send Holding Register Empty Interrupt
|
||||||
|
* RB_IER_RECV_RDY - receive data interrupt
|
||||||
|
* @return None
|
||||||
|
**/
|
||||||
|
void UART3_INTCfg(UINT8 s, UINT8 i)
|
||||||
|
{
|
||||||
|
if (s)
|
||||||
|
{
|
||||||
|
R8_UART3_IER |= i;
|
||||||
|
R8_UART3_MCR |= RB_MCR_INT_OE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
R8_UART3_IER &= ~i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn UART0_Reset
|
||||||
|
*
|
||||||
|
* @brief Serial port software reset
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
**/
|
||||||
|
void UART0_Reset(void)
|
||||||
|
{
|
||||||
|
R8_UART0_IER = RB_IER_RESET;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn UART1_Reset
|
||||||
|
*
|
||||||
|
* @brief Serial port software reset
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
**/
|
||||||
|
void UART1_Reset(void)
|
||||||
|
{
|
||||||
|
R8_UART1_IER = RB_IER_RESET;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn UART2_Reset
|
||||||
|
*
|
||||||
|
* @brief Serial port software reset
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
**/
|
||||||
|
void UART2_Reset(void)
|
||||||
|
{
|
||||||
|
R8_UART2_IER = RB_IER_RESET;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn UART3_Reset
|
||||||
|
*
|
||||||
|
* @brief Serial port software reset
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
**/
|
||||||
|
void UART3_Reset(void)
|
||||||
|
{
|
||||||
|
R8_UART3_IER = RB_IER_RESET;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn UART0_SendString
|
||||||
|
*
|
||||||
|
* @brief Serial multi-byte transmission
|
||||||
|
*
|
||||||
|
* @param buf - The first address of the data content to be sent
|
||||||
|
* l - length of data to be sent
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void UART0_SendString(PUINT8 buf, UINT16 l)
|
||||||
|
{
|
||||||
|
UINT16 len = l;
|
||||||
|
|
||||||
|
while (len)
|
||||||
|
{
|
||||||
|
if (R8_UART0_TFC != UART_FIFO_SIZE)
|
||||||
|
{
|
||||||
|
R8_UART0_THR = *buf++;
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn UART1_SendString
|
||||||
|
*
|
||||||
|
* @brief Serial multi-byte transmission
|
||||||
|
*
|
||||||
|
* @param buf - The first address of the data content to be sent
|
||||||
|
* l - length of data to be sent
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void UART1_SendString(PUINT8 buf, UINT16 l)
|
||||||
|
{
|
||||||
|
UINT16 len = l;
|
||||||
|
|
||||||
|
while (len)
|
||||||
|
{
|
||||||
|
if (R8_UART1_TFC != UART_FIFO_SIZE)
|
||||||
|
{
|
||||||
|
R8_UART1_THR = *buf++;
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn UART2_SendString
|
||||||
|
*
|
||||||
|
* @brief Serial multi-byte transmission
|
||||||
|
*
|
||||||
|
* @param buf - The first address of the data content to be sent
|
||||||
|
* l - length of data to be sent
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void UART2_SendString(PUINT8 buf, UINT16 l)
|
||||||
|
{
|
||||||
|
UINT16 len = l;
|
||||||
|
|
||||||
|
while (len)
|
||||||
|
{
|
||||||
|
if (R8_UART2_TFC != UART_FIFO_SIZE)
|
||||||
|
{
|
||||||
|
R8_UART2_THR = *buf++;
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn UART3_SendString
|
||||||
|
*
|
||||||
|
* @brief Serial multi-byte transmission
|
||||||
|
*
|
||||||
|
* @param buf - The first address of the data content to be sent
|
||||||
|
* l - length of data to be sent
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void UART3_SendString(PUINT8 buf, UINT16 l)
|
||||||
|
{
|
||||||
|
UINT16 len = l;
|
||||||
|
|
||||||
|
while (len)
|
||||||
|
{
|
||||||
|
if (R8_UART3_TFC != UART_FIFO_SIZE)
|
||||||
|
{
|
||||||
|
R8_UART3_THR = *buf++;
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn UART0_RecvString
|
||||||
|
*
|
||||||
|
* @brief Serial port read multibyte
|
||||||
|
*
|
||||||
|
* @param buf - The first address of the read data storage buffer
|
||||||
|
*
|
||||||
|
* @return read data length
|
||||||
|
*/
|
||||||
|
UINT16 UART0_RecvString(PUINT8 buf)
|
||||||
|
{
|
||||||
|
UINT16 len = 0;
|
||||||
|
|
||||||
|
while (R8_UART0_RFC)
|
||||||
|
{
|
||||||
|
*buf++ = R8_UART0_RBR;
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn UART1_RecvString
|
||||||
|
*
|
||||||
|
* @brief Serial port read multibyte
|
||||||
|
*
|
||||||
|
* @param buf - The first address of the read data storage buffer
|
||||||
|
*
|
||||||
|
* @return read data length
|
||||||
|
*/
|
||||||
|
|
||||||
|
UINT16 UART1_RecvString(PUINT8 buf)
|
||||||
|
{
|
||||||
|
UINT16 len = 0;
|
||||||
|
|
||||||
|
while (R8_UART1_RFC)
|
||||||
|
{
|
||||||
|
*buf++ = R8_UART1_RBR;
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn UART2_RecvString
|
||||||
|
*
|
||||||
|
* @brief Serial port read multibyte
|
||||||
|
*
|
||||||
|
* @param buf - The first address of the read data storage buffer
|
||||||
|
*
|
||||||
|
* @return read data length
|
||||||
|
*/
|
||||||
|
|
||||||
|
UINT16 UART2_RecvString(PUINT8 buf)
|
||||||
|
{
|
||||||
|
UINT16 len = 0;
|
||||||
|
|
||||||
|
while (R8_UART2_RFC)
|
||||||
|
{
|
||||||
|
*buf++ = R8_UART2_RBR;
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* @fn UART3_RecvString
|
||||||
|
*
|
||||||
|
* @brief Serial port read multibyte
|
||||||
|
*
|
||||||
|
* @param buf - The first address of the read data storage buffer
|
||||||
|
*
|
||||||
|
* @return read data length
|
||||||
|
*/
|
||||||
|
|
||||||
|
UINT16 UART3_RecvString(PUINT8 buf)
|
||||||
|
{
|
||||||
|
UINT16 len = 0;
|
||||||
|
|
||||||
|
while (R8_UART3_RFC)
|
||||||
|
{
|
||||||
|
*buf++ = R8_UART3_RBR;
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (len);
|
||||||
|
}
|
|
@ -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,386 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
// config serial reg
|
||||||
|
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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
volatile struct uart_registers *uxreg = (struct uart_registers *)serial_cfg->hw_cfg.serial_register_base;
|
||||||
|
|
||||||
|
if (1 == uxreg->LSR.data_rdy) {
|
||||||
|
/* UART_II_RECV_RDY is cleared by reading RBR */
|
||||||
|
ch = (uxreg->RFC > 0) ? uxreg->RBR : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
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 = (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();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
|
@ -307,6 +307,17 @@ KERNELPATHS += \
|
||||||
-I$(KERNEL_ROOT)/include #
|
-I$(KERNEL_ROOT)/include #
|
||||||
endif
|
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)
|
ifeq ($(BSP_ROOT),$(KERNEL_ROOT)/board/rv32m1-vega)
|
||||||
KERNELPATHS += \
|
KERNELPATHS += \
|
||||||
-I$(KERNEL_ROOT)/arch/risc-v/rv32m1-vega \
|
-I$(KERNEL_ROOT)/arch/risc-v/rv32m1-vega \
|
||||||
|
|
Loading…
Reference in New Issue