#include volatile uint32_t QK_WFE_MASK = 0; #define __ASM __asm /*!< asm keyword for GNU Compiler */ #define __INLINE inline /*!< inline keyword for GNU Compiler */ /********************************************************************* * @fn __get_FFLAGS * * @brief Return the Floating-Point Accrued Exceptions * * @return fflags value */ uint32_t RISCV_get_FFLAGS(void) { uint32_t result; __ASM volatile ( "csrr %0," "fflags" : "=r" (result) ); return (result); } /********************************************************************* * @fn __set_FFLAGS * * @brief Set the Floating-Point Accrued Exceptions * * @param value - set FFLAGS value * * @return none */ void RISCV_set_FFLAGS(uint32_t value) { __ASM volatile ("csrw fflags, %0" : : "r" (value) ); } /********************************************************************* * @fn __get_FRM * * @brief Return the Floating-Point Dynamic Rounding Mode * * @return frm value */ uint32_t RISCV_get_FRM(void) { uint32_t result; __ASM volatile ( "csrr %0," "frm" : "=r" (result) ); return (result); } /********************************************************************* * @fn __set_FRM * * @brief Set the Floating-Point Dynamic Rounding Mode * * @param value - set frm value * * @return none */ void RISCV_set_FRM(uint32_t value) { __ASM volatile ("csrw frm, %0" : : "r" (value) ); } /********************************************************************* * @fn __get_FCSR * * @brief Return the Floating-Point Control and Status Register * * @return fcsr value */ uint32_t RISCV_get_FCSR(void) { uint32_t result; __ASM volatile ( "csrr %0," "fcsr" : "=r" (result) ); return (result); } /********************************************************************* * @fn __set_FCSR * * @brief Set the Floating-Point Dynamic Rounding Mode * * @param value - set fcsr value * * @return none */ void RISCV_set_FCSR(uint32_t value) { __ASM volatile ("csrw fcsr, %0" : : "r" (value) ); } /********************************************************************* * @fn __get_MSTATUS * * @brief Return the Machine Status Register * * @return mstatus value */ uint32_t RISCV_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 RISCV_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 RISCV_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 RISCV_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 RISCV_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 RISCV_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 RISCV_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 RISCV_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 RISCV_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 RISCV_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 RISCV_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 RISCV_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 RISCV_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 RISCV_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 RISCV_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 RISCV_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 RISCV_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 RISCV_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 RISCV_get_SP(void) { uint32_t result; __ASM volatile ( "mv %0," "sp" : "=r"(result) : ); return (result); } /********************************************************************* * @fn __set_MCOUNT_INHIBIT * * @brief Set Instruction and cycle count shield switch in machine mode * * @return mcause value */ void RISCV_set_MCOUNT_INHIBIT(uint32_t value) { __ASM volatile ("csrw mcounteren, %0" : : "r" (value) ); } /********************************************************************* * @fn __get_MCOUNT_INHIBIT * * @brief Return Instruction and cycle count shield switch in machine mode * * @return SP value */ uint32_t RISCV_get_MCOUNT_INHIBIT(void) { uint32_t result; __ASM volatile ( "csrr %0," "mcounteren" : "=r"(result) : ); return (result); } /********************************************************************* * @fn __set_MCYCLE * * @brief Set the number of cycles in machine mode * * @return mcause value */ void RISCV_set_MCYCLE(uint32_t value) { __ASM volatile ("csrw mcycle, %0" : : "r" (value) ); } /********************************************************************* * @fn __get_MCYCLE * * @brief Return the number of cycles in machine mode * * @return SP value */ uint32_t RISCV_get_MCYCLE(void) { uint32_t result; __ASM volatile ( "csrr %0," "mcycle" : "=r"(result) : ); return (result); } /********************************************************************* * @fn __set_MINSTRET * * @brief Set the number of completed instructions in machine mode * * @return mcause value */ void RISCV_set_MINSTRET(uint32_t value) { __ASM volatile ("csrw minstret, %0" : : "r" (value) ); } /********************************************************************* * @fn __get_MINSTRET * * @brief Return the number of completed instructions in machine mode * * @return SP value */ uint32_t RISCV_get_MINSTRET(void) { uint32_t result; __ASM volatile ( "csrr %0," "minstret" : "=r"(result) : ); return (result); } /********************************************************************* * @fn __set_UCYCLE * * @brief Set the number of cycles in user mode * * @return mcause value */ void RISCV_set_UCYCLE(uint32_t value) { __ASM volatile ("csrw cycle, %0" : : "r" (value) ); } /********************************************************************* * @fn __get_UCYCLE * * @brief Return the number of cycles in user mode * * @return SP value */ uint32_t RISCV_get_UCYCLE(void) { uint32_t result; __ASM volatile ( "csrr %0," "cycle" : "=r"(result) : ); return (result); } /********************************************************************* * @fn __set_UINSTRET * * @brief Set the number of completed instructions in user mode * * @return mcause value */ void RISCV_set_UINSTRET(uint32_t value) { __ASM volatile ("csrw instret, %0" : : "r" (value) ); } /********************************************************************* * @fn __get_UINSTRET * * @brief Return the number of completed instructions in user mode * * @return SP value */ uint32_t RISCV_get_UINSTRET(void) { uint32_t result; __ASM volatile ( "csrr %0," "instret" : "=r"(result) : ); return (result); } /* ------------------------------------------------------------------------------------------------------------------ */ /* HSEM */ /* HSEM Key */ #define QK_HSEM_KEY (0x5AA50000) /********************************************************************* * @fn HSEM_Take * * @brief Take a semaphore in 2 Step mode. * * @param HSEM_ID - pointer to a HSEM_ID_TypeDef structure. * ProcessID - Process ID from 0 to 255. * * @return READY - Take success. * NoREADY - Take error. */ QK_ErrorStatus QK_HSEM_Take(QK_HSEM_ID_TypeDef HSEM_ID, uint32_t ProcessID) { QK_ErrorStatus status = QK_NoREADY; QK_HSEM->RX[HSEM_ID] = ((ProcessID & 0xFF) | ((QK_NVIC_GetCurrentCoreID() << 8) | (1 << 31))); if( QK_HSEM->RX[HSEM_ID] == ((ProcessID & 0xFF) | ((QK_NVIC_GetCurrentCoreID() << 8) | (1 << 31)))) { status = QK_READY; } else { status = QK_NoREADY; } return (status); } /********************************************************************* * @fn HSEM_FastTake * * @brief Fast Take a semaphore with 1 Step mode. * * @param HSEM_ID - pointer to a HSEM_ID_TypeDef structure. * * @return READY - Take success. * NoREADY - Take error. */ QK_ErrorStatus QK_HSEM_FastTake(QK_HSEM_ID_TypeDef HSEM_ID) { QK_ErrorStatus status = QK_NoREADY; if( QK_HSEM->RLRX[HSEM_ID] == ((QK_NVIC_GetCurrentCoreID() << 8) | (1 << 31))) { status = QK_READY; } else { status = QK_NoREADY; } return (status); } /********************************************************************* * @fn HSEM_GetOneSemTakenState * * @brief Get one semaphore state Taken or not. * * @param HSEM_ID - pointer to a HSEM_ID_TypeDef structure. * * @return ENABLE - Take. * DISABLE - No Take. */ QK_FunctionalState QK_HSEM_GetOneSemTakenState(QK_HSEM_ID_TypeDef HSEM_ID) { QK_FunctionalState status = QK_DISABLE; if( (QK_HSEM->RX[HSEM_ID] & (1 << 31)) == (1 << 31)) { status = QK_ENABLE; } else { status = QK_DISABLE; } return (status); } /********************************************************************* * @fn HSEM_GetAllSemTakenState * * @brief Get all semaphore state Taken or not. * * @return All semaphore state Taken or not. */ uint32_t QK_HSEM_GetAllSemTakenState(void) { return (QK_HSEM->LSE); } /********************************************************************* * @fn HSEM_OwnCoreGetAllSemTakenState * * @brief Its own core(V3F or V5F) get all semaphore state Taken or not. * * @return All semaphore state Taken or not for own core(V3F or V5F) . */ uint32_t QK_HSEM_OwnCoreGetAllSemTakenState(void) { return (QK_HSEM->LSM); } /********************************************************************* * @fn HSEM_ReleaseOneSem * * @brief Release one semaphore. * * @param HSEM_ID - pointer to a HSEM_ID_TypeDef structure. * ProcessID - Process ID from 0 to 255. * * @return none */ void QK_HSEM_ReleaseOneSem(QK_HSEM_ID_TypeDef HSEM_ID, uint32_t ProcessID) { QK_HSEM->RX[HSEM_ID] = (ProcessID & 0xFF) | ((QK_NVIC_GetCurrentCoreID() << 8)); } /********************************************************************* * @fn HSEM_ReleaseAllSem * * @brief Release all semaphore. * * @return none */ void QK_HSEM_ReleaseAllSem(void) { QK_HSEM->CLR = QK_HSEM_KEY | (1<<13) | (1<<12); } /********************************************************************* * @fn HSEM_ReleaseSem_MatchCID_PID * * @brief Release semaphore that matches the ProcessID and CoreID. * * @param CoreID - core ID. * HSEM_Core_ID_V3F - Riscv V3F * HSEM_Core_ID_V5F - Riscv V5F * ProcessID - Process ID from 0 to 255. * * @return none */ void QK_HSEM_ReleaseSem_MatchCID_PID(uint32_t CoreID, uint32_t ProcessID) { QK_HSEM->CLR = QK_HSEM_KEY | CoreID | (ProcessID & 0xFF); } /********************************************************************* * @fn HSEM_ReleaseSem_MatchCID * * @brief Release semaphore that matches the CoreID. * * @param CoreID - core ID. * HSEM_Core_ID_V3F - Riscv V3F * HSEM_Core_ID_V5F - Riscv V5F * * @return none */ void QK_HSEM_ReleaseSem_MatchCID(uint32_t CoreID ) { QK_HSEM->CLR = QK_HSEM_KEY | CoreID | (1<<12); } /********************************************************************* * @fn HSEM_ReleaseSem_MatchPID * * @brief Release semaphore that matches the ProcessID and CoreID. * * @param ProcessID - Process ID from 0 to 255. * * @return none */ void QK_HSEM_ReleaseSem_MatchPID(uint32_t ProcessID) { QK_HSEM->CLR = QK_HSEM_KEY | (ProcessID & 0xFF) | (1<<13); } /********************************************************************* * @fn HSEM_SetClearKey * * @brief Set semaphore Key. * * @param Key - semaphore key value from 0 to 0xFFFF. * * @return none */ void QK_HSEM_SetClearKey(uint32_t Key) { QK_HSEM->CLR = (Key << 16); } /********************************************************************* * @fn HSEM_GetClearKey * * @brief Get semaphore Key. * * @return semaphore key value from 0 to 0xFFFF. */ uint32_t QK_HSEM_GetClearKey(void) { return ((QK_HSEM->KEY >> 16)); } /********************************************************************* * @fn HSEM_ITConfig * * @brief Enables or disables the HSEM interrupts. * * @param HSEM_ID - pointer to a HSEM_ID_TypeDef structure. * NewState - ENABLE or DISABLE. * * @return none */ void QK_HSEM_ITConfig(QK_HSEM_ID_TypeDef HSEM_ID, QK_FunctionalState NewState) { if(NewState != QK_DISABLE) { QK_HSEM->IER |= (1 << HSEM_ID); } else { QK_HSEM->IER &= (~(uint32_t)(1 << HSEM_ID)); } } /********************************************************************* * @fn HSEM_GetFlagStatus * * @brief Checks whether the specified HSEM flag is set or not. * * @param HSEM_ID - pointer to a HSEM_ID_TypeDef structure. * * @return FlagStatus: SET or RESET. */ QK_FlagStatus QK_HSEM_GetFlagStatus(QK_HSEM_ID_TypeDef HSEM_ID) { QK_FlagStatus bitstatus = QK_RESET; if((QK_HSEM->ISR & (1<ISR = (1<ISM & (1<ISR = (1<