core_ck802.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  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. #include <rthw.h>
  25. #include <rtthread.h>
  26. #include <stdint.h>
  27. #include <core_ck802.h>
  28. /* flag in interrupt handling */
  29. rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
  30. rt_uint32_t rt_thread_switch_interrupt_flag;
  31. /*******************************************************************************
  32. * Hardware Abstraction Layer
  33. Core Function Interface contains:
  34. - Core VIC Functions
  35. - Core CORET Functions
  36. - Core Register Access Functions
  37. ******************************************************************************/
  38. /**
  39. \defgroup CSI_Core_FunctionInterface Functions and Instructions Reference
  40. */
  41. /* ########################## NVIC functions #################################### */
  42. /**
  43. \ingroup CSI_Core_FunctionInterface
  44. \defgroup CSI_Core_NVICFunctions NVIC Functions
  45. \brief Functions that manage interrupts and exceptions via the NVIC.
  46. @{
  47. */
  48. /* Interrupt Priorities are WORD accessible only under CSKYv6M */
  49. /* The following MACROS handle generation of the register offset and byte masks */
  50. #define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
  51. #define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
  52. static uint32_t s_nvic_prio_bits = __NVIC_PRIO_BITS;
  53. /**
  54. \brief initialize the NVIC interrupt controller
  55. \param [in] prio_bits the priority bits of NVIC interrupt controller.
  56. */
  57. void drv_nvic_init(uint32_t prio_bits)
  58. {
  59. if (s_nvic_prio_bits >= 8U)
  60. {
  61. return;
  62. }
  63. s_nvic_prio_bits = prio_bits;
  64. }
  65. /**
  66. \brief Enable External Interrupt
  67. \details Enables a device-specific interrupt in the NVIC interrupt controller.
  68. \param [in] IRQn External interrupt number. Value cannot be negative.
  69. */
  70. void drv_nvic_enable_irq(int32_t IRQn)
  71. {
  72. NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
  73. #ifdef CONFIG_SYSTEM_SECURE
  74. NVIC->ISSR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
  75. #endif
  76. }
  77. /**
  78. \brief Disable External Interrupt
  79. \details Disables a device-specific interrupt in the NVIC interrupt controller.
  80. \param [in] IRQn External interrupt number. Value cannot be negative.
  81. */
  82. void drv_nvic_disable_irq(int32_t IRQn)
  83. {
  84. NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
  85. }
  86. /**
  87. \brief Enable External Secure Interrupt
  88. \details Enables a secure device-specific interrupt in the NVIC interrupt controller.
  89. \param [in] IRQn External interrupt number. Value cannot be negative.
  90. */
  91. void drv_nvic_enable_sirq(int32_t IRQn)
  92. {
  93. NVIC->ISSR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
  94. }
  95. /**
  96. \brief Get Pending Interrupt
  97. \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
  98. \param [in] IRQn Interrupt number.
  99. \return 0 Interrupt status is not pending.
  100. \return 1 Interrupt status is pending.
  101. */
  102. uint32_t drv_nvic_get_pending_irq(int32_t IRQn)
  103. {
  104. return ((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
  105. }
  106. /**
  107. \brief Set Pending Interrupt
  108. \details Sets the pending bit of an external interrupt.
  109. \param [in] IRQn Interrupt number. Value cannot be negative.
  110. */
  111. void drv_nvic_set_pending_irq(int32_t IRQn)
  112. {
  113. NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
  114. }
  115. /**
  116. \brief Clear Pending Interrupt
  117. \details Clears the pending bit of an external interrupt.
  118. \param [in] IRQn External interrupt number. Value cannot be negative.
  119. */
  120. void drv_nvic_clear_pending_irq(int32_t IRQn)
  121. {
  122. NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
  123. }
  124. /**
  125. \brief Get Wake up Interrupt
  126. \details Reads the wake up register in the NVIC and returns the pending bit for the specified interrupt.
  127. \param [in] IRQn Interrupt number.
  128. \return 0 Interrupt is not set as wake up interrupt.
  129. \return 1 Interrupt is set as wake up interrupt.
  130. */
  131. uint32_t drv_nvic_get_wakeup_irq(int32_t IRQn)
  132. {
  133. return ((uint32_t)(((NVIC->IWER[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
  134. }
  135. /**
  136. \brief Set Wake up Interrupt
  137. \details Sets the wake up bit of an external interrupt.
  138. \param [in] IRQn Interrupt number. Value cannot be negative.
  139. */
  140. void drv_nvic_set_wakeup_irq(int32_t IRQn)
  141. {
  142. NVIC->IWER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
  143. }
  144. /**
  145. \brief Clear Wake up Interrupt
  146. \details Clears the wake up bit of an external interrupt.
  147. \param [in] IRQn External interrupt number. Value cannot be negative.
  148. */
  149. void drv_nvic_clear_wakeup_irq(int32_t IRQn)
  150. {
  151. NVIC->IWDR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
  152. }
  153. /**
  154. \brief Get Active Interrupt
  155. \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt.
  156. \param [in] IRQn Device specific interrupt number.
  157. \return 0 Interrupt status is not active.
  158. \return 1 Interrupt status is active.
  159. \note IRQn must not be negative.
  160. */
  161. uint32_t drv_nvic_get_active(int32_t IRQn)
  162. {
  163. return ((uint32_t)(((NVIC->IABR[0] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
  164. }
  165. /**
  166. \brief Set Threshold register
  167. \details set the threshold register in the NVIC.
  168. \param [in] VectThreshold specific vecter threshold.
  169. \param [in] PrioThreshold specific priority threshold.
  170. */
  171. void drv_nvic_set_threshold(uint32_t VectThreshold, uint32_t PrioThreshold)
  172. {
  173. NVIC->IPTR = 0x80000000 | (((VectThreshold + 32) & 0xFF) << 8) | ((PrioThreshold & 0x3) << 6);
  174. }
  175. /**
  176. \brief Set Interrupt Priority
  177. \details Sets the priority of an interrupt.
  178. \note The priority cannot be set for every core interrupt.
  179. \param [in] IRQn Interrupt number.
  180. \param [in] priority Priority to set.
  181. */
  182. void drv_nvic_set_prio(int32_t IRQn, uint32_t priority)
  183. {
  184. NVIC->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
  185. (((priority << (8U - s_nvic_prio_bits)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
  186. }
  187. /**
  188. \brief Get Interrupt Priority
  189. \details Reads the priority of an interrupt.
  190. The interrupt number can be positive to specify an external (device specific) interrupt,
  191. or negative to specify an internal (core) interrupt.
  192. \param [in] IRQn Interrupt number.
  193. \return Interrupt Priority.
  194. Value is aligned automatically to the implemented priority bits of the microcontroller.
  195. */
  196. uint32_t drv_nvic_get_prio(int32_t IRQn)
  197. {
  198. return ((uint32_t)(((NVIC->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn)) & (uint32_t)0xFFUL) >> (8U - s_nvic_prio_bits)));
  199. }
  200. /*@} end of CSI_Core_NVICFunctions */
  201. /* ################################## SysTick function ############################################ */
  202. /**
  203. \ingroup CSI_Core_FunctionInterface
  204. \defgroup CSI_Core_SysTickFunctions SysTick Functions
  205. \brief Functions that configure the System.
  206. @{
  207. */
  208. /**
  209. \brief CORE timer Configuration
  210. \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
  211. Counter is in free running mode to generate periodic interrupts.
  212. \param [in] ticks Number of ticks between two interrupts.
  213. \param [in] IRQn core timer Interrupt number.
  214. \return 0 Function succeeded.
  215. \return 1 Function failed.
  216. \note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
  217. function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
  218. must contain a vendor-specific implementation of this function.
  219. */
  220. uint32_t drv_coret_config(uint32_t ticks, int32_t IRQn)
  221. {
  222. if ((ticks - 1UL) > CORET_LOAD_RELOAD_Msk)
  223. {
  224. return (1UL); /* Reload value impossible */
  225. }
  226. CORET->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
  227. drv_nvic_set_prio(IRQn, (1UL << s_nvic_prio_bits) - 1UL); /* set Priority for Systick Interrupt */
  228. CORET->VAL = 0UL; /* Load the CORET Counter Value */
  229. CORET->CTRL = CORET_CTRL_CLKSOURCE_Msk |
  230. CORET_CTRL_TICKINT_Msk |
  231. CORET_CTRL_ENABLE_Msk; /* Enable CORET IRQ and CORET Timer */
  232. return (0UL); /* Function successful */
  233. }
  234. /**
  235. \brief get CORE timer reload value
  236. \return CORE timer counter value.
  237. */
  238. uint32_t drv_coret_get_load(void)
  239. {
  240. return CORET->LOAD;
  241. }
  242. /**
  243. \brief get CORE timer counter value
  244. \return CORE timer counter value.
  245. */
  246. uint32_t drv_coret_get_value(void)
  247. {
  248. return CORET->VAL;
  249. }
  250. /*@} end of CSI_Core_SysTickFunctions */
  251. #if 0
  252. /* ##################################### DCC function ########################################### */
  253. /**
  254. \ingroup CSI_Core_FunctionInterface
  255. \defgroup CSI_core_DebugFunctions HAD Functions
  256. \brief Functions that access the HAD debug interface.
  257. @{
  258. */
  259. /**
  260. \brief HAD Send Character
  261. \details Transmits a character via the HAD channel 0, and
  262. \li Just returns when no debugger is connected that has booked the output.
  263. \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted.
  264. \param [in] ch Character to transmit.
  265. \returns Character to transmit.
  266. */
  267. uint32_t HAD_SendChar(uint32_t ch)
  268. {
  269. DCC->DERJR = (uint8_t)ch;
  270. return (ch);
  271. }
  272. /**
  273. \brief HAD Receive Character
  274. \details Inputs a character via the external variable \ref HAD_RxBuffer.
  275. \return Received character.
  276. \return -1 No character pending.
  277. */
  278. int32_t HAD_ReceiveChar(void)
  279. {
  280. int32_t ch = -1; /* no character available */
  281. if (_FLD2VAL(DCC_EHSR_JW, DCC->EHSR))
  282. {
  283. ch = DCC->DERJW;
  284. }
  285. return (ch);
  286. }
  287. /**
  288. \brief HAD Check Character
  289. \details Checks whether a character is pending for reading in the variable \ref HAD_RxBuffer.
  290. \return 0 No character available.
  291. \return 1 Character available.
  292. */
  293. int32_t HAD_CheckChar(void)
  294. {
  295. return _FLD2VAL(DCC_EHSR_JW, DCC->EHSR); /* no character available */
  296. }
  297. #endif