1 /*
2 * Copyright (c) 2006-2023, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2022-07-15 Emuzit first version
9 */
10 #include <rthw.h>
11 #include "ch56x_pfic.h"
12 #include "ch56x_sys.h"
13 #include "isr_sp.h"
14
rt_hw_interrupt_mask(int vector)15 void rt_hw_interrupt_mask(int vector)
16 {
17 pfic_interrupt_mask(vector);
18 }
19
rt_hw_interrupt_umask(int vector)20 void rt_hw_interrupt_umask(int vector)
21 {
22 pfic_interrupt_umask(vector);
23 }
24
25 /**
26 * @brief Trigger software interrupt.
27 */
pfic_swi_pendset(void)28 void pfic_swi_pendset(void)
29 {
30 volatile struct pfic_registers *pfic = (void *)PFIC_REG_BASE;
31 _pfic_ireg_bit_set(pfic, IPSR, SWI_IRQn);
32 }
33
34 /**
35 * @brief Clear software interrupt.
36 */
pfic_swi_pendreset(void)37 void pfic_swi_pendreset(void)
38 {
39 volatile struct pfic_registers *pfic = (void *)PFIC_REG_BASE;
40 _pfic_ireg_bit_set(pfic, IPRR, SWI_IRQn);
41 }
42
43 /**
44 * @brief Write PFIC interrupt configuration register.
45 *
46 * @param key_bit is (PFIC_CFGR_KEYx + bit_position), one of the following :
47 * PFIC_CFGR_NMISET / PFIC_CFGR_NMIRESET
48 * PFIC_CFGR_EXCSET / PFIC_CFGR_EXCRESET
49 * PFIC_CFGR_PFICRESET
50 * PFIC_CFGR_SYSRESET
51 * All others are treated as NEST/HWSTK (B.1/B.0) write.
52 */
pfic_cfgr_set(uint32_t key_bit)53 void pfic_cfgr_set(uint32_t key_bit)
54 {
55 volatile struct pfic_registers *pfic = (void *)PFIC_REG_BASE;
56 uint32_t u32v;
57
58 switch (key_bit)
59 {
60 case PFIC_CFGR_NMISET:
61 case PFIC_CFGR_NMIRESET:
62 case PFIC_CFGR_EXCSET:
63 case PFIC_CFGR_EXCRESET:
64 case PFIC_CFGR_PFICRESET:
65 case PFIC_CFGR_SYSRESET:
66 pfic->CFGR = key_bit;
67 default:
68 /* B.1/B.0 hold NEST/HWSTK, key ignored */
69 u32v = key_bit & (CFGR_NESTCTRL_MASK | CFGR_HWSTKCTRL_MASK);
70 pfic->CFGR = cfgr_nest_hwstk(u32v);
71 }
72 }
73
74 /**
75 * @brief Make SysTick ready, systick/swi irq are enabled.
76 *
77 * @param count is (HCLK/8) clocks count to generate systick irq.
78 * if 0 => calculate with current HCLK and RT_TICK_PER_SECOND
79 */
systick_init(uint32_t count)80 void systick_init(uint32_t count)
81 {
82 volatile struct systick_registers *systick = (void *)SysTick_REG_BASE;
83 volatile struct pfic_registers *pfic = (void *)PFIC_REG_BASE;
84
85 if (count == 0)
86 count = sys_hclk_get() / 8 / RT_TICK_PER_SECOND;
87
88 _pfic_irqn_disable(pfic, SysTick_IRQn);
89 pfic->IPRIOR[SysTick_IRQn] = 0xe0;
90 pfic->IPRIOR[SWI_IRQn] = 0xf0;
91 systick->CTLR.reg = 0;
92 systick->CNTL = 0;
93 systick->CNTH = 0;
94 systick->CMPLR = count - 1;
95 systick->CMPHR = 0;
96 systick->CNTFG.cntif = 0;
97 /* enable & reload SysTick, with HCLK/8 */
98 systick->CTLR.reg = RB_STKCTL_STRELOAD | RB_STKCTL_STIE | RB_STKCTL_STE;
99 _pfic_irqn_enable(pfic, SysTick_IRQn);
100 _pfic_irqn_enable(pfic, SWI_IRQn);
101 }
102
103 void systick_handler(void) __attribute__((interrupt()));
systick_handler(void)104 void systick_handler(void)
105 {
106 volatile struct systick_registers *systick;
107
108 isr_sp_enter();
109 rt_interrupt_enter();
110
111 rt_tick_increase();
112 systick = (struct systick_registers *)SysTick_REG_BASE;
113 /* clear count-to-zero flag */
114 systick->CNTFG.cntif = 0;
115
116 rt_interrupt_leave();
117 isr_sp_leave();
118 }
119