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