From 7f7cfd229f645e084630e6e196c536d368124c29 Mon Sep 17 00:00:00 2001 From: Lars Beemster Date: Mon, 24 Feb 2025 14:43:19 +0100 Subject: [PATCH 1/6] CH59x bringup and blinky --- ch32fun/ch32fun.c | 170 +++++++++++++++- ch32fun/ch32fun.h | 18 +- ch32fun/ch32fun.ld | 17 +- ch32fun/ch32fun.mk | 21 ++ ch32fun/ch59xhw.h | 328 +++++++++++++++++++++++++++++++ examples_ch59x/blink/Makefile | 10 + examples_ch59x/blink/blink.c | 17 ++ examples_ch59x/blink/funconfig.h | 11 ++ 8 files changed, 583 insertions(+), 9 deletions(-) create mode 100644 ch32fun/ch59xhw.h create mode 100644 examples_ch59x/blink/Makefile create mode 100644 examples_ch59x/blink/blink.c create mode 100644 examples_ch59x/blink/funconfig.h diff --git a/ch32fun/ch32fun.c b/ch32fun/ch32fun.c index b6280864..dd295637 100644 --- a/ch32fun/ch32fun.c +++ b/ch32fun/ch32fun.c @@ -966,6 +966,24 @@ void USBPD_WKUP_IRQHandler( void ) __attribute__((section(".text.vector_handler void TIM2_CC_IRQHandler( void ) __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used)); void TIM2_TRG_IRQHandler( void ) __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used)); void TIM2_BRK_IRQHandler( void ) __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used)); +// CH59x +void TMR0_IRQHandler( void ) __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used)); +void GPIOA_IRQHandler( void ) __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used)); +void GPIOB_IRQHandler( void ) __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used)); +void SPI0_IRQHandler( void ) __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used)); +void USB_IRQHandler( void ) __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used)); +void TMR1_IRQHandler( void ) __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used)); +void TMR2_IRQHandler( void ) __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used)); +void UART0_IRQHandler( void ) __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used)); +void UART1_IRQHandler( void ) __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used)); +void ADC_IRQHandler( void ) __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used)); +void I2C_IRQHandler( void ) __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used)); +void PWMX_IRQHandler( void ) __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used)); +void TMR3_IRQHandler( void ) __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used)); +void UART2_IRQHandler( void ) __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used)); +void UART3_IRQHandler( void ) __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used)); +void WDOG_BAT_IRQHandler( void ) __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used)); + void InterruptVector() __attribute__((naked)) __attribute((section(".init"))) __attribute((weak,alias("InterruptVectorDefault"))) __attribute((naked)); @@ -1060,7 +1078,7 @@ asm volatile( " mret\n" : : [main]"r"(main) ); } -#elif defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x) +#elif defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x) || defined(CH59x) void handle_reset( void ) { @@ -1472,7 +1490,7 @@ void DelaySysTick( uint32_t n ) #ifdef CH32V003 uint32_t targend = SysTick->CNT + n; while( ((int32_t)( SysTick->CNT - targend )) < 0 ); -#elif defined(CH32V20x) || defined(CH32V30x) +#elif defined(CH32V20x) || defined(CH32V30x) || defined(CH59x) uint64_t targend = SysTick->CNT + n; while( ((int64_t)( SysTick->CNT - targend )) < 0 ); #elif defined(CH32V10x) || defined(CH32X03x) @@ -1483,6 +1501,144 @@ void DelaySysTick( uint32_t n ) #endif } +#if defined(CH59x) +/** + * @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. + */ +vu32 IRQ_STA = 0; +__attribute__( ( always_inline ) ) RV_STATIC_INLINE void sys_safe_access_enable(void) +{ + if(read_csr(0x800) & 0x08) + { + IRQ_STA = read_csr(0x800); + write_csr(0x800, (IRQ_STA&(~0x08))); + } + ADD_N_NOPS(2); + R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1; + R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2; + ADD_N_NOPS(2); +} + +__attribute__( ( always_inline ) ) RV_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; + ADD_N_NOPS(2); +} + +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; + ADD_N_NOPS(4); + sys_safe_access_disable(); + sys_safe_access_enable(); + ADD_N_NOPS(2); + 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; + ADD_N_NOPS(4); + 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(); + } + sys_safe_access_enable(); + R8_PLL_CONFIG |= 1 << 7; + sys_safe_access_disable(); +} +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; + } +} + +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; + } +} +#endif + void SystemInit( void ) { #if defined(CH32V30x) && defined(TARGET_MCU_MEMORY_SPLIT) @@ -1541,7 +1697,9 @@ void SystemInit( void ) #endif #endif -#if defined(FUNCONF_USE_HSI) && FUNCONF_USE_HSI +#if defined(CH59x) + SetSysClock(CLK_SOURCE_PLL_60MHz); +#elif defined(FUNCONF_USE_HSI) && FUNCONF_USE_HSI #if defined(CH32V30x) || defined(CH32V20x) || defined(CH32V10x) EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; #endif @@ -1600,9 +1758,11 @@ void SystemInit( void ) #endif #endif +#if !defined(CH59x) RCC->INTR = 0x009F0000; // Clear PLL, CSSC, HSE, HSI and LSI ready flags. +#endif -#if defined(FUNCONF_USE_PLL) && FUNCONF_USE_PLL +#if defined(FUNCONF_USE_PLL) && FUNCONF_USE_PLL && !defined(CH59x) while((RCC->CTLR & RCC_PLLRDY) == 0); // Wait till PLL is ready uint32_t tmp32 = RCC->CFGR0 & ~(0x03); // clr the SW RCC->CFGR0 = tmp32 | RCC_SW_PLL; // Select PLL as system clock source @@ -1617,6 +1777,7 @@ void SystemInit( void ) #endif } +#if defined(FUNCONF_INIT_ANALOG) && FUNCONF_INIT_ANALOG void funAnalogInit( void ) { //RCC->CFGR0 &= ~(0x1F<<11); // Assume ADCPRE = 0 @@ -1655,6 +1816,7 @@ int funAnalogRead( int nAnalogNumber ) // get result return ADC1->RDATAR; } +#endif // C++ Support diff --git a/ch32fun/ch32fun.h b/ch32fun/ch32fun.h index 3dc94095..6ba8abf6 100644 --- a/ch32fun/ch32fun.h +++ b/ch32fun/ch32fun.h @@ -128,6 +128,10 @@ #define FUNCONF_DEBUG_HARDFAULT 1 #endif +#if !defined( FUNCONF_INIT_ANALOG ) + #define FUNCONF_INIT_ANALOG 1 +#endif + #if defined( CH32X03x ) && FUNCONF_USE_PLL #error No PLL on the X03x #endif @@ -160,6 +164,8 @@ #endif #elif defined(CH32V30x) #define HSE_VALUE (8000000) + #elif defined(CH59x) + #define HSE_VALUE (32000000) #endif #endif @@ -348,6 +354,8 @@ typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus; #include "ch32v20xhw.h" #elif defined( CH32V30x ) #include "ch32v30xhw.h" +#elif defined( CH59x ) + #include "ch59xhw.h" #endif #if defined(__riscv) || defined(__riscv__) || defined( CH32V003FUN_BASE ) @@ -817,11 +825,16 @@ extern "C" { // and take two cycles, so you typically would use 0, 2, 4, etc. #define ADD_N_NOPS( n ) asm volatile( ".rept " #n "\nc.nop\n.endr" ); +#define FUN_HIGH 0x1 +#define FUN_LOW 0x0 +#if defined(CH59x) +#define funDigitalWrite( pin, value ) { if(value==FUN_HIGH){GPIOA_SetBits(pin);} else if(value==FUN_LOW){GPIOA_ResetBits(pin);} } +void GPIOA_ModeCfg(uint32_t pin, GPIOModeTypeDef mode); +#define funPinMode( pin, mode ) GPIOA_ModeCfg(pin, mode) +#else // Arduino-like GPIO Functionality #define GpioOf( pin ) ((GPIO_TypeDef *)(GPIOA_BASE + 0x400 * ((pin)>>4))) -#define FUN_HIGH 0x1 -#define FUN_LOW 0x0 #define FUN_OUTPUT (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP) #define FUN_INPUT (GPIO_CNF_IN_FLOATING) @@ -846,6 +859,7 @@ extern "C" { #define funGpioInitC() { RCC->APB2PCENR |= ( RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOC ); } #define funGpioInitD() { RCC->APB2PCENR |= ( RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOD ); } #define funDigitalRead( pin ) ((int)((GpioOf(pin)->INDR >> ((pin)&0xf)) & 1)) +#endif #define ANALOG_0 0 diff --git a/ch32fun/ch32fun.ld b/ch32fun/ch32fun.ld index 029a018a..991b0332 100644 --- a/ch32fun/ch32fun.ld +++ b/ch32fun/ch32fun.ld @@ -65,9 +65,20 @@ MEMORY FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 32K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 6K #elif TARGET_MCU_LD == 7 - /* CH32V005, CH32V006, CH32V007 */ - FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 62K - RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 8K + /* CH32V005, CH32V006, CH32V007 */ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 62K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 8K +#elif TARGET_MCU_LD == 8 + /* CH591/2 */ + #if MCU_PACKAGE == 1 + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 192K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 24K + #elif MCU_PACKAGE == 2 + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 448K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 24K + #else + #error "Unknown MCU package" + #endif #else #error "Unknown MCU target" #endif diff --git a/ch32fun/ch32fun.mk b/ch32fun/ch32fun.mk index eb76e650..51e80158 100644 --- a/ch32fun/ch32fun.mk +++ b/ch32fun/ch32fun.mk @@ -183,6 +183,27 @@ else endif TARGET_MCU_LD:=3 + else ifeq ($(findstring CH59,$(TARGET_MCU)),CH59) # CH592 1 + TARGET_MCU_PACKAGE?=CH592F + CFLAGS_ARCH+=-march=rv32imac_zicsr \ + -mabi=ilp32 \ + -DCH59x=1 + + # MCU Flash/RAM split + ifeq ($(findstring 591, $(TARGET_MCU_PACKAGE)), 591) + MCU_PACKAGE:=1 + else ifeq ($(findstring 592, $(TARGET_MCU_PACKAGE)), 592) + MCU_PACKAGE:=2 + endif + + # Package + ifeq ($(findstring D, $(TARGET_MCU_PACKAGE)), D) + CFLAGS+=-DCH59xD + else ifeq ($(findstring F, $(TARGET_MCU_PACKAGE)), F) + CFLAGS+=-DCH59xF + endif + + TARGET_MCU_LD:=8 else ERROR:=$(error Unknown MCU $(TARGET_MCU)) endif diff --git a/ch32fun/ch59xhw.h b/ch32fun/ch59xhw.h new file mode 100644 index 00000000..eb8d9b01 --- /dev/null +++ b/ch32fun/ch59xhw.h @@ -0,0 +1,328 @@ +#ifndef TODO_HARDWARE_H +#define TODO_HARDWARE_H + +#include "ch32fun.h" + +#ifndef __ASSEMBLER__ // Things before this can be used in assembly. + +#ifdef __cplusplus +extern "C" { +#endif + +/* Interrupt Number Definition, according to the selected device */ +typedef enum IRQn +{ + /****** RISC-V Processor Exceptions Numbers *******************************************************/ + NonMaskableInt_IRQn = 2, /* 2 Non Maskable Interrupt */ + EXC_IRQn = 3, /* 3 Exception Interrupt */ + Ecall_M_Mode_IRQn = 5, /* 5 Ecall M Mode Interrupt */ + Ecall_U_Mode_IRQn = 8, /* 8 Ecall U Mode Interrupt */ + Break_Point_IRQn = 9, /* 9 Break Point Interrupt */ + SysTicK_IRQn = 12, /* 12 System timer Interrupt */ + Software_IRQn = 14, /* 14 software Interrupt */ + + /****** RISC-V specific Interrupt Numbers *********************************************************/ + TMR0_IRQn = 16, /* 0: TMR0 */ + GPIOA_IRQn = 17, /* GPIOA */ + GPIOB_IRQn = 18, /* GPIOB */ + SPI0_IRQn = 19, /* SPI0 */ + BB_IRQn = 20, /* BLEB */ + LLE_IRQn = 21, /* BLEL */ + USB_IRQn = 22, /* USB */ + TMR1_IRQn = 24, /* TMR1 */ + TMR2_IRQn = 25, /* TMR2 */ + UART0_IRQn = 26, /* UART0 */ + UART1_IRQn = 27, /* UART1 */ + RTC_IRQn = 28, /* RTC */ + ADC_IRQn = 29, /* ADC */ + I2C_IRQn = 30, /* I2C */ + PWMX_IRQn = 31, /* PWMX */ + TMR3_IRQn = 32, /* TMR3 */ + UART2_IRQn = 33, /* UART2 */ + UART3_IRQn = 34, /* UART3 */ + WDOG_BAT_IRQn = 35, /* WDOG_BAT */ +} IRQn_Type; + +#define BASE_VECTOR "\n\ + .balign 2\n\ + .option push;\n\ + .option norvc;\n\ + j handle_reset\n\ + .word 0\n\ + .word NMI_Handler /* NMI Handler */\n\ + .word HardFault_Handler /* Hard Fault Handler */\n\ + .word 0xF5F9BDA9\n\ + .word Ecall_M_Mode_Handler /* 5 */\n\ + .word 0\n\ + .word 0\n\ + .word Ecall_U_Mode_Handler /* 8 */\n\ + .word Break_Point_Handler /* 9 */\n\ + .word 0\n\ + .word 0\n\ + .word SysTick_Handler /* SysTick Handler */\n\ + .word 0\n\ + .word SW_Handler /* SW Handler */\n\ + .word 0\n\ + /* External Interrupts */\n\ + .word TMR0_IRQHandler /* 0: TMR0 */\n\ + .word GPIOA_IRQHandler /* GPIOA */\n\ + .word GPIOB_IRQHandler /* GPIOB */\n\ + .word SPI0_IRQHandler /* SPI0 */\n\ + .word BB_IRQHandler /* BLEB */\n\ + .word LLE_IRQHandler /* BLEL */\n\ + .word USB_IRQHandler /* USB */\n\ + .word 0\n\ + .word TMR1_IRQHandler /* TMR1 */\n\ + .word TMR2_IRQHandler /* TMR2 */\n\ + .word UART0_IRQHandler /* UART0 */\n\ + .word UART1_IRQHandler /* UART1 */\n\ + .word RTC_IRQHandler /* RTC */\n\ + .word ADC_IRQHandler /* ADC */\n\ + .word I2C_IRQHandler /* I2C */\n\ + .word PWMX_IRQHandler /* PWMX */\n\ + .word TMR3_IRQHandler /* TMR3 */\n\ + .word UART2_IRQHandler /* UART2 */\n\ + .word UART3_IRQHandler /* UART3 */\n\ + .word WDOG_BAT_IRQHandler /* WDOG_BAT */\n" + +#define DEFAULT_INTERRUPT_VECTOR_CONTENTS BASE_VECTOR "\n.option pop;\n" + +/* 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; + + +/* 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; +#endif /* __ASSEMBLER__*/ + +#ifdef __ASSEMBLER__ +#define CORE_PERIPH_BASE (0xE0000000) /* System peripherals base address in the alias region */ +#else +#define CORE_PERIPH_BASE ((uint32_t)(0xE0000000)) +#endif /* __ASSEMBLER__*/ + +#define PFIC_BASE (CORE_PERIPH_BASE + 0xE000) +#define SysTick_BASE (CORE_PERIPH_BASE + 0xF000) + +#define PFIC ((PFIC_Type *) PFIC_BASE) +#define NVIC PFIC +#define NVIC_KEY1 ((uint32_t)0xFA050000) +#define NVIC_KEY2 ((uint32_t)0xBCAF0000) +#define NVIC_KEY3 ((uint32_t)0xBEEF0000) + +#define SysTick ((SysTick_Type *) SysTick_BASE) +#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) + +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; + +/* System: clock configuration register */ +#define R32_CLK_SYS_CFG (*((vu32*)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 + +/* System: safe accessing register */ +#define R32_SAFE_ACCESS (*((vu32*)0x40001040)) // RW, safe accessing +#define R8_SAFE_ACCESS_SIG (*((vu8*)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 (*((vu8*)0x40001041)) // RF, chip ID register, always is ID_CH58* + +/*System: Miscellaneous Control register */ +#define R32_MISC_CTRL (*((vu32*)0x40001048)) // RWA, miscellaneous control register +#define R8_PLL_CONFIG (*((vu8*)0x4000104B)) // RWA, PLL configuration control, SAM +#define RB_PLL_CFG_DAT 0x7F // RWA, PLL configuration control, SAM + +/* System: Flash ROM control register */ +#define R32_FLASH_DATA (*((vu32*)0x40001800)) // RO/WO, flash ROM data +#define R32_FLASH_CONTROL (*((vu32*)0x40001804)) // RW, flash ROM control +#define R8_FLASH_DATA (*((vu8*)0x40001804)) // RO/WO, flash ROM data buffer +#define R8_FLASH_CTRL (*((vu8*)0x40001806)) // RW, flash ROM access control +#define R8_FLASH_CFG (*((vu8*)0x40001807)) // RW, flash ROM access config, SAM + +#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)); \ + }) + + +/* GPIO PA register */ +#define R32_PA_DIR (*((vu32*)0x400010A0)) // RW, GPIO PA I/O direction: 0=in, 1=out +#define R8_PA_DIR_0 (*((vu8*)0x400010A0)) // RW, GPIO PA I/O direction byte 0 +#define R8_PA_DIR_1 (*((vu8*)0x400010A1)) // RW, GPIO PA I/O direction byte 1 +#define R32_PA_PIN (*((vu32*)0x400010A4)) // RO, GPIO PA input +#define R8_PA_PIN_0 (*((vu8*)0x400010A4)) // RO, GPIO PA input byte 0 +#define R8_PA_PIN_1 (*((vu8*)0x400010A5)) // RO, GPIO PA input byte 1 +#define R32_PA_OUT (*((vu32*)0x400010A8)) // RW, GPIO PA output +#define R8_PA_OUT_0 (*((vu8*)0x400010A8)) // RW, GPIO PA output byte 0 +#define R8_PA_OUT_1 (*((vu8*)0x400010A9)) // RW, GPIO PA output byte 1 +#define R32_PA_CLR (*((vu32*)0x400010AC)) // WZ, GPIO PA clear output: 0=keep, 1=clear +#define R8_PA_CLR_0 (*((vu8*)0x400010AC)) // WZ, GPIO PA clear output byte 0 +#define R8_PA_CLR_1 (*((vu8*)0x400010AD)) // WZ, GPIO PA clear output byte 1 +#define R32_PA_PU (*((vu32*)0x400010B0)) // RW, GPIO PA pullup resistance enable +#define R8_PA_PU_0 (*((vu8*)0x400010B0)) // RW, GPIO PA pullup resistance enable byte 0 +#define R8_PA_PU_1 (*((vu8*)0x400010B1)) // RW, GPIO PA pullup resistance enable byte 1 +#define R32_PA_PD_DRV (*((vu32*)0x400010B4)) // RW, PA pulldown for input or PA driving capability for output +#define R8_PA_PD_DRV_0 (*((vu8*)0x400010B4)) // RW, PA pulldown for input or PA driving capability for output byte 0 +#define R8_PA_PD_DRV_1 (*((vu8*)0x400010B5)) // RW, PA pulldown for input or PA driving capability for output byte 1 + +/* GPIO PB register */ +#define R32_PB_DIR (*((vu32*)0x400010C0)) // RW, GPIO PB I/O direction: 0=in, 1=out +#define R8_PB_DIR_0 (*((vu8*)0x400010C0)) // RW, GPIO PB I/O direction byte 0 +#define R8_PB_DIR_1 (*((vu8*)0x400010C1)) // RW, GPIO PB I/O direction byte 1 +#define R8_PB_DIR_2 (*((vu8*)0x400010C2)) // RW, GPIO PB I/O direction byte 2 +#define R32_PB_PIN (*((vu32*)0x400010C4)) // RO, GPIO PB input +#define R8_PB_PIN_0 (*((vu8*)0x400010C4)) // RO, GPIO PB input byte 0 +#define R8_PB_PIN_1 (*((vu8*)0x400010C5)) // RO, GPIO PB input byte 1 +#define R8_PB_PIN_2 (*((vu8*)0x400010C6)) // RO, GPIO PB input byte 2 +#define R32_PB_OUT (*((vu32*)0x400010C8)) // RW, GPIO PB output +#define R8_PB_OUT_0 (*((vu8*)0x400010C8)) // RW, GPIO PB output byte 0 +#define R8_PB_OUT_1 (*((vu8*)0x400010C9)) // RW, GPIO PB output byte 1 +#define R8_PB_OUT_2 (*((vu8*)0x400010CA)) // RW, GPIO PB output byte 2 +#define R32_PB_CLR (*((vu32*)0x400010CC)) // WZ, GPIO PB clear output: 0=keep, 1=clear +#define R8_PB_CLR_0 (*((vu8*)0x400010CC)) // WZ, GPIO PB clear output byte 0 +#define R8_PB_CLR_1 (*((vu8*)0x400010CD)) // WZ, GPIO PB clear output byte 1 +#define R8_PB_CLR_2 (*((vu8*)0x400010CE)) // WZ, GPIO PB clear output byte 2 +#define R32_PB_PU (*((vu32*)0x400010D0)) // RW, GPIO PB pullup resistance enable +#define R8_PB_PU_0 (*((vu8*)0x400010D0)) // RW, GPIO PB pullup resistance enable byte 0 +#define R8_PB_PU_1 (*((vu8*)0x400010D1)) // RW, GPIO PB pullup resistance enable byte 1 +#define R8_PB_PU_2 (*((vu8*)0x400010D2)) // RW, GPIO PB pullup resistance enable byte 2 +#define R32_PB_PD_DRV (*((vu32*)0x400010D4)) // RW, PB pulldown for input or PB driving capability for output +#define R8_PB_PD_DRV_0 (*((vu8*)0x400010D4)) // RW, PB pulldown for input or PB driving capability for output byte 0 +#define R8_PB_PD_DRV_1 (*((vu8*)0x400010D5)) // RW, PB pulldown for input or PB driving capability for output byte 1 +#define R8_PB_PD_DRV_2 (*((vu8*)0x400010D6)) // RW, PB pulldown for input or PB driving capability for output byte 2 + +#define PA0 (0x00000001) /*!< Pin 0 selected */ +#define PA1 (0x00000002) /*!< Pin 1 selected */ +#define PA2 (0x00000004) /*!< Pin 2 selected */ +#define PA3 (0x00000008) /*!< Pin 3 selected */ +#define PA4 (0x00000010) /*!< Pin 4 selected */ +#define PA5 (0x00000020) /*!< Pin 5 selected */ +#define PA6 (0x00000040) /*!< Pin 6 selected */ +#define PA7 (0x00000080) /*!< Pin 7 selected */ +#define PA8 (0x00000100) /*!< Pin 8 selected */ +#define PA9 (0x00000200) /*!< Pin 9 selected */ +#define PA10 (0x00000400) /*!< Pin 10 selected */ +#define PA11 (0x00000800) /*!< Pin 11 selected */ +#define PA12 (0x00001000) /*!< Pin 12 selected */ +#define PA13 (0x00002000) /*!< Pin 13 selected */ +#define PA14 (0x00004000) /*!< Pin 14 selected */ +#define PA15 (0x00008000) /*!< Pin 15 selected */ + +#define PB0 (0x00000001) /*!< Pin 0 selected */ +#define PB1 (0x00000002) /*!< Pin 1 selected */ +#define PB2 (0x00000004) /*!< Pin 2 selected */ +#define PB3 (0x00000008) /*!< Pin 3 selected */ +#define PB4 (0x00000010) /*!< Pin 4 selected */ +#define PB5 (0x00000020) /*!< Pin 5 selected */ +#define PB6 (0x00000040) /*!< Pin 6 selected */ +#define PB7 (0x00000080) /*!< Pin 7 selected */ +#define PB8 (0x00000100) /*!< Pin 8 selected */ +#define PB9 (0x00000200) /*!< Pin 9 selected */ +#define PB10 (0x00000400) /*!< Pin 10 selected */ +#define PB11 (0x00000800) /*!< Pin 11 selected */ +#define PB12 (0x00001000) /*!< Pin 12 selected */ +#define PB13 (0x00002000) /*!< Pin 13 selected */ +#define PB14 (0x00004000) /*!< Pin 14 selected */ +#define PB15 (0x00008000) /*!< Pin 15 selected */ +#define PB16 (0x00010000) /*!< Pin 16 selected */ +#define PB17 (0x00020000) /*!< Pin 17 selected */ +#define PB18 (0x00040000) /*!< Pin 18 selected */ +#define PB19 (0x00080000) /*!< Pin 19 selected */ +#define PB20 (0x00100000) /*!< Pin 20 selected */ +#define PB21 (0x00200000) /*!< Pin 21 selected */ +#define PB22 (0x00400000) /*!< Pin 22 selected */ +#define PB23 (0x00800000) /*!< Pin 23 selected */ +#define PA_All (0xFFFFFFFF) /*!< All pins selected */ + +typedef enum +{ + GPIO_ModeIN_Floating, + GPIO_ModeIN_PU, + GPIO_ModeIN_PD, + GPIO_ModeOut_PP_5mA, + GPIO_ModeOut_PP_20mA, + +} GPIOModeTypeDef; + +#define GPIOA_ResetBits(pin) (R32_PA_CLR |= pin) +#define GPIOA_SetBits(pin) (R32_PA_OUT |= pin) +#define GPIOA_InverseBits(pin) (R32_PA_OUT ^= pin) +#define GPIOB_ResetBits(pin) (R32_PB_CLR |= pin) +#define GPIOB_SetBits(pin) (R32_PB_OUT |= pin) +#define GPIOB_InverseBits(pin) (R32_PB_OUT ^= pin) + + +#define HardFault_IRQn EXC_IRQn + +/* Standard Peripheral Library old definitions (maintained for legacy purpose) */ +#define HSI_Value HSI_VALUE +#define HSE_Value HSE_VALUE +#define HSEStartUp_TimeOut HSE_STARTUP_TIMEOUT + +#ifdef __cplusplus +} +#endif + +#endif // Header guard diff --git a/examples_ch59x/blink/Makefile b/examples_ch59x/blink/Makefile new file mode 100644 index 00000000..f91e0ef0 --- /dev/null +++ b/examples_ch59x/blink/Makefile @@ -0,0 +1,10 @@ +all : flash + +TARGET:=blink +TARGET_MCU:=CH592 +TARGET_MCU_PACKAGE:=CH592F + +include ../../ch32fun/ch32fun.mk + +flash : cv_flash +clean : cv_clean diff --git a/examples_ch59x/blink/blink.c b/examples_ch59x/blink/blink.c new file mode 100644 index 00000000..25992b82 --- /dev/null +++ b/examples_ch59x/blink/blink.c @@ -0,0 +1,17 @@ +#include "ch32fun.h" +#include + +int main() +{ + SystemInit(); + + funPinMode( PA8, GPIO_ModeOut_PP_5mA ); + + while(1) + { + funDigitalWrite( PA8, FUN_LOW ); // Turn on LED + Delay_Ms( 33 ); + funDigitalWrite( PA8, FUN_HIGH ); // Turn off LED + Delay_Ms( 300 ); + } +} diff --git a/examples_ch59x/blink/funconfig.h b/examples_ch59x/blink/funconfig.h new file mode 100644 index 00000000..584e59c0 --- /dev/null +++ b/examples_ch59x/blink/funconfig.h @@ -0,0 +1,11 @@ +#ifndef _FUNCONFIG_H +#define _FUNCONFIG_H + +#define FUNCONF_USE_HSI 0 // CH592 does not have HSI +#define FUNCONF_USE_HSE 1 +#define FUNCONF_DEBUG_HARDFAULT 0 +#define FUNCONF_USE_CLK_SEC 0 +#define FUNCONF_USE_DEBUGPRINTF 0 // UART is not implemented yet +#define FUNCONF_INIT_ANALOG 0 // ADC is not implemented yet + +#endif From 17ace987e2b207bbc395841b3831a770ba52908a Mon Sep 17 00:00:00 2001 From: Lars Beemster Date: Wed, 26 Feb 2025 18:50:36 +0100 Subject: [PATCH 2/6] simplify and #define sys_safe_access_..., abolish by #define GPIO ModeCfg --- ch32fun/ch32fun.c | 169 ++++++++-------------------------------------- ch32fun/ch32fun.h | 39 ++++++++++- ch32fun/ch59xhw.h | 77 ++++++++------------- 3 files changed, 92 insertions(+), 193 deletions(-) diff --git a/ch32fun/ch32fun.c b/ch32fun/ch32fun.c index dd295637..a33d7a82 100644 --- a/ch32fun/ch32fun.c +++ b/ch32fun/ch32fun.c @@ -1501,144 +1501,6 @@ void DelaySysTick( uint32_t n ) #endif } -#if defined(CH59x) -/** - * @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. - */ -vu32 IRQ_STA = 0; -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void sys_safe_access_enable(void) -{ - if(read_csr(0x800) & 0x08) - { - IRQ_STA = read_csr(0x800); - write_csr(0x800, (IRQ_STA&(~0x08))); - } - ADD_N_NOPS(2); - R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1; - R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2; - ADD_N_NOPS(2); -} - -__attribute__( ( always_inline ) ) RV_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; - ADD_N_NOPS(2); -} - -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; - ADD_N_NOPS(4); - sys_safe_access_disable(); - sys_safe_access_enable(); - ADD_N_NOPS(2); - 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; - ADD_N_NOPS(4); - 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(); - } - sys_safe_access_enable(); - R8_PLL_CONFIG |= 1 << 7; - sys_safe_access_disable(); -} -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; - } -} - -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; - } -} -#endif - void SystemInit( void ) { #if defined(CH32V30x) && defined(TARGET_MCU_MEMORY_SPLIT) @@ -1697,8 +1559,35 @@ void SystemInit( void ) #endif #endif -#if defined(CH59x) - SetSysClock(CLK_SOURCE_PLL_60MHz); +#if defined(CH59x) // has no HSI + // SYS_SAFE_ACCESS for writing RWA and WA registers + #define SYS_SAFE_ACCESS_ENABLE { R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1; R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2; ADD_N_NOPS(2); } + #define SYS_SAFE_ACCESS_DISABLE { R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG0; ADD_N_NOPS(2); } +#ifndef CLK_SOURCE_CH59X + #define CLK_SOURCE_CH59X CLK_SOURCE_PLL_60MHz +#endif + SYS_SAFE_ACCESS_ENABLE + R8_PLL_CONFIG &= ~(1 << 5); + SYS_CLKTypeDef sc = CLK_SOURCE_CH59X; + if(sc & 0x20) // HSE div + { + R32_CLK_SYS_CFG = (0 << 6) | (sc & 0x1f) | RB_TX_32M_PWR_EN | RB_PLL_PWR_EN; + ADD_N_NOPS(4); + R8_FLASH_CFG = 0X51; + } + + else if(sc & 0x40) // PLL div + { + R32_CLK_SYS_CFG = (1 << 6) | (sc & 0x1f) | RB_TX_32M_PWR_EN | RB_PLL_PWR_EN; + ADD_N_NOPS(4); + R8_FLASH_CFG = 0X52; + } + else + { + R32_CLK_SYS_CFG |= RB_CLK_SYS_MOD; + } + R8_PLL_CONFIG |= 1 << 7; + SYS_SAFE_ACCESS_DISABLE #elif defined(FUNCONF_USE_HSI) && FUNCONF_USE_HSI #if defined(CH32V30x) || defined(CH32V20x) || defined(CH32V10x) EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; diff --git a/ch32fun/ch32fun.h b/ch32fun/ch32fun.h index 6ba8abf6..6abc0056 100644 --- a/ch32fun/ch32fun.h +++ b/ch32fun/ch32fun.h @@ -828,9 +828,42 @@ extern "C" { #define FUN_HIGH 0x1 #define FUN_LOW 0x0 #if defined(CH59x) -#define funDigitalWrite( pin, value ) { if(value==FUN_HIGH){GPIOA_SetBits(pin);} else if(value==FUN_LOW){GPIOA_ResetBits(pin);} } -void GPIOA_ModeCfg(uint32_t pin, GPIOModeTypeDef mode); -#define funPinMode( pin, mode ) GPIOA_ModeCfg(pin, mode) +#define GPIOA_ResetBits(pin) (R32_PA_CLR |= pin) +#define GPIOA_SetBits(pin) (R32_PA_OUT |= pin) +#define GPIOA_InverseBits(pin) (R32_PA_OUT ^= pin) +#define GPIOA_ReadPortPin(pin) (R32_PA_PIN & (pin)) +#define GPIOB_ResetBits(pin) (R32_PB_CLR |= pin) +#define GPIOB_SetBits(pin) (R32_PB_OUT |= pin) +#define GPIOB_InverseBits(pin) (R32_PB_OUT ^= pin) +#define GPIOB_ReadPortPin(pin) (R32_PB_PIN & (pin)) +#define GPIO_ResetBits(pin) { if(pin & PB) GPIOB_ResetBits(pin); else GPIOA_ResetBits(pin); } +#define GPIO_SetBits(pin) { if(pin & PB) GPIOB_SetBits(pin); else GPIOA_SetBits(pin); } +#define GPIO_InverseBits(pin) { if(pin & PB) GPIOB_InverseBits(pin); else GPIOA_InverseBits(pin); } +#define funDigitalRead(pin) ( (pin & PB) ? GPIOB_ReadPortPin(pin) : GPIOA_ReadPortPin(pin) ) +#define funDigitalWrite( pin, value ) { if(value==FUN_HIGH){GPIO_SetBits(pin);} else if(value==FUN_LOW){GPIO_ResetBits(pin);} } +typedef enum +{ + GPIO_ModeIN_Floating, + GPIO_ModeIN_PU, + GPIO_ModeIN_PD, + GPIO_ModeOut_PP_5mA, + GPIO_ModeOut_PP_20mA, + +} GPIOModeTypeDef; +#define GPIO_ModeCfg(pd_drv, pu, dir, pin, mode) { switch(mode) { \ + case GPIO_ModeIN_Floating: \ + pd_drv &= ~pin; pu &= ~pin; dir &= ~pin; break; \ + case GPIO_ModeIN_PU: \ + pd_drv &= ~pin; pu |= pin; dir &= ~pin; break; \ + case GPIO_ModeIN_PD: \ + pd_drv |= pin; pu &= ~pin; dir &= ~pin; break; \ + case GPIO_ModeOut_PP_5mA: \ + pd_drv &= ~pin; dir |= pin; break; \ + case GPIO_ModeOut_PP_20mA: \ + pd_drv |= pin; dir |= pin; break; \ + } } +#define funPinMode( pin, mode ) { if(pin & PB) GPIO_ModeCfg(R32_PB_PD_DRV, R32_PB_PU, R32_PB_DIR, pin, mode) \ + else GPIO_ModeCfg(R32_PA_PD_DRV, R32_PA_PU, R32_PA_DIR, pin, mode) } #else // Arduino-like GPIO Functionality #define GpioOf( pin ) ((GPIO_TypeDef *)(GPIOA_BASE + 0x400 * ((pin)>>4))) diff --git a/ch32fun/ch59xhw.h b/ch32fun/ch59xhw.h index eb8d9b01..547243be 100644 --- a/ch32fun/ch59xhw.h +++ b/ch32fun/ch59xhw.h @@ -185,7 +185,7 @@ typedef enum #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 (*((vu8*)0x40001041)) // RF, chip ID register, always is ID_CH58* +#define R8_CHIP_ID (*((vu8*)0x40001041)) // RF, chip ID register, always is ID_CH59* /*System: Miscellaneous Control register */ #define R32_MISC_CTRL (*((vu32*)0x40001048)) // RWA, miscellaneous control register @@ -199,13 +199,6 @@ typedef enum #define R8_FLASH_CTRL (*((vu8*)0x40001806)) // RW, flash ROM access control #define R8_FLASH_CFG (*((vu8*)0x40001807)) // RW, flash ROM access config, SAM -#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)); \ - }) - /* GPIO PA register */ #define R32_PA_DIR (*((vu32*)0x400010A0)) // RW, GPIO PA I/O direction: 0=in, 1=out @@ -270,48 +263,32 @@ typedef enum #define PA14 (0x00004000) /*!< Pin 14 selected */ #define PA15 (0x00008000) /*!< Pin 15 selected */ -#define PB0 (0x00000001) /*!< Pin 0 selected */ -#define PB1 (0x00000002) /*!< Pin 1 selected */ -#define PB2 (0x00000004) /*!< Pin 2 selected */ -#define PB3 (0x00000008) /*!< Pin 3 selected */ -#define PB4 (0x00000010) /*!< Pin 4 selected */ -#define PB5 (0x00000020) /*!< Pin 5 selected */ -#define PB6 (0x00000040) /*!< Pin 6 selected */ -#define PB7 (0x00000080) /*!< Pin 7 selected */ -#define PB8 (0x00000100) /*!< Pin 8 selected */ -#define PB9 (0x00000200) /*!< Pin 9 selected */ -#define PB10 (0x00000400) /*!< Pin 10 selected */ -#define PB11 (0x00000800) /*!< Pin 11 selected */ -#define PB12 (0x00001000) /*!< Pin 12 selected */ -#define PB13 (0x00002000) /*!< Pin 13 selected */ -#define PB14 (0x00004000) /*!< Pin 14 selected */ -#define PB15 (0x00008000) /*!< Pin 15 selected */ -#define PB16 (0x00010000) /*!< Pin 16 selected */ -#define PB17 (0x00020000) /*!< Pin 17 selected */ -#define PB18 (0x00040000) /*!< Pin 18 selected */ -#define PB19 (0x00080000) /*!< Pin 19 selected */ -#define PB20 (0x00100000) /*!< Pin 20 selected */ -#define PB21 (0x00200000) /*!< Pin 21 selected */ -#define PB22 (0x00400000) /*!< Pin 22 selected */ -#define PB23 (0x00800000) /*!< Pin 23 selected */ -#define PA_All (0xFFFFFFFF) /*!< All pins selected */ - -typedef enum -{ - GPIO_ModeIN_Floating, - GPIO_ModeIN_PU, - GPIO_ModeIN_PD, - GPIO_ModeOut_PP_5mA, - GPIO_ModeOut_PP_20mA, - -} GPIOModeTypeDef; - -#define GPIOA_ResetBits(pin) (R32_PA_CLR |= pin) -#define GPIOA_SetBits(pin) (R32_PA_OUT |= pin) -#define GPIOA_InverseBits(pin) (R32_PA_OUT ^= pin) -#define GPIOB_ResetBits(pin) (R32_PB_CLR |= pin) -#define GPIOB_SetBits(pin) (R32_PB_OUT |= pin) -#define GPIOB_InverseBits(pin) (R32_PB_OUT ^= pin) +#define PB (0x10000000) /*!< Pin 0 selected */ +#define PB0 (0x10000001) /*!< Pin 0 selected */ +#define PB1 (0x10000002) /*!< Pin 1 selected */ +#define PB2 (0x10000004) /*!< Pin 2 selected */ +#define PB3 (0x10000008) /*!< Pin 3 selected */ +#define PB4 (0x10000010) /*!< Pin 4 selected */ +#define PB5 (0x10000020) /*!< Pin 5 selected */ +#define PB6 (0x10000040) /*!< Pin 6 selected */ +#define PB7 (0x10000080) /*!< Pin 7 selected */ +#define PB8 (0x10000100) /*!< Pin 8 selected */ +#define PB9 (0x10000200) /*!< Pin 9 selected */ +#define PB10 (0x10000400) /*!< Pin 10 selected */ +#define PB11 (0x10000800) /*!< Pin 11 selected */ +#define PB12 (0x10001000) /*!< Pin 12 selected */ +#define PB13 (0x10002000) /*!< Pin 13 selected */ +#define PB14 (0x10004000) /*!< Pin 14 selected */ +#define PB15 (0x10008000) /*!< Pin 15 selected */ +#define PB16 (0x10010000) /*!< Pin 16 selected */ +#define PB17 (0x10020000) /*!< Pin 17 selected */ +#define PB18 (0x10040000) /*!< Pin 18 selected */ +#define PB19 (0x10080000) /*!< Pin 19 selected */ +#define PB20 (0x10100000) /*!< Pin 20 selected */ +#define PB21 (0x10200000) /*!< Pin 21 selected */ +#define PB22 (0x10400000) /*!< Pin 22 selected */ +#define PB23 (0x10800000) /*!< Pin 23 selected */ +#define P_All (0xFFFFFFFF) /*!< All pins selected */ #define HardFault_IRQn EXC_IRQn From d6ecbcf849ad1b9bd5bd81abf2df7e7fcbc260d6 Mon Sep 17 00:00:00 2001 From: Lars Beemster Date: Sat, 1 Mar 2025 14:10:17 +0100 Subject: [PATCH 3/6] overload pin definitions of ch59x to ch32 defs, add (untested) debugprintfdemo --- ch32fun/ch32fun.h | 8 ----- ch32fun/ch59xhw.h | 25 ++++++++++++++ examples_ch59x/blink/blink.c | 2 +- examples_ch59x/blink/funconfig.h | 2 +- examples_ch59x/debugprintfdemo/Makefile | 10 ++++++ .../debugprintfdemo/debugprintfdemo.c | 34 +++++++++++++++++++ examples_ch59x/debugprintfdemo/funconfig.h | 10 ++++++ 7 files changed, 81 insertions(+), 10 deletions(-) create mode 100644 examples_ch59x/debugprintfdemo/Makefile create mode 100644 examples_ch59x/debugprintfdemo/debugprintfdemo.c create mode 100644 examples_ch59x/debugprintfdemo/funconfig.h diff --git a/ch32fun/ch32fun.h b/ch32fun/ch32fun.h index 6abc0056..23a9a2ca 100644 --- a/ch32fun/ch32fun.h +++ b/ch32fun/ch32fun.h @@ -841,15 +841,7 @@ extern "C" { #define GPIO_InverseBits(pin) { if(pin & PB) GPIOB_InverseBits(pin); else GPIOA_InverseBits(pin); } #define funDigitalRead(pin) ( (pin & PB) ? GPIOB_ReadPortPin(pin) : GPIOA_ReadPortPin(pin) ) #define funDigitalWrite( pin, value ) { if(value==FUN_HIGH){GPIO_SetBits(pin);} else if(value==FUN_LOW){GPIO_ResetBits(pin);} } -typedef enum -{ - GPIO_ModeIN_Floating, - GPIO_ModeIN_PU, - GPIO_ModeIN_PD, - GPIO_ModeOut_PP_5mA, - GPIO_ModeOut_PP_20mA, -} GPIOModeTypeDef; #define GPIO_ModeCfg(pd_drv, pu, dir, pin, mode) { switch(mode) { \ case GPIO_ModeIN_Floating: \ pd_drv &= ~pin; pu &= ~pin; dir &= ~pin; break; \ diff --git a/ch32fun/ch59xhw.h b/ch32fun/ch59xhw.h index 547243be..218bffc8 100644 --- a/ch32fun/ch59xhw.h +++ b/ch32fun/ch59xhw.h @@ -168,6 +168,11 @@ typedef enum CLK_SOURCE_PLL_24MHz = (0x40 | 20), } SYS_CLKTypeDef; +// For debug writing to the debug interface. +#define DMDATA0 ((vu32*)0xe0000380) +#define DMDATA1 ((vu32*)0xe0000384) +#define DMSTATUS_SENTINEL ((vu32*)0xe0000388)// Reads as 0x00000000 if debugger is attached. + /* System: clock configuration register */ #define R32_CLK_SYS_CFG (*((vu32*)0x40001008)) // RWA, system clock configuration, SAM #define RB_CLK_PLL_DIV 0x1F // RWA, output clock divider from PLL or CK32M @@ -290,6 +295,26 @@ typedef enum #define PB23 (0x10800000) /*!< Pin 23 selected */ #define P_All (0xFFFFFFFF) /*!< All pins selected */ +typedef enum +{ + GPIO_ModeIN_Floating, + GPIO_ModeIN_PU, + GPIO_ModeIN_PD, + GPIO_ModeOut_PP_5mA, + GPIO_ModeOut_PP_20mA, +} GPIOModeTypeDef; + +/* General Purpose I/O */ +typedef enum +{ + GPIO_CFGLR_IN_FLOAT = GPIO_ModeIN_Floating, + GPIO_CFGLR_IN_PUPD = GPIO_ModeIN_PU, // is most common + GPIO_CFGLR_IN_PU = GPIO_ModeIN_PU, + GPIO_CFGLR_IN_PD = GPIO_ModeIN_PD, // to suppress the -Wswitch warning + GPIO_CFGLR_OUT_10Mhz_PP = GPIO_ModeOut_PP_20mA, + GPIO_CFGLR_OUT_2Mhz_PP = GPIO_ModeOut_PP_5mA, + GPIO_CFGLR_OUT_50Mhz_PP = GPIO_ModeOut_PP_20mA, +} GPIO_CFGLR_PIN_MODE_Typedef; #define HardFault_IRQn EXC_IRQn diff --git a/examples_ch59x/blink/blink.c b/examples_ch59x/blink/blink.c index 25992b82..75b1ea87 100644 --- a/examples_ch59x/blink/blink.c +++ b/examples_ch59x/blink/blink.c @@ -5,7 +5,7 @@ int main() { SystemInit(); - funPinMode( PA8, GPIO_ModeOut_PP_5mA ); + funPinMode( PA8, GPIO_CFGLR_OUT_2Mhz_PP ); while(1) { diff --git a/examples_ch59x/blink/funconfig.h b/examples_ch59x/blink/funconfig.h index 584e59c0..49ed0f85 100644 --- a/examples_ch59x/blink/funconfig.h +++ b/examples_ch59x/blink/funconfig.h @@ -5,7 +5,7 @@ #define FUNCONF_USE_HSE 1 #define FUNCONF_DEBUG_HARDFAULT 0 #define FUNCONF_USE_CLK_SEC 0 -#define FUNCONF_USE_DEBUGPRINTF 0 // UART is not implemented yet +#define FUNCONF_USE_DEBUGPRINTF 0 // saves 16 bytes, enable / remove if you want printf over swio #define FUNCONF_INIT_ANALOG 0 // ADC is not implemented yet #endif diff --git a/examples_ch59x/debugprintfdemo/Makefile b/examples_ch59x/debugprintfdemo/Makefile new file mode 100644 index 00000000..04239d39 --- /dev/null +++ b/examples_ch59x/debugprintfdemo/Makefile @@ -0,0 +1,10 @@ +all : flash + +TARGET:=debugprintfdemo +TARGET_MCU:=CH592 +TARGET_MCU_PACKAGE:=CH592F + +include ../../ch32fun/ch32fun.mk + +flash : cv_flash +clean : cv_clean diff --git a/examples_ch59x/debugprintfdemo/debugprintfdemo.c b/examples_ch59x/debugprintfdemo/debugprintfdemo.c new file mode 100644 index 00000000..9ae474f1 --- /dev/null +++ b/examples_ch59x/debugprintfdemo/debugprintfdemo.c @@ -0,0 +1,34 @@ +/* Small example showing how to use the SWIO programming pin to + do printf through the debug interface */ + +#include "ch32fun.h" +#include + +uint32_t count; + +int last = 0; +void handle_debug_input( int numbytes, uint8_t * data ) +{ + last = data[0]; + count += numbytes; +} + +int main() +{ + SystemInit(); + + funPinMode( PA8, GPIO_CFGLR_OUT_10Mhz_PP ); + + while(1) + { + funDigitalWrite( PA8, FUN_LOW ); // Turn on LED + printf( "+%lu\n", count++ ); + Delay_Ms(100); + int i; + for( i = 0; i < 10000; i++ ) + poll_input(); + funDigitalWrite( PA8, FUN_HIGH ); // Turn off LED + printf( "-%lu[%c]\n", count++, last ); + Delay_Ms(100); + } +} diff --git a/examples_ch59x/debugprintfdemo/funconfig.h b/examples_ch59x/debugprintfdemo/funconfig.h new file mode 100644 index 00000000..135d439c --- /dev/null +++ b/examples_ch59x/debugprintfdemo/funconfig.h @@ -0,0 +1,10 @@ +#ifndef _FUNCONFIG_H +#define _FUNCONFIG_H + +#define FUNCONF_USE_HSI 0 // CH592 does not have HSI +#define FUNCONF_USE_HSE 1 +#define FUNCONF_DEBUG_HARDFAULT 0 +#define FUNCONF_USE_CLK_SEC 0 +#define FUNCONF_INIT_ANALOG 0 // ADC is not implemented yet + +#endif From ea55eeebf7c5cb382c77407d0791805015001375 Mon Sep 17 00:00:00 2001 From: Lars Beemster Date: Mon, 10 Mar 2025 18:22:02 +0100 Subject: [PATCH 4/6] _zicsr in macro, tabs in ch32fun.ld --- ch32fun/ch32fun.ld | 20 ++++++++++---------- ch32fun/ch32fun.mk | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ch32fun/ch32fun.ld b/ch32fun/ch32fun.ld index 991b0332..7dd34a08 100644 --- a/ch32fun/ch32fun.ld +++ b/ch32fun/ch32fun.ld @@ -69,16 +69,16 @@ MEMORY FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 62K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 8K #elif TARGET_MCU_LD == 8 - /* CH591/2 */ - #if MCU_PACKAGE == 1 - FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 192K - RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 24K - #elif MCU_PACKAGE == 2 - FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 448K - RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 24K - #else - #error "Unknown MCU package" - #endif + /* CH591/2 */ + #if MCU_PACKAGE == 1 + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 192K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 24K + #elif MCU_PACKAGE == 2 + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 448K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 24K + #else + #error "Unknown MCU package" +#endif #else #error "Unknown MCU target" #endif diff --git a/ch32fun/ch32fun.mk b/ch32fun/ch32fun.mk index 51e80158..e5b90ccb 100644 --- a/ch32fun/ch32fun.mk +++ b/ch32fun/ch32fun.mk @@ -185,7 +185,7 @@ else TARGET_MCU_LD:=3 else ifeq ($(findstring CH59,$(TARGET_MCU)),CH59) # CH592 1 TARGET_MCU_PACKAGE?=CH592F - CFLAGS_ARCH+=-march=rv32imac_zicsr \ + CFLAGS_ARCH+=-march=rv32imac \ -mabi=ilp32 \ -DCH59x=1 From 4b87983a03556a569457ce88e8ef33a944fc1dff Mon Sep 17 00:00:00 2001 From: Lars Beemster Date: Tue, 11 Mar 2025 17:49:20 +0100 Subject: [PATCH 5/6] fix setting SYSTEM_CORE_CLOCK --- ch32fun/ch32fun.h | 7 ++++++- ch32fun/ch59xhw.h | 18 +++++++++--------- examples_ch59x/blink/funconfig.h | 15 +++++++++------ examples_ch59x/debugprintfdemo/funconfig.h | 13 ++++++++----- 4 files changed, 32 insertions(+), 21 deletions(-) diff --git a/ch32fun/ch32fun.h b/ch32fun/ch32fun.h index 23a9a2ca..76025877 100644 --- a/ch32fun/ch32fun.h +++ b/ch32fun/ch32fun.h @@ -208,7 +208,12 @@ #endif #ifndef FUNCONF_SYSTEM_CORE_CLOCK - #if defined(FUNCONF_USE_HSI) && FUNCONF_USE_HSI + #if defined(CH59x) // no PLL multiplier, but a divider from the 480 MHz clock + #define FUNCONF_SYSTEM_CORE_CLOCK 60000000 // default in ch32fun.c using CLK_SOURCE_PLL_60MHz + #if defined(CLK_SOURCE_CH59X) + #error Must define FUNCONF_SYSTEM_CORE_CLOCK too if CLK_SOURCE_CH59X is defined + #endif + #elif defined(FUNCONF_USE_HSI) && FUNCONF_USE_HSI #define FUNCONF_SYSTEM_CORE_CLOCK ((HSI_VALUE)*(FUNCONF_PLL_MULTIPLIER)) #elif defined(FUNCONF_USE_HSE) && FUNCONF_USE_HSE #define FUNCONF_SYSTEM_CORE_CLOCK ((HSE_VALUE)*(FUNCONF_PLL_MULTIPLIER)) diff --git a/ch32fun/ch59xhw.h b/ch32fun/ch59xhw.h index 218bffc8..fd9f62e2 100644 --- a/ch32fun/ch59xhw.h +++ b/ch32fun/ch59xhw.h @@ -157,15 +157,15 @@ 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), + CLK_SOURCE_HSE_16MHz = (0x20 | 2), + CLK_SOURCE_HSE_8MHz = (0x20 | 4), + CLK_SOURCE_HSE_6_4MHz = (0x20 | 5), + CLK_SOURCE_HSE_4MHz = (0x20 | 8), + + CLK_SOURCE_PLL_60MHz = (0x40 | 8), + CLK_SOURCE_PLL_48MHz = (0x40 | 10), + CLK_SOURCE_PLL_32MHz = (0x40 | 15), + CLK_SOURCE_PLL_24MHz = (0x40 | 20), } SYS_CLKTypeDef; // For debug writing to the debug interface. diff --git a/examples_ch59x/blink/funconfig.h b/examples_ch59x/blink/funconfig.h index 49ed0f85..31dec37c 100644 --- a/examples_ch59x/blink/funconfig.h +++ b/examples_ch59x/blink/funconfig.h @@ -1,11 +1,14 @@ #ifndef _FUNCONFIG_H #define _FUNCONFIG_H -#define FUNCONF_USE_HSI 0 // CH592 does not have HSI -#define FUNCONF_USE_HSE 1 -#define FUNCONF_DEBUG_HARDFAULT 0 -#define FUNCONF_USE_CLK_SEC 0 -#define FUNCONF_USE_DEBUGPRINTF 0 // saves 16 bytes, enable / remove if you want printf over swio -#define FUNCONF_INIT_ANALOG 0 // ADC is not implemented yet +#define FUNCONF_USE_HSI 0 // CH592 does not have HSI +#define FUNCONF_USE_HSE 1 +#define CLK_SOURCE_CH59X CLK_SOURCE_PLL_60MHz // default so not really needed +#define FUNCONF_SYSTEM_CORE_CLOCK 60 * 1000 * 1000 // keep in line with CLK_SOURCE_CH59X + +#define FUNCONF_DEBUG_HARDFAULT 0 +#define FUNCONF_USE_CLK_SEC 0 +#define FUNCONF_USE_DEBUGPRINTF 0 // saves 16 bytes, enable / remove if you want printf over swio +#define FUNCONF_INIT_ANALOG 0 // ADC is not implemented yet #endif diff --git a/examples_ch59x/debugprintfdemo/funconfig.h b/examples_ch59x/debugprintfdemo/funconfig.h index 135d439c..3ee74d61 100644 --- a/examples_ch59x/debugprintfdemo/funconfig.h +++ b/examples_ch59x/debugprintfdemo/funconfig.h @@ -1,10 +1,13 @@ #ifndef _FUNCONFIG_H #define _FUNCONFIG_H -#define FUNCONF_USE_HSI 0 // CH592 does not have HSI -#define FUNCONF_USE_HSE 1 -#define FUNCONF_DEBUG_HARDFAULT 0 -#define FUNCONF_USE_CLK_SEC 0 -#define FUNCONF_INIT_ANALOG 0 // ADC is not implemented yet +#define FUNCONF_USE_HSI 0 // CH592 does not have HSI +#define FUNCONF_USE_HSE 1 +#define CLK_SOURCE_CH59X CLK_SOURCE_PLL_60MHz // default so not really needed +#define FUNCONF_SYSTEM_CORE_CLOCK 60 * 1000 * 1000 // keep in line with CLK_SOURCE_CH59X + +#define FUNCONF_DEBUG_HARDFAULT 0 +#define FUNCONF_USE_CLK_SEC 0 +#define FUNCONF_INIT_ANALOG 0 // ADC is not implemented yet #endif From f475b813a0443577f38cd6fc14f9be6e73d7f8e1 Mon Sep 17 00:00:00 2001 From: Lars Beemster Date: Wed, 12 Mar 2025 13:38:06 +0100 Subject: [PATCH 6/6] simplify funPinMode, change macro to function --- ch32fun/ch32fun.h | 64 ++++++++++++++++++++----------------- ch32fun/ch59xhw.h | 80 +++++++++++++++-------------------------------- 2 files changed, 61 insertions(+), 83 deletions(-) diff --git a/ch32fun/ch32fun.h b/ch32fun/ch32fun.h index 76025877..c326b51b 100644 --- a/ch32fun/ch32fun.h +++ b/ch32fun/ch32fun.h @@ -833,34 +833,42 @@ extern "C" { #define FUN_HIGH 0x1 #define FUN_LOW 0x0 #if defined(CH59x) -#define GPIOA_ResetBits(pin) (R32_PA_CLR |= pin) -#define GPIOA_SetBits(pin) (R32_PA_OUT |= pin) -#define GPIOA_InverseBits(pin) (R32_PA_OUT ^= pin) -#define GPIOA_ReadPortPin(pin) (R32_PA_PIN & (pin)) -#define GPIOB_ResetBits(pin) (R32_PB_CLR |= pin) -#define GPIOB_SetBits(pin) (R32_PB_OUT |= pin) -#define GPIOB_InverseBits(pin) (R32_PB_OUT ^= pin) -#define GPIOB_ReadPortPin(pin) (R32_PB_PIN & (pin)) -#define GPIO_ResetBits(pin) { if(pin & PB) GPIOB_ResetBits(pin); else GPIOA_ResetBits(pin); } -#define GPIO_SetBits(pin) { if(pin & PB) GPIOB_SetBits(pin); else GPIOA_SetBits(pin); } -#define GPIO_InverseBits(pin) { if(pin & PB) GPIOB_InverseBits(pin); else GPIOA_InverseBits(pin); } -#define funDigitalRead(pin) ( (pin & PB) ? GPIOB_ReadPortPin(pin) : GPIOA_ReadPortPin(pin) ) -#define funDigitalWrite( pin, value ) { if(value==FUN_HIGH){GPIO_SetBits(pin);} else if(value==FUN_LOW){GPIO_ResetBits(pin);} } - -#define GPIO_ModeCfg(pd_drv, pu, dir, pin, mode) { switch(mode) { \ - case GPIO_ModeIN_Floating: \ - pd_drv &= ~pin; pu &= ~pin; dir &= ~pin; break; \ - case GPIO_ModeIN_PU: \ - pd_drv &= ~pin; pu |= pin; dir &= ~pin; break; \ - case GPIO_ModeIN_PD: \ - pd_drv |= pin; pu &= ~pin; dir &= ~pin; break; \ - case GPIO_ModeOut_PP_5mA: \ - pd_drv &= ~pin; dir |= pin; break; \ - case GPIO_ModeOut_PP_20mA: \ - pd_drv |= pin; dir |= pin; break; \ - } } -#define funPinMode( pin, mode ) { if(pin & PB) GPIO_ModeCfg(R32_PB_PD_DRV, R32_PB_PU, R32_PB_DIR, pin, mode) \ - else GPIO_ModeCfg(R32_PA_PD_DRV, R32_PA_PU, R32_PA_DIR, pin, mode) } +#define OFFSET_FOR_GPIOB(pin) (((pin & PB) >> 31) * (&R32_PB_PIN - &R32_PA_PIN)) // 0 if GPIOA, 0x20 if GPIOB +#define GPIO_ResetBits(pin) (*(&R32_PA_CLR + OFFSET_FOR_GPIOB(pin)) |= (pin & ~PB)) +#define GPIO_SetBits(pin) (*(&R32_PA_OUT + OFFSET_FOR_GPIOB(pin)) |= (pin & ~PB)) +#define GPIO_InverseBits(pin) (*(&R32_PA_OUT + OFFSET_FOR_GPIOB(pin)) ^= (pin & ~PB)) +#define GPIO_ReadPortPin(pin) (*(&R32_PA_PIN + OFFSET_FOR_GPIOB(pin)) & (pin & ~PB)) +#define funDigitalRead(pin) GPIO_ReadPortPin(pin) +#define funDigitalWrite( pin, value ) { if((value)==FUN_HIGH){GPIO_SetBits(pin);} else if((value)==FUN_LOW){GPIO_ResetBits(pin);} } + +RV_STATIC_INLINE void funPinMode(u32 pin, GPIOModeTypeDef mode) +{ + switch(mode) { + case GPIO_ModeIN_Floating: + *(&R32_PA_PD_DRV + OFFSET_FOR_GPIOB(pin)) &= ~(pin & ~PB); + *(&R32_PA_PU + OFFSET_FOR_GPIOB(pin)) &= ~(pin & ~PB); + *(&R32_PA_DIR + OFFSET_FOR_GPIOB(pin)) &= ~(pin & ~PB); + break; + case GPIO_ModeIN_PU: + *(&R32_PA_PD_DRV + OFFSET_FOR_GPIOB(pin)) &= ~(pin & ~PB); + *(&R32_PA_PU + OFFSET_FOR_GPIOB(pin)) |= (pin & ~PB); + *(&R32_PA_DIR + OFFSET_FOR_GPIOB(pin)) &= ~(pin & ~PB); + break; + case GPIO_ModeIN_PD: + *(&R32_PA_PD_DRV + OFFSET_FOR_GPIOB(pin)) |= (pin & ~PB); + *(&R32_PA_PU + OFFSET_FOR_GPIOB(pin)) &= ~(pin & ~PB); + *(&R32_PA_DIR + OFFSET_FOR_GPIOB(pin)) &= ~(pin & ~PB); + break; + case GPIO_ModeOut_PP_5mA: + *(&R32_PA_PD_DRV + OFFSET_FOR_GPIOB(pin)) &= ~(pin & ~PB); + *(&R32_PA_DIR + OFFSET_FOR_GPIOB(pin)) |= (pin & ~PB); + break; + case GPIO_ModeOut_PP_20mA: + *(&R32_PA_PD_DRV + OFFSET_FOR_GPIOB(pin)) |= (pin & ~PB); + *(&R32_PA_DIR + OFFSET_FOR_GPIOB(pin)) |= (pin & ~PB); + break; + } +} #else // Arduino-like GPIO Functionality #define GpioOf( pin ) ((GPIO_TypeDef *)(GPIOA_BASE + 0x400 * ((pin)>>4))) diff --git a/ch32fun/ch59xhw.h b/ch32fun/ch59xhw.h index fd9f62e2..42ecc7c6 100644 --- a/ch32fun/ch59xhw.h +++ b/ch32fun/ch59xhw.h @@ -207,49 +207,19 @@ typedef enum /* GPIO PA register */ #define R32_PA_DIR (*((vu32*)0x400010A0)) // RW, GPIO PA I/O direction: 0=in, 1=out -#define R8_PA_DIR_0 (*((vu8*)0x400010A0)) // RW, GPIO PA I/O direction byte 0 -#define R8_PA_DIR_1 (*((vu8*)0x400010A1)) // RW, GPIO PA I/O direction byte 1 #define R32_PA_PIN (*((vu32*)0x400010A4)) // RO, GPIO PA input -#define R8_PA_PIN_0 (*((vu8*)0x400010A4)) // RO, GPIO PA input byte 0 -#define R8_PA_PIN_1 (*((vu8*)0x400010A5)) // RO, GPIO PA input byte 1 #define R32_PA_OUT (*((vu32*)0x400010A8)) // RW, GPIO PA output -#define R8_PA_OUT_0 (*((vu8*)0x400010A8)) // RW, GPIO PA output byte 0 -#define R8_PA_OUT_1 (*((vu8*)0x400010A9)) // RW, GPIO PA output byte 1 #define R32_PA_CLR (*((vu32*)0x400010AC)) // WZ, GPIO PA clear output: 0=keep, 1=clear -#define R8_PA_CLR_0 (*((vu8*)0x400010AC)) // WZ, GPIO PA clear output byte 0 -#define R8_PA_CLR_1 (*((vu8*)0x400010AD)) // WZ, GPIO PA clear output byte 1 #define R32_PA_PU (*((vu32*)0x400010B0)) // RW, GPIO PA pullup resistance enable -#define R8_PA_PU_0 (*((vu8*)0x400010B0)) // RW, GPIO PA pullup resistance enable byte 0 -#define R8_PA_PU_1 (*((vu8*)0x400010B1)) // RW, GPIO PA pullup resistance enable byte 1 #define R32_PA_PD_DRV (*((vu32*)0x400010B4)) // RW, PA pulldown for input or PA driving capability for output -#define R8_PA_PD_DRV_0 (*((vu8*)0x400010B4)) // RW, PA pulldown for input or PA driving capability for output byte 0 -#define R8_PA_PD_DRV_1 (*((vu8*)0x400010B5)) // RW, PA pulldown for input or PA driving capability for output byte 1 /* GPIO PB register */ #define R32_PB_DIR (*((vu32*)0x400010C0)) // RW, GPIO PB I/O direction: 0=in, 1=out -#define R8_PB_DIR_0 (*((vu8*)0x400010C0)) // RW, GPIO PB I/O direction byte 0 -#define R8_PB_DIR_1 (*((vu8*)0x400010C1)) // RW, GPIO PB I/O direction byte 1 -#define R8_PB_DIR_2 (*((vu8*)0x400010C2)) // RW, GPIO PB I/O direction byte 2 #define R32_PB_PIN (*((vu32*)0x400010C4)) // RO, GPIO PB input -#define R8_PB_PIN_0 (*((vu8*)0x400010C4)) // RO, GPIO PB input byte 0 -#define R8_PB_PIN_1 (*((vu8*)0x400010C5)) // RO, GPIO PB input byte 1 -#define R8_PB_PIN_2 (*((vu8*)0x400010C6)) // RO, GPIO PB input byte 2 #define R32_PB_OUT (*((vu32*)0x400010C8)) // RW, GPIO PB output -#define R8_PB_OUT_0 (*((vu8*)0x400010C8)) // RW, GPIO PB output byte 0 -#define R8_PB_OUT_1 (*((vu8*)0x400010C9)) // RW, GPIO PB output byte 1 -#define R8_PB_OUT_2 (*((vu8*)0x400010CA)) // RW, GPIO PB output byte 2 #define R32_PB_CLR (*((vu32*)0x400010CC)) // WZ, GPIO PB clear output: 0=keep, 1=clear -#define R8_PB_CLR_0 (*((vu8*)0x400010CC)) // WZ, GPIO PB clear output byte 0 -#define R8_PB_CLR_1 (*((vu8*)0x400010CD)) // WZ, GPIO PB clear output byte 1 -#define R8_PB_CLR_2 (*((vu8*)0x400010CE)) // WZ, GPIO PB clear output byte 2 #define R32_PB_PU (*((vu32*)0x400010D0)) // RW, GPIO PB pullup resistance enable -#define R8_PB_PU_0 (*((vu8*)0x400010D0)) // RW, GPIO PB pullup resistance enable byte 0 -#define R8_PB_PU_1 (*((vu8*)0x400010D1)) // RW, GPIO PB pullup resistance enable byte 1 -#define R8_PB_PU_2 (*((vu8*)0x400010D2)) // RW, GPIO PB pullup resistance enable byte 2 #define R32_PB_PD_DRV (*((vu32*)0x400010D4)) // RW, PB pulldown for input or PB driving capability for output -#define R8_PB_PD_DRV_0 (*((vu8*)0x400010D4)) // RW, PB pulldown for input or PB driving capability for output byte 0 -#define R8_PB_PD_DRV_1 (*((vu8*)0x400010D5)) // RW, PB pulldown for input or PB driving capability for output byte 1 -#define R8_PB_PD_DRV_2 (*((vu8*)0x400010D6)) // RW, PB pulldown for input or PB driving capability for output byte 2 #define PA0 (0x00000001) /*!< Pin 0 selected */ #define PA1 (0x00000002) /*!< Pin 1 selected */ @@ -268,31 +238,31 @@ typedef enum #define PA14 (0x00004000) /*!< Pin 14 selected */ #define PA15 (0x00008000) /*!< Pin 15 selected */ -#define PB (0x10000000) /*!< Pin 0 selected */ -#define PB0 (0x10000001) /*!< Pin 0 selected */ -#define PB1 (0x10000002) /*!< Pin 1 selected */ -#define PB2 (0x10000004) /*!< Pin 2 selected */ -#define PB3 (0x10000008) /*!< Pin 3 selected */ -#define PB4 (0x10000010) /*!< Pin 4 selected */ -#define PB5 (0x10000020) /*!< Pin 5 selected */ -#define PB6 (0x10000040) /*!< Pin 6 selected */ -#define PB7 (0x10000080) /*!< Pin 7 selected */ -#define PB8 (0x10000100) /*!< Pin 8 selected */ -#define PB9 (0x10000200) /*!< Pin 9 selected */ -#define PB10 (0x10000400) /*!< Pin 10 selected */ -#define PB11 (0x10000800) /*!< Pin 11 selected */ -#define PB12 (0x10001000) /*!< Pin 12 selected */ -#define PB13 (0x10002000) /*!< Pin 13 selected */ -#define PB14 (0x10004000) /*!< Pin 14 selected */ -#define PB15 (0x10008000) /*!< Pin 15 selected */ -#define PB16 (0x10010000) /*!< Pin 16 selected */ -#define PB17 (0x10020000) /*!< Pin 17 selected */ -#define PB18 (0x10040000) /*!< Pin 18 selected */ -#define PB19 (0x10080000) /*!< Pin 19 selected */ -#define PB20 (0x10100000) /*!< Pin 20 selected */ -#define PB21 (0x10200000) /*!< Pin 21 selected */ -#define PB22 (0x10400000) /*!< Pin 22 selected */ -#define PB23 (0x10800000) /*!< Pin 23 selected */ +#define PB (0x80000000) /* Bit mask to indicate bank B */ +#define PB0 (0x80000001) /*!< Pin 0 selected */ +#define PB1 (0x80000002) /*!< Pin 1 selected */ +#define PB2 (0x80000004) /*!< Pin 2 selected */ +#define PB3 (0x80000008) /*!< Pin 3 selected */ +#define PB4 (0x80000010) /*!< Pin 4 selected */ +#define PB5 (0x80000020) /*!< Pin 5 selected */ +#define PB6 (0x80000040) /*!< Pin 6 selected */ +#define PB7 (0x80000080) /*!< Pin 7 selected */ +#define PB8 (0x80000100) /*!< Pin 8 selected */ +#define PB9 (0x80000200) /*!< Pin 9 selected */ +#define PB10 (0x80000400) /*!< Pin 10 selected */ +#define PB11 (0x80000800) /*!< Pin 11 selected */ +#define PB12 (0x80001000) /*!< Pin 12 selected */ +#define PB13 (0x80002000) /*!< Pin 13 selected */ +#define PB14 (0x80004000) /*!< Pin 14 selected */ +#define PB15 (0x80008000) /*!< Pin 15 selected */ +#define PB16 (0x80010000) /*!< Pin 16 selected */ +#define PB17 (0x80020000) /*!< Pin 17 selected */ +#define PB18 (0x80040000) /*!< Pin 18 selected */ +#define PB19 (0x80080000) /*!< Pin 19 selected */ +#define PB20 (0x80100000) /*!< Pin 20 selected */ +#define PB21 (0x80200000) /*!< Pin 21 selected */ +#define PB22 (0x80400000) /*!< Pin 22 selected */ +#define PB23 (0x80800000) /*!< Pin 23 selected */ #define P_All (0xFFFFFFFF) /*!< All pins selected */ typedef enum