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