636 lines
		
	
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			636 lines
		
	
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /********************************** (C) COPYRIGHT  *******************************
 | |
|  * File Name          : core_riscv.h
 | |
|  * Author             : WCH
 | |
|  * Version            : V1.1.0
 | |
|  * Date               : 2023/04/10
 | |
|  * Description        : CH592 RISC-V Core Peripheral Access Layer Header File
 | |
|  *********************************************************************************
 | |
|  * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
 | |
|  * Attention: This software (modified or not) and binary are used for 
 | |
|  * microcontroller manufactured by Nanjing Qinheng Microelectronics.
 | |
|  *******************************************************************************/
 | |
| #ifndef __CORE_RV3A_H__
 | |
| #define __CORE_RV3A_H__
 | |
| 
 | |
| #ifdef __cplusplus
 | |
| extern "C" {
 | |
| #endif
 | |
| 
 | |
| /* IO definitions */
 | |
| #ifdef __cplusplus
 | |
|   #define __I    volatile  /*!< defines 'read only' permissions      */
 | |
| #else
 | |
|   #define __I    volatile const /*!< defines 'read only' permissions     */
 | |
| #endif
 | |
| #define __O                 volatile  /*!< defines 'write only' permissions     */
 | |
| #define __IO                volatile  /*!< defines 'read / write' permissions   */
 | |
| #define RV_STATIC_INLINE    static inline
 | |
| 
 | |
| //typedef enum {SUCCESS = 0, ERROR = !SUCCESS} ErrorStatus;
 | |
| 
 | |
| typedef enum
 | |
| {
 | |
|     DISABLE = 0,
 | |
|     ENABLE = !DISABLE
 | |
| } FunctionalState;
 | |
| typedef enum
 | |
| {
 | |
|     RESET = 0,
 | |
|     SET = !RESET
 | |
| } FlagStatus, ITStatus;
 | |
| 
 | |
| /* memory mapped structure for Program Fast Interrupt Controller (PFIC) */
 | |
| typedef struct
 | |
| {
 | |
|     __I uint32_t  ISR[8];           // 0
 | |
|     __I uint32_t  IPR[8];           // 20H
 | |
|     __IO uint32_t ITHRESDR;         // 40H
 | |
|     uint8_t       RESERVED[4];      // 44H
 | |
|     __O uint32_t  CFGR;             // 48H
 | |
|     __I uint32_t  GISR;             // 4CH
 | |
|     __IO uint8_t  VTFIDR[4];        // 50H
 | |
|     uint8_t       RESERVED0[0x0C];  // 54H
 | |
|     __IO uint32_t VTFADDR[4];       // 60H
 | |
|     uint8_t       RESERVED1[0x90];  // 70H
 | |
|     __O uint32_t  IENR[8];          // 100H
 | |
|     uint8_t       RESERVED2[0x60];  // 120H
 | |
|     __O uint32_t  IRER[8];          // 180H
 | |
|     uint8_t       RESERVED3[0x60];  // 1A0H
 | |
|     __O uint32_t  IPSR[8];          // 200H
 | |
|     uint8_t       RESERVED4[0x60];  // 220H
 | |
|     __O uint32_t  IPRR[8];          // 280H
 | |
|     uint8_t       RESERVED5[0x60];  // 2A0H
 | |
|     __IO uint32_t IACTR[8];         // 300H
 | |
|     uint8_t       RESERVED6[0xE0];  // 320H
 | |
|     __IO uint8_t  IPRIOR[256];      // 400H
 | |
|     uint8_t       RESERVED7[0x810]; // 500H
 | |
|     __IO uint32_t SCTLR;            // D10H
 | |
| } PFIC_Type;
 | |
| 
 | |
| /* memory mapped structure for SysTick */
 | |
| typedef struct
 | |
| {
 | |
|     __IO uint32_t CTLR;
 | |
|     __IO uint32_t SR;
 | |
|     __IO uint64_t CNT;
 | |
|     __IO uint64_t CMP;
 | |
| } SysTick_Type;
 | |
| 
 | |
| #define PFIC                    ((PFIC_Type *)0xE000E000)
 | |
| #define SysTick                 ((SysTick_Type *)0xE000F000)
 | |
| 
 | |
| #define PFIC_KEY1               ((uint32_t)0xFA050000)
 | |
| #define PFIC_KEY2               ((uint32_t)0xBCAF0000)
 | |
| #define PFIC_KEY3               ((uint32_t)0xBEEF0000)
 | |
| 
 | |
| /* ##########################   define  #################################### */
 | |
| #define __nop()                 __asm__ volatile("nop")
 | |
| 
 | |
| #define read_csr(reg)           ({unsigned long __tmp;                        \
 | |
|      __asm__ volatile ("csrr %0, " #reg : "=r"(__tmp));                 \
 | |
|          __tmp; })
 | |
| 
 | |
| #define write_csr(reg, val)     ({                                      \
 | |
|     if (__builtin_constant_p(val) && (unsigned long)(val) < 32)    \
 | |
|       __asm__ volatile ("csrw  " #reg ", %0" :: "i"(val));              \
 | |
|     else                                                            \
 | |
|       __asm__ volatile ("csrw  " #reg ", %0" :: "r"(val)); })
 | |
| 
 | |
| #define PFIC_EnableAllIRQ()     {write_csr(0x800, 0x88);}
 | |
| #define PFIC_DisableAllIRQ()    {write_csr(0x800, 0x80);asm volatile("fence.i");}
 | |
| /* ##########################   PFIC functions  #################################### */
 | |
| 
 | |
| /*********************************************************************
 | |
|  * @fn      __risc_v_enable_irq
 | |
|  *
 | |
|  * @brief   recover Global Interrupt
 | |
|  *
 | |
|  * @return  mpie and mie bit in mstatus.
 | |
|  */
 | |
| __attribute__((always_inline)) RV_STATIC_INLINE uint32_t __risc_v_enable_irq(uint32_t mpie_mie)
 | |
| {
 | |
|   uint32_t result;
 | |
| 
 | |
|   __asm volatile ("csrrs %0, 0x800, %1" : \
 | |
|           "=r"(result): "r"(mpie_mie) : "memory");
 | |
|   return result;
 | |
| }
 | |
| 
 | |
| /*********************************************************************
 | |
|  * @fn      __disable_irq
 | |
|  *
 | |
|  * @brief   Disable Global Interrupt
 | |
|  *
 | |
|  * @return  mpie and mie bit in mstatus.
 | |
|  */
 | |
| __attribute__((always_inline)) RV_STATIC_INLINE uint32_t __risc_v_disable_irq(void)
 | |
| {
 | |
|   uint32_t result;
 | |
| 
 | |
|   __asm volatile ("csrrc %0, 0x800, %1" : \
 | |
|           "=r"(result): "r"(0x88) : "memory");
 | |
|   return result & 0x88;
 | |
| }
 | |
| 
 | |
| /*******************************************************************************
 | |
|  * @fn      PFIC_EnableIRQ
 | |
|  *
 | |
|  * @brief   Enable Interrupt
 | |
|  *
 | |
|  * @param   IRQn    - Interrupt Numbers
 | |
|  */
 | |
| __attribute__((always_inline)) RV_STATIC_INLINE void PFIC_EnableIRQ(IRQn_Type IRQn)
 | |
| {
 | |
|     PFIC->IENR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn)&0x1F));
 | |
| }
 | |
| 
 | |
| /*******************************************************************************
 | |
|  * @fn      PFIC_DisableIRQ
 | |
|  *
 | |
|  * @brief   Disable Interrupt
 | |
|  *
 | |
|  * @param   IRQn    - Interrupt Numbers
 | |
|  */
 | |
| __attribute__((always_inline)) RV_STATIC_INLINE void PFIC_DisableIRQ(IRQn_Type IRQn)
 | |
| {
 | |
|     PFIC->IRER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn)&0x1F));
 | |
|     asm volatile("fence.i");
 | |
| }
 | |
| 
 | |
| /*******************************************************************************
 | |
|  * @fn      PFIC_GetStatusIRQ
 | |
|  *
 | |
|  * @brief   Get Interrupt Enable State
 | |
|  *
 | |
|  * @param   IRQn    - Interrupt Numbers
 | |
|  *
 | |
|  * @return  1: Interrupt Enable
 | |
|  *          0: Interrupt Disable
 | |
|  */
 | |
| __attribute__((always_inline)) RV_STATIC_INLINE uint32_t PFIC_GetStatusIRQ(IRQn_Type IRQn)
 | |
| {
 | |
|     return ((uint32_t)((PFIC->ISR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn)&0x1F))) ? 1 : 0));
 | |
| }
 | |
| 
 | |
| /*******************************************************************************
 | |
|  * @fn      PFIC_GetPendingIRQ
 | |
|  *
 | |
|  * @brief   Get Interrupt Pending State
 | |
|  *
 | |
|  * @param   IRQn    - Interrupt Numbers
 | |
|  *
 | |
|  * @return  1: Interrupt Pending Enable
 | |
|  *          0: Interrupt Pending Disable
 | |
|  */
 | |
| __attribute__((always_inline)) RV_STATIC_INLINE uint32_t PFIC_GetPendingIRQ(IRQn_Type IRQn)
 | |
| {
 | |
|     return ((uint32_t)((PFIC->IPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn)&0x1F))) ? 1 : 0));
 | |
| }
 | |
| 
 | |
| /*******************************************************************************
 | |
|  * @fn      PFIC_SetPendingIRQ
 | |
|  *
 | |
|  * @brief   Set Interrupt Pending
 | |
|  *
 | |
|  * @param   IRQn    - Interrupt Numbers
 | |
|  */
 | |
| __attribute__((always_inline)) RV_STATIC_INLINE void PFIC_SetPendingIRQ(IRQn_Type IRQn)
 | |
| {
 | |
|     PFIC->IPSR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn)&0x1F));
 | |
| }
 | |
| 
 | |
| /*******************************************************************************
 | |
|  * @fn      PFIC_ClearPendingIRQ
 | |
|  *
 | |
|  * @brief   Clear Interrupt Pending
 | |
|  *
 | |
|  * @param   IRQn    - Interrupt Numbers
 | |
|  */
 | |
| __attribute__((always_inline)) RV_STATIC_INLINE void PFIC_ClearPendingIRQ(IRQn_Type IRQn)
 | |
| {
 | |
|     PFIC->IPRR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn)&0x1F));
 | |
| }
 | |
| 
 | |
| /*******************************************************************************
 | |
|  * @fn      PFIC_GetActive
 | |
|  *
 | |
|  * @brief   Get Interrupt Active State
 | |
|  *
 | |
|  * @param   IRQn    - Interrupt Numbers
 | |
|  *
 | |
|  * @return  1: Interrupt Active
 | |
|  *          0: Interrupt No Active.
 | |
|  */
 | |
| __attribute__((always_inline)) RV_STATIC_INLINE uint32_t PFIC_GetActive(IRQn_Type IRQn)
 | |
| {
 | |
|     return ((uint32_t)((PFIC->IACTR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn)&0x1F))) ? 1 : 0));
 | |
| }
 | |
| 
 | |
| /*******************************************************************************
 | |
|  * @fn      PFIC_SetPriority
 | |
|  *
 | |
|  * @brief   Set Interrupt Priority
 | |
|  *
 | |
|  * @param   IRQn        - Interrupt Numbers
 | |
|  * @param   priority    - bit7-bit4:   priority
 | |
|  */
 | |
| __attribute__((always_inline)) RV_STATIC_INLINE void PFIC_SetPriority(IRQn_Type IRQn, uint8_t priority)
 | |
| {
 | |
|     PFIC->IPRIOR[(uint32_t)(IRQn)] = priority;
 | |
| }
 | |
| 
 | |
| /*********************************************************************
 | |
|  * @fn      SetVTFIRQ
 | |
|  *
 | |
|  * @brief   Set VTF Interrupt
 | |
|  *
 | |
|  * @param   addr - VTF interrupt service function base address.
 | |
|  *                  IRQn - Interrupt Numbers
 | |
|  *                  num - VTF Interrupt Numbers
 | |
|  *                  NewState -  DISABLE or ENABLE
 | |
|  *
 | |
|  * @return  none
 | |
|  */
 | |
| __attribute__((always_inline)) RV_STATIC_INLINE void SetVTFIRQ(uint32_t addr, IRQn_Type IRQn, uint8_t num, FunctionalState NewState){
 | |
|   if(num > 3)  return ;
 | |
| 
 | |
|   if (NewState != DISABLE)
 | |
|   {
 | |
|       PFIC->VTFIDR[num] = IRQn;
 | |
|       PFIC->VTFADDR[num] = ((addr&0xFFFFFFFE)|0x1);
 | |
|   }
 | |
|   else{
 | |
|       PFIC->VTFIDR[num] = IRQn;
 | |
|       PFIC->VTFADDR[num] = ((addr&0xFFFFFFFE)&(~0x1));
 | |
|   }
 | |
| }
 | |
| 
 | |
| /*********************************************************************
 | |
|  * @fn       _SEV
 | |
|  *
 | |
|  * @brief   Set Event
 | |
|  *
 | |
|  * @return  none
 | |
|  */
 | |
| __attribute__( ( always_inline ) ) RV_STATIC_INLINE void _SEV(void)
 | |
| {
 | |
| 
 | |
|     PFIC->SCTLR |= (1<<3)|(1<<5);
 | |
| 
 | |
| }
 | |
| 
 | |
| /*********************************************************************
 | |
|  * @fn       _WFE
 | |
|  *
 | |
|  * @brief   Wait for Events
 | |
|  *
 | |
|  * @return  none
 | |
|  */
 | |
| __attribute__( ( always_inline ) ) RV_STATIC_INLINE void _WFE(void)
 | |
| {
 | |
|     PFIC->SCTLR |= (1<<3);
 | |
|     asm volatile ("wfi");
 | |
| }
 | |
| 
 | |
| 
 | |
| /*********************************************************************
 | |
|  * @fn      __WFE
 | |
|  *
 | |
|  * @brief   Wait for Events
 | |
|  *
 | |
|  * @return  None
 | |
|  */
 | |
| __attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFE(void)
 | |
| {
 | |
|     _SEV();
 | |
|     _WFE();
 | |
|     _WFE();
 | |
| }
 | |
| 
 | |
| /*********************************************************************
 | |
|  * @fn      __WFI
 | |
|  *
 | |
|  * @brief   Wait for Interrupt
 | |
|  */
 | |
| __attribute__((always_inline)) RV_STATIC_INLINE void __WFI(void)
 | |
| {
 | |
|     PFIC->SCTLR &= ~(1 << 3); // wfi
 | |
|     __asm__ volatile("wfi");
 | |
| }
 | |
| 
 | |
| /*********************************************************************
 | |
|  * @fn      PFIC_SystemReset
 | |
|  *
 | |
|  * @brief   Initiate a system reset request
 | |
|  */
 | |
| __attribute__((always_inline)) RV_STATIC_INLINE void PFIC_SystemReset(void)
 | |
| {
 | |
|     PFIC->CFGR = PFIC_KEY3 | (1 << 7);
 | |
| }
 | |
| 
 | |
| /*********************************************************************
 | |
|  *  @fn      __AMOADD_W
 | |
|  *
 | |
|  *  @brief   Atomic Add with 32bit value
 | |
|  *              Atomically ADD 32bit value with value in memory using amoadd.d.
 | |
|  *              addr   Address pointer to data, address need to be 4byte aligned
 | |
|  *                        value  value to be ADDed
 | |
|  *
 | |
|  *
 | |
|  * @return  return memory value + add value
 | |
|  */
 | |
| __attribute__((always_inline)) RV_STATIC_INLINE int32_t __AMOADD_W(volatile int32_t *addr, int32_t value)
 | |
| {
 | |
|     int32_t result;
 | |
| 
 | |
|     __asm volatile ("amoadd.w %0, %2, %1" : \
 | |
|             "=r"(result), "+A"(*addr) : "r"(value) : "memory");
 | |
|     return *addr;
 | |
| }
 | |
| 
 | |
| /*********************************************************************
 | |
|  * @fn      __AMOAND_W
 | |
|  *
 | |
|  * @brief  Atomic And with 32bit value
 | |
|  *              Atomically AND 32bit value with value in memory using amoand.d.
 | |
|  *              addr   Address pointer to data, address need to be 4byte aligned
 | |
|  *              value  value to be ANDed
 | |
|  *
 | |
|  *
 | |
|  * @return  return memory value & and value
 | |
|  */
 | |
| __attribute__((always_inline)) RV_STATIC_INLINE int32_t __AMOAND_W(volatile int32_t *addr, int32_t value)
 | |
| {
 | |
|     int32_t result;
 | |
| 
 | |
|     __asm volatile ("amoand.w %0, %2, %1" : \
 | |
|             "=r"(result), "+A"(*addr) : "r"(value) : "memory");
 | |
|     return *addr;
 | |
| }
 | |
| 
 | |
| /*********************************************************************
 | |
|  * @fn         __AMOMAX_W
 | |
|  *
 | |
|  * @brief      Atomic signed MAX with 32bit value
 | |
|  * @details   Atomically signed max compare 32bit value with value in memory using amomax.d.
 | |
|  *                 addr   Address pointer to data, address need to be 4byte aligned
 | |
|  *                 value  value to be compared
 | |
|  *
 | |
|  *
 | |
|  * @return the bigger value
 | |
|  */
 | |
| __attribute__((always_inline)) RV_STATIC_INLINE int32_t __AMOMAX_W(volatile int32_t *addr, int32_t value)
 | |
| {
 | |
|     int32_t result;
 | |
| 
 | |
|     __asm volatile ("amomax.w %0, %2, %1" : \
 | |
|             "=r"(result), "+A"(*addr) : "r"(value) : "memory");
 | |
|     return *addr;
 | |
| }
 | |
| 
 | |
| /*********************************************************************
 | |
|  * @fn        __AMOMAXU_W
 | |
|  *
 | |
|  * @brief  Atomic unsigned MAX with 32bit value
 | |
|  *             Atomically unsigned max compare 32bit value with value in memory using amomaxu.d.
 | |
|  *             addr   Address pointer to data, address need to be 4byte aligned
 | |
|  *             value  value to be compared
 | |
|  *
 | |
|  * @return  return the bigger value
 | |
|  */
 | |
| __attribute__((always_inline)) RV_STATIC_INLINE uint32_t __AMOMAXU_W(volatile uint32_t *addr, uint32_t value)
 | |
| {
 | |
|     uint32_t result;
 | |
| 
 | |
|     __asm volatile ("amomaxu.w %0, %2, %1" : \
 | |
|             "=r"(result), "+A"(*addr) : "r"(value) : "memory");
 | |
|     return *addr;
 | |
| }
 | |
| 
 | |
| /*********************************************************************
 | |
|  * @fn      __AMOMIN_W
 | |
|  *
 | |
|  * @brief  Atomic signed MIN with 32bit value
 | |
|  *             Atomically signed min compare 32bit value with value in memory using amomin.d.
 | |
|  *             addr   Address pointer to data, address need to be 4byte aligned
 | |
|  *             value  value to be compared
 | |
|  *
 | |
|  *
 | |
|  * @return  the smaller value
 | |
|  */
 | |
| __attribute__((always_inline)) RV_STATIC_INLINE int32_t __AMOMIN_W(volatile int32_t *addr, int32_t value)
 | |
| {
 | |
|     int32_t result;
 | |
| 
 | |
|     __asm volatile ("amomin.w %0, %2, %1" : \
 | |
|             "=r"(result), "+A"(*addr) : "r"(value) : "memory");
 | |
|     return *addr;
 | |
| }
 | |
| 
 | |
| /*********************************************************************
 | |
|  * @fn      __AMOMINU_W
 | |
|  *
 | |
|  * @brief   Atomic unsigned MIN with 32bit value
 | |
|  *              Atomically unsigned min compare 32bit value with value in memory using amominu.d.
 | |
|  *              addr   Address pointer to data, address need to be 4byte aligned
 | |
|  *              value  value to be compared
 | |
|  *
 | |
|  *
 | |
|  * @return the smaller value
 | |
|  */
 | |
| __attribute__((always_inline)) RV_STATIC_INLINE uint32_t __AMOMINU_W(volatile uint32_t *addr, uint32_t value)
 | |
| {
 | |
|     uint32_t result;
 | |
| 
 | |
|     __asm volatile ("amominu.w %0, %2, %1" : \
 | |
|             "=r"(result), "+A"(*addr) : "r"(value) : "memory");
 | |
|     return *addr;
 | |
| }
 | |
| 
 | |
| /*********************************************************************
 | |
|  * @fn           __AMOOR_W
 | |
|  *
 | |
|  * @brief       Atomic OR with 32bit value
 | |
|  * @details    Atomically OR 32bit value with value in memory using amoor.d.
 | |
|  *                  addr   Address pointer to data, address need to be 4byte aligned
 | |
|  *                  value  value to be ORed
 | |
|  *
 | |
|  *
 | |
|  * @return  return memory value | and value
 | |
|  */
 | |
| __attribute__((always_inline)) RV_STATIC_INLINE int32_t __AMOOR_W(volatile int32_t *addr, int32_t value)
 | |
| {
 | |
|     int32_t result;
 | |
| 
 | |
|     __asm volatile ("amoor.w %0, %2, %1" : \
 | |
|             "=r"(result), "+A"(*addr) : "r"(value) : "memory");
 | |
|     return *addr;
 | |
| }
 | |
| 
 | |
| /*********************************************************************
 | |
|  * @fn          __AMOSWAP_W
 | |
|  *
 | |
|  * @brief      Atomically swap new 32bit value into memory using amoswap.d.
 | |
|  *                  addr      Address pointer to data, address need to be 4byte aligned
 | |
|  *                  newval    New value to be stored into the address
 | |
|  *
 | |
|  * @return    return the original value in memory
 | |
|  */
 | |
| __attribute__((always_inline)) RV_STATIC_INLINE uint32_t __AMOSWAP_W(volatile uint32_t *addr, uint32_t newval)
 | |
| {
 | |
|     uint32_t result;
 | |
| 
 | |
|     __asm volatile ("amoswap.w %0, %2, %1" : \
 | |
|             "=r"(result), "+A"(*addr) : "r"(newval) : "memory");
 | |
|     return result;
 | |
| }
 | |
| 
 | |
| /*********************************************************************
 | |
|  * @fn        __AMOXOR_W
 | |
|  *
 | |
|  * @brief    Atomic XOR with 32bit value
 | |
|  * @details Atomically XOR 32bit value with value in memory using amoxor.d.
 | |
|  *               addr   Address pointer to data, address need to be 4byte aligned
 | |
|  *               value  value to be XORed
 | |
|  *
 | |
|  *
 | |
|  * @return  return memory value ^ and value
 | |
|  */
 | |
| __attribute__((always_inline)) RV_STATIC_INLINE int32_t __AMOXOR_W(volatile int32_t *addr, int32_t value)
 | |
| {
 | |
|     int32_t result;
 | |
| 
 | |
|     __asm volatile ("amoxor.w %0, %2, %1" : \
 | |
|             "=r"(result), "+A"(*addr) : "r"(value) : "memory");
 | |
|     return *addr;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief   Return the Machine Status Register
 | |
|  *
 | |
|  * @return  mstatus value
 | |
|  */
 | |
| uint32_t __get_MSTATUS(void);
 | |
| 
 | |
| /**
 | |
|  * @brief   Return the Machine ISA Register
 | |
|  *
 | |
|  * @return  misa value
 | |
|  */
 | |
| uint32_t __get_MISA(void);
 | |
| 
 | |
| /***
 | |
|  * @brief   Return the Machine Trap-Vector Base-Address Register
 | |
|  *
 | |
|  * @return  mtvec value
 | |
|  */
 | |
| uint32_t __get_MTVEC(void);
 | |
| 
 | |
| /**
 | |
|  * @brief   Return the Machine Seratch Register
 | |
|  *
 | |
|  * @return  mscratch value
 | |
|  */
 | |
| uint32_t __get_MSCRATCH(void);
 | |
| 
 | |
| /**
 | |
|  * @brief   Return the Machine Exception Program Register
 | |
|  *
 | |
|  * @return  mepc value
 | |
|  */
 | |
| uint32_t __get_MEPC(void);
 | |
| 
 | |
| /**
 | |
|  * @brief   Return the Machine Cause Register
 | |
|  *
 | |
|  * @return  mcause value
 | |
|  */
 | |
| uint32_t __get_MCAUSE(void);
 | |
| 
 | |
| /**
 | |
|  * @brief   Return the Machine Trap Value Register
 | |
|  *
 | |
|  * @return  mtval value
 | |
|  */
 | |
| uint32_t __get_MTVAL(void);
 | |
| 
 | |
| /**
 | |
|  * @brief   Return Vendor ID Register
 | |
|  *
 | |
|  * @return  mvendorid value
 | |
|  */
 | |
| uint32_t __get_MVENDORID(void);
 | |
| 
 | |
| /**
 | |
|  * @brief   Return Machine Architecture ID Register
 | |
|  *
 | |
|  * @return  marchid value
 | |
|  */
 | |
| uint32_t __get_MARCHID(void);
 | |
| 
 | |
| /**
 | |
|  * @brief   Return Machine Implementation ID Register
 | |
|  *
 | |
|  * @return  mimpid value
 | |
|  */
 | |
| uint32_t __get_MIMPID(void);
 | |
| 
 | |
| /**
 | |
|  * @brief   Return Hart ID Register
 | |
|  *
 | |
|  * @return  mhartid value
 | |
|  */
 | |
| uint32_t __get_MHARTID(void);
 | |
| 
 | |
| /**
 | |
|  * @brief   Return SP Register
 | |
|  *
 | |
|  * @return  SP value
 | |
|  */
 | |
| uint32_t __get_SP(void);
 | |
| 
 | |
| #define SysTick_LOAD_RELOAD_Msk    (0xFFFFFFFFFFFFFFFF)
 | |
| #define SysTick_CTLR_SWIE          (1 << 31)
 | |
| #define SysTick_CTLR_INIT          (1 << 5)
 | |
| #define SysTick_CTLR_MODE          (1 << 4)
 | |
| #define SysTick_CTLR_STRE          (1 << 3)
 | |
| #define SysTick_CTLR_STCLK         (1 << 2)
 | |
| #define SysTick_CTLR_STIE          (1 << 1)
 | |
| #define SysTick_CTLR_STE           (1 << 0)
 | |
| 
 | |
| #define SysTick_SR_CNTIF           (1 << 0)
 | |
| 
 | |
| RV_STATIC_INLINE uint32_t SysTick_Config(uint64_t ticks)
 | |
| {
 | |
|     if((ticks - 1) > SysTick_LOAD_RELOAD_Msk)
 | |
|         return (1); /* Reload value impossible */
 | |
| 
 | |
|     SysTick->CMP = ticks - 1; /* set reload register */
 | |
|     PFIC_EnableIRQ(SysTick_IRQn);
 | |
|     SysTick->CTLR = SysTick_CTLR_INIT |
 | |
|                     SysTick_CTLR_STRE |
 | |
|                     SysTick_CTLR_STCLK |
 | |
|                     SysTick_CTLR_STIE |
 | |
|                     SysTick_CTLR_STE; /* Enable SysTick IRQ and SysTick Timer */
 | |
|     return (0);                       /* Function successful */
 | |
| }
 | |
| 
 | |
| RV_STATIC_INLINE uint32_t __SysTick_Config(uint64_t ticks)
 | |
| {
 | |
|     if((ticks - 1) > SysTick_LOAD_RELOAD_Msk)
 | |
|         return (1); /* Reload value impossible */
 | |
| 
 | |
|     SysTick->CMP = ticks - 1; /* set reload register */
 | |
|     SysTick->CTLR = SysTick_CTLR_INIT |
 | |
|                     SysTick_CTLR_STRE |
 | |
|                     SysTick_CTLR_STCLK |
 | |
|                     SysTick_CTLR_STIE |
 | |
|                     SysTick_CTLR_STE; /* Enable SysTick IRQ and SysTick Timer */
 | |
|     return (0);                       /* Function successful */
 | |
| }
 | |
| 
 | |
| #ifdef __cplusplus
 | |
| }
 | |
| #endif
 | |
| 
 | |
| #endif /* __CORE_RV3A_H__ */
 |