Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CH59x bringup and blinky #534

Merged
merged 6 commits into from
Mar 12, 2025
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 55 additions & 4 deletions ch32fun/ch32fun.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -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 )
{
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -1541,7 +1559,36 @@ void SystemInit( void )
#endif
#endif

#if defined(FUNCONF_USE_HSI) && FUNCONF_USE_HSI
#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;
#endif
Expand Down Expand Up @@ -1600,9 +1647,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
Expand All @@ -1617,6 +1666,7 @@ void SystemInit( void )
#endif
}

#if defined(FUNCONF_INIT_ANALOG) && FUNCONF_INIT_ANALOG
void funAnalogInit( void )
{
//RCC->CFGR0 &= ~(0x1F<<11); // Assume ADCPRE = 0
Expand Down Expand Up @@ -1655,6 +1705,7 @@ int funAnalogRead( int nAnalogNumber )
// get result
return ADC1->RDATAR;
}
#endif

// C++ Support

Expand Down
50 changes: 47 additions & 3 deletions ch32fun/ch32fun.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -160,6 +164,8 @@
#endif
#elif defined(CH32V30x)
#define HSE_VALUE (8000000)
#elif defined(CH59x)
#define HSE_VALUE (32000000)
#endif
#endif

Expand Down Expand Up @@ -202,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))
Expand Down Expand Up @@ -348,6 +359,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 )
Expand Down Expand Up @@ -817,11 +830,41 @@ 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 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) }
#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)

Expand All @@ -846,6 +889,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
Expand Down
17 changes: 14 additions & 3 deletions ch32fun/ch32fun.ld
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
21 changes: 21 additions & 0 deletions ch32fun/ch32fun.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
-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
Expand Down
Loading
Loading