interrupt handling
Diff: interruptStuff.cpp
- Revision:
- 2:bd5afc5aa139
- Child:
- 3:eaae5433ab45
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/interruptStuff.cpp Thu Mar 05 20:16:40 2015 +0000 @@ -0,0 +1,369 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + 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()