Add ch569 SRC from CH569EVT.ZIP

This commit is contained in:
songyanguang 2025-04-07 17:44:27 +08:00
parent fd1e44de35
commit 0fa8ff5368
32 changed files with 10736 additions and 0 deletions

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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();
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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