summaryrefslogtreecommitdiff
path: root/bsp/wch/risc-v/libraries/ch56x_drivers/ch56x_pfic.c
blob: b6d1f5fbb19ea12625089c376f493f625422d94b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*
 * Copyright (c) 2006-2023, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author            Notes
 * 2022-07-15     Emuzit            first version
 */
#include <rthw.h>
#include "ch56x_pfic.h"
#include "ch56x_sys.h"
#include "isr_sp.h"

void rt_hw_interrupt_mask(int vector)
{
    pfic_interrupt_mask(vector);
}

void rt_hw_interrupt_umask(int vector)
{
    pfic_interrupt_umask(vector);
}

/**
 * @brief   Trigger software interrupt.
 */
void pfic_swi_pendset(void)
{
    volatile struct pfic_registers *pfic = (void *)PFIC_REG_BASE;
    _pfic_ireg_bit_set(pfic, IPSR, SWI_IRQn);
}

/**
 * @brief   Clear software interrupt.
 */
void pfic_swi_pendreset(void)
{
    volatile struct pfic_registers *pfic = (void *)PFIC_REG_BASE;
    _pfic_ireg_bit_set(pfic, IPRR, SWI_IRQn);
}

/**
 * @brief   Write PFIC interrupt configuration register.
 *
 * @param   key_bit is (PFIC_CFGR_KEYx + bit_position), one of the following :
 *          PFIC_CFGR_NMISET / PFIC_CFGR_NMIRESET
 *          PFIC_CFGR_EXCSET / PFIC_CFGR_EXCRESET
 *          PFIC_CFGR_PFICRESET
 *          PFIC_CFGR_SYSRESET
 *          All others are treated as NEST/HWSTK (B.1/B.0) write.
 */
void pfic_cfgr_set(uint32_t key_bit)
{
    volatile struct pfic_registers *pfic = (void *)PFIC_REG_BASE;
    uint32_t u32v;

    switch (key_bit)
    {
    case PFIC_CFGR_NMISET:
    case PFIC_CFGR_NMIRESET:
    case PFIC_CFGR_EXCSET:
    case PFIC_CFGR_EXCRESET:
    case PFIC_CFGR_PFICRESET:
    case PFIC_CFGR_SYSRESET:
        pfic->CFGR = key_bit;
    default:
        /* B.1/B.0 hold NEST/HWSTK, key ignored */
        u32v = key_bit & (CFGR_NESTCTRL_MASK | CFGR_HWSTKCTRL_MASK);
        pfic->CFGR = cfgr_nest_hwstk(u32v);
    }
}

/**
 * @brief   Make SysTick ready, systick/swi irq are enabled.
 *
 * @param   count is (HCLK/8) clocks count to generate systick irq.
 *          if 0 => calculate with current HCLK and RT_TICK_PER_SECOND
 */
void systick_init(uint32_t count)
{
    volatile struct systick_registers *systick = (void *)SysTick_REG_BASE;
    volatile struct pfic_registers *pfic = (void *)PFIC_REG_BASE;

    if (count == 0)
        count = sys_hclk_get() / 8 / RT_TICK_PER_SECOND;

    _pfic_irqn_disable(pfic, SysTick_IRQn);
    pfic->IPRIOR[SysTick_IRQn] = 0xe0;
    pfic->IPRIOR[SWI_IRQn] = 0xf0;
    systick->CTLR.reg = 0;
    systick->CNTL  = 0;
    systick->CNTH  = 0;
    systick->CMPLR = count - 1;
    systick->CMPHR = 0;
    systick->CNTFG.cntif = 0;
    /* enable & reload SysTick, with HCLK/8 */
    systick->CTLR.reg = RB_STKCTL_STRELOAD | RB_STKCTL_STIE | RB_STKCTL_STE;
    _pfic_irqn_enable(pfic, SysTick_IRQn);
    _pfic_irqn_enable(pfic, SWI_IRQn);
}

void systick_handler(void) __attribute__((interrupt()));
void systick_handler(void)
{
    volatile struct systick_registers *systick;

    isr_sp_enter();
    rt_interrupt_enter();

    rt_tick_increase();
    systick = (struct systick_registers *)SysTick_REG_BASE;
    /* clear count-to-zero flag */
    systick->CNTFG.cntif = 0;

    rt_interrupt_leave();
    isr_sp_leave();
}