2 * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 /******************************************************************************
19 * @brief CSI CK802 Core Peripheral Access Layer File
22 ******************************************************************************/
25 #include <core_ck802.h>
28 /*******************************************************************************
29 * Hardware Abstraction Layer
30 Core Function Interface contains:
32 - Core CORET Functions
33 - Core Register Access Functions
34 ******************************************************************************/
36 \defgroup CSI_Core_FunctionInterface Functions and Instructions Reference
39 /* ########################## NVIC functions #################################### */
41 \ingroup CSI_Core_FunctionInterface
42 \defgroup CSI_Core_NVICFunctions NVIC Functions
43 \brief Functions that manage interrupts and exceptions via the NVIC.
47 /* Interrupt Priorities are WORD accessible only under CSKYv6M */
48 /* The following MACROS handle generation of the register offset and byte masks */
49 #define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
50 #define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
52 static uint32_t s_nvic_prio_bits = __NVIC_PRIO_BITS;
55 \brief initialize the NVIC interrupt controller
56 \param [in] prio_bits the priority bits of NVIC interrupt controller.
58 void drv_nvic_init(uint32_t prio_bits)
60 if (s_nvic_prio_bits >= 8U) {
64 s_nvic_prio_bits = prio_bits;
68 \brief Enable External Interrupt
69 \details Enables a device-specific interrupt in the NVIC interrupt controller.
70 \param [in] IRQn External interrupt number. Value cannot be negative.
72 void drv_nvic_enable_irq(int32_t IRQn)
74 NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
75 NVIC->ISSR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
79 \brief Disable External Interrupt
80 \details Disables a device-specific interrupt in the NVIC interrupt controller.
81 \param [in] IRQn External interrupt number. Value cannot be negative.
83 void drv_nvic_disable_irq(int32_t IRQn)
85 NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
89 \brief Enable External Secure Interrupt
90 \details Enables a secure device-specific interrupt in the NVIC interrupt controller.
91 \param [in] IRQn External interrupt number. Value cannot be negative.
93 void drv_nvic_enable_sirq(int32_t IRQn)
95 NVIC->ISSR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
99 \brief Get Pending Interrupt
100 \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
101 \param [in] IRQn Interrupt number.
102 \return 0 Interrupt status is not pending.
103 \return 1 Interrupt status is pending.
105 uint32_t drv_nvic_get_pending_irq(int32_t IRQn)
107 return ((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
111 \brief Set Pending Interrupt
112 \details Sets the pending bit of an external interrupt.
113 \param [in] IRQn Interrupt number. Value cannot be negative.
115 void drv_nvic_set_pending_irq(int32_t IRQn)
117 NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
121 \brief Clear Pending Interrupt
122 \details Clears the pending bit of an external interrupt.
123 \param [in] IRQn External interrupt number. Value cannot be negative.
125 void drv_nvic_clear_pending_irq(int32_t IRQn)
127 NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
131 \brief Get Wake up Interrupt
132 \details Reads the wake up register in the NVIC and returns the pending bit for the specified interrupt.
133 \param [in] IRQn Interrupt number.
134 \return 0 Interrupt is not set as wake up interrupt.
135 \return 1 Interrupt is set as wake up interrupt.
137 uint32_t drv_nvic_get_wakeup_irq(int32_t IRQn)
139 return ((uint32_t)(((NVIC->IWER[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
143 \brief Set Wake up Interrupt
144 \details Sets the wake up bit of an external interrupt.
145 \param [in] IRQn Interrupt number. Value cannot be negative.
147 void drv_nvic_set_wakeup_irq(int32_t IRQn)
149 NVIC->IWER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
153 \brief Clear Wake up Interrupt
154 \details Clears the wake up bit of an external interrupt.
155 \param [in] IRQn External interrupt number. Value cannot be negative.
157 void drv_nvic_clear_wakeup_irq(int32_t IRQn)
159 NVIC->IWDR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
163 \brief Get Active Interrupt
164 \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt.
165 \param [in] IRQn Device specific interrupt number.
166 \return 0 Interrupt status is not active.
167 \return 1 Interrupt status is active.
168 \note IRQn must not be negative.
170 uint32_t drv_nvic_get_active(int32_t IRQn)
172 return ((uint32_t)(((NVIC->IABR[0] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
176 \brief Set Threshold register
177 \details set the threshold register in the NVIC.
178 \param [in] VectThreshold specific vecter threshold.
179 \param [in] PrioThreshold specific priority threshold.
181 void drv_nvic_set_threshold(uint32_t VectThreshold, uint32_t PrioThreshold)
183 NVIC->IPTR = 0x80000000 | (((VectThreshold + 32) & 0xFF) << 8) | ((PrioThreshold & 0x3) << 6);
187 \brief Set Interrupt Priority
188 \details Sets the priority of an interrupt.
189 \note The priority cannot be set for every core interrupt.
190 \param [in] IRQn Interrupt number.
191 \param [in] priority Priority to set.
193 void drv_nvic_set_prio(int32_t IRQn, uint32_t priority)
195 NVIC->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
196 (((priority << (8U - s_nvic_prio_bits)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
200 \brief Get Interrupt Priority
201 \details Reads the priority of an interrupt.
202 The interrupt number can be positive to specify an external (device specific) interrupt,
203 or negative to specify an internal (core) interrupt.
204 \param [in] IRQn Interrupt number.
205 \return Interrupt Priority.
206 Value is aligned automatically to the implemented priority bits of the microcontroller.
208 uint32_t drv_nvic_get_prio(int32_t IRQn)
210 return ((uint32_t)(((NVIC->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn)) & (uint32_t)0xFFUL) >> (8U - s_nvic_prio_bits)));
214 /*@} end of CSI_Core_NVICFunctions */
216 /* ################################## SysTick function ############################################ */
218 \ingroup CSI_Core_FunctionInterface
219 \defgroup CSI_Core_SysTickFunctions SysTick Functions
220 \brief Functions that configure the System.
226 \brief CORE timer Configuration
227 \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
228 Counter is in free running mode to generate periodic interrupts.
229 \param [in] ticks Number of ticks between two interrupts.
230 \param [in] IRQn core timer Interrupt number.
231 \return 0 Function succeeded.
232 \return 1 Function failed.
233 \note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
234 function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
235 must contain a vendor-specific implementation of this function.
237 uint32_t drv_coret_config(uint32_t ticks, int32_t IRQn)
239 if ((ticks - 1UL) > CORET_LOAD_RELOAD_Msk) {
240 return (1UL); /* Reload value impossible */
243 CORET->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
244 //drv_nvic_set_prio(IRQn, (1UL << s_nvic_prio_bits) - 1UL); fix me /* set Priority for Systick Interrupt */
245 CORET->VAL = 0UL; /* Load the CORET Counter Value */
246 CORET->CTRL = CORET_CTRL_CLKSOURCE_Msk |
247 CORET_CTRL_TICKINT_Msk |
248 CORET_CTRL_ENABLE_Msk; /* Enable CORET IRQ and CORET Timer */
249 return (0UL); /* Function successful */
253 \brief get CORE timer reload value
254 \return CORE timer counter value.
256 uint32_t drv_coret_get_load(void)
262 \brief get CORE timer counter value
263 \return CORE timer counter value.
265 uint32_t drv_coret_get_value(void)
270 /*@} end of CSI_Core_SysTickFunctions */
273 /* ##################################### DCC function ########################################### */
275 \ingroup CSI_Core_FunctionInterface
276 \defgroup CSI_core_DebugFunctions HAD Functions
277 \brief Functions that access the HAD debug interface.
282 \brief HAD Send Character
283 \details Transmits a character via the HAD channel 0, and
284 \li Just returns when no debugger is connected that has booked the output.
285 \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted.
286 \param [in] ch Character to transmit.
287 \returns Character to transmit.
289 uint32_t HAD_SendChar(uint32_t ch)
291 DCC->DERJR = (uint8_t)ch;
298 \brief HAD Receive Character
299 \details Inputs a character via the external variable \ref HAD_RxBuffer.
300 \return Received character.
301 \return -1 No character pending.
303 int32_t HAD_ReceiveChar(void)
305 int32_t ch = -1; /* no character available */
307 if (_FLD2VAL(DCC_EHSR_JW, DCC->EHSR)) {
316 \brief HAD Check Character
317 \details Checks whether a character is pending for reading in the variable \ref HAD_RxBuffer.
318 \return 0 No character available.
319 \return 1 Character available.
321 int32_t HAD_CheckChar(void)
323 return _FLD2VAL(DCC_EHSR_JW, DCC->EHSR); /* no character available */
328 /*@} end of CSI_core_DebugFunctions */