st25r3916_irq.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. /******************************************************************************
  2. * \attention
  3. *
  4. * <h2><center>&copy; COPYRIGHT 2020 STMicroelectronics</center></h2>
  5. *
  6. * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
  7. * You may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at:
  9. *
  10. * www.st.com/myliberty
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
  15. * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
  17. * See the License for the specific language governing permissions and
  18. * limitations under the License.
  19. *
  20. ******************************************************************************/
  21. /*
  22. * PROJECT: ST25R3916 firmware
  23. * Revision:
  24. * LANGUAGE: ISO C99
  25. */
  26. /*! \file
  27. *
  28. * \author Gustavo Patricio
  29. *
  30. * \brief ST25R3916 Interrupt handling
  31. *
  32. */
  33. /*
  34. ******************************************************************************
  35. * INCLUDES
  36. ******************************************************************************
  37. */
  38. #include "st25r3916_irq.h"
  39. #include "st25r3916_com.h"
  40. #include "st25r3916_led.h"
  41. #include "st25r3916.h"
  42. #include "utils.h"
  43. /*
  44. ******************************************************************************
  45. * LOCAL DATA TYPES
  46. ******************************************************************************
  47. */
  48. /*! Holds current and previous interrupt callback pointer as well as current Interrupt status and mask */
  49. typedef struct
  50. {
  51. void (*prevCallback)(void); /*!< call back function for ST25R3916 interrupt */
  52. void (*callback)(void); /*!< call back function for ST25R3916 interrupt */
  53. uint32_t status; /*!< latest interrupt status */
  54. uint32_t mask; /*!< Interrupt mask. Negative mask = ST25R3916 mask regs */
  55. } st25r3916Interrupt;
  56. /*
  57. ******************************************************************************
  58. * GLOBAL DEFINES
  59. ******************************************************************************
  60. */
  61. /*! Length of the interrupt registers */
  62. #define ST25R3916_INT_REGS_LEN ( (ST25R3916_REG_IRQ_TARGET - ST25R3916_REG_IRQ_MAIN) + 1U )
  63. /*
  64. ******************************************************************************
  65. * GLOBAL VARIABLES
  66. ******************************************************************************
  67. */
  68. static volatile st25r3916Interrupt st25r3916interrupt; /*!< Instance of ST25R3916 interrupt */
  69. /*
  70. ******************************************************************************
  71. * GLOBAL FUNCTIONS
  72. ******************************************************************************
  73. */
  74. void st25r3916InitInterrupts( void )
  75. {
  76. platformIrqST25RPinInitialize();
  77. platformIrqST25RSetCallback( st25r3916Isr );
  78. st25r3916interrupt.callback = NULL;
  79. st25r3916interrupt.prevCallback = NULL;
  80. st25r3916interrupt.status = ST25R3916_IRQ_MASK_NONE;
  81. st25r3916interrupt.mask = ST25R3916_IRQ_MASK_NONE;
  82. }
  83. /*******************************************************************************/
  84. void st25r3916Isr( void )
  85. {
  86. st25r3916CheckForReceivedInterrupts();
  87. // Check if callback is set and run it
  88. if( NULL != st25r3916interrupt.callback )
  89. {
  90. st25r3916interrupt.callback();
  91. }
  92. }
  93. /*******************************************************************************/
  94. void st25r3916CheckForReceivedInterrupts( void )
  95. {
  96. uint8_t iregs[ST25R3916_INT_REGS_LEN];
  97. uint32_t irqStatus;
  98. /* Initialize iregs */
  99. irqStatus = ST25R3916_IRQ_MASK_NONE;
  100. ST_MEMSET( iregs, (int32_t)(ST25R3916_IRQ_MASK_ALL & 0xFFU), ST25R3916_INT_REGS_LEN );
  101. /* In case the IRQ is Edge (not Level) triggered read IRQs until done */
  102. while( platformGpioIsHigh( ST25R_INT_PORT, ST25R_INT_PIN ) )
  103. {
  104. st25r3916ReadMultipleRegisters( ST25R3916_REG_IRQ_MAIN, iregs, ST25R3916_INT_REGS_LEN );
  105. irqStatus |= (uint32_t)iregs[0];
  106. irqStatus |= (uint32_t)iregs[1]<<8;
  107. irqStatus |= (uint32_t)iregs[2]<<16;
  108. irqStatus |= (uint32_t)iregs[3]<<24;
  109. }
  110. /* Forward all interrupts, even masked ones to application */
  111. platformProtectST25RIrqStatus();
  112. st25r3916interrupt.status |= irqStatus;
  113. platformUnprotectST25RIrqStatus();
  114. /* Send an IRQ event to LED handling */
  115. st25r3916ledEvtIrq( st25r3916interrupt.status );
  116. }
  117. /*******************************************************************************/
  118. void st25r3916ModifyInterrupts(uint32_t clr_mask, uint32_t set_mask)
  119. {
  120. uint8_t i;
  121. uint32_t old_mask;
  122. uint32_t new_mask;
  123. old_mask = st25r3916interrupt.mask;
  124. new_mask = ((~old_mask & set_mask) | (old_mask & clr_mask));
  125. st25r3916interrupt.mask &= ~clr_mask;
  126. st25r3916interrupt.mask |= set_mask;
  127. for(i=0; i<ST25R3916_INT_REGS_LEN; i++)
  128. {
  129. if( ((new_mask >> (8U*i)) & 0xFFU) == 0U )
  130. {
  131. continue;
  132. }
  133. st25r3916WriteRegister(ST25R3916_REG_IRQ_MASK_MAIN + i, (uint8_t)((st25r3916interrupt.mask>>(8U*i)) & 0xFFU) );
  134. }
  135. return;
  136. }
  137. /*******************************************************************************/
  138. uint32_t st25r3916WaitForInterruptsTimed( uint32_t mask, uint16_t tmo )
  139. {
  140. uint32_t tmrDelay;
  141. uint32_t status;
  142. tmrDelay = platformTimerCreate( tmo );
  143. /* Run until specific interrupt has happen or the timer has expired */
  144. do
  145. {
  146. status = (st25r3916interrupt.status & mask);
  147. } while( ( !platformTimerIsExpired( tmrDelay ) || (tmo == 0U)) && (status == 0U) );
  148. platformTimerDestroy( tmrDelay );
  149. status = st25r3916interrupt.status & mask;
  150. platformProtectST25RIrqStatus();
  151. st25r3916interrupt.status &= ~status;
  152. platformUnprotectST25RIrqStatus();
  153. return status;
  154. }
  155. /*******************************************************************************/
  156. uint32_t st25r3916GetInterrupt( uint32_t mask )
  157. {
  158. uint32_t irqs;
  159. irqs = (st25r3916interrupt.status & mask);
  160. if(irqs != ST25R3916_IRQ_MASK_NONE)
  161. {
  162. platformProtectST25RIrqStatus();
  163. st25r3916interrupt.status &= ~irqs;
  164. platformUnprotectST25RIrqStatus();
  165. }
  166. return irqs;
  167. }
  168. /*******************************************************************************/
  169. void st25r3916ClearAndEnableInterrupts( uint32_t mask )
  170. {
  171. st25r3916GetInterrupt( mask );
  172. st25r3916EnableInterrupts( mask );
  173. }
  174. /*******************************************************************************/
  175. void st25r3916EnableInterrupts(uint32_t mask)
  176. {
  177. st25r3916ModifyInterrupts(mask, 0);
  178. }
  179. /*******************************************************************************/
  180. void st25r3916DisableInterrupts(uint32_t mask)
  181. {
  182. st25r3916ModifyInterrupts(0, mask);
  183. }
  184. /*******************************************************************************/
  185. void st25r3916ClearInterrupts( void )
  186. {
  187. uint8_t iregs[ST25R3916_INT_REGS_LEN];
  188. st25r3916ReadMultipleRegisters(ST25R3916_REG_IRQ_MAIN, iregs, ST25R3916_INT_REGS_LEN);
  189. platformProtectST25RIrqStatus();
  190. st25r3916interrupt.status = ST25R3916_IRQ_MASK_NONE;
  191. platformUnprotectST25RIrqStatus();
  192. return;
  193. }
  194. /*******************************************************************************/
  195. void st25r3916IRQCallbackSet( void (*cb)(void) )
  196. {
  197. st25r3916interrupt.prevCallback = st25r3916interrupt.callback;
  198. st25r3916interrupt.callback = cb;
  199. }
  200. /*******************************************************************************/
  201. void st25r3916IRQCallbackRestore( void )
  202. {
  203. st25r3916interrupt.callback = st25r3916interrupt.prevCallback;
  204. st25r3916interrupt.prevCallback = NULL;
  205. }