core_riscv.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599
  1. /********************************** (C) COPYRIGHT *******************************
  2. * File Name : core_riscv.h
  3. * Author : WCH
  4. * Version : V1.0.2
  5. * Date : 2025/03/06
  6. * Description : RISC-V V4 Core Peripheral Access Layer Header File for CH32V30x
  7. *********************************************************************************
  8. * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
  9. * Attention: This software (modified or not) and binary are used for
  10. * microcontroller manufactured by Nanjing Qinheng Microelectronics.
  11. *******************************************************************************/
  12. #ifndef __CORE_RISCV_H__
  13. #define __CORE_RISCV_H__
  14. #ifdef __cplusplus
  15. extern "C" {
  16. #endif
  17. /* IO definitions */
  18. #ifdef __cplusplus
  19. #define __I volatile /* defines 'read only' permissions */
  20. #else
  21. #define __I volatile const /* defines 'read only' permissions */
  22. #endif
  23. #define __O volatile /* defines 'write only' permissions */
  24. #define __IO volatile /* defines 'read / write' permissions */
  25. /* Standard Peripheral Library old types (maintained for legacy purpose) */
  26. typedef __I uint64_t vuc64; /* Read Only */
  27. typedef __I uint32_t vuc32; /* Read Only */
  28. typedef __I uint16_t vuc16; /* Read Only */
  29. typedef __I uint8_t vuc8; /* Read Only */
  30. typedef const uint64_t uc64; /* Read Only */
  31. typedef const uint32_t uc32; /* Read Only */
  32. typedef const uint16_t uc16; /* Read Only */
  33. typedef const uint8_t uc8; /* Read Only */
  34. typedef __I int64_t vsc64; /* Read Only */
  35. typedef __I int32_t vsc32; /* Read Only */
  36. typedef __I int16_t vsc16; /* Read Only */
  37. typedef __I int8_t vsc8; /* Read Only */
  38. typedef const int64_t sc64; /* Read Only */
  39. typedef const int32_t sc32; /* Read Only */
  40. typedef const int16_t sc16; /* Read Only */
  41. typedef const int8_t sc8; /* Read Only */
  42. typedef __IO uint64_t vu64;
  43. typedef __IO uint32_t vu32;
  44. typedef __IO uint16_t vu16;
  45. typedef __IO uint8_t vu8;
  46. typedef uint64_t u64;
  47. typedef uint32_t u32;
  48. typedef uint16_t u16;
  49. typedef uint8_t u8;
  50. typedef __IO int64_t vs64;
  51. typedef __IO int32_t vs32;
  52. typedef __IO int16_t vs16;
  53. typedef __IO int8_t vs8;
  54. typedef int64_t s64;
  55. typedef int32_t s32;
  56. typedef int16_t s16;
  57. typedef int8_t s8;
  58. typedef enum {NoREADY = 0, READY = !NoREADY} ErrorStatus;
  59. typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;
  60. typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus;
  61. #define RV_STATIC_INLINE static inline
  62. /* memory mapped structure for Program Fast Interrupt Controller (PFIC) */
  63. typedef struct{
  64. __I uint32_t ISR[8];
  65. __I uint32_t IPR[8];
  66. __IO uint32_t ITHRESDR;
  67. __IO uint32_t RESERVED;
  68. __IO uint32_t CFGR;
  69. __I uint32_t GISR;
  70. __IO uint8_t VTFIDR[4];
  71. uint8_t RESERVED0[12];
  72. __IO uint32_t VTFADDR[4];
  73. uint8_t RESERVED1[0x90];
  74. __O uint32_t IENR[8];
  75. uint8_t RESERVED2[0x60];
  76. __O uint32_t IRER[8];
  77. uint8_t RESERVED3[0x60];
  78. __O uint32_t IPSR[8];
  79. uint8_t RESERVED4[0x60];
  80. __O uint32_t IPRR[8];
  81. uint8_t RESERVED5[0x60];
  82. __IO uint32_t IACTR[8];
  83. uint8_t RESERVED6[0xE0];
  84. __IO uint8_t IPRIOR[256];
  85. uint8_t RESERVED7[0x810];
  86. __IO uint32_t SCTLR;
  87. }PFIC_Type;
  88. /* memory mapped structure for SysTick */
  89. typedef struct
  90. {
  91. __IO uint32_t CTLR;
  92. __IO uint32_t SR;
  93. __IO uint64_t CNT;
  94. __IO uint64_t CMP;
  95. }SysTick_Type;
  96. #define PFIC ((PFIC_Type *) 0xE000E000 )
  97. #define NVIC PFIC
  98. #define NVIC_KEY1 ((uint32_t)0xFA050000)
  99. #define NVIC_KEY2 ((uint32_t)0xBCAF0000)
  100. #define NVIC_KEY3 ((uint32_t)0xBEEF0000)
  101. #define SysTick ((SysTick_Type *) 0xE000F000)
  102. /*********************************************************************
  103. * @fn __enable_irq
  104. *
  105. * @brief Enable Global Interrupt
  106. *
  107. * @return none
  108. */
  109. __attribute__( ( always_inline ) ) RV_STATIC_INLINE void __enable_irq()
  110. {
  111. __asm volatile ("csrs 0x800, %0" : : "r" (0x88) );
  112. }
  113. /*********************************************************************
  114. * @fn __disable_irq
  115. *
  116. * @brief Disable Global Interrupt
  117. *
  118. * @return none
  119. */
  120. __attribute__( ( always_inline ) ) RV_STATIC_INLINE void __disable_irq()
  121. {
  122. __asm volatile ("csrc 0x800, %0" : : "r" (0x88) );
  123. __asm volatile ("fence.i");
  124. }
  125. /*********************************************************************
  126. * @fn __NOP
  127. *
  128. * @brief nop
  129. *
  130. * @return none
  131. */
  132. __attribute__( ( always_inline ) ) RV_STATIC_INLINE void __NOP()
  133. {
  134. __asm volatile ("nop");
  135. }
  136. /*********************************************************************
  137. * @fn NVIC_EnableIRQ
  138. *
  139. * @brief Enable Interrupt
  140. *
  141. * @param IRQn - Interrupt Numbers
  142. *
  143. * @return none
  144. */
  145. __attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
  146. {
  147. NVIC->IENR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
  148. }
  149. /*********************************************************************
  150. * @fn NVIC_DisableIRQ
  151. *
  152. * @brief Disable Interrupt
  153. *
  154. * @param IRQn - Interrupt Numbers
  155. *
  156. * @return none
  157. */
  158. __attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
  159. {
  160. NVIC->IRER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
  161. __asm volatile ("fence.i");
  162. }
  163. /*********************************************************************
  164. * @fn NVIC_GetStatusIRQ
  165. *
  166. * @brief Get Interrupt Enable State
  167. *
  168. * @param IRQn - Interrupt Numbers
  169. *
  170. * @return 1 - Interrupt Enable
  171. * 0 - Interrupt Disable
  172. */
  173. __attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t NVIC_GetStatusIRQ(IRQn_Type IRQn)
  174. {
  175. return((uint32_t) ((NVIC->ISR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
  176. }
  177. /*********************************************************************
  178. * @fn NVIC_GetPendingIRQ
  179. *
  180. * @brief Get Interrupt Pending State
  181. *
  182. * @param IRQn - Interrupt Numbers
  183. *
  184. * @return 1 - Interrupt Pending Enable
  185. * 0 - Interrupt Pending Disable
  186. */
  187. __attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
  188. {
  189. return((uint32_t) ((NVIC->IPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
  190. }
  191. /*********************************************************************
  192. * @fn NVIC_SetPendingIRQ
  193. *
  194. * @brief Set Interrupt Pending
  195. *
  196. * @param IRQn - Interrupt Numbers
  197. *
  198. * @return none
  199. */
  200. __attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
  201. {
  202. NVIC->IPSR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
  203. }
  204. /*********************************************************************
  205. * @fn NVIC_ClearPendingIRQ
  206. *
  207. * @brief Clear Interrupt Pending
  208. *
  209. * @param IRQn - Interrupt Numbers
  210. *
  211. * @return none
  212. */
  213. __attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
  214. {
  215. NVIC->IPRR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
  216. }
  217. /*********************************************************************
  218. * @fn NVIC_GetActive
  219. *
  220. * @brief Get Interrupt Active State
  221. *
  222. * @param IRQn - Interrupt Numbers
  223. *
  224. * @return 1 - Interrupt Active
  225. * 0 - Interrupt No Active
  226. */
  227. __attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
  228. {
  229. return((uint32_t)((NVIC->IACTR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
  230. }
  231. /*********************************************************************
  232. * @fn NVIC_SetPriority
  233. *
  234. * @brief Set Interrupt Priority
  235. *
  236. * @param IRQn - Interrupt Numbers
  237. * interrupt nesting enable-8 Level(CSR-0x804 bit1 = 1 bit[3:2] = 3)
  238. * priority - bit[7:5] - Preemption Priority
  239. * bit[4:0] - Reserve
  240. * interrupt nesting enable-4 Level(CSR-0x804 bit1 = 1 bit[3:2] = 2)
  241. * priority - bit[7:6] - Preemption Priority
  242. * bit[5] - Sub priority
  243. * bit[4:0] - Reserve
  244. * interrupt nesting enable-2 Level(CSR-0x804 bit1 = 1 bit[3:2] = 1)
  245. * priority - bit[7] - Preemption Priority
  246. * bit[6:5] - Sub priority
  247. * bit[4:0] - Reserve
  248. * interrupt nesting disable(CSR-0x804 bit1 = 0)
  249. * priority - bit[7:5] - Sub priority
  250. * bit[4:0] - Reserve
  251. *
  252. * @return none
  253. */
  254. __attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint8_t priority)
  255. {
  256. NVIC->IPRIOR[(uint32_t)(IRQn)] = priority;
  257. }
  258. /*********************************************************************
  259. * @fn __WFI
  260. *
  261. * @brief Wait for Interrupt
  262. *
  263. * @return none
  264. */
  265. __attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFI(void)
  266. {
  267. NVIC->SCTLR &= ~(1<<3); // wfi
  268. asm volatile ("wfi");
  269. }
  270. /*********************************************************************
  271. * @fn _SEV
  272. *
  273. * @brief Set Event
  274. *
  275. * @return none
  276. */
  277. __attribute__( ( always_inline ) ) RV_STATIC_INLINE void _SEV(void)
  278. {
  279. uint32_t t;
  280. t = NVIC->SCTLR;
  281. NVIC->SCTLR |= (1<<3)|(1<<5);
  282. NVIC->SCTLR = (NVIC->SCTLR & ~(1<<5)) | ( t & (1<<5));
  283. }
  284. /*********************************************************************
  285. * @fn _WFE
  286. *
  287. * @brief Wait for Events
  288. *
  289. * @return none
  290. */
  291. __attribute__( ( always_inline ) ) RV_STATIC_INLINE void _WFE(void)
  292. {
  293. NVIC->SCTLR |= (1<<3);
  294. asm volatile ("wfi");
  295. }
  296. /*********************************************************************
  297. * @fn __WFE
  298. *
  299. * @brief Wait for Events
  300. *
  301. * @return none
  302. */
  303. __attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFE(void)
  304. {
  305. _SEV();
  306. _WFE();
  307. _WFE();
  308. }
  309. /*********************************************************************
  310. * @fn SetVTFIRQ
  311. *
  312. * @brief Set VTF Interrupt
  313. *
  314. * @param add - VTF interrupt service function base address.
  315. * IRQn -Interrupt Numbers
  316. * num - VTF Interrupt Numbers
  317. * NewState - DISABLE or ENABLE
  318. *
  319. * @return none
  320. */
  321. __attribute__( ( always_inline ) ) RV_STATIC_INLINE void SetVTFIRQ(uint32_t addr, IRQn_Type IRQn, uint8_t num, FunctionalState NewState)
  322. {
  323. if(num > 3) return ;
  324. if (NewState != DISABLE)
  325. {
  326. NVIC->VTFIDR[num] = IRQn;
  327. NVIC->VTFADDR[num] = ((addr&0xFFFFFFFE)|0x1);
  328. }
  329. else
  330. {
  331. NVIC->VTFIDR[num] = IRQn;
  332. NVIC->VTFADDR[num] = ((addr&0xFFFFFFFE)&(~0x1));
  333. }
  334. }
  335. /*********************************************************************
  336. * @fn NVIC_SystemReset
  337. *
  338. * @brief Initiate a system reset request
  339. *
  340. * @return none
  341. */
  342. __attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_SystemReset(void)
  343. {
  344. NVIC->CFGR = NVIC_KEY3|(1<<7);
  345. }
  346. /*********************************************************************
  347. * @fn __AMOADD_W
  348. *
  349. * @brief Atomic Add with 32bit value
  350. * Atomically ADD 32bit value with value in memory using amoadd.d.
  351. *
  352. * @param addr - Address pointer to data, address need to be 4byte aligned
  353. * value - value to be ADDed
  354. *
  355. * @return return memory value + add value
  356. */
  357. __attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOADD_W(volatile int32_t *addr, int32_t value)
  358. {
  359. int32_t result;
  360. __asm volatile ("amoadd.w %0, %2, %1" : \
  361. "=r"(result), "+A"(*addr) : "r"(value) : "memory");
  362. return *addr;
  363. }
  364. /*********************************************************************
  365. * @fn __AMOAND_W
  366. *
  367. * @brief Atomic And with 32bit value
  368. * Atomically AND 32bit value with value in memory using amoand.d.
  369. *
  370. * @param addr - Address pointer to data, address need to be 4byte aligned
  371. * value - value to be ANDed
  372. *
  373. * @return return memory value & and value
  374. */
  375. __attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOAND_W(volatile int32_t *addr, int32_t value)
  376. {
  377. int32_t result;
  378. __asm volatile ("amoand.w %0, %2, %1" : \
  379. "=r"(result), "+A"(*addr) : "r"(value) : "memory");
  380. return *addr;
  381. }
  382. /*********************************************************************
  383. * @fn __AMOMAX_W
  384. *
  385. * @brief Atomic signed MAX with 32bit value
  386. * Atomically signed max compare 32bit value with value in memory using amomax.d.
  387. * @param addr - Address pointer to data, address need to be 4byte aligned
  388. * value - value to be compared
  389. *
  390. * @return return the bigger value
  391. */
  392. __attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOMAX_W(volatile int32_t *addr, int32_t value)
  393. {
  394. int32_t result;
  395. __asm volatile ("amomax.w %0, %2, %1" : \
  396. "=r"(result), "+A"(*addr) : "r"(value) : "memory");
  397. return *addr;
  398. }
  399. /*********************************************************************
  400. * @fn __AMOMAXU_W
  401. *
  402. * @brief Atomic unsigned MAX with 32bit value
  403. * Atomically unsigned max compare 32bit value with value in memory using amomaxu.d.
  404. *
  405. * @param addr - Address pointer to data, address need to be 4byte aligned
  406. * value - value to be compared
  407. *
  408. * @return return the bigger value
  409. */
  410. __attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t __AMOMAXU_W(volatile uint32_t *addr, uint32_t value)
  411. {
  412. uint32_t result;
  413. __asm volatile ("amomaxu.w %0, %2, %1" : \
  414. "=r"(result), "+A"(*addr) : "r"(value) : "memory");
  415. return *addr;
  416. }
  417. /*********************************************************************
  418. * @fn __AMOMIN_W
  419. *
  420. * @brief Atomic signed MIN with 32bit value
  421. * Atomically signed min compare 32bit value with value in memory using amomin.d.
  422. *
  423. * @param addr - Address pointer to data, address need to be 4byte aligned
  424. * value - value to be compared
  425. *
  426. * @return return the smaller value
  427. */
  428. __attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOMIN_W(volatile int32_t *addr, int32_t value)
  429. {
  430. int32_t result;
  431. __asm volatile ("amomin.w %0, %2, %1" : \
  432. "=r"(result), "+A"(*addr) : "r"(value) : "memory");
  433. return *addr;
  434. }
  435. /*********************************************************************
  436. * @fn __AMOMINU_W
  437. *
  438. * @brief Atomic unsigned MIN with 32bit value
  439. * Atomically unsigned min compare 32bit value with value in memory using amominu.d.
  440. *
  441. * @param addr - Address pointer to data, address need to be 4byte aligned
  442. * value - value to be compared
  443. *
  444. * @return return the smaller value
  445. */
  446. __attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t __AMOMINU_W(volatile uint32_t *addr, uint32_t value)
  447. {
  448. uint32_t result;
  449. __asm volatile ("amominu.w %0, %2, %1" : \
  450. "=r"(result), "+A"(*addr) : "r"(value) : "memory");
  451. return *addr;
  452. }
  453. /*********************************************************************
  454. * @fn __AMOOR_W
  455. *
  456. * @brief Atomic OR with 32bit value
  457. * Atomically OR 32bit value with value in memory using amoor.d.
  458. *
  459. * @param addr - Address pointer to data, address need to be 4byte aligned
  460. * value - value to be ORed
  461. *
  462. * @return return memory value | and value
  463. */
  464. __attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOOR_W(volatile int32_t *addr, int32_t value)
  465. {
  466. int32_t result;
  467. __asm volatile ("amoor.w %0, %2, %1" : \
  468. "=r"(result), "+A"(*addr) : "r"(value) : "memory");
  469. return *addr;
  470. }
  471. /*********************************************************************
  472. * @fn __AMOSWAP_W
  473. *
  474. * @brief Atomically swap new 32bit value into memory using amoswap.d.
  475. *
  476. * @param addr - Address pointer to data, address need to be 4byte aligned
  477. * newval - New value to be stored into the address
  478. *
  479. * @return return the original value in memory
  480. */
  481. __attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t __AMOSWAP_W(volatile uint32_t *addr, uint32_t newval)
  482. {
  483. uint32_t result;
  484. __asm volatile ("amoswap.w %0, %2, %1" : \
  485. "=r"(result), "+A"(*addr) : "r"(newval) : "memory");
  486. return result;
  487. }
  488. /*********************************************************************
  489. * @fn __AMOXOR_W
  490. *
  491. * @brief Atomic XOR with 32bit value
  492. * Atomically XOR 32bit value with value in memory using amoxor.d.
  493. *
  494. * @param addr - Address pointer to data, address need to be 4byte aligned
  495. * value - value to be XORed
  496. *
  497. * @return return memory value ^ and value
  498. */
  499. __attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOXOR_W(volatile int32_t *addr, int32_t value)
  500. {
  501. int32_t result;
  502. __asm volatile ("amoxor.w %0, %2, %1" : \
  503. "=r"(result), "+A"(*addr) : "r"(value) : "memory");
  504. return *addr;
  505. }
  506. /* Core_Exported_Functions */
  507. extern uint32_t __get_FFLAGS(void);
  508. extern void __set_FFLAGS(uint32_t value);
  509. extern uint32_t __get_FRM(void);
  510. extern void __set_FRM(uint32_t value);
  511. extern uint32_t __get_FCSR(void);
  512. extern void __set_FCSR(uint32_t value);
  513. extern uint32_t __get_MSTATUS(void);
  514. extern void __set_MSTATUS(uint32_t value);
  515. extern uint32_t __get_MISA(void);
  516. extern void __set_MISA(uint32_t value);
  517. extern uint32_t __get_MTVEC(void);
  518. extern void __set_MTVEC(uint32_t value);
  519. extern uint32_t __get_MSCRATCH(void);
  520. extern void __set_MSCRATCH(uint32_t value);
  521. extern uint32_t __get_MEPC(void);
  522. extern void __set_MEPC(uint32_t value);
  523. extern uint32_t __get_MCAUSE(void);
  524. extern void __set_MCAUSE(uint32_t value);
  525. extern uint32_t __get_MTVAL(void);
  526. extern void __set_MTVAL(uint32_t value);
  527. extern uint32_t __get_MVENDORID(void);
  528. extern uint32_t __get_MARCHID(void);
  529. extern uint32_t __get_MIMPID(void);
  530. extern uint32_t __get_MHARTID(void);
  531. extern uint32_t __get_SP(void);
  532. #ifdef __cplusplus
  533. }
  534. #endif
  535. #endif