interrupt.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. //###########################################################################
  2. //
  3. // FILE: interrupt.c
  4. //
  5. // TITLE: Stellaris style wrapper driver for C28x PIE Interrupt Controller.
  6. //
  7. //###########################################################################
  8. // $TI Release: F2837xD Support Library v3.05.00.00 $
  9. // $Release Date: Tue Jun 26 03:15:23 CDT 2018 $
  10. // $Copyright:
  11. // Copyright (C) 2013-2018 Texas Instruments Incorporated - http://www.ti.com/
  12. //
  13. // Redistribution and use in source and binary forms, with or without
  14. // modification, are permitted provided that the following conditions
  15. // are met:
  16. //
  17. // Redistributions of source code must retain the above copyright
  18. // notice, this list of conditions and the following disclaimer.
  19. //
  20. // Redistributions in binary form must reproduce the above copyright
  21. // notice, this list of conditions and the following disclaimer in the
  22. // documentation and/or other materials provided with the
  23. // distribution.
  24. //
  25. // Neither the name of Texas Instruments Incorporated nor the names of
  26. // its contributors may be used to endorse or promote products derived
  27. // from this software without specific prior written permission.
  28. //
  29. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  30. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  31. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  32. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  33. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  34. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  35. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  36. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  37. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  38. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  39. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  40. // $
  41. //###########################################################################
  42. //*****************************************************************************
  43. //
  44. //! \addtogroup interrupt_api
  45. //! @{
  46. //
  47. //*****************************************************************************
  48. #include "F28x_Project.h"
  49. #include "inc/hw_types.h"
  50. #include "driverlib/interrupt.h"
  51. #include <stdbool.h>
  52. #include <stdint.h>
  53. #include <string.h>
  54. //*****************************************************************************
  55. //
  56. //! \internal
  57. //! The default interrupt handler.
  58. //!
  59. //! This is the default interrupt handler. Whenever an interrupt is
  60. //! unregisterd this handler takes it place.
  61. //!
  62. //! \return None.
  63. //
  64. //*****************************************************************************
  65. __interrupt void IntDefaultHandler(void)
  66. {
  67. asm(" ESTOP0");
  68. return;
  69. }
  70. //*****************************************************************************
  71. //
  72. //! Enables the processor interrupt.
  73. //!
  74. //! Allows the processor to respond to interrupts. This does not affect the
  75. //! set of interrupts enabled in the interrupt controller; it just gates the
  76. //! single interrupt from the controller to the processor.
  77. //!
  78. //! \note Previously, this function had no return value. As such, it was
  79. //! possible to include <tt>interrupt.h</tt> and call this function without
  80. //! having included <tt>hw_types.h</tt>. Now that the return is a
  81. //! <tt>bool</tt>, a compiler error will occur in this case. The solution
  82. //! is to include <tt>hw_types.h</tt> before including <tt>interrupt.h</tt>.
  83. //!
  84. //! \return Returns \b true if interrupts were disabled when the function was
  85. //! called or \b false if they were initially enabled.
  86. //
  87. //*****************************************************************************
  88. bool
  89. IntMasterEnable(void)
  90. {
  91. //
  92. // Enable processor interrupts.
  93. //
  94. return __enable_interrupts() & 0x1;
  95. }
  96. //*****************************************************************************
  97. //
  98. //! Disables the processor interrupt.
  99. //!
  100. //! Prevents the processor from receiving interrupts. This does not affect the
  101. //! set of interrupts enabled in the interrupt controller; it just gates the
  102. //! single interrupt from the controller to the processor.
  103. //!
  104. //! \note Previously, this function had no return value. As such, it was
  105. //! possible to include <tt>interrupt.h</tt> and call this function without
  106. //! having included <tt>hw_types.h</tt>. Now that the return is a
  107. //! <tt>bool</tt>, a compiler error will occur in this case. The solution
  108. //! is to include <tt>hw_types.h</tt> before including <tt>interrupt.h</tt>.
  109. //!
  110. //! \return Returns \b true if interrupts were already disabled when the
  111. //! function was called or \b false if they were initially enabled.
  112. //
  113. //*****************************************************************************
  114. bool
  115. IntMasterDisable(void)
  116. {
  117. //
  118. // Disable processor interrupts.
  119. //
  120. return __disable_interrupts() & 0x1;
  121. }
  122. //*****************************************************************************
  123. //
  124. //! Registers a function to be called when an interrupt occurs.
  125. //
  126. //! Assumes PIE is enabled
  127. //!
  128. //! \param ui32Interrupt specifies the interrupt in question.
  129. //! \param pfnHandler is a pointer to the function to be called.
  130. //!
  131. //! This function is used to specify the handler function to be called when the
  132. //! given interrupt is asserted to the processor. When the interrupt occurs,
  133. //! if it is enabled (via IntEnable()), the handler function will be called in
  134. //! interrupt context. Since the handler function can pre-empt other code, care
  135. //! must be taken to protect memory or peripherals that are accessed by the
  136. //! handler and other non-handler code.
  137. //!
  138. //! \return None.
  139. //
  140. //*****************************************************************************
  141. void
  142. IntRegister(uint32_t ui32Interrupt, void (*pfnHandler)(void))
  143. {
  144. EALLOW;
  145. //Copy ISR address into PIE table
  146. memcpy((uint16_t *) &PieVectTable + ((ui32Interrupt & 0xFFFF0000) >> 16)*2, (uint16_t *) &pfnHandler, sizeof(pfnHandler));
  147. EDIS;
  148. }
  149. //*****************************************************************************
  150. //
  151. //! Unregisters the function to be called when an interrupt occurs.
  152. //!
  153. //! \param ui32Interrupt specifies the interrupt in question.
  154. //!
  155. //! This function is used to indicate that no handler should be called when the
  156. //! given interrupt is asserted to the processor. The interrupt source will be
  157. //! automatically disabled (via IntDisable()) if necessary.
  158. //!
  159. //! \sa IntRegister() for important information about registering interrupt
  160. //! handlers.
  161. //!
  162. //! \return None.
  163. //
  164. //*****************************************************************************
  165. void
  166. IntUnregister(uint32_t ui32Interrupt)
  167. {
  168. uint32_t temp;
  169. temp = (uint32_t) IntDefaultHandler;
  170. EALLOW;
  171. //Copy default ISR address into PIE table
  172. memcpy((uint16_t *) &PieVectTable + ((ui32Interrupt & 0xFFFF0000) >> 16)*2, (uint16_t *) &temp, sizeof(temp));
  173. EDIS;
  174. }
  175. //*****************************************************************************
  176. //
  177. //! Enables an interrupt.
  178. //!
  179. //! \param ui32Interrupt specifies the interrupt to be enabled.
  180. //!
  181. //! The specified interrupt is enabled in the interrupt controller. Other
  182. //! enables for the interrupt (such as at the peripheral level) are unaffected
  183. //! by this function.
  184. //!
  185. //! \return None.
  186. //
  187. //*****************************************************************************
  188. void
  189. IntEnable(uint32_t ui32Interrupt)
  190. {
  191. uint16_t ui16IntsEnabled;
  192. ui32Interrupt = ui32Interrupt >> 16;
  193. EALLOW;
  194. //Ensure that PIE is enabled
  195. PieCtrlRegs.PIECTRL.bit.ENPIE=1;
  196. ui16IntsEnabled = IntMasterDisable();
  197. if (ui32Interrupt >= 0x20 && ui32Interrupt <= 0x7F) //Lower PIE table
  198. {
  199. //Enable Individual PIE interrupt
  200. *(uint16_t *)((&PieCtrlRegs.PIEIER1.all) + (((ui32Interrupt-0x20)/8))*2) |= 1 << ((ui32Interrupt-0x20)%8);
  201. // Wait for any pending interrupts to get to the CPU
  202. asm(" nop");
  203. asm(" nop");
  204. asm(" nop");
  205. asm(" nop");
  206. asm(" nop");
  207. //Clear the CPU flag
  208. IntIFRClear(1 << ((ui32Interrupt - 0x20)/8));
  209. //Acknowlege any interrupts
  210. PieCtrlRegs.PIEACK.all = 1 << ((ui32Interrupt - 0x20)/8);
  211. //Enable PIE Group Interrupt
  212. IER |= 1 << ((ui32Interrupt - 0x20)/8);
  213. }
  214. else if (ui32Interrupt >= 0x80) //Upper PIE table
  215. {
  216. //Enable Individual PIE interrupt
  217. *(uint16_t *)((&PieCtrlRegs.PIEIER1.all) + (((ui32Interrupt-0x80)/8))*2) |= 1 << (((ui32Interrupt-0x80)%8)+8);
  218. // Wait for any pending interrupts to get to the CPU
  219. asm(" nop");
  220. asm(" nop");
  221. asm(" nop");
  222. asm(" nop");
  223. asm(" nop");
  224. //Clear the CPU flag
  225. IntIFRClear(1 << ((ui32Interrupt - 0x80)/8));
  226. //Acknowlege any interrupts
  227. PieCtrlRegs.PIEACK.all = 1 << ((ui32Interrupt - 0x80)/8);
  228. //Enable PIE Group Interrupt
  229. IER |= 1 << ((ui32Interrupt - 0x80)/8);
  230. }
  231. else if (ui32Interrupt >= 0x0D && ui32Interrupt <= 0x10) //INT13, INT14, DLOGINT, & RTOSINT
  232. {
  233. //Enable PIE Group Interrupt
  234. IER |= 1 << (ui32Interrupt - 1);
  235. }
  236. else
  237. {
  238. //Other interrupts
  239. }
  240. EDIS;
  241. //Re-enable interrupts if they were enabled
  242. if(!ui16IntsEnabled){
  243. IntMasterEnable();
  244. }
  245. }
  246. //*****************************************************************************
  247. //
  248. //! Disables an interrupt.
  249. //!
  250. //! \param ui32Interrupt specifies the interrupt to be disabled.
  251. //!
  252. //! The specified interrupt is disabled in the interrupt controller. Other
  253. //! enables for the interrupt (such as at the peripheral level) are unaffected
  254. //! by this function.
  255. //!
  256. //! \return None.
  257. //
  258. //*****************************************************************************
  259. void
  260. IntDisable(uint32_t ui32Interrupt)
  261. {
  262. uint16_t ui16IntsEnabled;
  263. ui32Interrupt = ui32Interrupt >> 16;
  264. EALLOW;
  265. ui16IntsEnabled = IntMasterDisable();
  266. if (ui32Interrupt >= 0x20 && ui32Interrupt <= 0x7F) //Lower PIE table
  267. {
  268. //Disable Individual PIE interrupt
  269. *(uint16_t *)((&PieCtrlRegs.PIEIER1.all) + (((ui32Interrupt-0x20)/8))*2) &= ~(1 << ((ui32Interrupt-0x20)%8));
  270. // Wait for any pending interrupts to get to the CPU
  271. asm(" nop");
  272. asm(" nop");
  273. asm(" nop");
  274. asm(" nop");
  275. asm(" nop");
  276. //Clear the CPU flag
  277. IntIFRClear(1 << ((ui32Interrupt - 0x20)/8));
  278. //Acknowlege any interrupts
  279. PieCtrlRegs.PIEACK.all = 1 << ((ui32Interrupt - 0x20)/8);
  280. }
  281. else if (ui32Interrupt >= 0x80) //Upper PIE table
  282. {
  283. //Disable Individual PIE interrupt
  284. *(uint16_t *)((&PieCtrlRegs.PIEIER1.all) + (((ui32Interrupt-0x80)/8))*2) &= ~(1 << (((ui32Interrupt-0x80)%8)+8));
  285. // Wait for any pending interrupts to get to the CPU
  286. asm(" nop");
  287. asm(" nop");
  288. asm(" nop");
  289. asm(" nop");
  290. asm(" nop");
  291. //Clear the CPU flag
  292. IntIFRClear(1 << ((ui32Interrupt - 0x80)/8));
  293. //Acknowlege any interrupts
  294. PieCtrlRegs.PIEACK.all = 1 << ((ui32Interrupt - 0x80)/8);
  295. }
  296. else if (ui32Interrupt >= 0x0D && ui32Interrupt <= 0x10) //INT13, INT14, DLOGINT, & RTOSINT //Work-around Case
  297. {
  298. //Disable PIE Group Interrupt
  299. IER &= ~(1 << (ui32Interrupt - 1));
  300. }
  301. else
  302. {
  303. //Other Interrupts
  304. }
  305. EDIS;
  306. //Re-enable interrupts if they were enabled
  307. if(!ui16IntsEnabled){
  308. IntMasterEnable();
  309. }
  310. }
  311. void IntIFRClear(uint16_t ui16Interrupts)
  312. {
  313. switch(ui16Interrupts){
  314. case 0x0001:
  315. IFR &= ~0x0001;
  316. break;
  317. case 0x0002:
  318. IFR &= ~0x0002;
  319. break;
  320. case 0x0004:
  321. IFR &= ~0x0004;
  322. break;
  323. case 0x0008:
  324. IFR &= ~0x0008;
  325. break;
  326. case 0x0010:
  327. IFR &= ~0x0010;
  328. break;
  329. case 0x0020:
  330. IFR &= ~0x0020;
  331. break;
  332. case 0x0040:
  333. IFR &= ~0x0040;
  334. break;
  335. case 0x0080:
  336. IFR &= ~0x0080;
  337. break;
  338. case 0x0100:
  339. IFR &= ~0x0100;
  340. break;
  341. case 0x0200:
  342. IFR &= ~0x0200;
  343. break;
  344. case 0x0400:
  345. IFR &= ~0x0400;
  346. break;
  347. case 0x0800:
  348. IFR &= ~0x0800;
  349. break;
  350. case 0x1000:
  351. IFR &= ~0x1000;
  352. break;
  353. case 0x2000:
  354. IFR &= ~0x2000;
  355. break;
  356. case 0x4000:
  357. IFR &= ~0x4000;
  358. break;
  359. case 0x8000:
  360. IFR &= ~0x8000;
  361. break;
  362. default:
  363. break;
  364. }
  365. }
  366. //*****************************************************************************
  367. //
  368. // Close the Doxygen group.
  369. //! @}
  370. //
  371. //*****************************************************************************