sdk: copy RVMSIS
This commit is contained in:
parent
d81590c60b
commit
3c4c7b5640
306
sdk/RVMSIS/core_riscv.c
Normal file
306
sdk/RVMSIS/core_riscv.c
Normal file
@ -0,0 +1,306 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : core_riscv.c
|
||||
* Author : WCH
|
||||
* Version : V1.1.0
|
||||
* Date : 2021/06/06
|
||||
* Description : RISC-V Core Peripheral Access Layer Source 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.
|
||||
*******************************************************************************/
|
||||
#include <stdint.h>
|
||||
|
||||
/* define compiler specific symbols */
|
||||
#if defined ( __CC_ARM )
|
||||
#define __ASM __asm /*!< asm keyword for ARM Compiler */
|
||||
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
|
||||
|
||||
#elif defined ( __ICCARM__ )
|
||||
#define __ASM __asm /*!< asm keyword for IAR Compiler */
|
||||
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */
|
||||
|
||||
#elif defined ( __GNUC__ )
|
||||
#define __ASM __asm /*!< asm keyword for GNU Compiler */
|
||||
#define __INLINE inline /*!< inline keyword for GNU Compiler */
|
||||
|
||||
#elif defined ( __TASKING__ )
|
||||
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
|
||||
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __get_MSTATUS
|
||||
*
|
||||
* @brief Return the Machine Status Register
|
||||
*
|
||||
* @return mstatus value
|
||||
*/
|
||||
uint32_t __get_MSTATUS(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ( "csrr %0," "mstatus" : "=r" (result) );
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __set_MSTATUS
|
||||
*
|
||||
* @brief Set the Machine Status Register
|
||||
*
|
||||
* @param value - set mstatus value
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void __set_MSTATUS(uint32_t value)
|
||||
{
|
||||
__ASM volatile ("csrw mstatus, %0" : : "r" (value) );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __get_MISA
|
||||
*
|
||||
* @brief Return the Machine ISA Register
|
||||
*
|
||||
* @return misa value
|
||||
*/
|
||||
uint32_t __get_MISA(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ( "csrr %0," "misa" : "=r" (result) );
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __set_MISA
|
||||
*
|
||||
* @brief Set the Machine ISA Register
|
||||
*
|
||||
* @param value - set misa value
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void __set_MISA(uint32_t value)
|
||||
{
|
||||
__ASM volatile ("csrw misa, %0" : : "r" (value) );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __get_MTVEC
|
||||
*
|
||||
* @brief Return the Machine Trap-Vector Base-Address Register
|
||||
*
|
||||
* @return mtvec value
|
||||
*/
|
||||
uint32_t __get_MTVEC(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ( "csrr %0," "mtvec" : "=r" (result) );
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __set_MTVEC
|
||||
*
|
||||
* @brief Set the Machine Trap-Vector Base-Address Register
|
||||
*
|
||||
* @param value - set mtvec value
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void __set_MTVEC(uint32_t value)
|
||||
{
|
||||
__ASM volatile ("csrw mtvec, %0" : : "r" (value) );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __get_MSCRATCH
|
||||
*
|
||||
* @brief Return the Machine Seratch Register
|
||||
*
|
||||
* @return mscratch value
|
||||
*/
|
||||
uint32_t __get_MSCRATCH(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ( "csrr %0," "mscratch" : "=r" (result) );
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __set_MSCRATCH
|
||||
*
|
||||
* @brief Set the Machine Seratch Register
|
||||
*
|
||||
* @param value - set mscratch value
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void __set_MSCRATCH(uint32_t value)
|
||||
{
|
||||
__ASM volatile ("csrw mscratch, %0" : : "r" (value) );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __get_MEPC
|
||||
*
|
||||
* @brief Return the Machine Exception Program Register
|
||||
*
|
||||
* @return mepc value
|
||||
*/
|
||||
uint32_t __get_MEPC(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ( "csrr %0," "mepc" : "=r" (result) );
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __set_MEPC
|
||||
*
|
||||
* @brief Set the Machine Exception Program Register
|
||||
*
|
||||
* @return mepc value
|
||||
*/
|
||||
void __set_MEPC(uint32_t value)
|
||||
{
|
||||
__ASM volatile ("csrw mepc, %0" : : "r" (value) );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __get_MCAUSE
|
||||
*
|
||||
* @brief Return the Machine Cause Register
|
||||
*
|
||||
* @return mcause value
|
||||
*/
|
||||
uint32_t __get_MCAUSE(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ( "csrr %0," "mcause" : "=r" (result) );
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __set_MEPC
|
||||
*
|
||||
* @brief Set the Machine Cause Register
|
||||
*
|
||||
* @return mcause value
|
||||
*/
|
||||
void __set_MCAUSE(uint32_t value)
|
||||
{
|
||||
__ASM volatile ("csrw mcause, %0" : : "r" (value) );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __get_MTVAL
|
||||
*
|
||||
* @brief Return the Machine Trap Value Register
|
||||
*
|
||||
* @return mtval value
|
||||
*/
|
||||
uint32_t __get_MTVAL(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ( "csrr %0," "mtval" : "=r" (result) );
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __set_MTVAL
|
||||
*
|
||||
* @brief Set the Machine Trap Value Register
|
||||
*
|
||||
* @return mtval value
|
||||
*/
|
||||
void __set_MTVAL(uint32_t value)
|
||||
{
|
||||
__ASM volatile ("csrw mtval, %0" : : "r" (value) );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __get_MVENDORID
|
||||
*
|
||||
* @brief Return Vendor ID Register
|
||||
*
|
||||
* @return mvendorid value
|
||||
*/
|
||||
uint32_t __get_MVENDORID(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ( "csrr %0," "mvendorid" : "=r" (result) );
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __get_MARCHID
|
||||
*
|
||||
* @brief Return Machine Architecture ID Register
|
||||
*
|
||||
* @return marchid value
|
||||
*/
|
||||
uint32_t __get_MARCHID(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ( "csrr %0," "marchid" : "=r" (result) );
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __get_MIMPID
|
||||
*
|
||||
* @brief Return Machine Implementation ID Register
|
||||
*
|
||||
* @return mimpid value
|
||||
*/
|
||||
uint32_t __get_MIMPID(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ( "csrr %0," "mimpid" : "=r" (result) );
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __get_MHARTID
|
||||
*
|
||||
* @brief Return Hart ID Register
|
||||
*
|
||||
* @return mhartid value
|
||||
*/
|
||||
uint32_t __get_MHARTID(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ( "csrr %0," "mhartid" : "=r" (result) );
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __get_SP
|
||||
*
|
||||
* @brief Return SP Register
|
||||
*
|
||||
* @return SP value
|
||||
*/
|
||||
uint32_t __get_SP(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ( "mv %0," "sp" : "=r"(result) : );
|
||||
return (result);
|
||||
}
|
||||
|
592
sdk/RVMSIS/core_riscv.h
Normal file
592
sdk/RVMSIS/core_riscv.h
Normal file
@ -0,0 +1,592 @@
|
||||
/********************************** (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);__nop();__nop();}
|
||||
#define PFIC_DisableAllIRQ() {write_csr(0x800, 0x80);__nop();__nop();}
|
||||
/* ########################## PFIC functions #################################### */
|
||||
|
||||
/*******************************************************************************
|
||||
* @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));
|
||||
__nop();
|
||||
__nop();
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* @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: pre-emption priority
|
||||
* bit6-bit4: subpriority
|
||||
*/
|
||||
__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 */
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CORE_RV3A_H__ */
|
Loading…
Reference in New Issue
Block a user