interrupt handling

Dependencies:  

Revision:
3:eaae5433ab45
Parent:
2:bd5afc5aa139
Child:
4:9ab0d84bbd07
--- a/readerComm.cpp	Thu Mar 05 20:16:40 2015 +0000
+++ b/readerComm.cpp	Thu Mar 12 15:05:36 2015 +0000
@@ -16,6 +16,7 @@
 
 #include    "mbed.h"
 #include    "readerComm.h"
+#include    "interruptStuff.h"
 #include    "main.h"
 
 uint8_t     afi = 0;
@@ -30,11 +31,20 @@
 extern  int8_t          rxtxState;          // Transmit/Receive byte count (main.cpp)
 extern  uint8_t         buf[300];           // main.cpp
 extern  uint8_t         irqRegister;        // Interrupt register (main.cpp)
-extern  uint8_t         irqFlag;            // main.cpp
+volatile extern  uint8_t         irqFlag;            // main.cpp
 extern  uint8_t         rxErrorFlag;        // main.cpp
 extern  uint8_t         readerMode;         // Determines how interrupts will be handled (main.cpp)
 extern  uint8_t         buffer[2];
 
+extern  uint8_t tagFlag;
+extern  DigitalIn   irqPin;
+extern  DigitalOut  debug1LED;
+extern  DigitalOut  debug2LED;
+extern  DigitalOut  ISO15693LED;
+extern  DigitalOut  heartbeatLED;
+
+extern  DigitalOut  testPin;
+
 void initialSettings(void)
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 //  initialSettings()
@@ -44,18 +54,21 @@
     
     mod_control[0] = SOFT_INIT;
     spiDirectCommand(mod_control);
+    
     mod_control[0] = IDLE;
     spiDirectCommand(mod_control);
+    
     mod_control[0] = MODULATOR_CONTROL;
     mod_control[1] = 0x21;                  // 6.78 MHz, OOK 100%
     spiWriteSingle(mod_control, 2);
+    
     mod_control[0] = MODULATOR_CONTROL;
     spiReadSingle(mod_control, 1);
 }   // End of initialSettings()
 
 void spiDirectCommand(uint8_t *buffer)
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-//  directCommand()
+//  spiDirectCommand()
 //  Description:    Transmit a Direct Command to the reader chip.
 //  Parameter:      *buffer =   the direct command.
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
@@ -64,8 +77,11 @@
     *buffer = (0x9F & *buffer);     // Setup command mode
     CS = SELECT;
     spi.write(*buffer);
+    
+    spi.write(0x00);
+    
     CS = DESELECT;
-}   // End of directCommand()
+}   // End of spiDirectCommand()
 
 void spiWriteSingle(uint8_t *buffer, uint8_t length)
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
@@ -83,7 +99,6 @@
         *buffer = (0x1F & *buffer);     // Register address
         for(i = 0; i < 2; i++) {
             spi.write(*buffer);
-            temp = spi.write(0x00);
             buffer++;
             length--;
         }
@@ -104,9 +119,7 @@
     while(number > 0) {
         *buffer = (0x40 | *buffer);     // Address, read, single
         *buffer = (0x5F & *buffer);     // Register address
-        temp = spi.write(*buffer);
-//        *buffer = spi.write(*buffer);
-//        temp = spi.write(0x00);         // dummy read
+        spi.write(*buffer);
         *buffer = spi.write(0x00);      // *buffer <- register contents
         buffer++;
         number--;
@@ -126,15 +139,16 @@
 {
     CS = SELECT;
     *buffer = (0x60 | *buffer);     // Address, read, continuous
-    *buffer = (0x7f & *buffer);     // Register address
+    *buffer = (0x7F & *buffer);     // Register address
     spi.write(*buffer);
-    temp = spi.write(0x00);
     while(length > 0) {
-        spi.write(0x00);
         *buffer = spi.write(0x00);
         buffer++;
         length--;
-    } // while
+    }
+    
+    spi.write(0x00); spi.write(0x00);   // 16 clock cycles, see TRF7970A FW Design Hints SLOA159 section 7.3
+    
     CS = DESELECT;
 }   // End of spiReadContinuous()
 
@@ -207,21 +221,13 @@
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 //  turnRfOn()
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-{
-    uint8_t cmd[2];
-    
-    cmd[0] = CHIP_STATUS_CONTROL;
-    cmd[1] = CHIP_STATUS_CONTROL;
-    spiReadSingle(&cmd[1], 1);
-    cmd[1] &= 0x3F;
-    cmd[1] |= 0x20;
-    spiWriteSingle(cmd, 2);
-    
-//    wait_ms(100);
-//    spiReadSingle(cmd, 1);
-//    printf("Cmd[0]: 0x%X\r\n", cmd[0]);
-//    printf("Cmd[1]: 0x%X\r\n", cmd[1]);
-    
+{   
+    command[0] = CHIP_STATUS_CONTROL;
+    command[1] = CHIP_STATUS_CONTROL;
+    spiReadSingle(&command[1], 1);
+    command[1] &= 0x3F;
+    command[1] |= 0x20;
+    spiWriteSingle(command, 2);
 }   // End of turnRfOn()
 
 void turnRfOff(void)
@@ -229,13 +235,11 @@
 //  turnRfOff()
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 {
-    uint8_t cmd[2];
-    
-    cmd[0] = CHIP_STATUS_CONTROL;
-    cmd[1] = CHIP_STATUS_CONTROL;
-    spiReadSingle(&cmd[1], 1);
-    cmd[1] &= 0x1F;
-    spiWriteSingle(cmd, 2);
+    command[0] = CHIP_STATUS_CONTROL;
+    command[1] = CHIP_STATUS_CONTROL;
+    spiReadSingle(&command[1], 1);
+    command[1] &= 0x1F;
+    spiWriteSingle(command, 2);
 }   // End of turnRfOff()
 
 void writeIsoControl(uint8_t iso_control)
@@ -254,40 +258,38 @@
     write[1] = iso_control;
     write[1] &= ~BIT5;
     spiWriteSingle(write, 2);
-    
-//    wait_ms(100);
-//    spiReadSingle(write, 1);
-//    printf("Reg[0]: 0x%X\r\n", write[0]);
-//    printf("Reg[1]: 0x%X\r\n", write[1]);
-
     iso_control &= 0x1F;
 }   // End of writeIsoControl()
 
-void resetIrqStatus(void)
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-//  resetIrqStatus()
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-{
-    uint8_t irq_status[4];
-    
-    irq_status[0] = IRQ_STATUS;
-    irq_status[1] = IRQ_MASK;
-    
-    spiReadContinuous(irq_status, 2);   // Read second register as dummy read
-}
-
 void iso15693FindTag(void)
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 //  iso15693FindTag()
+//  Description:    Used to detect ISO15693 conforming tags.
+//                  If an ISO15693 conforming tag is found ISO15693LED is turned ON.
+//                  1) Turn RF ON
+//                  2) Perform a complete anticollision sequence
+//                  3) Turn RF OFF
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 {
     turnRfOn();
     writeIsoControl(0x02);
-    // The VCD should wait at least 1 ms after it activated the
-    // powering field before sending the first request, to
-    // ensure that the VICCs are ready to receive it. (ISO15693-3)
-    wait_ms(6);
-    flags = SIXTEEN_SLOTS;                  // 0x06
+    wait_ms(6); // The VCD should wait at least 1 ms after it activated the
+                // powering field before sending the first request, to
+                // ensure that the VICCs are ready to receive it. (ISO15693-3)
+    /*
+    //  Field Level Test:
+    buffer[0] = CHIP_STATUS_CONTROL;
+    buffer[1] = 0x23;
+    spiWriteSingle(buffer, 2);
+    wait_ms(1);
+    buffer[0] = CHECK_INTERNAL_RF;
+    spiDirectCommand(buffer);
+    buffer[0] = RSSI_LEVELS;
+    spiReadSingle(buffer, 1);
+    printf("RSSI: 0x%X\r\n", buffer[0]);
+    //  Result: RSSI = 0x40 (Range is 0x40 to 0x7F)
+    */
+    flags = SIXTEEN_SLOTS;                  // SIXTEEN_SLOTS = 0x06
     buf[20] = 0x00;
     Iso15693Anticollision(&buf[20], 0x00);  // Send Inventory request
     turnRfOff();
@@ -303,19 +305,20 @@
 //              length =    number of significant bits of mask value
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 {
-    uint8_t i = 1, j = 1, command[2], no_slots, found = 0;
-    uint8_t *p_slot_no, slot_no[17];
-    uint8_t new_mask[8], new_length, mask_size;
-    uint32_t size;
-    uint8_t fifo_length = 0;
-    uint16_t k;
+    uint8_t     i = 1, j = 1, command[2], no_slots, found = 0;
+    uint8_t     *p_slot_no, slot_no[17];
+    uint8_t     new_mask[8], new_length, mask_size;
+    uint32_t    size;
+    uint8_t     fifo_length = 0;
+    uint16_t    k;
+    uint8_t     irqStatus[2], iso_control;
 
     slot_no[0] = 0x00;
-    if ((flags & BIT5) == 0x00) {                       // flag bit5 is the number of slots indicator
-        no_slots = 16;                                  // 16 slots if bit5 is cleared
+    if ((flags & BIT5) == 0x00) {                       // flags<5> is the number of slots indicator
+        no_slots = 16;                                  // 16 slots if flags<5> is cleared
     }
     else {
-        no_slots = 1;                                   // 1 slot if bit5 is set
+        no_slots = 1;                                   // 1 slot if flags<5> is set
     }
     
     p_slot_no = &slot_no[0];                            // slot number pointer
@@ -352,34 +355,86 @@
     buf[4] = (char) (size << 4);
 
     resetIrqStatus();
-    
+    //  ***** Original code sets up a 30 ms counter here *****
+    //  ***** Original code enables IRQ here *****
+    //  ***** nRF51422 clear IRQ register *****
+    readerInt.enable_irq();
     spiRawWrite(&buf[0], mask_size + fifo_length);      // Write to FIFO
     irqRegister = 0x01;
     irqFlag = 0x00;
-    readerInt.enable_irq();
+    //  ***** Original code starts the counter here *****
     
-    printf("Anticollision 1  \r\n"); wait_ms(100);
+    /*
+    //  Continuously read the IRQ STATUS register
+    while(1) {
+        readIrqStatus(irqStatus);
+        printf("IRQ: 0x%X\r\n", irqStatus[1]);
+        wait_ms(100);
+    }
+    */
+    
+    //  Wait for end-of-TX interrupt:
+    //  IRQ_STATUS<7> set at start of TX, but
+    //  IRQ pin doesn't go high until TX ends.
+    
+    while(irqFlag == 0x00) {};
+    
+    // ***** Original code stops the counter here *****
+    
+    //  Begin: This code used to be in interruptStuff.cpp/trf7970IrqHandler()
     
-    while(irqFlag == 0x00);                             // Wait for end-of-TX interrupt
+    do {
+        iso_control = ISO_CONTROL;
+        spiReadSingle(&iso_control, 1);
+        readIrqStatus(irqStatus);
+        
+        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 **********
     
-    printf("Anticollision 2  \r\n"); wait_ms(100);
+    //  End: This code used to be in interruptStuff.cpp/trf7970IrqHandler()
     
-    for (j=1; j <= no_slots; j++) {                     // 1 or 16 available timeslots
+    for (j = 1; j <= no_slots; j++) {                     // 1 or 16 available timeslots
         rxtxState = 1;
+        //  ***** Original code sets up a 20 ms counter and starts it here *****
         irqFlag = 0x00;
         while(irqFlag == 0x00);                         // Wait for interrupt
+        
+        //  ***** Original code stops the counter here *****
         while(irqRegister == 0x01) {                    // Wait for RX complete
             k++;
             if (k == 0xFFF0) {
                 irqRegister = 0x00;
                 rxErrorFlag = 0x00;
             }
-        }   // while
+        }
         command[0] = RSSI_LEVELS;                       // Read RSSI levels
         spiReadSingle(command, 1);
+        
         switch (irqRegister) {
             case 0xFF:                  // If received UID in buffer
-                printf("ISO15693: [ ");
+                found = 1;
+                printf("\r\nISO15693: [ ");
                 for (i=3; i < 11; i++) {
                     printf("%c", buf[i]);
                 }
@@ -392,11 +447,13 @@
             break;
             
             case 0x00:                  // Timer interrupt
+                //  ***** Original code does nothing! *****
             break;
             
             default:
+                //  ***** Original code does nothing *****
             break;
-        }   // switch
+        }   // switch (irqRegister)
         
         command[0] = RESET;             // FIFO must be reset before receiving the next response
         spiDirectCommand(command);
@@ -404,20 +461,20 @@
         if ((no_slots == 16) && (j < 16)) {         // If 16 slots used then send EOF (next slot)
             stopDecoders();
             runDecoders();
-            txNextSlot();
+            txNextSlot();   // RESET must precede txNextSlot, see "TRF7970A FW Design Hints SLOA159.
         }
         else if ((no_slots == 16) && (j == 16)) {   // At end of slot 16, stop the slot counter
             stopDecoders();
             disableSlotCounter();
         }
-        else if (no_slots == 1) {                   // 1 slot is uesd
+        else if (no_slots == 1) {                   // 1 slot is used
             break;
         }
-    }   // for
+    }   // for (j = 1; j <= no_slots; j++)
     
     if (found == 1) {
         ISO15693LED = LED_ON;
-        printf("Found ISO15693 tag\r\n");
+//        printf("Found ISO15693 tag\r\n");
     }
     else {
         ISO15693LED = LED_OFF;
@@ -452,6 +509,7 @@
 
         p_slot_no--;
     }
+    //  ***** Original code disables IRQ here *****
+    //readerInt.disable_irq();
     
-    readerInt.disable_irq();
 }   // End of Iso15693Anticollision()