interrupt handling
interruptStuff.cpp
- Committer:
- rwclough
- Date:
- 2015-03-05
- Revision:
- 2:bd5afc5aa139
- Child:
- 3:eaae5433ab45
File content as of revision 2:bd5afc5aa139:
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Filename: interruptHandler.cpp Description: Handles interrupt from TRF7970 Copyright (C) 2015 Gymtrack, Inc. Author: Ron Clough Date: 2015-03-03 Changes: Rev Date Who Details ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 0.0 2015-03-03 RWC Original version. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "mbed.h" #include "interruptStuff.h" #include "readerComm.h" InterruptIn readerInt(p7); // Interrupt from TRF7970 DigitalIn irqPin(p7, PullNone); extern Serial pc; // main.cpp extern uint8_t irqRegister; // Interrupt register (main.cpp) extern uint8_t buf[300]; extern int16_t nfc_state; extern uint8_t nfc_protocol; extern uint8_t active; extern int8_t rxtxState; extern uint8_t rxErrorFlag; extern uint8_t tagFlag; extern uint8_t irqFlag; void setupIrq(void) // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // setupIrq() // Description: Interrupt from TRF7970 appears at pin 7 of // on nRF51-DK eval board. trf7970IrqHandler() is called // when a rising edge is detected. // Interrupts are initially disabled. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * { readerInt.rise(&trf7970IrqHandler); // Interrupt on rising edge, call trf7970IrqHandler() readerInt.disable_irq(); } void readIrqStatus(uint8_t *buffer) // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // readIrqStatus() // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * { *buffer = IRQ_STATUS; *(buffer + 1) = IRQ_MASK; spiReadContinuous(buffer, 2); } // End of readIrqStatus() void nfcModeIrq(uint8_t *Register) // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // nfcModeIrq() // bit0 - RF collision avoidance error // bit1 - RF collision avoidance OK // bit2 - Change in RF field level // bit3 - SDD OK // bit4 - Communication error // bit5 - FIFO high/low // bit6 - RX // bit7 - TX // // irqRegister is used for signaling to the protocol functions // irqRegister = 0x00 - OK // irqRegister = 0x01 - progress // irqRegister = 0x02 - error // irqRegister = 0xFF - end of RX // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * { if (*Register == BIT0) { irqRegister = 0x02; } else if (*Register == BIT1) { irqRegister = 0x00; } else if (*Register == BIT3) { irqRegister = 0x00; } else if ((*Register & BIT4) == BIT4) { *Register = RX_SPECIAL_SETTINGS; // Check filter and gain spiReadSingle(Register, 1); stopDecoders(); irqRegister = 0x02; } else if (*Register == BIT7) { // TX complete irqRegister = 0x00; trf7970Reset(); } else if (*Register == 0x40 || *Register == 0x44) { // RX flag means that EOF has been received and // the number of unread bytes is in FIFOstatus register *Register = RX_SPECIAL_SETTINGS; // Check filter and gain spiReadSingle(Register, 1); *Register = FIFO_CONTROL; spiReadSingle(Register, 1); *Register = 0x7F & *Register; buf[nfc_state] = FIFO; // Write the received bytes to the correct place in the buffer spiReadContinuous(&buf[nfc_state], *Register); nfc_state = nfc_state + *Register; trf7970Reset(); // Reset the FIFO after last byte has been read out irqRegister = 0xFF; // Signal to the receive function that these are the last bytes resetIrqStatus(); } else if ((*Register == 0x60) || (*Register == 0x64)) { // RX and FIFO interrupt irqRegister = 0x01; } else if (*Register == 0x48) { // SDD complete irqRegister = 0x00; } } // End of nfcModeIrq() void targetIrq(uint8_t *Register) // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // targetIrq() // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * { uint8_t command, i; if (*Register == 0x48) { TargetProtocol: // Determine the NFC target protocol command = NFC_TARGET_PROTOCOL; spiReadSingle(&command, 1); //read the NFCtargetprotocol register command &= 0x3F; buf[50] = ISO_CONTROL; if (command == 0x09) { nfc_protocol = 0x01; *Register = FIFO_CONTROL; spiReadSingle(Register, 1); // Determine the number of bytes left in FIFO *Register = 0x7F & *Register; buf[nfc_state] = FIFO; // Write the received bytes to the correct place in the buffer spiReadContinuous(&buf[nfc_state], *Register); nfc_state = nfc_state + *Register; irqRegister = 0xFF; } else { *Register = FIFO_CONTROL; spiReadSingle(Register, 1); // Determine the number of bytes left in FIFO *Register = 0x7F & *Register; buf[nfc_state] = FIFO; // Write the received bytes to the correct place in the buffer spiReadContinuous(&buf[nfc_state], *Register); nfc_state = nfc_state + *Register; irqRegister = 0xFF; if ((command == 0x01)) { // 14443A - active buf[51] = NFC106AC; spiWriteSingle(&buf[50], 2); nfc_protocol = 0x02; active = 0xFF; } else if (command == 0x05) { // 14443B - tag emulation buf[51] = TAG14443B; spiWriteSingle(&buf[50], 2); nfc_protocol = 0x07; active = 0x00; } else if (command == 0x12) { if(buf[1] == 0x06) { // Felica 212 - passive buf[51] = NFC212PA; spiWriteSingle(&buf[50], 2); nfc_protocol = 0x03; active = 0x00; } else { // Felica 212 - active buf[51] = NFC212AC; spiWriteSingle(&buf[50], 2); nfc_protocol = 0x04; active = 0xFF; } } // if (command == 0x12) else if (command == 0x13) { if(buf[1] == 0x06) { //Felica 424 - passive buf[51] = NFC424PA; spiWriteSingle(&buf[50], 2); nfc_protocol = 0x05; active = 0x00; } else { // Felica 424 - active buf[51] = NFC424AC; spiWriteSingle(&buf[50], 2); nfc_protocol = 0x06; active = 0xFF; } // if (buf[1] == 0x06) } // if (command == 0x13) } // if (command == 0x09) } // if (*Register == 0x48) else if (*Register == 0x60) { irqRegister = 0x01; buf[nfc_state] = FIFO; spiReadContinuous(&buf[nfc_state], FIFO_MORE); // Read FIFO_MORE bytes from FIFO nfc_state = nfc_state + FIFO_MORE; resetIrqStatus(); } else if ((*Register & BIT3) == BIT3) { // SDD finished irqRegister = 0xFF; for(i = 0; i < 255; i++); nfc_protocol = 0x01; trf7970Reset(); stopDecoders(); runDecoders(); } else if (*Register == 0x44) { readIrqStatus(Register); if (*Register == 0x40) { goto TargetProtocol; } else if (*Register == 0x00) { goto RFfieldChange; } } else if (*Register == BIT2) { // RF field change RFfieldChange: trf7970Reset(); stopDecoders(); runDecoders(); } resetIrqStatus(); } // End of targetIrq() void howToHandleTrf7970Irq(uint8_t *irq_status) // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // howToHandleTrf7970Irq() // Description: The Interrupt Handler determines how the IRQ should // be handled. The Trf797x IRQ status register is read // to determine the cause of the IRQ. // Conditions are checked and appropriate actions taken. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * { printf("*irq_status: %X\r\n", *irq_status); if (*irq_status == 0xA0) { // BIT5 and BIT7, TX active and only 3 bytes left in FIFO irqRegister = 0x00; } else if (*irq_status == BIT7) { // TX complete irqRegister = 0x00; trf7970Reset(); // Reset the FIFO after TX } else if ((*irq_status & BIT1) == BIT1) { // Collision error irqRegister = 0x02; // RX complete stopDecoders(); trf7970Reset(); resetIrqStatus(); } else if (*irq_status == BIT6) { // RX flag means that EOF has been received // and the number of unread bytes is in FIFOstatus register if (rxErrorFlag == 0x02) { irqRegister = 0x02; return; } *irq_status = FIFO_CONTROL; spiReadSingle(irq_status, 1); // Determine the number of bytes left in FIFO *irq_status = 0x7F & *irq_status; buf[rxtxState] = FIFO; // Write the received bytes to the correct place in the buffer spiReadContinuous(&buf[rxtxState], *irq_status); rxtxState = rxtxState + *irq_status; trf7970Reset(); // Reset the FIFO after last byte has been read out irqRegister = 0xFF; // Signal to the receive funnction that thiese are the last bytes } else if (*irq_status == 0x60) { // RX active and 9 bytes already in FIFO irqRegister = 0x01; buf[rxtxState] = FIFO; spiReadContinuous(&buf[rxtxState], 86); // Read 86 bytes from FIFO rxtxState = rxtxState + 86; if (irqPin) { // If IRQ pin high readIrqStatus(irq_status); // IRQ_CLR ??? if (*irq_status == 0x40) { // End of recieve *irq_status = FIFO_CONTROL; spiReadSingle(irq_status, 1); // Determine the number of bytes left in FIFO *irq_status = 0x7F & *irq_status; buf[rxtxState] = FIFO; // Write the received bytes to the correct place in the buffer spiReadContinuous(&buf[rxtxState], *irq_status); rxtxState = rxtxState + *irq_status; irqRegister = 0xFF; // Signal to the receive funnction that these are the last bytes trf7970Reset(); // Reset the FIFO after last byte has been read out } else if(*irq_status == 0x50) { // End of receive and error irqRegister = 0x02; } } else { readIrqStatus(irq_status); if(irq_status[0] == 0x00) { irqRegister = 0xFF; } } } else if ((*irq_status & BIT4) == BIT4) { // CRC error if ((*irq_status & BIT5) == BIT5) { irqRegister = 0x01; // RX active rxErrorFlag = 0x02; } if ((*irq_status & BIT6) == BIT6) { // 4 Bit receive buf[200] = FIFO; // Write the received bytes to the correct place in the buffer spiReadContinuous(&buf[200], 1); trf7970Reset(); irqRegister = 0x02; // End of RX rxErrorFlag = 0x02; } else { irqRegister = 0x02; // End of RX } } else if ((*irq_status & BIT2) == BIT2) { // Byte framing error if ((*irq_status & BIT5) == BIT5) { irqRegister = 0x01; // RX active rxErrorFlag = 0x02; } else irqRegister = 0x02; // End of RX } else if ((*irq_status == BIT0)) { // No response interrupt irqRegister = 0x00; } else { // Interrupt register not properly set printf ("Interrupt Error\r\n"); irqRegister = 0x02; stopDecoders(); // Reset the FIFO after TX trf7970Reset(); resetIrqStatus(); // IRQ_CLR; ??? } } // End of howToHandleTrf7970Irq() void trf7970IrqHandler(void) // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // trf7970IrqHandler() // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * { uint8_t irqStatus[2], iso_control; irqFlag = 0x02; do { // Do I need to clear interrupt flag here? iso_control = ISO_CONTROL; spiReadSingle(&iso_control, 1); readIrqStatus(irqStatus); printf("IRQ status: %X %X\r\n", irqStatus[0], irqStatus[1]); if (*irqStatus == 0xA0) { // TX active and only 3 bytes left in FIFO break; } if ((iso_control & BIT5) != BIT5) { // RFID mode howToHandleTrf7970Irq(irqStatus); } else { // NFC mode if ((iso_control & BIT2) == BIT2) { // Tag emulation tagFlag = 1; nfcModeIrq(irqStatus); } else { if ((iso_control & BIT4) == BIT4) { // Active mode nfcModeIrq(irqStatus); } else { // Passive mode targetIrq(irqStatus); } } } } while(irqPin); // While IRQ pin is high ********** } // End of trf7970IrqHandler()