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