Updated the ch32fun.h/c files.
This commit is contained in:
parent
075f10ebee
commit
240e26c130
2 changed files with 289 additions and 99 deletions
113
inc/ch32fun.h
113
inc/ch32fun.h
|
|
@ -24,7 +24,11 @@
|
|||
4. Delays
|
||||
Delay_Us(n)
|
||||
Delay_Ms(n)
|
||||
DelaySysTick( uint32_t n );
|
||||
DelaySysTick( uint32_t n )
|
||||
TimeElapsed32( uint32_t now, uint32_t start);
|
||||
TimeElapsed32U( now, start ); // For if events could be in the future.
|
||||
funSysTick32()
|
||||
funSysTick64()
|
||||
|
||||
5. printf
|
||||
printf, _write may be semihosted, or printed to UART.
|
||||
|
|
@ -85,6 +89,7 @@
|
|||
#define FUNCONF_ISR_IN_RAM 0 // Put the interrupt vector in RAM.
|
||||
#define FUNCONF_SUPPORT_CONSTRUCTORS 0 // Call functions with __attribute__((constructor)) in SystemInit()
|
||||
#define FUNCONF_ICACHE_EN 1 // Enables ICache on cores that support it, may require power-down + power up to work properly at flash time.
|
||||
#define FUNCONF_OVERRIDE_STARTUP 0 // User code will have its own `handle_reset` and `InterruptVector`
|
||||
*/
|
||||
|
||||
// Sanity check for when porting old code.
|
||||
|
|
@ -139,6 +144,10 @@
|
|||
#define FUNCONF_ENABLE_HPE 0
|
||||
#endif
|
||||
|
||||
#ifndef FUNCONF_TINYVECTOR
|
||||
#define FUNCONF_TINYVECTOR 0
|
||||
#endif
|
||||
|
||||
#if FUNCONF_ENABLE_HPE == 1
|
||||
#define INTERRUPT_DECORATOR __attribute__((interrupt("WCH-Interrupt-fast")))
|
||||
#else
|
||||
|
|
@ -278,6 +287,10 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef FUNCONF_OVERRIDE_STARTUP
|
||||
#define FUNCONF_OVERRIDE_STARTUP 0
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Legacy, for EVT, CMSIS
|
||||
|
||||
|
|
@ -884,7 +897,8 @@ extern "C" {
|
|||
#define Ticks_from_Us(n) ((n) * DELAY_US_TIME)
|
||||
#define Ticks_from_Ms(n) ((n) * DELAY_MS_TIME)
|
||||
|
||||
#define TimeElapsed32(now,start) ((uint32_t)((uint32_t)(now)-(uint32_t)(start)))
|
||||
#define TimeElapsed32(now,start) ((int32_t)((uint32_t)(now)-(uint32_t)(start)))
|
||||
#define TimeElapsed32u(now,start) ((uint32_t)((uint32_t)(now)-(uint32_t)(start)))
|
||||
|
||||
// Add a certain number of nops. Note: These are usually executed in pairs
|
||||
// and take two cycles, so you typically would use 0, 2, 4, etc.
|
||||
|
|
@ -893,17 +907,23 @@ extern "C" {
|
|||
#define FUN_HIGH 0x1
|
||||
#define FUN_LOW 0x0
|
||||
#if defined(CH57x) || defined(CH58x) || defined(CH59x)
|
||||
|
||||
#if defined( PB ) && defined( R32_PB_PIN )
|
||||
#define OFFSET_FOR_GPIOB(pin) (((pin & PB) >> 31) * (&R32_PB_PIN - &R32_PA_PIN)) // 0 if GPIOA, 0x20 if GPIOB
|
||||
#else
|
||||
#define PB 0
|
||||
#define OFFSET_FOR_GPIOB(pin) 0
|
||||
#endif
|
||||
#define GPIO_ResetBits(pin) (*(&R32_PA_CLR + OFFSET_FOR_GPIOB(pin)) = (pin & ~PB))
|
||||
#define GPIO_SetBits(pin) (*(&R32_PA_SET + 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)
|
||||
|
||||
#if defined(CH571_CH573) || defined(CH582_CH583) // 582/3 doesn't have _SET
|
||||
#define GPIO_SetBits(pin) (*(&R32_PA_OUT + OFFSET_FOR_GPIOB(pin)) |= (1<<(pin & ~PB)))
|
||||
#else
|
||||
#define GPIO_SetBits(pin) (*(&R32_PA_SET + OFFSET_FOR_GPIOB(pin)) = (1<<(pin & ~PB)))
|
||||
#endif
|
||||
#define GPIO_ResetBits(pin) (*(&R32_PA_CLR + OFFSET_FOR_GPIOB(pin)) = (1<<(pin & ~PB)))
|
||||
#define GPIO_InverseBits(pin) (*(&R32_PA_OUT + OFFSET_FOR_GPIOB(pin)) ^= (1<<(pin & ~PB)))
|
||||
#define GPIO_ReadPortPin(pin) (*(&R32_PA_PIN + OFFSET_FOR_GPIOB(pin)) & (1<<(pin & ~PB)))
|
||||
#define funDigitalRead(pin) !!GPIO_ReadPortPin(pin)
|
||||
#define funDigitalWrite( pin, value ) do{ if((value)==FUN_HIGH){GPIO_SetBits(pin);} else if((value)==FUN_LOW){GPIO_ResetBits(pin);} }while(0)
|
||||
#define funGpioInitAll() // funGpioInitAll() does not do anything on ch5xx, put here for consistency
|
||||
|
||||
|
|
@ -911,27 +931,27 @@ 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);
|
||||
*(&R32_PA_PD_DRV + OFFSET_FOR_GPIOB(pin)) &= ~(1<<(pin & ~PB));
|
||||
*(&R32_PA_PU + OFFSET_FOR_GPIOB(pin)) &= ~(1<<(pin & ~PB));
|
||||
*(&R32_PA_DIR + OFFSET_FOR_GPIOB(pin)) &= ~(1<<(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);
|
||||
*(&R32_PA_PD_DRV + OFFSET_FOR_GPIOB(pin)) &= ~(1<<(pin & ~PB));
|
||||
*(&R32_PA_PU + OFFSET_FOR_GPIOB(pin)) |= (1<<(pin & ~PB));
|
||||
*(&R32_PA_DIR + OFFSET_FOR_GPIOB(pin)) &= ~(1<<(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);
|
||||
*(&R32_PA_PD_DRV + OFFSET_FOR_GPIOB(pin)) |= (1<<(pin & ~PB));
|
||||
*(&R32_PA_PU + OFFSET_FOR_GPIOB(pin)) &= ~(1<<(pin & ~PB));
|
||||
*(&R32_PA_DIR + OFFSET_FOR_GPIOB(pin)) &= ~(1<<(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);
|
||||
*(&R32_PA_PD_DRV + OFFSET_FOR_GPIOB(pin)) &= ~(1<<(pin & ~PB));
|
||||
*(&R32_PA_DIR + OFFSET_FOR_GPIOB(pin)) |= (1<<(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);
|
||||
*(&R32_PA_PD_DRV + OFFSET_FOR_GPIOB(pin)) |= (1<<(pin & ~PB));
|
||||
*(&R32_PA_DIR + OFFSET_FOR_GPIOB(pin)) |= (1<<(pin & ~PB));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -948,14 +968,14 @@ RV_STATIC_INLINE void funPinMode(u32 pin, GPIOModeTypeDef mode)
|
|||
#define funDigitalWrite( pin, value ) do{ GpioOf( pin )->BSHR = 1<<((!(value))*16 + ((pin) & 0xf)); }while(0)
|
||||
|
||||
#if defined(CH32X03x)
|
||||
#define funGpioInitAll() { RCC->APB2PCENR |= ( RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC ); }
|
||||
#define funPinMode( pin, mode ) { *((&GpioOf(pin)->CFGLR)+((pin&0x8)>>3)) = ( (*((&GpioOf(pin)->CFGLR)+((pin&0x8)>>3))) & (~(0xf<<(4*((pin)&0x7))))) | ((mode)<<(4*((pin)&0x7))); }
|
||||
#define funGpioInitAll() do{ RCC->APB2PCENR |= ( RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC ); }while(0)
|
||||
#define funPinMode( pin, mode ) do{ *((&GpioOf(pin)->CFGLR)+((pin&0x8)>>3)) = ( (*((&GpioOf(pin)->CFGLR)+((pin&0x8)>>3))) & (~(0xf<<(4*((pin)&0x7))))) | ((mode)<<(4*((pin)&0x7))); }while(0)
|
||||
#elif defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x) || defined(CH32L103)
|
||||
#define funGpioInitAll() { RCC->APB2PCENR |= ( RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD ); }
|
||||
#define funPinMode( pin, mode ) { *((&GpioOf(pin)->CFGLR)+((pin&0x8)>>3)) = ( (*((&GpioOf(pin)->CFGLR)+((pin&0x8)>>3))) & (~(0xf<<(4*((pin)&0x7))))) | ((mode)<<(4*((pin)&0x7))); }
|
||||
#define funGpioInitB() { RCC->APB2PCENR |= ( RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB ); }
|
||||
#define funGpioInitAll() do{ RCC->APB2PCENR |= ( RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE ); }while(0)
|
||||
#define funPinMode( pin, mode ) do{ *((&GpioOf(pin)->CFGLR)+((pin&0x8)>>3)) = ( (*((&GpioOf(pin)->CFGLR)+((pin&0x8)>>3))) & (~(0xf<<(4*((pin)&0x7))))) | ((mode)<<(4*((pin)&0x7))); }while(0)
|
||||
#define funGpioInitB() do{ RCC->APB2PCENR |= ( RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB ); }while(0)
|
||||
#elif defined(CH32H41x)
|
||||
#define funGpioInitAll() { RCC->HB2PCENR |= ( RCC_HB2Periph_AFIO | RCC_HB2Periph_GPIOA | RCC_HB2Periph_GPIOB | RCC_HB2Periph_GPIOC | RCC_HB2Periph_GPIOD | RCC_HB2Periph_GPIOE | RCC_HB2Periph_GPIOF ); }
|
||||
#define funGpioInitAll() do{ RCC->HB2PCENR |= ( RCC_HB2Periph_AFIO | RCC_HB2Periph_GPIOA | RCC_HB2Periph_GPIOB | RCC_HB2Periph_GPIOC | RCC_HB2Periph_GPIOD | RCC_HB2Periph_GPIOE | RCC_HB2Periph_GPIOF ); }while(0)
|
||||
|
||||
RV_STATIC_INLINE void funPinMode(u32 pin, GPIOMode_TypeDef mode, GPIOSpeed_TypeDef speed)
|
||||
{
|
||||
|
|
@ -971,13 +991,13 @@ RV_STATIC_INLINE void funPinAF(u32 pin, u32 af)
|
|||
}
|
||||
|
||||
#else
|
||||
#define funGpioInitAll() { RCC->APB2PCENR |= ( RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD ); }
|
||||
#define funPinMode( pin, mode ) { GpioOf(pin)->CFGLR = (GpioOf(pin)->CFGLR & (~(0xf<<(4*((pin)&0xf))))) | ((mode)<<(4*((pin)&0xf))); }
|
||||
#define funGpioInitAll() do{ RCC->APB2PCENR |= ( RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD ); }while(0)
|
||||
#define funPinMode( pin, mode ) do{ GpioOf(pin)->CFGLR = (GpioOf(pin)->CFGLR & (~(0xf<<(4*((pin)&0xf))))) | ((mode)<<(4*((pin)&0xf))); }while(0)
|
||||
#endif
|
||||
|
||||
#define funGpioInitA() { RCC->APB2PCENR |= ( RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA ); }
|
||||
#define funGpioInitC() { RCC->APB2PCENR |= ( RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOC ); }
|
||||
#define funGpioInitD() { RCC->APB2PCENR |= ( RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOD ); }
|
||||
#define funGpioInitA() do{ RCC->APB2PCENR |= ( RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA ); }while(0)
|
||||
#define funGpioInitC() do{ RCC->APB2PCENR |= ( RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOC ); }while(0)
|
||||
#define funGpioInitD() do{ RCC->APB2PCENR |= ( RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOD ); }while(0)
|
||||
#define funDigitalRead( pin ) ((int)((GpioOf(pin)->INDR >> ((pin)&0xf)) & 1))
|
||||
#endif
|
||||
|
||||
|
|
@ -999,7 +1019,6 @@ RV_STATIC_INLINE void funPinAF(u32 pin, u32 af)
|
|||
|
||||
#if defined(__riscv) || defined(__riscv__) || defined( CH32V003FUN_BASE )
|
||||
|
||||
|
||||
// Stuff that can only be compiled on device (not for the programmer, or other host programs)
|
||||
|
||||
// Initialize the ADC calibrate it and set some sane defaults.
|
||||
|
|
@ -1009,28 +1028,48 @@ void funAnalogInit( void );
|
|||
// Be sure to call funAnalogInit first.
|
||||
int funAnalogRead( int nAnalogNumber );
|
||||
|
||||
void handle_reset() __attribute__((naked)) __attribute((section(".text.handle_reset"))) __attribute__((used));
|
||||
#if FUNCONF_CUSTOM_MTVEC
|
||||
void handle_reset( void ) __attribute__((naked)) __attribute__((section(".init"))) __attribute__((used));
|
||||
#else
|
||||
void handle_reset( void ) __attribute__((naked)) __attribute__((section(".text.handle_reset"))) __attribute__((used));
|
||||
#endif
|
||||
|
||||
|
||||
void DefaultIRQHandler( void ) __attribute__((section(VECTOR_HANDLER_SECTION))) __attribute__((naked)) __attribute__((used));
|
||||
// used to clear the CSS flag in case of clock fail switch
|
||||
#if defined(FUNCONF_USE_CLK_SEC) && FUNCONF_USE_CLK_SEC
|
||||
void NMI_RCC_CSS_IRQHandler( void ) __attribute__((section(VECTOR_HANDLER_SECTION))) __attribute__((naked)) __attribute__((used));
|
||||
#endif
|
||||
|
||||
void funRebootToBootloader();
|
||||
|
||||
void DelaySysTick( uint32_t n );
|
||||
|
||||
// #define funSysTick32() is defined per-architecture.
|
||||
|
||||
// Get a 64-bit timestamp. Please in general try to use 32-bit timestamps
|
||||
// whenever possible. Use functions that automatically handle rollover
|
||||
// correctly like TimeElapsed32( start, end ). Only use this in cases where
|
||||
// you must act on time periods exceeding 2^31 ticks.
|
||||
//
|
||||
// Also, if you are on a platform without a hardware 64-bit timer, you must
|
||||
// call this function at least once every 2^32 ticks to make sure MSBs aren't
|
||||
// lost.
|
||||
uint64_t funSysTick64( void );
|
||||
|
||||
// Depending on a LOT of factors, it's about 6 cycles per n.
|
||||
// **DO NOT send it zero or less.**
|
||||
#ifndef __MACOSX__
|
||||
#ifndef __DELAY_TINY_DEFINED__
|
||||
#define __DELAY_TINY_DEFINED__
|
||||
|
||||
static inline void Delay_Tiny( int n ) {
|
||||
__ASM volatile( "\
|
||||
mv a5, %[n]\n\
|
||||
asm volatile( "\
|
||||
1: \
|
||||
c.addi a5, -1\n\
|
||||
c.bnez a5, 1b" : : [n]"r"(n) : "a5" );
|
||||
c.addi %[n], -1\n\
|
||||
c.bnez %[n], 1b" : [n]"+r"(n) );
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif //defined(__riscv) || defined(__riscv__) || defined( CH32V003FUN_BASE )
|
||||
|
|
|
|||
275
src/ch32fun.c
275
src/ch32fun.c
|
|
@ -92,6 +92,12 @@ void __libc_init_array(void)
|
|||
#include <stdint.h>
|
||||
#include <ch32fun.h>
|
||||
|
||||
#ifdef putchar
|
||||
// Host stdio headers may define putchar as a macro. The firmware provides its
|
||||
// own weak implementation below, so remove the host macro on every toolchain.
|
||||
#undef putchar
|
||||
#endif
|
||||
|
||||
#if defined(CH32H41x)
|
||||
volatile v5f_main v5f_start_function = NULL;
|
||||
static int start_v5f(void)
|
||||
|
|
@ -920,6 +926,7 @@ void I2C2_ER_IRQHandler( void ) __attribute__((section(VECTOR_HANDLER_SECTION)
|
|||
void SPI2_IRQHandler( void ) __attribute__((section(VECTOR_HANDLER_SECTION))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
|
||||
void USART1_IRQHandler( void ) __attribute__((section(VECTOR_HANDLER_SECTION))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
|
||||
void USART2_IRQHandler( void ) __attribute__((section(VECTOR_HANDLER_SECTION))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
|
||||
void OPCM_IRQHandler( void ) __attribute__((section(VECTOR_HANDLER_SECTION))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
|
||||
void USART3_IRQHandler( void ) __attribute__((section(VECTOR_HANDLER_SECTION))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
|
||||
void EXTI15_10_IRQHandler( void ) __attribute__((section(VECTOR_HANDLER_SECTION))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
|
||||
void RTCAlarm_IRQHandler( void ) __attribute__((section(VECTOR_HANDLER_SECTION))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
|
||||
|
|
@ -1067,9 +1074,12 @@ void USART_WKUP_IRQHandler( void ) __attribute__((section(VECTOR_HANDLER_SECTIO
|
|||
|
||||
void handle_reset( void ) __attribute__((section(".text.handle_reset")));
|
||||
|
||||
#if !FUNCONF_OVERRIDE_STARTUP
|
||||
#if FUNCONF_ISR_IN_RAM
|
||||
void Init() __attribute__((naked)) __attribute((section(".init"))) __attribute((weak,alias("InitDefault"))) __attribute((naked));
|
||||
void InitDefault() __attribute__((naked)) __attribute((section(".init"))) __attribute((naked));
|
||||
|
||||
#if !defined(FUNCONF_TINYVECTOR) || !FUNCONF_TINYVECTOR
|
||||
void InitDefault( void )
|
||||
{
|
||||
asm volatile( "\n\
|
||||
|
|
@ -1079,6 +1089,9 @@ void handle_reset( void ) __attribute__((section(".text.handle_reset")));
|
|||
j handle_reset\n\
|
||||
.option pop;\n" );
|
||||
}
|
||||
#else
|
||||
void InitDefault() __attribute__((naked)) __attribute((section(".init"))) __attribute((weak,alias("handle_reset")));
|
||||
#endif
|
||||
|
||||
void InterruptVector() __attribute__((naked)) __attribute((section(VECTOR_HANDLER_SECTION))) __attribute((weak,alias("InterruptVectorDefault"))) __attribute((naked));
|
||||
void InterruptVectorDefault() __attribute__((naked)) __attribute((section(VECTOR_HANDLER_SECTION))) __attribute((naked));
|
||||
|
|
@ -1089,6 +1102,7 @@ void handle_reset( void ) __attribute__((section(".text.handle_reset")));
|
|||
#else
|
||||
void InterruptVector() __attribute__((naked)) __attribute((section(".init"))) __attribute((weak,alias("InterruptVectorDefault"))) __attribute((naked));
|
||||
void InterruptVectorDefault() __attribute__((naked)) __attribute((section(".init"))) __attribute((naked));
|
||||
|
||||
void InterruptVectorDefault( void )
|
||||
{
|
||||
#if !defined(FUNCONF_TINYVECTOR) || !FUNCONF_TINYVECTOR
|
||||
|
|
@ -1103,7 +1117,7 @@ void handle_reset( void ) __attribute__((section(".text.handle_reset")));
|
|||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if FUNCONF_ISR_IN_RAM
|
||||
#define VECTOR_HANDLER_SECTION ".data.vector_handler"
|
||||
|
|
@ -1112,6 +1126,7 @@ void handle_reset( void ) __attribute__((section(".text.handle_reset")));
|
|||
#endif
|
||||
|
||||
|
||||
#if !FUNCONF_OVERRIDE_STARTUP
|
||||
|
||||
#if defined( CH32V003 ) || defined( CH32X03x ) || defined(CH32V00x)
|
||||
|
||||
|
|
@ -1129,18 +1144,19 @@ void handle_reset( void )
|
|||
// Setup the interrupt vector, processor status and INTSYSCR.
|
||||
|
||||
#if FUNCONF_ENABLE_HPE // Enabled nested and hardware (HPE) stack, since it's really good on the x035.
|
||||
" li t0, 0x1888\n\
|
||||
csrs mstatus, t0\n"
|
||||
" li t0, 0x0b\n\
|
||||
csrw 0x804, t0\n"
|
||||
" li a3, 0x1888\n\
|
||||
csrs mstatus, a3\n"
|
||||
" li a3, 0x0b\n\
|
||||
csrw 0x804, a3\n"
|
||||
#else
|
||||
" li a0, 0x1880\n\
|
||||
csrw mstatus, a0\n"
|
||||
#endif
|
||||
" li a3, 0x3\n\
|
||||
la a0, InterruptVector\n\
|
||||
or a0, a0, a3\n\
|
||||
csrw mtvec, a0\n"
|
||||
#if !defined(FUNCONF_TINYVECTOR) || !FUNCONF_TINYVECTOR
|
||||
" la a3, InterruptVector\n\
|
||||
ori a3, a3, 3\n\
|
||||
csrw mtvec, a3\n"
|
||||
#endif
|
||||
: : : "a0", "a3", "memory");
|
||||
|
||||
// Careful: Use registers to prevent overwriting of self-data.
|
||||
|
|
@ -1218,8 +1234,8 @@ void handle_reset( void )
|
|||
la a1, _highcode_vma_start\n\
|
||||
la a2, _highcode_vma_end\n\
|
||||
bgeu a1, a2, 2f\n\
|
||||
1: lw t0, (a0)\n\
|
||||
sw t0, (a1)\n\
|
||||
1: lw a3, (a0)\n\
|
||||
sw a3, (a1)\n\
|
||||
addi a0, a0, 4\n\
|
||||
addi a1, a1, 4\n\
|
||||
bltu a1, a2, 1b\n\
|
||||
|
|
@ -1230,8 +1246,8 @@ void handle_reset( void )
|
|||
la a1, _data_vma\n\
|
||||
la a2, _edata\n\
|
||||
beq a1, a2, 2f\n\
|
||||
1: lw t0, 0(a0)\n\
|
||||
sw t0, 0(a1)\n\
|
||||
1: lw a3, 0(a0)\n\
|
||||
sw a3, 0(a1)\n\
|
||||
addi a0, a0, 4\n\
|
||||
addi a1, a1, 4\n\
|
||||
bltu a1, a2, 1b\n\
|
||||
|
|
@ -1248,27 +1264,33 @@ void handle_reset( void )
|
|||
|
||||
// Setup the interrupt vector, processor status and INTSYSCR.
|
||||
asm volatile(
|
||||
" li t0, 0x1f\n\
|
||||
csrw 0xbc0, t0\n"
|
||||
" li a3, 0x1f\n\
|
||||
csrw 0xbc0, a3\n"
|
||||
|
||||
#if defined(CH32V30x) && !defined( DISABLED_FLOAT )
|
||||
" li t0, 0x7888\n\
|
||||
csrs mstatus, t0\n"
|
||||
" li a3, 0x7888\n\
|
||||
csrs mstatus, a3\n"
|
||||
#else
|
||||
" li t0, 0x1888\n\
|
||||
csrs mstatus, t0\n"
|
||||
" li a3, 0x1888\n\
|
||||
csrs mstatus, a3\n"
|
||||
#endif
|
||||
|
||||
#if FUNCONF_ENABLE_HPE // Enabled nested and hardware (HPE) stack, since it's really good on the x035.
|
||||
" li t0, 0x0b\n\
|
||||
csrw 0x804, t0\n"
|
||||
" li a3, 0x0b\n\
|
||||
csrw 0x804, a3\n"
|
||||
#endif
|
||||
" la t0, InterruptVector\n\
|
||||
ori t0, t0, 3\n\
|
||||
csrw mtvec, t0\n"
|
||||
: : [InterruptVector]"r"(InterruptVector) : "t0", "memory"
|
||||
: : : "a3", "memory"
|
||||
);
|
||||
|
||||
#if !defined(FUNCONF_TINYVECTOR) || !FUNCONF_TINYVECTOR
|
||||
asm volatile(
|
||||
" la a3, InterruptVector\n\
|
||||
ori a3, a3, 3\n\
|
||||
csrw mtvec, a3\n"
|
||||
: : [InterruptVector]"r"(InterruptVector) : "a3", "memory"
|
||||
);
|
||||
#endif
|
||||
|
||||
#if defined( FUNCONF_SYSTICK_USE_HCLK ) && FUNCONF_SYSTICK_USE_HCLK && !defined(CH32V10x)
|
||||
SysTick->CTLR = 5;
|
||||
#else
|
||||
|
|
@ -1302,19 +1324,19 @@ void handle_reset( void )
|
|||
.option push\n\
|
||||
.option norelax\n\
|
||||
la gp, __global_pointer$\n\
|
||||
.option pop\n\
|
||||
csrr a7, mhartid\n\
|
||||
bnez a7, 5f\n\
|
||||
la sp, _v3f_stack\n\
|
||||
j 3f\n\
|
||||
5: la sp, _v5f_stack\n"
|
||||
"3:\n"
|
||||
.option pop\n"
|
||||
);
|
||||
|
||||
asm volatile(
|
||||
#if __GNUC__ > 10
|
||||
" .option arch, +zicsr\n"
|
||||
#endif
|
||||
" csrr a7, mhartid\n\
|
||||
bnez a7, 5f\n\
|
||||
la sp, _v3f_stack\n\
|
||||
j 3f\n\
|
||||
5: la sp, _v5f_stack\n"
|
||||
"3:\n"
|
||||
);
|
||||
|
||||
// Careful: Use registers to prevent overwriting of self-data.
|
||||
|
|
@ -1335,8 +1357,8 @@ void handle_reset( void )
|
|||
la a1, _itcm_vma_start\n\
|
||||
la a2, _itcm_vma_end\n\
|
||||
bgeu a1, a2, 2f\n\
|
||||
1: lw t0, (a0)\n\
|
||||
sw t0, (a1)\n\
|
||||
1: lw a3, (a0)\n\
|
||||
sw a3, (a1)\n\
|
||||
addi a0, a0, 4\n\
|
||||
addi a1, a1, 4\n\
|
||||
bltu a1, a2, 1b\n\
|
||||
|
|
@ -1346,8 +1368,8 @@ void handle_reset( void )
|
|||
la a1, _dtcm_vma_start\n\
|
||||
la a2, _dtcm_vma_end\n\
|
||||
bgeu a1, a2, 2f\n\
|
||||
1: lw t0, (a0)\n\
|
||||
sw t0, (a1)\n\
|
||||
1: lw a3, (a0)\n\
|
||||
sw a3, (a1)\n\
|
||||
addi a0, a0, 4\n\
|
||||
addi a1, a1, 4\n\
|
||||
bltu a1, a2, 1b\n\
|
||||
|
|
@ -1357,8 +1379,8 @@ void handle_reset( void )
|
|||
la a1, _data_vma\n\
|
||||
la a2, _edata\n\
|
||||
beq a1, a2, 2f\n\
|
||||
1: lw t0, 0(a0)\n\
|
||||
sw t0, 0(a1)\n\
|
||||
1: lw a3, 0(a0)\n\
|
||||
sw a3, 0(a1)\n\
|
||||
addi a0, a0, 4\n\
|
||||
addi a1, a1, 4\n\
|
||||
bltu a1, a2, 1b\n\
|
||||
|
|
@ -1376,40 +1398,47 @@ void handle_reset( void )
|
|||
// Setup the interrupt vector, processor status and INTSYSCR.
|
||||
asm volatile(
|
||||
" bnez a7, 5f\n\
|
||||
la t0, 0x12370303\n\
|
||||
csrw 0xbc0, t0\n\
|
||||
la a3, 0x12370303\n\
|
||||
csrw 0xbc0, a3\n\
|
||||
j 3f\n\
|
||||
5: la t0, 0x12378400\n\
|
||||
csrw 0xbc0, t0\n\
|
||||
5: la a3, 0x12378400\n\
|
||||
csrw 0xbc0, a3\n\
|
||||
3:\n"
|
||||
|
||||
#if !defined( DISABLED_FLOAT )
|
||||
" li t0, 0x7888\n\
|
||||
csrs mstatus, t0\n"
|
||||
" li a3, 0x7888\n\
|
||||
csrs mstatus, a3\n"
|
||||
#else
|
||||
" li t0, 0x1888\n\
|
||||
csrs mstatus, t0\n"
|
||||
" li a3, 0x1888\n\
|
||||
csrs mstatus, a3\n"
|
||||
#endif
|
||||
|
||||
#if FUNCONF_ENABLE_HPE
|
||||
" bnez a7, 5f\n\
|
||||
li t0, 0x01\n\
|
||||
csrw 0xBC1, t0\n\
|
||||
li t0, 0x0b\n\
|
||||
csrw 0x804, t0\n\
|
||||
li a3, 0x01\n\
|
||||
csrw 0xBC1, a3\n\
|
||||
li a3, 0x0b\n\
|
||||
csrw 0x804, a3\n\
|
||||
j 3f\n\
|
||||
5: li t0, 0x07\n\
|
||||
csrw 0xBC1, t0\n\
|
||||
li t0, 0x0b\n\
|
||||
csrw 0x804, t0\n\
|
||||
5: li a3, 0x07\n\
|
||||
csrw 0xBC1, a3\n\
|
||||
li a3, 0x0b\n\
|
||||
csrw 0x804, a3\n\
|
||||
3:\n"
|
||||
#endif
|
||||
" la t0, InterruptVector\n\
|
||||
ori t0, t0, 3\n\
|
||||
csrw mtvec, t0\n"
|
||||
: : [InterruptVector]"r"(InterruptVector) : "t0", "memory"
|
||||
: : : "a3", "memory"
|
||||
);
|
||||
|
||||
|
||||
#if !defined(FUNCONF_TINYVECTOR) || !FUNCONF_TINYVECTOR
|
||||
asm volatile(
|
||||
" la a3, InterruptVector\n\
|
||||
ori a3, a3, 3\n\
|
||||
csrw mtvec, a3\n"
|
||||
: : [InterruptVector]"r"(InterruptVector) : "a3", "memory"
|
||||
);
|
||||
#endif
|
||||
|
||||
#if defined( FUNCONF_SYSTICK_USE_HCLK ) && FUNCONF_SYSTICK_USE_HCLK
|
||||
SysTick->CTLR = 5;
|
||||
#else
|
||||
|
|
@ -1431,6 +1460,7 @@ void handle_reset( void )
|
|||
: : [main]"r"(main), [start_v5f]"r"(start_v5f) );
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined( __riscv_float_abi_double )
|
||||
#define FLOAD( src, offset, dst ) \
|
||||
|
|
@ -1651,14 +1681,22 @@ WEAK int putchar(int c)
|
|||
extern int USBFS_SendEndpointNEW( int endp, uint8_t* data, int len, int copy);
|
||||
WEAK int _write(int fd, const char *buf, int size)
|
||||
{
|
||||
while(USBFS_SendEndpointNEW(3, (uint8_t*)buf, size, 1) == -1); // -1 == busy
|
||||
if(USBFS_SendEndpointNEW(3, (uint8_t*)buf, size, /*copy*/1) == -1) { // -1 == busy
|
||||
// wait for 1ms to try again once more
|
||||
Delay_Ms(1);
|
||||
USBFS_SendEndpointNEW(3, (uint8_t*)buf, size, /*copy*/1);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
WEAK int putchar(int c)
|
||||
{
|
||||
uint8_t single = c;
|
||||
while(USBFS_SendEndpointNEW(3, &single, 1, 1) == -1); // -1 == busy
|
||||
if(USBFS_SendEndpointNEW(3, &single, 1, /*copy*/1) == -1) { // -1 == busy
|
||||
// wait for 1ms to try again once more
|
||||
Delay_Ms(1);
|
||||
USBFS_SendEndpointNEW(3, &single, 1, /*copy*/1);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1850,10 +1888,10 @@ void DelaySysTick( uint32_t n )
|
|||
#if defined(CH32V003) || defined(CH32V00x)
|
||||
uint32_t targend = SysTick->CNT + n;
|
||||
while( ((int32_t)( SysTick->CNT - targend )) < 0 );
|
||||
#elif defined(CH32V20x) || defined(CH32V30x) || defined(CH32X03x) || defined(CH32L103) || defined(CH582_CH583) || defined(CH591_CH592) || defined(CH32H41x)
|
||||
#elif defined(CH32V20x) || defined(CH32V30x) || defined(CH32X03x) || defined(CH32L103) || defined(CH582_CH583) || defined(CH591_CH592)
|
||||
uint64_t targend = SysTick->CNT + n;
|
||||
while( ((int64_t)( SysTick->CNT - targend )) < 0 );
|
||||
#elif defined(CH32V10x) || defined(CH570_CH572) || defined(CH584_CH585)
|
||||
#elif defined(CH32V10x) || defined(CH570_CH572) || defined(CH584_CH585) || defined(CH32H41x)
|
||||
uint32_t targend = SysTick->CNTL + n;
|
||||
while( ((int32_t)( SysTick->CNTL - targend )) < 0 );
|
||||
#elif defined(CH571_CH573)
|
||||
|
|
@ -1865,6 +1903,44 @@ void DelaySysTick( uint32_t n )
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Computes a 64-bit SysTick timestamp from the current CPU.
|
||||
// If the CPU supports a 64-bit SysTick, then it will make sure it
|
||||
// did not race condition. If it's a 32-bit SysTick, a virtual
|
||||
// high word will be generated and incremented any time a wraparound
|
||||
// is detected.
|
||||
//
|
||||
// In general, please do not use this function. In 99% of cases, using 32-bit
|
||||
// functions with proper rollover is better. For instance you can use
|
||||
// TimeElapsed32( start, end ).
|
||||
//
|
||||
// This should only be used when you must act on time periods exceeding 2^31
|
||||
// ticks.
|
||||
//
|
||||
uint64_t funSysTick64( void )
|
||||
{
|
||||
uint32_t base = funSysTick32();
|
||||
#ifdef funSysTickHigh
|
||||
|
||||
uint32_t high = funSysTickHigh();
|
||||
uint32_t check = funSysTick32();
|
||||
|
||||
// If and only if check is higher than base can we guarantee high is
|
||||
// valid and matches the check.
|
||||
if( check >= base )
|
||||
return ((uint64_t)high<<32) | check;
|
||||
|
||||
// Else we need a new high.
|
||||
return (((uint64_t)(funSysTickHigh()))<<32) | check;
|
||||
#else
|
||||
static uint32_t lastBase;
|
||||
static uint32_t high;
|
||||
if( base < lastBase ) { high++; }
|
||||
lastBase = base;
|
||||
return ((uint64_t)high<<32) | base;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(CH32H41x)
|
||||
void StartV5F(v5f_main function)
|
||||
{
|
||||
|
|
@ -1956,6 +2032,14 @@ void SystemInit( void )
|
|||
#define CLK_SOURCE_CH5XX CLK_SOURCE_PLL_60MHz
|
||||
#endif
|
||||
#if (defined(CH570_CH572) || defined(CH584_CH585))
|
||||
#if (defined(CH584_CH585) && CLK_SOURCE_CH5XX == 0xff)
|
||||
#warning "The ch584/5 does not support an exact 60MHz setting. Please pick an availabe clock source from the SYS_CLKTypeDef enum in ch5xxhw.h"
|
||||
#warning "Choosing CLK_SOURCE_HSE_PLL_62_4MHz for now"
|
||||
#undef CLK_SOURCE_CH5XX
|
||||
#define CLK_SOURCE_CH5XX CLK_SOURCE_HSE_PLL_62_4MHz
|
||||
#undef FUNCONF_SYSTEM_CORE_CLOCK
|
||||
#define FUNCONF_SYSTEM_CORE_CLOCK 62400000
|
||||
#endif
|
||||
SYS_CLKTypeDef sc = CLK_SOURCE_CH5XX;
|
||||
|
||||
if(sc == RB_CLK_SYS_MOD) // LSI
|
||||
|
|
@ -1966,6 +2050,7 @@ void SystemInit( void )
|
|||
}
|
||||
else
|
||||
{
|
||||
#if defined(CH570_CH572)
|
||||
if((sc & RB_CLK_SYS_MOD) == 0x40) // PLL div
|
||||
{
|
||||
SYS_SAFE_ACCESS(
|
||||
|
|
@ -1980,6 +2065,56 @@ void SystemInit( void )
|
|||
R8_FLASH_CFG = (sc & 0x1F) ? 0x02 : 0x07;
|
||||
);
|
||||
}
|
||||
#else
|
||||
if( sc & 0x100) // PLL
|
||||
{
|
||||
if( (sc&0x1F) == 0 ) // HSI@16MHz, HSE@32MHz
|
||||
{
|
||||
SYS_SAFE_ACCESS(
|
||||
R8_FLASH_SCK = R8_FLASH_SCK|(1<<4);
|
||||
R8_FLASH_CFG = 0x07;
|
||||
);
|
||||
}
|
||||
else if( (sc&0x1F) < 10 ) // HSI/HSE+PLL>=39MHz
|
||||
{
|
||||
SYS_SAFE_ACCESS(
|
||||
R8_FLASH_SCK = R8_FLASH_SCK & (~(1<<4));
|
||||
R8_FLASH_CFG = 0x01; // Probably a divider value for flash clock
|
||||
);
|
||||
}
|
||||
else if( (sc&0x1F) < 16 ) // HSI/HSE+PLL>19.5MHz
|
||||
{
|
||||
SYS_SAFE_ACCESS(
|
||||
R8_FLASH_SCK = R8_FLASH_SCK & (~(1<<4));
|
||||
R8_FLASH_CFG = 0x02;
|
||||
);
|
||||
}
|
||||
else // HSI/HSE+PLL<=19.5MHz
|
||||
{
|
||||
SYS_SAFE_ACCESS(
|
||||
R8_FLASH_SCK = R8_FLASH_SCK|(1<<4);
|
||||
R8_FLASH_CFG = 0x03;
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( (sc&0x1F) < 8 ) //HSI>=4MHz, HSE>=6.4Mhz
|
||||
{
|
||||
SYS_SAFE_ACCESS(
|
||||
R8_FLASH_SCK = R8_FLASH_SCK & (~(1<<4));
|
||||
R8_FLASH_CFG = 0x51;
|
||||
);
|
||||
}
|
||||
else // HSI=2MHz,1MHz, HSE=4Mhz,2Mhz
|
||||
{
|
||||
SYS_SAFE_ACCESS(
|
||||
R8_FLASH_SCK = R8_FLASH_SCK & (~(1<<4));
|
||||
R8_FLASH_CFG = 0x57;
|
||||
);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
SYS_SAFE_ACCESS(
|
||||
#ifdef CH570_CH572
|
||||
R8_CLK_SYS_CFG = sc;
|
||||
|
|
@ -2176,6 +2311,22 @@ int funAnalogRead( int nAnalogNumber )
|
|||
}
|
||||
#endif
|
||||
|
||||
void funRebootToBootloader()
|
||||
{
|
||||
#if defined(CH32V003) || defined(CH32V00x) || defined(CH32X03x)
|
||||
FLASH->BOOT_MODEKEYR = FLASH_KEY1;
|
||||
FLASH->BOOT_MODEKEYR = FLASH_KEY2;
|
||||
FLASH->STATR = 1<<14;
|
||||
RCC->RSTSCKR |= 0x1000000;
|
||||
PFIC->SCTLR = 1<<31;
|
||||
#elif defined(CH5xx)
|
||||
SYS_SAFE_ACCESS(
|
||||
R8_RESET_STATUS = 1<<7;
|
||||
R8_RST_WDOG_CTRL = 5;
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
// C++ Support
|
||||
|
||||
#ifdef CPLUSPLUS
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue