2024-12-02 16:26:55 +08:00
/********************************** (C) COPYRIGHT *******************************
* File Name : CH59x_SYS . c
* Author : WCH
* Version : V1 .2
* Date : 2021 / 11 / 17
* Description
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright ( c ) 2021 Nanjing Qinheng Microelectronics Co . , Ltd .
2024-12-08 11:32:01 +08:00
* Attention : This software ( modified or not ) and binary are used for
2024-12-02 16:26:55 +08:00
* microcontroller manufactured by Nanjing Qinheng Microelectronics .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "CH59x_common.h"
/*********************************************************************
* @ fn SetSysClock
*
* @ brief <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ϵ ͳ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʱ <EFBFBD> <EFBFBD>
*
* @ param sc - ϵ ͳ ʱ <EFBFBD> <EFBFBD> Դ ѡ <EFBFBD> <EFBFBD> refer to SYS_CLKTypeDef
*
* @ return none
*/
__HIGH_CODE
void SetSysClock ( SYS_CLKTypeDef sc )
{
sys_safe_access_enable ( ) ;
R8_PLL_CONFIG & = ~ ( 1 < < 5 ) ; //
sys_safe_access_disable ( ) ;
2024-12-08 11:32:01 +08:00
if ( sc & 0x20 ) // HSE div
2024-12-02 16:26:55 +08:00
{
sys_safe_access_enable ( ) ;
R32_CLK_SYS_CFG = ( 0 < < 6 ) | ( sc & 0x1f ) | RB_TX_32M_PWR_EN | RB_PLL_PWR_EN ;
__nop ( ) ;
__nop ( ) ;
__nop ( ) ;
__nop ( ) ;
sys_safe_access_disable ( ) ;
sys_safe_access_enable ( ) ;
SAFEOPERATE ;
R8_FLASH_CFG = 0 X51 ;
sys_safe_access_disable ( ) ;
}
2024-12-08 11:32:01 +08:00
else if ( sc & 0x40 ) // PLL div
2024-12-02 16:26:55 +08:00
{
sys_safe_access_enable ( ) ;
R32_CLK_SYS_CFG = ( 1 < < 6 ) | ( sc & 0x1f ) | RB_TX_32M_PWR_EN | RB_PLL_PWR_EN ;
__nop ( ) ;
__nop ( ) ;
__nop ( ) ;
__nop ( ) ;
sys_safe_access_disable ( ) ;
sys_safe_access_enable ( ) ;
R8_FLASH_CFG = 0 X52 ;
sys_safe_access_disable ( ) ;
}
else
{
sys_safe_access_enable ( ) ;
R32_CLK_SYS_CFG | = RB_CLK_SYS_MOD ;
sys_safe_access_disable ( ) ;
}
2024-12-08 11:32:01 +08:00
// <20> <> <EFBFBD> <EFBFBD> FLASH clk<6C> <6B> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2024-12-02 16:26:55 +08:00
sys_safe_access_enable ( ) ;
R8_PLL_CONFIG | = 1 < < 7 ;
sys_safe_access_disable ( ) ;
}
/*********************************************************************
* @ fn GetSysClock
*
* @ brief <EFBFBD> <EFBFBD> ȡ <EFBFBD> <EFBFBD> ǰ ϵ ͳ ʱ <EFBFBD> <EFBFBD>
*
* @ param none
*
* @ return Hz
*/
uint32_t GetSysClock ( void )
{
uint16_t rev ;
rev = R32_CLK_SYS_CFG & 0xff ;
2024-12-08 11:32:01 +08:00
if ( ( rev & 0x40 ) = = ( 0 < < 6 ) )
2024-12-02 16:26:55 +08:00
{ // 32M<32> <4D> <EFBFBD> з<EFBFBD> Ƶ
return ( 32000000 / ( rev & 0x1f ) ) ;
}
2024-12-08 11:32:01 +08:00
else if ( ( rev & RB_CLK_SYS_MOD ) = = ( 1 < < 6 ) )
2024-12-02 16:26:55 +08:00
{ // PLL<4C> <4C> <EFBFBD> з<EFBFBD> Ƶ
return ( 480000000 / ( rev & 0x1f ) ) ;
}
else
{ // 32K<32> <4B> <EFBFBD> <EFBFBD> Ƶ
return ( 32000 ) ;
}
}
/*********************************************************************
* @ fn SYS_GetInfoSta
*
* @ brief <EFBFBD> <EFBFBD> ȡ <EFBFBD> <EFBFBD> ǰ ϵ ͳ <EFBFBD> <EFBFBD> Ϣ ״ ̬
*
* @ param i - refer to SYS_InfoStaTypeDef
*
* @ return <EFBFBD> Ƿ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*/
uint8_t SYS_GetInfoSta ( SYS_InfoStaTypeDef i )
{
2024-12-08 11:32:01 +08:00
if ( i = = STA_SAFEACC_ACT )
2024-12-02 16:26:55 +08:00
{
return ( R8_SAFE_ACCESS_SIG & RB_SAFE_ACC_ACT ) ;
}
else
{
return ( R8_GLOB_CFG_INFO & ( 1 < < i ) ) ;
}
}
/*********************************************************************
* @ fn SYS_ResetExecute
*
* @ brief ִ <EFBFBD> <EFBFBD> ϵ ͳ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> λ
*
* @ param none
*
* @ return none
*/
__HIGH_CODE
void SYS_ResetExecute ( void )
{
FLASH_ROM_SW_RESET ( ) ;
sys_safe_access_enable ( ) ;
R8_RST_WDOG_CTRL | = RB_SOFTWARE_RESET ;
sys_safe_access_disable ( ) ;
}
/*********************************************************************
* @ fn SYS_DisableAllIrq
*
* @ brief <EFBFBD> ر <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ж ϣ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ǰ <EFBFBD> ж <EFBFBD> ֵ
*
* @ param pirqv - <EFBFBD> <EFBFBD> ǰ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ж <EFBFBD> ֵ
*
* @ return none
*/
void SYS_DisableAllIrq ( uint32_t * pirqv )
{
2024-12-08 11:32:01 +08:00
* pirqv = ( PFIC - > ISR [ 0 ] > > 8 ) | ( PFIC - > ISR [ 1 ] < < 24 ) ;
2024-12-02 16:26:55 +08:00
PFIC - > IRER [ 0 ] = 0xffffffff ;
PFIC - > IRER [ 1 ] = 0xffffffff ;
}
/*********************************************************************
* @ fn SYS_RecoverIrq
*
* @ brief <EFBFBD> ָ <EFBFBD> ֮ ǰ <EFBFBD> ر յ <EFBFBD> <EFBFBD> ж <EFBFBD> ֵ
*
* @ param irq_status - <EFBFBD> <EFBFBD> ǰ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ж <EFBFBD> ֵ
*
* @ return none
*/
void SYS_RecoverIrq ( uint32_t irq_status )
{
PFIC - > IENR [ 0 ] = ( irq_status < < 8 ) ;
PFIC - > IENR [ 1 ] = ( irq_status > > 24 ) ;
}
/*********************************************************************
* @ fn SYS_GetSysTickCnt
*
* @ brief <EFBFBD> <EFBFBD> ȡ <EFBFBD> <EFBFBD> ǰ ϵ ͳ ( SYSTICK ) <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ֵ
*
* @ param none
*
* @ return <EFBFBD> <EFBFBD> ǰ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ֵ
*/
uint32_t SYS_GetSysTickCnt ( void )
{
uint32_t val ;
val = SysTick - > CNT ;
return ( val ) ;
}
/*********************************************************************
* @ fn WWDG_ITCfg
*
* @ brief <EFBFBD> <EFBFBD> <EFBFBD> Ź <EFBFBD> <EFBFBD> <EFBFBD> ʱ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ж <EFBFBD> ʹ <EFBFBD> <EFBFBD>
*
* @ param s - <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ <EFBFBD> <EFBFBD> ж <EFBFBD>
*
* @ return none
*/
void WWDG_ITCfg ( FunctionalState s )
{
uint8_t ctrl = R8_RST_WDOG_CTRL ;
2024-12-08 11:32:01 +08:00
if ( s = = DISABLE )
2024-12-02 16:26:55 +08:00
{
ctrl & = ~ RB_WDOG_INT_EN ;
}
else
{
ctrl | = RB_WDOG_INT_EN ;
}
sys_safe_access_enable ( ) ;
R8_RST_WDOG_CTRL = ctrl ;
sys_safe_access_disable ( ) ;
}
/*********************************************************************
* @ fn WWDG_ResetCfg
*
* @ brief <EFBFBD> <EFBFBD> <EFBFBD> Ź <EFBFBD> <EFBFBD> <EFBFBD> ʱ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> λ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*
* @ param s - <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ <EFBFBD> <EFBFBD> <EFBFBD> λ
*
* @ return none
*/
void WWDG_ResetCfg ( FunctionalState s )
{
uint8_t ctrl = R8_RST_WDOG_CTRL ;
2024-12-08 11:32:01 +08:00
if ( s = = DISABLE )
2024-12-02 16:26:55 +08:00
{
ctrl & = ~ RB_WDOG_RST_EN ;
}
else
{
ctrl | = RB_WDOG_RST_EN ;
}
sys_safe_access_enable ( ) ;
R8_RST_WDOG_CTRL = ctrl ;
sys_safe_access_disable ( ) ;
}
/*********************************************************************
* @ fn WWDG_ClearFlag
*
* @ brief <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ź <EFBFBD> <EFBFBD> ж ϱ <EFBFBD> ־ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ¼ <EFBFBD> <EFBFBD> ؼ <EFBFBD> <EFBFBD> <EFBFBD> ֵ Ҳ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*
* @ param none
*
* @ return none
*/
void WWDG_ClearFlag ( void )
{
sys_safe_access_enable ( ) ;
R8_RST_WDOG_CTRL | = RB_WDOG_INT_FLAG ;
sys_safe_access_disable ( ) ;
}
/*********************************************************************
* @ fn HardFault_Handler
*
* @ brief Ӳ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ж ϣ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ִ <EFBFBD> и <EFBFBD> λ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> λ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ <EFBFBD> ϵ 縴 λ
*
* @ param none
*
* @ return none
*/
__INTERRUPT
__HIGH_CODE
2024-12-08 11:32:01 +08:00
__attribute__ ( ( weak ) ) void HardFault_Handler ( void )
2024-12-02 16:26:55 +08:00
{
2024-12-08 11:32:01 +08:00
// https://www.cnblogs.com/gscw/p/18159920
// <20> <> <EFBFBD> غ<EFBFBD> <D8BA> <EFBFBD> <EFBFBD> <EFBFBD> PC ָ<> <D6B8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͬʱʹ <CAB1> á<EFBFBD> <C3A1> <EFBFBD> <EFBFBD> غ<EFBFBD> <D8BA> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> <D2AA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʹ <EFBFBD> ò<EFBFBD> <C3B2> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 壬<EFBFBD> <E5A3AC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ӡֵΪ<D6B5> գ <EFBFBD> <D5A3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> ʹ <EFBFBD> <CAB9> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
struct __MEMORY_CTL
{
struct __MEMORY_CTL * pNext ;
uint16_t len ;
uint16_t used ;
} ;
typedef struct __MEMORY_CTL MemoryCtl ;
extern MemoryCtl * MemCtlStart ;
extern MemoryCtl * MemCtlEnd ;
MemoryCtl * MemHead ;
MemHead = MemCtlStart ;
while ( MemHead ! = MemCtlEnd )
{
printf ( " |%8x,%8x,%8d..... \n " , MemHead - > used , ( uint32_t ) MemHead ,
( uint32_t ) ( MemHead - > pNext ) - ( uint32_t ) MemHead - sizeof ( struct __MEMORY_CTL ) ) ;
MemHead = MemHead - > pNext ;
}
printf ( " \n " ) ;
uint32_t v_mepc , v_mcause , v_mtval ;
printf ( " hardfault \n " ) ;
v_mepc = __get_MEPC ( ) ;
v_mcause = __get_MCAUSE ( ) ;
v_mtval = __get_MTVAL ( ) ;
printf ( " mepc:%08x \n " , v_mepc ) ;
printf ( " mcause:%08x \n " , v_mcause ) ;
printf ( " mtval:%08x \n " , v_mtval ) ;
#if 0
2024-12-02 16:26:55 +08:00
FLASH_ROM_SW_RESET ( ) ;
sys_safe_access_enable ( ) ;
R16_INT32K_TUNE = 0xFFFF ;
sys_safe_access_disable ( ) ;
sys_safe_access_enable ( ) ;
R8_RST_WDOG_CTRL | = RB_SOFTWARE_RESET ;
sys_safe_access_disable ( ) ;
2024-12-08 11:32:01 +08:00
# endif
while ( 1 ) ;
2024-12-02 16:26:55 +08:00
}
/*********************************************************************
* @ fn mDelayuS
*
* @ brief uS <EFBFBD> <EFBFBD> ʱ
*
* @ param t - ʱ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*
* @ return none
*/
__HIGH_CODE
void mDelayuS ( uint16_t t )
{
uint32_t i ;
2024-12-08 11:32:01 +08:00
# if (FREQ_SYS == 80000000)
2024-12-02 16:26:55 +08:00
i = t * 20 ;
2024-12-08 11:32:01 +08:00
# elif (FREQ_SYS == 60000000)
2024-12-02 16:26:55 +08:00
i = t * 15 ;
2024-12-08 11:32:01 +08:00
# elif (FREQ_SYS == 48000000)
2024-12-02 16:26:55 +08:00
i = t * 12 ;
2024-12-08 11:32:01 +08:00
# elif (FREQ_SYS == 40000000)
2024-12-02 16:26:55 +08:00
i = t * 10 ;
2024-12-08 11:32:01 +08:00
# elif (FREQ_SYS == 32000000)
2024-12-02 16:26:55 +08:00
i = t < < 3 ;
2024-12-08 11:32:01 +08:00
# elif (FREQ_SYS == 24000000)
2024-12-02 16:26:55 +08:00
i = t * 6 ;
2024-12-08 11:32:01 +08:00
# elif (FREQ_SYS == 16000000)
2024-12-02 16:26:55 +08:00
i = t < < 2 ;
2024-12-08 11:32:01 +08:00
# elif (FREQ_SYS == 8000000)
2024-12-02 16:26:55 +08:00
i = t < < 1 ;
2024-12-08 11:32:01 +08:00
# elif (FREQ_SYS == 4000000)
2024-12-02 16:26:55 +08:00
i = t ;
2024-12-08 11:32:01 +08:00
# elif (FREQ_SYS == 2000000)
2024-12-02 16:26:55 +08:00
i = t > > 1 ;
2024-12-08 11:32:01 +08:00
# elif (FREQ_SYS == 1000000)
2024-12-02 16:26:55 +08:00
i = t > > 2 ;
# else
i = t < < 1 ;
# endif
do
{
__nop ( ) ;
2024-12-08 11:32:01 +08:00
} while ( - - i ) ;
2024-12-02 16:26:55 +08:00
}
/*********************************************************************
* @ fn mDelaymS
*
* @ brief mS <EFBFBD> <EFBFBD> ʱ
*
* @ param t - ʱ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*
* @ return none
*/
__HIGH_CODE
void mDelaymS ( uint16_t t )
{
uint16_t i ;
2024-12-08 11:32:01 +08:00
for ( i = 0 ; i < t ; i + + )
2024-12-02 16:26:55 +08:00
{
mDelayuS ( 1000 ) ;
}
}
# ifdef DEBUG
int _write ( int fd , char * buf , int size )
{
int i ;
2024-12-08 11:32:01 +08:00
for ( i = 0 ; i < size ; i + + )
2024-12-02 16:26:55 +08:00
{
# if DEBUG == Debug_UART0
2024-12-08 11:32:01 +08:00
while ( R8_UART0_TFC = = UART_FIFO_SIZE ) ; /* <20> ȴ<EFBFBD> <C8B4> <EFBFBD> <EFBFBD> ݷ<EFBFBD> <DDB7> <EFBFBD> */
R8_UART0_THR = * buf + + ; /* <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> */
2024-12-02 16:26:55 +08:00
# elif DEBUG == Debug_UART1
2024-12-08 11:32:01 +08:00
while ( R8_UART1_TFC = = UART_FIFO_SIZE ) ; /* <20> ȴ<EFBFBD> <C8B4> <EFBFBD> <EFBFBD> ݷ<EFBFBD> <DDB7> <EFBFBD> */
R8_UART1_THR = * buf + + ; /* <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> */
2024-12-02 16:26:55 +08:00
# elif DEBUG == Debug_UART2
2024-12-08 11:32:01 +08:00
while ( R8_UART2_TFC = = UART_FIFO_SIZE ) ; /* <20> ȴ<EFBFBD> <C8B4> <EFBFBD> <EFBFBD> ݷ<EFBFBD> <DDB7> <EFBFBD> */
R8_UART2_THR = * buf + + ; /* <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> */
# elif DEBUG == Debug_UART3
while ( R8_UART3_TFC = = UART_FIFO_SIZE ) ; /* <20> ȴ<EFBFBD> <C8B4> <EFBFBD> <EFBFBD> ݷ<EFBFBD> <DDB7> <EFBFBD> */
R8_UART3_THR = * buf + + ; /* <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> */
2024-12-02 16:26:55 +08:00
# endif
}
return size ;
}
# endif
2024-12-11 14:38:19 +08:00
// // https://www.cnblogs.com/debugdabiaoge/p/18543792
// __HIGH_CODE
// void *__wrap_memcpy(void *dst ,void *src, size_t size)
// {
// __MCPY(dst, src, (void *)((uint32_t)src+size));
// return dst;
// }
2024-12-11 14:36:25 +08:00
2024-12-02 16:26:55 +08:00
/*********************************************************************
* @ fn _sbrk
*
* @ brief Change the spatial position of data segment .
*
* @ return size : Data length
*/
2024-12-08 11:32:01 +08:00
__attribute__ ( ( used ) ) void * _sbrk ( ptrdiff_t incr )
2024-12-02 16:26:55 +08:00
{
extern char _end [ ] ;
extern char _heap_end [ ] ;
static char * curbrk = _end ;
if ( ( curbrk + incr < _end ) | | ( curbrk + incr > _heap_end ) )
2024-12-08 11:32:01 +08:00
return NULL - 1 ;
2024-12-02 16:26:55 +08:00
curbrk + = incr ;
return curbrk - incr ;
}