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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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