xref: /nrf52832-nimble/rt-thread/libcpu/c-sky/ck802/core_ck802.c (revision 104654410c56c573564690304ae786df310c91fc)
1*10465441SEvalZero /*
2*10465441SEvalZero  * File      : core_ck802.c
3*10465441SEvalZero  * This file is part of RT-Thread RTOS
4*10465441SEvalZero  * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
5*10465441SEvalZero  *
6*10465441SEvalZero  *  This program is free software; you can redistribute it and/or modify
7*10465441SEvalZero  *  it under the terms of the GNU General Public License as published by
8*10465441SEvalZero  *  the Free Software Foundation; either version 2 of the License, or
9*10465441SEvalZero  *  (at your option) any later version.
10*10465441SEvalZero  *
11*10465441SEvalZero  *  This program is distributed in the hope that it will be useful,
12*10465441SEvalZero  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13*10465441SEvalZero  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*10465441SEvalZero  *  GNU General Public License for more details.
15*10465441SEvalZero  *
16*10465441SEvalZero  *  You should have received a copy of the GNU General Public License along
17*10465441SEvalZero  *  with this program; if not, write to the Free Software Foundation, Inc.,
18*10465441SEvalZero  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*10465441SEvalZero  *
20*10465441SEvalZero  * Change Logs:
21*10465441SEvalZero  * Date           Author       Notes
22*10465441SEvalZero  * 2017-01-01     Urey         first version
23*10465441SEvalZero  */
24*10465441SEvalZero 
25*10465441SEvalZero #include <rthw.h>
26*10465441SEvalZero #include <rtthread.h>
27*10465441SEvalZero 
28*10465441SEvalZero #include <stdint.h>
29*10465441SEvalZero #include <core_ck802.h>
30*10465441SEvalZero 
31*10465441SEvalZero /* flag in interrupt handling */
32*10465441SEvalZero rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
33*10465441SEvalZero rt_uint32_t rt_thread_switch_interrupt_flag;
34*10465441SEvalZero 
35*10465441SEvalZero /*******************************************************************************
36*10465441SEvalZero  *                Hardware Abstraction Layer
37*10465441SEvalZero   Core Function Interface contains:
38*10465441SEvalZero   - Core VIC Functions
39*10465441SEvalZero   - Core CORET Functions
40*10465441SEvalZero   - Core Register Access Functions
41*10465441SEvalZero  ******************************************************************************/
42*10465441SEvalZero /**
43*10465441SEvalZero   \defgroup CSI_Core_FunctionInterface Functions and Instructions Reference
44*10465441SEvalZero */
45*10465441SEvalZero 
46*10465441SEvalZero /* ##########################   NVIC functions  #################################### */
47*10465441SEvalZero /**
48*10465441SEvalZero   \ingroup  CSI_Core_FunctionInterface
49*10465441SEvalZero   \defgroup CSI_Core_NVICFunctions NVIC Functions
50*10465441SEvalZero   \brief    Functions that manage interrupts and exceptions via the NVIC.
51*10465441SEvalZero   @{
52*10465441SEvalZero  */
53*10465441SEvalZero 
54*10465441SEvalZero /* Interrupt Priorities are WORD accessible only under CSKYv6M                   */
55*10465441SEvalZero /* The following MACROS handle generation of the register offset and byte masks */
56*10465441SEvalZero #define _BIT_SHIFT(IRQn)         (  ((((uint32_t)(int32_t)(IRQn))         )      &  0x03UL) * 8UL)
57*10465441SEvalZero #define _IP_IDX(IRQn)            (   (((uint32_t)(int32_t)(IRQn))                >>    2UL)      )
58*10465441SEvalZero 
59*10465441SEvalZero static uint32_t s_nvic_prio_bits = __NVIC_PRIO_BITS;
60*10465441SEvalZero 
61*10465441SEvalZero /**
62*10465441SEvalZero   \brief   initialize the NVIC interrupt controller
63*10465441SEvalZero   \param [in]      prio_bits  the priority bits of NVIC interrupt controller.
64*10465441SEvalZero  */
drv_nvic_init(uint32_t prio_bits)65*10465441SEvalZero void drv_nvic_init(uint32_t prio_bits)
66*10465441SEvalZero {
67*10465441SEvalZero     if (s_nvic_prio_bits >= 8U)
68*10465441SEvalZero     {
69*10465441SEvalZero         return;
70*10465441SEvalZero     }
71*10465441SEvalZero 
72*10465441SEvalZero     s_nvic_prio_bits = prio_bits;
73*10465441SEvalZero }
74*10465441SEvalZero 
75*10465441SEvalZero /**
76*10465441SEvalZero   \brief   Enable External Interrupt
77*10465441SEvalZero   \details Enables a device-specific interrupt in the NVIC interrupt controller.
78*10465441SEvalZero   \param [in]      IRQn  External interrupt number. Value cannot be negative.
79*10465441SEvalZero  */
drv_nvic_enable_irq(int32_t IRQn)80*10465441SEvalZero void drv_nvic_enable_irq(int32_t IRQn)
81*10465441SEvalZero {
82*10465441SEvalZero     NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
83*10465441SEvalZero #ifdef CONFIG_SYSTEM_SECURE
84*10465441SEvalZero     NVIC->ISSR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
85*10465441SEvalZero #endif
86*10465441SEvalZero }
87*10465441SEvalZero 
88*10465441SEvalZero /**
89*10465441SEvalZero   \brief   Disable External Interrupt
90*10465441SEvalZero   \details Disables a device-specific interrupt in the NVIC interrupt controller.
91*10465441SEvalZero   \param [in]      IRQn  External interrupt number. Value cannot be negative.
92*10465441SEvalZero  */
drv_nvic_disable_irq(int32_t IRQn)93*10465441SEvalZero void drv_nvic_disable_irq(int32_t IRQn)
94*10465441SEvalZero {
95*10465441SEvalZero     NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
96*10465441SEvalZero }
97*10465441SEvalZero 
98*10465441SEvalZero /**
99*10465441SEvalZero   \brief   Enable External Secure Interrupt
100*10465441SEvalZero   \details Enables a secure device-specific interrupt in the NVIC interrupt controller.
101*10465441SEvalZero   \param [in]      IRQn  External interrupt number. Value cannot be negative.
102*10465441SEvalZero  */
drv_nvic_enable_sirq(int32_t IRQn)103*10465441SEvalZero void drv_nvic_enable_sirq(int32_t IRQn)
104*10465441SEvalZero {
105*10465441SEvalZero     NVIC->ISSR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
106*10465441SEvalZero }
107*10465441SEvalZero 
108*10465441SEvalZero /**
109*10465441SEvalZero   \brief   Get Pending Interrupt
110*10465441SEvalZero   \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
111*10465441SEvalZero   \param [in]      IRQn  Interrupt number.
112*10465441SEvalZero   \return             0  Interrupt status is not pending.
113*10465441SEvalZero   \return             1  Interrupt status is pending.
114*10465441SEvalZero  */
drv_nvic_get_pending_irq(int32_t IRQn)115*10465441SEvalZero uint32_t drv_nvic_get_pending_irq(int32_t IRQn)
116*10465441SEvalZero {
117*10465441SEvalZero     return ((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
118*10465441SEvalZero }
119*10465441SEvalZero 
120*10465441SEvalZero /**
121*10465441SEvalZero   \brief   Set Pending Interrupt
122*10465441SEvalZero   \details Sets the pending bit of an external interrupt.
123*10465441SEvalZero   \param [in]      IRQn  Interrupt number. Value cannot be negative.
124*10465441SEvalZero  */
drv_nvic_set_pending_irq(int32_t IRQn)125*10465441SEvalZero void drv_nvic_set_pending_irq(int32_t IRQn)
126*10465441SEvalZero {
127*10465441SEvalZero     NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
128*10465441SEvalZero }
129*10465441SEvalZero 
130*10465441SEvalZero /**
131*10465441SEvalZero   \brief   Clear Pending Interrupt
132*10465441SEvalZero   \details Clears the pending bit of an external interrupt.
133*10465441SEvalZero   \param [in]      IRQn  External interrupt number. Value cannot be negative.
134*10465441SEvalZero  */
drv_nvic_clear_pending_irq(int32_t IRQn)135*10465441SEvalZero void drv_nvic_clear_pending_irq(int32_t IRQn)
136*10465441SEvalZero {
137*10465441SEvalZero     NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
138*10465441SEvalZero }
139*10465441SEvalZero 
140*10465441SEvalZero /**
141*10465441SEvalZero   \brief   Get Wake up Interrupt
142*10465441SEvalZero   \details Reads the wake up register in the NVIC and returns the pending bit for the specified interrupt.
143*10465441SEvalZero   \param [in]      IRQn  Interrupt number.
144*10465441SEvalZero   \return             0  Interrupt is not set as wake up interrupt.
145*10465441SEvalZero   \return             1  Interrupt is set as wake up interrupt.
146*10465441SEvalZero  */
drv_nvic_get_wakeup_irq(int32_t IRQn)147*10465441SEvalZero uint32_t drv_nvic_get_wakeup_irq(int32_t IRQn)
148*10465441SEvalZero {
149*10465441SEvalZero     return ((uint32_t)(((NVIC->IWER[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
150*10465441SEvalZero }
151*10465441SEvalZero 
152*10465441SEvalZero /**
153*10465441SEvalZero   \brief   Set Wake up Interrupt
154*10465441SEvalZero   \details Sets the wake up bit of an external interrupt.
155*10465441SEvalZero   \param [in]      IRQn  Interrupt number. Value cannot be negative.
156*10465441SEvalZero  */
drv_nvic_set_wakeup_irq(int32_t IRQn)157*10465441SEvalZero void drv_nvic_set_wakeup_irq(int32_t IRQn)
158*10465441SEvalZero {
159*10465441SEvalZero     NVIC->IWER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
160*10465441SEvalZero }
161*10465441SEvalZero 
162*10465441SEvalZero /**
163*10465441SEvalZero   \brief   Clear Wake up Interrupt
164*10465441SEvalZero   \details Clears the wake up bit of an external interrupt.
165*10465441SEvalZero   \param [in]      IRQn  External interrupt number. Value cannot be negative.
166*10465441SEvalZero  */
drv_nvic_clear_wakeup_irq(int32_t IRQn)167*10465441SEvalZero void drv_nvic_clear_wakeup_irq(int32_t IRQn)
168*10465441SEvalZero {
169*10465441SEvalZero     NVIC->IWDR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
170*10465441SEvalZero }
171*10465441SEvalZero 
172*10465441SEvalZero /**
173*10465441SEvalZero   \brief   Get Active Interrupt
174*10465441SEvalZero   \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt.
175*10465441SEvalZero   \param [in]      IRQn  Device specific interrupt number.
176*10465441SEvalZero   \return             0  Interrupt status is not active.
177*10465441SEvalZero   \return             1  Interrupt status is active.
178*10465441SEvalZero   \note    IRQn must not be negative.
179*10465441SEvalZero  */
drv_nvic_get_active(int32_t IRQn)180*10465441SEvalZero uint32_t drv_nvic_get_active(int32_t IRQn)
181*10465441SEvalZero {
182*10465441SEvalZero     return ((uint32_t)(((NVIC->IABR[0] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
183*10465441SEvalZero }
184*10465441SEvalZero 
185*10465441SEvalZero /**
186*10465441SEvalZero   \brief   Set Threshold register
187*10465441SEvalZero   \details set the threshold register in the NVIC.
188*10465441SEvalZero   \param [in]      VectThreshold  specific vecter threshold.
189*10465441SEvalZero   \param [in]      PrioThreshold  specific priority threshold.
190*10465441SEvalZero  */
drv_nvic_set_threshold(uint32_t VectThreshold,uint32_t PrioThreshold)191*10465441SEvalZero void drv_nvic_set_threshold(uint32_t VectThreshold, uint32_t PrioThreshold)
192*10465441SEvalZero {
193*10465441SEvalZero     NVIC->IPTR = 0x80000000 | (((VectThreshold + 32) & 0xFF) << 8) | ((PrioThreshold & 0x3) << 6);
194*10465441SEvalZero }
195*10465441SEvalZero 
196*10465441SEvalZero /**
197*10465441SEvalZero   \brief   Set Interrupt Priority
198*10465441SEvalZero   \details Sets the priority of an interrupt.
199*10465441SEvalZero   \note    The priority cannot be set for every core interrupt.
200*10465441SEvalZero   \param [in]      IRQn  Interrupt number.
201*10465441SEvalZero   \param [in]  priority  Priority to set.
202*10465441SEvalZero  */
drv_nvic_set_prio(int32_t IRQn,uint32_t priority)203*10465441SEvalZero void drv_nvic_set_prio(int32_t IRQn, uint32_t priority)
204*10465441SEvalZero {
205*10465441SEvalZero     NVIC->IPR[_IP_IDX(IRQn)]  = ((uint32_t)(NVIC->IPR[_IP_IDX(IRQn)]  & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
206*10465441SEvalZero                                  (((priority << (8U - s_nvic_prio_bits)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
207*10465441SEvalZero }
208*10465441SEvalZero 
209*10465441SEvalZero /**
210*10465441SEvalZero   \brief   Get Interrupt Priority
211*10465441SEvalZero   \details Reads the priority of an interrupt.
212*10465441SEvalZero            The interrupt number can be positive to specify an external (device specific) interrupt,
213*10465441SEvalZero            or negative to specify an internal (core) interrupt.
214*10465441SEvalZero   \param [in]   IRQn  Interrupt number.
215*10465441SEvalZero   \return             Interrupt Priority.
216*10465441SEvalZero                       Value is aligned automatically to the implemented priority bits of the microcontroller.
217*10465441SEvalZero  */
drv_nvic_get_prio(int32_t IRQn)218*10465441SEvalZero uint32_t drv_nvic_get_prio(int32_t IRQn)
219*10465441SEvalZero {
220*10465441SEvalZero     return ((uint32_t)(((NVIC->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn)) & (uint32_t)0xFFUL) >> (8U - s_nvic_prio_bits)));
221*10465441SEvalZero }
222*10465441SEvalZero 
223*10465441SEvalZero 
224*10465441SEvalZero /*@} end of CSI_Core_NVICFunctions */
225*10465441SEvalZero 
226*10465441SEvalZero /* ##################################    SysTick function  ############################################ */
227*10465441SEvalZero /**
228*10465441SEvalZero   \ingroup  CSI_Core_FunctionInterface
229*10465441SEvalZero   \defgroup CSI_Core_SysTickFunctions SysTick Functions
230*10465441SEvalZero   \brief    Functions that configure the System.
231*10465441SEvalZero   @{
232*10465441SEvalZero  */
233*10465441SEvalZero 
234*10465441SEvalZero 
235*10465441SEvalZero /**
236*10465441SEvalZero   \brief   CORE timer Configuration
237*10465441SEvalZero   \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
238*10465441SEvalZero            Counter is in free running mode to generate periodic interrupts.
239*10465441SEvalZero   \param [in]  ticks  Number of ticks between two interrupts.
240*10465441SEvalZero   \param [in]  IRQn   core timer Interrupt number.
241*10465441SEvalZero   \return          0  Function succeeded.
242*10465441SEvalZero   \return          1  Function failed.
243*10465441SEvalZero   \note    When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
244*10465441SEvalZero            function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
245*10465441SEvalZero            must contain a vendor-specific implementation of this function.
246*10465441SEvalZero  */
drv_coret_config(uint32_t ticks,int32_t IRQn)247*10465441SEvalZero uint32_t drv_coret_config(uint32_t ticks, int32_t IRQn)
248*10465441SEvalZero {
249*10465441SEvalZero     if ((ticks - 1UL) > CORET_LOAD_RELOAD_Msk)
250*10465441SEvalZero     {
251*10465441SEvalZero         return (1UL);                                                   /* Reload value impossible */
252*10465441SEvalZero     }
253*10465441SEvalZero 
254*10465441SEvalZero     CORET->LOAD  = (uint32_t)(ticks - 1UL);                           /* set reload register */
255*10465441SEvalZero     drv_nvic_set_prio(IRQn, (1UL << s_nvic_prio_bits) - 1UL);         /* set Priority for Systick Interrupt */
256*10465441SEvalZero     CORET->VAL   = 0UL;                                               /* Load the CORET Counter Value */
257*10465441SEvalZero     CORET->CTRL  = CORET_CTRL_CLKSOURCE_Msk |
258*10465441SEvalZero                    CORET_CTRL_TICKINT_Msk |
259*10465441SEvalZero                    CORET_CTRL_ENABLE_Msk;                           /* Enable CORET IRQ and CORET Timer */
260*10465441SEvalZero     return (0UL);                                                     /* Function successful */
261*10465441SEvalZero }
262*10465441SEvalZero 
263*10465441SEvalZero /**
264*10465441SEvalZero   \brief   get CORE timer reload value
265*10465441SEvalZero   \return          CORE timer counter value.
266*10465441SEvalZero  */
drv_coret_get_load(void)267*10465441SEvalZero uint32_t drv_coret_get_load(void)
268*10465441SEvalZero {
269*10465441SEvalZero     return CORET->LOAD;
270*10465441SEvalZero }
271*10465441SEvalZero 
272*10465441SEvalZero /**
273*10465441SEvalZero   \brief   get CORE timer counter value
274*10465441SEvalZero   \return          CORE timer counter value.
275*10465441SEvalZero  */
drv_coret_get_value(void)276*10465441SEvalZero uint32_t drv_coret_get_value(void)
277*10465441SEvalZero {
278*10465441SEvalZero     return CORET->VAL;
279*10465441SEvalZero }
280*10465441SEvalZero 
281*10465441SEvalZero /*@} end of CSI_Core_SysTickFunctions */
282*10465441SEvalZero 
283*10465441SEvalZero #if 0
284*10465441SEvalZero /* ##################################### DCC function ########################################### */
285*10465441SEvalZero /**
286*10465441SEvalZero   \ingroup  CSI_Core_FunctionInterface
287*10465441SEvalZero   \defgroup CSI_core_DebugFunctions HAD Functions
288*10465441SEvalZero   \brief    Functions that access the HAD debug interface.
289*10465441SEvalZero   @{
290*10465441SEvalZero  */
291*10465441SEvalZero 
292*10465441SEvalZero /**
293*10465441SEvalZero   \brief   HAD Send Character
294*10465441SEvalZero   \details Transmits a character via the HAD channel 0, and
295*10465441SEvalZero            \li Just returns when no debugger is connected that has booked the output.
296*10465441SEvalZero            \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted.
297*10465441SEvalZero   \param [in]     ch  Character to transmit.
298*10465441SEvalZero   \returns            Character to transmit.
299*10465441SEvalZero  */
300*10465441SEvalZero uint32_t HAD_SendChar(uint32_t ch)
301*10465441SEvalZero {
302*10465441SEvalZero     DCC->DERJR = (uint8_t)ch;
303*10465441SEvalZero 
304*10465441SEvalZero     return (ch);
305*10465441SEvalZero }
306*10465441SEvalZero 
307*10465441SEvalZero 
308*10465441SEvalZero /**
309*10465441SEvalZero   \brief   HAD Receive Character
310*10465441SEvalZero   \details Inputs a character via the external variable \ref HAD_RxBuffer.
311*10465441SEvalZero   \return             Received character.
312*10465441SEvalZero   \return         -1  No character pending.
313*10465441SEvalZero  */
314*10465441SEvalZero int32_t HAD_ReceiveChar(void)
315*10465441SEvalZero {
316*10465441SEvalZero     int32_t ch = -1;                           /* no character available */
317*10465441SEvalZero 
318*10465441SEvalZero     if (_FLD2VAL(DCC_EHSR_JW, DCC->EHSR))
319*10465441SEvalZero     {
320*10465441SEvalZero         ch = DCC->DERJW;
321*10465441SEvalZero     }
322*10465441SEvalZero 
323*10465441SEvalZero     return (ch);
324*10465441SEvalZero }
325*10465441SEvalZero 
326*10465441SEvalZero /**
327*10465441SEvalZero   \brief   HAD Check Character
328*10465441SEvalZero   \details Checks whether a character is pending for reading in the variable \ref HAD_RxBuffer.
329*10465441SEvalZero   \return          0  No character available.
330*10465441SEvalZero   \return          1  Character available.
331*10465441SEvalZero  */
332*10465441SEvalZero int32_t HAD_CheckChar(void)
333*10465441SEvalZero {
334*10465441SEvalZero     return _FLD2VAL(DCC_EHSR_JW, DCC->EHSR);                              /* no character available */
335*10465441SEvalZero }
336*10465441SEvalZero 
337*10465441SEvalZero #endif
338