| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- /******************************************************************************
- * \attention
- *
- * <h2><center>© COPYRIGHT 2020 STMicroelectronics</center></h2>
- *
- * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
- * You may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * www.st.com/myliberty
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
- * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- ******************************************************************************/
- /*
- * PROJECT: ST25R3916 firmware
- * Revision:
- * LANGUAGE: ISO C99
- */
- /*! \file
- *
- * \author Gustavo Patricio
- *
- * \brief ST25R3916 Interrupt handling
- *
- */
- /*
- ******************************************************************************
- * INCLUDES
- ******************************************************************************
- */
- #include "st25r3916_irq.h"
- #include "st25r3916_com.h"
- #include "st25r3916_led.h"
- #include "st25r3916.h"
- #include "utils.h"
- /*
- ******************************************************************************
- * LOCAL DATA TYPES
- ******************************************************************************
- */
- /*! Holds current and previous interrupt callback pointer as well as current Interrupt status and mask */
- typedef struct {
- void (*prevCallback)(void); /*!< call back function for ST25R3916 interrupt */
- void (*callback)(void); /*!< call back function for ST25R3916 interrupt */
- uint32_t status; /*!< latest interrupt status */
- uint32_t mask; /*!< Interrupt mask. Negative mask = ST25R3916 mask regs */
- } st25r3916Interrupt;
- /*
- ******************************************************************************
- * GLOBAL DEFINES
- ******************************************************************************
- */
- /*! Length of the interrupt registers */
- #define ST25R3916_INT_REGS_LEN ((ST25R3916_REG_IRQ_TARGET - ST25R3916_REG_IRQ_MAIN) + 1U)
- /*
- ******************************************************************************
- * GLOBAL VARIABLES
- ******************************************************************************
- */
- static volatile st25r3916Interrupt st25r3916interrupt; /*!< Instance of ST25R3916 interrupt */
- /*
- ******************************************************************************
- * GLOBAL FUNCTIONS
- ******************************************************************************
- */
- void st25r3916InitInterrupts(void) {
- platformIrqST25RPinInitialize();
- platformIrqST25RSetCallback(st25r3916Isr);
- st25r3916interrupt.callback = NULL;
- st25r3916interrupt.prevCallback = NULL;
- st25r3916interrupt.status = ST25R3916_IRQ_MASK_NONE;
- st25r3916interrupt.mask = ST25R3916_IRQ_MASK_NONE;
- }
- /*******************************************************************************/
- void st25r3916Isr(void) {
- st25r3916CheckForReceivedInterrupts();
- // Check if callback is set and run it
- if(NULL != st25r3916interrupt.callback) {
- st25r3916interrupt.callback();
- }
- }
- /*******************************************************************************/
- void st25r3916CheckForReceivedInterrupts(void) {
- uint8_t iregs[ST25R3916_INT_REGS_LEN];
- uint32_t irqStatus;
- /* Initialize iregs */
- irqStatus = ST25R3916_IRQ_MASK_NONE;
- ST_MEMSET(iregs, (int32_t)(ST25R3916_IRQ_MASK_ALL & 0xFFU), ST25R3916_INT_REGS_LEN);
- /* In case the IRQ is Edge (not Level) triggered read IRQs until done */
- while(platformGpioIsHigh(ST25R_INT_PORT, ST25R_INT_PIN)) {
- st25r3916ReadMultipleRegisters(ST25R3916_REG_IRQ_MAIN, iregs, ST25R3916_INT_REGS_LEN);
- irqStatus |= (uint32_t)iregs[0];
- irqStatus |= (uint32_t)iregs[1] << 8;
- irqStatus |= (uint32_t)iregs[2] << 16;
- irqStatus |= (uint32_t)iregs[3] << 24;
- }
- /* Forward all interrupts, even masked ones to application */
- platformProtectST25RIrqStatus();
- st25r3916interrupt.status |= irqStatus;
- platformUnprotectST25RIrqStatus();
- /* Send an IRQ event to LED handling */
- st25r3916ledEvtIrq(st25r3916interrupt.status);
- }
- /*******************************************************************************/
- void st25r3916ModifyInterrupts(uint32_t clr_mask, uint32_t set_mask) {
- uint8_t i;
- uint32_t old_mask;
- uint32_t new_mask;
- old_mask = st25r3916interrupt.mask;
- new_mask = ((~old_mask & set_mask) | (old_mask & clr_mask));
- st25r3916interrupt.mask &= ~clr_mask;
- st25r3916interrupt.mask |= set_mask;
- for(i = 0; i < ST25R3916_INT_REGS_LEN; i++) {
- if(((new_mask >> (8U * i)) & 0xFFU) == 0U) {
- continue;
- }
- st25r3916WriteRegister(
- ST25R3916_REG_IRQ_MASK_MAIN + i,
- (uint8_t)((st25r3916interrupt.mask >> (8U * i)) & 0xFFU));
- }
- return;
- }
- /*******************************************************************************/
- uint32_t st25r3916WaitForInterruptsTimed(uint32_t mask, uint16_t tmo) {
- uint32_t tmrDelay;
- uint32_t status;
- tmrDelay = platformTimerCreate(tmo);
- /* Run until specific interrupt has happen or the timer has expired */
- do {
- status = (st25r3916interrupt.status & mask);
- } while((!platformTimerIsExpired(tmrDelay) || (tmo == 0U)) && (status == 0U));
- platformTimerDestroy(tmrDelay);
- status = st25r3916interrupt.status & mask;
- platformProtectST25RIrqStatus();
- st25r3916interrupt.status &= ~status;
- platformUnprotectST25RIrqStatus();
- return status;
- }
- /*******************************************************************************/
- uint32_t st25r3916GetInterrupt(uint32_t mask) {
- uint32_t irqs;
- irqs = (st25r3916interrupt.status & mask);
- if(irqs != ST25R3916_IRQ_MASK_NONE) {
- platformProtectST25RIrqStatus();
- st25r3916interrupt.status &= ~irqs;
- platformUnprotectST25RIrqStatus();
- }
- return irqs;
- }
- /*******************************************************************************/
- void st25r3916ClearAndEnableInterrupts(uint32_t mask) {
- st25r3916GetInterrupt(mask);
- st25r3916EnableInterrupts(mask);
- }
- /*******************************************************************************/
- void st25r3916EnableInterrupts(uint32_t mask) {
- st25r3916ModifyInterrupts(mask, 0);
- }
- /*******************************************************************************/
- void st25r3916DisableInterrupts(uint32_t mask) {
- st25r3916ModifyInterrupts(0, mask);
- }
- /*******************************************************************************/
- void st25r3916ClearInterrupts(void) {
- uint8_t iregs[ST25R3916_INT_REGS_LEN];
- st25r3916ReadMultipleRegisters(ST25R3916_REG_IRQ_MAIN, iregs, ST25R3916_INT_REGS_LEN);
- platformProtectST25RIrqStatus();
- st25r3916interrupt.status = ST25R3916_IRQ_MASK_NONE;
- platformUnprotectST25RIrqStatus();
- return;
- }
- /*******************************************************************************/
- void st25r3916IRQCallbackSet(void (*cb)(void)) {
- st25r3916interrupt.prevCallback = st25r3916interrupt.callback;
- st25r3916interrupt.callback = cb;
- }
- /*******************************************************************************/
- void st25r3916IRQCallbackRestore(void) {
- st25r3916interrupt.callback = st25r3916interrupt.prevCallback;
- st25r3916interrupt.prevCallback = NULL;
- }
|