Compare commits

...

10 Commits

Author SHA1 Message Date
nova
9d9bb3b156 restructuring 2024-05-10 02:40:12 +02:00
Richard Goulter
f4fa6fedd4 update readme 2023-12-23 08:03:10 +07:00
Richard Goulter
683e7ea92e check in nix 2023-12-21 23:00:40 +07:00
Richard Goulter
52f3ba680a rename sdk lib 2023-12-21 22:46:50 +07:00
Richard Goulter
7500f5489a add app, profile 2023-12-21 22:46:50 +07:00
Richard Goulter
1294d9f0c0 add Makefile 2023-12-21 22:46:50 +07:00
Richard Goulter
8a4775cf03 sdk: copy Ld 2023-12-21 22:44:09 +07:00
Richard Goulter
31c6c4e250 sdk: copy StdPeriphDriver 2023-12-21 22:44:09 +07:00
Richard Goulter
c4be43ec91 sdk: copy Startup 2023-12-21 22:43:50 +07:00
Richard Goulter
3c4c7b5640 sdk: copy RVMSIS 2023-12-21 22:43:16 +07:00
49 changed files with 12813 additions and 7 deletions

159
Makefile Normal file
View File

@ -0,0 +1,159 @@
## Makefile
# Prefix for older riscv gcc is risv-none-embed
# Prefix for newer riscv gcc is risv-none-elf
# TOOLCHAIN_PREFIX := riscv-none-embed
TOOLCHAIN_PREFIX := riscv-none-elf
APP_C_SRCS += \
./src/main.c
SDK_BLE_HAL_C_SRCS := \
./sdk/BLE/HAL/MCU.c \
./sdk/BLE/HAL/RTC.c \
./sdk/BLE/HAL/SLEEP.c
SDK_STDPERIPHDRIVER_C_SRCS += \
./sdk/StdPeriphDriver/CH59x_adc.c \
./sdk/StdPeriphDriver/CH59x_clk.c \
./sdk/StdPeriphDriver/CH59x_flash.c \
./sdk/StdPeriphDriver/CH59x_gpio.c \
./sdk/StdPeriphDriver/CH59x_i2c.c \
./sdk/StdPeriphDriver/CH59x_lcd.c \
./sdk/StdPeriphDriver/CH59x_pwr.c \
./sdk/StdPeriphDriver/CH59x_sys.c \
./sdk/StdPeriphDriver/CH59x_uart1.c
SDK_RVMSIS_C_SRCS += \
./sdk/RVMSIS/core_riscv.c
SDK_BLE_LIB_S_UPPER_SRCS += \
./sdk/BLE/LIB/ble_task_scheduler.S
SDK_STARTUP_S_UPPER_SRCS += \
./sdk/Startup/startup_CH592.S
C_SRCS := \
$(APP_C_SRCS) \
$(SDK_BLE_HAL_C_SRCS) \
$(SDK_STDPERIPHDRIVER_C_SRCS) \
$(SDK_RVMSIS_C_SRCS)
S_UPPER_SRCS := \
$(SDK_BLE_LIB_S_UPPER_SRCS) \
$(SDK_STARTUP_S_UPPER_SRCS)
OBJS := \
$(foreach src,$(C_SRCS),$(subst ./,obj/,$(patsubst %.c,%.o,$(src)))) \
$(foreach src,$(S_UPPER_SRCS),$(subst ./,obj/,$(patsubst %.S,%.o,$(src))))
MAKEFILE_DEPS := \
$(foreach obj,$(OBJS),$(patsubst %.o,%.d,$(obj)))
STDPERIPHDRIVER_LIBS := -L"./sdk/StdPeriphDriver" -lISP592
BLE_LIB_LIBS := -L"./sdk/BLE/LIB" -lCH59xBLE
LIBS := $(STDPERIPHDRIVER_LIBS) $(BLE_LIB_LIBS)
SECONDARY_FLASH := main.hex
SECONDARY_LIST := main.lst
SECONDARY_SIZE := main.siz
# ARCH is rv32imac on older gcc, rv32imac_zicsr on newer gcc
# ARCH := rv32imac
ARCH := rv32imac_zicsr
CFLAGS_COMMON := \
-march=$(ARCH) \
-mabi=ilp32 \
-mcmodel=medany \
-msmall-data-limit=8 \
-mno-save-restore \
-Os \
-fmessage-length=0 \
-fsigned-char \
-ffunction-sections \
-fdata-sections
#-g
.PHONY: all
all: main.elf secondary-outputs
.PHONY: clean
clean:
-rm $(OBJS)
-rm $(MAKEFILE_DEPS)
-rm $(SECONDARY_FLASH)
-rm $(SECONDARY_LIST)
-rm main.elf
-rm main.map
-rm -r ./obj
.PHONY: secondary-outputs
secondary-outputs: $(SECONDARY_FLASH) $(SECONDARY_LIST) $(SECONDARY_SIZE)
main.elf: $(OBJS)
${TOOLCHAIN_PREFIX}-gcc \
$(CFLAGS_COMMON) \
-T "sdk/Ld/Link.ld" \
-nostartfiles \
-Xlinker \
--gc-sections \
-Xlinker \
--print-memory-usage \
-Wl,-Map,"main.map" \
-Lobj \
--specs=nano.specs \
--specs=nosys.specs \
-o "main.elf" \
$(OBJS) \
$(LIBS)
%.hex: %.elf
@ ${TOOLCHAIN_PREFIX}-objcopy -O ihex "$<" "$@"
%.lst: %.elf
@ ${TOOLCHAIN_PREFIX}-objdump \
--source \
--all-headers \
--demangle \
--line-numbers \
--wide "$<" > "$@"
%.siz: %.elf
@ ${TOOLCHAIN_PREFIX}-size --format=berkeley "$<"
obj/%.o: ./%.c
@ mkdir --parents $(dir $@)
@ ${TOOLCHAIN_PREFIX}-gcc \
$(CFLAGS_COMMON) \
-DDEBUG=1 \
-I"src/include" \
-I"sdk/StdPeriphDriver/inc" \
-I"sdk/RVMSIS" \
-I"sdk/BLE/LIB" \
-I"sdk/BLE/HAL/include" \
-std=gnu99 \
-MMD \
-MP \
-MF"$(@:%.o=%.d)" \
-MT"$(@)" \
-c \
-o "$@" "$<"
obj/%.o: ./%.S
@ mkdir --parents $(dir $@)
@ ${TOOLCHAIN_PREFIX}-gcc \
$(CFLAGS_COMMON) \
-x assembler \
-MMD \
-MP \
-MF"$(@:%.o=%.d)" \
-MT"$(@)" \
-c \
-o "$@" "$<"
f: clean all
wchisp flash ./main.elf

21
README.md Normal file
View File

@ -0,0 +1,21 @@
CH592 Makefile Template
=======================
A Makefile template for the [openwch/ch592](https://github.com/openwch/ch592) to remove the need for MounRiver Studio.\
Based on [rgoulter/ch592-ble-hid-keyboard-example](https://github.com/rgoulter/ch592-ble-hid-keyboard-example)
The elf can be flashed to the CH592 using [wchisp](https://github.com/ch32-rs/wchisp). (Enter the CH592 bootloader by holding down BOOT when connecting it using USB).\
The SDK for CH592 from the openwch EVT is vendored under ``sdk/``. (Encoding has been changed from gbk to utf-8).
``make`` to complie \
``make clean`` to clean/remove the compiled elf \
``make flash`` to flash \
``make f`` to compile and flash.
To install the toolchain using Gentoo native tools\
``crossdev --target riscv-none-elf --with-arch=rv32imca_zicsr --with-abi=ilp32``\
``echo "cross-riscv-none-elf/newlib nano" >> /etc/portage/package.use/embedded``\
``emerge -a cross-riscv-none-elf/newlib``

View File

@ -1,7 +0,0 @@
CH592 BLE HID Keyboard
======================
The BLE/HID_Keyboard example from `openwch/ch592`_,
in its own repo so it's easier to build.
.. _openwch/ch592 https://github.com/openwch/ch592

BIN
sdk/BLE/LIB/libCH59xBLE.a Normal file

Binary file not shown.

177
sdk/Ld/Link.ld Normal file
View File

@ -0,0 +1,177 @@
ENTRY( _start )
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 448K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 26K
}
SECTIONS
{
.init :
{
_sinit = .;
. = ALIGN(4);
KEEP(*(SORT_NONE(.init)))
. = ALIGN(4);
_einit = .;
} >FLASH AT>FLASH
/* .vector :
{
*(.vector);
} >FLASH AT>FLASH */
.highcodelalign :
{
. = ALIGN(4);
PROVIDE(_highcode_lma = .);
} >FLASH AT>FLASH
.highcode :
{
. = ALIGN(4);
PROVIDE(_highcode_vma_start = .);
*(.vector);
KEEP(*(SORT_NONE(.vector_handler)))
*(.highcode);
*(.highcode.*);
. = ALIGN(4);
PROVIDE(_highcode_vma_end = .);
} >RAM AT>FLASH
.text :
{
. = ALIGN(4);
KEEP(*(SORT_NONE(.handle_reset)))
*(.text)
*(.text.*)
*(.rodata)
*(.rodata*)
*(.sdata2.*)
*(.glue_7)
*(.glue_7t)
*(.gnu.linkonce.t.*)
. = ALIGN(4);
} >FLASH AT>FLASH
.fini :
{
KEEP(*(SORT_NONE(.fini)))
. = ALIGN(4);
} >FLASH AT>FLASH
PROVIDE( _etext = . );
PROVIDE( _eitcm = . );
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH AT>FLASH
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
} >FLASH AT>FLASH
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH AT>FLASH
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
} >FLASH AT>FLASH
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
} >FLASH AT>FLASH
.dalign :
{
. = ORIGIN(RAM) + MAX(0x800 , SIZEOF(.highcode));
} >RAM AT>FLASH
.dlalign :
{
. = ALIGN(4);
PROVIDE(_data_lma = .);
} >FLASH AT>FLASH
.data :
{
. = ALIGN(4);
PROVIDE(_data_vma = .);
*(.gnu.linkonce.r.*)
*(.data .data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
PROVIDE( __global_pointer$ = . + 0x800 );
*(.sdata .sdata.*)
*(.gnu.linkonce.s.*)
. = ALIGN(8);
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
. = ALIGN(4);
PROVIDE( _edata = .);
} >RAM AT>FLASH
.bss :
{
. = ALIGN(4);
PROVIDE( _sbss = .);
*(.sbss*)
*(.gnu.linkonce.sb.*)
*(.bss*)
*(.gnu.linkonce.b.*)
*(COMMON*)
. = ALIGN(4);
PROVIDE( _ebss = .);
} >RAM AT>FLASH
PROVIDE( _end = _ebss);
PROVIDE( end = . );
.stack ORIGIN(RAM)+LENGTH(RAM) :
{
. = ALIGN(4);
PROVIDE(_eusrstack = . );
} >RAM
}

306
sdk/RVMSIS/core_riscv.c Normal file
View File

@ -0,0 +1,306 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : core_riscv.c
* Author : WCH
* Version : V1.1.0
* Date : 2021/06/06
* Description : RISC-V Core Peripheral Access Layer Source File
*********************************************************************************
* 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_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);
}

592
sdk/RVMSIS/core_riscv.h Normal file
View File

@ -0,0 +1,592 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : core_riscv.h
* Author : WCH
* Version : V1.1.0
* Date : 2023/04/10
* Description : CH592 RISC-V Core Peripheral Access Layer Header File
*********************************************************************************
* 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_RV3A_H__
#define __CORE_RV3A_H__
#ifdef __cplusplus
extern "C" {
#endif
/* 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 {SUCCESS = 0, ERROR = !SUCCESS} ErrorStatus;
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
{
__I uint32_t ISR[8]; // 0
__I uint32_t IPR[8]; // 20H
__IO uint32_t ITHRESDR; // 40H
uint8_t RESERVED[4]; // 44H
__O uint32_t CFGR; // 48H
__I uint32_t GISR; // 4CH
__IO uint8_t VTFIDR[4]; // 50H
uint8_t RESERVED0[0x0C]; // 54H
__IO uint32_t VTFADDR[4]; // 60H
uint8_t RESERVED1[0x90]; // 70H
__O uint32_t IENR[8]; // 100H
uint8_t RESERVED2[0x60]; // 120H
__O uint32_t IRER[8]; // 180H
uint8_t RESERVED3[0x60]; // 1A0H
__O uint32_t IPSR[8]; // 200H
uint8_t RESERVED4[0x60]; // 220H
__O uint32_t IPRR[8]; // 280H
uint8_t RESERVED5[0x60]; // 2A0H
__IO uint32_t IACTR[8]; // 300H
uint8_t RESERVED6[0xE0]; // 320H
__IO uint8_t IPRIOR[256]; // 400H
uint8_t RESERVED7[0x810]; // 500H
__IO uint32_t SCTLR; // D10H
} PFIC_Type;
/* memory mapped structure for SysTick */
typedef struct
{
__IO uint32_t CTLR;
__IO uint32_t SR;
__IO uint64_t CNT;
__IO uint64_t CMP;
} SysTick_Type;
#define PFIC ((PFIC_Type *)0xE000E000)
#define SysTick ((SysTick_Type *)0xE000F000)
#define PFIC_KEY1 ((uint32_t)0xFA050000)
#define PFIC_KEY2 ((uint32_t)0xBCAF0000)
#define PFIC_KEY3 ((uint32_t)0xBEEF0000)
/* ########################## define #################################### */
#define __nop() __asm__ volatile("nop")
#define read_csr(reg) ({unsigned long __tmp; \
__asm__ volatile ("csrr %0, " #reg : "=r"(__tmp)); \
__tmp; })
#define write_csr(reg, val) ({ \
if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \
__asm__ volatile ("csrw " #reg ", %0" :: "i"(val)); \
else \
__asm__ volatile ("csrw " #reg ", %0" :: "r"(val)); })
#define PFIC_EnableAllIRQ() {write_csr(0x800, 0x88);__nop();__nop();}
#define PFIC_DisableAllIRQ() {write_csr(0x800, 0x80);__nop();__nop();}
/* ########################## PFIC functions #################################### */
/*******************************************************************************
* @fn PFIC_EnableIRQ
*
* @brief Enable Interrupt
*
* @param IRQn - Interrupt Numbers
*/
__attribute__((always_inline)) RV_STATIC_INLINE void PFIC_EnableIRQ(IRQn_Type IRQn)
{
PFIC->IENR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn)&0x1F));
}
/*******************************************************************************
* @fn PFIC_DisableIRQ
*
* @brief Disable Interrupt
*
* @param IRQn - Interrupt Numbers
*/
__attribute__((always_inline)) RV_STATIC_INLINE void PFIC_DisableIRQ(IRQn_Type IRQn)
{
PFIC->IRER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn)&0x1F));
__nop();
__nop();
}
/*******************************************************************************
* @fn PFIC_GetStatusIRQ
*
* @brief Get Interrupt Enable State
*
* @param IRQn - Interrupt Numbers
*
* @return 1: Interrupt Enable
* 0: Interrupt Disable
*/
__attribute__((always_inline)) RV_STATIC_INLINE uint32_t PFIC_GetStatusIRQ(IRQn_Type IRQn)
{
return ((uint32_t)((PFIC->ISR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(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
*/
__attribute__((always_inline)) RV_STATIC_INLINE uint32_t PFIC_GetPendingIRQ(IRQn_Type IRQn)
{
return ((uint32_t)((PFIC->IPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn)&0x1F))) ? 1 : 0));
}
/*******************************************************************************
* @fn PFIC_SetPendingIRQ
*
* @brief Set Interrupt Pending
*
* @param IRQn - Interrupt Numbers
*/
__attribute__((always_inline)) RV_STATIC_INLINE void PFIC_SetPendingIRQ(IRQn_Type IRQn)
{
PFIC->IPSR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn)&0x1F));
}
/*******************************************************************************
* @fn PFIC_ClearPendingIRQ
*
* @brief Clear Interrupt Pending
*
* @param IRQn - Interrupt Numbers
*/
__attribute__((always_inline)) RV_STATIC_INLINE void PFIC_ClearPendingIRQ(IRQn_Type IRQn)
{
PFIC->IPRR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn)&0x1F));
}
/*******************************************************************************
* @fn PFIC_GetActive
*
* @brief Get Interrupt Active State
*
* @param IRQn - Interrupt Numbers
*
* @return 1: Interrupt Active
* 0: Interrupt No Active.
*/
__attribute__((always_inline)) RV_STATIC_INLINE uint32_t PFIC_GetActive(IRQn_Type IRQn)
{
return ((uint32_t)((PFIC->IACTR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn)&0x1F))) ? 1 : 0));
}
/*******************************************************************************
* @fn PFIC_SetPriority
*
* @brief Set Interrupt Priority
*
* @param IRQn - Interrupt Numbers
* @param priority - bit7: pre-emption priority
* bit6-bit4: subpriority
*/
__attribute__((always_inline)) RV_STATIC_INLINE void PFIC_SetPriority(IRQn_Type IRQn, uint8_t priority)
{
PFIC->IPRIOR[(uint32_t)(IRQn)] = priority;
}
/*********************************************************************
* @fn SetVTFIRQ
*
* @brief Set VTF Interrupt
*
* @param addr - VTF interrupt service function base address.
* IRQn - Interrupt Numbers
* num - VTF Interrupt Numbers
* NewState - DISABLE or ENABLE
*
* @return none
*/
__attribute__((always_inline)) RV_STATIC_INLINE void SetVTFIRQ(uint32_t addr, IRQn_Type IRQn, uint8_t num, FunctionalState NewState){
if(num > 3) return ;
if (NewState != DISABLE)
{
PFIC->VTFIDR[num] = IRQn;
PFIC->VTFADDR[num] = ((addr&0xFFFFFFFE)|0x1);
}
else{
PFIC->VTFIDR[num] = IRQn;
PFIC->VTFADDR[num] = ((addr&0xFFFFFFFE)&(~0x1));
}
}
/*********************************************************************
* @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 __WFI
*
* @brief Wait for Interrupt
*/
__attribute__((always_inline)) RV_STATIC_INLINE void __WFI(void)
{
PFIC->SCTLR &= ~(1 << 3); // wfi
__asm__ volatile("wfi");
}
/*********************************************************************
* @fn PFIC_SystemReset
*
* @brief Initiate a system reset request
*/
__attribute__((always_inline)) RV_STATIC_INLINE void PFIC_SystemReset(void)
{
PFIC->CFGR = PFIC_KEY3 | (1 << 7);
}
/*********************************************************************
* @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
* @details 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
* @details 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
* @details 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;
}
/**
* @brief Return the Machine Status Register
*
* @return mstatus value
*/
uint32_t __get_MSTATUS(void);
/**
* @brief Return the Machine ISA Register
*
* @return misa value
*/
uint32_t __get_MISA(void);
/***
* @brief Return the Machine Trap-Vector Base-Address Register
*
* @return mtvec value
*/
uint32_t __get_MTVEC(void);
/**
* @brief Return the Machine Seratch Register
*
* @return mscratch value
*/
uint32_t __get_MSCRATCH(void);
/**
* @brief Return the Machine Exception Program Register
*
* @return mepc value
*/
uint32_t __get_MEPC(void);
/**
* @brief Return the Machine Cause Register
*
* @return mcause value
*/
uint32_t __get_MCAUSE(void);
/**
* @brief Return the Machine Trap Value Register
*
* @return mtval value
*/
uint32_t __get_MTVAL(void);
/**
* @brief Return Vendor ID Register
*
* @return mvendorid value
*/
uint32_t __get_MVENDORID(void);
/**
* @brief Return Machine Architecture ID Register
*
* @return marchid value
*/
uint32_t __get_MARCHID(void);
/**
* @brief Return Machine Implementation ID Register
*
* @return mimpid value
*/
uint32_t __get_MIMPID(void);
/**
* @brief Return Hart ID Register
*
* @return mhartid value
*/
uint32_t __get_MHARTID(void);
/**
* @brief Return SP Register
*
* @return SP value
*/
uint32_t __get_SP(void);
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFFFFFFFFFFF)
#define SysTick_CTLR_SWIE (1 << 31)
#define SysTick_CTLR_INIT (1 << 5)
#define SysTick_CTLR_MODE (1 << 4)
#define SysTick_CTLR_STRE (1 << 3)
#define SysTick_CTLR_STCLK (1 << 2)
#define SysTick_CTLR_STIE (1 << 1)
#define SysTick_CTLR_STE (1 << 0)
#define SysTick_SR_CNTIF (1 << 0)
RV_STATIC_INLINE uint32_t SysTick_Config(uint64_t 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_CTLR_INIT |
SysTick_CTLR_STRE |
SysTick_CTLR_STCLK |
SysTick_CTLR_STIE |
SysTick_CTLR_STE; /* Enable SysTick IRQ and SysTick Timer */
return (0); /* Function successful */
}
#ifdef __cplusplus
}
#endif
#endif /* __CORE_RV3A_H__ */

185
sdk/Startup/startup_CH592.S Normal file
View File

@ -0,0 +1,185 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : startup_CH59x.s
* Author : WCH
* Version : V1.0.0
* Date : 2021/02/25
* 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.
*******************************************************************************/
.section .init,"ax",@progbits
.global _start
.align 1
_start:
j handle_reset
.section .vector,"ax",@progbits
.align 1
_vector_base:
.option norvc;
.word 0
.word 0
.word NMI_Handler /* NMI Handler */
.word HardFault_Handler /* Hard Fault Handler */
.word 0xF5F9BDA9
.word Ecall_M_Mode_Handler /* 5 */
.word 0
.word 0
.word Ecall_U_Mode_Handler /* 8 */
.word Break_Point_Handler /* 9 */
.word 0
.word 0
.word SysTick_Handler /* SysTick Handler */
.word 0
.word SW_Handler /* SW Handler */
.word 0
/* External Interrupts */
.word TMR0_IRQHandler /* 0: TMR0 */
.word GPIOA_IRQHandler /* GPIOA */
.word GPIOB_IRQHandler /* GPIOB */
.word SPI0_IRQHandler /* SPI0 */
.word BB_IRQHandler /* BLEB */
.word LLE_IRQHandler /* BLEL */
.word USB_IRQHandler /* USB */
.word 0
.word TMR1_IRQHandler /* TMR1 */
.word TMR2_IRQHandler /* TMR2 */
.word UART0_IRQHandler /* UART0 */
.word UART1_IRQHandler /* UART1 */
.word RTC_IRQHandler /* RTC */
.word ADC_IRQHandler /* ADC */
.word I2C_IRQHandler /* I2C */
.word PWMX_IRQHandler /* PWMX */
.word TMR3_IRQHandler /* TMR3 */
.word UART2_IRQHandler /* UART2 */
.word UART3_IRQHandler /* UART3 */
.word WDOG_BAT_IRQHandler /* WDOG_BAT */
.option rvc;
.section .vector_handler, "ax", @progbits
.weak NMI_Handler
.weak HardFault_Handler
.weak Ecall_M_Mode_Handler
.weak Ecall_U_Mode_Handler
.weak Break_Point_Handler
.weak SysTick_Handler
.weak SW_Handler
.weak TMR0_IRQHandler
.weak GPIOA_IRQHandler
.weak GPIOB_IRQHandler
.weak SPI0_IRQHandler
.weak BB_IRQHandler
.weak LLE_IRQHandler
.weak USB_IRQHandler
.weak TMR1_IRQHandler
.weak TMR2_IRQHandler
.weak UART0_IRQHandler
.weak UART1_IRQHandler
.weak RTC_IRQHandler
.weak ADC_IRQHandler
.weak I2C_IRQHandler
.weak PWMX_IRQHandler
.weak TMR3_IRQHandler
.weak UART2_IRQHandler
.weak UART3_IRQHandler
.weak WDOG_BAT_IRQHandler
NMI_Handler:
HardFault_Handler:
Ecall_M_Mode_Handler:
Ecall_U_Mode_Handler:
Break_Point_Handler:
SysTick_Handler:
SW_Handler:
TMR0_IRQHandler:
GPIOA_IRQHandler:
GPIOB_IRQHandler:
SPI0_IRQHandler:
BB_IRQHandler:
LLE_IRQHandler:
USB_IRQHandler:
TMR1_IRQHandler:
TMR2_IRQHandler:
UART0_IRQHandler:
UART1_IRQHandler:
RTC_IRQHandler:
ADC_IRQHandler:
I2C_IRQHandler:
PWMX_IRQHandler:
TMR3_IRQHandler:
UART2_IRQHandler:
UART3_IRQHandler:
WDOG_BAT_IRQHandler:
1:
j 1b
.section .handle_reset,"ax",@progbits
.weak handle_reset
.align 1
handle_reset:
.option push
.option norelax
la gp, __global_pointer$
.option pop
1:
la sp, _eusrstack
/* Load highcode code section from flash to RAM */
2:
la a0, _highcode_lma
la a1, _highcode_vma_start
la a2, _highcode_vma_end
bgeu a1, a2, 2f
1:
lw t0, (a0)
sw t0, (a1)
addi a0, a0, 4
addi a1, a1, 4
bltu a1, a2, 1b
/* Load data section from flash to RAM */
2:
la a0, _data_lma
la a1, _data_vma
la a2, _edata
bgeu a1, a2, 2f
1:
lw t0, (a0)
sw t0, (a1)
addi a0, a0, 4
addi a1, a1, 4
bltu a1, a2, 1b
2:
/* clear bss section */
la a0, _sbss
la a1, _ebss
bgeu a0, a1, 2f
1:
sw zero, (a0)
addi a0, a0, 4
bltu a0, a1, 1b
2:
/* 流水线控制位 & 动态预测控制位 */
li t0, 0x1f
csrw 0xbc0, t0
/* 打开嵌套中断、硬件压栈功能 */
li t0, 0x3
csrw 0x804, t0
li t0, 0x88
csrs mstatus, t0
la t0, _vector_base
/* 配置向量表模式为绝对地址模式 */
ori t0, t0, 3
csrw mtvec, t0
la t0, main
csrw mepc, t0
mret

View File

@ -0,0 +1,257 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_adc.c
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* 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 "CH59x_common.h"
/*********************************************************************
* @fn ADC_DataCalib_Rough
*
* @brief ,,ADC后调用此函数获取校准值
*
* @param none
*
* @return
*/
signed short ADC_DataCalib_Rough(void) // 采样数据粗调,获取偏差值
{
uint16_t i;
uint32_t sum = 0;
uint8_t ch = 0; // 备份通道
uint8_t cfg = 0; // 备份
ch = R8_ADC_CHANNEL;
cfg = R8_ADC_CFG;
R8_ADC_CFG |= RB_ADC_OFS_TEST; // 进入测试模式
R8_ADC_CFG &= ~RB_ADC_DIFF_EN; // 关闭差分
R8_ADC_CONVERT |= RB_ADC_START;
while(R8_ADC_CONVERT & RB_ADC_START);
for(i = 0; i < 16; i++)
{
R8_ADC_CONVERT |= RB_ADC_START;
while(R8_ADC_CONVERT & RB_ADC_START);
sum += (~R16_ADC_DATA) & RB_ADC_DATA;
}
sum = (sum + 8) >> 4;
R8_ADC_CFG = cfg; // 恢复配置值
R8_ADC_CHANNEL = ch;
return (2048 - sum);
}
/*********************************************************************
* @fn ADC_ExtSingleChSampInit
*
* @brief
*
* @param sp - refer to ADC_SampClkTypeDef
* @param ga - refer to ADC_SignalPGATypeDef
*
* @return none
*/
void ADC_ExtSingleChSampInit(ADC_SampClkTypeDef sp, ADC_SignalPGATypeDef ga)
{
R8_TKEY_CFG &= ~RB_TKEY_PWR_ON;
R8_ADC_CFG = RB_ADC_POWER_ON | RB_ADC_BUF_EN | (sp << 6) | ((ga&0xF) << 4);
if( ga & ADC_PGA_2_ )
{
R8_ADC_CONVERT |= RB_ADC_PGA_GAIN2;
}
else
{
R8_ADC_CONVERT &= ~RB_ADC_PGA_GAIN2;
}
}
/*********************************************************************
* @fn ADC_ExtDiffChSampInit
*
* @brief
*
* @param sp - refer to ADC_SampClkTypeDef
* @param ga - refer to ADC_SignalPGATypeDef
*
* @return none
*/
void ADC_ExtDiffChSampInit(ADC_SampClkTypeDef sp, ADC_SignalPGATypeDef ga)
{
R8_TKEY_CFG &= ~RB_TKEY_PWR_ON;
R8_ADC_CFG = RB_ADC_POWER_ON | RB_ADC_DIFF_EN | (sp << 6) | ((ga&0xF) << 4);
if( ga & ADC_PGA_2_ )
{
R8_ADC_CONVERT |= RB_ADC_PGA_GAIN2;
}
else
{
R8_ADC_CONVERT &= ~RB_ADC_PGA_GAIN2;
}
}
/*********************************************************************
* @fn ADC_InterTSSampInit
*
* @brief
*
* @param none
*
* @return none
*/
void ADC_InterTSSampInit(void)
{
R8_TKEY_CFG &= ~RB_TKEY_PWR_ON;
R8_TEM_SENSOR = RB_TEM_SEN_PWR_ON;
R8_ADC_CHANNEL = CH_INTE_VTEMP;
R8_ADC_CFG = RB_ADC_POWER_ON | RB_ADC_DIFF_EN | (3 << 4);
R8_ADC_CONVERT &= ~RB_ADC_PGA_GAIN2;
}
/*********************************************************************
* @fn ADC_InterBATSampInit
*
* @brief
*
* @param none
*
* @return none
*/
void ADC_InterBATSampInit(void)
{
R8_TKEY_CFG &= ~RB_TKEY_PWR_ON;
R8_ADC_CHANNEL = CH_INTE_VBAT;
R8_ADC_CFG = RB_ADC_POWER_ON | RB_ADC_BUF_EN | (0 << 4); // 使用-12dB模式
R8_ADC_CONVERT &= ~RB_ADC_PGA_GAIN2;
}
/*********************************************************************
* @fn TouchKey_ChSampInit
*
* @brief
*
* @param none
*
* @return none
*/
void TouchKey_ChSampInit(void)
{
R8_ADC_CFG = RB_ADC_POWER_ON | RB_ADC_BUF_EN | (ADC_PGA_0 << 4) | (SampleFreq_8 << 6);
R8_ADC_CONVERT &= ~RB_ADC_PGA_GAIN2;
R8_TKEY_CFG |= RB_TKEY_PWR_ON;
}
/*********************************************************************
* @fn ADC_ExcutSingleConver
*
* @brief ADC执行单次转换
*
* @param none
*
* @return ADC转换后的数据
*/
uint16_t ADC_ExcutSingleConver(void)
{
R8_ADC_CONVERT |= RB_ADC_START;
while(R8_ADC_CONVERT & RB_ADC_START);
return (R16_ADC_DATA & RB_ADC_DATA);
}
/*********************************************************************
* @fn TouchKey_ExcutSingleConver
*
* @brief TouchKey转换后数据
*
* @param charg - Touchkey充电时间,5bits有效, t=charg*Tadc
* @param disch - Touchkey放电时间,3bits有效, t=disch*Tadc
*
* @return TouchKey等效数据
*/
uint16_t TouchKey_ExcutSingleConver(uint8_t charg, uint8_t disch)
{
R8_TKEY_COUNT = (disch << 5) | (charg & 0x1f);
R8_TKEY_CONVERT = RB_TKEY_START;
while(R8_TKEY_CONVERT & RB_TKEY_START);
return (R16_ADC_DATA & RB_ADC_DATA);
}
/*********************************************************************
* @fn ADC_AutoConverCycle
*
* @brief ADC的周期
*
* @param cycle - (256-cycle)*16*Tsys
*
* @return none
*/
void ADC_AutoConverCycle(uint8_t cycle)
{
R8_ADC_AUTO_CYCLE = cycle;
}
/*********************************************************************
* @fn ADC_DMACfg
*
* @brief DMA功能
*
* @param s - DMA功能
* @param startAddr - DMA
* @param endAddr - DMA
* @param m - DMA模式
*
* @return none
*/
void ADC_DMACfg(uint8_t s, uint32_t startAddr, uint32_t endAddr, ADC_DMAModeTypeDef m)
{
if(s == DISABLE)
{
R8_ADC_CTRL_DMA &= ~(RB_ADC_DMA_ENABLE | RB_ADC_IE_DMA_END);
}
else
{
R16_ADC_DMA_BEG = startAddr&0xFFFF;
R16_ADC_DMA_END = endAddr&0xFFFF;
if(m)
{
R8_ADC_CTRL_DMA |= RB_ADC_DMA_LOOP | RB_ADC_IE_DMA_END | RB_ADC_DMA_ENABLE;
}
else
{
R8_ADC_CTRL_DMA &= ~RB_ADC_DMA_LOOP;
R8_ADC_CTRL_DMA |= RB_ADC_IE_DMA_END | RB_ADC_DMA_ENABLE;
}
}
}
/*********************************************************************
* @fn adc_to_temperature_celsius
*
* @brief Convert ADC value to temperature(Celsius)
*
* @param adc_val - adc value
*
* @return temperature (Celsius)
*/
int adc_to_temperature_celsius(uint16_t adc_val)
{
uint32_t C25 = 0;
int temp;
C25 = (*((PUINT32)ROM_CFG_TMP_25C));
/* current temperature = standard temperature + (adc deviation * adc linearity coefficient) */
temp = (((C25 >> 16) & 0xFFFF) ? ((C25 >> 16) & 0xFFFF) : 25) + \
(adc_val - ((int)(C25 & 0xFFFF))) * 100 / 283;
return (temp);
}

View File

@ -0,0 +1,578 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_clk.c
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* 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 "CH59x_common.h"
/*********************************************************************
* @fn LClk32K_Select
*
* @brief 32K
*
* @param hc - 32K使用内部还是外部
*
* @return none
*/
void LClk32K_Select(LClk32KTypeDef hc)
{
uint8_t cfg = R8_CK32K_CONFIG;
if(hc == Clk32K_LSI)
{
cfg &= ~RB_CLK_OSC32K_XT;
}
else
{
cfg |= RB_CLK_OSC32K_XT;
}
sys_safe_access_enable();
R8_CK32K_CONFIG = cfg;
sys_safe_access_disable();
}
/*********************************************************************
* @fn LClk32K_Cfg
*
* @brief 32K
*
* @param hc - 32K还是外部32K
* @param s -
*
* @return none
*/
void LClk32K_Cfg(LClk32KTypeDef hc, FunctionalState s)
{
uint8_t cfg = R8_CK32K_CONFIG;
if(hc == Clk32K_LSI)
{
if(s == DISABLE)
{
cfg &= ~RB_CLK_INT32K_PON;
}
else
{
cfg |= RB_CLK_INT32K_PON;
}
}
else
{
if(s == DISABLE)
{
cfg &= ~RB_CLK_XT32K_PON;
}
else
{
cfg |= RB_CLK_XT32K_PON;
}
}
sys_safe_access_enable();
R8_CK32K_CONFIG = cfg;
sys_safe_access_disable();
}
/*********************************************************************
* @fn HSECFG_Current
*
* @brief HSE晶体
*
* @param c - 75%,100%,125%,150%
*
* @return none
*/
void HSECFG_Current(HSECurrentTypeDef c)
{
uint8_t x32M_c;
x32M_c = R8_XT32M_TUNE;
x32M_c = (x32M_c & 0xfc) | (c & 0x03);
sys_safe_access_enable();
R8_XT32M_TUNE = x32M_c;
sys_safe_access_disable();
}
/*********************************************************************
* @fn HSECFG_Capacitance
*
* @brief HSE晶体
*
* @param c - refer to HSECapTypeDef
*
* @return none
*/
void HSECFG_Capacitance(HSECapTypeDef c)
{
uint8_t x32M_c;
x32M_c = R8_XT32M_TUNE;
x32M_c = (x32M_c & 0x8f) | (c << 4);
sys_safe_access_enable();
R8_XT32M_TUNE = x32M_c;
sys_safe_access_disable();
}
/*********************************************************************
* @fn LSECFG_Current
*
* @brief LSE晶体
*
* @param c - 70%,100%,140%,200%
*
* @return none
*/
void LSECFG_Current(LSECurrentTypeDef c)
{
uint8_t x32K_c;
x32K_c = R8_XT32K_TUNE;
x32K_c = (x32K_c & 0xfc) | (c & 0x03);
sys_safe_access_enable();
R8_XT32K_TUNE = x32K_c;
sys_safe_access_disable();
}
/*********************************************************************
* @fn LSECFG_Capacitance
*
* @brief LSE晶体
*
* @param c - refer to LSECapTypeDef
*
* @return none
*/
void LSECFG_Capacitance(LSECapTypeDef c)
{
uint8_t x32K_c;
x32K_c = R8_XT32K_TUNE;
x32K_c = (x32K_c & 0x0f) | (c << 4);
sys_safe_access_enable();
R8_XT32K_TUNE = x32K_c;
sys_safe_access_disable();
}
/*********************************************************************
* @fn Calibration_LSI
*
* @brief 32K时钟
*
* @param cali_Lv - Level_32 2.4ms 1000ppm (32M ) 1100ppm (60M )
* Level_64 4.4ms 800ppm (32M ) 1000ppm (60M )
* Level_128 8.4ms 600ppm (32M ) 800ppm (60M )
*
* @return none
*/
void Calibration_LSI(Cali_LevelTypeDef cali_Lv)
{
UINT32 i;
INT32 cnt_offset;
UINT8 retry = 0;
INT32 freq_sys;
UINT32 cnt_32k = 0;
freq_sys = GetSysClock();
sys_safe_access_enable();
R8_CK32K_CONFIG &= ~RB_CLK_OSC32K_FILT;
R8_CK32K_CONFIG |= RB_CLK_OSC32K_FILT;
sys_safe_access_disable();
sys_safe_access_enable();
R8_XT32K_TUNE &= ~3;
R8_XT32K_TUNE |= 1;
sys_safe_access_disable();
// 粗调
sys_safe_access_enable();
R8_OSC_CAL_CTRL &= ~RB_OSC_CNT_TOTAL;
R8_OSC_CAL_CTRL |= 1;
sys_safe_access_disable();
while(1)
{
sys_safe_access_enable();
R8_OSC_CAL_CTRL |= RB_OSC_CNT_EN;
R16_OSC_CAL_CNT |= RB_OSC_CAL_OV_CLR;
R16_OSC_CAL_CNT |= RB_OSC_CAL_IF;
sys_safe_access_disable();
while( (R8_OSC_CAL_CTRL & RB_OSC_CNT_EN) == 0 )
{
sys_safe_access_enable();
R8_OSC_CAL_CTRL |= RB_OSC_CNT_EN;
sys_safe_access_disable();
}
while(!(R8_OSC_CAL_CTRL & RB_OSC_CNT_HALT)); // 用于丢弃
sys_safe_access_enable();
R8_OSC_CAL_CTRL &= ~RB_OSC_CNT_EN;
R8_OSC_CAL_CTRL |= RB_OSC_CNT_EN;
R16_OSC_CAL_CNT |= RB_OSC_CAL_OV_CLR;
R16_OSC_CAL_CNT |= RB_OSC_CAL_IF;
sys_safe_access_disable();
while( (R8_OSC_CAL_CTRL & RB_OSC_CNT_EN) == 0 )
{
sys_safe_access_enable();
R8_OSC_CAL_CTRL |= RB_OSC_CNT_EN;
sys_safe_access_disable();
}
while(R8_OSC_CAL_CTRL & RB_OSC_CNT_HALT);
cnt_32k = RTC_GetCycle32k();
while(RTC_GetCycle32k() == cnt_32k);
R16_OSC_CAL_CNT |= RB_OSC_CAL_OV_CLR;
while(!(R8_OSC_CAL_CTRL & RB_OSC_CNT_HALT));
i = R16_OSC_CAL_CNT; // 实时校准后采样值
cnt_offset = (i & 0x3FFF) + R8_OSC_CAL_OV_CNT * 0x3FFF - 2000 * (freq_sys / 1000) / CAB_LSIFQ;
if(((cnt_offset > -37 * (freq_sys / 1000) / CAB_LSIFQ) && (cnt_offset < 37 * (freq_sys / 1000) / CAB_LSIFQ)) || retry > 2)
{
if(retry)
break;
}
retry++;
cnt_offset = (cnt_offset > 0) ? (((cnt_offset * 2) / (74 * (freq_sys/1000) / 60000)) + 1) / 2 : (((cnt_offset * 2) / (74 * (freq_sys/1000) / 60000 )) - 1) / 2;
sys_safe_access_enable();
R16_INT32K_TUNE += cnt_offset;
sys_safe_access_disable();
}
// 细调
// 配置细调参数后丢弃2次捕获值软件行为上判断已有一次这里只留一次
sys_safe_access_enable();
R8_OSC_CAL_CTRL &= ~RB_OSC_CNT_TOTAL;
R8_OSC_CAL_CTRL |= cali_Lv;
sys_safe_access_disable();
while( (R8_OSC_CAL_CTRL & RB_OSC_CNT_TOTAL) != cali_Lv )
{
sys_safe_access_enable();
R8_OSC_CAL_CTRL |= cali_Lv;
sys_safe_access_disable();
}
sys_safe_access_enable();
R8_OSC_CAL_CTRL &= ~RB_OSC_CNT_EN;
R8_OSC_CAL_CTRL |= RB_OSC_CNT_EN;
R16_OSC_CAL_CNT |= RB_OSC_CAL_OV_CLR;
R16_OSC_CAL_CNT |= RB_OSC_CAL_IF;
sys_safe_access_disable();
while( (R8_OSC_CAL_CTRL & RB_OSC_CNT_EN) == 0 )
{
sys_safe_access_enable();
R8_OSC_CAL_CTRL |= RB_OSC_CNT_EN;
sys_safe_access_disable();
}
while(!(R8_OSC_CAL_CTRL & RB_OSC_CNT_HALT)); // 用于丢弃
sys_safe_access_enable();
R8_OSC_CAL_CTRL &= ~RB_OSC_CNT_EN;
R8_OSC_CAL_CTRL |= RB_OSC_CNT_EN;
R16_OSC_CAL_CNT |= RB_OSC_CAL_OV_CLR;
R16_OSC_CAL_CNT |= RB_OSC_CAL_IF;
sys_safe_access_disable();
while( (R8_OSC_CAL_CTRL & RB_OSC_CNT_EN) == 0 )
{
sys_safe_access_enable();
R8_OSC_CAL_CTRL |= RB_OSC_CNT_EN;
sys_safe_access_disable();
}
while(R8_OSC_CAL_CTRL & RB_OSC_CNT_HALT);
cnt_32k = RTC_GetCycle32k();
while(RTC_GetCycle32k() == cnt_32k);
R16_OSC_CAL_CNT |= RB_OSC_CAL_OV_CLR;
while(!(R8_OSC_CAL_CTRL & RB_OSC_CNT_HALT));
sys_safe_access_enable();
R8_OSC_CAL_CTRL &= ~RB_OSC_CNT_EN;
sys_safe_access_disable();
i = R16_OSC_CAL_CNT; // 实时校准后采样值
cnt_offset = (i & 0x3FFF) + R8_OSC_CAL_OV_CNT * 0x3FFF - 4000 * (1 << cali_Lv) * (freq_sys / 1000000) / 256 * 1000/(CAB_LSIFQ/256);
cnt_offset = (cnt_offset > 0) ? ((((cnt_offset * 2*(100 )) / (1366 * ((1 << cali_Lv)/8) * (freq_sys/1000) / 60000)) + 1) / 2)<<5 : ((((cnt_offset * 2*(100)) / (1366 * ((1 << cali_Lv)/8) * (freq_sys/1000) / 60000)) - 1) / 2)<<5;
sys_safe_access_enable();
R16_INT32K_TUNE += cnt_offset;
sys_safe_access_disable();
}
/*********************************************************************
* @fn RTCInitTime
*
* @brief RTC时钟初始化当前时间
*
* @param y - MAX_Y = BEGYEAR + 44
* @param mon - MAX_MON = 12
* @param d - MAX_D = 31
* @param h - MAX_H = 23
* @param m - MAX_M = 59
* @param s - MAX_S = 59
*
* @return none
*/
void RTC_InitTime(uint16_t y, uint16_t mon, uint16_t d, uint16_t h, uint16_t m, uint16_t s)
{
uint32_t t;
uint16_t year, month, day, sec2, t32k;
volatile uint8_t clk_pin;
year = y;
month = mon;
day = 0;
while(year > BEGYEAR)
{
day += YearLength(year - 1);
year--;
}
while(month > 1)
{
day += monthLength(IsLeapYear(y), month - 2);
month--;
}
day += d - 1;
sec2 = (h % 24) * 1800 + m * 30 + s / 2;
t32k = (s & 1) ? (0x8000) : (0);
t = sec2;
t = t << 16 | t32k;
do
{
clk_pin = (R8_CK32K_CONFIG & RB_32K_CLK_PIN);
} while(clk_pin != (R8_CK32K_CONFIG & RB_32K_CLK_PIN));
if(!clk_pin)
{
while(!clk_pin)
{
do
{
clk_pin = (R8_CK32K_CONFIG & RB_32K_CLK_PIN);
} while(clk_pin != (R8_CK32K_CONFIG & RB_32K_CLK_PIN));
}
}
sys_safe_access_enable();
R32_RTC_TRIG = day;
R8_RTC_MODE_CTRL |= RB_RTC_LOAD_HI;
sys_safe_access_disable();
while((R32_RTC_TRIG & 0x3FFF) != (R32_RTC_CNT_DAY & 0x3FFF));
sys_safe_access_enable();
R32_RTC_TRIG = t;
R8_RTC_MODE_CTRL |= RB_RTC_LOAD_LO;
sys_safe_access_disable();
}
/*********************************************************************
* @fn RTC_GetTime
*
* @brief
*
* @param py - MAX_Y = BEGYEAR + 44
* @param pmon - MAX_MON = 12
* @param pd - MAX_D = 31
* @param ph - MAX_H = 23
* @param pm - MAX_M = 59
* @param ps - MAX_S = 59
*
* @return none
*/
void RTC_GetTime(uint16_t *py, uint16_t *pmon, uint16_t *pd, uint16_t *ph, uint16_t *pm, uint16_t *ps)
{
uint32_t t;
uint16_t day, sec2, t32k;
day = R32_RTC_CNT_DAY & 0x3FFF;
sec2 = R16_RTC_CNT_2S;
t32k = R16_RTC_CNT_32K;
t = sec2 * 2 + ((t32k < 0x8000) ? 0 : 1);
*py = BEGYEAR;
while(day >= YearLength(*py))
{
day -= YearLength(*py);
(*py)++;
}
*pmon = 0;
while(day >= monthLength(IsLeapYear(*py), *pmon))
{
day -= monthLength(IsLeapYear(*py), *pmon);
(*pmon)++;
}
(*pmon)++;
*pd = day + 1;
*ph = t / 3600;
*pm = t % 3600 / 60;
*ps = t % 60;
}
/*********************************************************************
* @fn RTC_SetCycle32k
*
* @brief LSE/LSI时钟RTC
*
* @param cyc - MAX_CYC = 0xA8BFFFFF = 2831155199
*
* @return none
*/
void RTC_SetCycle32k(uint32_t cyc)
{
volatile uint8_t clk_pin;
do
{
clk_pin = (R8_CK32K_CONFIG & RB_32K_CLK_PIN);
} while((clk_pin != (R8_CK32K_CONFIG & RB_32K_CLK_PIN)) || (!clk_pin));
sys_safe_access_enable();
R32_RTC_TRIG = cyc;
R8_RTC_MODE_CTRL |= RB_RTC_LOAD_LO;
sys_safe_access_disable();
}
/*********************************************************************
* @fn RTC_GetCycle32k
*
* @brief LSE/LSI时钟RTC
*
* @param none
*
* @return MAX_CYC = 0xA8BFFFFF = 2831155199
*/
uint32_t RTC_GetCycle32k(void)
{
volatile uint32_t i;
do
{
i = R32_RTC_CNT_32K;
} while(i != R32_RTC_CNT_32K);
return (i);
}
/*********************************************************************
* @fn RTC_TMRFunCfg
*
* @brief RTC定时模式配置32768Hz
*
* @param t - refer to RTC_TMRCycTypeDef
*
* @return none
*/
void RTC_TMRFunCfg(RTC_TMRCycTypeDef t)
{
sys_safe_access_enable();
R8_RTC_MODE_CTRL &= ~(RB_RTC_TMR_EN | RB_RTC_TMR_MODE);
sys_safe_access_disable();
sys_safe_access_enable();
R8_RTC_MODE_CTRL |= RB_RTC_TMR_EN | (t);
sys_safe_access_disable();
}
/*********************************************************************
* @fn RTC_TRIGFunCfg
*
* @brief RTC时间触发模式配置
*
* @param cyc - LSE/LSI时钟周期数
*
* @return none
*/
void RTC_TRIGFunCfg(uint32_t cyc)
{
uint32_t t;
t = RTC_GetCycle32k() + cyc;
if(t > RTC_MAX_COUNT)
{
t -= RTC_MAX_COUNT;
}
sys_safe_access_enable();
R32_RTC_TRIG = t;
R8_RTC_MODE_CTRL |= RB_RTC_TRIG_EN;
sys_safe_access_disable();
}
/*********************************************************************
* @fn RTC_ModeFunDisable
*
* @brief RTC
*
* @param m -
*
* @return none
*/
void RTC_ModeFunDisable(RTC_MODETypeDef m)
{
uint8_t i = 0;
if(m == RTC_TRIG_MODE)
{
i |= RB_RTC_TRIG_EN;
}
else if(m == RTC_TMR_MODE)
{
i |= RB_RTC_TMR_EN;
}
sys_safe_access_enable();
R8_RTC_MODE_CTRL &= ~(i);
sys_safe_access_disable();
}
/*********************************************************************
* @fn RTC_GetITFlag
*
* @brief RTC中断标志
*
* @param f - refer to RTC_EVENTTypeDef
*
* @return
*/
uint8_t RTC_GetITFlag(RTC_EVENTTypeDef f)
{
if(f == RTC_TRIG_EVENT)
{
return (R8_RTC_FLAG_CTRL & RB_RTC_TRIG_FLAG);
}
else
{
return (R8_RTC_FLAG_CTRL & RB_RTC_TMR_FLAG);
}
}
/*********************************************************************
* @fn RTC_ClearITFlag
*
* @brief RTC中断标志
*
* @param f - refer to RTC_EVENTTypeDef
*
* @return none
*/
void RTC_ClearITFlag(RTC_EVENTTypeDef f)
{
switch(f)
{
case RTC_TRIG_EVENT:
R8_RTC_FLAG_CTRL = RB_RTC_TRIG_CLR;
break;
case RTC_TMR_EVENT:
R8_RTC_FLAG_CTRL = RB_RTC_TMR_CLR;
break;
default:
break;
}
}

View File

@ -0,0 +1,167 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_flash.c
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* 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 "CH59x_common.h"
/* RESET_EN */
#define RESET_Enable 0x00000008
#define RESET_Disable 0xFFFFFFF7
/* LOCKUP_RST_EN */
#define UART_NO_KEY_Enable 0x00000100
#define UART_NO_KEY_Disable 0xFFFFFEFF
/* BOOT_PIN */
#define BOOT_PIN_PB22 0x00000200
#define BOOT_PIN_PB11 0xFFFFFDFF
/* FLASH_WRProt */
#define FLASH_WRProt 0xFFF003FF
/*********************************************************************
* @fn FLASH_ROM_READ
*
* @brief Read Flash
*
* @param StartAddr - read address
* @param Buffer - read buffer
* @param len - read len
*
* @return none
*/
void FLASH_ROM_READ(uint32_t StartAddr, void *Buffer, uint32_t len)
{
uint32_t i, Length = (len + 3) >> 2;
uint32_t *pCode = (uint32_t *)StartAddr;
uint32_t *pBuf = (uint32_t *)Buffer;
for(i = 0; i < Length; i++)
{
*pBuf++ = *pCode++;
}
}
/*********************************************************************
* @fn UserOptionByteConfig
*
* @brief Configure User Option Byte.,
* (使使.S文件线)
*
* @param RESET_EN - 使
* @param BOOT_PIN - ENABLE-使boot脚-PB22,DISABLE-使boot脚-PB11
* @param UART_NO_KEY_EN - 使
* @param FLASHProt_Size - (4K)
*
* @return 0-Success, 1-Err
*/
uint8_t UserOptionByteConfig(FunctionalState RESET_EN, FunctionalState BOOT_PIN, FunctionalState UART_NO_KEY_EN,
uint32_t FLASHProt_Size)
{
uint32_t s, t;
FLASH_ROM_READ(0x14, &s, 4);
if(s == 0xF5F9BDA9)
{
s = 0;
FLASH_EEPROM_CMD(CMD_GET_ROM_INFO, 0x7EFFC, &s, 4);
s &= 0xFF;
if(RESET_EN == ENABLE)
s |= RESET_Enable;
else
s &= RESET_Disable;
/* bit[7:0]-bit[31-24] */
s |= ((~(s << 24)) & 0xFF000000); //高8位 配置信息取反;
if(BOOT_PIN == ENABLE)
s |= BOOT_PIN_PB22;
if(UART_NO_KEY_EN == ENABLE)
s |= UART_NO_KEY_Enable;
/* bit[23-10] */
s &= 0xFF0003FF;
s |= ((FLASHProt_Size << 10) | (5 << 20)) & 0x00FFFC00;
/*Write user option byte*/
FLASH_ROM_WRITE(0x14, &s, 4);
/* Verify user option byte */
FLASH_ROM_READ(0x14, &t, 4);
if(s == t)
return 0;
else
return 1;
}
return 1;
}
/*********************************************************************
* @fn UserOptionByteClose_SWD
*
* @brief 线.,
* (使使.S文件线)
*
* @return 0-Success, 1-Err
*/
uint8_t UserOptionByteClose_SWD(void)
{
uint32_t s, t;
FLASH_ROM_READ(0x14, &s, 4);
if(s == 0xF5F9BDA9)
{
FLASH_EEPROM_CMD(CMD_GET_ROM_INFO, 0x7EFFC, &s, 4);
s &= ~((1 << 4) | (1 << 7)); //禁用调试功能, 禁用SPI读写FLASH
/* bit[7:0]-bit[31-24] */
s &= 0x00FFFFFF;
s |= ((~(s << 24)) & 0xFF000000); //高8位 配置信息取反;
/*Write user option byte*/
FLASH_ROM_WRITE(0x14, &s, 4);
/* Verify user option byte */
FLASH_ROM_READ(0x14, &t, 4);
if(s == t)
return 0;
else
return 1;
}
return 1;
}
/*********************************************************************
* @fn UserOptionByte_Active
*
* @brief
*
* @return 0-Success, 1-Err
*/
void UserOptionByte_Active(void)
{
FLASH_ROM_SW_RESET();
sys_safe_access_enable();
R16_INT32K_TUNE = 0xFFFF;
sys_safe_access_disable();
sys_safe_access_enable();
R8_RST_WDOG_CTRL |= RB_SOFTWARE_RESET;
sys_safe_access_disable();
while(1);
}

View File

@ -0,0 +1,263 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_gpio.c
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* 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 "CH59x_common.h"
/*********************************************************************
* @fn GPIOA_ModeCfg
*
* @brief GPIOA端口引脚模式配置
*
* @param pin - PA0-PA15
* @param mode -
*
* @return none
*/
void GPIOA_ModeCfg(uint32_t pin, GPIOModeTypeDef mode)
{
switch(mode)
{
case GPIO_ModeIN_Floating:
R32_PA_PD_DRV &= ~pin;
R32_PA_PU &= ~pin;
R32_PA_DIR &= ~pin;
break;
case GPIO_ModeIN_PU:
R32_PA_PD_DRV &= ~pin;
R32_PA_PU |= pin;
R32_PA_DIR &= ~pin;
break;
case GPIO_ModeIN_PD:
R32_PA_PD_DRV |= pin;
R32_PA_PU &= ~pin;
R32_PA_DIR &= ~pin;
break;
case GPIO_ModeOut_PP_5mA:
R32_PA_PD_DRV &= ~pin;
R32_PA_DIR |= pin;
break;
case GPIO_ModeOut_PP_20mA:
R32_PA_PD_DRV |= pin;
R32_PA_DIR |= pin;
break;
default:
break;
}
}
/*********************************************************************
* @fn GPIOB_ModeCfg
*
* @brief GPIOB端口引脚模式配置
*
* @param pin - PB0-PB23
* @param mode -
*
* @return none
*/
void GPIOB_ModeCfg(uint32_t pin, GPIOModeTypeDef mode)
{
switch(mode)
{
case GPIO_ModeIN_Floating:
R32_PB_PD_DRV &= ~pin;
R32_PB_PU &= ~pin;
R32_PB_DIR &= ~pin;
break;
case GPIO_ModeIN_PU:
R32_PB_PD_DRV &= ~pin;
R32_PB_PU |= pin;
R32_PB_DIR &= ~pin;
break;
case GPIO_ModeIN_PD:
R32_PB_PD_DRV |= pin;
R32_PB_PU &= ~pin;
R32_PB_DIR &= ~pin;
break;
case GPIO_ModeOut_PP_5mA:
R32_PB_PD_DRV &= ~pin;
R32_PB_DIR |= pin;
break;
case GPIO_ModeOut_PP_20mA:
R32_PB_PD_DRV |= pin;
R32_PB_DIR |= pin;
break;
default:
break;
}
}
/*********************************************************************
* @fn GPIOA_ITModeCfg
*
* @brief GPIOA引脚中断模式配置
*
* @param pin - PA0-PA15
* @param mode -
*
* @return none
*/
void GPIOA_ITModeCfg(uint32_t pin, GPIOITModeTpDef mode)
{
switch(mode)
{
case GPIO_ITMode_LowLevel: // 低电平触发
R16_PA_INT_MODE &= ~pin;
R32_PA_CLR |= pin;
break;
case GPIO_ITMode_HighLevel: // 高电平触发
R16_PA_INT_MODE &= ~pin;
R32_PA_OUT |= pin;
break;
case GPIO_ITMode_FallEdge: // 下降沿触发
R16_PA_INT_MODE |= pin;
R32_PA_CLR |= pin;
break;
case GPIO_ITMode_RiseEdge: // 上升沿触发
R16_PA_INT_MODE |= pin;
R32_PA_OUT |= pin;
break;
default:
break;
}
R16_PA_INT_IF = pin;
R16_PA_INT_EN |= pin;
}
/*********************************************************************
* @fn GPIOB_ITModeCfg
*
* @brief GPIOB引脚中断模式配置
*
* @param pin - PB0-PB23
* @param mode -
*
* @return none
*/
void GPIOB_ITModeCfg(uint32_t pin, GPIOITModeTpDef mode)
{
uint32_t Pin = pin | ((pin & (GPIO_Pin_22 | GPIO_Pin_23)) >> 14);
switch(mode)
{
case GPIO_ITMode_LowLevel: // 低电平触发
R16_PB_INT_MODE &= ~Pin;
R32_PB_CLR |= pin;
break;
case GPIO_ITMode_HighLevel: // 高电平触发
R16_PB_INT_MODE &= ~Pin;
R32_PB_OUT |= pin;
break;
case GPIO_ITMode_FallEdge: // 下降沿触发
R16_PB_INT_MODE |= Pin;
R32_PB_CLR |= pin;
break;
case GPIO_ITMode_RiseEdge: // 上升沿触发
R16_PB_INT_MODE |= Pin;
R32_PB_OUT |= pin;
break;
default:
break;
}
R16_PB_INT_IF = Pin;
R16_PB_INT_EN |= Pin;
}
/*********************************************************************
* @fn GPIOPinRemap
*
* @brief
*
* @param s - 使
* @param perph - RB_RF_ANT_SW_EN - RF antenna switch control output on PA4/PA5/PA12/PA13/PA14/PA15
* RB_PIN_U0_INV - RXD0/RXD0_/TXD0/TXD0_ invert input/output
* RB_PIN_INTX - INTX: INT24/INT25 PB8/PB9 -> INT24_/INT25_ PB22/PB23
* RB_PIN_MODEM - MODEM: PA6/PA7 -> PB12/PB13
* RB_PIN_I2C - I2C: PB14/PB15 -> PB14/PB15
* RB_PIN_PWMX - PWMX: PA12/PA13 -> PA6/PA7
* RB_PIN_SPI0 - SPI0: PA12/PA13/PA14/PA15 -> PB12/PB13/PB14/PB15
* RB_PIN_UART3 - UART3: PA4/PA5 -> PA4/PA5
* RB_PIN_UART2 - UART2: PB22/PB23 -> PA6/PA7
* RB_PIN_UART1 - UART1: PA8/PA9 -> PB12/PB13
* RB_PIN_UART0 - UART0: PB4/PB7 -> PA15/PA14
* RB_PIN_TMR3 - TMR2: PB22 -> PB22
* RB_PIN_TMR2 - TMR2: PA11 -> PB11
* RB_PIN_TMR1 - TMR1: PA10 -> PB10
* RB_PIN_TMR0 - TMR0: PA9 -> PB23
*
* @return none
*/
void GPIOPinRemap(FunctionalState s, uint16_t perph)
{
if(s)
{
R16_PIN_ALTERNATE |= perph;
}
else
{
R16_PIN_ALTERNATE &= ~perph;
}
}
/*********************************************************************
* @fn GPIOAGPPCfg
*
* @brief GPIO引脚功能控制
*
* @param s - ENABLE -
* DISABLE -
* @param perph - RB_PIN_ADC8_9_IE - ADC/TKEY 9/8
* RB_PIN_ADC6_7_IE - ADC/TKEY 7/6
* RB_PIN_ADC10_IE - ADC/TKEY 10
* RB_PIN_ADC11_IE - ADC/TKEY 11
* RB_PIN_USB2_DP_PU - USB2 U2D+
* RB_PIN_USB2_IE - USB2引脚
* RB_PIN_USB_DP_PU - USB UD+
* RB_PIN_USB_IE - USB
* RB_PIN_ADC0_IE - ADC/TKEY 0
* RB_PIN_ADC1_IE - ADC/TKEY 1
* RB_PIN_ADC12_IE - ADC/TKEY 12
* RB_PIN_ADC13_IE - ADC/TKEY 13
* RB_PIN_XT32K_IE - 32KHz晶振LSE引脚
* RB_PIN_ADC2_3_IE - ADC/TKEY 2/3
* RB_PIN_ADC4_5_IE - ADC/TKEY 4/5
*
* @return none
*/
void GPIOAGPPCfg(FunctionalState s, uint16_t perph)
{
if(s)
{
R16_PIN_ANALOG_IE |= perph;
}
else
{
R16_PIN_ANALOG_IE &= ~perph;
}
}

View File

@ -0,0 +1,672 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_i2c.c
* Author : WCH
* Version : V1.0
* Date : 2021/03/15
* 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 "CH59x_common.h"
/*********************************************************************
* @fn I2C_Init
*
* @brief Initializes the I2Cx peripheral according to the specified
* parameters in the I2C_InitStruct.
*
* @param I2C_Mode - refer to I2C_ModeTypeDef
* @param I2C_ClockSpeed - Specifies the clock frequency(Hz).
* This parameter must be set to a value lower than 400kHz
* @param I2C_DutyCycle - Specifies the I2C fast mode duty cycle.refer to I2C_DutyTypeDef
* @param I2C_Ack - Enables or disables the acknowledgement.refer to I2C_AckTypeDef
* @param I2C_AckAddr - Specifies if 7-bit or 10-bit address is acknowledged.refer to I2C_AckAddrTypeDef
* @param I2C_OwnAddress1 - Specifies the first device own address.
* This parameter can be a 7-bit or 10-bit address.
*
* @return none
*/
void I2C_Init(I2C_ModeTypeDef I2C_Mode, UINT32 I2C_ClockSpeed, I2C_DutyTypeDef I2C_DutyCycle,
I2C_AckTypeDef I2C_Ack, I2C_AckAddrTypeDef I2C_AckAddr, UINT16 I2C_OwnAddress1)
{
uint32_t sysClock;
uint16_t tmpreg;
I2C_SoftwareResetCmd(ENABLE);
I2C_SoftwareResetCmd(DISABLE);
sysClock = GetSysClock();
R16_I2C_CTRL2 &= ~RB_I2C_FREQ;
R16_I2C_CTRL2 |= (sysClock / 1000000);
R16_I2C_CTRL1 &= ~RB_I2C_PE;
if(I2C_ClockSpeed <= 100000)
{
tmpreg = (sysClock / (I2C_ClockSpeed << 1)) & RB_I2C_CCR;
if(tmpreg < 0x04)
tmpreg = 0x04;
R16_I2C_RTR = (((sysClock / 1000000) + 1) > 0x3F) ? 0x3F : ((sysClock / 1000000) + 1);
}
else
{
if(I2C_DutyCycle == I2C_DutyCycle_2)
{
tmpreg = (sysClock / (I2C_ClockSpeed * 3)) & RB_I2C_CCR;
}
else
{
tmpreg = (sysClock / (I2C_ClockSpeed * 25)) & RB_I2C_CCR;
tmpreg |= I2C_DutyCycle_16_9;
}
if(tmpreg == 0)
{
tmpreg |= (uint16_t)0x0001;
}
tmpreg |= RB_I2C_F_S;
R16_I2C_RTR = (uint16_t)((((sysClock / 1000000) * (uint16_t)300) / (uint16_t)1000) + (uint16_t)1);
}
R16_I2C_CKCFGR = tmpreg;
R16_I2C_CTRL1 |= RB_I2C_PE;
R16_I2C_CTRL1 &= ~(RB_I2C_SMBUS | RB_I2C_SMBTYPE | RB_I2C_ACK);
R16_I2C_CTRL1 |= I2C_Mode | I2C_Ack;
R16_I2C_OADDR1 &= ~0xFFFF;
R16_I2C_OADDR1 |= I2C_AckAddr | I2C_OwnAddress1;
}
/*********************************************************************
* @fn I2C_Cmd
*
* @brief Enables or disables the specified I2C peripheral.
*
* @param NewState - ENABLE or DISABLE.
*
* @return none
*/
void I2C_Cmd(FunctionalState NewState)
{
if(NewState != DISABLE)
R16_I2C_CTRL1 |= RB_I2C_PE;
else
R16_I2C_CTRL1 &= ~RB_I2C_PE;
}
/*********************************************************************
* @fn I2C_GenerateSTART
*
* @brief Generates I2Cx communication START condition.
*
* @param NewState - ENABLE or DISABLE.
*
* @return none
*/
void I2C_GenerateSTART(FunctionalState NewState)
{
if(NewState != DISABLE)
R16_I2C_CTRL1 |= RB_I2C_START;
else
R16_I2C_CTRL1 &= ~RB_I2C_START;
}
/*********************************************************************
* @fn I2C_GenerateSTOP
*
* @brief Generates I2Cx communication STOP condition.
*
* @param NewState - ENABLE or DISABLE.
*
* @return none
*/
void I2C_GenerateSTOP(FunctionalState NewState)
{
if(NewState != DISABLE)
R16_I2C_CTRL1 |= RB_I2C_STOP;
else
R16_I2C_CTRL1 &= ~RB_I2C_STOP;
}
/*********************************************************************
* @fn I2C_AcknowledgeConfig
*
* @brief Enables or disables the specified I2C acknowledge feature.
*
* @param NewState - ENABLE or DISABLE.
*
* @return none
*/
void I2C_AcknowledgeConfig(FunctionalState NewState)
{
if(NewState != DISABLE)
R16_I2C_CTRL1 |= RB_I2C_ACK;
else
R16_I2C_CTRL1 &= ~RB_I2C_ACK;
}
/*********************************************************************
* @fn I2C_OwnAddress2Config
*
* @brief Configures the specified I2C own address2.
*
* @param Address - specifies the 7bit I2C own address2.
*
* @return none
*/
void I2C_OwnAddress2Config(uint8_t Address)
{
R16_I2C_OADDR2 &= ~RB_I2C_ADD2;
R16_I2C_OADDR2 |= (uint16_t)(Address & RB_I2C_ADD2);
}
/*********************************************************************
* @fn I2C_DualAddressCmd
*
* @brief Enables or disables the specified I2C dual addressing mode.
*
* @param NewState - ENABLE or DISABLE.
*
* @return none
*/
void I2C_DualAddressCmd(FunctionalState NewState)
{
if(NewState != DISABLE)
R16_I2C_OADDR2 |= RB_I2C_ENDUAL;
else
R16_I2C_OADDR2 &= ~RB_I2C_ENDUAL;
}
/*********************************************************************
* @fn I2C_GeneralCallCmd
*
* @brief Enables or disables the specified I2C general call feature.
*
* @param NewState - ENABLE or DISABLE.
*
* @return none
*/
void I2C_GeneralCallCmd(FunctionalState NewState)
{
if(NewState != DISABLE)
R16_I2C_CTRL1 |= RB_I2C_ENGC;
else
R16_I2C_CTRL1 &= ~RB_I2C_ENGC;
}
/*********************************************************************
* @fn I2C_ITConfig
*
* @brief Enables or disables the specified I2C interrupts.
*
* @param I2C_IT - specifies the I2C interrupts sources to be enabled or disabled.
* I2C_IT_BUF - Buffer interrupt mask.
* I2C_IT_EVT - Event interrupt mask.
* I2C_IT_ERR - Error interrupt mask.
* @param NewState - ENABLE or DISABLE.
*
* @return none
*/
void I2C_ITConfig(I2C_ITTypeDef I2C_IT, FunctionalState NewState)
{
if(NewState != DISABLE)
R16_I2C_CTRL2 |= I2C_IT;
else
R16_I2C_CTRL2 &= (uint16_t)~I2C_IT;
}
/*********************************************************************
* @fn I2C_SendData
*
* @brief Sends a data byte through the I2Cx peripheral.
*
* @param Data - Byte to be transmitted.
*
* @return none
*/
void I2C_SendData(uint8_t Data)
{
R16_I2C_DATAR = Data;
}
/*********************************************************************
* @fn I2C_ReceiveData
*
* @brief Returns the most recent received data by the I2Cx peripheral.
*
* @return The value of the received data.
*/
uint8_t I2C_ReceiveData(void)
{
return (uint8_t)R16_I2C_DATAR;
}
/*********************************************************************
* @fn I2C_Send7bitAddress
*
* @brief Transmits the address byte to select the slave device.
*
* @param Address - specifies the slave address which will be transmitted.
* @param I2C_Direction - specifies whether the I2C device will be a Transmitter or a Receiver.
* I2C_Direction_Transmitter - Transmitter mode.
* I2C_Direction_Receiver - Receiver mode.
*
* @return none
*/
void I2C_Send7bitAddress(uint8_t Address, uint8_t I2C_Direction)
{
if(I2C_Direction != I2C_Direction_Transmitter)
Address |= OADDR1_ADD0_Set;
else
Address &= OADDR1_ADD0_Reset;
R16_I2C_DATAR = Address;
}
/*********************************************************************
* @fn I2C_SoftwareResetCmd
*
* @brief Enables or disables the specified I2C software reset.
*
* @param NewState - ENABLE or DISABLE.
*
* @return none
*/
void I2C_SoftwareResetCmd(FunctionalState NewState)
{
if(NewState != DISABLE)
R16_I2C_CTRL1 |= RB_I2C_SWRST;
else
R16_I2C_CTRL1 &= ~RB_I2C_SWRST;
}
/*********************************************************************
* @fn I2C_NACKPositionConfig
*
* @brief Selects the specified I2C NACK position in master receiver mode.
*
* @param I2C_NACKPosition - specifies the NACK position.
* I2C_NACKPosition_Next - indicates that the next byte will be the last received byte.
* I2C_NACKPosition_Current - indicates that current byte is the last received byte.
*
* @return none
*/
void I2C_NACKPositionConfig(uint16_t I2C_NACKPosition)
{
if(I2C_NACKPosition == I2C_NACKPosition_Next)
R16_I2C_CTRL1 |= I2C_NACKPosition_Next;
else
R16_I2C_CTRL1 &= I2C_NACKPosition_Current;
}
/*********************************************************************
* @fn I2C_SMBusAlertConfig
*
* @brief Drives the SMBusAlert pin high or low for the specified I2C.
*
* @param I2C_SMBusAlert - specifies SMBAlert pin level.
* I2C_SMBusAlert_Low - SMBAlert pin driven low.
* I2C_SMBusAlert_High - SMBAlert pin driven high.
*
* @return none
*/
void I2C_SMBusAlertConfig(uint16_t I2C_SMBusAlert)
{
if(I2C_SMBusAlert == I2C_SMBusAlert_Low)
R16_I2C_CTRL1 |= I2C_SMBusAlert_Low;
else
R16_I2C_CTRL1 &= I2C_SMBusAlert_High;
}
/*********************************************************************
* @fn I2C_TransmitPEC
*
* @brief Enables or disables the specified I2C PEC transfer.
*
* @param NewState - ENABLE or DISABLE.
*
* @return none
*/
void I2C_TransmitPEC(FunctionalState NewState)
{
if(NewState != DISABLE)
R16_I2C_CTRL1 |= RB_I2C_PEC;
else
R16_I2C_CTRL1 &= ~RB_I2C_PEC;
}
/*********************************************************************
* @fn I2C_PECPositionConfig
*
* @brief Selects the specified I2C PEC position.
*
* @param I2C_PECPosition - specifies the PEC position.
* I2C_PECPosition_Next - indicates that the next byte is PEC.
* I2C_PECPosition_Current - indicates that current byte is PEC.
*
* @return none
*/
void I2C_PECPositionConfig(uint16_t I2C_PECPosition)
{
if(I2C_PECPosition == I2C_PECPosition_Next)
R16_I2C_CTRL1 |= I2C_PECPosition_Next;
else
R16_I2C_CTRL1 &= I2C_PECPosition_Current;
}
/*********************************************************************
* @fn I2C_CalculatePEC
*
* @brief Enables or disables the PEC value calculation of the transferred bytes.
*
* @param NewState - ENABLE or DISABLE.
*
* @return none
*/
void I2C_CalculatePEC(FunctionalState NewState)
{
if(NewState != DISABLE)
R16_I2C_CTRL1 |= RB_I2C_ENPEC;
else
R16_I2C_CTRL1 &= ~RB_I2C_ENPEC;
}
/*********************************************************************
* @fn I2C_GetPEC
*
* @brief Returns the PEC value for the specified I2C.
*
* @return The PEC value.
*/
uint8_t I2C_GetPEC(void)
{
return (R16_I2C_STAR2 >> 8);
}
/*********************************************************************
* @fn I2C_ARPCmd
*
* @brief Enables or disables the specified I2C ARP.
*
* @param NewState - ENABLE or DISABLE.
*
* @return none
*/
void I2C_ARPCmd(FunctionalState NewState)
{
if(NewState != DISABLE)
R16_I2C_CTRL1 |= RB_I2C_EBARP;
else
R16_I2C_CTRL1 &= ~RB_I2C_EBARP;
}
/*********************************************************************
* @fn I2C_StretchClockCmd
*
* @brief Enables or disables the specified I2C Clock stretching.
*
* @param NewState - ENABLE or DISABLE.
*
* @return none
*/
void I2C_StretchClockCmd(FunctionalState NewState)
{
if(NewState == DISABLE)
R16_I2C_CTRL1 |= RB_I2C_NOSTRETCH;
else
R16_I2C_CTRL1 &= ~RB_I2C_NOSTRETCH;
}
/*********************************************************************
* @fn I2C_FastModeDutyCycleConfig
*
* @brief Selects the specified I2C fast mode duty cycle.
*
* @param I2C_DutyCycle - specifies the fast mode duty cycle.
* I2C_DutyCycle_2 - I2C fast mode Tlow/Thigh = 2.
* I2C_DutyCycle_16_9 - I2C fast mode Tlow/Thigh = 16/9.
*
* @return none
*/
void I2C_FastModeDutyCycleConfig(uint16_t I2C_DutyCycle)
{
if(I2C_DutyCycle != I2C_DutyCycle_16_9)
R16_I2C_CKCFGR &= ~I2C_DutyCycle_16_9;
else
R16_I2C_CKCFGR |= I2C_DutyCycle_16_9;
}
/*********************************************************************
* @fn I2C_CheckEvent
*
* @brief Checks whether the last I2Cx Event is equal to the one passed as parameter.
*
* @param I2C_EVENT - specifies the event to be checked.
* I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED : EV1.
* I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED : EV1.
* I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED : EV1.
* I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED : EV1.
* I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED : EV1.
* I2C_EVENT_SLAVE_BYTE_RECEIVED : EV2.
* (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_DUALF) : EV2.
* (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_GENCALL) : EV2.
* I2C_EVENT_SLAVE_BYTE_TRANSMITTED : EV3.
* (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_DUALF) : EV3.
* (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_GENCALL) : EV3.
* I2C_EVENT_SLAVE_ACK_FAILURE : EV3_2.
* I2C_EVENT_SLAVE_STOP_DETECTED : EV4.
* I2C_EVENT_MASTER_MODE_SELECT : EV5.
* I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED : EV6.
* I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED : EV6.
* I2C_EVENT_MASTER_BYTE_RECEIVED : EV7.
* I2C_EVENT_MASTER_BYTE_TRANSMITTING : EV8.
* I2C_EVENT_MASTER_BYTE_TRANSMITTED : EV8_2.
* I2C_EVENT_MASTER_MODE_ADDRESS10 : EV9.
*
* @return 1 - SUCCESS or 0 - ERROR.
*/
uint8_t I2C_CheckEvent(uint32_t I2C_EVENT)
{
uint32_t lastevent = 0;
uint32_t flag1 = 0, flag2 = 0;
uint8_t status = 0;
flag1 = R16_I2C_STAR1;
flag2 = R16_I2C_STAR2;
flag2 = flag2 << 16;
lastevent = (flag1 | flag2) & FLAG_Mask;
if((lastevent & I2C_EVENT) == I2C_EVENT)
{
status = !0;
}
else
{
status = 0;
}
return status;
}
/*********************************************************************
* @fn I2C_GetLastEvent
*
* @brief Returns the last I2Cx Event.
*
* @return The last event.
*/
uint32_t I2C_GetLastEvent(void)
{
uint32_t lastevent = 0;
uint32_t flag1 = 0, flag2 = 0;
flag1 = R16_I2C_STAR1;
flag2 = R16_I2C_STAR2;
flag2 = flag2 << 16;
lastevent = (flag1 | flag2) & FLAG_Mask;
return lastevent;
}
/*********************************************************************
* @fn I2C_GetFlagStatus
*
* @brief Checks whether the last I2Cx Event is equal to the one passed as parameter.
*
* @param I2C_FLAG - specifies the flag to check.
* I2C_FLAG_DUALF - Dual flag (Slave mode).
* I2C_FLAG_SMBHOST - SMBus host header (Slave mode).
* I2C_FLAG_SMBDEFAULT - SMBus default header (Slave mode).
* I2C_FLAG_GENCALL - General call header flag (Slave mode).
* I2C_FLAG_TRA - Transmitter/Receiver flag.
* I2C_FLAG_BUSY - Bus busy flag.
* I2C_FLAG_MSL - Master/Slave flag.
* I2C_FLAG_SMBALERT - SMBus Alert flag.
* I2C_FLAG_TIMEOUT - Timeout or Tlow error flag.
* I2C_FLAG_PECERR - PEC error in reception flag.
* I2C_FLAG_OVR - Overrun/Underrun flag (Slave mode).
* I2C_FLAG_AF - Acknowledge failure flag.
* I2C_FLAG_ARLO - Arbitration lost flag (Master mode).
* I2C_FLAG_BERR - Bus error flag.
* I2C_FLAG_TXE - Data register empty flag (Transmitter).
* I2C_FLAG_RXNE - Data register not empty (Receiver) flag.
* I2C_FLAG_STOPF - Stop detection flag (Slave mode).
* I2C_FLAG_ADD10 - 10-bit header sent flag (Master mode).
* I2C_FLAG_BTF - Byte transfer finished flag.
* I2C_FLAG_ADDR - Address sent flag (Master mode) "ADSL"
* Address matched flag (Slave mode)"ENDA".
* I2C_FLAG_SB - Start bit flag (Master mode).
*
* @return FlagStatus - SET or RESET.
*/
FlagStatus I2C_GetFlagStatus(uint32_t I2C_FLAG)
{
FlagStatus bitstatus = RESET;
__IO uint32_t i2creg = 0, i2cxbase = 0;
i2cxbase = (uint32_t)BA_I2C;
i2creg = I2C_FLAG >> 28;
I2C_FLAG &= FLAG_Mask;
if(i2creg != 0)
{
i2cxbase += 0x14;
}
else
{
I2C_FLAG = (uint32_t)(I2C_FLAG >> 16);
i2cxbase += 0x18;
}
if(((*(__IO uint32_t *)i2cxbase) & I2C_FLAG) != (uint32_t)RESET)
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
/*********************************************************************
* @fn I2C_ClearFlag
*
* @brief Clears the I2Cx's pending flags.
*
* @param I2C_FLAG - specifies the flag to clear.
* I2C_FLAG_SMBALERT - SMBus Alert flag.
* I2C_FLAG_TIMEOUT - Timeout or Tlow error flag.
* I2C_FLAG_PECERR - PEC error in reception flag.
* I2C_FLAG_OVR - Overrun/Underrun flag (Slave mode).
* I2C_FLAG_AF - Acknowledge failure flag.
* I2C_FLAG_ARLO - Arbitration lost flag (Master mode).
* I2C_FLAG_BERR - Bus error flag.
*
* @return none
*/
void I2C_ClearFlag(uint32_t I2C_FLAG)
{
uint32_t flagpos = 0;
flagpos = I2C_FLAG & FLAG_Mask;
R16_I2C_STAR1 = (uint16_t)~flagpos;
}
/*********************************************************************
* @fn I2C_GetITStatus
*
* @brief Checks whether the specified I2C interrupt has occurred or not.
*
* @param II2C_IT - specifies the interrupt source to check.
* I2C_FLAG_SMBALERT - SMBus Alert flag.
* I2C_FLAG_TIMEOUT - Timeout or Tlow error flag.
* I2C_FLAG_PECERR - PEC error in reception flag.
* I2C_FLAG_OVR - Overrun/Underrun flag (Slave mode).
* I2C_FLAG_AF - Acknowledge failure flag.
* I2C_FLAG_ARLO - Arbitration lost flag (Master mode).
* I2C_FLAG_BERR - Bus error flag.
* I2C_FLAG_TXE - Data register empty flag (Transmitter).
* I2C_FLAG_RXNE - Data register not empty (Receiver) flag.
* I2C_FLAG_STOPF - Stop detection flag (Slave mode).
* I2C_FLAG_ADD10 - 10-bit header sent flag (Master mode).
* I2C_FLAG_BTF - Byte transfer finished flag.
* I2C_FLAG_ADDR - Address sent flag (Master mode) "ADSL"
* Address matched flag (Slave mode)"ENDA".
* I2C_FLAG_SB - Start bit flag (Master mode).
*
* @return none
*/
ITStatus I2C_GetITStatus(uint32_t I2C_IT)
{
ITStatus bitstatus = RESET;
uint32_t enablestatus = 0;
enablestatus = (uint32_t)(((I2C_IT & ITEN_Mask) >> 16) & (R16_I2C_CTRL2));
I2C_IT &= FLAG_Mask;
if(((R16_I2C_STAR1 & I2C_IT) != (uint32_t)RESET) && enablestatus)
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
/*********************************************************************
* @fn I2C_ClearITPendingBit
*
* @brief Clears the I2Cx interrupt pending bits.
*
* @param I2C_IT - specifies the interrupt pending bit to clear.
* I2C_IT_SMBALERT - SMBus Alert interrupt.
* I2C_IT_TIMEOUT - Timeout or Tlow error interrupt.
* I2C_IT_PECERR - PEC error in reception interrupt.
* I2C_IT_OVR - Overrun/Underrun interrupt (Slave mode).
* I2C_IT_AF - Acknowledge failure interrupt.
* I2C_IT_ARLO - Arbitration lost interrupt (Master mode).
* I2C_IT_BERR - Bus error interrupt.
*
* @return none
*/
void I2C_ClearITPendingBit(uint32_t I2C_IT)
{
uint32_t flagpos = 0;
flagpos = I2C_IT & FLAG_Mask;
R16_I2C_STAR1 = (uint16_t)~flagpos;
}

View File

@ -0,0 +1,31 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_lcd.c
* Author : WCH
* Version : V1.0
* Date : 2018/12/15
* 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 "CH59x_common.h"
#include "CH59x_lcd.h"
/*******************************************************************************
* Function Name : LCD_DefInit
* Description : LCD段式屏驱动初始化配置
* Input : duty
* bias
* Return : None
*******************************************************************************/
void LCD_Init(LCDDutyTypeDef duty, LCDBiasTypeDef bias)
{
R32_PIN_CONFIG2 = 0xfffeff3f; // 关闭数字输入
R32_LCD_CMD = 0x1ffff << 8;
R32_LCD_CMD |= RB_LCD_SYS_EN | RB_LCD_ON |
(LCD_CLK_128 << 5) |
(duty << 3) |
(bias << 2);
}

View File

@ -0,0 +1,123 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_pwm.c
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* 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 "CH59x_common.h"
/*********************************************************************
* @fn PWMX_CycleCfg
*
* @brief PWM4-PWM11基准时钟配置
*
* @param cyc - refer to PWMX_CycleTypeDef
*
* @return none
*/
void PWMX_CycleCfg(PWMX_CycleTypeDef cyc)
{
switch(cyc)
{
case PWMX_Cycle_256:
R8_PWM_CONFIG = R8_PWM_CONFIG & 0xf0;
break;
case PWMX_Cycle_255:
R8_PWM_CONFIG = (R8_PWM_CONFIG & 0xf0) | 0x01;
break;
case PWMX_Cycle_128:
R8_PWM_CONFIG = (R8_PWM_CONFIG & 0xf0) | (1 << 2);
break;
case PWMX_Cycle_127:
R8_PWM_CONFIG = (R8_PWM_CONFIG & 0xf0) | (1 << 2) | 0x01;
break;
case PWMX_Cycle_64:
R8_PWM_CONFIG = (R8_PWM_CONFIG & 0xf0) | (2 << 2);
break;
case PWMX_Cycle_63:
R8_PWM_CONFIG = (R8_PWM_CONFIG & 0xf0) | (2 << 2) | 0x01;
break;
case PWMX_Cycle_32:
R8_PWM_CONFIG = (R8_PWM_CONFIG & 0xf0) | (3 << 2);
break;
case PWMX_Cycle_31:
R8_PWM_CONFIG = (R8_PWM_CONFIG & 0xf0) | (3 << 2) | 0x01;
break;
default:
break;
}
}
/*********************************************************************
* @fn PWMX_ACTOUT
*
* @brief PWM4-PWM11通道输出波形配置
*
* @param ch - select channel of pwm, refer to channel of PWM define
* @param da - effective pulse width
* @param pr - select wave polar, refer to PWMX_PolarTypeDef
* @param s - control pwmx function, ENABLE or DISABLE
*
* @return none
*/
void PWMX_ACTOUT(uint8_t ch, uint8_t da, PWMX_PolarTypeDef pr, FunctionalState s)
{
uint8_t i;
if(s == DISABLE)
{
R8_PWM_OUT_EN &= ~(ch);
}
else
{
(pr) ? (R8_PWM_POLAR |= (ch)) : (R8_PWM_POLAR &= ~(ch));
for(i = 0; i < 8; i++)
{
if((ch >> i) & 1)
{
*((volatile uint8_t *)((&R8_PWM4_DATA) + i)) = da;
}
}
R8_PWM_OUT_EN |= (ch);
}
}
/*********************************************************************
* @fn PWMX_AlterOutCfg
*
* @brief PWM
*
* @param ch - select group of PWM alternate output
* RB_PWM4_5_STAG_EN - PWM4 PWM5
* RB_PWM6_7_STAG_EN - PWM6 PWM7
* RB_PWM8_9_STAG_EN - PWM8 PWM9
* RB_PWM10_11_STAG_EN - PWM10 PWM11
* @param s - control pwmx function, ENABLE or DISABLE
*
* @return none
*/
void PWMX_AlterOutCfg(uint8_t ch, FunctionalState s)
{
if(s == DISABLE)
{
R8_PWM_CONFIG &= ~(ch);
}
else
{
R8_PWM_CONFIG |= (ch);
}
}

View File

@ -0,0 +1,406 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_pwr.c
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* 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 "CH59x_common.h"
/*********************************************************************
* @fn PWR_DCDCCfg
*
* @brief DC/DC电源
*
* @param s - DCDC电源
*
* @return none
*/
void PWR_DCDCCfg(FunctionalState s)
{
uint16_t adj = R16_AUX_POWER_ADJ;
uint16_t plan = R16_POWER_PLAN;
if(s == DISABLE)
{
adj &= ~RB_DCDC_CHARGE;
plan &= ~(RB_PWR_DCDC_EN | RB_PWR_DCDC_PRE); // 旁路 DC/DC
sys_safe_access_enable();
R16_AUX_POWER_ADJ = adj;
R16_POWER_PLAN = plan;
sys_safe_access_disable();
}
else
{
uint32_t HW_Data[2];
FLASH_EEPROM_CMD(CMD_GET_ROM_INFO, ROM_CFG_ADR_HW, HW_Data, 0);
if((HW_Data[0]) & (1 << 13))
{
return;
}
adj |= RB_DCDC_CHARGE;
plan |= RB_PWR_DCDC_PRE;
sys_safe_access_enable();
R16_AUX_POWER_ADJ = adj;
R16_POWER_PLAN = plan;
sys_safe_access_disable();
DelayUs(10);
sys_safe_access_enable();
R16_POWER_PLAN |= RB_PWR_DCDC_EN;
sys_safe_access_disable();
}
}
/*********************************************************************
* @fn PWR_UnitModCfg
*
* @brief
*
* @param s -
* @param unit - please refer to unit of controllable power supply
*
* @return none
*/
void PWR_UnitModCfg(FunctionalState s, uint8_t unit)
{
uint8_t ck32k_cfg = R8_CK32K_CONFIG;
if(s == DISABLE) //关闭
{
ck32k_cfg &= ~(unit & 0x03);
}
else //打开
{
ck32k_cfg |= (unit & 0x03);
}
sys_safe_access_enable();
R8_CK32K_CONFIG = ck32k_cfg;
sys_safe_access_disable();
}
/*********************************************************************
* @fn PWR_PeriphClkCfg
*
* @brief
*
* @param s -
* @param perph - please refer to Peripher CLK control bit define
*
* @return none
*/
void PWR_PeriphClkCfg(FunctionalState s, uint16_t perph)
{
uint32_t sleep_ctrl = R32_SLEEP_CONTROL;
if(s == DISABLE)
{
sleep_ctrl |= perph;
}
else
{
sleep_ctrl &= ~perph;
}
sys_safe_access_enable();
R32_SLEEP_CONTROL = sleep_ctrl;
sys_safe_access_disable();
}
/*********************************************************************
* @fn PWR_PeriphWakeUpCfg
*
* @brief
*
* @param s -
* @param perph -
* RB_SLP_USB_WAKE - USB
* RB_SLP_RTC_WAKE - RTC
* RB_SLP_GPIO_WAKE - GPIO
* RB_SLP_BAT_WAKE - BAT
* @param mode - refer to WakeUP_ModeypeDef
*
* @return none
*/
void PWR_PeriphWakeUpCfg(FunctionalState s, uint8_t perph, WakeUP_ModeypeDef mode)
{
uint8_t m;
if(s == DISABLE)
{
sys_safe_access_enable();
R8_SLP_WAKE_CTRL &= ~perph;
sys_safe_access_disable();
}
else
{
switch(mode)
{
case Short_Delay:
m = 0x01;
break;
case Long_Delay:
m = 0x00;
break;
default:
m = 0x01;
break;
}
sys_safe_access_enable();
R8_SLP_WAKE_CTRL |= RB_WAKE_EV_MODE | perph;
sys_safe_access_disable();
sys_safe_access_enable();
R8_SLP_POWER_CTRL &= ~(RB_WAKE_DLY_MOD);
sys_safe_access_disable();
sys_safe_access_enable();
R8_SLP_POWER_CTRL |= m;
sys_safe_access_disable();
}
}
/*********************************************************************
* @fn PowerMonitor
*
* @brief
*
* @param s -
* @param vl - refer to VolM_LevelypeDef
*
* @return none
*/
void PowerMonitor(FunctionalState s, VolM_LevelypeDef vl)
{
uint8_t ctrl = R8_BAT_DET_CTRL;
uint8_t cfg = R8_BAT_DET_CFG;
if(s == DISABLE)
{
sys_safe_access_enable();
R8_BAT_DET_CTRL = 0;
sys_safe_access_disable();
}
else
{
if(vl & 0x80)
{
cfg = vl & 0x03;
ctrl = RB_BAT_MON_EN | ((vl >> 2) & 1);
}
else
{
cfg = vl & 0x03;
ctrl = RB_BAT_DET_EN;
}
sys_safe_access_enable();
R8_BAT_DET_CTRL = ctrl;
R8_BAT_DET_CFG = cfg;
sys_safe_access_disable();
mDelayuS(1);
sys_safe_access_enable();
R8_BAT_DET_CTRL |= RB_BAT_LOW_IE | RB_BAT_LOWER_IE;
sys_safe_access_disable();
}
}
/*********************************************************************
* @fn LowPower_Idle
*
* @brief -Idle模式
*
* @param none
*
* @return none
*/
__HIGH_CODE
void LowPower_Idle(void)
{
FLASH_ROM_SW_RESET();
R8_FLASH_CTRL = 0x04; //flash关闭
PFIC->SCTLR &= ~(1 << 2); // sleep
__WFI();
__nop();
__nop();
}
/*********************************************************************
* @fn LowPower_Halt
*
* @brief -Halt模式HSI/5
*
* @param none
*
* @return none
*/
__HIGH_CODE
void LowPower_Halt(void)
{
uint8_t x32Kpw, x32Mpw;
FLASH_ROM_SW_RESET();
R8_FLASH_CTRL = 0x04; //flash关闭
x32Kpw = R8_XT32K_TUNE;
x32Mpw = R8_XT32M_TUNE;
x32Mpw = (x32Mpw & 0xfc) | 0x03; // 150%额定电流
if(R16_RTC_CNT_32K > 0x3fff)
{ // 超过500ms
x32Kpw = (x32Kpw & 0xfc) | 0x01; // LSE驱动电流降低到额定电流
}
sys_safe_access_enable();
R8_BAT_DET_CTRL = 0; // 关闭电压监控
sys_safe_access_disable();
sys_safe_access_enable();
R8_XT32K_TUNE = x32Kpw;
R8_XT32M_TUNE = x32Mpw;
sys_safe_access_disable();
sys_safe_access_enable();
R8_PLL_CONFIG |= (1 << 5);
sys_safe_access_disable();
PFIC->SCTLR |= (1 << 2); //deep sleep
__WFI();
__nop();
__nop();
sys_safe_access_enable();
R8_PLL_CONFIG &= ~(1 << 5);
sys_safe_access_disable();
}
/*******************************************************************************
* Function Name : LowPower_Sleep
* Description : -Sleep模式
80M时flash内代码退30us延迟
* Input : rm:
RB_PWR_RAM2K - 2K retention SRAM
RB_PWR_RAM24K - 24K main SRAM
RB_PWR_EXTEND - USB BLE
RB_PWR_XROM - FlashROM
NULL -
* Return : None
*******************************************************************************/
__HIGH_CODE
void LowPower_Sleep(uint16_t rm)
{
__attribute__((aligned(4))) uint8_t MacAddr[6] = {0};
uint8_t x32Kpw, x32Mpw;
uint16_t power_plan;
GetMACAddress(MacAddr);
x32Kpw = R8_XT32K_TUNE;
x32Mpw = R8_XT32M_TUNE;
x32Mpw = (x32Mpw & 0xfc) | 0x03; // 150%额定电流
if(R16_RTC_CNT_32K > 0x3fff)
{ // 超过500ms
x32Kpw = (x32Kpw & 0xfc) | 0x01; // LSE驱动电流降低到额定电流
}
sys_safe_access_enable();
R8_BAT_DET_CTRL = 0; // 关闭电压监控
sys_safe_access_disable();
sys_safe_access_enable();
R8_XT32K_TUNE = x32Kpw;
R8_XT32M_TUNE = x32Mpw;
sys_safe_access_disable();
sys_safe_access_enable();
R16_POWER_PLAN &= ~RB_XT_PRE_EN;
sys_safe_access_disable();
PFIC->SCTLR |= (1 << 2); //deep sleep
power_plan = R16_POWER_PLAN & (RB_PWR_DCDC_EN | RB_PWR_DCDC_PRE);
power_plan |= RB_PWR_PLAN_EN | RB_PWR_CORE | rm | (2<<11);
sys_safe_access_enable();
R8_SLP_POWER_CTRL |= RB_RAM_RET_LV;
R16_POWER_PLAN = power_plan;
sys_safe_access_disable();
if((rm & RB_XT_PRE_EN) == 0)
{
sys_safe_access_enable();
R8_PLL_CONFIG |= (1 << 5);
sys_safe_access_disable();
}
__WFI();
__nop();
__nop();
sys_safe_access_enable();
R16_POWER_PLAN &= ~RB_XT_PRE_EN;
sys_safe_access_disable();
if((rm & RB_XT_PRE_EN) == 0)
{
sys_safe_access_enable();
R8_PLL_CONFIG &= ~(1 << 5);
sys_safe_access_disable();
DelayUs(20);
}
}
/*********************************************************************
* @fn LowPower_Shutdown
*
* @brief -Shutdown模式HSI/5
* @note DCDC功能强制关闭
*
* @param rm -
* RB_PWR_RAM2K - 2K retention SRAM
* RB_PWR_RAM16K - 16K main SRAM
* NULL -
*
* @return none
*/
__HIGH_CODE
void LowPower_Shutdown(uint16_t rm)
{
uint8_t x32Kpw, x32Mpw;
FLASH_ROM_SW_RESET();
x32Kpw = R8_XT32K_TUNE;
x32Mpw = R8_XT32M_TUNE;
x32Mpw = (x32Mpw & 0xfc) | 0x03; // 150%额定电流
if(R16_RTC_CNT_32K > 0x3fff)
{ // 超过500ms
x32Kpw = (x32Kpw & 0xfc) | 0x01; // LSE驱动电流降低到额定电流
}
sys_safe_access_enable();
R8_BAT_DET_CTRL = 0; // 关闭电压监控
sys_safe_access_disable();
sys_safe_access_enable();
R8_XT32K_TUNE = x32Kpw;
R8_XT32M_TUNE = x32Mpw;
sys_safe_access_disable();
SetSysClock(CLK_SOURCE_HSE_6_4MHz);
PFIC->SCTLR |= (1 << 2); //deep sleep
sys_safe_access_enable();
R8_SLP_POWER_CTRL |= RB_RAM_RET_LV;
sys_safe_access_disable();
sys_safe_access_enable();
R16_POWER_PLAN = RB_PWR_PLAN_EN | rm;
sys_safe_access_disable();
__WFI();
__nop();
__nop();
FLASH_ROM_SW_RESET();
sys_safe_access_enable();
R8_RST_WDOG_CTRL |= RB_SOFTWARE_RESET;
sys_safe_access_disable();
}

View File

@ -0,0 +1,370 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_SPI0.c
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* 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 "CH59x_common.h"
/*********************************************************************
* @fn SPI0_MasterDefInit
*
* @brief 0+3线+8MHz
*
* @param none
*
* @return none
*/
void SPI0_MasterDefInit(void)
{
R8_SPI0_CLOCK_DIV = 4; // 主频时钟4分频
R8_SPI0_CTRL_MOD = RB_SPI_ALL_CLEAR;
R8_SPI0_CTRL_MOD = RB_SPI_MOSI_OE | RB_SPI_SCK_OE;
R8_SPI0_CTRL_CFG |= RB_SPI_AUTO_IF; // 访问BUFFER/FIFO自动清除IF_BYTE_END标志
R8_SPI0_CTRL_CFG &= ~RB_SPI_DMA_ENABLE; // 不启动DMA方式
}
/*********************************************************************
* @fn SPI0_CLKCfg
*
* @brief SPI0 = d*Tsys
*
* @param c -
*
* @return none
*/
void SPI0_CLKCfg(uint8_t c)
{
if(c == 2)
{
R8_SPI0_CTRL_CFG |= RB_SPI_MST_DLY_EN;
}
else
{
R8_SPI0_CTRL_CFG &= ~RB_SPI_MST_DLY_EN;
}
R8_SPI0_CLOCK_DIV = c;
}
/*********************************************************************
* @fn SPI0_DataMode
*
* @brief
*
* @param m - refer to ModeBitOrderTypeDef
*
* @return none
*/
void SPI0_DataMode(ModeBitOrderTypeDef m)
{
switch(m)
{
case Mode0_LowBitINFront:
R8_SPI0_CTRL_MOD &= ~RB_SPI_MST_SCK_MOD;
R8_SPI0_CTRL_CFG |= RB_SPI_BIT_ORDER;
break;
case Mode0_HighBitINFront:
R8_SPI0_CTRL_MOD &= ~RB_SPI_MST_SCK_MOD;
R8_SPI0_CTRL_CFG &= ~RB_SPI_BIT_ORDER;
break;
case Mode3_LowBitINFront:
R8_SPI0_CTRL_MOD |= RB_SPI_MST_SCK_MOD;
R8_SPI0_CTRL_CFG |= RB_SPI_BIT_ORDER;
break;
case Mode3_HighBitINFront:
R8_SPI0_CTRL_MOD |= RB_SPI_MST_SCK_MOD;
R8_SPI0_CTRL_CFG &= ~RB_SPI_BIT_ORDER;
break;
default:
break;
}
}
/*********************************************************************
* @fn SPI0_MasterSendByte
*
* @brief (buffer)
*
* @param d -
*
* @return none
*/
void SPI0_MasterSendByte(uint8_t 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 (buffer)
*
* @param none
*
* @return
*/
uint8_t SPI0_MasterRecvByte(void)
{
R8_SPI0_CTRL_MOD &= ~RB_SPI_FIFO_DIR;
R8_SPI0_BUFFER = 0xFF; // 启动传输
while(!(R8_SPI0_INT_FLAG & RB_SPI_FREE));
return (R8_SPI0_BUFFER);
}
/*********************************************************************
* @fn SPI0_MasterTrans
*
* @brief 使FIFO连续发送多字节
*
* @param pbuf -
* @param len - 4095
*
* @return none
*/
void SPI0_MasterTrans(uint8_t *pbuf, uint16_t len)
{
uint16_t sendlen;
sendlen = len;
R8_SPI0_CTRL_MOD &= ~RB_SPI_FIFO_DIR; // 设置数据方向为输出
R16_SPI0_TOTAL_CNT = sendlen; // 设置要发送的数据长度
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); // 等待FIFO中的数据全部发送完成
}
/*********************************************************************
* @fn SPI0_MasterRecv
*
* @brief 使FIFO连续接收多字节
*
* @param pbuf -
* @param len - 4095
*
* @return none
*/
void SPI0_MasterRecv(uint8_t *pbuf, uint16_t len)
{
uint16_t readlen;
readlen = len;
R8_SPI0_CTRL_MOD |= RB_SPI_FIFO_DIR; // 设置数据方向为输入
R16_SPI0_TOTAL_CNT = len; // 设置需要接收的数据长度FIFO方向为输入长度不为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 DMA方式连续发送数据
*
* @param pbuf - ,
* @param len -
*
* @return none
*/
void SPI0_MasterDMATrans(uint8_t *pbuf, uint16_t len)
{
R8_SPI0_CTRL_MOD &= ~RB_SPI_FIFO_DIR;
R16_SPI0_DMA_BEG = (uint32_t)pbuf;
R16_SPI0_DMA_END = (uint32_t)(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 DMA方式连续接收数据
*
* @param pbuf - ,
* @param len -
*
* @return none
*/
void SPI0_MasterDMARecv(uint8_t *pbuf, uint16_t len)
{
R8_SPI0_CTRL_MOD |= RB_SPI_FIFO_DIR;
R16_SPI0_DMA_BEG = (uint32_t)pbuf;
R16_SPI0_DMA_END = (uint32_t)(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 MISO的GPIO对应为输入模式
*
* @return none
*/
void SPI0_SlaveInit(void)
{
R8_SPI0_CTRL_MOD = RB_SPI_ALL_CLEAR;
R8_SPI0_CTRL_MOD = RB_SPI_MISO_OE | RB_SPI_MODE_SLAVE;
R8_SPI0_CTRL_CFG |= RB_SPI_AUTO_IF;
}
/*********************************************************************
* @fn SPI0_SlaveRecvByte
*
* @brief
*
* @return
*/
uint8_t SPI0_SlaveRecvByte(void)
{
R8_SPI0_CTRL_MOD |= RB_SPI_FIFO_DIR;
while(R8_SPI0_FIFO_COUNT == 0);
return R8_SPI0_FIFO;
}
/*********************************************************************
* @fn SPI0_SlaveSendByte
*
* @brief
*
* @param d -
*
* @return none
*/
void SPI0_SlaveSendByte(uint8_t d)
{
R8_SPI0_CTRL_MOD &= ~RB_SPI_FIFO_DIR;
R8_SPI0_FIFO = d;
while(R8_SPI0_FIFO_COUNT != 0); // 等待发送完成
}
/*********************************************************************
* @fn SPI0_SlaveRecv
*
* @brief
*
* @param pbuf -
* @param len -
*
* @return none
*/
__HIGH_CODE
void SPI0_SlaveRecv(uint8_t *pbuf, uint16_t len)
{
uint16_t revlen;
revlen = len;
R8_SPI0_CTRL_MOD |= RB_SPI_FIFO_DIR;
R8_SPI0_INT_FLAG = RB_SPI_IF_CNT_END;
while(revlen)
{
if(R8_SPI0_FIFO_COUNT)
{
*pbuf = R8_SPI0_FIFO;
pbuf++;
revlen--;
}
}
}
/*********************************************************************
* @fn SPI0_SlaveTrans
*
* @brief
*
* @param pbuf -
* @param len - 4095
*
* @return none
*/
__HIGH_CODE
void SPI0_SlaveTrans(uint8_t *pbuf, uint16_t len)
{
uint16_t sendlen;
sendlen = len;
R8_SPI0_CTRL_MOD &= ~RB_SPI_FIFO_DIR; // 设置数据方向为输出
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); // 等待FIFO中的数据全部发送完成
}
/*********************************************************************
* @fn SPI0_SlaveDMARecv
*
* @brief DMA方式连续接收数据
*
* @param pbuf - ,
* @param len -
*
* @return none
*/
void SPI0_SlaveDMARecv(uint8_t *pbuf, uint16_t len)
{
R8_SPI0_CTRL_MOD |= RB_SPI_FIFO_DIR;
R16_SPI0_DMA_BEG = (uint32_t)pbuf;
R16_SPI0_DMA_END = (uint32_t)(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_SlaveDMATrans
*
* @brief DMA方式连续发送数据
*
* @param pbuf - ,
* @param len -
*
* @return none
*/
void SPI0_SlaveDMATrans(uint8_t *pbuf, uint16_t len)
{
R8_SPI0_CTRL_MOD &= ~RB_SPI_FIFO_DIR;
R16_SPI0_DMA_BEG = (uint32_t)pbuf;
R16_SPI0_DMA_END = (uint32_t)(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;
}

View File

@ -0,0 +1,368 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_SYS.c
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* 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 "CH59x_common.h"
volatile uint32_t IRQ_STA = 0;
/*********************************************************************
* @fn SetSysClock
*
* @brief
*
* @param sc - refer to SYS_CLKTypeDef
*
* @return none
*/
__HIGH_CODE
void SetSysClock(SYS_CLKTypeDef sc)
{
sys_safe_access_enable();
R8_PLL_CONFIG &= ~(1 << 5); //
sys_safe_access_disable();
if(sc & 0x20) // HSE div
{
sys_safe_access_enable();
R32_CLK_SYS_CFG = (0 << 6) | (sc & 0x1f) | RB_TX_32M_PWR_EN | RB_PLL_PWR_EN;
__nop();
__nop();
__nop();
__nop();
sys_safe_access_disable();
sys_safe_access_enable();
SAFEOPERATE;
R8_FLASH_CFG = 0X51;
sys_safe_access_disable();
}
else if(sc & 0x40) // PLL div
{
sys_safe_access_enable();
R32_CLK_SYS_CFG = (1 << 6) | (sc & 0x1f) | RB_TX_32M_PWR_EN | RB_PLL_PWR_EN;
__nop();
__nop();
__nop();
__nop();
sys_safe_access_disable();
sys_safe_access_enable();
R8_FLASH_CFG = 0X52;
sys_safe_access_disable();
}
else
{
sys_safe_access_enable();
R32_CLK_SYS_CFG |= RB_CLK_SYS_MOD;
sys_safe_access_disable();
}
//更改FLASH clk的驱动能力
sys_safe_access_enable();
R8_PLL_CONFIG |= 1 << 7;
sys_safe_access_disable();
}
/*********************************************************************
* @fn GetSysClock
*
* @brief
*
* @param none
*
* @return Hz
*/
uint32_t GetSysClock(void)
{
uint16_t rev;
rev = R32_CLK_SYS_CFG & 0xff;
if((rev & 0x40) == (0 << 6))
{ // 32M进行分频
return (32000000 / (rev & 0x1f));
}
else if((rev & RB_CLK_SYS_MOD) == (1 << 6))
{ // PLL进行分频
return (480000000 / (rev & 0x1f));
}
else
{ // 32K做主频
return (32000);
}
}
/*********************************************************************
* @fn SYS_GetInfoSta
*
* @brief
*
* @param i - refer to SYS_InfoStaTypeDef
*
* @return
*/
uint8_t SYS_GetInfoSta(SYS_InfoStaTypeDef i)
{
if(i == STA_SAFEACC_ACT)
{
return (R8_SAFE_ACCESS_SIG & RB_SAFE_ACC_ACT);
}
else
{
return (R8_GLOB_CFG_INFO & (1 << i));
}
}
/*********************************************************************
* @fn SYS_ResetExecute
*
* @brief
*
* @param none
*
* @return none
*/
__HIGH_CODE
void SYS_ResetExecute(void)
{
FLASH_ROM_SW_RESET();
sys_safe_access_enable();
R8_RST_WDOG_CTRL |= RB_SOFTWARE_RESET;
sys_safe_access_disable();
}
/*********************************************************************
* @fn SYS_DisableAllIrq
*
* @brief
*
* @param pirqv -
*
* @return none
*/
void SYS_DisableAllIrq(uint32_t *pirqv)
{
*pirqv = (PFIC->ISR[0] >> 8) | (PFIC->ISR[1] << 24);
PFIC->IRER[0] = 0xffffffff;
PFIC->IRER[1] = 0xffffffff;
}
/*********************************************************************
* @fn SYS_RecoverIrq
*
* @brief
*
* @param irq_status -
*
* @return none
*/
void SYS_RecoverIrq(uint32_t irq_status)
{
PFIC->IENR[0] = (irq_status << 8);
PFIC->IENR[1] = (irq_status >> 24);
}
/*********************************************************************
* @fn SYS_GetSysTickCnt
*
* @brief (SYSTICK)
*
* @param none
*
* @return
*/
uint32_t SYS_GetSysTickCnt(void)
{
uint32_t val;
val = SysTick->CNT;
return (val);
}
/*********************************************************************
* @fn WWDG_ITCfg
*
* @brief 使
*
* @param s -
*
* @return none
*/
void WWDG_ITCfg(FunctionalState s)
{
uint8_t ctrl = R8_RST_WDOG_CTRL;
if(s == DISABLE)
{
ctrl &= ~RB_WDOG_INT_EN;
}
else
{
ctrl |= RB_WDOG_INT_EN;
}
sys_safe_access_enable();
R8_RST_WDOG_CTRL = ctrl;
sys_safe_access_disable();
}
/*********************************************************************
* @fn WWDG_ResetCfg
*
* @brief
*
* @param s -
*
* @return none
*/
void WWDG_ResetCfg(FunctionalState s)
{
uint8_t ctrl = R8_RST_WDOG_CTRL;
if(s == DISABLE)
{
ctrl &= ~RB_WDOG_RST_EN;
}
else
{
ctrl |= RB_WDOG_RST_EN;
}
sys_safe_access_enable();
R8_RST_WDOG_CTRL = ctrl;
sys_safe_access_disable();
}
/*********************************************************************
* @fn WWDG_ClearFlag
*
* @brief
*
* @param none
*
* @return none
*/
void WWDG_ClearFlag(void)
{
sys_safe_access_enable();
R8_RST_WDOG_CTRL |= RB_WDOG_INT_FLAG;
sys_safe_access_disable();
}
/*********************************************************************
* @fn HardFault_Handler
*
* @brief
*
* @param none
*
* @return none
*/
__INTERRUPT
__HIGH_CODE
__attribute__((weak))
void HardFault_Handler(void)
{
FLASH_ROM_SW_RESET();
sys_safe_access_enable();
R16_INT32K_TUNE = 0xFFFF;
sys_safe_access_disable();
sys_safe_access_enable();
R8_RST_WDOG_CTRL |= RB_SOFTWARE_RESET;
sys_safe_access_disable();
while(1);
}
/*********************************************************************
* @fn mDelayuS
*
* @brief uS
*
* @param t -
*
* @return none
*/
__HIGH_CODE
void mDelayuS(uint16_t t)
{
uint32_t i;
#if(FREQ_SYS == 80000000)
i = t * 20;
#elif(FREQ_SYS == 60000000)
i = t * 15;
#elif(FREQ_SYS == 48000000)
i = t * 12;
#elif(FREQ_SYS == 40000000)
i = t * 10;
#elif(FREQ_SYS == 32000000)
i = t << 3;
#elif(FREQ_SYS == 24000000)
i = t * 6;
#elif(FREQ_SYS == 16000000)
i = t << 2;
#elif(FREQ_SYS == 8000000)
i = t << 1;
#elif(FREQ_SYS == 4000000)
i = t;
#elif(FREQ_SYS == 2000000)
i = t >> 1;
#elif(FREQ_SYS == 1000000)
i = t >> 2;
#else
i = t << 1;
#endif
do
{
__nop();
} while(--i);
}
/*********************************************************************
* @fn mDelaymS
*
* @brief mS
*
* @param t -
*
* @return none
*/
__HIGH_CODE
void mDelaymS(uint16_t t)
{
uint16_t i;
for(i = 0; i < t; i++)
{
mDelayuS(1000);
}
}
#ifdef DEBUG
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,75 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_timer0.c
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* 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 "CH59x_common.h"
/*********************************************************************
* @fn TMR0_TimerInit
*
* @brief
*
* @param t - Tsys, 67108864
*
* @return none
*/
void TMR0_TimerInit(uint32_t t)
{
R32_TMR0_CNT_END = t;
R8_TMR0_CTRL_MOD = RB_TMR_ALL_CLEAR;
R8_TMR0_CTRL_MOD = RB_TMR_COUNT_EN;
}
/*********************************************************************
* @fn TMR0_EXTSingleCounterInit
*
* @brief 沿
*
* @param cap -
*
* @return none
*/
void TMR0_EXTSingleCounterInit(CapModeTypeDef cap)
{
R8_TMR0_CTRL_MOD = RB_TMR_ALL_CLEAR;
R8_TMR0_CTRL_MOD = RB_TMR_COUNT_EN | RB_TMR_CAP_COUNT | RB_TMR_MODE_IN | (cap << 6);
}
/*********************************************************************
* @fn TMR0_PWMInit
*
* @brief PWM
*
* @param pr - select wave polar, refer to PWMX_PolarTypeDef
* @param ts - set pwm repeat times, refer to PWM_RepeatTsTypeDef
*
* @return none
*/
void TMR0_PWMInit(PWMX_PolarTypeDef pr, PWM_RepeatTsTypeDef ts)
{
R8_TMR0_CTRL_MOD = RB_TMR_ALL_CLEAR;
R8_TMR0_CTRL_MOD = (pr << 4) | (ts << 6);
}
/*********************************************************************
* @fn TMR0_CapInit
*
* @brief
*
* @param cap - select capture mode, refer to 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);
}

View File

@ -0,0 +1,104 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_timer1.c
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* 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 "CH59x_common.h"
/*********************************************************************
* @fn TMR1_TimerInit
*
* @brief
*
* @param t - Tsys, 67108864
*
* @return none
*/
void TMR1_TimerInit(uint32_t t)
{
R32_TMR1_CNT_END = t;
R8_TMR1_CTRL_MOD = RB_TMR_ALL_CLEAR;
R8_TMR1_CTRL_MOD = RB_TMR_COUNT_EN;
}
/*********************************************************************
* @fn TMR1_EXTSingleCounterInit
*
* @brief 沿
*
* @param cap -
*
* @return none
*/
void TMR1_EXTSingleCounterInit(CapModeTypeDef cap)
{
R8_TMR1_CTRL_MOD = RB_TMR_ALL_CLEAR;
R8_TMR1_CTRL_MOD = RB_TMR_COUNT_EN | RB_TMR_CAP_COUNT | RB_TMR_MODE_IN | (cap << 6);
}
/*********************************************************************
* @fn TMR1_PWMInit
*
* @brief PWM
*
* @param pr - select wave polar, refer to PWMX_PolarTypeDef
* @param ts - set pwm repeat times, refer to PWM_RepeatTsTypeDef
*
* @return none
*/
void TMR1_PWMInit(PWMX_PolarTypeDef pr, PWM_RepeatTsTypeDef ts)
{
R8_TMR1_CTRL_MOD = RB_TMR_ALL_CLEAR;
R8_TMR1_CTRL_MOD = (pr << 4) | (ts << 6);
}
/*********************************************************************
* @fn TMR1_CapInit
*
* @brief
*
* @param cap - select capture mode, refer to 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 TMR1_DMACfg
*
* @brief DMA功能
*
* @param s - DMA功能
* @param startAddr - DMA
* @param endAddr - DMA
* @param m - DMA模式
*
* @return none
*/
void TMR1_DMACfg(uint8_t s, uint16_t startAddr, uint16_t endAddr, DMAModeTypeDef m)
{
if(s == DISABLE)
{
R8_TMR1_CTRL_DMA = 0;
}
else
{
R16_TMR1_DMA_BEG = startAddr;
R16_TMR1_DMA_END = endAddr;
if(m)
R8_TMR1_CTRL_DMA = RB_TMR_DMA_LOOP | RB_TMR_DMA_ENABLE;
else
R8_TMR1_CTRL_DMA = RB_TMR_DMA_ENABLE;
}
}

View File

@ -0,0 +1,104 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_timer2.c
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* 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 "CH59x_common.h"
/*********************************************************************
* @fn TMR2_TimerInit
*
* @brief
*
* @param t - Tsys, 67108864
*
* @return none
*/
void TMR2_TimerInit(uint32_t t)
{
R32_TMR2_CNT_END = t;
R8_TMR2_CTRL_MOD = RB_TMR_ALL_CLEAR;
R8_TMR2_CTRL_MOD = RB_TMR_COUNT_EN;
}
/*********************************************************************
* @fn TMR2_EXTSingleCounterInit
*
* @brief 沿
*
* @param cap -
*
* @return none
*/
void TMR2_EXTSingleCounterInit(CapModeTypeDef cap)
{
R8_TMR2_CTRL_MOD = RB_TMR_ALL_CLEAR;
R8_TMR2_CTRL_MOD = RB_TMR_COUNT_EN | RB_TMR_CAP_COUNT | RB_TMR_MODE_IN | (cap << 6);
}
/*********************************************************************
* @fn TMR2_PWMInit
*
* @brief PWM
*
* @param pr - select wave polar, refer to PWMX_PolarTypeDef
* @param ts - set pwm repeat times, refer to PWM_RepeatTsTypeDef
*
* @return none
*/
void TMR2_PWMInit(PWMX_PolarTypeDef pr, PWM_RepeatTsTypeDef ts)
{
R8_TMR2_CTRL_MOD = RB_TMR_ALL_CLEAR;
R8_TMR2_CTRL_MOD = (pr << 4) | (ts << 6);
}
/*********************************************************************
* @fn TMR2_CapInit
*
* @brief
*
* @param cap - select capture mode, refer to 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 TMR2_DMACfg
*
* @brief DMA功能
*
* @param s - DMA功能
* @param startAddr - DMA
* @param endAddr - DMA
* @param m - DMA模式
*
* @return none
*/
void TMR2_DMACfg(uint8_t s, uint32_t startAddr, uint32_t endAddr, DMAModeTypeDef m)
{
if(s == DISABLE)
{
R8_TMR2_CTRL_DMA = 0;
}
else
{
R16_TMR2_DMA_BEG = startAddr&0xFFFF;
R16_TMR2_DMA_END = endAddr&0xFFFF;
if(m)
R8_TMR2_CTRL_DMA = RB_TMR_DMA_LOOP | RB_TMR_DMA_ENABLE;
else
R8_TMR2_CTRL_DMA = RB_TMR_DMA_ENABLE;
}
}

View File

@ -0,0 +1,75 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_timer3.c
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* 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 "CH59x_common.h"
/*********************************************************************
* @fn TMR3_TimerInit
*
* @brief
*
* @param t - Tsys, 67108864
*
* @return none
*/
void TMR3_TimerInit(uint32_t t)
{
R32_TMR3_CNT_END = t;
R8_TMR3_CTRL_MOD = RB_TMR_ALL_CLEAR;
R8_TMR3_CTRL_MOD = RB_TMR_COUNT_EN;
}
/*********************************************************************
* @fn TMR3_EXTSingleCounterInit
*
* @brief 沿
*
* @param cap -
*
* @return none
*/
void TMR3_EXTSingleCounterInit(CapModeTypeDef cap)
{
R8_TMR3_CTRL_MOD = RB_TMR_ALL_CLEAR;
R8_TMR3_CTRL_MOD = RB_TMR_COUNT_EN | RB_TMR_CAP_COUNT | RB_TMR_MODE_IN | (cap << 6);
}
/*********************************************************************
* @fn TMR3_PWMInit
*
* @brief PWM
*
* @param pr - select wave polar, refer to PWMX_PolarTypeDef
* @param ts - set pwm repeat times, refer to PWM_RepeatTsTypeDef
*
* @return none
*/
void TMR3_PWMInit(PWMX_PolarTypeDef pr, PWM_RepeatTsTypeDef ts)
{
R8_TMR3_CTRL_MOD = RB_TMR_ALL_CLEAR;
R8_TMR3_CTRL_MOD = (pr << 4) | (ts << 6);
}
/*********************************************************************
* @fn TMR3_CapInit
*
* @brief
*
* @param cap - select capture mode, refer to CapModeTypeDef
*
* @return none
*/
void TMR3_CapInit(CapModeTypeDef cap)
{
R8_TMR3_CTRL_MOD = RB_TMR_ALL_CLEAR;
R8_TMR3_CTRL_MOD = RB_TMR_COUNT_EN | RB_TMR_MODE_IN | (cap << 6);
}

View File

@ -0,0 +1,151 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_uart0.c
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* 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 "CH59x_common.h"
/*********************************************************************
* @fn UART0_DefInit
*
* @brief
*
* @param none
*
* @return none
*/
void UART0_DefInit(void)
{
UART0_BaudRateCfg(115200);
R8_UART0_FCR = (2 << 6) | RB_FCR_TX_FIFO_CLR | RB_FCR_RX_FIFO_CLR | RB_FCR_FIFO_EN; // FIFO打开触发点4字节
R8_UART0_LCR = RB_LCR_WORD_SZ;
R8_UART0_IER = RB_IER_TXD_EN;
R8_UART0_DIV = 1;
}
/*********************************************************************
* @fn UART0_BaudRateCfg
*
* @brief
*
* @param baudrate -
*
* @return none
*/
void UART0_BaudRateCfg(uint32_t baudrate)
{
uint32_t x;
x = 10 * GetSysClock() / 8 / baudrate;
x = (x + 5) / 10;
R16_UART0_DL = (uint16_t)x;
}
/*********************************************************************
* @fn UART0_ByteTrigCfg
*
* @brief
*
* @param b - refer to UARTByteTRIGTypeDef
*
* @return none
*/
void UART0_ByteTrigCfg(UARTByteTRIGTypeDef b)
{
R8_UART0_FCR = (R8_UART0_FCR & ~RB_FCR_FIFO_TRIG) | (b << 6);
}
/*********************************************************************
* @fn UART0_INTCfg
*
* @brief
*
* @param s - 使
* @param i -
* RB_IER_MODEM_CHG - 使 UART0
* RB_IER_LINE_STAT - 线
* RB_IER_THR_EMPTY -
* RB_IER_RECV_RDY -
*
* @return none
*/
void UART0_INTCfg(FunctionalState s, uint8_t i)
{
if(s)
{
R8_UART0_IER |= i;
R8_UART0_MCR |= RB_MCR_INT_OE;
}
else
{
R8_UART0_IER &= ~i;
}
}
/*********************************************************************
* @fn UART0_Reset
*
* @brief
*
* @param none
*
* @return none
*/
void UART0_Reset(void)
{
R8_UART0_IER = RB_IER_RESET;
}
/*********************************************************************
* @fn UART0_SendString
*
* @brief
*
* @param buf -
* @param l -
*
* @return none
*/
void UART0_SendString(uint8_t *buf, uint16_t l)
{
uint16_t len = l;
while(len)
{
if(R8_UART0_TFC != UART_FIFO_SIZE)
{
R8_UART0_THR = *buf++;
len--;
}
}
}
/*********************************************************************
* @fn UART0_RecvString
*
* @brief
*
* @param buf -
*
* @return
*/
uint16_t UART0_RecvString(uint8_t *buf)
{
uint16_t len = 0;
while(R8_UART0_RFC)
{
*buf++ = R8_UART0_RBR;
len++;
}
return (len);
}

View File

@ -0,0 +1,150 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_uart1.c
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* 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 "CH59x_common.h"
/*********************************************************************
* @fn UART1_DefInit
*
* @brief
*
* @param none
*
* @return none
*/
void UART1_DefInit(void)
{
UART1_BaudRateCfg(115200);
R8_UART1_FCR = (2 << 6) | RB_FCR_TX_FIFO_CLR | RB_FCR_RX_FIFO_CLR | RB_FCR_FIFO_EN; // FIFO打开触发点4字节
R8_UART1_LCR = RB_LCR_WORD_SZ;
R8_UART1_IER = RB_IER_TXD_EN;
R8_UART1_DIV = 1;
}
/*********************************************************************
* @fn UART1_BaudRateCfg
*
* @brief
*
* @param baudrate -
*
* @return none
*/
void UART1_BaudRateCfg(uint32_t baudrate)
{
uint32_t x;
x = 10 * GetSysClock() / 8 / baudrate;
x = (x + 5) / 10;
R16_UART1_DL = (uint16_t)x;
}
/*********************************************************************
* @fn UART1_ByteTrigCfg
*
* @brief
*
* @param b - refer to UARTByteTRIGTypeDef
*
* @return none
*/
void UART1_ByteTrigCfg(UARTByteTRIGTypeDef b)
{
R8_UART1_FCR = (R8_UART1_FCR & ~RB_FCR_FIFO_TRIG) | (b << 6);
}
/*********************************************************************
* @fn UART1_INTCfg
*
* @brief
*
* @param s - 使
* @param i -
* RB_IER_MODEM_CHG - 使 UART0
* RB_IER_LINE_STAT - 线
* RB_IER_THR_EMPTY -
* RB_IER_RECV_RDY -
*
* @return none
*/
void UART1_INTCfg(FunctionalState s, uint8_t i)
{
if(s)
{
R8_UART1_IER |= i;
R8_UART1_MCR |= RB_MCR_INT_OE;
}
else
{
R8_UART1_IER &= ~i;
}
}
/*********************************************************************
* @fn UART1_Reset
*
* @brief
*
* @param none
*
* @return none
*/
void UART1_Reset(void)
{
R8_UART1_IER = RB_IER_RESET;
}
/*********************************************************************
* @fn UART1_SendString
*
* @brief
*
* @param buf -
* @param l -
*
* @return none
*/
void UART1_SendString(uint8_t *buf, uint16_t l)
{
uint16_t len = l;
while(len)
{
if(R8_UART1_TFC != UART_FIFO_SIZE)
{
R8_UART1_THR = *buf++;
len--;
}
}
}
/*********************************************************************
* @fn UART1_RecvString
*
* @brief
*
* @param buf -
*
* @return
*/
uint16_t UART1_RecvString(uint8_t *buf)
{
uint16_t len = 0;
while(R8_UART1_RFC)
{
*buf++ = R8_UART1_RBR;
len++;
}
return (len);
}

View File

@ -0,0 +1,151 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_uart2.c
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* 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 "CH59x_common.h"
/*********************************************************************
* @fn UART2_DefInit
*
* @brief
*
* @param none
*
* @return none
*/
void UART2_DefInit(void)
{
UART2_BaudRateCfg(115200);
R8_UART2_FCR = (2 << 6) | RB_FCR_TX_FIFO_CLR | RB_FCR_RX_FIFO_CLR | RB_FCR_FIFO_EN; // FIFO打开触发点4字节
R8_UART2_LCR = RB_LCR_WORD_SZ;
R8_UART2_IER = RB_IER_TXD_EN;
R8_UART2_DIV = 1;
}
/*********************************************************************
* @fn UART2_BaudRateCfg
*
* @brief
*
* @param baudrate -
*
* @return none
*/
void UART2_BaudRateCfg(uint32_t baudrate)
{
uint32_t x;
x = 10 * GetSysClock() / 8 / baudrate;
x = (x + 5) / 10;
R16_UART2_DL = (uint16_t)x;
}
/*********************************************************************
* @fn UART2_ByteTrigCfg
*
* @brief
*
* @param b - refer to UARTByteTRIGTypeDef
*
* @return none
*/
void UART2_ByteTrigCfg(UARTByteTRIGTypeDef b)
{
R8_UART2_FCR = (R8_UART2_FCR & ~RB_FCR_FIFO_TRIG) | (b << 6);
}
/*********************************************************************
* @fn UART2_INTCfg
*
* @brief
*
* @param s - 使
* @param i -
* RB_IER_MODEM_CHG - 使 UART0
* RB_IER_LINE_STAT - 线
* RB_IER_THR_EMPTY -
* RB_IER_RECV_RDY -
*
* @return none
*/
void UART2_INTCfg(FunctionalState s, uint8_t i)
{
if(s)
{
R8_UART2_IER |= i;
R8_UART2_MCR |= RB_MCR_INT_OE;
}
else
{
R8_UART2_IER &= ~i;
}
}
/*********************************************************************
* @fn UART2_Reset
*
* @brief
*
* @param none
*
* @return none
*/
void UART2_Reset(void)
{
R8_UART2_IER = RB_IER_RESET;
}
/*********************************************************************
* @fn UART2_SendString
*
* @brief
*
* @param buf -
* @param l -
*
* @return none
*/
void UART2_SendString(uint8_t *buf, uint16_t l)
{
uint16_t len = l;
while(len)
{
if(R8_UART2_TFC != UART_FIFO_SIZE)
{
R8_UART2_THR = *buf++;
len--;
}
}
}
/*********************************************************************
* @fn UART2_RecvString
*
* @brief
*
* @param buf -
*
* @return
*/
uint16_t UART2_RecvString(uint8_t *buf)
{
uint16_t len = 0;
while(R8_UART2_RFC)
{
*buf++ = R8_UART2_RBR;
len++;
}
return (len);
}

View File

@ -0,0 +1,151 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_uart3.c
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* 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 "CH59x_common.h"
/*********************************************************************
* @fn UART3_DefInit
*
* @brief
*
* @param none
*
* @return none
*/
void UART3_DefInit(void)
{
UART3_BaudRateCfg(115200);
R8_UART3_FCR = (2 << 6) | RB_FCR_TX_FIFO_CLR | RB_FCR_RX_FIFO_CLR | RB_FCR_FIFO_EN; // FIFO打开触发点4字节
R8_UART3_LCR = RB_LCR_WORD_SZ;
R8_UART3_IER = RB_IER_TXD_EN;
R8_UART3_DIV = 1;
}
/*********************************************************************
* @fn UART3_BaudRateCfg
*
* @brief
*
* @param baudrate -
*
* @return none
*/
void UART3_BaudRateCfg(uint32_t baudrate)
{
uint32_t x;
x = 10 * GetSysClock() / 8 / baudrate;
x = (x + 5) / 10;
R16_UART3_DL = (uint16_t)x;
}
/*********************************************************************
* @fn UART3_ByteTrigCfg
*
* @brief
*
* @param b - refer to UARTByteTRIGTypeDef
*
* @return none
*/
void UART3_ByteTrigCfg(UARTByteTRIGTypeDef b)
{
R8_UART3_FCR = (R8_UART3_FCR & ~RB_FCR_FIFO_TRIG) | (b << 6);
}
/*********************************************************************
* @fn UART3_INTCfg
*
* @brief
*
* @param s - 使
* @param i -
* RB_IER_MODEM_CHG - 使 UART0
* RB_IER_LINE_STAT - 线
* RB_IER_THR_EMPTY -
* RB_IER_RECV_RDY -
*
* @return none
*/
void UART3_INTCfg(FunctionalState s, uint8_t i)
{
if(s)
{
R8_UART3_IER |= i;
R8_UART3_MCR |= RB_MCR_INT_OE;
}
else
{
R8_UART3_IER &= ~i;
}
}
/*********************************************************************
* @fn UART3_Reset
*
* @brief
*
* @param none
*
* @return none
*/
void UART3_Reset(void)
{
R8_UART3_IER = RB_IER_RESET;
}
/*********************************************************************
* @fn UART3_SendString
*
* @brief
*
* @param buf -
* @param l -
*
* @return none
*/
void UART3_SendString(uint8_t *buf, uint16_t l)
{
uint16_t len = l;
while(len)
{
if(R8_UART3_TFC != UART_FIFO_SIZE)
{
R8_UART3_THR = *buf++;
len--;
}
}
}
/*********************************************************************
* @fn UART3_RecvString
*
* @brief
*
* @param buf -
*
* @return
*/
uint16_t UART3_RecvString(uint8_t *buf)
{
uint16_t len = 0;
while(R8_UART3_RFC)
{
*buf++ = R8_UART3_RBR;
len++;
}
return (len);
}

View File

@ -0,0 +1,113 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_usbdev.c
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* 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 "CH59x_common.h"
uint8_t *pEP0_RAM_Addr;
uint8_t *pEP1_RAM_Addr;
uint8_t *pEP2_RAM_Addr;
uint8_t *pEP3_RAM_Addr;
/*********************************************************************
* @fn USB_DeviceInit
*
* @brief USB设备功能初始化48
*
* @param none
*
* @return none
*/
void USB_DeviceInit(void)
{
R8_USB_CTRL = 0x00; // 先设定模式,取消 RB_UC_CLR_ALL
R8_UEP4_1_MOD = RB_UEP4_RX_EN | RB_UEP4_TX_EN | RB_UEP1_RX_EN | RB_UEP1_TX_EN; // 端点4 OUT+IN,端点1 OUT+IN
R8_UEP2_3_MOD = RB_UEP2_RX_EN | RB_UEP2_TX_EN | RB_UEP3_RX_EN | RB_UEP3_TX_EN; // 端点2 OUT+IN,端点3 OUT+IN
R16_UEP0_DMA = (uint16_t)(uint32_t)pEP0_RAM_Addr;
R16_UEP1_DMA = (uint16_t)(uint32_t)pEP1_RAM_Addr;
R16_UEP2_DMA = (uint16_t)(uint32_t)pEP2_RAM_Addr;
R16_UEP3_DMA = (uint16_t)(uint32_t)pEP3_RAM_Addr;
R8_UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
R8_UEP1_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK | RB_UEP_AUTO_TOG;
R8_UEP2_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK | RB_UEP_AUTO_TOG;
R8_UEP3_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK | RB_UEP_AUTO_TOG;
R8_UEP4_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
R8_USB_DEV_AD = 0x00;
R8_USB_CTRL = RB_UC_DEV_PU_EN | RB_UC_INT_BUSY | RB_UC_DMA_EN; // 启动USB设备及DMA在中断期间中断标志未清除前自动返回NAK
R16_PIN_ANALOG_IE |= RB_PIN_USB_IE | RB_PIN_USB_DP_PU; // 防止USB端口浮空及上拉电阻
R8_USB_INT_FG = 0xFF; // 清中断标志
R8_UDEV_CTRL = RB_UD_PD_DIS | RB_UD_PORT_EN; // 允许USB端口
R8_USB_INT_EN = RB_UIE_SUSPEND | RB_UIE_BUS_RST | RB_UIE_TRANSFER;
}
/*********************************************************************
* @fn DevEP1_IN_Deal
*
* @brief 1
*
* @param l - (<64B)
*
* @return none
*/
void DevEP1_IN_Deal(uint8_t l)
{
R8_UEP1_T_LEN = l;
R8_UEP1_CTRL = (R8_UEP1_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_ACK;
}
/*********************************************************************
* @fn DevEP2_IN_Deal
*
* @brief 2
*
* @param l - (<64B)
*
* @return none
*/
void DevEP2_IN_Deal(uint8_t l)
{
R8_UEP2_T_LEN = l;
R8_UEP2_CTRL = (R8_UEP2_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_ACK;
}
/*********************************************************************
* @fn DevEP3_IN_Deal
*
* @brief 3
*
* @param l - (<64B)
*
* @return none
*/
void DevEP3_IN_Deal(uint8_t l)
{
R8_UEP3_T_LEN = l;
R8_UEP3_CTRL = (R8_UEP3_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_ACK;
}
/*********************************************************************
* @fn DevEP4_IN_Deal
*
* @brief 4
*
* @param l - (<64B)
*
* @return none
*/
void DevEP4_IN_Deal(uint8_t l)
{
R8_UEP4_T_LEN = l;
R8_UEP4_CTRL = (R8_UEP4_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_ACK;
}

View File

@ -0,0 +1,695 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_usbhost.c
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* 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 "CH59x_common.h"
#if DISK_LIB_ENABLE
#include "CHRV3UFI.H"
#endif
uint8_t UsbDevEndp0Size; // USB设备的端点0的最大包尺寸
uint8_t FoundNewDev;
_RootHubDev ThisUsbDev; //ROOT口
_DevOnHubPort DevOnHubPort[HUB_MAX_PORTS]; // 假定:不超过1个外部HUB,每个外部HUB不超过HUB_MAX_PORTS个端口(多了不管)
uint8_t *pHOST_RX_RAM_Addr;
uint8_t *pHOST_TX_RAM_Addr;
/*获取设备描述符*/
__attribute__((aligned(4))) const uint8_t SetupGetDevDescr[] = {USB_REQ_TYP_IN, USB_GET_DESCRIPTOR, 0x00,
USB_DESCR_TYP_DEVICE, 0x00, 0x00, sizeof(USB_DEV_DESCR), 0x00};
/*获取配置描述符*/
__attribute__((aligned(4))) const uint8_t SetupGetCfgDescr[] = {USB_REQ_TYP_IN, USB_GET_DESCRIPTOR, 0x00,
USB_DESCR_TYP_CONFIG, 0x00, 0x00, 0x04, 0x00};
/*设置USB地址*/
__attribute__((aligned(4))) const uint8_t SetupSetUsbAddr[] = {USB_REQ_TYP_OUT, USB_SET_ADDRESS, USB_DEVICE_ADDR, 0x00,
0x00, 0x00, 0x00, 0x00};
/*设置USB配置*/
__attribute__((aligned(4))) const uint8_t SetupSetUsbConfig[] = {USB_REQ_TYP_OUT, USB_SET_CONFIGURATION, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00};
/*设置USB接口配置*/
__attribute__((aligned(4))) const uint8_t SetupSetUsbInterface[] = {USB_REQ_RECIP_INTERF, USB_SET_INTERFACE, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00};
/*清除端点STALL*/
__attribute__((aligned(4))) const uint8_t SetupClrEndpStall[] = {USB_REQ_TYP_OUT | USB_REQ_RECIP_ENDP, USB_CLEAR_FEATURE,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
/*********************************************************************
* @fn DisableRootHubPort
*
* @brief ROOT-HUB端口,,
*
* @param none
*
* @return none
*/
void DisableRootHubPort(void)
{
#ifdef FOR_ROOT_UDISK_ONLY
CHRV3DiskStatus = DISK_DISCONNECT;
#endif
#ifndef DISK_BASE_BUF_LEN
ThisUsbDev.DeviceStatus = ROOT_DEV_DISCONNECT;
ThisUsbDev.DeviceAddress = 0x00;
#endif
}
/*********************************************************************
* @fn AnalyzeRootHub
*
* @brief ROOT-HUB状态,ROOT-HUB端口的设备插拔事件
* ,DisableRootHubPort(),,,
*
* @param none
*
* @return ERR_SUCCESS为没有情况,ERR_USB_CONNECT为检测到新连接,ERR_USB_DISCON为检测到断开
*/
uint8_t AnalyzeRootHub(void)
{
uint8_t s;
s = ERR_SUCCESS;
if(R8_USB_MIS_ST & RB_UMS_DEV_ATTACH)
{ // 设备存在
#ifdef DISK_BASE_BUF_LEN
if(CHRV3DiskStatus == DISK_DISCONNECT
#else
if(ThisUsbDev.DeviceStatus == ROOT_DEV_DISCONNECT // 检测到有设备插入
#endif
|| (R8_UHOST_CTRL & RB_UH_PORT_EN) == 0x00)
{ // 检测到有设备插入,但尚未允许,说明是刚插入
DisableRootHubPort(); // 关闭端口
#ifdef DISK_BASE_BUF_LEN
CHRV3DiskStatus = DISK_CONNECT;
#else
ThisUsbDev.DeviceSpeed = R8_USB_MIS_ST & RB_UMS_DM_LEVEL ? 0 : 1;
ThisUsbDev.DeviceStatus = ROOT_DEV_CONNECTED; //置连接标志
#endif
PRINT("USB dev in\n");
s = ERR_USB_CONNECT;
}
}
#ifdef DISK_BASE_BUF_LEN
else if(CHRV3DiskStatus >= DISK_CONNECT)
{
#else
else if(ThisUsbDev.DeviceStatus >= ROOT_DEV_CONNECTED)
{ //检测到设备拔出
#endif
DisableRootHubPort(); // 关闭端口
PRINT("USB dev out\n");
if(s == ERR_SUCCESS)
{
s = ERR_USB_DISCON;
}
}
// R8_USB_INT_FG = RB_UIF_DETECT; // 清中断标志
return (s);
}
/*********************************************************************
* @fn SetHostUsbAddr
*
* @brief USB主机当前操作的USB设备地址
*
* @param addr - USB设备地址
*
* @return none
*/
void SetHostUsbAddr(uint8_t addr)
{
R8_USB_DEV_AD = (R8_USB_DEV_AD & RB_UDA_GP_BIT) | (addr & MASK_USB_ADDR);
}
/*********************************************************************
* @fn SetUsbSpeed
*
* @brief USB速度
*
* @param FullSpeed - USB速度
*
* @return none
*/
void SetUsbSpeed(uint8_t FullSpeed)
{
#ifndef DISK_BASE_BUF_LEN
if(FullSpeed) // 全速
{
R8_USB_CTRL &= ~RB_UC_LOW_SPEED; // 全速
R8_UH_SETUP &= ~RB_UH_PRE_PID_EN; // 禁止PRE PID
}
else
{
R8_USB_CTRL |= RB_UC_LOW_SPEED; // 低速
}
#endif
(void)FullSpeed;
}
/*********************************************************************
* @fn ResetRootHubPort
*
* @brief ,线,,
*
* @param none
*
* @return none
*/
void ResetRootHubPort(void)
{
UsbDevEndp0Size = DEFAULT_ENDP0_SIZE; //USB设备的端点0的最大包尺寸
SetHostUsbAddr(0x00);
R8_UHOST_CTRL &= ~RB_UH_PORT_EN; // 关掉端口
SetUsbSpeed(1); // 默认为全速
R8_UHOST_CTRL = (R8_UHOST_CTRL & ~RB_UH_LOW_SPEED) | RB_UH_BUS_RESET; // 默认为全速,开始复位
mDelaymS(15); // 复位时间10mS到20mS
R8_UHOST_CTRL = R8_UHOST_CTRL & ~RB_UH_BUS_RESET; // 结束复位
mDelayuS(250);
R8_USB_INT_FG = RB_UIF_DETECT; // 清中断标志
}
/*********************************************************************
* @fn EnableRootHubPort
*
* @brief 使ROOT-HUB端口,bUH_PORT_EN置1开启端口,
*
* @param none
*
* @return ERR_SUCCESS为检测到新连接,ERR_USB_DISCON为无连接
*/
uint8_t EnableRootHubPort(void)
{
#ifdef DISK_BASE_BUF_LEN
if(CHRV3DiskStatus < DISK_CONNECT)
CHRV3DiskStatus = DISK_CONNECT;
#else
if(ThisUsbDev.DeviceStatus < ROOT_DEV_CONNECTED)
ThisUsbDev.DeviceStatus = ROOT_DEV_CONNECTED;
#endif
if(R8_USB_MIS_ST & RB_UMS_DEV_ATTACH)
{ // 有设备
#ifndef DISK_BASE_BUF_LEN
if((R8_UHOST_CTRL & RB_UH_PORT_EN) == 0x00)
{ // 尚未使能
ThisUsbDev.DeviceSpeed = (R8_USB_MIS_ST & RB_UMS_DM_LEVEL) ? 0 : 1;
if(ThisUsbDev.DeviceSpeed == 0)
{
R8_UHOST_CTRL |= RB_UH_LOW_SPEED; // 低速
}
}
#endif
R8_UHOST_CTRL |= RB_UH_PORT_EN; //使能HUB端口
return (ERR_SUCCESS);
}
return (ERR_USB_DISCON);
}
#ifndef DISK_BASE_BUF_LEN
/*********************************************************************
* @fn SelectHubPort
*
* @brief HUB口
*
* @param HubPortIndex - ROOT-HUB端口的外部HUB的指定端口
*
* @return None
*/
void SelectHubPort(uint8_t HubPortIndex)
{
if(HubPortIndex) // 选择操作指定的ROOT-HUB端口的外部HUB的指定端口
{
SetHostUsbAddr(DevOnHubPort[HubPortIndex - 1].DeviceAddress); // 设置USB主机当前操作的USB设备地址
SetUsbSpeed(DevOnHubPort[HubPortIndex - 1].DeviceSpeed); // 设置当前USB速度
if(DevOnHubPort[HubPortIndex - 1].DeviceSpeed == 0) // 通过外部HUB与低速USB设备通讯需要前置ID
{
R8_UEP1_CTRL |= RB_UH_PRE_PID_EN; // 启用PRE PID
mDelayuS(100);
}
}
else
{
SetHostUsbAddr(ThisUsbDev.DeviceAddress); // 设置USB主机当前操作的USB设备地址
SetUsbSpeed(ThisUsbDev.DeviceSpeed); // 设置USB设备的速度
}
}
#endif
/*********************************************************************
* @fn WaitUSB_Interrupt
*
* @brief USB中断
*
* @param none
*
* @return ERR_SUCCESS ,ERR_USB_UNKNOWN
*/
uint8_t WaitUSB_Interrupt(void)
{
uint16_t i;
for(i = WAIT_USB_TOUT_200US; i != 0 && (R8_USB_INT_FG & RB_UIF_TRANSFER) == 0; i--)
{
;
}
return ((R8_USB_INT_FG & RB_UIF_TRANSFER) ? ERR_SUCCESS : ERR_USB_UNKNOWN);
}
/*********************************************************************
* @fn USBHostTransact
*
* @brief ,/PID令牌,,20uS为单位的NAK重试总时间(0,0xFFFF),0,/
* ,,,
*
* @param endp_pid - , 4token_pid令牌, 4
* @param tog -
* @param timeout -
*
* @return ERR_USB_UNKNOWN
* ERR_USB_DISCON
* ERR_USB_CONNECT
* ERR_SUCCESS
*/
uint8_t USBHostTransact(uint8_t endp_pid, uint8_t tog, uint32_t timeout)
{
uint8_t TransRetry;
uint8_t s, r;
uint16_t i;
R8_UH_RX_CTRL = R8_UH_TX_CTRL = tog;
TransRetry = 0;
do
{
R8_UH_EP_PID = endp_pid; // 指定令牌PID和目的端点号
R8_USB_INT_FG = RB_UIF_TRANSFER;
for(i = WAIT_USB_TOUT_200US; i != 0 && (R8_USB_INT_FG & RB_UIF_TRANSFER) == 0; i--)
{
;
}
R8_UH_EP_PID = 0x00; // 停止USB传输
if((R8_USB_INT_FG & RB_UIF_TRANSFER) == 0)
{
return (ERR_USB_UNKNOWN);
}
if(R8_USB_INT_FG & RB_UIF_DETECT)
{ // USB设备插拔事件
// mDelayuS( 200 ); // 等待传输完成
R8_USB_INT_FG = RB_UIF_DETECT;
s = AnalyzeRootHub(); // 分析ROOT-HUB状态
if(s == ERR_USB_CONNECT)
FoundNewDev = 1;
#ifdef DISK_BASE_BUF_LEN
if(CHRV3DiskStatus == DISK_DISCONNECT)
{
return (ERR_USB_DISCON);
} // USB设备断开事件
if(CHRV3DiskStatus == DISK_CONNECT)
{
return (ERR_USB_CONNECT);
} // USB设备连接事件
#else
if(ThisUsbDev.DeviceStatus == ROOT_DEV_DISCONNECT)
{
return (ERR_USB_DISCON);
} // USB设备断开事件
if(ThisUsbDev.DeviceStatus == ROOT_DEV_CONNECTED)
{
return (ERR_USB_CONNECT);
} // USB设备连接事件
#endif
mDelayuS(200); // 等待传输完成
}
if(R8_USB_INT_FG & RB_UIF_TRANSFER) // 传输完成事件
{
if(R8_USB_INT_ST & RB_UIS_TOG_OK)
{
return (ERR_SUCCESS);
}
r = R8_USB_INT_ST & MASK_UIS_H_RES; // USB设备应答状态
if(r == USB_PID_STALL)
{
return (r | ERR_USB_TRANSFER);
}
if(r == USB_PID_NAK)
{
if(timeout == 0)
{
return (r | ERR_USB_TRANSFER);
}
if(timeout < 0xFFFFFFFF)
{
timeout--;
}
--TransRetry;
}
else
switch(endp_pid >> 4)
{
case USB_PID_SETUP:
case USB_PID_OUT:
if(r)
{
return (r | ERR_USB_TRANSFER);
} // 不是超时/出错,意外应答
break; // 超时重试
case USB_PID_IN:
if(r == USB_PID_DATA0 || r == USB_PID_DATA1)
{ // 不同步则需丢弃后重试
} // 不同步重试
else if(r)
{
return (r | ERR_USB_TRANSFER);
} // 不是超时/出错,意外应答
break; // 超时重试
default:
return (ERR_USB_UNKNOWN); // 不可能的情况
break;
}
}
else
{ // 其它中断,不应该发生的情况
R8_USB_INT_FG = 0xFF; /* 清中断标志 */
}
mDelayuS(15);
} while(++TransRetry < 3);
return (ERR_USB_TRANSFER); // 应答超时
}
/*********************************************************************
* @fn HostCtrlTransfer
*
* @brief ,8pSetupReq中,DataBuf为可选的收发缓冲区
*
* @param DataBuf - ,DataBuf需指向有效缓冲区用于存放后续数据
* @param RetLen - RetLen指向的字节变量中
*
* @return ERR_USB_BUF_OVER IN状态阶段出错
* ERR_SUCCESS
*/
uint8_t HostCtrlTransfer(uint8_t *DataBuf, uint8_t *RetLen)
{
uint16_t RemLen = 0;
uint8_t s, RxLen, RxCnt, TxCnt;
uint8_t *pBuf;
uint8_t *pLen;
pBuf = DataBuf;
pLen = RetLen;
mDelayuS(200);
if(pLen)
{
*pLen = 0; // 实际成功收发的总长度
}
R8_UH_TX_LEN = sizeof(USB_SETUP_REQ);
s = USBHostTransact(USB_PID_SETUP << 4 | 0x00, 0x00, 200000 / 20); // SETUP阶段,200mS超时
if(s != ERR_SUCCESS)
{
return (s);
}
R8_UH_RX_CTRL = R8_UH_TX_CTRL = RB_UH_R_TOG | RB_UH_R_AUTO_TOG | RB_UH_T_TOG | RB_UH_T_AUTO_TOG; // 默认DATA1
R8_UH_TX_LEN = 0x01; // 默认无数据故状态阶段为IN
RemLen = pSetupReq->wLength;
PRINT("wLength: %x\n", RemLen);
if(RemLen && pBuf) // 需要收发数据
{
PRINT("bRequestType: %x\n", pSetupReq->bRequestType);
if(pSetupReq->bRequestType & USB_REQ_TYP_IN) // 收
{
while(RemLen)
{
mDelayuS(200);
s = USBHostTransact(USB_PID_IN << 4 | 0x00, R8_UH_RX_CTRL, 200000 / 20); // IN数据
if(s != ERR_SUCCESS)
{
return (s);
}
RxLen = R8_USB_RX_LEN < RemLen ? R8_USB_RX_LEN : RemLen;
RemLen -= RxLen;
if(pLen)
{
*pLen += RxLen; // 实际成功收发的总长度
}
for(RxCnt = 0; RxCnt != RxLen; RxCnt++)
{
*pBuf = pHOST_RX_RAM_Addr[RxCnt];
pBuf++;
}
if(R8_USB_RX_LEN == 0 || (R8_USB_RX_LEN & (UsbDevEndp0Size - 1)))
{
break; // 短包
}
}
R8_UH_TX_LEN = 0x00; // 状态阶段为OUT
}
else // 发
{
while(RemLen)
{
mDelayuS(200);
R8_UH_TX_LEN = RemLen >= UsbDevEndp0Size ? UsbDevEndp0Size : RemLen;
for(TxCnt = 0; TxCnt != R8_UH_TX_LEN; TxCnt++)
{
pHOST_TX_RAM_Addr[TxCnt] = *pBuf;
pBuf++;
}
s = USBHostTransact(USB_PID_OUT << 4 | 0x00, R8_UH_TX_CTRL, 200000 / 20); // OUT数据
if(s != ERR_SUCCESS)
{
return (s);
}
RemLen -= R8_UH_TX_LEN;
if(pLen)
{
*pLen += R8_UH_TX_LEN; // 实际成功收发的总长度
}
}
PRINT("Send: %d\n", *pLen);
// R8_UH_TX_LEN = 0x01; // 状态阶段为IN
}
}
mDelayuS(200);
s = USBHostTransact((R8_UH_TX_LEN ? USB_PID_IN << 4 | 0x00 : USB_PID_OUT << 4 | 0x00), RB_UH_R_TOG | RB_UH_T_TOG, 200000 / 20); // STATUS阶段
if(s != ERR_SUCCESS)
{
return (s);
}
if(R8_UH_TX_LEN == 0)
{
return (ERR_SUCCESS); // 状态OUT
}
if(R8_USB_RX_LEN == 0)
{
return (ERR_SUCCESS); // 状态IN,检查IN状态返回数据长度
}
return (ERR_USB_BUF_OVER); // IN状态阶段错误
}
/*********************************************************************
* @fn CopySetupReqPkg
*
* @brief
*
* @param pReqPkt -
*
* @return none
*/
void CopySetupReqPkg(const uint8_t *pReqPkt) // 复制控制传输的请求包
{
uint8_t i;
for(i = 0; i != sizeof(USB_SETUP_REQ); i++)
{
((uint8_t *)pSetupReq)[i] = *pReqPkt;
pReqPkt++;
}
}
/*********************************************************************
* @fn CtrlGetDeviceDescr
*
* @brief , pHOST_TX_RAM_Addr
*
* @param none
*
* @return ERR_USB_BUF_OVER
* ERR_SUCCESS
*/
uint8_t CtrlGetDeviceDescr(void)
{
uint8_t s;
uint8_t len;
UsbDevEndp0Size = DEFAULT_ENDP0_SIZE;
CopySetupReqPkg(SetupGetDevDescr);
s = HostCtrlTransfer(Com_Buffer, &len); // 执行控制传输
if(s != ERR_SUCCESS)
{
return (s);
}
UsbDevEndp0Size = ((PUSB_DEV_DESCR)Com_Buffer)->bMaxPacketSize0; // 端点0最大包长度,这是简化处理,正常应该先获取前8字节后立即更新UsbDevEndp0Size再继续
if(len < ((PUSB_SETUP_REQ)SetupGetDevDescr)->wLength)
{
return (ERR_USB_BUF_OVER); // 描述符长度错误
}
return (ERR_SUCCESS);
}
/*********************************************************************
* @fn CtrlGetConfigDescr
*
* @brief , pHOST_TX_RAM_Addr
*
* @param none
*
* @return ERR_USB_BUF_OVER
* ERR_SUCCESS
*/
uint8_t CtrlGetConfigDescr(void)
{
uint8_t s;
uint8_t len;
CopySetupReqPkg(SetupGetCfgDescr);
s = HostCtrlTransfer(Com_Buffer, &len); // 执行控制传输
if(s != ERR_SUCCESS)
{
return (s);
}
if(len < ((PUSB_SETUP_REQ)SetupGetCfgDescr)->wLength)
{
return (ERR_USB_BUF_OVER); // 返回长度错误
}
len = ((PUSB_CFG_DESCR)Com_Buffer)->wTotalLength;
CopySetupReqPkg(SetupGetCfgDescr);
pSetupReq->wLength = len; // 完整配置描述符的总长度
s = HostCtrlTransfer(Com_Buffer, &len); // 执行控制传输
if(s != ERR_SUCCESS)
{
return (s);
}
#ifdef DISK_BASE_BUF_LEN
if(len > 64)
len = 64;
memcpy(TxBuffer, Com_Buffer, len); //U盘操作时需要拷贝到TxBuffer
#endif
return (ERR_SUCCESS);
}
/*********************************************************************
* @fn CtrlSetUsbAddress
*
* @brief USB设备地址
*
* @param addr -
*
* @return ERR_SUCCESS
*/
uint8_t CtrlSetUsbAddress(uint8_t addr)
{
uint8_t s;
CopySetupReqPkg(SetupSetUsbAddr);
pSetupReq->wValue = addr; // USB设备地址
s = HostCtrlTransfer(NULL, NULL); // 执行控制传输
if(s != ERR_SUCCESS)
{
return (s);
}
SetHostUsbAddr(addr); // 设置USB主机当前操作的USB设备地址
mDelaymS(10); // 等待USB设备完成操作
return (ERR_SUCCESS);
}
/*********************************************************************
* @fn CtrlSetUsbConfig
*
* @brief USB设备配置
*
* @param cfg -
*
* @return ERR_SUCCESS
*/
uint8_t CtrlSetUsbConfig(uint8_t cfg)
{
CopySetupReqPkg(SetupSetUsbConfig);
pSetupReq->wValue = cfg; // USB设备配置
return (HostCtrlTransfer(NULL, NULL)); // 执行控制传输
}
/*********************************************************************
* @fn CtrlClearEndpStall
*
* @brief STALL
*
* @param endp -
*
* @return ERR_SUCCESS
*/
uint8_t CtrlClearEndpStall(uint8_t endp)
{
CopySetupReqPkg(SetupClrEndpStall); // 清除端点的错误
pSetupReq->wIndex = endp; // 端点地址
return (HostCtrlTransfer(NULL, NULL)); // 执行控制传输
}
/*********************************************************************
* @fn CtrlSetUsbIntercace
*
* @brief USB设备接口
*
* @param cfg -
*
* @return ERR_SUCCESS
*/
uint8_t CtrlSetUsbIntercace(uint8_t cfg)
{
CopySetupReqPkg(SetupSetUsbInterface);
pSetupReq->wValue = cfg; // USB设备配置
return (HostCtrlTransfer(NULL, NULL)); // 执行控制传输
}
/*********************************************************************
* @fn USB_HostInit
*
* @brief USB主机功能初始化
*
* @param none
*
* @return none
*/
void USB_HostInit(void)
{
R8_USB_CTRL = RB_UC_HOST_MODE;
R8_UHOST_CTRL = 0;
R8_USB_DEV_AD = 0x00;
R8_UH_EP_MOD = RB_UH_EP_TX_EN | RB_UH_EP_RX_EN;
R16_UH_RX_DMA = (uint16_t)(uint32_t)pHOST_RX_RAM_Addr;
R16_UH_TX_DMA = (uint16_t)(uint32_t)pHOST_TX_RAM_Addr;
R8_UH_RX_CTRL = 0x00;
R8_UH_TX_CTRL = 0x00;
R8_USB_CTRL = RB_UC_HOST_MODE | RB_UC_INT_BUSY | RB_UC_DMA_EN;
R8_UH_SETUP = RB_UH_SOF_EN;
R8_USB_INT_FG = 0xFF;
DisableRootHubPort();
R8_USB_INT_EN = RB_UIE_TRANSFER | RB_UIE_DETECT;
FoundNewDev = 0;
}

View File

@ -0,0 +1,832 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_usbhost.c
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* 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 "CH59x_common.h"
#if DISK_LIB_ENABLE
#include "CHRV3UFI.H"
#endif
/* 设置HID上传速率 */
__attribute__((aligned(4))) const uint8_t SetupSetHIDIdle[] = {0x21, HID_SET_IDLE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
/* 获取HID设备报表描述符 */
__attribute__((aligned(4))) const uint8_t SetupGetHIDDevReport[] = {0x81, USB_GET_DESCRIPTOR, 0x00, USB_DESCR_TYP_REPORT,
0x00, 0x00, 0x41, 0x00};
/* 获取HUB描述符 */
__attribute__((aligned(4))) const uint8_t SetupGetHubDescr[] = {HUB_GET_HUB_DESCRIPTOR, HUB_GET_DESCRIPTOR, 0x00,
USB_DESCR_TYP_HUB, 0x00, 0x00, sizeof(USB_HUB_DESCR), 0x00};
__attribute__((aligned(4))) uint8_t Com_Buffer[128]; // 定义用户临时缓冲区,枚举时用于处理描述符,枚举结束也可以用作普通临时缓冲区
/*********************************************************************
* @fn AnalyzeHidIntEndp
*
* @brief HID中断端点的地址,HubPortIndex是0保存到ROOTHUBHUB下结构体
*
* @param buf - HubPortIndex0HUB0HUB下的端口号
*
* @return
*/
uint8_t AnalyzeHidIntEndp(uint8_t *buf, uint8_t HubPortIndex)
{
uint8_t i, s, l;
s = 0;
if(HubPortIndex)
{
memset(DevOnHubPort[HubPortIndex - 1].GpVar, 0, sizeof(DevOnHubPort[HubPortIndex - 1].GpVar)); //清空数组
}
else
{
memset(ThisUsbDev.GpVar, 0, sizeof(ThisUsbDev.GpVar)); //清空数组
}
for(i = 0; i < ((PUSB_CFG_DESCR)buf)->wTotalLength; i += l) // 搜索中断端点描述符,跳过配置描述符和接口描述符
{
if(((PUSB_ENDP_DESCR)(buf + i))->bDescriptorType == USB_DESCR_TYP_ENDP // 是端点描述符
&& (((PUSB_ENDP_DESCR)(buf + i))->bmAttributes & USB_ENDP_TYPE_MASK) == USB_ENDP_TYPE_INTER // 是中断端点
&& (((PUSB_ENDP_DESCR)(buf + i))->bEndpointAddress & USB_ENDP_DIR_MASK)) // 是IN端点
{ // 保存中断端点的地址,位7用于同步标志位,清0
if(HubPortIndex)
{
DevOnHubPort[HubPortIndex - 1].GpVar[s] = ((PUSB_ENDP_DESCR)(buf + i))->bEndpointAddress & USB_ENDP_ADDR_MASK;
}
else
{
ThisUsbDev.GpVar[s] = ((PUSB_ENDP_DESCR)(buf + i))->bEndpointAddress & USB_ENDP_ADDR_MASK; // 中断端点的地址可以根据需要保存wMaxPacketSize和bInterval
}
PRINT("%02x ", (uint16_t)ThisUsbDev.GpVar[s]);
s++;
if(s >= 4)
{
break; //只分析4个端点
}
}
l = ((PUSB_ENDP_DESCR)(buf + i))->bLength; // 当前描述符长度,跳过
if(l > 16)
{
break;
}
}
PRINT("\n");
return (s);
}
/*********************************************************************
* @fn AnalyzeBulkEndp
*
* @brief ,GpVar[0]GpVar[1]GpVar[2]GpVar[3]
*
* @param buf - HubPortIndex0HUB0HUB下的端口号
*
* @return 0
*/
uint8_t AnalyzeBulkEndp(uint8_t *buf, uint8_t HubPortIndex)
{
uint8_t i, s1, s2, l;
s1 = 0;
s2 = 2;
if(HubPortIndex)
{
memset(DevOnHubPort[HubPortIndex - 1].GpVar, 0, sizeof(DevOnHubPort[HubPortIndex - 1].GpVar)); //清空数组
}
else
{
memset(ThisUsbDev.GpVar, 0, sizeof(ThisUsbDev.GpVar)); //清空数组
}
for(i = 0; i < ((PUSB_CFG_DESCR)buf)->wTotalLength; i += l) // 搜索中断端点描述符,跳过配置描述符和接口描述符
{
if((((PUSB_ENDP_DESCR)(buf + i))->bDescriptorType == USB_DESCR_TYP_ENDP) // 是端点描述符
&& ((((PUSB_ENDP_DESCR)(buf + i))->bmAttributes & USB_ENDP_TYPE_MASK) == USB_ENDP_TYPE_BULK)) // 是中断端点
{
if(HubPortIndex)
{
if(((PUSB_ENDP_DESCR)(buf + i))->bEndpointAddress & USB_ENDP_DIR_MASK)
{
DevOnHubPort[HubPortIndex - 1].GpVar[s1++] = ((PUSB_ENDP_DESCR)(buf + i))->bEndpointAddress & USB_ENDP_ADDR_MASK;
}
else
{
DevOnHubPort[HubPortIndex - 1].GpVar[s2++] = ((PUSB_ENDP_DESCR)(buf + i))->bEndpointAddress & USB_ENDP_ADDR_MASK;
}
}
else
{
if(((PUSB_ENDP_DESCR)(buf + i))->bEndpointAddress & USB_ENDP_DIR_MASK)
{
ThisUsbDev.GpVar[s1++] = ((PUSB_ENDP_DESCR)(buf + i))->bEndpointAddress & USB_ENDP_ADDR_MASK;
}
else
{
ThisUsbDev.GpVar[s2++] = ((PUSB_ENDP_DESCR)(buf + i))->bEndpointAddress & USB_ENDP_ADDR_MASK;
}
}
if(s1 == 2)
{
s1 = 1;
}
if(s2 == 4)
{
s2 = 3;
}
}
l = ((PUSB_ENDP_DESCR)(buf + i))->bLength; // 当前描述符长度,跳过
if(l > 16)
{
break;
}
}
return (0);
}
/*********************************************************************
* @fn InitRootDevice
*
* @brief ROOT-HUB端口的USB设备
*
* @param none
*
* @return
*/
uint8_t InitRootDevice(void)
{
uint8_t i, s;
uint8_t cfg, dv_cls, if_cls;
PRINT("Reset host port\n");
ResetRootHubPort(); // 检测到设备后,复位相应端口的USB总线
for(i = 0, s = 0; i < 100; i++)
{ // 等待USB设备复位后重新连接,100mS超时
mDelaymS(1);
if(EnableRootHubPort() == ERR_SUCCESS)
{ // 使能端口
i = 0;
s++;
if(s > 100)
{
break; // 已经稳定连接100mS
}
}
}
if(i)
{ // 复位后设备没有连接
DisableRootHubPort();
PRINT("Disable host port because of disconnect\n");
return (ERR_USB_DISCON);
}
SetUsbSpeed(ThisUsbDev.DeviceSpeed); // 设置当前USB速度
PRINT("GetDevDescr: ");
s = CtrlGetDeviceDescr(); // 获取设备描述符
if(s == ERR_SUCCESS)
{
for(i = 0; i < ((PUSB_SETUP_REQ)SetupGetDevDescr)->wLength; i++)
{
PRINT("x%02X ", (uint16_t)(Com_Buffer[i]));
}
PRINT("\n");
ThisUsbDev.DeviceVID = ((PUSB_DEV_DESCR)Com_Buffer)->idVendor; //保存VID PID信息
ThisUsbDev.DevicePID = ((PUSB_DEV_DESCR)Com_Buffer)->idProduct;
dv_cls = ((PUSB_DEV_DESCR)Com_Buffer)->bDeviceClass;
s = CtrlSetUsbAddress(((PUSB_SETUP_REQ)SetupSetUsbAddr)->wValue);
if(s == ERR_SUCCESS)
{
ThisUsbDev.DeviceAddress = ((PUSB_SETUP_REQ)SetupSetUsbAddr)->wValue; // 保存USB地址
PRINT("GetCfgDescr: ");
s = CtrlGetConfigDescr();
if(s == ERR_SUCCESS)
{
for(i = 0; i < ((PUSB_CFG_DESCR)Com_Buffer)->wTotalLength; i++)
{
PRINT("x%02X ", (uint16_t)(Com_Buffer[i]));
}
PRINT("\n");
/* 分析配置描述符,获取端点数据/各端点地址/各端点大小等,更新变量endp_addr和endp_size等 */
cfg = ((PUSB_CFG_DESCR)Com_Buffer)->bConfigurationValue;
if_cls = ((PUSB_CFG_DESCR_LONG)Com_Buffer)->itf_descr.bInterfaceClass; // 接口类代码
if((dv_cls == 0x00) && (if_cls == USB_DEV_CLASS_STORAGE))
{ // 是USB存储类设备,基本上确认是U盘
#ifdef FOR_ROOT_UDISK_ONLY
CHRV3DiskStatus = DISK_USB_ADDR;
return (ERR_SUCCESS);
}
else
{
return (ERR_USB_UNSUPPORT);
}
#else
s = CtrlSetUsbConfig(cfg); // 设置USB设备配置
if(s == ERR_SUCCESS)
{
ThisUsbDev.DeviceStatus = ROOT_DEV_SUCCESS;
ThisUsbDev.DeviceType = USB_DEV_CLASS_STORAGE;
PRINT("USB-Disk Ready\n");
SetUsbSpeed(1); // 默认为全速
return (ERR_SUCCESS);
}
}
else if((dv_cls == 0x00) && (if_cls == USB_DEV_CLASS_PRINTER) && ((PUSB_CFG_DESCR_LONG)Com_Buffer)->itf_descr.bInterfaceSubClass == 0x01)
{ // 是打印机类设备
s = CtrlSetUsbConfig(cfg); // 设置USB设备配置
if(s == ERR_SUCCESS)
{
// 需保存端点信息以便主程序进行USB传输
ThisUsbDev.DeviceStatus = ROOT_DEV_SUCCESS;
ThisUsbDev.DeviceType = USB_DEV_CLASS_PRINTER;
PRINT("USB-Print Ready\n");
SetUsbSpeed(1); // 默认为全速
return (ERR_SUCCESS);
}
}
else if((dv_cls == 0x00) && (if_cls == USB_DEV_CLASS_HID) && ((PUSB_CFG_DESCR_LONG)Com_Buffer)->itf_descr.bInterfaceSubClass <= 0x01)
{ // 是HID类设备,键盘/鼠标等
// 从描述符中分析出HID中断端点的地址
s = AnalyzeHidIntEndp(Com_Buffer, 0); // 从描述符中分析出HID中断端点的地址
PRINT("AnalyzeHidIntEndp %02x\n", (uint16_t)s);
// 保存中断端点的地址,位7用于同步标志位,清0
if_cls = ((PUSB_CFG_DESCR_LONG)Com_Buffer)->itf_descr.bInterfaceProtocol;
s = CtrlSetUsbConfig(cfg); // 设置USB设备配置
if(s == ERR_SUCCESS)
{
// Set_Idle( );
// 需保存端点信息以便主程序进行USB传输
ThisUsbDev.DeviceStatus = ROOT_DEV_SUCCESS;
if(if_cls == 1)
{
ThisUsbDev.DeviceType = DEV_TYPE_KEYBOARD;
// 进一步初始化,例如设备键盘指示灯LED等
PRINT("USB-Keyboard Ready\n");
SetUsbSpeed(1); // 默认为全速
return (ERR_SUCCESS);
}
else if(if_cls == 2)
{
ThisUsbDev.DeviceType = DEV_TYPE_MOUSE;
// 为了以后查询鼠标状态,应该分析描述符,取得中断端口的地址,长度等信息
PRINT("USB-Mouse Ready\n");
SetUsbSpeed(1); // 默认为全速
return (ERR_SUCCESS);
}
s = ERR_USB_UNSUPPORT;
}
}
else if(dv_cls == USB_DEV_CLASS_HUB)
{ // 是HUB类设备,集线器等
s = CtrlGetHubDescr();
if(s == ERR_SUCCESS)
{
PRINT("Max Port:%02X ", (((PXUSB_HUB_DESCR)Com_Buffer)->bNbrPorts));
ThisUsbDev.GpHUBPortNum = ((PXUSB_HUB_DESCR)Com_Buffer)->bNbrPorts; // 保存HUB的端口数量
if(ThisUsbDev.GpHUBPortNum > HUB_MAX_PORTS)
{
ThisUsbDev.GpHUBPortNum = HUB_MAX_PORTS; // 因为定义结构DevOnHubPort时人为假定每个HUB不超过HUB_MAX_PORTS个端口
}
s = CtrlSetUsbConfig(cfg); // 设置USB设备配置
if(s == ERR_SUCCESS)
{
ThisUsbDev.DeviceStatus = ROOT_DEV_SUCCESS;
ThisUsbDev.DeviceType = USB_DEV_CLASS_HUB;
//需保存端点信息以便主程序进行USB传输,本来中断端点可用于HUB事件通知,但本程序使用查询状态控制传输代替
//给HUB各端口上电,查询各端口状态,初始化有设备连接的HUB端口,初始化设备
for(i = 1; i <= ThisUsbDev.GpHUBPortNum; i++) // 给HUB各端口都上电
{
DevOnHubPort[i - 1].DeviceStatus = ROOT_DEV_DISCONNECT; // 清外部HUB端口上设备的状态
s = HubSetPortFeature(i, HUB_PORT_POWER);
if(s != ERR_SUCCESS)
{
PRINT("Ext-HUB Port_%1d# power on error\n", (uint16_t)i); // 端口上电失败
}
}
PRINT("USB-HUB Ready\n");
SetUsbSpeed(1); // 默认为全速
return (ERR_SUCCESS);
}
}
}
else
{ // 可以进一步分析
s = CtrlSetUsbConfig(cfg); // 设置USB设备配置
if(s == ERR_SUCCESS)
{
// 需保存端点信息以便主程序进行USB传输
ThisUsbDev.DeviceStatus = ROOT_DEV_SUCCESS;
ThisUsbDev.DeviceType = DEV_TYPE_UNKNOW;
SetUsbSpeed(1); // 默认为全速
return (ERR_SUCCESS); /* 未知设备初始化成功 */
}
}
#endif
}
}
}
PRINT("InitRootDev Err = %02X\n", (uint16_t)s);
#ifdef FOR_ROOT_UDISK_ONLY
CHRV3DiskStatus = DISK_CONNECT;
#else
ThisUsbDev.DeviceStatus = ROOT_DEV_FAILED;
#endif
SetUsbSpeed(1); // 默认为全速
return (s);
}
/*********************************************************************
* @fn InitDevOnHub
*
* @brief HUB后的二级USB设备
*
* @param HubPortIndex - HUB
*
* @return
*/
uint8_t InitDevOnHub(uint8_t HubPortIndex)
{
uint8_t i, s, cfg, dv_cls, if_cls;
uint8_t ifc;
PRINT("Init dev @ExtHub-port_%1d ", (uint16_t)HubPortIndex);
if(HubPortIndex == 0)
{
return (ERR_USB_UNKNOWN);
}
SelectHubPort(HubPortIndex); // 选择操作指定的ROOT-HUB端口的外部HUB的指定端口,选择速度
PRINT("GetDevDescr: ");
s = CtrlGetDeviceDescr(); // 获取设备描述符
if(s != ERR_SUCCESS)
{
return (s);
}
DevOnHubPort[HubPortIndex - 1].DeviceVID = ((uint16_t)((PUSB_DEV_DESCR)Com_Buffer)->idVendor); //保存VID PID信息
DevOnHubPort[HubPortIndex - 1].DevicePID = ((uint16_t)((PUSB_DEV_DESCR)Com_Buffer)->idProduct);
dv_cls = ((PUSB_DEV_DESCR)Com_Buffer)->bDeviceClass; // 设备类代码
cfg = (1 << 4) + HubPortIndex; // 计算出一个USB地址,避免地址重叠
s = CtrlSetUsbAddress(cfg); // 设置USB设备地址
if(s != ERR_SUCCESS)
{
return (s);
}
DevOnHubPort[HubPortIndex - 1].DeviceAddress = cfg; // 保存分配的USB地址
PRINT("GetCfgDescr: ");
s = CtrlGetConfigDescr(); // 获取配置描述符
if(s != ERR_SUCCESS)
{
return (s);
}
cfg = ((PUSB_CFG_DESCR)Com_Buffer)->bConfigurationValue;
for(i = 0; i < ((PUSB_CFG_DESCR)Com_Buffer)->wTotalLength; i++)
{
PRINT("x%02X ", (uint16_t)(Com_Buffer[i]));
}
PRINT("\n");
/* 分析配置描述符,获取端点数据/各端点地址/各端点大小等,更新变量endp_addr和endp_size等 */
if_cls = ((PXUSB_CFG_DESCR_LONG)Com_Buffer)->itf_descr.bInterfaceClass; // 接口类代码
if(dv_cls == 0x00 && if_cls == USB_DEV_CLASS_STORAGE) // 是USB存储类设备,基本上确认是U盘
{
AnalyzeBulkEndp(Com_Buffer, HubPortIndex);
for(i = 0; i != 4; i++)
{
PRINT("%02x ", (uint16_t)DevOnHubPort[HubPortIndex - 1].GpVar[i]);
}
PRINT("\n");
s = CtrlSetUsbConfig(cfg); // 设置USB设备配置
if(s == ERR_SUCCESS)
{
DevOnHubPort[HubPortIndex - 1].DeviceStatus = ROOT_DEV_SUCCESS;
DevOnHubPort[HubPortIndex - 1].DeviceType = USB_DEV_CLASS_STORAGE;
PRINT("USB-Disk Ready\n");
SetUsbSpeed(1); // 默认为全速
return (ERR_SUCCESS);
}
}
else if((dv_cls == 0x00) && (if_cls == USB_DEV_CLASS_HID) && (((PXUSB_CFG_DESCR_LONG)Com_Buffer)->itf_descr.bInterfaceSubClass <= 0x01)) // 是HID类设备,键盘/鼠标等
{
ifc = ((PXUSB_CFG_DESCR_LONG)Com_Buffer)->cfg_descr.bNumInterfaces;
s = AnalyzeHidIntEndp(Com_Buffer, HubPortIndex); // 从描述符中分析出HID中断端点的地址
PRINT("AnalyzeHidIntEndp %02x\n", (uint16_t)s);
if_cls = ((PXUSB_CFG_DESCR_LONG)Com_Buffer)->itf_descr.bInterfaceProtocol;
s = CtrlSetUsbConfig(cfg); // 设置USB设备配置
if(s == ERR_SUCCESS)
{
for(dv_cls = 0; dv_cls < ifc; dv_cls++)
{
s = CtrlGetHIDDeviceReport(dv_cls); //获取报表描述符
if(s == ERR_SUCCESS)
{
for(i = 0; i < 64; i++)
{
PRINT("x%02X ", (uint16_t)(Com_Buffer[i]));
}
PRINT("\n");
}
}
//需保存端点信息以便主程序进行USB传输
DevOnHubPort[HubPortIndex - 1].DeviceStatus = ROOT_DEV_SUCCESS;
if(if_cls == 1)
{
DevOnHubPort[HubPortIndex - 1].DeviceType = DEV_TYPE_KEYBOARD;
//进一步初始化,例如设备键盘指示灯LED等
if(ifc > 1)
{
PRINT("USB_DEV_CLASS_HID Ready\n");
DevOnHubPort[HubPortIndex - 1].DeviceType = USB_DEV_CLASS_HID; //复合HID设备
}
PRINT("USB-Keyboard Ready\n");
SetUsbSpeed(1); // 默认为全速
return (ERR_SUCCESS);
}
else if(if_cls == 2)
{
DevOnHubPort[HubPortIndex - 1].DeviceType = DEV_TYPE_MOUSE;
//为了以后查询鼠标状态,应该分析描述符,取得中断端口的地址,长度等信息
if(ifc > 1)
{
PRINT("USB_DEV_CLASS_HID Ready\n");
DevOnHubPort[HubPortIndex - 1].DeviceType = USB_DEV_CLASS_HID; //复合HID设备
}
PRINT("USB-Mouse Ready\n");
SetUsbSpeed(1); // 默认为全速
return (ERR_SUCCESS);
}
s = ERR_USB_UNSUPPORT;
}
}
else if(dv_cls == USB_DEV_CLASS_HUB) // 是HUB类设备,集线器等
{
DevOnHubPort[HubPortIndex - 1].DeviceType = USB_DEV_CLASS_HUB;
PRINT("This program don't support Level 2 HUB\n"); // 需要支持多级HUB级联请参考本程序进行扩展
s = HubClearPortFeature(i, HUB_PORT_ENABLE); // 禁止HUB端口
if(s != ERR_SUCCESS)
{
return (s);
}
s = ERR_USB_UNSUPPORT;
}
else //其他设备
{
AnalyzeBulkEndp(Com_Buffer, HubPortIndex); //分析出批量端点
for(i = 0; i != 4; i++)
{
PRINT("%02x ", (uint16_t)DevOnHubPort[HubPortIndex - 1].GpVar[i]);
}
PRINT("\n");
s = CtrlSetUsbConfig(cfg); // 设置USB设备配置
if(s == ERR_SUCCESS)
{
//需保存端点信息以便主程序进行USB传输
DevOnHubPort[HubPortIndex - 1].DeviceStatus = ROOT_DEV_SUCCESS;
DevOnHubPort[HubPortIndex - 1].DeviceType = dv_cls ? dv_cls : if_cls;
SetUsbSpeed(1); // 默认为全速
return (ERR_SUCCESS); //未知设备初始化成功
}
}
PRINT("InitDevOnHub Err = %02X\n", (uint16_t)s);
DevOnHubPort[HubPortIndex - 1].DeviceStatus = ROOT_DEV_FAILED;
SetUsbSpeed(1); // 默认为全速
return (s);
}
/*********************************************************************
* @fn EnumHubPort
*
* @brief ROOT-HUB端口上的外部HUB集线器的各个端口,USB设备
*
* @param RootHubIndex - ROOT_HUB0和ROOT_HUB1
*
* @return
*/
uint8_t EnumHubPort()
{
uint8_t i, s;
for(i = 1; i <= ThisUsbDev.GpHUBPortNum; i++) // 查询集线器的端口是否有变化
{
SelectHubPort(0); // 选择操作指定的ROOT-HUB端口,设置当前USB速度以及被操作设备的USB地址
s = HubGetPortStatus(i); // 获取端口状态
if(s != ERR_SUCCESS)
{
return (s); // 可能是该HUB断开了
}
if(((Com_Buffer[0] & (1 << (HUB_PORT_CONNECTION & 0x07))) && (Com_Buffer[2] & (1 << (HUB_C_PORT_CONNECTION & 0x07)))) || (Com_Buffer[2] == 0x10))
{ // 发现有设备连接
DevOnHubPort[i - 1].DeviceStatus = ROOT_DEV_CONNECTED; // 有设备连接
DevOnHubPort[i - 1].DeviceAddress = 0x00;
s = HubGetPortStatus(i); // 获取端口状态
if(s != ERR_SUCCESS)
{
return (s); // 可能是该HUB断开了
}
DevOnHubPort[i - 1].DeviceSpeed = Com_Buffer[1] & (1 << (HUB_PORT_LOW_SPEED & 0x07)) ? 0 : 1; // 低速还是全速
if(DevOnHubPort[i - 1].DeviceSpeed)
{
PRINT("Found full speed device on port %1d\n", (uint16_t)i);
}
else
{
PRINT("Found low speed device on port %1d\n", (uint16_t)i);
}
mDelaymS(200); // 等待设备上电稳定
s = HubSetPortFeature(i, HUB_PORT_RESET); // 对有设备连接的端口复位
if(s != ERR_SUCCESS)
{
return (s); // 可能是该HUB断开了
}
PRINT("Reset port and then wait in\n");
do // 查询复位端口,直到复位完成,把完成后的状态显示出来
{
mDelaymS(1);
s = HubGetPortStatus(i);
if(s != ERR_SUCCESS)
{
return (s); // 可能是该HUB断开了
}
} while(Com_Buffer[0] & (1 << (HUB_PORT_RESET & 0x07))); // 端口正在复位则等待
mDelaymS(100);
s = HubClearPortFeature(i, HUB_C_PORT_RESET); // 清除复位完成标志
// s = HubSetPortFeature( i, HUB_PORT_ENABLE ); // 启用HUB端口
s = HubClearPortFeature(i, HUB_C_PORT_CONNECTION); // 清除连接或移除变化标志
if(s != ERR_SUCCESS)
{
return (s);
}
s = HubGetPortStatus(i); // 再读取状态,复查设备是否还在
if(s != ERR_SUCCESS)
{
return (s);
}
if((Com_Buffer[0] & (1 << (HUB_PORT_CONNECTION & 0x07))) == 0)
{
DevOnHubPort[i - 1].DeviceStatus = ROOT_DEV_DISCONNECT; // 设备不在了
}
s = InitDevOnHub(i); // 初始化二级USB设备
if(s != ERR_SUCCESS)
{
return (s);
}
SetUsbSpeed(1); // 默认为全速
}
else if(Com_Buffer[2] & (1 << (HUB_C_PORT_ENABLE & 0x07))) // 设备连接出错
{
HubClearPortFeature(i, HUB_C_PORT_ENABLE); // 清除连接错误标志
PRINT("Device on port error\n");
s = HubSetPortFeature(i, HUB_PORT_RESET); // 对有设备连接的端口复位
if(s != ERR_SUCCESS)
return (s); // 可能是该HUB断开了
do // 查询复位端口,直到复位完成,把完成后的状态显示出来
{
mDelaymS(1);
s = HubGetPortStatus(i);
if(s != ERR_SUCCESS)
return (s); // 可能是该HUB断开了
} while(Com_Buffer[0] & (1 << (HUB_PORT_RESET & 0x07))); // 端口正在复位则等待
}
else if((Com_Buffer[0] & (1 << (HUB_PORT_CONNECTION & 0x07))) == 0) // 设备已经断开
{
if(DevOnHubPort[i - 1].DeviceStatus >= ROOT_DEV_CONNECTED)
{
PRINT("Device on port %1d removed\n", (uint16_t)i);
}
DevOnHubPort[i - 1].DeviceStatus = ROOT_DEV_DISCONNECT; // 有设备连接
if(Com_Buffer[2] & (1 << (HUB_C_PORT_CONNECTION & 0x07)))
{
HubClearPortFeature(i, HUB_C_PORT_CONNECTION); // 清除移除变化标志
}
}
}
return (ERR_SUCCESS); // 返回操作成功
}
/*********************************************************************
* @fn EnumAllHubPort
*
* @brief ROOT-HUB端口下外部HUB后的二级USB设备
*
* @return
*/
uint8_t EnumAllHubPort(void)
{
uint8_t s;
if((ThisUsbDev.DeviceStatus >= ROOT_DEV_SUCCESS) && (ThisUsbDev.DeviceType == USB_DEV_CLASS_HUB)) // HUB枚举成功
{
SelectHubPort(0); // 选择操作指定的ROOT-HUB端口,设置当前USB速度以及被操作设备的USB地址
s = EnumHubPort(); // 枚举指定ROOT-HUB端口上的外部HUB集线器的各个端口,检查各端口有无连接或移除事件
if(s != ERR_SUCCESS) // 可能是HUB断开了
{
PRINT("EnumAllHubPort err = %02X\n", (uint16_t)s);
}
SetUsbSpeed(1); // 默认为全速
}
return (ERR_SUCCESS);
}
/*********************************************************************
* @fn SearchTypeDevice
*
* @brief ROOT-HUB以及外部HUB各端口上搜索指定类型的设备所在的端口号,0xFFFF.
* USB的厂商VID产品PID进行搜索(VID和PID),
*
* @param type -
*
* @return 8ROOT-HUB端口号,8HUB的端口号,80ROOT-HUB端口上
*/
uint16_t SearchTypeDevice(uint8_t type)
{
uint8_t RootHubIndex; //CH554只有一个USB口,RootHubIndex = 0,只需看返回值的低八位即可
uint8_t HubPortIndex;
RootHubIndex = 0;
if((ThisUsbDev.DeviceType == USB_DEV_CLASS_HUB) && (ThisUsbDev.DeviceStatus >= ROOT_DEV_SUCCESS)) // 外部集线器HUB且枚举成功
{
for(HubPortIndex = 1; HubPortIndex <= ThisUsbDev.GpHUBPortNum; HubPortIndex++) // 搜索外部HUB的各个端口
{
if(DevOnHubPort[HubPortIndex - 1].DeviceType == type && DevOnHubPort[HubPortIndex - 1].DeviceStatus >= ROOT_DEV_SUCCESS)
{
return (((uint16_t)RootHubIndex << 8) | HubPortIndex); // 类型匹配且枚举成功
}
}
}
if((ThisUsbDev.DeviceType == type) && (ThisUsbDev.DeviceStatus >= ROOT_DEV_SUCCESS))
{
return ((uint16_t)RootHubIndex << 8); // 类型匹配且枚举成功,在ROOT-HUB端口上
}
return (0xFFFF);
}
/*********************************************************************
* @fn SETorOFFNumLock
*
* @brief NumLock的点灯判断
*
* @param buf -
*
* @return
*/
uint8_t SETorOFFNumLock(uint8_t *buf)
{
uint8_t tmp[] = {0x21, 0x09, 0x00, 0x02, 0x00, 0x00, 0x01, 0x00};
uint8_t len, s;
if((buf[2] == 0x53) & ((buf[0] | buf[1] | buf[3] | buf[4] | buf[5] | buf[6] | buf[7]) == 0))
{
for(s = 0; s != sizeof(tmp); s++)
{
((uint8_t *)pSetupReq)[s] = tmp[s];
}
s = HostCtrlTransfer(Com_Buffer, &len); // 执行控制传输
if(s != ERR_SUCCESS)
{
return (s);
}
}
return (ERR_SUCCESS);
}
/*********************************************************************
* @fn CtrlGetHIDDeviceReport
*
* @brief HID设备报表描述符,TxBuffer中
*
* @param none
*
* @return
*/
uint8_t CtrlGetHIDDeviceReport(uint8_t infc)
{
uint8_t s;
uint8_t len;
CopySetupReqPkg(SetupSetHIDIdle);
pSetupReq->wIndex = infc;
s = HostCtrlTransfer(Com_Buffer, &len); // 执行控制传输
if(s != ERR_SUCCESS)
{
return (s);
}
CopySetupReqPkg(SetupGetHIDDevReport);
pSetupReq->wIndex = infc;
s = HostCtrlTransfer(Com_Buffer, &len); // 执行控制传输
if(s != ERR_SUCCESS)
{
return (s);
}
return (ERR_SUCCESS);
}
/*********************************************************************
* @fn CtrlGetHubDescr
*
* @brief HUB描述符,Com_Buffer中
*
* @param none
*
* @return
*/
uint8_t CtrlGetHubDescr(void)
{
uint8_t s;
uint8_t len;
CopySetupReqPkg(SetupGetHubDescr);
s = HostCtrlTransfer(Com_Buffer, &len); // 执行控制传输
if(s != ERR_SUCCESS)
{
return (s);
}
if(len < ((PUSB_SETUP_REQ)SetupGetHubDescr)->wLength)
{
return (ERR_USB_BUF_OVER); // 描述符长度错误
}
// if ( len < 4 ) return( ERR_USB_BUF_OVER ); // 描述符长度错误
return (ERR_SUCCESS);
}
/*********************************************************************
* @fn HubGetPortStatus
*
* @brief HUB端口状态,Com_Buffer中
*
* @param HubPortIndex -
*
* @return
*/
uint8_t HubGetPortStatus(uint8_t HubPortIndex)
{
uint8_t s;
uint8_t len;
pSetupReq->bRequestType = HUB_GET_PORT_STATUS;
pSetupReq->bRequest = HUB_GET_STATUS;
pSetupReq->wValue = 0x0000;
pSetupReq->wIndex = 0x0000 | HubPortIndex;
pSetupReq->wLength = 0x0004;
s = HostCtrlTransfer(Com_Buffer, &len); // 执行控制传输
if(s != ERR_SUCCESS)
{
return (s);
}
if(len < 4)
{
return (ERR_USB_BUF_OVER); // 描述符长度错误
}
return (ERR_SUCCESS);
}
/*********************************************************************
* @fn HubSetPortFeature
*
* @brief HUB端口特性
*
* @param HubPortIndex -
* @param FeatureSelt -
*
* @return
*/
uint8_t HubSetPortFeature(uint8_t HubPortIndex, uint8_t FeatureSelt)
{
pSetupReq->bRequestType = HUB_SET_PORT_FEATURE;
pSetupReq->bRequest = HUB_SET_FEATURE;
pSetupReq->wValue = 0x0000 | FeatureSelt;
pSetupReq->wIndex = 0x0000 | HubPortIndex;
pSetupReq->wLength = 0x0000;
return (HostCtrlTransfer(NULL, NULL)); // 执行控制传输
}
/*********************************************************************
* @fn HubClearPortFeature
*
* @brief HUB端口特性
*
* @param HubPortIndex -
* @param FeatureSelt -
*
* @return
*/
uint8_t HubClearPortFeature(uint8_t HubPortIndex, uint8_t FeatureSelt)
{
pSetupReq->bRequestType = HUB_CLEAR_PORT_FEATURE;
pSetupReq->bRequest = HUB_CLEAR_FEATURE;
pSetupReq->wValue = 0x0000 | FeatureSelt;
pSetupReq->wIndex = 0x0000 | HubPortIndex;
pSetupReq->wLength = 0x0000;
return (HostCtrlTransfer(NULL, NULL)); // 执行控制传输
}

View File

@ -0,0 +1,1848 @@
/* Define for CH592 */
/* Website: http://wch.cn */
/* Email: tech@wch.cn */
/* Author: W.ch 2023.02 */
/* V0.2 SpecialFunctionRegister */
// multi-blocks: __BASE_TYPE__, __CH592SFR_H__, __CH592USBSFR_H__, __USB_TYPE__...
#ifndef __BASE_TYPE__
#define __BASE_TYPE__
#ifdef __cplusplus
extern "C" {
#endif
/* ********************************************************************************************************************* */
/* Base types & constants */
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
#ifndef NULL
#define NULL 0
#endif
#ifndef VOID
#define VOID void
#endif
#ifndef CONST
#define CONST const
#endif
#ifndef BOOL
typedef unsigned char BOOL;
#endif
#ifndef BOOLEAN
typedef unsigned char BOOLEAN;
#endif
#ifndef CHAR
typedef char CHAR;
#endif
#ifndef INT8
typedef char INT8;
#endif
#ifndef INT16
typedef short INT16;
#endif
#ifndef INT32
typedef long INT32;
#endif
#ifndef UINT8
typedef unsigned char UINT8;
#endif
#ifndef UINT16
typedef unsigned short UINT16;
#endif
#ifndef UINT32
typedef unsigned long UINT32;
#endif
#ifndef UINT64
typedef unsigned long long UINT64;
#endif
#ifndef UINT8V
typedef unsigned char volatile UINT8V;
#endif
#ifndef UINT16V
typedef unsigned short volatile UINT16V;
#endif
#ifndef UINT32V
typedef unsigned long volatile UINT32V;
#endif
#ifndef UINT64V
typedef unsigned long long volatile UINT64V;
#endif
#ifndef PVOID
typedef void *PVOID;
#endif
#ifndef PCHAR
typedef char *PCHAR;
#endif
#ifndef PCHAR
typedef const char *PCCHAR;
#endif
#ifndef PINT8
typedef char *PINT8;
#endif
#ifndef PINT16
typedef short *PINT16;
#endif
#ifndef PINT32
typedef long *PINT32;
#endif
#ifndef PUINT8
typedef unsigned char *PUINT8;
#endif
#ifndef PUINT16
typedef unsigned short *PUINT16;
#endif
#ifndef PUINT32
typedef unsigned long *PUINT32;
#endif
#ifndef PUINT8V
typedef volatile unsigned char *PUINT8V;
#endif
#ifndef PUINT16V
typedef volatile unsigned short *PUINT16V;
#endif
#ifndef PUINT32V
typedef volatile unsigned long *PUINT32V;
#endif
#ifndef PUINT64V
typedef volatile unsigned long long *PUINT64V;
#endif
/* ********************************************************************************************************************* */
/* Base macros */
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif
#ifdef DEBUG
#define PRINT(X...) printf(X)
#else
#define PRINT(X...)
#endif
/* Calculate the byte offset of a field in a structure of type */
#define FIELD_OFFSET(Type, Field) ((UINT16)&(((Type *)0)->Field))
/* Calculate the size of a field in a structure of type */
#define FIELD_SIZE(Type, Field) (sizeof(((Type *)0)->Field))
/* An expression that yields the type of a field in a struct */
#define FIELD_TYPE(Type, Field) (((Type *)0)->Field)
/* Return the number of elements in a statically sized array */
#define NUMBER_OF(Array) (sizeof(Array)/sizeof((Array)[0]))
#define NUMBER_OF_FIELD(Type, Field) (NUMBER_OF(FIELD_TYPE(Type, Field)))
#ifdef __cplusplus
}
#endif
#endif // __BASE_TYPE__
#ifndef __CH592SFR_H__
#define __CH592SFR_H__
#ifdef __cplusplus
extern "C" {
#endif
/* ********************************************************************************************************************* */
// Address Space
// CODE: 00000000H - 0007FFFFH 512K
// DATA: 20000000H - 20007FFFH 32KB
// SFR: 40000000H - 4000FFFFH 64KB
//
// SFR: 40000000H - 4000FFFFH, 64KB
// SYS: +1000H - 1BFFH, include base configuration, interrupt, GPIO, etc...
// TMR0: +2000H - 23FFH
// TMR1: +2400H - 27FFH
// TMR2: +2800H - 2BFFH
// TMR3: +2C00H - 2FFFH
// UART0: +3000H - 33FFH
// UART1: +3400H - 37FFH
// UART2: +3800H - 3BFFH
// UART3: +3C00H - 3FFFH
// SPI0: +4000H - 43FFH
// I2C: +4800H - 4BFFH
// PWMx: +5000H - 53FFH
// LCD: +6000H - 63FFH
// USB: +8000H - 83FFH
// BLE: +C000H - D3FFH
// Register Bit Attribute / Bit Access Type
// RF: Read only for Fixed value
// RO: Read Only (internal change)
// RZ: Read only with auto clear Zero
// WO: Write Only (read zero or different)
// WA: Write only under safe Accessing mode (read zero or different)
// WZ: Write only with auto clear Zero
// RW: Read / Write
// RWA: Read / Write under safe Accessing mode
// RW1: Read / Write 1 to Clear
/* Register name rule:
R32_* for 32 bits register (UINT32,ULONG)
R16_* for 16 bits register (UINT16,USHORT)
R8_* for 8 bits register (UINT8,UCHAR)
RB_* for bit or bit mask of 8 bit register
BA_* for base address point
b* for GPIO bit mask
Others for register address offset */
/* ********************************************************************************************************************* */
/* Independent watch-dog register */
#define R32_IWDG_KR (*((PUINT32V)0x40001000)) // WO, watch-dog key register
#define R32_IWDG_CFG (*((PUINT32V)0x40001004)) // RW, watch-dog configuration
#define RB_RLR 0x0FFF // RW, watch-dog counter reload (write protect)
#define RB_PR 0x7000 // PR, prescale (write protect)
#define RB_PVU 0x8000 // RO, register update flag (write protect)
#define RB_COUNT 0xFF0000 // RO, watch-dog down counter
#define RB_STOP_EN 0x20000000 // RW, watch-dog stop enable (write protect)
#define RB_WR_PROTECT 0x40000000 // RO, write protect
#define RB_IWDG_EN 0x80000000 // RO, watch-dog enable
/* System: safe accessing register */
#define R32_SAFE_ACCESS (*((PUINT32V)0x40001040)) // RW, safe accessing
#define R8_SAFE_ACCESS_SIG (*((PUINT8V)0x40001040)) // WO, safe accessing sign register, must write SAFE_ACCESS_SIG1 then SAFE_ACCESS_SIG2 to enter safe accessing mode
#define RB_SAFE_ACC_MODE 0x03 // RO, current safe accessing mode: 11=safe/unlocked (SAM), other=locked (00..01..10..11)
#define RB_SAFE_ACC_ACT 0x08 // RO, indicate safe accessing status now: 0=locked, read only, 1=safe/unlocked (SAM), write enabled
#define RB_SAFE_ACC_TIMER 0x70 // RO, safe accessing timer bit mask (16*clock number)
#define SAFE_ACCESS_SIG1 0x57 // WO: safe accessing sign value step 1
#define SAFE_ACCESS_SIG2 0xA8 // WO: safe accessing sign value step 2
#define SAFE_ACCESS_SIG0 0x00 // WO: safe accessing sign value for disable
#define R8_CHIP_ID (*((PUINT8V)0x40001041)) // RF, chip ID register, always is ID_CH58*
#define R8_SAFE_ACCESS_ID (*((PUINT8V)0x40001042)) // RF, safe accessing ID register, always 0x0C
#define R8_WDOG_COUNT (*((PUINT8V)0x40001043)) // RW, watch-dog count, count by clock frequency Fsys/131072
/* System: global configuration register */
#define R32_GLOBAL_CONFIG (*((PUINT32V)0x40001044)) // RW, global configuration
#define R8_RESET_STATUS (*((PUINT8V)0x40001044)) // RO, reset status
#define RB_RESET_FLAG 0x07 // RO: recent reset flag
#define RST_FLAG_SW 0x00
#define RST_FLAG_RPOR 0x01
#define RST_FLAG_WTR 0x02
#define RST_FLAG_MR 0x03
//#define RST_FLAG_GPWSM 0x04 // RO, power on reset flag during sleep/shutdown: 0=no power on reset during sleep/shutdown, 1=power on reset occurred during sleep/shutdown
#define RST_FLAG_GPWSM 0x05
// RB_RESET_FLAG: recent reset flag
// 000 - SR, software reset, by RB_SOFTWARE_RESET=1 @RB_WDOG_RST_EN=0
// 001 - RPOR, real power on reset
// 010 - WTR, watch-dog timer-out reset
// 011 - MR, external manual reset by RST pin input low
// 101 - GRWSM, global reset by waking under shutdown mode
// 1?? - LRW, power on reset occurred during sleep
#define R8_GLOB_ROM_CFG R8_RESET_STATUS // RWA, flash ROM configuration, SAM
#define RB_ROM_CODE_OFS 0x10 // RWA, code offset address selection in Flash ROM: 0=start address 0x000000, 1=start address 0x040000
#define RB_ROM_CTRL_EN 0x20 // RWA, enable flash ROM control interface enable: 0=disable access, 1=enable access control register
#define RB_ROM_DATA_WE 0x40 // RWA, enable flash ROM data & code area being erase/write: 0=all writing protect, 1=enable data area program and erase
#define RB_ROM_CODE_WE 0x80 // RWA, enable flash ROM code area being erase/write: 0=code writing protect, 1=enable code area program and erase
#define R8_GLOB_CFG_INFO (*((PUINT8V)0x40001045)) // RO, global configuration information and status
#define RB_CFG_ROM_READ 0x01 // RO, indicate protected status of Flash ROM code and data: 0=reading protect, 1=enable read by external programmer
#define RB_CFG_RESET_EN 0x04 // RO, manual reset input enable status
#define RB_CFG_BOOT_EN 0x08 // RO, boot-loader enable status
#define RB_CFG_DEBUG_EN 0x10 // RO, debug enable status
#define RB_BOOT_LOADER 0x20 // RO, indicate boot loader status: 0=application status (by software reset), 1=boot loader status
#define R8_RST_WDOG_CTRL (*((PUINT8V)0x40001046)) // RWA, reset and watch-dog control, SAM
#define RB_SOFTWARE_RESET 0x01 // WA/WZ, global software reset, high action, auto clear
#define RB_WDOG_RST_EN 0x02 // RWA, enable watch-dog reset if watch-dog timer overflow: 0=as timer only, 1=enable reset if timer overflow
#define RB_WDOG_INT_EN 0x04 // RWA, watch-dog timer overflow interrupt enable: 0=disable, 1=enable
#define RB_WDOG_INT_FLAG 0x10 // RW1, watch-dog timer overflow interrupt flag, cleared by RW1 or reload watch-dog count or __SEV(Send-Event)
#define R8_GLOB_RESET_KEEP (*((PUINT8V)0x40001047)) // RW, value keeper during global reset
/* System: clock configuration register */
#define R32_CLOCK_CONFIG (*((PUINT32V)0x40001008)) // RWA, clock configuration, SAM
#define R32_CLK_SYS_CFG (*((PUINT32V)0x40001008)) // RWA, system clock configuration, SAM
#define RB_CLK_PLL_DIV 0x1F // RWA, output clock divider from PLL or CK32M
#define RB_CLK_SYS_MOD 0xC0 // RWA, system clock source mode: 00=divided from 32MHz, 01=divided from PLL-480MHz, 10=directly from 32MHz, 11=directly from 32KHz
#define RB_TX_32M_PWR_EN 0x40000 // RWA, extern 32MHz HSE power contorl
#define RB_XT_FORCE_EN 0x80000 // RWA, system clock control in Halt mode
#define RB_PLL_PWR_EN 0x100000 // RWA, PLL power control
// Fck32k = RB_CLK_OSC32K_XT ? XT_32KHz : RC_32KHz
// Fpll = XT_32MHz * 15 = 480MHz
// Fsys = RB_CLK_SYS_MOD==3 ? Fck32k : ( ( RB_CLK_SYS_MOD[0] ? Fpll : XT_32MHz ) / RB_CLK_PLL_DIV )
// default: Fsys = XT_32MHz / RB_CLK_PLL_DIV = 32MHz / 5 = 6.4MHz
// range: 32KHz, 2MHz~10MHz, 15MHz~80MHz
/* System: sleep control register */
#define R32_SLEEP_CONTROL (*((PUINT32V)0x4000100C)) // RWA, sleep control, SAM
#define R8_SLP_CLK_OFF0 (*((PUINT8V)0x4000100C)) // RWA, sleep clock off control byte 0, SAM
#define RB_SLP_CLK_TMR0 0x01 // RWA, close TMR0 clock
#define RB_SLP_CLK_TMR1 0x02 // RWA, close TMR1 clock
#define RB_SLP_CLK_TMR2 0x04 // RWA, close TMR2 clock
#define RB_SLP_CLK_TMR3 0x08 // RWA, close TMR3 clock
#define RB_SLP_CLK_UART0 0x10 // RWA, close UART0 clock
#define RB_SLP_CLK_UART1 0x20 // RWA, close UART1 clock
#define RB_SLP_CLK_UART2 0x40 // RWA, close UART2 clock
#define RB_SLP_CLK_UART3 0x80 // RWA, close UART3 clock
#define R8_SLP_CLK_OFF1 (*((PUINT8V)0x4000100D)) // RWA, sleep clock off control byte 1, SAM
#define RB_SLP_CLK_SPI0 0x01 // RWA, close SPI0 clock
#define RB_SLP_CLK_PWMX 0x04 // RWA, close PWMx clock
#define RB_SLP_CLK_I2C 0x08 // RWA, close I2C clock
#define RB_SLP_CLK_USB 0x10 // RWA, close USB clock
#define RB_SLP_CLK_LCD 0x40 // RWA, close LCD clock
#define RB_SLP_CLK_BLE 0x80 // RWA, close BLE clock
#define R8_SLP_WAKE_CTRL (*((PUINT8V)0x4000100E)) // RWA, wake control, SAM
#define RB_SLP_USB_WAKE 0x01 // RWA, enable USB waking
//#define RB_SLP_BLE_WAKE 0x04 // RWA, enable BLE waking
#define RB_SLP_RTC_WAKE 0x08 // RWA, enable RTC waking
#define RB_SLP_GPIO_WAKE 0x10 // RWA, enable GPIO waking
#define RB_SLP_BAT_WAKE 0x20 // RWA, enable BAT waking
#define RB_WAKE_EV_MODE 0x40 // RWA, event wakeup mode: 0=event keep valid for long time, 1=short pulse event
#define RB_GPIO_WAKE_MODE 0x80 // RWA,
#define R8_SLP_POWER_CTRL (*((PUINT8V)0x4000100F)) // RWA, peripherals power down control, SAM
#define RB_WAKE_DLY_MOD 0x03 // RWA, wakeup delay time selection
// RB_WAKE_DLY_MOD select wakeup delay
// 00: long time, 3590 cycles+TSUHSE
// 01: short time, 520 cycles+TSUHSE
// 10: shorter time, 70 cycles+TSUHSE
// 11: no delay, 8 cycles+TSUHSE
//#define RB_SLP_USB_PWR_DN 0x01 // RWA, enable USB power down
//#define RB_SLP_BLE_PWR_DN 0x04 // RWA, enable BLE power down
#define RB_SLP_CLK_RAMX 0x10 // RWA, close main SRAM clock
#define RB_SLP_CLK_RAM2K 0x20 // RWA, close retention 2KB SRAM clock
#define RB_RAM_RET_LV 0x40 // RWA, SRAM retention voltage selection: 0=normal, 1=low voltage for low power
#define R32_SLEEP_CTRL2 (*((PUINT32V)0x40001010)) // RWA, touchkey wake up enable
#define RB_TKEY0_5_WAKE_EN 0x003F // RWA, touchkey wake up enable channel 0-5
#define RB_TKEY8_13_WAKE_EN 0x3F00 // RWA, touchkey wake up enable channel 8-13
/* System: I/O pin configuration register */
#define R32_PIN_CONFIG (*((PUINT32V)0x40001018)) // RW, I/O pin configuration
#define R16_PIN_ALTERNATE (*((PUINT16V)0x40001018)) // RW, function pin alternate configuration
#define RB_PIN_TMR0 0x01 // RW, TMR0 alternate pin enable: 0=TMR0/PWM0/CAP0 on PA[9], 1=TMR0_/PWM0_/CAP0_ on PB[23]
#define RB_PIN_TMR1 0x02 // RW, TMR1 alternate pin enable: 0=TMR1/PWM1/CAP1 on PA[10], 1=TMR1_/PWM1_/CAP1_ on PB[10]
#define RB_PIN_TMR2 0x04 // RW, TMR2 alternate pin enable: 0=TMR2/PWM2/CAP2 on PA[11], 1=TMR2_/PWM2_/CAP2_ on PB[11]
#define RB_PIN_TMR3 0x08 // RW, TMR3 alternate pin enable: 0=TMR3/PWM3/CAP3 on PA[2], 1=TMR3_/PWM3_/CAP3_ on PB[22]
#define RB_PIN_UART0 0x10 // RW, RXD0/TXD0 alternate pin enable: 0=RXD0/TXD0 on PB[4]/PB[7], 1=RXD0_/TXD0_ on PA[15]/PA[14]
#define RB_PIN_UART1 0x20 // RW, RXD1/TXD1 alternate pin enable: 0=RXD1/TXD1 on PA[8]/PA[9], 1=RXD1_/TXD1_ on PB[12]/PB[13]
#define RB_PIN_UART2 0x40 // RW, RXD2/TXD2 alternate pin enable: 0=RXD2/TXD2 on PA[6]/PA[7], 1=RXD2_/TXD2_ on PB[22]/PB[23]
#define RB_PIN_UART3 0x80 // RW, RXD3/TXD3 alternate pin enable: 0=RXD3/TXD3 on PA[4]/PA[5], 1=RXD3_/TXD3_ on PB[20]/PB[21]
#define RB_PIN_SPI0 0x100 // RW, SCS/SCK0/MOSI/MISO alternate pin enable: 0=SCS/SCK0/MOSI/MISO on PA[12]/PA[13]/PA[14]/PA[15], 1=SCS_/SCK0_/MOSI_/MISO_ on PB[12]/PB[13]/PB[14]/PB[15]
#define RB_PIN_PWMX 0x400 // RW, PWM4/PWM5/PWM7/PWM8/PWM9 alternate pin enable: 0=PWM4/5/7/8/9 on PA[12]/PA[13]/PB[4]/PB[6]/PB[7], 1=PWM4/5/7/8/9 on PA[6]/PA[7]/PB[1]/PB[2]/P[3]
#define RB_PIN_I2C 0x800 // RW, SCL/SDA alternate pin enable: 0=SCL/SDA on PB[13]/PB[12], 1=SCL_/SDA_ on PB[21]/PB[20]
#define RB_PIN_MODEM 0x1000 // RW, DSR/DTR alternate pin enable: 0=DSR/DTR on PB[1]/PB[5], 1=DSR_/DTR_ on PB[14]/PB[15]
#define RB_RF_ANT_SW_EN 0x8000 // RW, RF antenna switch control output enable: 0=disable output, 1=output on PB[16]/PB[17]/PB[18]/PB[19]/PB[20]/PB[21]
#define R16_PIN_ANALOG_IE (*((PUINT16V)0x4000101A)) // RW, analog pin enable and digital input disable
#define RB_PIN_USB_DP_PU 0x40 // RW, USB UDP internal pullup resistance enable: 0=enable/disable by RB_UC_DEV_PU_EN, 1=enable pullup, replace RB_UC_DEV_PU_EN under sleep mode
#define RB_PIN_USB_IE 0x80 // RW, USB analog I/O enable: 0=analog I/O disable, 1=analog I/O enable
#define R32_PIN_CONFIG2 (*((PUINT32V)0x4000101C)) // RW, I/O pin configuration
#define RB_PIN_PA4_15_DIS 0xFFF0 // RW, PA4-PA15 digital input disable
#define RB_PIN_PB0_DIS 0x10000 // RW, PB0 digital input disable
#define RB_PIN_PB4_DIS 0x100000 // RW, PB4 digital input disable
#define RB_PIN_PB6_7_DIS 0xC00000 // RW, PB6-PB7 digital input disable
#define RB_PIN_PB22_23_DIS 0x3000000 // RW, PB22-PB23 digital input disable
#define RB_PIN_PB10_15_DIS 0xFC000000 // RW, PB10-PB15 digital input disable
/* System: power management register */
#define R32_POWER_MANAG (*((PUINT32V)0x40001020)) // RWA, power management register, SAM
#define R16_POWER_PLAN (*((PUINT16V)0x40001020)) // RWA, power plan before sleep instruction, SAM
#define RB_PWR_XROM 0x01 // RWA, power for flash ROM
#define RB_PWR_RAM2K 0x02 // RWA, power for retention 2KB SRAM
#define RB_PWR_CORE 0x04 // RWA, power retention for core and base peripherals
#define RB_PWR_EXTEND 0x08 // RWA, power retention for USB and BLE
#define RB_PWR_RAM24K 0x10 // RWA, power for main SRAM
#define RB_MAIN_ACT 0x40 // RWA, main power chose
#define RB_PWR_SYS_EN 0x80 // RWA, power for system
#define RB_PWR_LDO_EN 0x0100 // RWA, LDO enable
#define RB_PWR_DCDC_EN 0x0200 // RWA, DC/DC converter enable: 0=DC/DC disable and bypass, 1=DC/DC enable
#define RB_PWR_DCDC_PRE 0x0400 // RWA, DC/DC converter pre-enable
#define RB_XT_PRE_CFG 0x1800 // RWA, extern 32MHz HSE early wake up time configuration
#define RB_PWR_MUST_0 0x2000 // RWA, must write 0
#define RB_XT_PRE_EN 0x4000 // RWA, extern 32MHz HSE early wake up enable, must be used with LSI/LSE
#define RB_PWR_PLAN_EN 0x8000 // RWA/WZ, power plan enable, auto clear after sleep executed
#define R16_AUX_POWER_ADJ (*((PUINT16V)0x40001022)) // RWA, aux power adjust control, SAM
#define RB_ULPLDO_ADJ 0x0007 // RWA, Ultra-Low-Power LDO voltage adjust
#define RB_DCDC_CHARGE 0x0080 // RWA, DC/DC aux charge enable
#define RB_IPU_TKEY_SEL 0xC000 // RWA, TouchKey wakeup
/* System: battery detector register */
#define R32_BATTERY_CTRL (*((PUINT32V)0x40001024)) // RWA, battery voltage detector, SAM
#define R8_BAT_DET_CTRL (*((PUINT8V)0x40001024)) // RWA, battery voltage detector control, SAM
#define RB_BAT_DET_EN 0x01 // RWA, battery voltage detector enable if RB_BAT_MON_EN=0
#define RB_BAT_LOW_VTHX 0x01 // RWA, select monitor threshold voltage if RB_BAT_MON_EN=1
#define RB_BAT_MON_EN 0x02 // RWA, battery voltage monitor enable under sleep mode
#define RB_BAT_LOWER_IE 0x04 // RWA, interrupt enable for battery lower voltage
#define RB_BAT_LOW_IE 0x08 // RWA, interrupt enable for battery low voltage
// request NMI interrupt if both RB_BAT_LOWER_IE and RB_BAT_LOW_IE enabled
#define R8_BAT_DET_CFG (*((PUINT8V)0x40001025)) // RWA, battery voltage detector configuration, SAM
#define RB_BAT_LOW_VTH 0x03 // RWA, select detector/monitor threshold voltage of battery voltage low
#define R8_BAT_STATUS (*((PUINT8V)0x40001026)) // RO, battery status
#define RB_BAT_STAT_LOWER 0x01 // RO, battery lower voltage status for detector, high action
#define RB_BAT_STAT_LOW 0x02 // RO, battery low voltage status for detector/monitor, high action
/* System: 32KHz oscillator control register */
#define R32_OSC32K_CTRL (*((PUINT32V)0x4000102C)) // RWA, 32KHz oscillator control, SAM
#define R16_INT32K_TUNE (*((PUINT16V)0x4000102C)) // RWA, internal 32KHz oscillator tune control, SAM
#define RB_INT32K_TUNE 0x1FFF // RWA, internal 32KHz oscillator frequency tune
#define R8_XT32K_TUNE (*((PUINT8V)0x4000102E)) // RWA, external 32KHz oscillator tune control, SAM
#define RB_XT32K_I_TUNE 0x03 // RWA, external 32KHz oscillator current tune: 00=75% current, 01=standard current, 10=150% current, 11=200% current for startup
#define RB_XT32K_C_LOAD 0xF0 // RWA, external 32KHz oscillator load capacitor tune: Cap = RB_XT32K_C_LOAD + 12pF
#define R8_CK32K_CONFIG (*((PUINT8V)0x4000102F)) // RWA, 32KHz oscillator configure
#define RB_CLK_XT32K_PON 0x01 // RWA, external 32KHz oscillator power on
#define RB_CLK_INT32K_PON 0x02 // RWA, internal 32KHz oscillator power on
#define RB_CLK_OSC32K_XT 0x04 // RWA, 32KHz oscillator source selection: 0=RC, 1=XT
#define RB_CLK_OSC32K_FILT 0x08 // RWA, internal 32KHz oscillator low noise mode disable: 1=enable, 0=disable
#define RB_32K_CLK_PIN 0x80 // RO, 32KHz oscillator clock pin status
/* System: real-time clock register */
#define R32_RTC_CTRL (*((PUINT32V)0x40001030)) // RWA, RTC control, SAM
#define R8_RTC_FLAG_CTRL (*((PUINT8V)0x40001030)) // RW, RTC flag and clear control
#define RB_RTC_TMR_CLR 0x10 // RW, set 1 to clear RTC timer action flag, auto clear
#define RB_RTC_TRIG_CLR 0x20 // RW, set 1 to clear RTC trigger action flag, auto clear
#define RB_RTC_TMR_FLAG 0x40 // RO, RTC timer action flag
#define RB_RTC_TRIG_FLAG 0x80 // RO, RTC trigger action flag
#define R8_RTC_MODE_CTRL (*((PUINT8V)0x40001031)) // RWA, RTC mode control, SAM
#define RB_RTC_TMR_MODE 0x07 // RWA, RTC timer mode: 000=0.125S, 001=0.25S, 010=0.5S, 011=1S, 100=2S, 101=4S, 110=8S, 111=16S
#define RB_RTC_IGNORE_B0 0x08 // RWA, force ignore bit0 for trigger mode: 0=compare bit0, 1=ignore bit0
#define RB_RTC_TMR_EN 0x10 // RWA, RTC timer mode enable
#define RB_RTC_TRIG_EN 0x20 // RWA, RTC trigger mode enable
#define RB_RTC_LOAD_LO 0x40 // RWA, set 1 to load RTC count low word R32_RTC_CNT_32K, auto clear after loaded
#define RB_RTC_LOAD_HI 0x80 // RWA, set 1 to load RTC count high word R32_RTC_CNT_DAY, auto clear after loaded
#define R32_RTC_TRIG (*((PUINT32V)0x40001034)) // RWA, RTC trigger value, SAM
#define R32_RTC_CNT_32K (*((PUINT32V)0x40001038)) // RO, RTC count based 32KHz
#define R16_RTC_CNT_32K (*((PUINT16V)0x40001038)) // RO, RTC count based 32KHz
#define R16_RTC_CNT_2S (*((PUINT16V)0x4000103A)) // RO, RTC count based 2 second
#define R32_RTC_CNT_DAY (*((PUINT32V)0x4000103C)) // RO, RTC count based one day, only low 14 bit
/*System: Miscellaneous Control register */
#define R32_MISC_CTRL (*((PUINT32V)0x40001048)) // RWA, miscellaneous control register
#define R8_PLL_CONFIG (*((PUINT8V)0x4000104B)) // RWA, PLL configuration control, SAM
#define RB_PLL_CFG_DAT 0x7F // RWA, PLL configuration control, SAM
/* System: 32MHz oscillator control register */
#define R8_XT32M_TUNE (*((PUINT8V)0x4000104E)) // RWA, external 32MHz oscillator tune control, SAM
#define RB_XT32M_I_BIAS 0x03 // RWA, external 32MHz oscillator bias current tune: 00=75% current, 01=standard current, 10=125% current, 11=150% current
#define RB_XT32M_C_LOAD 0x70 // RWA, external 32MHz oscillator load capacitor tune: Cap = RB_XT32M_C_LOAD * 2 + 10pF
/* System: oscillator frequency calibration register */
#define R32_OSC_CALIB (*((PUINT32V)0x40001050)) // RWA, oscillator frequency calibration, SAM
#define R16_OSC_CAL_CNT (*((PUINT16V)0x40001050)) // RO, system clock count value for 32KHz multi-cycles
#define RB_OSC_CAL_CNT 0x3FFF // RO, system clock count value for 32KHz multi-cycles
#define RB_OSC_CAL_OV_CLR 0x4000 // RW1, indicate R8_OSC_CAL_OV_CNT not zero, set 1 to clear R8_OSC_CAL_OV_CNT
#define RB_OSC_CAL_IF 0x8000 // RW1, interrupt flag for oscillator capture end, set 1 to clear
#define R8_OSC_CAL_OV_CNT (*((PUINT8V)0x40001052)) // RO, oscillator frequency calibration overflow times
#define R8_OSC_CAL_CTRL (*((PUINT8V)0x40001053)) // RWA, oscillator frequency calibration control, SAM
#define RB_OSC_CNT_TOTAL 0x07 // RWA, total cycles mode for oscillator capture
// RB_OSC_CNT_TOTAL: select total cycles for oscillator capture
// 000: 1
// 001: 2
// 010: 4
// 011: 32
// 100: 64
// 101: 128
// 110: 1024
// 111: 2047
#define RB_OSC_CNT_HALT 0x08 // RO, calibration counter halt status: 0=counting, 1=halt for reading count value
#define RB_OSC_CAL_IE 0x10 // RWA, interrupt enable for oscillator capture end
#define RB_OSC_CNT_EN 0x20 // RWA, calibration counter enable
#define RB_OSC_CNT_END 0x40 // RWA, select oscillator capture end mode: 0=normal, 1=append 2 cycles
/* System: ADC and Touch-key register */
#define R32_ADC_CTRL (*((PUINT32V)0x40001058)) // RW, ADC control
#define R8_ADC_CHANNEL (*((PUINT8V)0x40001058)) // RW, ADC input channel selection
#define RB_ADC_CH_INX 0x0F // RW, ADC input channel index
#define R8_ADC_CFG (*((PUINT8V)0x40001059)) // RW, ADC configure
#define RB_ADC_POWER_ON 0x01 // RW, ADC power control: 0=power down, 1=power on
#define RB_ADC_BUF_EN 0x02 // RW, ADC input buffer enable
#define RB_ADC_DIFF_EN 0x04 // RW, ADC input channel mode: 0=single-end, 1=differnetial
#define RB_ADC_OFS_TEST 0x08 // RW, enable ADC offset test mode: 0=normal mode, 1=short to test offset
#define RB_ADC_PGA_GAIN 0x30 // RW, set ADC input PGA gain: 00=-12dB, 01=-6dB, 10=0dB, 11=6dB
#define RB_ADC_CLK_DIV 0xC0 // RW, select ADC clock frequency: 00=3.2MHz, 01=8MHz, 10=5.33MHz, 11=4MHz
#define R8_ADC_CONVERT (*((PUINT8V)0x4000105A)) // RW, ADC convert control
#define RB_ADC_START 0x01 // RW, ADC convert start control: 0=stop ADC convert, 1=start an ADC convert, auto clear
#define RB_ADC_PGA_GAIN2 0x02 // RW, ADC gain direction, must be 0 when using TS
#define RB_ADC_EOC_X 0x80 // RO, end of ADC conversion flag
#define R8_TEM_SENSOR (*((PUINT8V)0x4000105B)) // RW, temperature sensor control
#define RB_TEM_SEN_PWR_ON 0x80 // RW, temperature sensor power control: 0=power down, 1=power on
#define R32_ADC_DATA (*((PUINT32V)0x4000105C)) // RO, ADC data and status
#define R16_ADC_DATA (*((PUINT16V)0x4000105C)) // RO, ADC data
#define RB_ADC_DATA 0x0FFF // RO, ADC conversion data
#define R8_ADC_INT_FLAG (*((PUINT8V)0x4000105E)) // RO, ADC interrupt flag register
#define RB_ADC_IF_EOC 0x80 // RO, ADC conversion interrupt flag: 0=free or converting, 1=end of conversion, interrupt action, auto ADC or write R8_ADC_CONVERT or write R8_TKEY_CONVERT to clear flag
#define R32_TKEY_CTRL (*((PUINT8V)0x40001054)) // RW, Touchkey control
#define R8_TKEY_COUNT (*((PUINT8V)0x40001054)) // RW, Touchkey charge and discharge count
#define RB_TKEY_CHARG_CNT 0x1F // RW, Touchkey charge count
#define RB_TKEY_DISCH_CNT 0xE0 // RW, Touchkey discharge count
#define R8_TKEY_CONVERT (*((PUINT8V)0x40001056)) // RW, Touchkey convert control
#define RB_TKEY_START 0x01 // RW, Touchkey convert start control: 0=stop Touchkey convert, 1=start a Touchkey convert, auto clear
#define R8_TKEY_CFG (*((PUINT8V)0x40001057)) // RW, Touchkey configure
#define RB_TKEY_PWR_ON 0x01 // RW, Touchkey power on: 0=power down, 1=power on
#define RB_TKEY_CURRENT 0x02 // RW, Touchkey charge current selection: 0=35uA, 1=70uA
#define RB_TKEY_DRV_EN 0x04 // RW, Touchkey drive shield enable
#define RB_TKEY_PGA_ADJ 0x08 // RW, ADC input PGA speed selection: 0=slow, 1=fast
#define RB_TKEY_DMA_EN 0x10 // RW, Touchkey DMA enable
#define RB_TKEY_AUTO_EN 0x20 // RW, Touchkey auto-trigger enable
#define RB_TKEY_RAND_EN 0x40 // RW, Touchkey random trigger enable
#define R32_ADC_DMA_CTRL (*((PUINT32V)0x40001060)) // RW, ADC DMA control
#define R8_ADC_CTRL_DMA (*((PUINT8V)0x40001061)) // RW, ADC DMA control
#define RB_ADC_DMA_ENABLE 0x01 // RW, ADC DMA enable
#define RB_ADC_DMA_LOOP 0x04 // RW, ADC DMA address loop enable
#define RB_ADC_IE_DMA_END 0x08 // RW, enable interrupt for ADC DMA completion
#define RB_ADC_IE_EOC 0x10 // RW, enable interrupt for end of ADC conversion
#define RB_ADC_CONT_EN 0x40 // RW, enable contineous conversion ADC
#define RB_ADC_AUTO_EN 0x80 // RW, enable auto continuing ADC for DMA
#define R8_ADC_DMA_IF (*((PUINT8V)0x40001062)) // RW1, ADC interrupt flag
#define RB_ADC_IF_DMA_END 0x08 // RW1, interrupt flag for ADC DMA completion
#define RB_ADC_IF_END_ADC 0x10 // RW1, interrupt flag for end of ADC conversion, DMA for auto ADC or write R8_ADC_CONVERT to clear flag
#define R8_ADC_AUTO_CYCLE (*((PUINT8V)0x40001063)) // RW, auto ADC cycle value, unit is 16 Fsys
#define R32_ADC_DMA_NOW (*((PUINT32V)0x40001064)) // RW, ADC DMA current address
#define R16_ADC_DMA_NOW (*((PUINT16V)0x40001064)) // RW, ADC DMA current address
#define R32_ADC_DMA_BEG (*((PUINT32V)0x40001068)) // RW, ADC DMA begin address
#define R16_ADC_DMA_BEG (*((PUINT16V)0x40001068)) // RW, ADC DMA begin address
#define R32_ADC_DMA_END (*((PUINT32V)0x4000106C)) // RW, ADC DMA end address
#define R16_ADC_DMA_END (*((PUINT16V)0x4000106C)) // RW, ADC DMA end address
/* System: Flash ROM control register */
#define R32_FLASH_DATA (*((PUINT32V)0x40001800)) // RO/WO, flash ROM data
#define R32_FLASH_CONTROL (*((PUINT32V)0x40001804)) // RW, flash ROM control
#define R8_FLASH_DATA (*((PUINT8V)0x40001804)) // RO/WO, flash ROM data buffer
#define R8_FLASH_CTRL (*((PUINT8V)0x40001806)) // RW, flash ROM access control
#define R8_FLASH_CFG (*((PUINT8V)0x40001807)) // RW, flash ROM access config, SAM
/* System: GPIO interrupt control register */
#define R32_GPIO_INT_EN (*((PUINT32V)0x40001090)) // RW, GPIO interrupt enable
#define R16_PA_INT_EN (*((PUINT16V)0x40001090)) // RW, GPIO PA interrupt enable
#define R16_PB_INT_EN (*((PUINT16V)0x40001092)) // RW, GPIO PB interrupt enable
#define R32_GPIO_INT_MODE (*((PUINT32V)0x40001094)) // RW, GPIO interrupt mode: 0=level action, 1=edge action
#define R16_PA_INT_MODE (*((PUINT16V)0x40001094)) // RW, GPIO PA interrupt mode: 0=level action, 1=edge action
#define R16_PB_INT_MODE (*((PUINT16V)0x40001096)) // RW, GPIO PB interrupt mode: 0=level action, 1=edge action
#define R32_GPIO_INT_IF (*((PUINT32V)0x4000109C)) // RW1, GPIO interrupt flag
#define R16_PA_INT_IF (*((PUINT16V)0x4000109C)) // RW1, GPIO PA interrupt flag
#define R16_PB_INT_IF (*((PUINT16V)0x4000109E)) // RW1, GPIO PB interrupt flag
/* GPIO PA register */
#define R32_PA_DIR (*((PUINT32V)0x400010A0)) // RW, GPIO PA I/O direction: 0=in, 1=out
#define R8_PA_DIR_0 (*((PUINT8V)0x400010A0)) // RW, GPIO PA I/O direction byte 0
#define R8_PA_DIR_1 (*((PUINT8V)0x400010A1)) // RW, GPIO PA I/O direction byte 1
#define R32_PA_PIN (*((PUINT32V)0x400010A4)) // RO, GPIO PA input
#define R8_PA_PIN_0 (*((PUINT8V)0x400010A4)) // RO, GPIO PA input byte 0
#define R8_PA_PIN_1 (*((PUINT8V)0x400010A5)) // RO, GPIO PA input byte 1
#define R32_PA_OUT (*((PUINT32V)0x400010A8)) // RW, GPIO PA output
#define R8_PA_OUT_0 (*((PUINT8V)0x400010A8)) // RW, GPIO PA output byte 0
#define R8_PA_OUT_1 (*((PUINT8V)0x400010A9)) // RW, GPIO PA output byte 1
#define R32_PA_CLR (*((PUINT32V)0x400010AC)) // WZ, GPIO PA clear output: 0=keep, 1=clear
#define R8_PA_CLR_0 (*((PUINT8V)0x400010AC)) // WZ, GPIO PA clear output byte 0
#define R8_PA_CLR_1 (*((PUINT8V)0x400010AD)) // WZ, GPIO PA clear output byte 1
#define R32_PA_PU (*((PUINT32V)0x400010B0)) // RW, GPIO PA pullup resistance enable
#define R8_PA_PU_0 (*((PUINT8V)0x400010B0)) // RW, GPIO PA pullup resistance enable byte 0
#define R8_PA_PU_1 (*((PUINT8V)0x400010B1)) // RW, GPIO PA pullup resistance enable byte 1
#define R32_PA_PD_DRV (*((PUINT32V)0x400010B4)) // RW, PA pulldown for input or PA driving capability for output
#define R8_PA_PD_DRV_0 (*((PUINT8V)0x400010B4)) // RW, PA pulldown for input or PA driving capability for output byte 0
#define R8_PA_PD_DRV_1 (*((PUINT8V)0x400010B5)) // RW, PA pulldown for input or PA driving capability for output byte 1
/* GPIO PB register */
#define R32_PB_DIR (*((PUINT32V)0x400010C0)) // RW, GPIO PB I/O direction: 0=in, 1=out
#define R8_PB_DIR_0 (*((PUINT8V)0x400010C0)) // RW, GPIO PB I/O direction byte 0
#define R8_PB_DIR_1 (*((PUINT8V)0x400010C1)) // RW, GPIO PB I/O direction byte 1
#define R8_PB_DIR_2 (*((PUINT8V)0x400010C2)) // RW, GPIO PB I/O direction byte 2
#define R32_PB_PIN (*((PUINT32V)0x400010C4)) // RO, GPIO PB input
#define R8_PB_PIN_0 (*((PUINT8V)0x400010C4)) // RO, GPIO PB input byte 0
#define R8_PB_PIN_1 (*((PUINT8V)0x400010C5)) // RO, GPIO PB input byte 1
#define R8_PB_PIN_2 (*((PUINT8V)0x400010C6)) // RO, GPIO PB input byte 2
#define R32_PB_OUT (*((PUINT32V)0x400010C8)) // RW, GPIO PB output
#define R8_PB_OUT_0 (*((PUINT8V)0x400010C8)) // RW, GPIO PB output byte 0
#define R8_PB_OUT_1 (*((PUINT8V)0x400010C9)) // RW, GPIO PB output byte 1
#define R8_PB_OUT_2 (*((PUINT8V)0x400010CA)) // RW, GPIO PB output byte 2
#define R32_PB_CLR (*((PUINT32V)0x400010CC)) // WZ, GPIO PB clear output: 0=keep, 1=clear
#define R8_PB_CLR_0 (*((PUINT8V)0x400010CC)) // WZ, GPIO PB clear output byte 0
#define R8_PB_CLR_1 (*((PUINT8V)0x400010CD)) // WZ, GPIO PB clear output byte 1
#define R8_PB_CLR_2 (*((PUINT8V)0x400010CE)) // WZ, GPIO PB clear output byte 2
#define R32_PB_PU (*((PUINT32V)0x400010D0)) // RW, GPIO PB pullup resistance enable
#define R8_PB_PU_0 (*((PUINT8V)0x400010D0)) // RW, GPIO PB pullup resistance enable byte 0
#define R8_PB_PU_1 (*((PUINT8V)0x400010D1)) // RW, GPIO PB pullup resistance enable byte 1
#define R8_PB_PU_2 (*((PUINT8V)0x400010D2)) // RW, GPIO PB pullup resistance enable byte 2
#define R32_PB_PD_DRV (*((PUINT32V)0x400010D4)) // RW, PB pulldown for input or PB driving capability for output
#define R8_PB_PD_DRV_0 (*((PUINT8V)0x400010D4)) // RW, PB pulldown for input or PB driving capability for output byte 0
#define R8_PB_PD_DRV_1 (*((PUINT8V)0x400010D5)) // RW, PB pulldown for input or PB driving capability for output byte 1
#define R8_PB_PD_DRV_2 (*((PUINT8V)0x400010D6)) // RW, PB pulldown for input or PB driving capability for output byte 2
/* GPIO register address offset and bit define */
#define BA_PA ((PUINT8V)0x400010A0) // point GPIO PA base address
#define BA_PB ((PUINT8V)0x400010C0) // point GPIO PB base address
#define GPIO_DIR 0x00
#define GPIO_DIR_0 0x00
#define GPIO_DIR_1 0x01
#define GPIO_DIR_2 0x02
#define GPIO_PIN 0x04
#define GPIO_PIN_0 0x04
#define GPIO_PIN_1 0x05
#define GPIO_PIN_2 0x06
#define GPIO_OUT 0x08
#define GPIO_OUT_0 0x08
#define GPIO_OUT_1 0x09
#define GPIO_OUT_2 0x0A
#define GPIO_CLR 0x0C
#define GPIO_CLR_0 0x0C
#define GPIO_CLR_1 0x0D
#define GPIO_CLR_2 0x0E
#define GPIO_PU 0x10
#define GPIO_PU_0 0x10
#define GPIO_PU_1 0x11
#define GPIO_PU_2 0x12
#define GPIO_PD_DRV 0x14
#define GPIO_PD_DRV_0 0x14
#define GPIO_PD_DRV_1 0x15
#define GPIO_PD_DRV_2 0x16
/* GPIO alias name */
#define bAIN9 (1<<0) // PA0
#define bSCK1 (1<<0) // PA0
#define bAIN8 (1<<1) // PA1
#define bSDO (1<<1) // PA1
#define bMOSI1 bSDO
#define bAIN7 (1<<2) // PA2
#define bSDI (1<<2) // PA2
#define bMISO1 bSDI
#define bAIN6 (1<<3) // PA3
#define bAIN0 (1<<4) // PA4
#define bRXD3 (1<<4) // PA4
#define bRXD3_ (1<<4) // PA4
#define bAIN1 (1<<5) // PA5
#define bTXD3 (1<<5) // PA5
#define bTXD3_ (1<<5) // PA5
#define bAIN10 (1<<6) // PA6
#define bRXD2_ (1<<6) // PA6
#define bPWM4_ (1<<6) // PA6
#define bAIN11 (1<<7) // PA7
#define bTXD2_ (1<<7) // PA7
#define bPWM5_ (1<<7) // PA7
#define bAIN12 (1<<8) // PA8
#define bRXD1 (1<<8) // PA8
#define bAIN13 (1<<9) // PA9
#define bTMR0 (1<<9) // PA9
#define bCAP0 bTMR0
#define bPWM0 bTMR0
#define bTXD1 (1<<9) // PA9
#define bX32KI (1<<10) // PA10
#define bTMR1 (1<<10) // PA10
#define bCAP1 bTMR1
#define bPWM1 bTMR1
#define bX32KO (1<<11) // PA11
#define bTMR2 (1<<11) // PA11
#define bCAP2 bTMR2
#define bPWM2 bTMR2
#define bAIN2 (1<<12) // PA12
#define bPWM4 (1<<12) // PA12
#define bSCS (1<<12) // PA12
#define bAIN3 (1<<13) // PA13
#define bSCK0 (1<<13) // PA13
#define bPWM5 (1<<13) // PA13
#define bAIN4 (1<<14) // PA14
#define bMOSI (1<<14) // PA14
#define bTXD0_ (1<<14) // PA14
#define bAIN5 (1<<15) // PA15
#define bMISO (1<<15) // PA15
#define bRXD0_ (1<<15) // PA15
#define bPWM6 (1<<0) // PB0
#define bCTS (1<<0) // PB0
#define bDSR (1<<1) // PB1
#define bPWM7_ (1<<1) // PB1
#define bRI (1<<2) // PB2
#define bPWM8_ (1<<2) // PB2
#define bDCD (1<<3) // PB3
#define bPWM9_ (1<<3) // PB3
#define bPWM7 (1<<4) // PB4
#define bRXD0 (1<<4) // PB4
#define bDTR (1<<5) // PB5
#define bRTS (1<<6) // PB6
#define bPWM8 (1<<6) // PB6
#define bTXD0 (1<<7) // PB7
#define bPWM9 (1<<7) // PB7
#define bUDM (1<<10) // PB10
#define bTMR1_ (1<<10) // PB10
#define bCAP1_ bTMR1_
#define bPWM1_ bTMR1_
#define bUDP (1<<11) // PB11
#define bTMR2_ (1<<11) // PB11
#define bCAP2_ bTMR2_
#define bPWM2_ bTMR2_
#define bU2DM (1<<12) // PB12
#define bSCS_ (1<<12) // PB12
#define bRXD1_ (1<<12) // PB12
#define bU2DP (1<<13) // PB13
#define bSCK0_ (1<<13) // PB13
#define bTXD1_ (1<<13) // PB13
#define bTIO (1<<14) // PB14
#define bDSR_ (1<<14) // PB14
#define bMOSI_ (1<<14) // PB14
#define bSDA (1<<14) // PB14
#define bPWM10 (1<<14) // PB14
#define bTCK (1<<15) // PB15
#define bMISO_ (1<<15) // PB15
#define bSCL (1<<15) // PB15
#define bDTR_ (1<<15) // PB15
#define bRXD2 (1<<22) // PB22
#define bTMR3 (1<<22) // PB22
#define bCAP3 bTMR3
#define bPWM3 bTMR3
#define bTMR3_ (1<<22) // PB22
#define bCAP3_ bTMR3_
#define bPWM3_ bTMR3_
#define bRST (1<<23) // PB23
#define bTMR0_ (1<<23) // PB23
#define bCAP0_ bTMR0_
#define bPWM0_ bTMR0_
#define bTXD2 (1<<23) // PB23
#define bPWM11 (1<<23) // PB23
/* Timer0 register */
#define R32_TMR0_CONTROL (*((PUINT32V)0x40002000)) // RW, TMR0 control
#define R8_TMR0_CTRL_MOD (*((PUINT8V)0x40002000)) // RW, TMR0 mode control
#define R8_TMR0_INTER_EN (*((PUINT8V)0x40002002)) // RW, TMR0 interrupt enable
// #define R32_TMR0_STATUS (*((PUINT32V)0x40002004)) // RW, TMR0 status
#define R8_TMR0_INT_FLAG (*((PUINT8V)0x40002006)) // RW1, TMR0 interrupt flag
#define R8_TMR0_FIFO_COUNT (*((PUINT8V)0x40002007)) // RO, TMR0 FIFO count status
#define R32_TMR0_COUNT (*((PUINT32V)0x40002008)) // RO, TMR0 current count
#define R16_TMR0_COUNT (*((PUINT16V)0x40002008)) // RO, TMR0 current count
#define R8_TMR0_COUNT (*((PUINT8V)0x40002008)) // RO, TMR0 current count
#define R32_TMR0_CNT_END (*((PUINT32V)0x4000200C)) // RW, TMR0 end count value, only low 26 bit
#define R32_TMR0_FIFO (*((PUINT32V)0x40002010)) // RO/WO, TMR0 FIFO register, only low 26 bit
#define R16_TMR0_FIFO (*((PUINT16V)0x40002010)) // RO/WO, TMR0 FIFO register
#define R8_TMR0_FIFO (*((PUINT8V)0x40002010)) // RO/WO, TMR0 FIFO register
/* Timer1 register */
#define R32_TMR1_CONTROL (*((PUINT32V)0x40002400)) // RW, TMR1 control
#define R8_TMR1_CTRL_MOD (*((PUINT8V)0x40002400)) // RW, TMR1 mode control
#define R8_TMR1_CTRL_DMA (*((PUINT8V)0x40002401)) // RW, TMR1 DMA control
#define R8_TMR1_INTER_EN (*((PUINT8V)0x40002402)) // RW, TMR1 interrupt enable
// #define R32_TMR1_STATUS (*((PUINT32V)0x40002404)) // RW, TMR1 status
#define R8_TMR1_INT_FLAG (*((PUINT8V)0x40002406)) // RW1, TMR1 interrupt flag
#define R8_TMR1_FIFO_COUNT (*((PUINT8V)0x40002407)) // RO, TMR1 FIFO count status
#define R32_TMR1_COUNT (*((PUINT32V)0x40002408)) // RO, TMR1 current count
#define R16_TMR1_COUNT (*((PUINT16V)0x40002408)) // RO, TMR1 current count
#define R8_TMR1_COUNT (*((PUINT8V)0x40002408)) // RO, TMR1 current count
#define R32_TMR1_CNT_END (*((PUINT32V)0x4000240C)) // RW, TMR1 end count value, only low 26 bit
#define R32_TMR1_FIFO (*((PUINT32V)0x40002410)) // RO/WO, TMR1 FIFO register, only low 26 bit
#define R16_TMR1_FIFO (*((PUINT16V)0x40002410)) // RO/WO, TMR1 FIFO register
#define R8_TMR1_FIFO (*((PUINT8V)0x40002410)) // RO/WO, TMR1 FIFO register
#define R32_TMR1_DMA_NOW (*((PUINT32V)0x40002414)) // RW, TMR1 DMA current address
#define R16_TMR1_DMA_NOW (*((PUINT16V)0x40002414)) // RW, TMR1 DMA current address
#define R32_TMR1_DMA_BEG (*((PUINT32V)0x40002418)) // RW, TMR1 DMA begin address
#define R16_TMR1_DMA_BEG (*((PUINT16V)0x40002418)) // RW, TMR1 DMA begin address
#define R32_TMR1_DMA_END (*((PUINT32V)0x4000241C)) // RW, TMR1 DMA end address
#define R16_TMR1_DMA_END (*((PUINT16V)0x4000241C)) // RW, TMR1 DMA end address
/* Timer2 register */
#define R32_TMR2_CONTROL (*((PUINT32V)0x40002800)) // RW, TMR2 control
#define R8_TMR2_CTRL_MOD (*((PUINT8V)0x40002800)) // RW, TMR2 mode control
#define R8_TMR2_CTRL_DMA (*((PUINT8V)0x40002801)) // RW, TMR2 DMA control
#define R8_TMR2_INTER_EN (*((PUINT8V)0x40002802)) // RW, TMR2 interrupt enable
// #define R32_TMR2_STATUS (*((PUINT32V)0x40002804)) // RW, TMR2 status
#define R8_TMR2_INT_FLAG (*((PUINT8V)0x40002806)) // RW1, TMR2 interrupt flag
#define R8_TMR2_FIFO_COUNT (*((PUINT8V)0x40002807)) // RO, TMR2 FIFO count status
#define R32_TMR2_COUNT (*((PUINT32V)0x40002808)) // RO, TMR2 current count
#define R16_TMR2_COUNT (*((PUINT16V)0x40002808)) // RO, TMR2 current count
#define R8_TMR2_COUNT (*((PUINT8V)0x40002808)) // RO, TMR2 current count
#define R32_TMR2_CNT_END (*((PUINT32V)0x4000280C)) // RW, TMR2 end count value, only low 26 bit
#define R32_TMR2_FIFO (*((PUINT32V)0x40002810)) // RO/WO, TMR2 FIFO register, only low 26 bit
#define R16_TMR2_FIFO (*((PUINT16V)0x40002810)) // RO/WO, TMR2 FIFO register
#define R8_TMR2_FIFO (*((PUINT8V)0x40002810)) // RO/WO, TMR2 FIFO register
#define R32_TMR2_DMA_NOW (*((PUINT32V)0x40002814)) // RW, TMR2 DMA current address
#define R16_TMR2_DMA_NOW (*((PUINT16V)0x40002814)) // RW, TMR2 DMA current address
#define R32_TMR2_DMA_BEG (*((PUINT32V)0x40002818)) // RW, TMR2 DMA begin address
#define R16_TMR2_DMA_BEG (*((PUINT16V)0x40002818)) // RW, TMR2 DMA begin address
#define R32_TMR2_DMA_END (*((PUINT32V)0x4000281C)) // RW, TMR2 DMA end address
#define R16_TMR2_DMA_END (*((PUINT16V)0x4000281C)) // RW, TMR2 DMA end address
/* Timer3 register */
#define R32_TMR3_CONTROL (*((PUINT32V)0x40002C00)) // RW, TMR3 control
#define R8_TMR3_CTRL_MOD (*((PUINT8V)0x40002C00)) // RW, TMR3 mode control
#define R8_TMR3_INTER_EN (*((PUINT8V)0x40002C02)) // RW, TMR3 interrupt enable
// #define R32_TMR3_STATUS (*((PUINT32V)0x40002C04)) // RW, TMR3 status
#define R8_TMR3_INT_FLAG (*((PUINT8V)0x40002C06)) // RW1, TMR3 interrupt flag
#define R8_TMR3_FIFO_COUNT (*((PUINT8V)0x40002C07)) // RO, TMR3 FIFO count status
#define R32_TMR3_COUNT (*((PUINT32V)0x40002C08)) // RO, TMR3 current count
#define R16_TMR3_COUNT (*((PUINT16V)0x40002C08)) // RO, TMR3 current count
#define R8_TMR3_COUNT (*((PUINT8V)0x40002C08)) // RO, TMR3 current count
#define R32_TMR3_CNT_END (*((PUINT32V)0x40002C0C)) // RW, TMR3 end count value, only low 26 bit
#define R32_TMR3_FIFO (*((PUINT32V)0x40002C10)) // RO/WO, TMR3 FIFO register, only low 26 bit
#define R16_TMR3_FIFO (*((PUINT16V)0x40002C10)) // RO/WO, TMR3 FIFO register
#define R8_TMR3_FIFO (*((PUINT8V)0x40002C10)) // RO/WO, TMR3 FIFO register
/* Timer register address offset and bit define */
#define TMR_FIFO_SIZE 8 // timer FIFO size (depth)
#define BA_TMR0 ((PUINT8V)0x40002000) // point TMR0 base address
#define BA_TMR1 ((PUINT8V)0x40002400) // point TMR1 base address
#define BA_TMR2 ((PUINT8V)0x40002800) // point TMR2 base address
#define BA_TMR3 ((PUINT8V)0x40002C00) // point TMR3 base address
#define TMR_CTRL_MOD 0
#define RB_TMR_MODE_IN 0x01 // RW, timer in mode: 0=timer/PWM, 1=capture/count
#define RB_TMR_ALL_CLEAR 0x02 // RW, force clear timer FIFO and count
#define RB_TMR_COUNT_EN 0x04 // RW, timer count enable
#define RB_TMR_OUT_EN 0x08 // RW, timer output enable
#define RB_TMR_OUT_POLAR 0x10 // RW, timer PWM output polarity: 0=default low and high action, 1=default high and low action
#define RB_TMR_CAP_COUNT 0x10 // RW, count sub-mode if RB_TMR_MODE_IN=1: 0=capture, 1=count
#define RB_TMR_PWM_REPEAT 0xC0 // RW, timer PWM repeat mode: 00=1, 01=4, 10=8, 11-16
#define RB_TMR_CAP_EDGE 0xC0 // RW, timer capture edge mode: 00=disable, 01=edge change, 10=fall to fall, 11-rise to rise
#define TMR_CTRL_DMA 1
#define RB_TMR_DMA_ENABLE 0x01 // RW, timer1/2 DMA enable
#define RB_TMR_DMA_LOOP 0x04 // RW, timer1/2 DMA address loop enable
#define TMR_INTER_EN 2
#define RB_TMR_IE_CYC_END 0x01 // RW, enable interrupt for timer capture count timeout or PWM cycle end
#define RB_TMR_IE_DATA_ACT 0x02 // RW, enable interrupt for timer capture input action or PWM trigger
#define RB_TMR_IE_FIFO_HF 0x04 // RW, enable interrupt for timer FIFO half (capture fifo >=4 or PWM fifo <=3)
#define RB_TMR_IE_DMA_END 0x08 // RW, enable interrupt for timer1/2 DMA completion
#define RB_TMR_IE_FIFO_OV 0x10 // RW, enable interrupt for timer FIFO overflow
#define TMR_INT_FLAG 6
#define RB_TMR_IF_CYC_END 0x01 // RW1, interrupt flag for timer capture count timeout or PWM cycle end
#define RB_TMR_IF_DATA_ACT 0x02 // RW1, interrupt flag for timer capture input action or PWM trigger
#define RB_TMR_IF_FIFO_HF 0x04 // RW1, interrupt flag for timer FIFO half (capture fifo >=4 or PWM fifo <=3)
#define RB_TMR_IF_DMA_END 0x08 // RW1, interrupt flag for timer1/2 DMA completion
#define RB_TMR_IF_FIFO_OV 0x10 // RW1, interrupt flag for timer FIFO overflow
#define TMR_FIFO_COUNT 7
#define TMR_COUNT 0x08
#define TMR_CNT_END 0x0C
#define TMR_FIFO 0x10
#define TMR_DMA_NOW 0x14
#define TMR_DMA_BEG 0x18
#define TMR_DMA_END 0x1C
/* UART0 register */
#define R32_UART0_CTRL (*((PUINT32V)0x40003000)) // RW, UART0 control
#define R8_UART0_MCR (*((PUINT8V)0x40003000)) // RW, UART0 modem control
#define R8_UART0_IER (*((PUINT8V)0x40003001)) // RW, UART0 interrupt enable
#define R8_UART0_FCR (*((PUINT8V)0x40003002)) // RW, UART0 FIFO control
#define R8_UART0_LCR (*((PUINT8V)0x40003003)) // RW, UART0 line control
#define R32_UART0_STAT (*((PUINT32V)0x40003004)) // RO, UART0 status
#define R8_UART0_IIR (*((PUINT8V)0x40003004)) // RO, UART0 interrupt identification
#define R8_UART0_LSR (*((PUINT8V)0x40003005)) // RO, UART0 line status
#define R8_UART0_MSR (*((PUINT8V)0x40003006)) // RO, UART0 modem status
#define R32_UART0_FIFO (*((PUINT32V)0x40003008)) // RW, UART0 data or FIFO port
#define R8_UART0_RBR (*((PUINT8V)0x40003008)) // RO, UART0 receiver buffer, receiving byte
#define R8_UART0_THR (*((PUINT8V)0x40003008)) // WO, UART0 transmitter holding, transmittal byte
#define R8_UART0_RFC (*((PUINT8V)0x4000300A)) // RO, UART0 receiver FIFO count
#define R8_UART0_TFC (*((PUINT8V)0x4000300B)) // RO, UART0 transmitter FIFO count
#define R32_UART0_SETUP (*((PUINT32V)0x4000300C)) // RW, UART0 setup
#define R16_UART0_DL (*((PUINT16V)0x4000300C)) // RW, UART0 divisor latch
#define R8_UART0_DLL (*((PUINT8V)0x4000300C)) // RW, UART0 divisor latch LSB byte
// #define R8_UART0_DLM (*((PUINT8V)0x4000300D)) // RW, UART0 divisor latch MSB byte
#define R8_UART0_DIV (*((PUINT8V)0x4000300E)) // RW, UART0 pre-divisor latch byte, only low 7 bit, from 1 to 0/128
#define R8_UART0_ADR (*((PUINT8V)0x4000300F)) // RW, UART0 slave address: 0xFF=disable, other=enable
/* UART1 register */
#define R32_UART1_CTRL (*((PUINT32V)0x40003400)) // RW, UART1 control
#define R8_UART1_MCR (*((PUINT8V)0x40003400)) // RW, UART1 modem control
#define R8_UART1_IER (*((PUINT8V)0x40003401)) // RW, UART1 interrupt enable
#define R8_UART1_FCR (*((PUINT8V)0x40003402)) // RW, UART1 FIFO control
#define R8_UART1_LCR (*((PUINT8V)0x40003403)) // RW, UART1 line control
#define R32_UART1_STAT (*((PUINT32V)0x40003404)) // RO, UART1 status
#define R8_UART1_IIR (*((PUINT8V)0x40003404)) // RO, UART1 interrupt identification
#define R8_UART1_LSR (*((PUINT8V)0x40003405)) // RO, UART1 line status
#define R32_UART1_FIFO (*((PUINT32V)0x40003408)) // RW, UART1 data or FIFO port
#define R8_UART1_RBR (*((PUINT8V)0x40003408)) // RO, UART1 receiver buffer, receiving byte
#define R8_UART1_THR (*((PUINT8V)0x40003408)) // WO, UART1 transmitter holding, transmittal byte
#define R8_UART1_RFC (*((PUINT8V)0x4000340A)) // RO, UART1 receiver FIFO count
#define R8_UART1_TFC (*((PUINT8V)0x4000340B)) // RO, UART1 transmitter FIFO count
#define R32_UART1_SETUP (*((PUINT32V)0x4000340C)) // RW, UART1 setup
#define R16_UART1_DL (*((PUINT16V)0x4000340C)) // RW, UART1 divisor latch
#define R8_UART1_DLL (*((PUINT8V)0x4000340C)) // RW, UART1 divisor latch LSB byte
// #define R8_UART1_DLM (*((PUINT8V)0x4000340D)) // RW, UART1 divisor latch MSB byte
#define R8_UART1_DIV (*((PUINT8V)0x4000340E)) // RW, UART1 pre-divisor latch byte, only low 7 bit, from 1 to 0/128
/* UART2 register */
#define R32_UART2_CTRL (*((PUINT32V)0x40003800)) // RW, UART2 control
#define R8_UART2_MCR (*((PUINT8V)0x40003800)) // RW, UART2 modem control
#define R8_UART2_IER (*((PUINT8V)0x40003801)) // RW, UART2 interrupt enable
#define R8_UART2_FCR (*((PUINT8V)0x40003802)) // RW, UART2 FIFO control
#define R8_UART2_LCR (*((PUINT8V)0x40003803)) // RW, UART2 line control
#define R32_UART2_STAT (*((PUINT32V)0x40003804)) // RO, UART2 status
#define R8_UART2_IIR (*((PUINT8V)0x40003804)) // RO, UART2 interrupt identification
#define R8_UART2_LSR (*((PUINT8V)0x40003805)) // RO, UART2 line status
#define R32_UART2_FIFO (*((PUINT32V)0x40003808)) // RW, UART2 data or FIFO port
#define R8_UART2_RBR (*((PUINT8V)0x40003808)) // RO, UART2 receiver buffer, receiving byte
#define R8_UART2_THR (*((PUINT8V)0x40003808)) // WO, UART2 transmitter holding, transmittal byte
#define R8_UART2_RFC (*((PUINT8V)0x4000380A)) // RO, UART2 receiver FIFO count
#define R8_UART2_TFC (*((PUINT8V)0x4000380B)) // RO, UART2 transmitter FIFO count
#define R32_UART2_SETUP (*((PUINT32V)0x4000380C)) // RW, UART2 setup
#define R16_UART2_DL (*((PUINT16V)0x4000380C)) // RW, UART2 divisor latch
#define R8_UART2_DLL (*((PUINT8V)0x4000380C)) // RW, UART2 divisor latch LSB byte
// #define R8_UART2_DLM (*((PUINT8V)0x4000380D)) // RW, UART2 divisor latch MSB byte
#define R8_UART2_DIV (*((PUINT8V)0x4000380E)) // RW, UART2 pre-divisor latch byte, only low 7 bit, from 1 to 0/128
/* UART3 register */
#define R32_UART3_CTRL (*((PUINT32V)0x40003C00)) // RW, UART3 control
#define R8_UART3_MCR (*((PUINT8V)0x40003C00)) // RW, UART3 modem control
#define R8_UART3_IER (*((PUINT8V)0x40003C01)) // RW, UART3 interrupt enable
#define R8_UART3_FCR (*((PUINT8V)0x40003C02)) // RW, UART3 FIFO control
#define R8_UART3_LCR (*((PUINT8V)0x40003C03)) // RW, UART3 line control
#define R32_UART3_STAT (*((PUINT32V)0x40003C04)) // RO, UART3 status
#define R8_UART3_IIR (*((PUINT8V)0x40003C04)) // RO, UART3 interrupt identification
#define R8_UART3_LSR (*((PUINT8V)0x40003C05)) // RO, UART3 line status
#define R32_UART3_FIFO (*((PUINT32V)0x40003C08)) // RW, UART3 data or FIFO port
#define R8_UART3_RBR (*((PUINT8V)0x40003C08)) // RO, UART3 receiver buffer, receiving byte
#define R8_UART3_THR (*((PUINT8V)0x40003C08)) // WO, UART3 transmitter holding, transmittal byte
#define R8_UART3_RFC (*((PUINT8V)0x40003C0A)) // RO, UART3 receiver FIFO count
#define R8_UART3_TFC (*((PUINT8V)0x40003C0B)) // RO, UART3 transmitter FIFO count
#define R32_UART3_SETUP (*((PUINT32V)0x40003C0C)) // RW, UART3 setup
#define R16_UART3_DL (*((PUINT16V)0x40003C0C)) // RW, UART3 divisor latch
#define R8_UART3_DLL (*((PUINT8V)0x40003C0C)) // RW, UART3 divisor latch LSB byte
// #define R8_UART3_DLM (*((PUINT8V)0x40003C0D)) // RW, UART3 divisor latch MSB byte
#define R8_UART3_DIV (*((PUINT8V)0x40003C0E)) // RW, UART3 pre-divisor latch byte, only low 7 bit, from 1 to 0/128
/* UART register address offset and bit define */
#define UART_FIFO_SIZE 8 // UART FIFO size (depth)
#define UART_RECV_RDY_SZ 7 // the max FIFO trigger level for UART receiver data available
#define BA_UART0 ((PUINT8V)0x40003000) // point UART0 base address
#define BA_UART1 ((PUINT8V)0x40003400) // point UART1 base address
#define BA_UART2 ((PUINT8V)0x40003800) // point UART2 base address
#define BA_UART3 ((PUINT8V)0x40003C00) // point UART3 base address
#define UART_MCR 0
#define RB_MCR_DTR 0x01 // RW, UART0 control DTR
#define RB_MCR_RTS 0x02 // RW, UART0 control RTS
#define RB_MCR_OUT1 0x04 // RW, UART0 control OUT1
#define RB_MCR_OUT2 0x08 // RW, UART control OUT2
#define RB_MCR_INT_OE 0x08 // RW, UART interrupt output enable
#define RB_MCR_LOOP 0x10 // RW, UART0 enable local loop back
#define RB_MCR_AU_FLOW_EN 0x20 // RW, UART0 enable autoflow control
#define RB_MCR_TNOW 0x40 // RW, UART0 enable TNOW output on DTR pin
#define RB_MCR_HALF 0x80 // RW, UART0 enable half-duplex
#define UART_IER 1
#define RB_IER_RECV_RDY 0x01 // RW, UART interrupt enable for receiver data ready
#define RB_IER_THR_EMPTY 0x02 // RW, UART interrupt enable for THR empty
#define RB_IER_LINE_STAT 0x04 // RW, UART interrupt enable for receiver line status
#define RB_IER_MODEM_CHG 0x08 // RW, UART0 interrupt enable for modem status change
#define RB_IER_DTR_EN 0x10 // RW, UART0 DTR/TNOW output pin enable
#define RB_IER_RTS_EN 0x20 // RW, UART0 RTS output pin enable
#define RB_IER_TXD_EN 0x40 // RW, UART TXD pin enable
#define RB_IER_RESET 0x80 // WZ, UART software reset control, high action, auto clear
#define UART_FCR 2
#define RB_FCR_FIFO_EN 0x01 // RW, UART FIFO enable
#define RB_FCR_RX_FIFO_CLR 0x02 // WZ, clear UART receiver FIFO, high action, auto clear
#define RB_FCR_TX_FIFO_CLR 0x04 // WZ, clear UART transmitter FIFO, high action, auto clear
#define RB_FCR_FIFO_TRIG 0xC0 // RW, UART receiver FIFO trigger level: 00-1byte, 01-2bytes, 10-4bytes, 11-7bytes
#define UART_LCR 3
#define RB_LCR_WORD_SZ 0x03 // RW, UART word bit length: 00-5bit, 01-6bit, 10-7bit, 11-8bit
#define RB_LCR_STOP_BIT 0x04 // RW, UART stop bit length: 0-1bit, 1-2bit
#define RB_LCR_PAR_EN 0x08 // RW, UART parity enable
#define RB_LCR_PAR_MOD 0x30 // RW, UART parity mode: 00-odd, 01-even, 10-mark, 11-space
#define RB_LCR_BREAK_EN 0x40 // RW, UART break control enable
#define RB_LCR_DLAB 0x80 // RW, UART reserved bit
#define RB_LCR_GP_BIT 0x80 // RW, UART general purpose bit
#define UART_IIR 4
#define RB_IIR_NO_INT 0x01 // RO, UART no interrupt flag: 0=interrupt action, 1=no interrupt
#define RB_IIR_INT_MASK 0x0F // RO, UART interrupt flag bit mask
#define RB_IIR_FIFO_ID 0xC0 // RO, UART FIFO enabled flag
#define UART_LSR 5
#define RB_LSR_DATA_RDY 0x01 // RO, UART receiver fifo data ready status
#define RB_LSR_OVER_ERR 0x02 // RZ, UART receiver overrun error
#define RB_LSR_PAR_ERR 0x04 // RZ, UART receiver parity error
#define RB_LSR_FRAME_ERR 0x08 // RZ, UART receiver frame error
#define RB_LSR_BREAK_ERR 0x10 // RZ, UART receiver break error
#define RB_LSR_TX_FIFO_EMP 0x20 // RO, UART transmitter fifo empty status
#define RB_LSR_TX_ALL_EMP 0x40 // RO, UART transmitter all empty status
#define RB_LSR_ERR_RX_FIFO 0x80 // RO, indicate error in UART receiver fifo
#define UART_MSR 6
#define RB_MSR_CTS_CHG 0x01 // RZ, UART0 CTS changed status, high action
#define RB_MSR_DSR_CHG 0x02 // RZ, UART0 DSR changed status, high action
//#define RB_MSR_RI_CHG 0x04 // RZ, UART0 RI changed status, high action
//#define RB_MSR_DCD_CHG 0x08 // RZ, UART0 DCD changed status, high action
#define RB_MSR_CTS 0x10 // RO, UART0 CTS action status
#define RB_MSR_DSR 0x20 // RO, UART0 DSR action status
//#define RB_MSR_RI 0x40 // RO, UART0 RI action status
//#define RB_MSR_DCD 0x80 // RO, UART0 DCD action status
#define UART_RBR 8
#define UART_THR 8
#define UART_RFC 0x0A
#define UART_TFC 0x0B
#define UART_DLL 0x0C
// #define UART_DLM 0x0D
#define UART_DIV 0x0E
#define UART_ADR 0x0F
/* UART interrupt identification values for IIR bits 3:0 */
#define UART_II_SLV_ADDR 0x0E // RO, UART0 slave address match
#define UART_II_LINE_STAT 0x06 // RO, UART interrupt by receiver line status
#define UART_II_RECV_RDY 0x04 // RO, UART interrupt by receiver data available
#define UART_II_RECV_TOUT 0x0C // RO, UART interrupt by receiver fifo timeout
#define UART_II_THR_EMPTY 0x02 // RO, UART interrupt by THR empty
#define UART_II_MODEM_CHG 0x00 // RO, UART0 interrupt by modem status change
#define UART_II_NO_INTER 0x01 // RO, no UART interrupt is pending
/* SPI0 register */
#define R32_SPI0_CONTROL (*((PUINT32V)0x40004000)) // RW, SPI0 control
#define R8_SPI0_CTRL_MOD (*((PUINT8V)0x40004000)) // RW, SPI0 mode control
#define R8_SPI0_CTRL_CFG (*((PUINT8V)0x40004001)) // RW, SPI0 configuration control
#define R8_SPI0_INTER_EN (*((PUINT8V)0x40004002)) // RW, SPI0 interrupt enable
#define R8_SPI0_CLOCK_DIV (*((PUINT8V)0x40004003)) // RW, SPI0 master clock divisor
#define R8_SPI0_SLAVE_PRE (*((PUINT8V)0x40004003)) // RW, SPI0 slave preset value
#define R32_SPI0_STATUS (*((PUINT32V)0x40004004)) // RW, SPI0 status
#define R8_SPI0_BUFFER (*((PUINT8V)0x40004004)) // RO, SPI0 data buffer
#define R8_SPI0_RUN_FLAG (*((PUINT8V)0x40004005)) // RO, SPI0 work flag
#define R8_SPI0_INT_FLAG (*((PUINT8V)0x40004006)) // RW1, SPI0 interrupt flag
#define R8_SPI0_FIFO_COUNT (*((PUINT8V)0x40004007)) // RO, SPI0 FIFO count status
#define R32_SPI0_TOTAL_CNT (*((PUINT32V)0x4000400C)) // RW, SPI0 total byte count, only low 12 bit
#define R16_SPI0_TOTAL_CNT (*((PUINT16V)0x4000400C)) // RW, SPI0 total byte count, only low 12 bit
#define R32_SPI0_FIFO (*((PUINT32V)0x40004010)) // RW, SPI0 FIFO register
#define R8_SPI0_FIFO (*((PUINT8V)0x40004010)) // RO/WO, SPI0 FIFO register
#define R8_SPI0_FIFO_COUNT1 (*((PUINT8V)0x40004013)) // RO, SPI0 FIFO count status
#define R32_SPI0_DMA_NOW (*((PUINT32V)0x40004014)) // RW, SPI0 DMA current address
#define R16_SPI0_DMA_NOW (*((PUINT16V)0x40004014)) // RW, SPI0 DMA current address
#define R32_SPI0_DMA_BEG (*((PUINT32V)0x40004018)) // RW, SPI0 DMA begin address
#define R16_SPI0_DMA_BEG (*((PUINT16V)0x40004018)) // RW, SPI0 DMA begin address
#define R32_SPI0_DMA_END (*((PUINT32V)0x4000401C)) // RW, SPI0 DMA end address
#define R16_SPI0_DMA_END (*((PUINT16V)0x4000401C)) // RW, SPI0 DMA end address
/* SPI register address offset and bit define */
#define SPI_FIFO_SIZE 8 // SPI FIFO size (depth)
#define BA_SPI0 ((PUINT8V)0x40004000) // point SPI0 base address
#define SPI_CTRL_MOD 0
#define RB_SPI_MODE_SLAVE 0x01 // RW, SPI0 slave mode: 0=master/host, 1=slave/device
#define RB_SPI_ALL_CLEAR 0x02 // RW, force clear SPI FIFO and count
#define RB_SPI_2WIRE_MOD 0x04 // RW, SPI0 enable 2 wire mode for slave: 0=3wire(SCK0,MOSI,MISO), 1=2wire(SCK0,MISO=MXSX)
#define RB_SPI_MST_SCK_MOD 0x08 // RW, SPI master clock mode: 0=mode 0, 1=mode 3
#define RB_SPI_SLV_CMD_MOD 0x08 // RW, SPI0 slave command mode: 0=byte stream, 1=first byte command
#define RB_SPI_FIFO_DIR 0x10 // RW, SPI FIFO direction: 0=out(write @master mode), 1=in(read @master mode)
#define RB_SPI_SCK_OE 0x20 // RW, SPI SCK output enable
#define RB_SPI_MOSI_OE 0x40 // RW, SPI MOSI output enable
#define RB_SPI_MISO_OE 0x80 // RW, SPI MISO output enable
#define SPI_CTRL_CFG 1
#define RB_SPI_DMA_ENABLE 0x01 // RW, SPI0 DMA enable
#define RB_SPI_DMA_LOOP 0x04 // RW, SPI0 DMA address loop enable
#define RB_SPI_AUTO_IF 0x10 // RW, enable buffer/FIFO accessing to auto clear RB_SPI_IF_BYTE_END interrupt flag
#define RB_SPI_BIT_ORDER 0x20 // RW, SPI bit data order: 0=MSB first, 1=LSB first
#define RB_SPI_MST_DLY_EN 0x40 // RW, SPI master input delay enable
#define SPI_INTER_EN 2
#define RB_SPI_IE_CNT_END 0x01 // RW, enable interrupt for SPI total byte count end
#define RB_SPI_IE_BYTE_END 0x02 // RW, enable interrupt for SPI byte exchanged
#define RB_SPI_IE_FIFO_HF 0x04 // RW, enable interrupt for SPI FIFO half
#define RB_SPI_IE_DMA_END 0x08 // RW, enable interrupt for SPI0 DMA completion
#define RB_SPI_IE_FIFO_OV 0x10 // RW, enable interrupt for SPI0 FIFO overflow
#define RB_SPI_IE_FST_BYTE 0x80 // RW, enable interrupt for SPI0 slave mode first byte received
#define SPI_CLOCK_DIV 3
#define SPI_SLAVE_PRESET 3
#define SPI_BUFFER 4
#define SPI_RUN_FLAG 5
#define RB_SPI_SLV_CMD_ACT 0x10 // RO, SPI0 slave first byte / command flag
#define RB_SPI_FIFO_READY 0x20 // RO, SPI FIFO ready status
#define RB_SPI_SLV_CS_LOAD 0x40 // RO, SPI0 slave chip-select loading status
#define RB_SPI_SLV_SELECT 0x80 // RO, SPI0 slave selection status
#define SPI_INT_FLAG 6
#define RB_SPI_IF_CNT_END 0x01 // RW1, interrupt flag for SPI total byte count end
#define RB_SPI_IF_BYTE_END 0x02 // RW1, interrupt flag for SPI byte exchanged
#define RB_SPI_IF_FIFO_HF 0x04 // RW1, interrupt flag for SPI FIFO half (RB_SPI_FIFO_DIR ? >=4bytes : <4bytes)
#define RB_SPI_IF_DMA_END 0x08 // RW1, interrupt flag for SPI0 DMA completion
#define RB_SPI_IF_FIFO_OV 0x10 // RW1, interrupt flag for SPI0 FIFO overflow
#define RB_SPI_FREE 0x40 // RO, current SPI free status
#define RB_SPI_IF_FST_BYTE 0x80 // RW1, interrupt flag for SPI0 slave mode first byte received
#define SPI_FIFO_COUNT 7
#define SPI_TOTAL_CNT 0x0C
#define SPI_FIFO 0x10
#define SPI_DMA_NOW 0x14
#define SPI_DMA_BEG 0x18
#define SPI_DMA_END 0x1C
/* I2C register */
#define R16_I2C_CTRL1 (*((PUINT16V)0x40004800)) // RW, I2C control 1
#define R16_I2C_CTRL2 (*((PUINT16V)0x40004804)) // RW, I2C control 2
#define R16_I2C_OADDR1 (*((PUINT16V)0x40004808)) // RW, I2C own address register 1
#define R16_I2C_OADDR2 (*((PUINT16V)0x4000480C)) // RW, I2C own address register 2
#define R16_I2C_DATAR (*((PUINT16V)0x40004810)) // RW, I2C data register
#define R16_I2C_STAR1 (*((PUINT16V)0x40004814)) // R0, I2C stauts register 1
#define R16_I2C_STAR2 (*((PUINT16V)0x40004818)) // R0, I2C status register 2
// #define R8_I2C_PEC (*((PUINT8V) 0x40004819)) // R0, I2C Packet error checking register
#define R16_I2C_CKCFGR (*((PUINT16V)0x4000481C)) // RW, I2C clock control register
#define R16_I2C_RTR (*((PUINT16V)0x40004820)) // RW, I2C trise register
/* I2C register address offset and bit define */
#define BA_I2C ((PUINT8V)0x40004800) // point I2C base address
#define I2C_CTRL1 0
#define RB_I2C_PE 0x0001 // RW, Peripheral enable
#define RB_I2C_SMBUS 0x0002 // RW, SMBUS mode: 0=I2C mode, 1=SMBUS mode
#define RB_I2C_SMBTYPE 0x0008 // RW, SMBus type: 0=Device, 1=Host
#define RB_I2C_EBARP 0x0010 // RW, ARP enable
#define RB_I2C_ENPEC 0x0020 // RW, PEC ebable
#define RB_I2C_ENGC 0x0040 // RW, General call enable
#define RB_I2C_NOSTRETCH 0x0080 // RW, Clock stretching disable (Slave mode)
#define RB_I2C_START 0x0100 // RW, Start generation: master mode: 0=no start, 1=repeated start; slave mode: 0=no start, 1=start at bus free
#define RB_I2C_STOP 0x0200 // RW, Stop generation: master mode: 0=no stop, 1=stop after the current byte transfer or after the current Start condition is sent; slave mode: 0=no stop, 1=Release the SCL and SDA lines after the current byte transfer
#define RB_I2C_ACK 0x0400 // RW, Acknowledge enable
#define RB_I2C_POS 0x0800 // RW, Acknowledge/PEC Position (for data reception)
#define RB_I2C_PEC 0x1000 // RW, Packet error checking: 0=No PEC transfer, 1=PEC transfer (in Tx or Rx mode)
#define RB_I2C_ALERT 0x2000 // RW, SMBus alert: 0=Releases SMBA pin high, 1=Drives SMBA pin low.
#define RB_I2C_SWRST 0x8000 // RW, Software reset
#define I2C_CTRL2 4
#define RB_I2C_FREQ 0x003F // RW, Peripheral clock frequency, The minimum allowed frequency is 2 MHz,the maximum frequency is 36 MHz
#define RB_I2C_ITERREN 0x0100 // RW, Error interrupt enable
#define RB_I2C_ITEVTEN 0x0200 // RW, Event interrupt enable
#define RB_I2C_ITBUFEN 0x0400 // RW, Buffer interrupt enable
#define I2C_OADDR1 8
#define RB_I2C_ADD0 0x0001 // RW, bit0 of address in 10-bit addressing mode
#define RB_I2C_ADD7_1 0x00FE // RW, bit[7:1] of address
#define RB_I2C_ADD9_8 0x0300 // RW, bit[9:8] of address in 10-bit addressing mode
#define RB_I2C_ADDMODE 0x8000 // RW, Addressing mode (slave mode): 0=7-bit slave address, 1=10-bit slave address
#define I2C_OADDR2 12
#define RB_I2C_ENDUAL 0x0001 // RW, Dual addressing mode enable
#define RB_I2C_ADD2 0x00FE // RW, bit[7:1] of address2
#define I2C_DATAR 16
#define I2C_STAR1 20
#define RB_I2C_SB 0x0001 // RW0, Start bit flag (Master mode)
#define RB_I2C_ADDR 0x0002 // RW0, Address sent (master mode)/matched (slave mode) flag
#define RB_I2C_BTF 0x0004 // RO, Byte transfer finished flag
#define RB_I2C_ADD10 0x0008 // RO, 10-bit header sent flag (Master mode)
#define RB_I2C_STOPF 0x0010 // RO, Stop detection flag (slave mode)
#define RB_I2C_RxNE 0x0040 // RO, Data register not empty flag (receivers)
#define RB_I2C_TxE 0x0080 // RO, Data register empty flag (transmitters)
#define RB_I2C_BERR 0x0100 // RW0, Bus error flag
#define RB_I2C_ARLO 0x0200 // RW0, Arbitration lost flag (master mode)
#define RB_I2C_AF 0x0400 // RW0, Acknowledge failure flag
#define RB_I2C_OVR 0x0800 // RW0, Overrun/Underrun flag
#define RB_I2C_PECERR 0x1000 // RW0, PEC Error flag in reception
#define RB_I2C_TIMEOUT 0x4000 // RW0, Timeout or Tlow error flag
#define RB_I2C_SMBALERT 0x8000 // RW0, SMBus alert flag
#define I2C_STAR2 24
#define RB_I2C_MSL 0x0001 // RO, Mode statu: 0=Slave mode, 1=Master mode
#define RB_I2C_BUSY 0x0002 // RO, Bus busy flag
#define RB_I2C_TRA 0x0004 // RO, Trans flag: 0=data bytes received, 1=data bytes transmitted
#define RB_I2C_GENCALL 0x0010 // RO, General call address (Slave mode) received flag
#define RB_I2C_SMBDEFAULT 0x0020 // RO, SMBus device default address (Slave mode) received flag
#define RB_I2C_SMBHOST 0x0040 // RO, SMBus host header (Slave mode) received flag
#define RB_I2C_DUALF 0x0080 // RO, Dual flag (Slave mode): 0=Received address matched with OAR1, 1=Received address matched with OAR2
#define RB_I2C_PECX 0xFF00 // RO, Packet error checking register
#define I2C_CKCFGR 28
#define RB_I2C_CCR 0x0FFF // RW, Controls the SCL clock in Fm/Sm mode (Master mode)
#define RB_I2C_DUTY 0x4000 // RW, Fm mode duty cycle: 0=L/H=2, 1=L/H=16/9
#define RB_I2C_F_S 0x8000 // RW, I2C master mode selection: 0=standard mode, 1=fast mode
#define I2C_RTR 32
#define RB_I2C_TRISE 0x003F // RW, Maximum rise time in Fm/Sm mode (Master mode)
/* PWM4/5/6/7/8/9/10/11 register */
#define R32_PWM_CONTROL (*((PUINT32V)0x40005000)) // RW, PWM control
#define R8_PWM_OUT_EN (*((PUINT8V)0x40005000)) // RW, PWM output enable control
#define R8_PWM_POLAR (*((PUINT8V)0x40005001)) // RW, PWM output polarity control
#define R8_PWM_CONFIG (*((PUINT8V)0x40005002)) // RW, PWM configuration
#define R8_PWM_CLOCK_DIV (*((PUINT8V)0x40005003)) // RW, PWM clock divisor
#define R32_PWM4_7_DATA (*((PUINT32V)0x40005004)) // RW, PWM4-7 data holding
#define R8_PWM4_DATA (*((PUINT8V)0x40005004)) // RW, PWM4 data holding
#define R8_PWM5_DATA (*((PUINT8V)0x40005005)) // RW, PWM5 data holding
#define R8_PWM6_DATA (*((PUINT8V)0x40005006)) // RW, PWM6 data holding
#define R8_PWM7_DATA (*((PUINT8V)0x40005007)) // RW, PWM7 data holding
#define R32_PWM8_11_DATA (*((PUINT32V)0x40005008)) // RW, PWM8-11 data holding
#define R8_PWM8_DATA (*((PUINT8V)0x40005008)) // RW, PWM8 data holding
#define R8_PWM9_DATA (*((PUINT8V)0x40005009)) // RW, PWM9 data holding
#define R8_PWM10_DATA (*((PUINT8V)0x4000500A)) // RW, PWM10 data holding
#define R8_PWM11_DATA (*((PUINT8V)0x4000500B)) // RW, PWM11 data holding
#define R8_PWM_INT_CTRL (*((PUINT32V)0x4000500C)) // RW, PWM interrupt control
#define RB_PWM_IE_CYC 0x01 // RW, enable interrupt for PWM cycle end
#define RB_PWM_CYC_PRE 0x02 // RW, select PWM cycle interrupt point: 0=after count 0xFE (0x7E for 7 bits mode...), 1=after count 0xF0 (0x70 for 7 bits mode...)
#define RB_PWM_IF_CYC 0x80 // RW1, interrupt flag for PWM cycle end
#define R32_PWM_REG_DATA8 (*((PUINT32V)0x40005010)) // RW, PWM8-9 data register
#define R32_PWM_REG_CYCLE (*((PUINT32V)0x40005014)) // RW, PWM cycle value
/* PWM4/5/6/7/8/9/10/11 register address offset and bit define */
#define BA_PWMX ((PUINT8V)0x40005000) // point PWM4/5/6/7/8/9/10/11 base address
#define PWM_OUT_EN 0
#define RB_PWM4_OUT_EN 0x01 // RW, PWM4 output enable
#define RB_PWM5_OUT_EN 0x02 // RW, PWM5 output enable
#define RB_PWM6_OUT_EN 0x04 // RW, PWM6 output enable
#define RB_PWM7_OUT_EN 0x08 // RW, PWM7 output enable
#define RB_PWM8_OUT_EN 0x10 // RW, PWM8 output enable
#define RB_PWM9_OUT_EN 0x20 // RW, PWM9 output enable
#define RB_PWM10_OUT_EN 0x40 // RW, PWM10 output enable
#define RB_PWM11_OUT_EN 0x80 // RW, PWM11 output enable
#define PWM_POLAR 1
#define RB_PWM4_POLAR 0x01 // RW, PWM4 output polarity: 0=default low and high action, 1=default high and low action
#define RB_PWM5_POLAR 0x02 // RW, PWM5 output polarity: 0=default low and high action, 1=default high and low action
#define RB_PWM6_POLAR 0x04 // RW, PWM6 output polarity: 0=default low and high action, 1=default high and low action
#define RB_PWM7_POLAR 0x08 // RW, PWM7 output polarity: 0=default low and high action, 1=default high and low action
#define RB_PWM8_POLAR 0x10 // RW, PWM8 output polarity: 0=default low and high action, 1=default high and low action
#define RB_PWM9_POLAR 0x20 // RW, PWM9 output polarity: 0=default low and high action, 1=default high and low action
#define RB_PWM10_POLAR 0x40 // RW, PWM10 output polarity: 0=default low and high action, 1=default high and low action
#define RB_PWM11_POLAR 0x80 // RW, PWM11 output polarity: 0=default low and high action, 1=default high and low action
#define PWM_CONFIG 2
#define RB_PWM_CYCLE_SEL 0x01 // RW, PWM cycle selection: 0=256/128/64/32 clocks, 1=255/127/63/31 clocks
#define RB_PWM_STAG_ST 0x02 // RO, PWM stagger cycle status
#define RB_PWM_CYC_MOD 0x0C // RW, PWM data width mode: 00=8 bits data, 01=7 bits data, 10=6 bits data, 11=16 bits data
#define RB_PWM4_5_STAG_EN 0x10 // RW, PWM4/5 stagger output enable: 0=independent output, 1=stagger output
#define RB_PWM6_7_STAG_EN 0x20 // RW, PWM6/7 stagger output enable: 0=independent output, 1=stagger output
#define RB_PWM8_9_STAG_EN 0x40 // RW, PWM8/9 stagger output enable: 0=independent output, 1=stagger output
#define RB_PWM10_11_STAG_EN 0x80 // RW, PWM10/11 stagger output enable: 0=independent output, 1=stagger output
#define PWM_CLOCK_DIV 3
#define PWM4_DATA_HOLD 4
#define PWM5_DATA_HOLD 5
#define PWM6_DATA_HOLD 6
#define PWM7_DATA_HOLD 7
#define PWM8_DATA_HOLD 8
#define PWM9_DATA_HOLD 9
#define PWM10_DATA_HOLD 10
#define PWM11_DATA_HOLD 11
/* LCD register */
#define R32_LCD_CMD (*((PUINT32V)(0x40006000)))
#define RB_LCD_SYS_EN 0x01 // RW, LCD digital system enable
#define RB_LCD_ON 0x02 // RW, LCD analog system enable
#define RB_LCD_BIAS 0x04 // RW, LCD bias select: 0=1/2 bias, 1=1/3 bias
#define RB_LCD_DUTY 0x18 // RW, LCD duty select: 00=1/2 duty, 01=1/3 duty, 10=1/4 duty
#define RB_LCD_SCAN_CLK 0x60 // RW, LCD scan clock select: 00=256Hz, 01=512Hz, 10=1KHz, 11=128Hz
#define RB_LCD_VLCD_SEL 0x80 // RW, LCD drive voltage0=VIO33*100%(3.3V),1=VIO33*76%(2.5V)
#define RB_LCD_SEG0_7_EN 0xFF00 // RW, SEG0-SEG7 enable
#define RB_LCD_SEG8_15_EN 0xFF0000 // RW, SEG8-SEG15 enable
#define RB_LCD_SEG16_19_EN 0xF000000 // RW, SEG16-SEG19 enable
#define R32_LCD_RAM0 (*((PUINT32V)(0x40006004))) // RW, LCD driver data0, address 0-3
#define R32_LCD_RAM1 (*((PUINT32V)(0x40006008))) // RW, LCD driver data1, address 4-7
#define R32_LCD_RAM2 (*((PUINT32V)(0x4000600C))) // RW, LCD driver data2, address 8-12
/* Address space define */
#define BA_CODE ((PUINT32)0x00000000) // point code base address
#define SZ_CODE 0x00080000 // code size
#define BA_SFR ((PUINT32)0x40000000) // point SFR base address
#define SZ_SFR 0x00010000 // SFR size
#define BA_RAM ((PUINT32)0x20000000) // point RAM base address
#define SZ_RAM 0x00006800 // RAM size
/* Special Program Space */
#define DATA_FLASH_ADDR 0x70000 // start address of Data-Flash
#define DATA_FLASH_SIZE 0x8000 // size of Data-Flash
#define BOOT_LOAD_ADDR 0x78000 // start address of boot loader program
#define BOOT_LOAD_SIZE 0x6000 // size of boot loader program
#define BOOT_LOAD_CFG 0x7E000 // start address of configuration information for boot loader program
#define ROM_CFG_ADDR 0x7F000 // chip configuration information address
/*----- Reference Information --------------------------------------------*/
#define ID_CH592 0x92 // chip ID
#define ID_CH591 0x91 // chip ID
/* Interrupt routine address and interrupt number */
#define INT_ID_TMR0 16 // interrupt number for Timer0
#define INT_ID_GPIO_A 17 // interrupt number for GPIO port A
#define INT_ID_GPIO_B 18 // interrupt number for GPIO port B
#define INT_ID_SPI0 19 // interrupt number for SPI0
#define INT_ID_BLEB 20 // interrupt number for BLEBB
#define INT_ID_BLEL 21 // interrupt number for BLELLE
#define INT_ID_USB 22 // interrupt number for USB
#define INT_ID_TMR1 24 // interrupt number for Timer1
#define INT_ID_TMR2 25 // interrupt number for Timer2
#define INT_ID_UART0 26 // interrupt number for UART0
#define INT_ID_UART1 27 // interrupt number for UART1
#define INT_ID_RTC 28 // interrupt number for RTC
#define INT_ID_ADC 29 // interrupt number for ADC and TouchKey
#define INT_ID_I2C 30 // interrupt number for I2C
#define INT_ID_PWMX 31 // interrupt number for PWM4~11
#define INT_ID_TMR3 32 // interrupt number for Timer3
#define INT_ID_UART2 33 // interrupt number for UART2
#define INT_ID_UART3 34 // interrupt number for UART3
#define INT_ID_WDOG_BAT 35 // interrupt number for Watch-Dog timer and Battery low voltage
#define INT_VEC_ENTRY_SZ 4 // size of each interrupt vector entry
#define INT_ADDR_TMR0 (INT_ID_TMR0*INT_VEC_ENTRY_SZ) // interrupt vector address for Timer0
#define INT_ADDR_GPIO_A (INT_ID_GPIO_A*INT_VEC_ENTRY_SZ) // interrupt vector address for GPIO port A
#define INT_ADDR_GPIO_B (INT_ID_GPIO_B*INT_VEC_ENTRY_SZ) // interrupt vector address for GPIO port B
#define INT_ADDR_SPI0 (INT_ID_SPI0*INT_VEC_ENTRY_SZ) // interrupt vector address for SPI0
#define INT_ADDR_BLEB (INT_ID_BLEB*INT_VEC_ENTRY_SZ) // interrupt vector address for BLEBB
#define INT_ADDR_BLEL (INT_ID_BLEL*INT_VEC_ENTRY_SZ) // interrupt vector address for BLELLE
#define INT_ADDR_USB (INT_ID_USB*INT_VEC_ENTRY_SZ) // interrupt vector address for USB
#define INT_ADDR_TMR1 (INT_ID_TMR1*INT_VEC_ENTRY_SZ) // interrupt vector address for Timer1
#define INT_ADDR_TMR2 (INT_ID_TMR2*INT_VEC_ENTRY_SZ) // interrupt vector address for Timer2
#define INT_ADDR_UART0 (INT_ID_UART0*INT_VEC_ENTRY_SZ) // interrupt vector address for UART0
#define INT_ADDR_UART1 (INT_ID_UART1*INT_VEC_ENTRY_SZ) // interrupt vector address for UART1
#define INT_ADDR_RTC (INT_ID_RTC*INT_VEC_ENTRY_SZ) // interrupt vector address for RTC
#define INT_ADDR_ADC (INT_ID_ADC*INT_VEC_ENTRY_SZ) // interrupt vector address for ADC and TouchKey
#define INT_ADDR_I2C (INT_ID_I2C*INT_VEC_ENTRY_SZ) // interrupt vector address for I2C
#define INT_ADDR_PWMX (INT_ID_PWMX*INT_VEC_ENTRY_SZ) // interrupt vector address for PWM4~11
#define INT_ADDR_TMR3 (INT_ID_TMR3*INT_VEC_ENTRY_SZ) // interrupt vector address for Timer3
#define INT_ADDR_UART2 (INT_ID_UART2*INT_VEC_ENTRY_SZ) // interrupt vector address for UART2
#define INT_ADDR_UART3 (INT_ID_UART3*INT_VEC_ENTRY_SZ) // interrupt vector address for UART3
#define INT_ADDR_WDOG_BAT (INT_ID_WDOG_BAT*INT_VEC_ENTRY_SZ) // interrupt vector address for Watch-Dog timer and Battery low voltage
#ifndef TABLE_IRQN
#define __PFIC_PRIO_BITS 2 /*!< uses 8 Bits for the Priority Levels */
#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */
typedef enum IRQn
{
Reset_IRQn = 1,
NMI_IRQn = 2, /*!< Non Maskable Interrupt */
EXC_IRQn = 3, /*!< Exceptions Interrupt */
SysTick_IRQn = 12, /*!< System timer Interrupt */
SWI_IRQn = 14, /*!< software Interrupt */
TMR0_IRQn = 16,
GPIO_A_IRQn = 17,
GPIO_B_IRQn = 18,
SPI0_IRQn = 19,
BLEB_IRQn = 20,
BLEL_IRQn = 21,
USB_IRQn = 22,
TMR1_IRQn = 24,
TMR2_IRQn = 25,
UART0_IRQn = 26,
UART1_IRQn = 27,
RTC_IRQn = 28,
ADC_IRQn = 29,
I2C_IRQn = 30,
PWMX_IRQn = 31,
TMR3_IRQn = 32,
UART2_IRQn = 33,
UART3_IRQn = 34,
WDOG_BAT_IRQn = 35
} IRQn_Type;
#endif
#ifdef __cplusplus
}
#endif
#endif // __CH592SFR_H__
#ifndef __CH592USBSFR_H__
#define __CH592USBSFR_H__
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************************************/
/* Peripheral memory map */
/******************************************************************************/
/* usb addresses
// USB: +8000H - 83FFH */
#define USB_BASE_ADDR (0x40008000)
#define BA_USB ((PUINT8V)0x40008000) // point USB base address
/* USB */
#define R32_USB_CONTROL (*((PUINT32V)0x40008000)) // USB control & interrupt enable & device address
#define R8_USB_CTRL (*((PUINT8V)0x40008000)) // USB base control
#define RB_UC_HOST_MODE 0x80 // enable USB host mode: 0=device mode, 1=host mode
#define RB_UC_LOW_SPEED 0x40 // enable USB low speed: 0=12Mbps, 1=1.5Mbps
#define RB_UC_DEV_PU_EN 0x20 // USB device enable and internal pullup resistance enable
#define RB_UC_SYS_CTRL1 0x20 // USB system control high bit
#define RB_UC_SYS_CTRL0 0x10 // USB system control low bit
#define MASK_UC_SYS_CTRL 0x30 // bit mask of USB system control
// bUC_HOST_MODE & bUC_SYS_CTRL1 & bUC_SYS_CTRL0: USB system control
// 0 00: disable USB device and disable internal pullup resistance
// 0 01: enable USB device and disable internal pullup resistance, need RB_PIN_USB_DP_PU=1 or need external pullup resistance
// 0 1x: enable USB device and enable internal pullup resistance
// 1 00: enable USB host and normal status
// 1 01: enable USB host and force UDP/UDM output SE0 state
// 1 10: enable USB host and force UDP/UDM output J state
// 1 11: enable USB host and force UDP/UDM output resume or K state
#define RB_UC_INT_BUSY 0x08 // enable automatic responding busy for device mode or automatic pause for host mode during interrupt flag UIF_TRANSFER valid
#define RB_UC_RESET_SIE 0x04 // force reset USB SIE, need software clear
#define RB_UC_CLR_ALL 0x02 // force clear FIFO and count of USB
#define RB_UC_DMA_EN 0x01 // DMA enable and DMA interrupt enable for USB
#define R8_UDEV_CTRL (*((PUINT8V)0x40008001)) // USB device physical prot control
#define RB_UD_PD_DIS 0x80 // disable USB UDP/UDM pulldown resistance: 0=enable pulldown, 1=disable
#define RB_UD_DP_PIN 0x20 // ReadOnly: indicate current UDP pin level
#define RB_UD_DM_PIN 0x10 // ReadOnly: indicate current UDM pin level
#define RB_UD_LOW_SPEED 0x04 // enable USB physical port low speed: 0=full speed, 1=low speed
#define RB_UD_GP_BIT 0x02 // general purpose bit
#define RB_UD_PORT_EN 0x01 // enable USB physical port I/O: 0=disable, 1=enable
#define R8_UHOST_CTRL R8_UDEV_CTRL // USB host physical prot control
#define RB_UH_PD_DIS 0x80 // disable USB UDP/UDM pulldown resistance: 0=enable pulldown, 1=disable
#define RB_UH_DP_PIN 0x20 // ReadOnly: indicate current UDP pin level
#define RB_UH_DM_PIN 0x10 // ReadOnly: indicate current UDM pin level
#define RB_UH_LOW_SPEED 0x04 // enable USB port low speed: 0=full speed, 1=low speed
#define RB_UH_BUS_RESET 0x02 // control USB bus reset: 0=normal, 1=force bus reset
#define RB_UH_PORT_EN 0x01 // enable USB port: 0=disable, 1=enable port, automatic disabled if USB device detached
#define R8_USB_INT_EN (*((PUINT8V)0x40008002)) // USB interrupt enable
#define RB_UIE_DEV_SOF 0x80 // enable interrupt for SOF received for USB device mode
#define RB_UIE_DEV_NAK 0x40 // enable interrupt for NAK responded for USB device mode
#define RB_MOD_1_WIRE 0x20 // enable single wire mode
#define RB_UIE_FIFO_OV 0x10 // enable interrupt for FIFO overflow
#define RB_UIE_HST_SOF 0x08 // enable interrupt for host SOF timer action for USB host mode
#define RB_UIE_SUSPEND 0x04 // enable interrupt for USB suspend or resume event
#define RB_UIE_TRANSFER 0x02 // enable interrupt for USB transfer completion
#define RB_UIE_DETECT 0x01 // enable interrupt for USB device detected event for USB host mode
#define RB_UIE_BUS_RST 0x01 // enable interrupt for USB bus reset event for USB device mode
#define R8_USB_DEV_AD (*((PUINT8V)0x40008003)) // USB device address
#define RB_UDA_GP_BIT 0x80 // general purpose bit
#define MASK_USB_ADDR 0x7F // bit mask for USB device address
#define R32_USB_STATUS (*((PUINT32V)0x40008004)) // USB miscellaneous status & interrupt flag & interrupt status
#define R8_USB_MIS_ST (*((PUINT8V)0x40008005)) // USB miscellaneous status
#define RB_UMS_SOF_PRES 0x80 // RO, indicate host SOF timer presage status
#define RB_UMS_SOF_ACT 0x40 // RO, indicate host SOF timer action status for USB host
#define RB_UMS_SIE_FREE 0x20 // RO, indicate USB SIE free status
#define RB_UMS_R_FIFO_RDY 0x10 // RO, indicate USB receiving FIFO ready status (not empty)
#define RB_UMS_BUS_RESET 0x08 // RO, indicate USB bus reset status
#define RB_UMS_SUSPEND 0x04 // RO, indicate USB suspend status
#define RB_UMS_DM_LEVEL 0x02 // RO, indicate UDM level saved at device attached to USB host
#define RB_UMS_DEV_ATTACH 0x01 // RO, indicate device attached status on USB host
#define R8_USB_INT_FG (*((PUINT8V)0x40008006)) // USB interrupt flag
#define RB_U_IS_NAK 0x80 // RO, indicate current USB transfer is NAK received
#define RB_U_TOG_OK 0x40 // RO, indicate current USB transfer toggle is OK
#define RB_U_SIE_FREE 0x20 // RO, indicate USB SIE free status
#define RB_UIF_FIFO_OV 0x10 // FIFO overflow interrupt flag for USB, direct bit address clear or write 1 to clear
#define RB_UIF_HST_SOF 0x08 // host SOF timer interrupt flag for USB host, direct bit address clear or write 1 to clear
#define RB_UIF_SUSPEND 0x04 // USB suspend or resume event interrupt flag, direct bit address clear or write 1 to clear
#define RB_UIF_TRANSFER 0x02 // USB transfer completion interrupt flag, direct bit address clear or write 1 to clear
#define RB_UIF_DETECT 0x01 // device detected event interrupt flag for USB host mode, direct bit address clear or write 1 to clear
#define RB_UIF_BUS_RST 0x01 // bus reset event interrupt flag for USB device mode, direct bit address clear or write 1 to clear
#define R8_USB_INT_ST (*((PUINT8V)0x40008007)) // USB interrupt status
#define RB_UIS_SETUP_ACT 0x80 // RO, indicate SETUP token & 8 bytes setup request received for USB device mode
#define RB_UIS_TOG_OK 0x40 // RO, indicate current USB transfer toggle is OK
#define RB_UIS_TOKEN1 0x20 // RO, current token PID code bit 1 received for USB device mode
#define RB_UIS_TOKEN0 0x10 // RO, current token PID code bit 0 received for USB device mode
#define MASK_UIS_TOKEN 0x30 // RO, bit mask of current token PID code received for USB device mode
#define UIS_TOKEN_OUT 0x00
#define UIS_TOKEN_SOF 0x10
#define UIS_TOKEN_IN 0x20
#define UIS_TOKEN_SETUP 0x30
// bUIS_TOKEN1 & bUIS_TOKEN0: current token PID code received for USB device mode, keep last status during SETUP token, clear RB_UIF_TRANSFER ( RB_UIF_TRANSFER from 1 to 0 ) to set free
// 00: OUT token PID received
// 01: SOF token PID received
// 10: IN token PID received
// 11: free
#define MASK_UIS_ENDP 0x0F // RO, bit mask of current transfer endpoint number for USB device mode
#define MASK_UIS_H_RES 0x0F // RO, bit mask of current transfer handshake response for USB host mode: 0000=no response, time out from device, others=handshake response PID received
#define R8_USB_RX_LEN (*((PUINT8V)0x40008008)) // USB receiving length
#define R32_USB_BUF_MODE (*((PUINT32V)0x4000800C)) // USB endpoint buffer mode
#define R8_UEP4_1_MOD (*((PUINT8V)0x4000800C)) // endpoint 4/1 mode
#define RB_UEP1_RX_EN 0x80 // enable USB endpoint 1 receiving (OUT)
#define RB_UEP1_TX_EN 0x40 // enable USB endpoint 1 transmittal (IN)
#define RB_UEP1_BUF_MOD 0x10 // buffer mode of USB endpoint 1
// bUEPn_RX_EN & bUEPn_TX_EN & bUEPn_BUF_MOD: USB endpoint 1/2/3 buffer mode, buffer start address is UEPn_DMA
// 0 0 x: disable endpoint and disable buffer
// 1 0 0: 64 bytes buffer for receiving (OUT endpoint)
// 1 0 1: dual 64 bytes buffer by toggle bit bUEP_R_TOG selection for receiving (OUT endpoint), total=128bytes
// 0 1 0: 64 bytes buffer for transmittal (IN endpoint)
// 0 1 1: dual 64 bytes buffer by toggle bit bUEP_T_TOG selection for transmittal (IN endpoint), total=128bytes
// 1 1 0: 64 bytes buffer for receiving (OUT endpoint) + 64 bytes buffer for transmittal (IN endpoint), total=128bytes
// 1 1 1: dual 64 bytes buffer by bUEP_R_TOG selection for receiving (OUT endpoint) + dual 64 bytes buffer by bUEP_T_TOG selection for transmittal (IN endpoint), total=256bytes
#define RB_UEP4_RX_EN 0x08 // enable USB endpoint 4 receiving (OUT)
#define RB_UEP4_TX_EN 0x04 // enable USB endpoint 4 transmittal (IN)
// bUEP4_RX_EN & bUEP4_TX_EN: USB endpoint 4 buffer mode, buffer start address is UEP0_DMA
// 0 0: single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint)
// 1 0: single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint) + 64 bytes buffer for endpoint 4 receiving (OUT endpoint), total=128bytes
// 0 1: single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint) + 64 bytes buffer for endpoint 4 transmittal (IN endpoint), total=128bytes
// 1 1: single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint)
// + 64 bytes buffer for endpoint 4 receiving (OUT endpoint) + 64 bytes buffer for endpoint 4 transmittal (IN endpoint), total=192bytes
#define R8_UEP2_3_MOD (*((PUINT8V)0x4000800D)) // endpoint 2/3 mode
#define RB_UEP3_RX_EN 0x80 // enable USB endpoint 3 receiving (OUT)
#define RB_UEP3_TX_EN 0x40 // enable USB endpoint 3 transmittal (IN)
#define RB_UEP3_BUF_MOD 0x10 // buffer mode of USB endpoint 3
#define RB_UEP2_RX_EN 0x08 // enable USB endpoint 2 receiving (OUT)
#define RB_UEP2_TX_EN 0x04 // enable USB endpoint 2 transmittal (IN)
#define RB_UEP2_BUF_MOD 0x01 // buffer mode of USB endpoint 2
#define R8_UEP567_MOD (*((PUINT8V)0x4000800E)) // endpoint 5/6/7 mode
#define RB_UEP7_RX_EN 0x20 // enable USB endpoint 7 receiving (OUT)
#define RB_UEP7_TX_EN 0x10 // enable USB endpoint 7 transmittal (IN)
#define RB_UEP6_RX_EN 0x08 // enable USB endpoint 6 receiving (OUT)
#define RB_UEP6_TX_EN 0x04 // enable USB endpoint 6 transmittal (IN)
#define RB_UEP5_RX_EN 0x02 // enable USB endpoint 5 receiving (OUT)
#define RB_UEP5_TX_EN 0x01 // enable USB endpoint 5 transmittal (IN)
// bUEPn_RX_EN & bUEPn_TX_EN: USB endpoint 5/6/7 buffer mode, buffer start address is UEPn_DMA
// 0 0: disable endpoint and disable buffer
// 1 0: 64 bytes buffer for receiving (OUT endpoint)
// 0 1: 64 bytes buffer for transmittal (IN endpoint)
// 1 1: 64 bytes buffer for receiving (OUT endpoint) + 64 bytes buffer for transmittal (IN endpoint), total=128bytes
#define R8_UH_EP_MOD R8_UEP2_3_MOD //host endpoint mode
#define RB_UH_EP_TX_EN 0x40 // enable USB host OUT endpoint transmittal
#define RB_UH_EP_TBUF_MOD 0x10 // buffer mode of USB host OUT endpoint
// bUH_EP_TX_EN & bUH_EP_TBUF_MOD: USB host OUT endpoint buffer mode, buffer start address is UH_TX_DMA
// 0 x: disable endpoint and disable buffer
// 1 0: 64 bytes buffer for transmittal (OUT endpoint)
// 1 1: dual 64 bytes buffer by toggle bit bUH_T_TOG selection for transmittal (OUT endpoint), total=128bytes
#define RB_UH_EP_RX_EN 0x08 // enable USB host IN endpoint receiving
#define RB_UH_EP_RBUF_MOD 0x01 // buffer mode of USB host IN endpoint
// bUH_EP_RX_EN & bUH_EP_RBUF_MOD: USB host IN endpoint buffer mode, buffer start address is UH_RX_DMA
// 0 x: disable endpoint and disable buffer
// 1 0: 64 bytes buffer for receiving (IN endpoint)
// 1 1: dual 64 bytes buffer by toggle bit bUH_R_TOG selection for receiving (IN endpoint), total=128bytes
#define R16_UEP0_DMA (*((PUINT16V)0x40008010)) // endpoint 0 DMA buffer address
#define R16_UEP1_DMA (*((PUINT16V)0x40008014)) // endpoint 1 DMA buffer address
#define R16_UEP2_DMA (*((PUINT16V)0x40008018)) // endpoint 2 DMA buffer address
#define R16_UH_RX_DMA R16_UEP2_DMA // host rx endpoint buffer address
#define R16_UEP3_DMA (*((PUINT16V)0x4000801C)) // endpoint 3 DMA buffer address
#define R16_UH_TX_DMA R16_UEP3_DMA // host tx endpoint buffer address
#define R16_UEP5_DMA (*((PUINT16V)0x40008054)) // endpoint 5 DMA buffer address
#define R16_UEP6_DMA (*((PUINT16V)0x40008058)) // endpoint 6 DMA buffer address
#define R16_UEP7_DMA (*((PUINT16V)0x4000805C)) // endpoint 7 DMA buffer address
#define R32_USB_EP0_CTRL (*((PUINT32V)0x40008020)) // endpoint 0 control & transmittal length
#define R8_UEP0_T_LEN (*((PUINT8V)0x40008020)) // endpoint 0 transmittal length
#define R8_UEP0_CTRL (*((PUINT8V)0x40008022)) // endpoint 0 control
#define R32_USB_EP1_CTRL (*((PUINT32V)0x40008024)) // endpoint 1 control & transmittal length
#define R8_UEP1_T_LEN (*((PUINT8V)0x40008024)) // endpoint 1 transmittal length
#define R8_UEP1_CTRL (*((PUINT8V)0x40008026)) // endpoint 1 control
#define RB_UEP_R_TOG 0x80 // expected data toggle flag of USB endpoint X receiving (OUT): 0=DATA0, 1=DATA1
#define RB_UEP_T_TOG 0x40 // prepared data toggle flag of USB endpoint X transmittal (IN): 0=DATA0, 1=DATA1
#define RB_UEP_AUTO_TOG 0x10 // enable automatic toggle after successful transfer completion on endpoint 1/2/3: 0=manual toggle, 1=automatic toggle
#define RB_UEP_R_RES1 0x08 // handshake response type high bit for USB endpoint X receiving (OUT)
#define RB_UEP_R_RES0 0x04 // handshake response type low bit for USB endpoint X receiving (OUT)
#define MASK_UEP_R_RES 0x0C // bit mask of handshake response type for USB endpoint X receiving (OUT)
#define UEP_R_RES_ACK 0x00
#define UEP_R_RES_TOUT 0x04
#define UEP_R_RES_NAK 0x08
#define UEP_R_RES_STALL 0x0C
// RB_UEP_R_RES1 & RB_UEP_R_RES0: handshake response type for USB endpoint X receiving (OUT)
// 00: ACK (ready)
// 01: no response, time out to host, for non-zero endpoint isochronous transactions
// 10: NAK (busy)
// 11: STALL (error)
#define RB_UEP_T_RES1 0x02 // handshake response type high bit for USB endpoint X transmittal (IN)
#define RB_UEP_T_RES0 0x01 // handshake response type low bit for USB endpoint X transmittal (IN)
#define MASK_UEP_T_RES 0x03 // bit mask of handshake response type for USB endpoint X transmittal (IN)
#define UEP_T_RES_ACK 0x00
#define UEP_T_RES_TOUT 0x01
#define UEP_T_RES_NAK 0x02
#define UEP_T_RES_STALL 0x03
// bUEP_T_RES1 & bUEP_T_RES0: handshake response type for USB endpoint X transmittal (IN)
// 00: DATA0 or DATA1 then expecting ACK (ready)
// 01: DATA0 or DATA1 then expecting no response, time out from host, for non-zero endpoint isochronous transactions
// 10: NAK (busy)
// 11: STALL (error)
#define R8_UH_SETUP R8_UEP1_CTRL // host aux setup
#define RB_UH_PRE_PID_EN 0x80 // USB host PRE PID enable for low speed device via hub
#define RB_UH_SOF_EN 0x40 // USB host automatic SOF enable
#define R32_USB_EP2_CTRL (*((PUINT32V)0x40008028)) // endpoint 2 control & transmittal length
#define R8_UEP2_T_LEN (*((PUINT8V)0x40008028)) // endpoint 2 transmittal length
#define R8_UEP2_CTRL (*((PUINT8V)0x4000802A)) // endpoint 2 control
#define R8_UH_EP_PID R8_UEP2_T_LEN // host endpoint and PID
#define MASK_UH_TOKEN 0xF0 // bit mask of token PID for USB host transfer
#define MASK_UH_ENDP 0x0F // bit mask of endpoint number for USB host transfer
#define R8_UH_RX_CTRL R8_UEP2_CTRL // host receiver endpoint control
#define RB_UH_R_TOG 0x80 // expected data toggle flag of host receiving (IN): 0=DATA0, 1=DATA1
#define RB_UH_R_AUTO_TOG 0x10 // enable automatic toggle after successful transfer completion: 0=manual toggle, 1=automatic toggle
#define RB_UH_R_RES 0x04 // prepared handshake response type for host receiving (IN): 0=ACK (ready), 1=no response, time out to device, for isochronous transactions
#define R32_USB_EP3_CTRL (*((PUINT32V)0x4000802c)) // endpoint 3 control & transmittal length
#define R8_UEP3_T_LEN (*((PUINT8V)0x4000802c)) // endpoint 3 transmittal length
#define R8_UEP3_CTRL (*((PUINT8V)0x4000802e)) // endpoint 3 control
#define R8_UH_TX_LEN R8_UEP3_T_LEN // host transmittal endpoint transmittal length
#define R8_UH_TX_CTRL R8_UEP3_CTRL // host transmittal endpoint control
#define RB_UH_T_TOG 0x40 // prepared data toggle flag of host transmittal (SETUP/OUT): 0=DATA0, 1=DATA1
#define RB_UH_T_AUTO_TOG 0x10 // enable automatic toggle after successful transfer completion: 0=manual toggle, 1=automatic toggle
#define RB_UH_T_RES 0x01 // expected handshake response type for host transmittal (SETUP/OUT): 0=ACK (ready), 1=no response, time out from device, for isochronous transactions
#define R32_USB_EP4_CTRL (*((PUINT32V)0x40008030)) // endpoint 4 control & transmittal length
#define R8_UEP4_T_LEN (*((PUINT8V)0x40008030)) // endpoint 4 transmittal length
#define R8_UEP4_CTRL (*((PUINT8V)0x40008032)) // endpoint 4 control
#define R32_USB_EP5_CTRL (*((PUINT32V)0x40008064)) // endpoint 5 control & transmittal length
#define R8_UEP5_T_LEN (*((PUINT8V)0x40008064)) // endpoint 5 transmittal length
#define R8_UEP5_CTRL (*((PUINT8V)0x40008066)) // endpoint 5 control
#define R32_USB_EP6_CTRL (*((PUINT32V)0x40008068)) // endpoint 6 control & transmittal length
#define R8_UEP6_T_LEN (*((PUINT8V)0x40008068)) // endpoint 6 transmittal length
#define R8_UEP6_CTRL (*((PUINT8V)0x4000806A)) // endpoint 6 control
#define R32_USB_EP7_CTRL (*((PUINT32V)0x4000806C)) // endpoint 7 control & transmittal length
#define R8_UEP7_T_LEN (*((PUINT8V)0x4000806C)) // endpoint 7 transmittal length
#define R8_UEP7_CTRL (*((PUINT8V)0x4000806E)) // endpoint 7 control
#ifdef __cplusplus
}
#endif
#endif //__CH592USBSFR_H__
#ifndef __USB_TYPE__
#define __USB_TYPE__
#ifdef __cplusplus
extern "C" {
#endif
/*----- USB constant and structure define --------------------------------*/
/* USB PID */
#ifndef USB_PID_SETUP
#define USB_PID_NULL 0x00 /* reserved PID */
#define USB_PID_SOF 0x05
#define USB_PID_SETUP 0x0D
#define USB_PID_IN 0x09
#define USB_PID_OUT 0x01
#define USB_PID_ACK 0x02
#define USB_PID_NAK 0x0A
#define USB_PID_STALL 0x0E
#define USB_PID_DATA0 0x03
#define USB_PID_DATA1 0x0B
#define USB_PID_PRE 0x0C
#endif
/* USB standard device request code */
#ifndef USB_GET_DESCRIPTOR
#define USB_GET_STATUS 0x00
#define USB_CLEAR_FEATURE 0x01
#define USB_SET_FEATURE 0x03
#define USB_SET_ADDRESS 0x05
#define USB_GET_DESCRIPTOR 0x06
#define USB_SET_DESCRIPTOR 0x07
#define USB_GET_CONFIGURATION 0x08
#define USB_SET_CONFIGURATION 0x09
#define USB_GET_INTERFACE 0x0A
#define USB_SET_INTERFACE 0x0B
#define USB_SYNCH_FRAME 0x0C
#endif
/* USB hub class request code */
#ifndef HUB_GET_DESCRIPTOR
#define HUB_GET_STATUS 0x00
#define HUB_CLEAR_FEATURE 0x01
#define HUB_GET_STATE 0x02
#define HUB_SET_FEATURE 0x03
#define HUB_GET_DESCRIPTOR 0x06
#define HUB_SET_DESCRIPTOR 0x07
#endif
/* USB HID class request code */
#ifndef HID_GET_REPORT
#define HID_GET_REPORT 0x01
#define HID_GET_IDLE 0x02
#define HID_GET_PROTOCOL 0x03
#define HID_SET_REPORT 0x09
#define HID_SET_IDLE 0x0A
#define HID_SET_PROTOCOL 0x0B
#endif
/* Bit define for USB request type */
#ifndef USB_REQ_TYP_MASK
#define USB_REQ_TYP_IN 0x80 /* control IN, device to host */
#define USB_REQ_TYP_OUT 0x00 /* control OUT, host to device */
#define USB_REQ_TYP_READ 0x80 /* control read, device to host */
#define USB_REQ_TYP_WRITE 0x00 /* control write, host to device */
#define USB_REQ_TYP_MASK 0x60 /* bit mask of request type */
#define USB_REQ_TYP_STANDARD 0x00
#define USB_REQ_TYP_CLASS 0x20
#define USB_REQ_TYP_VENDOR 0x40
#define USB_REQ_TYP_RESERVED 0x60
#define USB_REQ_RECIP_MASK 0x1F /* bit mask of request recipient */
#define USB_REQ_RECIP_DEVICE 0x00
#define USB_REQ_RECIP_INTERF 0x01
#define USB_REQ_RECIP_ENDP 0x02
#define USB_REQ_RECIP_OTHER 0x03
#endif
/* USB request type for hub class request */
#ifndef HUB_GET_HUB_DESCRIPTOR
#define HUB_CLEAR_HUB_FEATURE 0x20
#define HUB_CLEAR_PORT_FEATURE 0x23
#define HUB_GET_BUS_STATE 0xA3
#define HUB_GET_HUB_DESCRIPTOR 0xA0
#define HUB_GET_HUB_STATUS 0xA0
#define HUB_GET_PORT_STATUS 0xA3
#define HUB_SET_HUB_DESCRIPTOR 0x20
#define HUB_SET_HUB_FEATURE 0x20
#define HUB_SET_PORT_FEATURE 0x23
#endif
/* Hub class feature selectors */
#ifndef HUB_PORT_RESET
#define HUB_C_HUB_LOCAL_POWER 0
#define HUB_C_HUB_OVER_CURRENT 1
#define HUB_PORT_CONNECTION 0
#define HUB_PORT_ENABLE 1
#define HUB_PORT_SUSPEND 2
#define HUB_PORT_OVER_CURRENT 3
#define HUB_PORT_RESET 4
#define HUB_PORT_POWER 8
#define HUB_PORT_LOW_SPEED 9
#define HUB_C_PORT_CONNECTION 16
#define HUB_C_PORT_ENABLE 17
#define HUB_C_PORT_SUSPEND 18
#define HUB_C_PORT_OVER_CURRENT 19
#define HUB_C_PORT_RESET 20
#endif
/* USB descriptor type */
#ifndef USB_DESCR_TYP_DEVICE
#define USB_DESCR_TYP_DEVICE 0x01
#define USB_DESCR_TYP_CONFIG 0x02
#define USB_DESCR_TYP_STRING 0x03
#define USB_DESCR_TYP_INTERF 0x04
#define USB_DESCR_TYP_ENDP 0x05
#define USB_DESCR_TYP_QUALIF 0x06
#define USB_DESCR_TYP_SPEED 0x07
#define USB_DESCR_TYP_OTG 0x09
#define USB_DESCR_TYP_HID 0x21
#define USB_DESCR_TYP_REPORT 0x22
#define USB_DESCR_TYP_PHYSIC 0x23
#define USB_DESCR_TYP_CS_INTF 0x24
#define USB_DESCR_TYP_CS_ENDP 0x25
#define USB_DESCR_TYP_HUB 0x29
#endif
/* USB device class */
#ifndef USB_DEV_CLASS_HUB
#define USB_DEV_CLASS_RESERVED 0x00
#define USB_DEV_CLASS_AUDIO 0x01
#define USB_DEV_CLASS_COMMUNIC 0x02
#define USB_DEV_CLASS_HID 0x03
#define USB_DEV_CLASS_MONITOR 0x04
#define USB_DEV_CLASS_PHYSIC_IF 0x05
#define USB_DEV_CLASS_POWER 0x06
#define USB_DEV_CLASS_PRINTER 0x07
#define USB_DEV_CLASS_STORAGE 0x08
#define USB_DEV_CLASS_HUB 0x09
#define USB_DEV_CLASS_VEN_SPEC 0xFF
#endif
/* USB endpoint type and attributes */
#ifndef USB_ENDP_TYPE_MASK
#define USB_ENDP_DIR_MASK 0x80
#define USB_ENDP_ADDR_MASK 0x0F
#define USB_ENDP_TYPE_MASK 0x03
#define USB_ENDP_TYPE_CTRL 0x00
#define USB_ENDP_TYPE_ISOCH 0x01
#define USB_ENDP_TYPE_BULK 0x02
#define USB_ENDP_TYPE_INTER 0x03
#endif
#ifndef USB_DEVICE_ADDR
#define USB_DEVICE_ADDR 0x02 /* 默认的USB设备地址 */
#endif
#ifndef DEFAULT_ENDP0_SIZE
#define DEFAULT_ENDP0_SIZE 8 /* default maximum packet size for endpoint 0 */
#endif
#ifndef MAX_PACKET_SIZE
#define MAX_PACKET_SIZE 64 /* maximum packet size */
#endif
#ifndef USB_BO_CBW_SIZE
#define USB_BO_CBW_SIZE 0x1F /* 命令块CBW的总长度 */
#define USB_BO_CSW_SIZE 0x0D /* 命令状态块CSW的总长度 */
#endif
#ifndef USB_BO_CBW_SIG
#define USB_BO_CBW_SIG 0x43425355 /* 命令块CBW识别标志'USBC' */
#define USB_BO_CSW_SIG 0x53425355 /* 命令状态块CSW识别标志'USBS' */
#endif
#ifndef __PACKED
#define __PACKED __attribute__((packed))
#endif
typedef struct __PACKED _USB_SETUP_REQ {
UINT8 bRequestType;
UINT8 bRequest;
UINT16 wValue;
UINT16 wIndex;
UINT16 wLength;
} USB_SETUP_REQ, *PUSB_SETUP_REQ;
typedef struct __PACKED _USB_DEVICE_DESCR {
UINT8 bLength;
UINT8 bDescriptorType;
UINT16 bcdUSB;
UINT8 bDeviceClass;
UINT8 bDeviceSubClass;
UINT8 bDeviceProtocol;
UINT8 bMaxPacketSize0;
UINT16 idVendor;
UINT16 idProduct;
UINT16 bcdDevice;
UINT8 iManufacturer;
UINT8 iProduct;
UINT8 iSerialNumber;
UINT8 bNumConfigurations;
} USB_DEV_DESCR, *PUSB_DEV_DESCR;
typedef struct __PACKED _USB_CONFIG_DESCR {
UINT8 bLength;
UINT8 bDescriptorType;
UINT16 wTotalLength;
UINT8 bNumInterfaces;
UINT8 bConfigurationValue;
UINT8 iConfiguration;
UINT8 bmAttributes;
UINT8 MaxPower;
} USB_CFG_DESCR, *PUSB_CFG_DESCR;
typedef struct __PACKED _USB_INTERF_DESCR {
UINT8 bLength;
UINT8 bDescriptorType;
UINT8 bInterfaceNumber;
UINT8 bAlternateSetting;
UINT8 bNumEndpoints;
UINT8 bInterfaceClass;
UINT8 bInterfaceSubClass;
UINT8 bInterfaceProtocol;
UINT8 iInterface;
} USB_ITF_DESCR, *PUSB_ITF_DESCR;
typedef struct __PACKED _USB_ENDPOINT_DESCR {
UINT8 bLength;
UINT8 bDescriptorType;
UINT8 bEndpointAddress;
UINT8 bmAttributes;
UINT16 wMaxPacketSize;
UINT8 bInterval;
} USB_ENDP_DESCR, *PUSB_ENDP_DESCR;
typedef struct __PACKED _USB_CONFIG_DESCR_LONG {
USB_CFG_DESCR cfg_descr;
USB_ITF_DESCR itf_descr;
USB_ENDP_DESCR endp_descr[1];
} USB_CFG_DESCR_LONG, *PUSB_CFG_DESCR_LONG;
typedef USB_CFG_DESCR_LONG *PXUSB_CFG_DESCR_LONG;
typedef struct __PACKED _USB_HUB_DESCR {
UINT8 bDescLength;
UINT8 bDescriptorType;
UINT8 bNbrPorts;
UINT8 wHubCharacteristicsL;
UINT8 wHubCharacteristicsH;
UINT8 bPwrOn2PwrGood;
UINT8 bHubContrCurrent;
UINT8 DeviceRemovable;
UINT8 PortPwrCtrlMask;
} USB_HUB_DESCR, *PUSB_HUB_DESCR;
typedef USB_HUB_DESCR *PXUSB_HUB_DESCR;
typedef struct __PACKED _USB_HID_DESCR {
UINT8 bLength;
UINT8 bDescriptorType;
UINT16 bcdHID;
UINT8 bCountryCode;
UINT8 bNumDescriptors;
UINT8 bDescriptorTypeX;
UINT8 wDescriptorLengthL;
UINT8 wDescriptorLengthH;
} USB_HID_DESCR, *PUSB_HID_DESCR;
typedef USB_HID_DESCR *PXUSB_HID_DESCR;
typedef struct __PACKED _UDISK_BOC_CBW { /* command of BulkOnly USB-FlashDisk */
UINT32 mCBW_Sig;
UINT32 mCBW_Tag;
UINT32 mCBW_DataLen; /* uppest byte of data length, always is 0 */
UINT8 mCBW_Flag; /* transfer direction and etc. */
UINT8 mCBW_LUN;
UINT8 mCBW_CB_Len; /* length of command block */
UINT8 mCBW_CB_Buf[16]; /* command block buffer */
} UDISK_BOC_CBW, *PUDISK_BOC_CBW;
typedef UDISK_BOC_CBW *PXUDISK_BOC_CBW;
typedef struct __PACKED _UDISK_BOC_CSW { /* status of BulkOnly USB-FlashDisk */
UINT32 mCSW_Sig;
UINT32 mCSW_Tag;
UINT32 mCSW_Residue; /* return: remainder bytes */
UINT8 mCSW_Status; /* return: result status */
} UDISK_BOC_CSW, *PUDISK_BOC_CSW;
typedef UDISK_BOC_CSW *PXUDISK_BOC_CSW;
#ifdef __cplusplus
}
#endif
#endif // __USB_TYPE__

View File

@ -0,0 +1,283 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_adc.h
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* 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 __CH59x_ADC_H__
#define __CH59x_ADC_H__
#ifdef __cplusplus
extern "C" {
#endif
#define ROM_CFG_TMP_25C 0x7F014
/**
* @brief adc single channel define
*/
typedef enum
{
CH_EXTIN_0 = 0, // ADC 外部模拟通道 0
CH_EXTIN_1, // ADC 外部模拟通道 1
CH_EXTIN_2, // ADC 外部模拟通道 2
CH_EXTIN_3, // ADC 外部模拟通道 3
CH_EXTIN_4, // ADC 外部模拟通道 4
CH_EXTIN_5, // ADC 外部模拟通道 5
CH_EXTIN_6, // ADC 外部模拟通道 6
CH_EXTIN_7, // ADC 外部模拟通道 7
CH_EXTIN_8, // ADC 外部模拟通道 8
CH_EXTIN_9, // ADC 外部模拟通道 9
CH_EXTIN_10, // ADC 外部模拟通道 10
CH_EXTIN_11, // ADC 外部模拟通道 11
CH_EXTIN_12, // ADC 外部模拟通道 12
CH_EXTIN_13, // ADC 外部模拟通道 13
CH_INTE_VBAT = 14, // ADC 内部电池检测通道
CH_INTE_VTEMP = 15, // ADC 内部温度传感器检测通道
} ADC_SingleChannelTypeDef;
/**
* @brief adc differential channel define
*/
typedef enum
{
CH_DIFF_0_2 = 0, // ADC 差分通道 #0-#2
CH_DIFF_1_3, // ADC 差分通道 #1-#3
} ADC_DiffChannelTypeDef;
/**
* @brief adc sampling clock
*/
typedef enum
{
SampleFreq_3_2 = 0, // 3.2M 采样频率
SampleFreq_8, // 8M 采样频率
SampleFreq_5_33, // 5.33M 采样频率
SampleFreq_4, // 4M 采样频率
} ADC_SampClkTypeDef;
/**
* @brief adc signal PGA
*/
typedef enum
{
ADC_PGA_1_4 = 0, // -12dB, 1/4倍
ADC_PGA_1_2, // -6dB, 1/2倍
ADC_PGA_0, // 0dB, 1倍无增益
ADC_PGA_2, // 6dB, 2倍
ADC_PGA_2_ = 0x10, // 6dB, 2倍
ADC_PGA_4, // 12dB, 4倍
ADC_PGA_8, // 18dB, 8倍
ADC_PGA_16, // 24dB, 16倍
} ADC_SignalPGATypeDef;
/**
* @brief Configuration DMA mode
*/
typedef enum
{
ADC_Mode_Single = 0, // 单次模式
ADC_Mode_LOOP, // 循环模式
} ADC_DMAModeTypeDef;
/**
* @brief ADC
*
* @param d - refer to ADC_SingleChannelTypeDef
*/
#define ADC_ChannelCfg(d) (R8_ADC_CHANNEL = d)
/**
* @brief ADC
*
* @param d - refer to ADC_SampClkTypeDef
*/
#define ADC_SampClkCfg(d) (R8_ADC_CFG = R8_ADC_CFG & (~RB_ADC_CLK_DIV) | (d << 6))
/**
* @brief ADC
*
* @param d - refer to ADC_SignalPGATypeDef
*/
#define ADC_PGACfg(d) (R8_ADC_CFG = R8_ADC_CFG & (~RB_ADC_PGA_GAIN) | (d << 4))
/**
* @brief
*
* @param d -
*/
#define ADC_TempCalibCfg(d) (R8_TEM_SENSOR = R8_TEM_SENSOR & (~RB_TEM_SEN_CALIB) | d)
/**
* @brief
*
* @param sp - refer to ADC_SampClkTypeDef
* @param ga - refer to ADC_SignalPGATypeDef
*/
void ADC_ExtSingleChSampInit(ADC_SampClkTypeDef sp, ADC_SignalPGATypeDef ga);
/**
* @brief
*
* @param sp - refer to ADC_SampClkTypeDef
* @param ga - refer to ADC_SignalPGATypeDef
*/
void ADC_ExtDiffChSampInit(ADC_SampClkTypeDef sp, ADC_SignalPGATypeDef ga);
/**
* @brief
*/
void TouchKey_ChSampInit(void);
/**
* @brief TouchKey电源
*/
#define TouchKey_DisableTSPower() (R8_TKEY_CFG &= ~RB_TKEY_PWR_ON)
/**
* @brief
*/
void ADC_InterTSSampInit(void);
/**
* @brief
*/
#define ADC_DisableTSPower() (R8_TEM_SENSOR = 0)
/**
* @brief
*/
void ADC_InterBATSampInit(void);
/**
* @brief ADC执行单次转换
*
* @return ADC转换后的数据
*/
uint16_t ADC_ExcutSingleConver(void);
/**
* @brief ,,ADC后调用此函数获取校准值
*
* @return
*/
signed short ADC_DataCalib_Rough(void);
/**
* @brief TouchKey转换后数据
*
* @param charg - Touchkey充电时间,5bits有效, t=charg*Tadc
* @param disch - Touchkey放电时间,3bits有效, t=disch*Tadc
*
* @return TouchKey等效数据
*/
uint16_t TouchKey_ExcutSingleConver(uint8_t charg, uint8_t disch);
/**
* @brief ADC的周期
*
* @param cycle - 16
*/
void ADC_AutoConverCycle(uint8_t cycle);
/**
* @brief DMA功能
*
* @param s - DMA功能
* @param startAddr - DMA
* @param endAddr - DMA
* @param m - DMA模式
*/
void ADC_DMACfg(uint8_t s, uint32_t startAddr, uint32_t endAddr, ADC_DMAModeTypeDef m);
/**
* @brief Convert ADC value to temperature(Celsius)
*
* @param adc_val - adc value
*
* @return temperature (Celsius)
*/
int adc_to_temperature_celsius(uint16_t adc_val);
/**
* @brief ADC转换值
*
* @return ADC转换值
*/
#define ADC_ReadConverValue() (R16_ADC_DATA)
/**
* @brief ADC执行单次转换
*/
#define ADC_StartUp() (R8_ADC_CONVERT = RB_ADC_START)
/**
* @brief ADC中断状态
*/
#define ADC_GetITStatus() (R8_ADC_INT_FLAG & RB_ADC_IF_EOC)
/**
* @brief ADC中断标志
*/
#define ADC_ClearITFlag() (R8_ADC_CONVERT = 0)
/**
* @brief ADC DMA完成状态
*/
#define ADC_GetDMAStatus() (R8_ADC_DMA_IF & RB_ADC_IF_DMA_END)
/**
* @brief ADC DMA完成标志
*/
#define ADC_ClearDMAFlag() (R8_ADC_DMA_IF |= RB_ADC_IF_DMA_END)
/**
* @brief ADC
*/
#define ADC_StartAutoDMA() (R8_ADC_CTRL_DMA |= RB_ADC_AUTO_EN)
/**
* @brief ADC
*/
#define ADC_StopAutoDMA() (R8_ADC_CTRL_DMA &= ~RB_ADC_AUTO_EN)
/**
* @brief ADC
*/
#define ADC_StartContDMA() (R8_ADC_CTRL_DMA |= RB_ADC_CONT_EN)
/**
* @brief ADC
*/
#define ADC_StopContDMA() (R8_ADC_CTRL_DMA &= ~RB_ADC_CONT_EN)
/**
* @brief TouchKey中断状态
*/
#define TouchKey_GetITStatus() (R8_ADC_INT_FLAG & RB_ADC_IF_EOC)
/**
* @brief TouchKey中断标志
*/
#define TouchKey_ClearITFlag() (R8_TKEY_CTRL |= RB_TKEY_PWR_ON)
/**
* @brief ADC电源
*/
#define ADC_DisablePower() (R8_ADC_CFG &= ~RB_ADC_POWER_ON)
#ifdef __cplusplus
}
#endif
#endif // __CH59x_ADC_H__

View File

@ -0,0 +1,290 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_clk.h
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* 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 __CH59x_CLK_H__
#define __CH59x_CLK_H__
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief
*/
typedef enum
{
CLK_SOURCE_LSI = 0x00,
CLK_SOURCE_LSE,
CLK_SOURCE_HSE_16MHz = 0x22,
CLK_SOURCE_HSE_8MHz = 0x24,
CLK_SOURCE_HSE_6_4MHz = 0x25,
CLK_SOURCE_HSE_4MHz = 0x28,
CLK_SOURCE_PLL_60MHz = 0x48,
CLK_SOURCE_PLL_48MHz = (0x40 | 10),
CLK_SOURCE_PLL_32MHz = (0x40 | 15),
CLK_SOURCE_PLL_24MHz = (0x40 | 20),
} SYS_CLKTypeDef;
/**
* @brief 32K时钟选择
*/
typedef enum
{
Clk32K_LSI = 0,
Clk32K_LSE,
} LClk32KTypeDef;
/**
* @brief 32M晶振电流挡位
*/
typedef enum
{
HSE_RCur_75 = 0,
HSE_RCur_100,
HSE_RCur_125,
HSE_RCur_150
} HSECurrentTypeDef;
/**
* @brief 32M晶振内部电容挡位
*/
typedef enum
{
HSECap_10p = 0,
HSECap_12p,
HSECap_14p,
HSECap_16p,
HSECap_18p,
HSECap_20p,
HSECap_22p,
HSECap_24p
} HSECapTypeDef;
/**
* @brief 32K晶振电流挡位
*/
typedef enum
{
LSE_RCur_70 = 0,
LSE_RCur_100,
LSE_RCur_140,
LSE_RCur_200
} LSECurrentTypeDef;
/**
* @brief 32K晶振内部电容挡位
*/
typedef enum
{
LSECap_2p = 0,
LSECap_13p,
LSECap_14p,
LSECap_15p,
LSECap_16p,
LSECap_17p,
LSECap_18p,
LSECap_19p,
LSECap_20p,
LSECap_21p,
LSECap_22p,
LSECap_23p,
LSECap_24p,
LSECap_25p,
LSECap_26p,
LSECap_27p
} LSECapTypeDef;
#define RTC_MAX_COUNT 0xA8C00000
#define MAX_DAY 0x00004000
#define MAX_2_SEC 0x0000A8C0
//#define MAX_SEC 0x545FFFFF
#define BEGYEAR 2020
#define IsLeapYear(yr) (!((yr) % 400) || (((yr) % 100) && !((yr) % 4)))
#define YearLength(yr) (IsLeapYear(yr) ? 366 : 365)
#define monthLength(lpyr, mon) (((mon) == 1) ? (28 + (lpyr)) : (((mon) > 6) ? (((mon) & 1) ? 31 : 30) : (((mon) & 1) ? 30 : 31)))
/**
* @brief rtc timer mode period define
*/
typedef enum
{
Period_0_125_S = 0, // 0.125s 周期
Period_0_25_S, // 0.25s 周期
Period_0_5_S, // 0.5s 周期
Period_1_S, // 1s 周期
Period_2_S, // 2s 周期
Period_4_S, // 4s 周期
Period_8_S, // 8s 周期
Period_16_S, // 16s 周期
} RTC_TMRCycTypeDef;
/**
* @brief rtc interrupt event define
*/
typedef enum
{
RTC_TRIG_EVENT = 0, // RTC 触发事件
RTC_TMR_EVENT, // RTC 周期定时事件
} RTC_EVENTTypeDef;
/**
* @brief rtc interrupt event define
*/
typedef enum
{
RTC_TRIG_MODE = 0, // RTC 触发模式
RTC_TMR_MODE, // RTC 周期定时模式
} RTC_MODETypeDef;
typedef enum
{
/* 校准精度越高,耗时越长 */
Level_32 = 3, // 用时 1.2ms 1000ppm (32M 主频) 1100ppm (60M 主频)
Level_64, // 用时 2.2ms 800ppm (32M 主频) 1000ppm (60M 主频)
Level_128, // 用时 4.2ms 600ppm (32M 主频) 800ppm (60M 主频)
} Cali_LevelTypeDef;
/**
* @brief 32K
*
* @param hc - 32K使用内部还是外部
*/
void LClk32K_Select(LClk32KTypeDef hc);
/**
* @brief HSE晶体
*
* @param c - 75%,100%,125%,150%
*/
void HSECFG_Current(HSECurrentTypeDef c);
/**
* @brief HSE晶体
*
* @param c - refer to HSECapTypeDef
*/
void HSECFG_Capacitance(HSECapTypeDef c);
/**
* @brief LSE晶体
*
* @param c - 70%,100%,140%,200%
*/
void LSECFG_Current(LSECurrentTypeDef c);
/**
* @brief LSE晶体
*
* @param c - refer to LSECapTypeDef
*/
void LSECFG_Capacitance(LSECapTypeDef c);
void Calibration_LSI(Cali_LevelTypeDef cali_Lv); /* 用主频校准内部32K时钟 */
/**
* @brief RTC时钟初始化当前时间
*
* @param y - MAX_Y = BEGYEAR + 44
* @param mon - MAX_MON = 12
* @param d - MAX_D = 31
* @param h - MAX_H = 23
* @param m - MAX_M = 59
* @param s - MAX_S = 59
*/
void RTC_InitTime(uint16_t y, uint16_t mon, uint16_t d, uint16_t h, uint16_t m, uint16_t s);
/**
* @brief
*
* @param py - MAX_Y = BEGYEAR + 44
* @param pmon - MAX_MON = 12
* @param pd - MAX_D = 31
* @param ph - MAX_H = 23
* @param pm - MAX_M = 59
* @param ps - MAX_S = 59
*/
void RTC_GetTime(uint16_t *py, uint16_t *pmon, uint16_t *pd, uint16_t *ph, uint16_t *pm, uint16_t *ps);
/**
* @brief LSE/LSI时钟RTC
*
* @param cyc - MAX_CYC = 0xA8BFFFFF = 2831155199
*/
void RTC_SetCycle32k(uint32_t cyc);
/**
* @brief LSE/LSI时钟RTC
*
* @return MAX_CYC = 0xA8BFFFFF = 2831155199
*/
uint32_t RTC_GetCycle32k(void);
/**
* @brief RTC定时模式配置32768Hz
*
* @param t - refer to RTC_TMRCycTypeDef
*/
void RTC_TRIGFunCfg(uint32_t cyc);
/**
* @brief RTC定时模式配置32768Hz
*
* @param t - refer to RTC_TMRCycTypeDef
*/
void RTC_TMRFunCfg(RTC_TMRCycTypeDef t);
/**
* @brief RTC
*
* @param m -
*/
void RTC_ModeFunDisable(RTC_MODETypeDef m);
/**
* @brief RTC中断标志
*
* @param f - refer to RTC_EVENTTypeDef
*
* @return
*/
uint8_t RTC_GetITFlag(RTC_EVENTTypeDef f);
/**
* @brief RTC中断标志
*
* @param f - refer to RTC_EVENTTypeDef
*/
void RTC_ClearITFlag(RTC_EVENTTypeDef f);
/**
* @brief 32K
*/
void LClk32K_Cfg(LClk32KTypeDef hc, FunctionalState s);
#ifdef __cplusplus
}
#endif
#endif // __CH59x_CLK_H__

View File

@ -0,0 +1,101 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_common.h
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* 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 __CH59x_COMM_H__
#define __CH59x_COMM_H__
#ifdef __cplusplus
extern "C" {
#endif
#ifndef NULL
#define NULL 0
#endif
#define ALL 0xFFFF
#ifndef __HIGH_CODE
#define __HIGH_CODE __attribute__((section(".highcode")))
#endif
#ifndef __INTERRUPT
#ifdef INT_SOFT
#define __INTERRUPT __attribute__((interrupt()))
#else
#define __INTERRUPT __attribute__((interrupt("WCH-Interrupt-fast")))
#endif
#endif
#define Debug_UART0 0
#define Debug_UART1 1
#define Debug_UART2 2
#define Debug_UART3 3
#ifdef DEBUG
#include <stdio.h>
#endif
/**
* @brief Hz
*/
#ifndef FREQ_SYS
#define FREQ_SYS 60000000
#endif
#ifndef SAFEOPERATE
#define SAFEOPERATE __nop();__nop()
#endif
/**
* @brief 32K时钟Hz
*/
#ifdef CLK_OSC32K
#if ( CLK_OSC32K == 1 )
#define CAB_LSIFQ 32000
#else
#define CAB_LSIFQ 32768
#endif
#else
#define CAB_LSIFQ 32000
#endif
#include <string.h>
#include <stdint.h>
#include "CH592SFR.h"
#include "core_riscv.h"
#include "CH59x_clk.h"
#include "CH59x_uart.h"
#include "CH59x_gpio.h"
#include "CH59x_i2c.h"
#include "CH59x_flash.h"
#include "CH59x_pwr.h"
#include "CH59x_pwm.h"
#include "CH59x_adc.h"
#include "CH59x_sys.h"
#include "CH59x_timer.h"
#include "CH59x_spi.h"
#include "CH59x_usbdev.h"
#include "CH59x_usbhost.h"
#include "ISP592.h"
#define DelayMs(x) mDelaymS(x)
#define DelayUs(x) mDelayuS(x)
#ifdef __cplusplus
}
#endif
#endif // __CH59x_COMM_H__

View File

@ -0,0 +1,42 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_flash.h
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* 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 __CH59x_FLASH_H__
#define __CH59x_FLASH_H__
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Flash-ROM
*
* @param StartAddr - read address
* @param Buffer - read buffer
* @param len - read len
*/
void FLASH_ROM_READ(uint32_t StartAddr, void *Buffer, uint32_t len);
void FLASH_ROM_READ(UINT32 StartAddr, PVOID Buffer, UINT32 len); /* 读取Flash-ROM */
UINT8 UserOptionByteConfig(FunctionalState RESET_EN, FunctionalState BOOT_PIN, FunctionalState UART_NO_KEY_EN,
UINT32 FLASHProt_Size);
UINT8 UserOptionByteClose_SWD(void);
void UserOptionByte_Active(void);
#ifdef __cplusplus
}
#endif
#endif // __CH59x_FLASH_H__

View File

@ -0,0 +1,274 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_gpio.h
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* 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 __CH59x_GPIO_H__
#define __CH59x_GPIO_H__
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief GPIO_pins_define
*/
#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_All (0xFFFFFFFF) /*!< All pins selected */
/**
* @brief Configuration GPIO Mode
*/
typedef enum
{
GPIO_ModeIN_Floating, //浮空输入
GPIO_ModeIN_PU, //上拉输入
GPIO_ModeIN_PD, //下拉输入
GPIO_ModeOut_PP_5mA, //推挽输出最大5mA
GPIO_ModeOut_PP_20mA, //推挽输出最大20mA
} GPIOModeTypeDef;
/**
* @brief Configuration GPIO IT Mode
*/
typedef enum
{
GPIO_ITMode_LowLevel, //低电平触发
GPIO_ITMode_HighLevel, //高电平触发
GPIO_ITMode_FallEdge, //下降沿触发
GPIO_ITMode_RiseEdge, //上升沿触发
} GPIOITModeTpDef;
/**
* @brief GPIOA端口引脚模式配置
*
* @param pin - PA0-PA15
* @param mode -
*/
void GPIOA_ModeCfg(uint32_t pin, GPIOModeTypeDef mode);
/**
* @brief GPIOB端口引脚模式配置
*
* @param pin - PB0-PB23
* @param mode -
*/
void GPIOB_ModeCfg(uint32_t pin, GPIOModeTypeDef mode);
/**
* @brief GPIOA端口引脚输出置低
*
* @param pin - PA0-PA15
*/
#define GPIOA_ResetBits(pin) (R32_PA_CLR |= pin)
/**
* @brief GPIOA端口引脚输出置高
*
* @param pin - PA0-PA15
*/
#define GPIOA_SetBits(pin) (R32_PA_OUT |= pin)
/**
* @brief GPIOB端口引脚输出置低
*
* @param pin - PB0-PB23
*/
#define GPIOB_ResetBits(pin) (R32_PB_CLR |= pin)
/**
* @brief GPIOB端口引脚输出置高
*
* @param pin - PB0-PB23
*/
#define GPIOB_SetBits(pin) (R32_PB_OUT |= pin)
/**
* @brief GPIOA端口引脚输出电平翻转
*
* @param pin - PA0-PA15
*/
#define GPIOA_InverseBits(pin) (R32_PA_OUT ^= pin)
/**
* @brief GPIOB端口引脚输出电平翻转
*
* @param pin - PB0-PB23
*/
#define GPIOB_InverseBits(pin) (R32_PB_OUT ^= pin)
/**
* @brief GPIOA端口32位数据返回16
*
* @return GPIOA端口32位数据
*/
#define GPIOA_ReadPort() (R32_PA_PIN)
/**
* @brief GPIOB端口32位数据返回24
*
* @return GPIOB端口32位数据
*/
#define GPIOB_ReadPort() (R32_PB_PIN)
/**
* @brief GPIOA端口引脚状态0-(!0)-
*
* @param pin - PA0-PA15
*
* @return GPIOA端口引脚状态
*/
#define GPIOA_ReadPortPin(pin) (R32_PA_PIN & (pin))
/**
* @brief GPIOB端口引脚状态0-(!0)-
*
* @param pin - PB0-PB23
*
* @return GPIOB端口引脚状态
*/
#define GPIOB_ReadPortPin(pin) (R32_PB_PIN & (pin))
/**
* @brief GPIOA引脚中断模式配置
*
* @param pin - PA0-PA15
* @param mode -
*/
void GPIOA_ITModeCfg(uint32_t pin, GPIOITModeTpDef mode);
/**
* @brief GPIOB引脚中断模式配置
*
* @param pin - PB0-PB23
* @param mode -
*/
void GPIOB_ITModeCfg(uint32_t pin, GPIOITModeTpDef mode);
/**
* @brief GPIOA端口中断标志状态
*
* @return GPIOA端口中断标志状态
*/
#define GPIOA_ReadITFlagPort() (R16_PA_INT_IF)
/**
* @brief GPIOB端口中断标志状态
*
* @return GPIOB端口中断标志状态
*/
#define GPIOB_ReadITFlagPort() ((R16_PB_INT_IF & (~((GPIO_Pin_22 | GPIO_Pin_23) >> 14))) | ((R16_PB_INT_IF << 14) & (GPIO_Pin_22 | GPIO_Pin_23)))
/**
* @brief GPIOA端口引脚中断标志状态
*
* @param pin - PA0-PA15
*
* @return GPIOA端口引脚中断标志状态
*/
#define GPIOA_ReadITFlagBit(pin) (R16_PA_INT_IF & (pin))
/**
* @brief GPIOB端口引脚中断标志状态
*
* @param pin - PB0-PB23
*
* @return GPIOB端口引脚中断标志状态
*/
#define GPIOB_ReadITFlagBit(pin) (R16_PB_INT_IF & ((pin) | (((pin) & (GPIO_Pin_22 | GPIO_Pin_23)) >> 14)))
/**
* @brief GPIOA端口引脚中断标志状态
*
* @param pin - PA0-PA15
*/
#define GPIOA_ClearITFlagBit(pin) (R16_PA_INT_IF = pin)
/**
* @brief GPIOB端口引脚中断标志状态
*
* @param pin - PB0-PB23
*/
#define GPIOB_ClearITFlagBit(pin) (R16_PB_INT_IF = ((pin) | (((pin) & (GPIO_Pin_22 | GPIO_Pin_23)) >> 14)))
/**
* @brief
*
* @param s - 使
* @param perph - RB_RF_ANT_SW_EN - RF antenna switch control output on PB16/PB17/PB18/PB19/PB20/PB21
* RB_PIN_U0_INV - RXD0/RXD0_/TXD0/TXD0_ invert input/output
* RB_PIN_INTX - INTX: INT24/INT25 PB8/PB9 -> INT24_/INT25_ PB22/PB23
* RB_PIN_MODEM - MODEM: PB1/PB5 -> PB14/PB15
* RB_PIN_I2C - I2C: PB13/PB12 -> PB21/PB20
* RB_PIN_PWMX - PWMX: PA12/PA13/PB4/PB6/PB7 -> PA6/PA7/PB1/PB2/PB3
* RB_PIN_SPI0 - SPI0: PA12/PA13/PA14/PA15 -> PB12/PB13/PB14/PB15
* RB_PIN_UART3 - UART3: PA4/PA5 -> PB20/PB21
* RB_PIN_UART2 - UART2: PA6/PA7 -> PB22/PB23
* RB_PIN_UART1 - UART1: PA8/PA9 -> PB12/PB13
* RB_PIN_UART0 - UART0: PB4/PB7 -> PA15/PA14
* RB_PIN_TMR3 - TMR2: PA9 -> PB23
* RB_PIN_TMR2 - TMR2: PA11 -> PB11
* RB_PIN_TMR1 - TMR1: PA10 -> PB10
* RB_PIN_TMR0 - TMR0: PA9 -> PB23
*/
void GPIOPinRemap(FunctionalState s, uint16_t perph);
/**
* @brief GPIO引脚功能控制
*
* @param s -
* @param perph - RB_PIN_ADC8_9_IE - ADC/TKEY 9/8
* RB_PIN_ADC6_7_IE - ADC/TKEY 7/6
* RB_PIN_ADC10_IE - ADC/TKEY 10
* RB_PIN_ADC11_IE - ADC/TKEY 11
* RB_PIN_USB2_DP_PU - USB2 U2D+
* RB_PIN_USB2_IE - USB2引脚
* RB_PIN_USB_DP_PU - USB UD+
* RB_PIN_USB_IE - USB
* RB_PIN_ADC0_IE - ADC/TKEY 0
* RB_PIN_ADC1_IE - ADC/TKEY 1
* RB_PIN_ADC12_IE - ADC/TKEY 12
* RB_PIN_ADC13_IE - ADC/TKEY 13
* RB_PIN_XT32K_IE - 32KHz晶振LSE引脚
* RB_PIN_ADC2_3_IE - ADC/TKEY 2/3
* RB_PIN_ADC4_5_IE - ADC/TKEY 4/5
*/
void GPIOAGPPCfg(FunctionalState s, uint16_t perph);
#ifdef __cplusplus
}
#endif
#endif // __CH59x_GPIO_H__

View File

@ -0,0 +1,180 @@
#ifndef __CH59x_I2C_H__
#define __CH59x_I2C_H__
#ifdef __cplusplus
extern "C" {
#endif
/* I2C_transfer_direction */
#define I2C_Direction_Transmitter ((uint8_t)0x00)
#define I2C_Direction_Receiver ((uint8_t)0x01)
/* I2C ADD0 mask */
#define OADDR1_ADD0_Set ((uint16_t)0x0001)
#define OADDR1_ADD0_Reset ((uint16_t)0xFFFE)
/* I2C_NACK_position */
#define I2C_NACKPosition_Next ((uint16_t)RB_I2C_POS)
#define I2C_NACKPosition_Current ((uint16_t)~RB_I2C_POS)
/* I2C_PEC_position */
#define I2C_PECPosition_Next ((uint16_t)RB_I2C_POS)
#define I2C_PECPosition_Current ((uint16_t)~RB_I2C_POS)
/* I2C_SMBus_alert_pin_level */
#define I2C_SMBusAlert_Low ((uint16_t)RB_I2C_ALERT)
#define I2C_SMBusAlert_High ((uint16_t)~RB_I2C_ALERT)
/* I2C FLAG mask */
#define FLAG_Mask ((uint32_t)0x00FFFFFF)
/* I2C Interrupt Enable mask */
#define ITEN_Mask ((uint32_t)0x07000000)
/* I2C_mode */
typedef enum
{
I2C_Mode_I2C = 0x0000,
I2C_Mode_SMBusDevice = 0x0002,
I2C_Mode_SMBusHost = 0x000A,
} I2C_ModeTypeDef;
/* I2C_duty_cycle_in_fast_mode */
typedef enum
{
I2C_DutyCycle_16_9 = RB_I2C_DUTY, /* I2C fast mode Tlow/Thigh = 16/9 */
I2C_DutyCycle_2 = 0x0000, /* I2C fast mode Tlow/Thigh = 2 */
} I2C_DutyTypeDef;
/* I2C_acknowledgement - Enables or disables the acknowledgement.*/
typedef enum
{
I2C_Ack_Enable = RB_I2C_ACK,
I2C_Ack_Disable = 0x0000,
} I2C_AckTypeDef;
/* I2C_acknowledged_address - Specifies if 7-bit or 10-bit address is acknowledged. */
typedef enum
{
I2C_AckAddr_7bit = 0x4000,
I2C_AckAddr_10bit = 0xC000,
} I2C_AckAddrTypeDef;
/* I2C_interrupts_definition */
typedef enum
{
I2C_IT_BUF = 0x0400, /* Buffer interrupt mask. */
I2C_IT_EVT = 0x0200, /* Event interrupt mask. */
I2C_IT_ERR = 0x0100, /* Error interrupt mask. */
} I2C_ITTypeDef;
/* I2C_interrupts_definition */
#define I2C_IT_SMBALERT ((uint32_t)0x01008000)
#define I2C_IT_TIMEOUT ((uint32_t)0x01004000)
#define I2C_IT_PECERR ((uint32_t)0x01001000)
#define I2C_IT_OVR ((uint32_t)0x01000800)
#define I2C_IT_AF ((uint32_t)0x01000400)
#define I2C_IT_ARLO ((uint32_t)0x01000200)
#define I2C_IT_BERR ((uint32_t)0x01000100)
#define I2C_IT_TXE ((uint32_t)0x06000080)
#define I2C_IT_RXNE ((uint32_t)0x06000040)
#define I2C_IT_STOPF ((uint32_t)0x02000010)
#define I2C_IT_ADD10 ((uint32_t)0x02000008)
#define I2C_IT_BTF ((uint32_t)0x02000004)
#define I2C_IT_ADDR ((uint32_t)0x02000002)
#define I2C_IT_SB ((uint32_t)0x02000001)
/* SR2 register flags */
#define I2C_FLAG_DUALF ((uint32_t)0x00800000)
#define I2C_FLAG_SMBHOST ((uint32_t)0x00400000)
#define I2C_FLAG_SMBDEFAULT ((uint32_t)0x00200000)
#define I2C_FLAG_GENCALL ((uint32_t)0x00100000)
#define I2C_FLAG_TRA ((uint32_t)0x00040000)
#define I2C_FLAG_BUSY ((uint32_t)0x00020000)
#define I2C_FLAG_MSL ((uint32_t)0x00010000)
/* SR1 register flags */
#define I2C_FLAG_SMBALERT ((uint32_t)0x10008000)
#define I2C_FLAG_TIMEOUT ((uint32_t)0x10004000)
#define I2C_FLAG_PECERR ((uint32_t)0x10001000)
#define I2C_FLAG_OVR ((uint32_t)0x10000800)
#define I2C_FLAG_AF ((uint32_t)0x10000400)
#define I2C_FLAG_ARLO ((uint32_t)0x10000200)
#define I2C_FLAG_BERR ((uint32_t)0x10000100)
#define I2C_FLAG_TXE ((uint32_t)0x10000080)
#define I2C_FLAG_RXNE ((uint32_t)0x10000040)
#define I2C_FLAG_STOPF ((uint32_t)0x10000010)
#define I2C_FLAG_ADD10 ((uint32_t)0x10000008)
#define I2C_FLAG_BTF ((uint32_t)0x10000004)
#define I2C_FLAG_ADDR ((uint32_t)0x10000002)
#define I2C_FLAG_SB ((uint32_t)0x10000001)
/****************I2C Master Events (Events grouped in order of communication)********************/
#define I2C_EVENT_MASTER_MODE_SELECT ((uint32_t)0x00030001) /* BUSY, MSL and SB flag */
#define I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ((uint32_t)0x00070082) /* BUSY, MSL, ADDR, TXE and TRA flags */
#define I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED ((uint32_t)0x00030002) /* BUSY, MSL and ADDR flags */
#define I2C_EVENT_MASTER_MODE_ADDRESS10 ((uint32_t)0x00030008) /* BUSY, MSL and ADD10 flags */
#define I2C_EVENT_MASTER_BYTE_RECEIVED ((uint32_t)0x00030040) /* BUSY, MSL and RXNE flags */
#define I2C_EVENT_MASTER_BYTE_TRANSMITTING ((uint32_t)0x00070080) /* TRA, BUSY, MSL, TXE flags */
#define I2C_EVENT_MASTER_BYTE_TRANSMITTED ((uint32_t)0x00070084) /* TRA, BUSY, MSL, TXE and BTF flags */
/******************I2C Slave Events (Events grouped in order of communication)******************/
#define I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED ((uint32_t)0x00020002) /* BUSY and ADDR flags */
#define I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED ((uint32_t)0x00060082) /* TRA, BUSY, TXE and ADDR flags */
#define I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED ((uint32_t)0x00820000) /* DUALF and BUSY flags */
#define I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED ((uint32_t)0x00860080) /* DUALF, TRA, BUSY and TXE flags */
#define I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED ((uint32_t)0x00120000) /* GENCALL and BUSY flags */
#define I2C_EVENT_SLAVE_BYTE_RECEIVED ((uint32_t)0x00020040) /* BUSY and RXNE flags */
#define I2C_EVENT_SLAVE_STOP_DETECTED ((uint32_t)0x00000010) /* STOPF flag */
#define I2C_EVENT_SLAVE_BYTE_TRANSMITTED ((uint32_t)0x00060084) /* TRA, BUSY, TXE and BTF flags */
#define I2C_EVENT_SLAVE_BYTE_TRANSMITTING ((uint32_t)0x00060080) /* TRA, BUSY and TXE flags */
#define I2C_EVENT_SLAVE_ACK_FAILURE ((uint32_t)0x00000400) /* AF flag */
void I2C_Init(I2C_ModeTypeDef I2C_Mode, UINT32 I2C_ClockSpeed, I2C_DutyTypeDef I2C_DutyCycle,
I2C_AckTypeDef I2C_Ack, I2C_AckAddrTypeDef I2C_AckAddr, UINT16 I2C_OwnAddress1);
void I2C_Cmd(FunctionalState NewState);
void I2C_GenerateSTART(FunctionalState NewState);
void I2C_GenerateSTOP(FunctionalState NewState);
void I2C_AcknowledgeConfig(FunctionalState NewState);
void I2C_OwnAddress2Config(uint8_t Address);
void I2C_DualAddressCmd(FunctionalState NewState);
void I2C_GeneralCallCmd(FunctionalState NewState);
void I2C_ITConfig(I2C_ITTypeDef I2C_IT, FunctionalState NewState);
void I2C_SendData(uint8_t Data);
uint8_t I2C_ReceiveData(void);
void I2C_Send7bitAddress(uint8_t Address, uint8_t I2C_Direction);
void I2C_SoftwareResetCmd(FunctionalState NewState);
void I2C_NACKPositionConfig(uint16_t I2C_NACKPosition);
void I2C_SMBusAlertConfig(uint16_t I2C_SMBusAlert);
void I2C_TransmitPEC(FunctionalState NewState);
void I2C_PECPositionConfig(uint16_t I2C_PECPosition);
void I2C_CalculatePEC(FunctionalState NewState);
uint8_t I2C_GetPEC(void);
void I2C_ARPCmd(FunctionalState NewState);
void I2C_StretchClockCmd(FunctionalState NewState);
void I2C_FastModeDutyCycleConfig(uint16_t I2C_DutyCycle);
/****************************************************************************************
* I2C State Monitoring Functions
****************************************************************************************/
uint8_t I2C_CheckEvent(uint32_t I2C_EVENT);
uint32_t I2C_GetLastEvent(void);
FlagStatus I2C_GetFlagStatus(uint32_t I2C_FLAG);
void I2C_ClearFlag(uint32_t I2C_FLAG);
ITStatus I2C_GetITStatus(uint32_t I2C_IT);
void I2C_ClearITPendingBit(uint32_t I2C_IT);
#ifdef __cplusplus
}
#endif
#endif // __CH59x_I2C_H__

View File

@ -0,0 +1,98 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_lcd.h
* Author : WCH
* Version : V1.0
* Date : 2022/12/05
* 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 __CH59x_LCD_H__
#define __CH59x_LCD_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "CH592SFR.h"
/**
* @brief Configuration LCD driver power
*/
typedef enum
{
LCD_PS_3V3 = 0, // 3.3V 驱动
LCD_PS_2V5, // 2.5V 驱动
}LCDDrvPowerTypeDef;
/**
* @brief Configuration LCD bias
*/
typedef enum
{
LCD_1_2_Bias = 0, // 2级分压
LCD_1_3_Bias, // 3级分压
}LCDBiasTypeDef;
/**
* @brief Configuration LCD duty
*/
typedef enum
{
LCD_1_2_Duty = 0, // COM0-COM1
LCD_1_3_Duty, // COM0-COM2
LCD_1_4_Duty, // COM0-COM3
}LCDDutyTypeDef;
/**
* @brief Configuration LCD scan clk
*/
typedef enum
{
LCD_CLK_256 = 0, // 256Hz
LCD_CLK_512, // 512Hz
LCD_CLK_1000, // 1KHz
LCD_CLK_128 // 128Hz
}LCDSCANCLKTypeDef;
/* LCD段式屏驱动初始化配置 */
void LCD_Init(LCDDutyTypeDef duty, LCDBiasTypeDef bias);
#define LCD_PowerDown() (R32_LCD_CMD &= ~(RB_LCD_ON | RB_LCD_SYS_EN)) /* LCD功能模块关闭 */
#define LCD_PowerOn() (R32_LCD_CMD |= (RB_LCD_ON | RB_LCD_SYS_EN)) /* LCD功能模块开启 */
// 输入值参考 LCDDrvPowerTypeDef
#define LCD_PowerCfg( d ) (R32_LCD_CMD = (R32_LCD_CMD & ~RB_LCD_VLCD_SEL) | (d<<7)) /* 配置LCD的 供电电压选择 */
// 输入值参考 LCDSCANCLKTypeDef
#define LCD_ScanCLKCfg( d ) (R32_LCD_CMD = (R32_LCD_CMD & ~RB_LCD_SCAN_CLK) | (d<<5)) /* 配置LCD的 扫描时钟选择 */
// 输入值参考 LCDDutyTypeDef
#define LCD_DutyCfg( d ) (R32_LCD_CMD = (R32_LCD_CMD & ~RB_LCD_DUTY) | (d<<3)) /* 配置LCD的 duty选择 */
// 输入值参考 LCDBiasTypeDef
#define LCD_BiasCfg( d ) (R32_LCD_CMD = (R32_LCD_CMD & ~RB_LCD_BIAS) | (d<<2)) /* 配置LCD的 bias选择 */
#define LCD_WriteData0( d ) (R32_LCD_RAM0 = (R32_LCD_RAM0 & 0xffffff00) | ((UINT32)d)) /* 填充SEG0驱动数值 */
#define LCD_WriteData1( d ) (R32_LCD_RAM0 = (R32_LCD_RAM0 & 0xffff00ff) | ((UINT32)d<<8)) /* 填充SEG1驱动数值 */
#define LCD_WriteData2( d ) (R32_LCD_RAM0 = (R32_LCD_RAM0 & 0xff00ffff) | ((UINT32)d<<16)) /* 填充SEG2驱动数值 */
#define LCD_WriteData3( d ) (R32_LCD_RAM0 = (R32_LCD_RAM0 & 0x00ffffff) | ((UINT32)d<<24)) /* 填充SEG3驱动数值 */
#define LCD_WriteData4( d ) (R32_LCD_RAM1 = (R32_LCD_RAM1 & 0xffffff00) | ((UINT32)d)) /* 填充SEG4驱动数值 */
#define LCD_WriteData5( d ) (R32_LCD_RAM1 = (R32_LCD_RAM1 & 0xffff00ff) | ((UINT32)d<<8)) /* 填充SEG5驱动数值 */
#define LCD_WriteData6( d ) (R32_LCD_RAM1 = (R32_LCD_RAM1 & 0xff00ffff) | ((UINT32)d<<16)) /* 填充SEG6驱动数值 */
#define LCD_WriteData7( d ) (R32_LCD_RAM1 = (R32_LCD_RAM1 & 0x00ffffff) | ((UINT32)d<<24)) /* 填充SEG7驱动数值 */
#define LCD_WriteData8( d ) (R32_LCD_RAM2 = (R32_LCD_RAM2 & 0xffffff00) | ((UINT32)d)) /* 填充SEG8驱动数值 */
#define LCD_WriteData9( d ) (R32_LCD_RAM2 = (R32_LCD_RAM2 & 0xffff00ff) | ((UINT32)d<<8)) /* 填充SEG9驱动数值 */
#define LCD_WriteData10( d ) (R32_LCD_RAM2 = (R32_LCD_RAM2 & 0xff00ffff) | ((UINT32)d<<16)) /* 填充SEG10驱动数值 */
#ifdef __cplusplus
}
#endif
#endif // __CH59x_LCD_H__

View File

@ -0,0 +1,152 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_pwm.h
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* 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 __CH59x_PWM_H__
#define __CH59x_PWM_H__
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief channel of PWM define
*/
#define CH_PWM4 0x01 // PWM4 通道
#define CH_PWM5 0x02 // PWM5 通道
#define CH_PWM6 0x04 // PWM6 通道
#define CH_PWM7 0x08 // PWM7 通道
#define CH_PWM8 0x10 // PWM8 通道
#define CH_PWM9 0x20 // PWM9 通道
#define CH_PWM10 0x40 // PWM10 通道
#define CH_PWM11 0x80 // PWM11 通道
/**
* @brief channel of PWM define
*/
typedef enum
{
High_Level = 0, // 默认低电平,高电平有效
Low_Level, // 默认高电平,低电平有效
} PWMX_PolarTypeDef;
/**
* @brief Configuration PWM4_11 Cycle size
*/
typedef enum
{
PWMX_Cycle_256 = 0, // 256 个PWMX周期
PWMX_Cycle_255, // 255 个PWMX周期
PWMX_Cycle_128, // 128 个PWMX周期
PWMX_Cycle_127, // 127 个PWMX周期
PWMX_Cycle_64, // 64 个PWMX周期
PWMX_Cycle_63, // 63 个PWMX周期
PWMX_Cycle_32, // 32 个PWMX周期
PWMX_Cycle_31, // 31 个PWMX周期
} PWMX_CycleTypeDef;
/**
* @brief PWM4-PWM11
*
* @param d - = d*Tsys
*/
#define PWMX_CLKCfg(d) (R8_PWM_CLOCK_DIV = d)
/**
* @brief PWM4-PWM11基准时钟配置
*
* @param cyc - refer to PWMX_CycleTypeDef
*/
void PWMX_CycleCfg(PWMX_CycleTypeDef cyc);
/**
* @brief PWM4
*
* @param d -
*/
#define PWM4_ActDataWidth(d) (R8_PWM4_DATA = d)
/**
* @brief PWM5
*
* @param d -
*/
#define PWM5_ActDataWidth(d) (R8_PWM5_DATA = d)
/**
* @brief PWM6
*
* @param d -
*/
#define PWM6_ActDataWidth(d) (R8_PWM6_DATA = d)
/**
* @brief PWM7
*
* @param d -
*/
#define PWM7_ActDataWidth(d) (R8_PWM7_DATA = d)
/**
* @brief PWM8
*
* @param d -
*/
#define PWM8_ActDataWidth(d) (R8_PWM8_DATA = d)
/**
* @brief PWM9
*
* @param d -
*/
#define PWM9_ActDataWidth(d) (R8_PWM9_DATA = d)
/**
* @brief PWM10
*
* @param d -
*/
#define PWM10_ActDataWidth(d) (R8_PWM10_DATA = d)
/**
* @brief PWM11
*
* @param d -
*/
#define PWM11_ActDataWidth(d) (R8_PWM11_DATA = d)
/**
* @brief PWM4-PWM11通道输出波形配置
*
* @param ch - select channel of pwm, refer to channel of PWM define
* @param da - effective pulse width
* @param pr - select wave polar, refer to PWMX_PolarTypeDef
* @param s - control pwmx function, ENABLE or DISABLE
*/
void PWMX_ACTOUT(uint8_t ch, uint8_t da, PWMX_PolarTypeDef pr, FunctionalState s);
/**
* @brief PWM
*
* @param ch - select group of PWM alternate output
* RB_PWM4_5_STAG_EN - PWM4 PWM5
* RB_PWM6_7_STAG_EN - PWM6 PWM7
* RB_PWM8_9_STAG_EN - PWM8 PWM9
* RB_PWM10_11_STAG_EN - PWM10 PWM11
* @param s - control pwmx function, ENABLE or DISABLE
*/
void PWMX_AlterOutCfg(uint8_t ch, FunctionalState s);
#ifdef __cplusplus
}
#endif
#endif // __CH59x_PWM_H__

View File

@ -0,0 +1,169 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_pwr.h
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* 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 __CH59x_PWR_H__
#define __CH59x_PWR_H__
#ifdef __cplusplus
extern "C" {
#endif
#define ROM_CFG_ADR_HW 0x7F00C // config address for hardware config for LDO&OSC and etc
/**
* @brief Peripher CLK control bit define
*/
#define BIT_SLP_CLK_TMR0 (0x00000001) /*!< TMR0 peripher clk bit */
#define BIT_SLP_CLK_TMR1 (0x00000002) /*!< TMR1 peripher clk bit */
#define BIT_SLP_CLK_TMR2 (0x00000004) /*!< TMR2 peripher clk bit */
#define BIT_SLP_CLK_TMR3 (0x00000008) /*!< TMR3 peripher clk bit */
#define BIT_SLP_CLK_UART0 (0x00000010) /*!< UART0 peripher clk bit */
#define BIT_SLP_CLK_UART1 (0x00000020) /*!< UART1 peripher clk bit */
#define BIT_SLP_CLK_UART2 (0x00000040) /*!< UART2 peripher clk bit */
#define BIT_SLP_CLK_UART3 (0x00000080) /*!< UART3 peripher clk bit */
#define BIT_SLP_CLK_SPI0 (0x00000100) /*!< SPI0 peripher clk bit */
//#define BIT_SLP_CLK_SPI1 (0x00000200) /*!< SPI1 peripher clk bit */
#define BIT_SLP_CLK_PWMX (0x00000400) /*!< PWMX peripher clk bit */
//#define BIT_SLP_CLK_LCD (0x00000800) /*!< LCD peripher clk bit */
#define BIT_SLP_CLK_USB (0x00001000) /*!< USB peripher clk bit */
//#define BIT_SLP_CLK_ETH (0x00002000) /*!< ETH peripher clk bit */
//#define BIT_SLP_CLK_LED (0x00004000) /*!< LED peripher clk bit */
#define BIT_SLP_CLK_BLE (0x00008000) /*!< BLE peripher clk bit */
#define BIT_SLP_CLK_RAMX (0x10000000) /*!< main SRAM RAM16K peripher clk bit */
#define BIT_SLP_CLK_RAM2K (0x20000000) /*!< RAM2K peripher clk bit */
#define BIT_SLP_CLK_ALL (0x3000FFFF) /*!< All peripher clk bit */
/**
* @brief unit of controllable power supply
*/
#define UNIT_SYS_LSE RB_CLK_XT32K_PON // 外部32K 时钟振荡
#define UNIT_SYS_LSI RB_CLK_INT32K_PON // 内部32K 时钟振荡
#define UNIT_SYS_HSE RB_CLK_XT32M_PON // 外部32M 时钟振荡
#define UNIT_SYS_PLL RB_CLK_PLL_PON // PLL 时钟振荡
/**
* @brief wakeup mode define
*/
typedef enum
{
Short_Delay = 0,
Long_Delay,
} WakeUP_ModeypeDef;
/**
* @brief wakeup mode define
*/
typedef enum
{
/* 下面等级将使用高精度监控210uA消耗 */
HALevel_1V9 = 0, // 1.7-1.9
HALevel_2V1, // 1.9-2.1
HALevel_2V3, // 2.1-2.3
HALevel_2V5, // 2.3-2.5
/* 下面等级将使用低功耗监控1uA消耗 */
LPLevel_1V8 = 0x80,
LPLevel_1V9,
LPLevel_2V0,
LPLevel_2V1,
LPLevel_2V2,
LPLevel_2V3,
LPLevel_2V4,
LPLevel_2V5,
} VolM_LevelypeDef;
/**
* @brief DC/DC电源
*
* @param s - DCDC电源
*/
void PWR_DCDCCfg(FunctionalState s);
/**
* @brief
*
* @param s -
* @param unit - please refer to unit of controllable power supply
*/
void PWR_UnitModCfg(FunctionalState s, uint8_t unit);
/**
* @brief
*
* @param s -
* @param perph - please refer to Peripher CLK control bit define
*/
void PWR_PeriphClkCfg(FunctionalState s, uint16_t perph);
/**
* @brief
*
* @param s -
* @param perph -
* RB_SLP_USB_WAKE - USB
* RB_SLP_RTC_WAKE - RTC
* RB_SLP_GPIO_WAKE - GPIO
* RB_SLP_BAT_WAKE - BAT
* @param mode - refer to WakeUP_ModeypeDef
*/
void PWR_PeriphWakeUpCfg(FunctionalState s, uint8_t perph, WakeUP_ModeypeDef mode);
/**
* @brief
*
* @param s -
* @param vl - refer to VolM_LevelypeDef
*/
void PowerMonitor(FunctionalState s, VolM_LevelypeDef vl);
/**
* @brief -Idle模式
*/
void LowPower_Idle(void);
/**
* @brief -Halt模式HSI/5
*/
void LowPower_Halt(void);
/**
* @brief -Sleep模式HSI/5
* @note DCDC功能强制关闭
*
* @param rm -
* RB_PWR_RAM2K - 2K retention SRAM
* RB_PWR_RAM16K - 16K main SRAM
* RB_PWR_EXTEND - USB BLE
* RB_PWR_XROM - FlashROM
* NULL -
*/
void LowPower_Sleep(uint16_t rm);
/**
* @brief -Shutdown模式HSI/5
* @note DCDC功能强制关闭
*
* @param rm -
* RB_PWR_RAM2K - 2K retention SRAM
* RB_PWR_RAM16K - 16K main SRAM
* NULL -
*/
void LowPower_Shutdown(uint16_t rm);
#ifdef __cplusplus
}
#endif
#endif // __CH59x_PWR_H__

View File

@ -0,0 +1,214 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_SPI.h
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* 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 __CH59x_SPI_H__
#define __CH59x_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 // FIFO 溢出
#define SPI0_IT_DMA_END RB_SPI_IE_DMA_END // DMA 传输结束
#define SPI0_IT_FIFO_HF RB_SPI_IE_FIFO_HF // FIFO 使用过半
#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, // 模式0低位在前
Mode0_HighBitINFront, // 模式0高位在前
Mode3_LowBitINFront, // 模式3低位在前
Mode3_HighBitINFront, // 模式3高位在前
} ModeBitOrderTypeDef;
/**
* @brief Configuration SPI0 slave mode
*/
typedef enum
{
Mode_DataStream = 0, // 数据流模式
Mose_FirstCmd, // 首字节命令模式
} Slave_ModeTypeDef;
/**
* @brief 0+3线+8MHz
*/
void SPI0_MasterDefInit(void);
/**
* @brief SPI0 = d*Tsys
*
* @param c -
*/
void SPI0_CLKCfg(uint8_t c);
/**
* @brief
*
* @param m - refer to ModeBitOrderTypeDef
*/
void SPI0_DataMode(ModeBitOrderTypeDef m);
/**
* @brief (buffer)
*
* @param d -
*/
void SPI0_MasterSendByte(uint8_t d);
/**
* @brief (buffer)
*
* @param none
*/
uint8_t SPI0_MasterRecvByte(void);
/**
* @brief 使FIFO连续发送多字节
*
* @param pbuf -
* @param len - 4095
*/
void SPI0_MasterTrans(uint8_t *pbuf, uint16_t len);
/**
* @brief 使FIFO连续接收多字节
*
* @param pbuf -
* @param len - 4095
*/
void SPI0_MasterRecv(uint8_t *pbuf, uint16_t len);
/**
* @brief DMA方式连续发送数据
*
* @param pbuf - ,
* @param len -
*/
void SPI0_MasterDMATrans(uint8_t *pbuf, uint16_t len);
/**
* @brief DMA方式连续接收数据
*
* @param pbuf - ,
* @param len -
*/
void SPI0_MasterDMARecv(uint8_t *pbuf, uint16_t len);
void SPI1_MasterDefInit(void); /* 主机模式默认初始化模式0+3线全双工+8MHz */
void SPI1_CLKCfg(UINT8 c); /* SPI1 基准时钟配置,= d*Tsys */
void SPI1_DataMode(ModeBitOrderTypeDef m); /* 设置数据流模式 */
void SPI1_MasterSendByte(UINT8 d); /* 发送单字节 (buffer) */
UINT8 SPI1_MasterRecvByte(void); /* 接收单字节 (buffer) */
void SPI1_MasterTrans(UINT8 *pbuf, UINT16 len); /* 使用FIFO连续发送多字节 */
void SPI1_MasterRecv(UINT8 *pbuf, UINT16 len); /* 使用FIFO连续接收多字节 */
/**
* @brief MISO的GPIO对应为输入模式
*/
void SPI0_SlaveInit(void);
/**
* @brief
*
* @param d -
*/
#define SetFirstData(d) (R8_SPI0_SLAVE_PRE = d)
/**
* @brief
*
* @param d -
*/
void SPI0_SlaveSendByte(uint8_t d);
/**
* @brief
*
* @return
*/
uint8_t SPI0_SlaveRecvByte(void);
/**
* @brief
*
* @param pbuf -
* @param len - 4095
*/
void SPI0_SlaveTrans(uint8_t *pbuf, uint16_t len);
/**
* @brief
*
* @param pbuf -
* @param len -
*/
void SPI0_SlaveRecv(uint8_t *pbuf, uint16_t len);
/**
* @brief DMA方式连续发送数据
*
* @param pbuf - ,
* @param len -
*/
void SPI0_SlaveDMATrans(uint8_t *pbuf, uint16_t len);
/**
* @brief DMA方式连续接收数据
*
* @param pbuf - ,
* @param len -
*/
void SPI0_SlaveDMARecv(uint8_t *pbuf, uint16_t len);
/**
* @brief SPI0中断
*
* @param s - 使/
* @param f - refer to SPI0 interrupt bit define
*/
#define SPI0_ITCfg(s, f) ((s) ? (R8_SPI0_INTER_EN |= f) : (R8_SPI0_INTER_EN &= ~f))
/**
* @brief 0-(!0)-
*
* @param f - refer to SPI0 interrupt bit define
*/
#define SPI0_GetITFlag(f) (R8_SPI0_INT_FLAG & f)
/**
* @brief
*
* @param f - refer to SPI0 interrupt bit define
*/
#define SPI0_ClearITFlag(f) (R8_SPI0_INT_FLAG = f)
/**
* @brief SPI0
*/
#define SPI0_Disable() (R8_SPI0_CTRL_MOD &= ~(RB_SPI_MOSI_OE | RB_SPI_SCK_OE | RB_SPI_MISO_OE))
#ifdef __cplusplus
}
#endif
#endif // __CH59x_SPI_H__

View File

@ -0,0 +1,205 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_SYS.h
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* 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 __CH59x_SYS_H__
#define __CH59x_SYS_H__
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief rtc interrupt event define
*/
typedef enum
{
RST_STATUS_SW = 0, // 软件复位
RST_STATUS_RPOR, // 上电复位
RST_STATUS_WTR, // 看门狗超时复位
RST_STATUS_MR, // 外部手动复位
RST_STATUS_LRM0, // 唤醒复位-软复位引起
RST_STATUS_GPWSM, // 下电模式唤醒复位
RST_STATUS_LRM1, // 唤醒复位-看门狗引起
RST_STATUS_LRM2, // 唤醒复位-手动复位引起
} SYS_ResetStaTypeDef;
/**
* @brief rtc interrupt event define
*/
typedef enum
{
INFO_ROM_READ = 0, // FlashROM 代码和数据区 是否可读
INFO_RESET_EN = 2, // RST#外部手动复位输入功能是否开启
INFO_BOOT_EN, // 系统引导程序 BootLoader 是否开启
INFO_DEBUG_EN, // 系统仿真调试接口是否开启
INFO_LOADER, // 当前系统是否处于Bootloader 区
STA_SAFEACC_ACT, // 当前系统是否处于安全访问状态否则RWA属性区域不可访问
} SYS_InfoStaTypeDef;
/**
* @brief ID类
*/
#define SYS_GetChipID() R8_CHIP_ID
/**
* @brief 访ID
*/
#define SYS_GetAccessID() R8_SAFE_ACCESS_ID
/**
* @brief
*
* @param sc - refer to SYS_CLKTypeDef
*/
void SetSysClock(SYS_CLKTypeDef sc);
/**
* @brief
*
* @return Hz
*/
uint32_t GetSysClock(void);
/**
* @brief
*
* @param i - refer to SYS_InfoStaTypeDef
*
* @return
*/
uint8_t SYS_GetInfoSta(SYS_InfoStaTypeDef i);
/**
* @brief
*
* @return refer to SYS_ResetStaTypeDef
*/
#define SYS_GetLastResetSta() (R8_RESET_STATUS & RB_RESET_FLAG)
/**
* @brief
*/
void SYS_ResetExecute(void);
/**
* @brief
*
* @param i - refer to SYS_InfoStaTypeDef
*/
#define SYS_ResetKeepBuf(d) (R8_GLOB_RESET_KEEP = d)
/**
* @brief
*
* @param pirqv -
*/
void SYS_DisableAllIrq(uint32_t *pirqv);
/**
* @brief
*
* @param irq_status -
*/
void SYS_RecoverIrq(uint32_t irq_status);
/**
* @brief (SYSTICK)
*
* @return
*/
uint32_t SYS_GetSysTickCnt(void);
/**
* @brief
*
* @param c -
*/
#define WWDG_SetCounter(c) (R8_WDOG_COUNT = c)
/**
* @brief 使
*
* @param s -
*/
void WWDG_ITCfg(FunctionalState s);
/**
* @brief
*
* @param s -
*/
void WWDG_ResetCfg(FunctionalState s);
/**
* @brief
*
* @return
*/
#define WWDG_GetFlowFlag() (R8_RST_WDOG_CTRL & RB_WDOG_INT_FLAG)
/**
* @brief
*/
void WWDG_ClearFlag(void);
/**
* @brief uS
*
* @param t -
*/
void mDelayuS(uint16_t t);
/**
* @brief mS
*
* @param t -
*/
void mDelaymS(uint16_t t);
extern volatile uint32_t IRQ_STA;
/**
* @brief Enter safe access mode.
*
* @NOTE: After enter safe access mode, about 16 system frequency cycles
* are in safe mode, and one or more secure registers can be rewritten
* within the valid period. The safe mode will be automatically
* terminated after the above validity period is exceeded.
*/
__attribute__((always_inline)) static inline void sys_safe_access_enable(void)
{
if(read_csr(0x800)&0x08)
{
IRQ_STA = read_csr(0x800);
write_csr(0x800, (IRQ_STA&(~0x08)));
}
SAFEOPERATE;
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
SAFEOPERATE;
}
__attribute__((always_inline)) static inline void sys_safe_access_disable(void)
{
R8_SAFE_ACCESS_SIG = 0;
write_csr(0x800, read_csr(0x800)|(IRQ_STA&0x08));
IRQ_STA = 0;
SAFEOPERATE;
}
#ifdef __cplusplus
}
#endif
#endif // __CH59x_SYS_H__

View File

@ -0,0 +1,595 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_timer.h
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* 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 __CH59x_TIMER_H__
#define __CH59x_TIMER_H__
#ifdef __cplusplus
extern "C" {
#endif
#define DataBit_25 (1 << 25)
/**
* @brief TMR0 interrupt bit define
*/
#define TMR0_3_IT_CYC_END 0x01 // 周期结束标志:捕捉-超时,定时-周期结束PWM-周期结束
#define TMR0_3_IT_DATA_ACT 0x02 // 数据有效标志:捕捉-新数据PWM-有效电平结束
#define TMR0_3_IT_FIFO_HF 0x04 // FIFO 使用过半:捕捉- FIFO>=4 PWM- FIFO<4
#define TMR1_2_IT_DMA_END 0x08 // DMA 结束支持TMR1和TMR2
#define TMR0_3_IT_FIFO_OV 0x10 // FIFO 溢出:捕捉- FIFO满 PWM- FIFO空
/**
* @brief Configuration PWM effective level repeat times
*/
typedef enum
{
PWM_Times_1 = 0, // PWM 有效输出重复1次数
PWM_Times_4, // PWM 有效输出重复4次数
PWM_Times_8, // PWM 有效输出重复8次数
PWM_Times_16, // PWM 有效输出重复16次数
} PWM_RepeatTsTypeDef;
/**
* @brief Configuration Cap mode
*/
typedef enum
{
CAP_NULL = 0, // 不捕捉 & 不计数
Edge_To_Edge, // 任意边沿之间 & 计数任意边沿
FallEdge_To_FallEdge, // 下降沿到下降沿 & 计数下降沿
RiseEdge_To_RiseEdge, // 上升沿到上升沿 & 计数上升沿
} CapModeTypeDef;
/**
* @brief Configuration DMA mode
*/
typedef enum
{
Mode_Single = 0, // 单次模式
Mode_LOOP, // 循环模式
} DMAModeTypeDef;
/**
* @brief
*
* @param t - Tsys, 67108864
*/
void TMR0_TimerInit(uint32_t t);
/**
* @brief 67108864
*
* @return
*/
#define TMR0_GetCurrentTimer() R32_TMR0_COUNT
/**
* @brief 沿
*
* @param cap -
*/
void TMR0_EXTSingleCounterInit(CapModeTypeDef cap);
/**
* @brief 67108862
*
* @param cyc -
*/
#define TMR0_CountOverflowCfg(cyc) (R32_TMR0_CNT_END = (cyc + 2))
/**
* @brief 67108862
*
* @return
*/
#define TMR0_GetCurrentCount() R32_TMR0_COUNT
/**
* @brief PWM0 , 67108864
*
* @param cyc -
*/
#define TMR0_PWMCycleCfg(cyc) (R32_TMR0_CNT_END = cyc)
/**
* @brief PWM
*
* @param pr - select wave polar, refer to PWMX_PolarTypeDef
* @param ts - set pwm repeat times, refer to PWM_RepeatTsTypeDef
*/
void TMR0_PWMInit(PWMX_PolarTypeDef pr, PWM_RepeatTsTypeDef ts);
/**
* @brief PWM0 , 67108864
*
* @param d -
*/
#define TMR0_PWMActDataWidth(d) (R32_TMR0_FIFO = d)
/**
* @brief CAP0 , 33554432
*
* @param cyc -
*/
#define TMR0_CAPTimeoutCfg(cyc) (R32_TMR0_CNT_END = cyc)
/**
* @brief
*
* @param cap - select capture mode, refer to CapModeTypeDef
*/
void TMR0_CapInit(CapModeTypeDef cap);
/**
* @brief
*
* @return
*/
#define TMR0_CAPGetData() R32_TMR0_FIFO
/**
* @brief
*
* @return
*/
#define TMR0_CAPDataCounter() R8_TMR0_FIFO_COUNT
/**
* @brief TMR0 PWM输出
*/
#define TMR0_PWMDisable() (R8_TMR0_CTRL_MOD &= ~RB_TMR_OUT_EN)
/**
* @brief TMR0 PWM输出
*/
#define TMR0_PWMEnable() (R8_TMR0_CTRL_MOD |= RB_TMR_OUT_EN)
/**
* @brief TMR0
*/
#define TMR0_Disable() (R8_TMR0_CTRL_MOD &= ~RB_TMR_COUNT_EN)
/**
* @brief TMR0
*/
#define TMR0_Enable() (R8_TMR0_CTRL_MOD |= RB_TMR_COUNT_EN)
/**
* @brief
*
* @param s - 使/
* @param f - refer to TMR interrupt bit define
*/
#define TMR0_ITCfg(s, f) ((s) ? (R8_TMR0_INTER_EN |= f) : (R8_TMR0_INTER_EN &= ~f))
/**
* @brief
*
* @param f - refer to TMR interrupt bit define
*/
#define TMR0_ClearITFlag(f) (R8_TMR0_INT_FLAG = f)
/**
* @brief
*
* @param f - refer to TMR interrupt bit define
*/
#define TMR0_GetITFlag(f) (R8_TMR0_INT_FLAG & f)
/**
* @brief
*
* @param t - Tsys, 67108864
*/
void TMR1_TimerInit(uint32_t t);
/**
* @brief 67108864
*
* @return
*/
#define TMR1_GetCurrentTimer() R32_TMR1_COUNT
/**
* @brief 沿
*
* @param cap -
*/
void TMR1_EXTSingleCounterInit(CapModeTypeDef cap);
/**
* @brief 67108862
*
* @param cyc -
*/
#define TMR1_CountOverflowCfg(cyc) (R32_TMR1_CNT_END = (cyc + 2))
/**
* @brief 67108862
*
* @return
*/
#define TMR1_GetCurrentCount() R32_TMR1_COUNT
/**
* @brief PWM1 , 67108864
*
* @param cyc -
*/
#define TMR1_PWMCycleCfg(cyc) (R32_TMR1_CNT_END = cyc)
/**
* @brief PWM
*
* @param pr - select wave polar, refer to PWMX_PolarTypeDef
* @param ts - set pwm repeat times, refer to PWM_RepeatTsTypeDef
*/
void TMR1_PWMInit(PWMX_PolarTypeDef pr, PWM_RepeatTsTypeDef ts);
/**
* @brief PWM1 , 67108864
*
* @param d -
*/
#define TMR1_PWMActDataWidth(d) (R32_TMR1_FIFO = d)
/**
* @brief CAP1 , 33554432
*
* @param cyc -
*/
#define TMR1_CAPTimeoutCfg(cyc) (R32_TMR1_CNT_END = cyc)
/**
* @brief
*
* @param cap - select capture mode, refer to CapModeTypeDef
*/
void TMR1_CapInit(CapModeTypeDef cap);
/**
* @brief
*
* @return
*/
#define TMR1_CAPGetData() R32_TMR1_FIFO
/**
* @brief
*
* @return
*/
#define TMR1_CAPDataCounter() R8_TMR1_FIFO_COUNT
/**
* @brief DMA功能
*
* @param s - DMA功能
* @param startAddr - DMA
* @param endAddr - DMA
* @param m - DMA模式
*/
void TMR1_DMACfg(uint8_t s, uint16_t startAddr, uint16_t endAddr, DMAModeTypeDef m);
/**
* @brief TMR1 PWM输出
*/
#define TMR1_PWMDisable() (R8_TMR1_CTRL_MOD &= ~RB_TMR_OUT_EN)
/**
* @brief TMR1 PWM输出
*/
#define TMR1_PWMEnable() (R8_TMR1_CTRL_MOD |= RB_TMR_OUT_EN)
/**
* @brief TMR1
*/
#define TMR1_Disable() (R8_TMR1_CTRL_MOD &= ~RB_TMR_COUNT_EN)
/**
* @brief TMR1
*/
#define TMR1_Enable() (R8_TMR1_CTRL_MOD |= RB_TMR_COUNT_EN)
/**
* @brief
*
* @param s - 使/
* @param f - refer to TMR interrupt bit define
*/
#define TMR1_ITCfg(s, f) ((s) ? (R8_TMR1_INTER_EN |= f) : (R8_TMR1_INTER_EN &= ~f))
/**
* @brief
*
* @param f - refer to TMR interrupt bit define
*/
#define TMR1_ClearITFlag(f) (R8_TMR1_INT_FLAG = f)
/**
* @brief
*
* @param f - refer to TMR interrupt bit define
*/
#define TMR1_GetITFlag(f) (R8_TMR1_INT_FLAG & f)
/**
* @brief
*
* @param t - Tsys, 67108864
*/
void TMR2_TimerInit(uint32_t t);
/**
* @brief 67108864
*
* @return
*/
#define TMR2_GetCurrentTimer() R32_TMR2_COUNT
/**
* @brief 沿
*
* @param cap -
*/
void TMR2_EXTSingleCounterInit(CapModeTypeDef cap);
/**
* @brief 67108862
*
* @param cyc -
*/
#define TMR2_CountOverflowCfg(cyc) (R32_TMR2_CNT_END = (cyc + 2))
/**
* @brief 67108862
*
* @return
*/
#define TMR2_GetCurrentCount() R32_TMR2_COUNT
/**
* @brief PWM2 , 67108864
*
* @param cyc -
*/
#define TMR2_PWMCycleCfg(cyc) (R32_TMR2_CNT_END = cyc)
/**
* @brief PWM
*
* @param pr - select wave polar, refer to PWMX_PolarTypeDef
* @param ts - set pwm repeat times, refer to PWM_RepeatTsTypeDef
*/
void TMR2_PWMInit(PWMX_PolarTypeDef pr, PWM_RepeatTsTypeDef ts);
/**
* @brief PWM2 , 67108864
*
* @param d -
*/
#define TMR2_PWMActDataWidth(d) (R32_TMR2_FIFO = d)
/**
* @brief CAP2 , 33554432
*
* @param cyc -
*/
#define TMR2_CAPTimeoutCfg(cyc) (R32_TMR2_CNT_END = cyc)
/**
* @brief
*
* @param cap - select capture mode, refer to CapModeTypeDef
*/
void TMR2_CapInit(CapModeTypeDef cap);
/**
* @brief
*
* @return
*/
#define TMR2_CAPGetData() R32_TMR2_FIFO
/**
* @brief
*
* @return
*/
#define TMR2_CAPDataCounter() R8_TMR2_FIFO_COUNT
/**
* @brief DMA功能
*
* @param s - DMA功能
* @param startAddr - DMA
* @param endAddr - DMA
* @param m - DMA模式
*/
void TMR2_DMACfg(uint8_t s, uint32_t startAddr, uint32_t endAddr, DMAModeTypeDef m);
/**
* @brief TMR2 PWM输出
*/
#define TMR2_PWMDisable() (R8_TMR2_CTRL_MOD &= ~RB_TMR_OUT_EN)
/**
* @brief TMR2 PWM输出
*/
#define TMR2_PWMEnable() (R8_TMR2_CTRL_MOD |= RB_TMR_OUT_EN)
/**
* @brief TMR2
*/
#define TMR2_Disable() (R8_TMR2_CTRL_MOD &= ~RB_TMR_COUNT_EN)
/**
* @brief TMR2
*/
#define TMR2_Enable() (R8_TMR2_CTRL_MOD |= RB_TMR_COUNT_EN)
/**
* @brief
*
* @param s - 使/
* @param f - refer to TMR interrupt bit define
*/
#define TMR2_ITCfg(s, f) ((s) ? (R8_TMR2_INTER_EN |= f) : (R8_TMR2_INTER_EN &= ~f))
/**
* @brief
*
* @param f - refer to TMR interrupt bit define
*/
#define TMR2_ClearITFlag(f) (R8_TMR2_INT_FLAG = f)
/**
* @brief
*
* @param f - refer to TMR interrupt bit define
*/
#define TMR2_GetITFlag(f) (R8_TMR2_INT_FLAG & f)
/**
* @brief
*
* @param t - Tsys, 67108864
*/
void TMR3_TimerInit(uint32_t t);
/**
* @brief 67108864
*
* @return
*/
#define TMR3_GetCurrentTimer() R32_TMR3_COUNT
/**
* @brief 沿
*
* @param cap -
*/
void TMR3_EXTSingleCounterInit(CapModeTypeDef cap);
/**
* @brief 67108862
*
* @param cyc -
*/
#define TMR3_CountOverflowCfg(cyc) (R32_TMR3_CNT_END = (cyc + 2))
/**
* @brief 67108862
*
* @return
*/
#define TMR3_GetCurrentCount() R32_TMR3_COUNT
/**
* @brief PWM3 , 67108864
*
* @param cyc -
*/
#define TMR3_PWMCycleCfg(cyc) (R32_TMR3_CNT_END = cyc)
/**
* @brief PWM
*
* @param pr - select wave polar, refer to PWMX_PolarTypeDef
* @param ts - set pwm repeat times, refer to PWM_RepeatTsTypeDef
*/
void TMR3_PWMInit(PWMX_PolarTypeDef pr, PWM_RepeatTsTypeDef ts);
/**
* @brief PWM3 , 67108864
*
* @param d -
*/
#define TMR3_PWMActDataWidth(d) (R32_TMR3_FIFO = d)
/**
* @brief CAP3 , 33554432
*
* @param cyc -
*/
#define TMR3_CAPTimeoutCfg(cyc) (R32_TMR3_CNT_END = cyc)
/**
* @brief
*
* @param cap - select capture mode, refer to CapModeTypeDef
*/
void TMR3_CapInit(CapModeTypeDef cap);
/**
* @brief
*
* @return
*/
#define TMR3_CAPGetData() R32_TMR3_FIFO
/**
* @brief
*
* @return
*/
#define TMR3_CAPDataCounter() R8_TMR3_FIFO_COUNT
/**
* @brief TMR3 PWM输出
*/
#define TMR3_PWMDisable() (R8_TMR3_CTRL_MOD &= ~RB_TMR_OUT_EN)
/**
* @brief TMR3 PWM输出
*/
#define TMR3_PWMEnable() (R8_TMR3_CTRL_MOD |= RB_TMR_OUT_EN)
/**
* @brief TMR3
*/
#define TMR3_Disable() (R8_TMR3_CTRL_MOD &= ~RB_TMR_COUNT_EN)
/**
* @brief TMR3
*/
#define TMR3_Enable() (R8_TMR3_CTRL_MOD |= RB_TMR_COUNT_EN)
/**
* @brief
*
* @param s - 使/
* @param f - refer to TMR interrupt bit define
*/
#define TMR3_ITCfg(s, f) ((s) ? (R8_TMR3_INTER_EN |= f) : (R8_TMR3_INTER_EN &= ~f))
/**
* @brief
*
* @param f - refer to TMR interrupt bit define
*/
#define TMR3_ClearITFlag(f) (R8_TMR3_INT_FLAG = f)
/**
* @brief
*
* @param f - refer to TMR interrupt bit define
*/
#define TMR3_GetITFlag(f) (R8_TMR3_INT_FLAG & f)
#ifdef __cplusplus
}
#endif
#endif // __CH59x_TIMER_H__

View File

@ -0,0 +1,412 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_uart.h
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* 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 __CH59x_UART_H__
#define __CH59x_UART_H__
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief LINE error and status define
*/
#define STA_ERR_BREAK RB_LSR_BREAK_ERR // 数据间隔错误
#define STA_ERR_FRAME RB_LSR_FRAME_ERR // 数据帧错误
#define STA_ERR_PAR RB_LSR_PAR_ERR // 奇偶校验位出错
#define STA_ERR_FIFOOV RB_LSR_OVER_ERR // 接收数据溢出
#define STA_TXFIFO_EMP RB_LSR_TX_FIFO_EMP // 当前发送FIFO空可以继续填充发送数据
#define STA_TXALL_EMP RB_LSR_TX_ALL_EMP // 当前所有发送数据都发送完成
#define STA_RECV_DATA RB_LSR_DATA_RDY // 当前有接收到数据
/**
* @brief Configuration UART TrigByte num
*/
typedef enum
{
UART_1BYTE_TRIG = 0, // 1字节触发
UART_2BYTE_TRIG, // 2字节触发
UART_4BYTE_TRIG, // 4字节触发
UART_7BYTE_TRIG, // 7字节触发
} UARTByteTRIGTypeDef;
/**
* @brief
*/
void UART0_DefInit(void);
/**
* @brief
*
* @param baudrate -
*/
void UART0_BaudRateCfg(uint32_t baudrate);
/**
* @brief
*
* @param b - refer to UARTByteTRIGTypeDef
*/
void UART0_ByteTrigCfg(UARTByteTRIGTypeDef b);
/**
* @brief
*
* @param s - 使
* @param i -
* RB_IER_MODEM_CHG - 使 UART0
* RB_IER_LINE_STAT - 线
* RB_IER_THR_EMPTY -
* RB_IER_RECV_RDY -
*/
void UART0_INTCfg(FunctionalState s, uint8_t i);
/**
* @brief
*/
void UART0_Reset(void);
/**
* @brief FIFO
*/
#define UART0_CLR_RXFIFO() (R8_UART0_FCR |= RB_FCR_RX_FIFO_CLR)
/**
* @brief FIFO
*/
#define UART0_CLR_TXFIFO() (R8_UART0_FCR |= RB_FCR_TX_FIFO_CLR)
/**
* @brief
*
* @return
*/
#define UART0_GetITFlag() (R8_UART0_IIR & RB_IIR_INT_MASK)
/**
* @brief
*
* @return refer to LINE error and status define
*/
#define UART0_GetLinSTA() (R8_UART0_LSR)
/**
* @brief
*
* @param b
*/
#define UART0_SendByte(b) (R8_UART0_THR = b)
/**
* @brief
*
* @param buf -
* @param l -
*/
void UART0_SendString(uint8_t *buf, uint16_t l);
/**
* @brief
*
* @return
*/
#define UART0_RecvByte() (R8_UART0_RBR)
/**
* @brief
*
* @param buf -
*
* @return
*/
uint16_t UART0_RecvString(uint8_t *buf);
/**
* @brief
*/
void UART1_DefInit(void);
/**
* @brief
*
* @param baudrate -
*/
void UART1_BaudRateCfg(uint32_t baudrate);
/**
* @brief
*
* @param b - refer to UARTByteTRIGTypeDef
*/
void UART1_ByteTrigCfg(UARTByteTRIGTypeDef b);
/**
* @brief
*
* @param s - 使
* @param i -
* RB_IER_MODEM_CHG - 使 UART0
* RB_IER_LINE_STAT - 线
* RB_IER_THR_EMPTY -
* RB_IER_RECV_RDY -
*/
void UART1_INTCfg(FunctionalState s, uint8_t i);
/**
* @brief
*/
void UART1_Reset(void);
/**
* @brief FIFO
*/
#define UART1_CLR_RXFIFO() (R8_UART1_FCR |= RB_FCR_RX_FIFO_CLR)
/**
* @brief FIFO
*/
#define UART1_CLR_TXFIFO() (R8_UART1_FCR |= RB_FCR_TX_FIFO_CLR)
/**
* @brief
*
* @return
*/
#define UART1_GetITFlag() (R8_UART1_IIR & RB_IIR_INT_MASK)
/**
* @brief
*
* @return refer to LINE error and status define
*/
#define UART1_GetLinSTA() (R8_UART1_LSR)
/**
* @brief
*
* @param b
*/
#define UART1_SendByte(b) (R8_UART1_THR = b)
/**
* @brief
*
* @param buf -
* @param l -
*/
void UART1_SendString(uint8_t *buf, uint16_t l);
/**
* @brief
*
* @return
*/
#define UART1_RecvByte() (R8_UART1_RBR)
/**
* @brief
*
* @param buf -
*
* @return
*/
uint16_t UART1_RecvString(uint8_t *buf);
/**
* @brief
*/
void UART2_DefInit(void);
/**
* @brief
*
* @param baudrate -
*/
void UART2_BaudRateCfg(uint32_t baudrate);
/**
* @brief
*
* @param b - refer to UARTByteTRIGTypeDef
*/
void UART2_ByteTrigCfg(UARTByteTRIGTypeDef b);
/**
* @brief
*
* @param s - 使
* @param i -
* RB_IER_MODEM_CHG - 使 UART0
* RB_IER_LINE_STAT - 线
* RB_IER_THR_EMPTY -
* RB_IER_RECV_RDY -
*/
void UART2_INTCfg(FunctionalState s, uint8_t i);
/**
* @brief
*/
void UART2_Reset(void);
/**
* @brief FIFO
*/
#define UART2_CLR_RXFIFO() (R8_UART2_FCR |= RB_FCR_RX_FIFO_CLR)
/**
* @brief FIFO
*/
#define UART2_CLR_TXFIFO() (R8_UART2_FCR |= RB_FCR_TX_FIFO_CLR)
/**
* @brief
*
* @return
*/
#define UART2_GetITFlag() (R8_UART2_IIR & RB_IIR_INT_MASK)
/**
* @brief
*
* @return refer to LINE error and status define
*/
#define UART2_GetLinSTA() (R8_UART2_LSR)
/**
* @brief
*
* @param b
*/
#define UART2_SendByte(b) (R8_UART2_THR = b)
/**
* @brief
*
* @param buf -
* @param l -
*/
void UART2_SendString(uint8_t *buf, uint16_t l);
/**
* @brief
*
* @return
*/
#define UART2_RecvByte() (R8_UART2_RBR)
/**
* @brief
*
* @param buf -
*
* @return
*/
uint16_t UART2_RecvString(uint8_t *buf);
/**
* @brief
*/
void UART3_DefInit(void);
/**
* @brief
*
* @param baudrate -
*/
void UART3_BaudRateCfg(uint32_t baudrate);
/**
* @brief
*
* @param b - refer to UARTByteTRIGTypeDef
*/
void UART3_ByteTrigCfg(UARTByteTRIGTypeDef b);
/**
* @brief
*
* @param s - 使
* @param i -
* RB_IER_MODEM_CHG - 使 UART0
* RB_IER_LINE_STAT - 线
* RB_IER_THR_EMPTY -
* RB_IER_RECV_RDY -
*/
void UART3_INTCfg(FunctionalState s, uint8_t i);
/**
* @brief
*/
void UART3_Reset(void);
/**
* @brief FIFO
*/
#define UART3_CLR_RXFIFO() (R8_UART3_FCR |= RB_FCR_RX_FIFO_CLR)
/**
* @brief FIFO
*/
#define UART3_CLR_TXFIFO() (R8_UART3_FCR |= RB_FCR_TX_FIFO_CLR)
/**
* @brief
*
* @return
*/
#define UART3_GetITFlag() (R8_UART3_IIR & RB_IIR_INT_MASK)
/**
* @brief
*
* @return refer to LINE error and status define
*/
#define UART3_GetLinSTA() (R8_UART3_LSR)
/**
* @brief
*
* @param b
*/
#define UART3_SendByte(b) (R8_UART3_THR = b)
/**
* @brief
*
* @param buf -
* @param l -
*/
void UART3_SendString(uint8_t *buf, uint16_t l);
/**
* @brief
*
* @return
*/
#define UART3_RecvByte() (R8_UART3_RBR)
/**
* @brief
*
* @param buf -
*
* @return
*/
uint16_t UART3_RecvString(uint8_t *buf);
#ifdef __cplusplus
}
#endif
#endif // __CH59x_UART_H__

View File

@ -0,0 +1,152 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_usbdev.h
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* 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 __CH59x_USBDEV_H__
#define __CH59x_USBDEV_H__
#ifdef __cplusplus
extern "C" {
#endif
/* HID类请求 */
#define DEF_USB_GET_IDLE 0x02 /* get idle for key or mouse */
#define DEF_USB_GET_PROTOCOL 0x03 /* get protocol for bios type */
#define DEF_USB_SET_REPORT 0x09 /* set report for key */
#define DEF_USB_SET_IDLE 0x0A /* set idle for key or mouse */
#define DEF_USB_SET_PROTOCOL 0x0B /* set protocol for bios type */
/* 以下缓存区是USB模块收发使用的数据缓冲区总共9个通道9块缓存用户可根据实际使用的通道数定义相应缓存区 */
extern uint8_t *pEP0_RAM_Addr; //ep0(64)+ep4_out(64)+ep4_in(64)
extern uint8_t *pEP1_RAM_Addr; //ep1_out(64)+ep1_in(64)
extern uint8_t *pEP2_RAM_Addr; //ep2_out(64)+ep2_in(64)
extern uint8_t *pEP3_RAM_Addr; //ep3_out(64)+ep3_in(64)
#define pSetupReqPak ((PUSB_SETUP_REQ)pEP0_RAM_Addr)
#define pEP0_DataBuf (pEP0_RAM_Addr)
#define pEP1_OUT_DataBuf (pEP1_RAM_Addr)
#define pEP1_IN_DataBuf (pEP1_RAM_Addr + 64)
#define pEP2_OUT_DataBuf (pEP2_RAM_Addr)
#define pEP2_IN_DataBuf (pEP2_RAM_Addr + 64)
#define pEP3_OUT_DataBuf (pEP3_RAM_Addr)
#define pEP3_IN_DataBuf (pEP3_RAM_Addr + 64)
#define pEP4_OUT_DataBuf (pEP0_RAM_Addr + 64)
#define pEP4_IN_DataBuf (pEP0_RAM_Addr + 128)
/**
* @brief USB设备功能初始化48
*/
void USB_DeviceInit(void);
/**
* @brief USB设备应答传输处理
*/
void USB_DevTransProcess(void);
/**
* @brief 1
*
* @param l - (<64B)
*/
void DevEP1_OUT_Deal(uint8_t l);
/**
* @brief 2
*
* @param l - (<64B)
*/
void DevEP2_OUT_Deal(uint8_t l);
/**
* @brief 3
*
* @param l - (<64B)
*/
void DevEP3_OUT_Deal(uint8_t l);
/**
* @brief 4
*
* @param l - (<64B)
*/
void DevEP4_OUT_Deal(uint8_t l);
/**
* @brief 1
*
* @param l - (<64B)
*/
void DevEP1_IN_Deal(uint8_t l);
/**
* @brief 2
*
* @param l - (<64B)
*/
void DevEP2_IN_Deal(uint8_t l);
/**
* @brief 3
*
* @param l - (<64B)
*/
void DevEP3_IN_Deal(uint8_t l);
/**
* @brief 4
*
* @param l - (<64B)
*/
void DevEP4_IN_Deal(uint8_t l);
/**
* @brief 1
*
* @return 0- (!0)-
*/
#define EP1_GetINSta() (R8_UEP1_CTRL & UEP_T_RES_NAK)
/**
* @brief 2
*
* @return 0- (!0)-
*/
#define EP2_GetINSta() (R8_UEP2_CTRL & UEP_T_RES_NAK)
/**
* @brief 3
*
* @return 0- (!0)-
*/
#define EP3_GetINSta() (R8_UEP3_CTRL & UEP_T_RES_NAK)
/**
* @brief 4
*
* @return 0- (!0)-
*/
#define EP4_GetINSta() (R8_UEP4_CTRL & UEP_T_RES_NAK)
/**
* @brief USB上拉电阻
*/
#define USB_DisablePin() (R16_PIN_ANALOG_IE &= ~(RB_PIN_USB_IE | RB_PIN_USB_DP_PU))
/**
* @brief USB
*/
#define USB_Disable() (R32_USB_CONTROL = 0)
#ifdef __cplusplus
}
#endif
#endif // __CH59x_USBDEV_H__

View File

@ -0,0 +1,314 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_usbhost.h
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* 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 __CH59x_USBHOST_H__
#define __CH59x_USBHOST_H__
#ifdef __cplusplus
extern "C" {
#endif
#if DISK_LIB_ENABLE
#if DISK_WITHOUT_USB_HUB
/* 不使用U盘文件系统库或者U盘挂载USBhub下面需要关闭下面定义 */
#define FOR_ROOT_UDISK_ONLY
#endif
/* 使用U盘文件系统库需要开启下面定义, 不使用请关闭 */
#define DISK_BASE_BUF_LEN 512 /* 默认的磁盘数据缓冲区大小为512字节,建议选择为2048甚至4096以支持某些大扇区的U盘,为0则禁止在.H文件中定义缓冲区并由应用程序在pDISK_BASE_BUF中指定 */
#endif
// 各子程序返回状态码
#define ERR_SUCCESS 0x00 // 操作成功
#define ERR_USB_CONNECT 0x15 /* 检测到USB设备连接事件,已经连接 */
#define ERR_USB_DISCON 0x16 /* 检测到USB设备断开事件,已经断开 */
#define ERR_USB_BUF_OVER 0x17 /* USB传输的数据有误或者数据太多缓冲区溢出 */
#define ERR_USB_DISK_ERR 0x1F /* USB存储器操作失败,在初始化时可能是USB存储器不支持,在读写操作中可能是磁盘损坏或者已经断开 */
#define ERR_USB_TRANSFER 0x20 /* NAK/STALL等更多错误码在0x20~0x2F */
#define ERR_USB_UNSUPPORT 0xFB /* 不支持的USB设备*/
#define ERR_USB_UNKNOWN 0xFE /* 设备操作出错*/
#define ERR_AOA_PROTOCOL 0x41 /* 协议版本出错 */
/*USB设备相关信息表,最多支持1个设备*/
#define ROOT_DEV_DISCONNECT 0
#define ROOT_DEV_CONNECTED 1
#define ROOT_DEV_FAILED 2
#define ROOT_DEV_SUCCESS 3
#define DEV_TYPE_KEYBOARD (USB_DEV_CLASS_HID | 0x20)
#define DEV_TYPE_MOUSE (USB_DEV_CLASS_HID | 0x30)
#define DEF_AOA_DEVICE 0xF0
#define DEV_TYPE_UNKNOW 0xFF
/*
: USB设备地址分配规则(USB_DEVICE_ADDR)
0x02 Root-HUB下的USB设备或外部HUB
0x1x Root-HUB下的外部HUB的端口x下的USB设备,x为1~n
*/
#define HUB_MAX_PORTS 4
#define WAIT_USB_TOUT_200US 800 // 等待USB中断超时时间
typedef struct
{
uint8_t DeviceStatus; // 设备状态,0-无设备,1-有设备但尚未初始化,2-有设备但初始化枚举失败,3-有设备且初始化枚举成功
uint8_t DeviceAddress; // 设备被分配的USB地址
uint8_t DeviceSpeed; // 0为低速,非0为全速
uint8_t DeviceType; // 设备类型
uint16_t DeviceVID;
uint16_t DevicePID;
uint8_t GpVar[4]; // 通用变量,存放端点
uint8_t GpHUBPortNum; // 通用变量,如果是HUB表示HUB端口数
} _RootHubDev;
typedef struct
{
UINT8 DeviceStatus; // 设备状态,0-无设备,1-有设备但尚未初始化,2-有设备但初始化枚举失败,3-有设备且初始化枚举成功
UINT8 DeviceAddress; // 设备被分配的USB地址
UINT8 DeviceSpeed; // 0为低速,非0为全速
UINT8 DeviceType; // 设备类型
UINT16 DeviceVID;
UINT16 DevicePID;
UINT8 GpVar[4]; // 通用变量
} _DevOnHubPort; // 假定:不超过1个外部HUB,每个外部HUB不超过HUB_MAX_PORTS个端口(多了不管)
extern _RootHubDev ThisUsbDev;
extern _DevOnHubPort DevOnHubPort[HUB_MAX_PORTS]; // 假定:不超过1个外部HUB,每个外部HUB不超过HUB_MAX_PORTS个端口(多了不管)
extern uint8_t UsbDevEndp0Size; // USB设备的端点0的最大包尺寸 */
extern uint8_t FoundNewDev;
extern uint8_t *pHOST_RX_RAM_Addr;
extern uint8_t *pHOST_TX_RAM_Addr;
extern _RootHubDev ThisUsb2Dev;
extern _DevOnHubPort DevOnU2HubPort[HUB_MAX_PORTS]; // 假定:不超过1个外部HUB,每个外部HUB不超过HUB_MAX_PORTS个端口(多了不管)
extern uint8_t Usb2DevEndp0Size; // USB设备的端点0的最大包尺寸 */
extern uint8_t FoundNewU2Dev;
extern uint8_t *pU2HOST_RX_RAM_Addr;
extern uint8_t *pU2HOST_TX_RAM_Addr;
#define pSetupReq ((PUSB_SETUP_REQ)pHOST_TX_RAM_Addr)
#define pU2SetupReq ((PUSB_SETUP_REQ)pU2HOST_TX_RAM_Addr)
extern uint8_t Com_Buffer[];
extern uint8_t U2Com_Buffer[];
/* 以下为USB主机请求包 */
extern const uint8_t SetupGetDevDescr[]; // 获取设备描述符*/
extern const uint8_t SetupGetCfgDescr[]; // 获取配置描述符*/
extern const uint8_t SetupSetUsbAddr[]; // 设置USB地址*/
extern const uint8_t SetupSetUsbConfig[]; // 设置USB配置*/
extern const uint8_t SetupSetUsbInterface[]; // 设置USB接口配置*/
extern const uint8_t SetupClrEndpStall[]; // 清除端点STALL*/
extern const uint8_t SetupGetU2DevDescr[]; // 获取设备描述符*/
extern const uint8_t SetupGetU2CfgDescr[]; // 获取配置描述符*/
extern const uint8_t SetupSetUsb2Addr[]; // 设置USB地址*/
extern const uint8_t SetupSetUsb2Config[]; // 设置USB配置*/
extern const uint8_t SetupSetUsb2Interface[]; // 设置USB接口配置*/
extern const uint8_t SetupClrU2EndpStall[]; // 清除端点STALL*/
/**
* @brief ROOT-HUB端口,,
*/
void DisableRootHubPort(void);
/**
* @brief ROOT-HUB状态,ROOT-HUB端口的设备插拔事件
* ,DisableRootHubPort(),,,
*
* @return ERR_SUCCESS为没有情况,ERR_USB_CONNECT为检测到新连接,ERR_USB_DISCON为检测到断开
*/
uint8_t AnalyzeRootHub(void);
/**
* @brief USB主机当前操作的USB设备地址
*
* @param addr - USB设备地址
*/
void SetHostUsbAddr(uint8_t addr);
/**
* @brief USB速度
*
* @param FullSpeed - USB速度
*/
void SetUsbSpeed(uint8_t FullSpeed);
/**
* @brief ,线,,
*/
void ResetRootHubPort(void);
/**
* @brief 使ROOT-HUB端口,bUH_PORT_EN置1开启端口,
*
* @return ERR_SUCCESS为检测到新连接,ERR_USB_DISCON为无连接
*/
uint8_t EnableRootHubPort(void);
/**
* @brief USB中断
*
* @return ERR_SUCCESS ,ERR_USB_UNKNOWN
*/
uint8_t WaitUSB_Interrupt(void);
/**
* @brief ,/PID令牌,,20uS为单位的NAK重试总时间(0,0xFFFF),0,/
* ,,,
*
* @param endp_pid - , 4token_pid令牌, 4
* @param tog -
* @param timeout -
*
* @return ERR_USB_UNKNOWN
* ERR_USB_DISCON
* ERR_USB_CONNECT
* ERR_SUCCESS
*/
uint8_t USBHostTransact(uint8_t endp_pid, uint8_t tog, uint32_t timeout);
/**
* @brief ,8pSetupReq中,DataBuf为可选的收发缓冲区
*
* @param DataBuf - ,DataBuf需指向有效缓冲区用于存放后续数据
* @param RetLen - RetLen指向的字节变量中
*
* @return ERR_USB_BUF_OVER IN状态阶段出错
* ERR_SUCCESS
*/
uint8_t HostCtrlTransfer(uint8_t *DataBuf, uint8_t *RetLen);
/**
* @brief
*
* @param pReqPkt -
*/
void CopySetupReqPkg(const uint8_t *pReqPkt);
/**
* @brief , pHOST_TX_RAM_Addr
*
* @return ERR_USB_BUF_OVER
* ERR_SUCCESS
*/
uint8_t CtrlGetDeviceDescr(void);
/**
* @brief , pHOST_TX_RAM_Addr
*
* @return ERR_USB_BUF_OVER
* ERR_SUCCESS
*/
uint8_t CtrlGetConfigDescr(void);
/**
* @brief USB设备地址
*
* @param addr -
*
* @return ERR_SUCCESS
*/
uint8_t CtrlSetUsbAddress(uint8_t addr);
/**
* @brief USB设备配置
*
* @param cfg -
*
* @return ERR_SUCCESS
*/
uint8_t CtrlSetUsbConfig(uint8_t cfg);
/**
* @brief STALL
*
* @param endp -
*
* @return ERR_SUCCESS
*/
uint8_t CtrlClearEndpStall(uint8_t endp);
/**
* @brief USB设备接口
*
* @param cfg -
*
* @return ERR_SUCCESS
*/
uint8_t CtrlSetUsbIntercace(uint8_t cfg);
/**
* @brief USB主机功能初始化
*/
void USB_HostInit(void);
uint8_t EnumAllHubPort(void);// 枚举所有ROOT-HUB端口下外部HUB后的二级USB设备
void SelectHubPort(uint8_t HubPortIndex); // HubPortIndex=0选择操作指定的ROOT-HUB端口,否则选择操作指定的ROOT-HUB端口的外部HUB的指定端口
uint16_t SearchTypeDevice(uint8_t type); // 在ROOT-HUB以及外部HUB各端口上搜索指定类型的设备所在的端口号,输出端口号为0xFFFF则未搜索到.
uint8_t SETorOFFNumLock(uint8_t *buf); // NumLock的点灯判断
/*************************************************************/
/**
* @brief ROOT-HUB端口的USB设备
*
* @return
*/
uint8_t InitRootDevice(void);
/**
* @brief HID设备报表描述符,TxBuffer中
*
* @return
*/
uint8_t CtrlGetHIDDeviceReport(uint8_t infc);
/**
* @brief HUB描述符,Com_Buffer中
*
* @return
*/
uint8_t CtrlGetHubDescr(void);
/**
* @brief HUB端口状态,Com_Buffer中
*
* @param HubPortIndex -
*
* @return
*/
uint8_t HubGetPortStatus(uint8_t HubPortIndex);
/**
* @brief HUB端口特性
*
* @param HubPortIndex -
* @param FeatureSelt -
*
* @return
*/
uint8_t HubSetPortFeature(uint8_t HubPortIndex, uint8_t FeatureSelt);
/**
* @brief HUB端口特性
*
* @param HubPortIndex -
* @param FeatureSelt -
*
* @return
*/
uint8_t HubClearPortFeature(uint8_t HubPortIndex, uint8_t FeatureSelt);
#ifdef __cplusplus
}
#endif
#endif // __CH59x_USBHOST_H__

View File

@ -0,0 +1,190 @@
/* CH592 Flash-ROM & Data-Flash */
/* Website: http://wch.cn */
/* Email: tech@wch.cn */
/* Author: W.ch 2020.06 */
/* V1.0 FlashROM library for USER/BOOT */
/* for the target in USER code area on the chip divided into USER code area and BOOT area */
/* 用于具有用户代码区和引导区的芯片、操作目标为用户代码区的情况,
IAP */
/* Flash-ROM feature:
for store program code, support block erasing, dword and page writing, dword verifying, unit for Length is byte,
minimal quantity for write or verify is one dword (4-bytes),
256 bytes/page for writing, FLASH_ROM_WRITE support one dword or more dword writing, but multiple of 256 is the best,
4KB (4096 bytes) bytes/block for erasing, so multiple of 4096 is the best */
/* Data-Flash(EEPROM) feature:
for store data, support block erasing, byte and page writing, byte reading,
minimal quantity for write or read is one byte,
256 bytes/page for writing, EEPROM_WRITE support one byte or more byte writing, but multiple of 256 is the best,
0.25KB/4KB (256/4096 bytes) bytes/block for erasing, so multiple of 256 or 4096 is the best */
#ifndef EEPROM_PAGE_SIZE
#define EEPROM_PAGE_SIZE 256 // Flash-ROM & Data-Flash page size for writing
#define EEPROM_BLOCK_SIZE 4096 // Flash-ROM & Data-Flash block size for erasing
#define EEPROM_MIN_ER_SIZE EEPROM_PAGE_SIZE // Data-Flash minimal size for erasing
//#define EEPROM_MIN_ER_SIZE EEPROM_BLOCK_SIZE // Flash-ROM minimal size for erasing
#define EEPROM_MIN_WR_SIZE 1 // Data-Flash minimal size for writing
#define EEPROM_MAX_SIZE 0x8000 // Data-Flash maximum size, 32KB
#endif
#ifndef FLASH_MIN_WR_SIZE
#define FLASH_MIN_WR_SIZE 4 // Flash-ROM minimal size for writing
#endif
#ifndef FLASH_ROM_MAX_SIZE
#define FLASH_ROM_MAX_SIZE 0x070000 // Flash-ROM maximum program size, 448KB
#endif
#ifndef CMD_FLASH_ROM_SW_RESET
// CMD_* for caller from FlashROM or RAM, auto execute CMD_FLASH_ROM_SW_RESET before command
#define CMD_FLASH_ROM_START_IO 0x00 // start FlashROM I/O, without parameter
#define CMD_FLASH_ROM_SW_RESET 0x04 // software reset FlashROM, without parameter
#define CMD_GET_ROM_INFO 0x06 // get information from FlashROM, parameter @Address,Buffer
#define CMD_GET_UNIQUE_ID 0x07 // get 64 bit unique ID, parameter @Buffer
#define CMD_FLASH_ROM_PWR_DOWN 0x0D // power-down FlashROM, without parameter
#define CMD_FLASH_ROM_PWR_UP 0x0C // power-up FlashROM, without parameter
#define CMD_FLASH_ROM_LOCK 0x08 // lock(protect)/unlock FlashROM data block, return 0 if success, parameter @StartAddr
// StartAddr: 0=unlock all, 1=lock boot code, 3=lock all code and data
#define CMD_EEPROM_ERASE 0x09 // erase Data-Flash block, return 0 if success, parameter @StartAddr,Length
#define CMD_EEPROM_WRITE 0x0A // write Data-Flash data block, return 0 if success, parameter @StartAddr,Buffer,Length
#define CMD_EEPROM_READ 0x0B // read Data-Flash data block, parameter @StartAddr,Buffer,Length
#define CMD_FLASH_ROM_ERASE 0x01 // erase FlashROM block, return 0 if success, parameter @StartAddr,Length
#define CMD_FLASH_ROM_WRITE 0x02 // write FlashROM data block, minimal block is dword, return 0 if success, parameter @StartAddr,Buffer,Length
#define CMD_FLASH_ROM_VERIFY 0x03 // read FlashROM data block, minimal block is dword, return 0 if success, parameter @StartAddr,Buffer,Length
#endif
#define ROM_CFG_MAC_ADDR 0x7F018 // address for MAC address information
#define ROM_CFG_BOOT_INFO 0x7DFF8 // address for BOOT information
/**
* @brief execute Flash/EEPROM command, caller from FlashROM or RAM
*
* @param cmd - CMD_* for caller from FlashROM or RAM.
* @param StartAddr - Address of the data to be process.
* @param Buffer - Pointer to the buffer where data should be process, Must be aligned to 4 bytes.
* @param Length - Size of data to be process, in bytes.
*
* @return 0-SUCCESS (!0)-FAILURE
*/
extern uint32_t FLASH_EEPROM_CMD( uint8_t cmd, uint32_t StartAddr, void *Buffer, uint32_t Length );
/**
* @brief start FlashROM I/O
*
* @return 0-SUCCESS (!0)-FAILURE
*/
#define FLASH_ROM_START_IO( ) FLASH_EEPROM_CMD( CMD_FLASH_ROM_START_IO, 0, NULL, 0 )
/**
* @brief software reset FlashROM
*
* @return 0-SUCCESS (!0)-FAILURE
*/
#define FLASH_ROM_SW_RESET( ) FLASH_EEPROM_CMD( CMD_FLASH_ROM_SW_RESET, 0, NULL, 0 )
/**
* @brief get 6 bytes MAC address
*
* @param Buffer - Pointer to the buffer where data should be stored, Must be aligned to 4 bytes.
*
* @return 0-SUCCESS (!0)-FAILURE
*/
#define GetMACAddress(Buffer) FLASH_EEPROM_CMD( CMD_GET_ROM_INFO, ROM_CFG_MAC_ADDR, Buffer, 0 )
/**
* @brief get 8 bytes BOOT information
*
* @param Buffer - Pointer to the buffer where data should be stored, Must be aligned to 4 bytes.
*
* @return 0-SUCCESS (!0)-FAILURE
*/
#define GET_BOOT_INFO(Buffer) FLASH_EEPROM_CMD( CMD_GET_ROM_INFO, ROM_CFG_BOOT_INFO, Buffer, 0 )
/**
* @brief get 64 bit unique ID
*
* @param Buffer - Pointer to the buffer where data should be stored, Must be aligned to 4 bytes.
*
* @return 0-SUCCESS (!0)-FAILURE
*/
#define GET_UNIQUE_ID(Buffer) FLASH_EEPROM_CMD( CMD_GET_UNIQUE_ID, 0, Buffer, 0 )
/**
* @brief power-down FlashROM
*
* @return 0-SUCCESS (!0)-FAILURE
*/
#define FLASH_ROM_PWR_DOWN( ) FLASH_EEPROM_CMD( CMD_FLASH_ROM_PWR_DOWN, 0, NULL, 0 )
/**
* @brief power-up FlashROM
*
* @return 0-SUCCESS (!0)-FAILURE
*/
#define FLASH_ROM_PWR_UP( ) FLASH_EEPROM_CMD( CMD_FLASH_ROM_PWR_UP, 0, NULL, 0 )
/**
* @brief read Data-Flash data block
*
* @param StartAddr - Address of the data to be read.
* @param Buffer - Pointer to the buffer where data should be stored, Must be aligned to 4 bytes.
* @param Length - Size of data to be read, in bytes.
*
* @return 0-SUCCESS (!0)-FAILURE
*/
#define EEPROM_READ(StartAddr,Buffer,Length) FLASH_EEPROM_CMD( CMD_EEPROM_READ, StartAddr, Buffer, Length )
/**
*
* @param StartAddr - Address of the data to be erased.
* @param Length - Size of data to be erased, in bytes.
*
* @return 0-SUCCESS (!0)-FAILURE
*/
#define EEPROM_ERASE(StartAddr,Length) FLASH_EEPROM_CMD( CMD_EEPROM_ERASE, StartAddr, NULL, Length )
/**
* @brief write Data-Flash data block
*
* @param StartAddr - Address of the data to be written.
* @param Buffer - Pointer to the source buffer, Must be aligned to 4 bytes.
* @param Length - Size of data to be written, in bytes.
*
* @return 0-SUCCESS (!0)-FAILURE
*/
#define EEPROM_WRITE(StartAddr,Buffer,Length) FLASH_EEPROM_CMD( CMD_EEPROM_WRITE, StartAddr, Buffer, Length )
/**
* @brief erase FlashROM block
*
* @param StartAddr - Address of the data to be erased.
* @param Length - Size of data to be erased, in bytes.
*
* @return 0-SUCCESS (!0)-FAILURE
*/
#define FLASH_ROM_ERASE(StartAddr,Length) FLASH_EEPROM_CMD( CMD_FLASH_ROM_ERASE, StartAddr, NULL, Length )
/**
* @brief write FlashROM data block, minimal block is dword.
*
* @param StartAddr - Address of the data to be written.
* @param Buffer - Pointer to the source buffer, Must be aligned to 4 bytes.
* @param Length - Size of data to be written, in bytes.
*
* @return 0-SUCCESS (!0)-FAILURE
*/
#define FLASH_ROM_WRITE(StartAddr,Buffer,Length) FLASH_EEPROM_CMD( CMD_FLASH_ROM_WRITE, StartAddr, Buffer, Length )
/**
* @brief verify FlashROM data block, minimal block is dword.
*
* @param StartAddr - Address of the data to verify.
* @param Buffer - Pointer to the source buffer, Must be aligned to 4 bytes.
* @param Length - Size of data to verify, in bytes.
*
* @return 0-SUCCESS (!0)-FAILURE
*/
#define FLASH_ROM_VERIFY(StartAddr,Buffer,Length) FLASH_EEPROM_CMD( CMD_FLASH_ROM_VERIFY, StartAddr, Buffer, Length )

Binary file not shown.

7
src/.clangd Normal file
View File

@ -0,0 +1,7 @@
#this file exist for clangd to propperly see all libraries
CompileFlags:
Add:
- "-I../sdk/StdPeriphDriver/inc/"
- "-I../sdk/RVMSIS/"
- "-I../sdk/BLE/HAL/include/"
- "-I../sdk/BLE/LIB/"

11
src/main.c Normal file
View File

@ -0,0 +1,11 @@
#include "CH59x_common.h"
int main(void){
//basic internal led blink example
SetSysClock(CLK_SOURCE_PLL_60MHz);
GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeOut_PP_20mA);
while (1) {
GPIOA_InverseBits(GPIO_Pin_8);
DelayMs(1000);
}
}