interrupt handling

Dependencies:  

Revision:
2:bd5afc5aa139
Parent:
1:1eb96189824d
Child:
3:eaae5433ab45
--- a/readerComm.cpp	Mon Mar 02 19:50:31 2015 +0000
+++ b/readerComm.cpp	Thu Mar 05 20:16:40 2015 +0000
@@ -1,5 +1,5 @@
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-    Filename:       readerComm.c
+    Filename:       readerComm.cpp
     Description:    Functions used to communicate with the TRF7970 eval bd.
                     Communication is by means of an SPI interface between
                     the nRF51-DK board (nRF51422 MCU) and the TRF7970 eval bd.
@@ -10,170 +10,448 @@
     Changes:
     Rev     Date        Who     Details
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-    0.0     2015-02-2   RWC     Original version.
+    0.0     2015-02-27  RWC     Original version.
     
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
 #include    "mbed.h"
 #include    "readerComm.h"
-
-extern  SPI         spi;    // main.cpp
-extern  DigitalOut  CS;     // main.cpp
+#include    "main.h"
 
-void firstComm(void) {
+uint8_t     afi = 0;
+uint8_t     flags = 0;                      // Stores the mask value (used in anticollision)
+uint8_t     command[2];
+uint8_t     temp;
+extern  DigitalOut      ISO15693LED;        // ISO15693 LED
+extern  SPI             spi;                // main.cpp
+extern  Serial          pc;                 // main.cpp
+extern  DigitalOut      CS;                 // main.cpp
+extern  InterruptIn     readerInt;          // main.cpp
+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
+extern  uint8_t         rxErrorFlag;        // main.cpp
+extern  uint8_t         readerMode;         // Determines how interrupts will be handled (main.cpp)
+extern  uint8_t         buffer[2];
+
+void initialSettings(void)
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-//  firstComm()
+//  initialSettings()
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-    int mod_control[2];
+{
+    uint8_t mod_control[2];
     
     mod_control[0] = SOFT_INIT;
-    directCommand(mod_control);
+    spiDirectCommand(mod_control);
     mod_control[0] = IDLE;
-    directCommand(mod_control);
+    spiDirectCommand(mod_control);
     mod_control[0] = MODULATOR_CONTROL;
-    mod_control[1] = 0x21;
-    writeSingle(mod_control, 2);
+    mod_control[1] = 0x21;                  // 6.78 MHz, OOK 100%
+    spiWriteSingle(mod_control, 2);
     mod_control[0] = MODULATOR_CONTROL;
-    readSingle(mod_control, 1);
-}   // End of firstComm()
+    spiReadSingle(mod_control, 1);
+}   // End of initialSettings()
 
-void directCommand(int *buffer) {
+void spiDirectCommand(uint8_t *buffer)
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 //  directCommand()
 //  Description:    Transmit a Direct Command to the reader chip.
 //  Parameter:      *buffer =   the direct command.
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+{
     *buffer = (0x80 | *buffer);     // Setup command mode
-    *buffer = (0x9f & *buffer);     // Setup command mode
+    *buffer = (0x9F & *buffer);     // Setup command mode
     CS = SELECT;
     spi.write(*buffer);
     CS = DESELECT;
 }   // End of directCommand()
 
-void writeSingle(int *buffer, int length) {
+void spiWriteSingle(uint8_t *buffer, uint8_t length)
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-//  writeSingle()
+//  spiWriteSingle()
 //  Description:    Writes to specified reader registers.
 //  Parameters:     *buffer =   addresses of the registers followed by the
-//                              contends to write.
+//                              contents to write.
 //                  length =    number of registers * 2.
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-    int i=0;
+{
+    uint8_t i=0;
     
     CS = SELECT;
     while(length > 0) {
-        *buffer = (0x1f & *buffer);     // Register address
+        *buffer = (0x1F & *buffer);     // Register address
         for(i = 0; i < 2; i++) {
             spi.write(*buffer);
+            temp = spi.write(0x00);
             buffer++;
             length--;
-        } // if
-    } // while
+        }
+    }
     CS = DESELECT;
-}   // End of writeSingle()
+}   // End of spiWriteSingle()
 
-void readSingle(int *buffer, int number) {
+void spiReadSingle(uint8_t *buffer, uint8_t number)
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-//  readSingle()
+//  spiReadSingle()
 //  Description:    Reads specified reader chip registers and 
 //                  writes register contents to *buffer.
 //  Parameters:     *buffer =   addresses of the registers.
 //                  number  =   number of registers.
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-    int temp;
-    
+{
     CS = SELECT;
     while(number > 0) {
         *buffer = (0x40 | *buffer);     // Address, read, single
-        *buffer = (0x5f & *buffer);     // Register address
+        *buffer = (0x5F & *buffer);     // Register address
         temp = spi.write(*buffer);
-        *buffer = spi.write(0x00);
+//        *buffer = spi.write(*buffer);
+//        temp = spi.write(0x00);         // dummy read
+        *buffer = spi.write(0x00);      // *buffer <- register contents
         buffer++;
         number--;
+    }
+    CS = DESELECT;
+}   // End of spiReadSingle()
+
+void spiReadContinuous(uint8_t *buffer, uint8_t length)
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+//  spiReadContinuous()
+//  Description:    Used in SPI mode to read a specified number of
+//                  reader chip registers from a specified address upwards.
+//                  Contents of the registers are stored in *buffer.
+//  Parameters:     *buffer =   address of first register.
+//                  length =    number of registers to read.
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+{
+    CS = SELECT;
+    *buffer = (0x60 | *buffer);     // Address, read, continuous
+    *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
     CS = DESELECT;
-}   // End of readSingle()
+}   // End of spiReadContinuous()
+
+void spiRawWrite(uint8_t *buffer, uint8_t length)
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+//  rawWrite()
+//  Description:    Used in SPI mode to write direct to the reader chip.
+//  Parameters:     *buffer =   raw data
+//                  length =    number of data bytes
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+{
+    CS = SELECT;
+    while(length > 0) {
+        temp = spi.write(*buffer);
+        buffer++;
+        length--;
+    }
+    CS = DESELECT;
+}   // End of spiRawWrite()
+
+void stopDecoders(void)
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+//  stopDecoders()
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+{
+    command[0] = STOP_DECODERS;
+    spiDirectCommand(command);
+}
 
-void turnRfOn(void) {
+void runDecoders(void)
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+//  runDecoders()
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+{
+    command[0] = RUN_DECODERS;
+    spiDirectCommand(command);
+}
+
+void txNextSlot(void)
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+//  txNextSlot()
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+{
+    command[0] = TRANSMIT_NEXT_SLOT;
+    spiDirectCommand(command);
+}
+
+void disableSlotCounter(void)
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+//  disableSlotCounter()
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+{
+    buf[40] = IRQ_MASK;
+    buf[41] = IRQ_MASK;
+    spiReadSingle(&buf[41], 1);
+    buf[41] &= 0xFE;
+    spiWriteSingle(&buf[40], 2);
+}
+
+void trf7970Reset(void)
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+//  trf7970Reset()
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+{
+    command[0] = RESET;
+    spiDirectCommand(command);
+}
+
+void turnRfOn(void)
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 //  turnRfOn()
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-    int command[2];
+{
+    uint8_t cmd[2];
     
-    command[0] = CHIP_STATUS_CONTROL;
-    command[1] = CHIP_STATUS_CONTROL;
-    readSingle(&command[1], 1);
-    command[1] &= 0x3F;
-    command[1] |= 0x20;
-    writeSingle(command, 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]);
+    
 }   // End of turnRfOn()
 
-void turnRfOff(void) {
+void turnRfOff(void)
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 //  turnRfOff()
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-    int command[2];
+{
+    uint8_t cmd[2];
     
-    command[0] = CHIP_STATUS_CONTROL;
-    command[1] = CHIP_STATUS_CONTROL;
-    readSingle(&command[1], 1);
-    command[1] &= 0x1F;
-    writeSingle(command, 2);
+    cmd[0] = CHIP_STATUS_CONTROL;
+    cmd[1] = CHIP_STATUS_CONTROL;
+    spiReadSingle(&cmd[1], 1);
+    cmd[1] &= 0x1F;
+    spiWriteSingle(cmd, 2);
 }   // End of turnRfOff()
 
-void writeIsoControl(int iso_control) {
+void writeIsoControl(uint8_t iso_control)
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 //  writeIsoControl()
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-    int write[4];
+{
+    uint8_t write[4];
     
-//    if((iso_control & BIT5) == BIT5)
-//    {   
-//        return;
-//    }
+    if ((iso_control & BIT5) == BIT5) {
+        printf("iso_control bit5 != 0\r\n");
+        return;
+    }
     
     write[0] = ISO_CONTROL;
     write[1] = iso_control;
-//    write[1] &= ~BIT5;
-    writeSingle(write, 2);
+    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) {
+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) {
+void iso15693FindTag(void)
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 //  iso15693FindTag()
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+{
     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;
-//  flags = ONE_SLOT;
-
-//    buf[20] = 0x00;
-//    Iso15693Anticollision(&buf[20], 0x00);  // Send Inventory request
-
+    flags = SIXTEEN_SLOTS;                  // 0x06
+    buf[20] = 0x00;
+    Iso15693Anticollision(&buf[20], 0x00);  // Send Inventory request
     turnRfOff();
-
     resetIrqStatus();                       // Clear any IRQs
 }   // End of iso15693FindTag()
 
-void Iso15693Anticollision(int *mask, int length) {
+void Iso15693Anticollision(uint8_t *mask, uint8_t length)
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 //  Iso15693Anticollision()
+//  Description: Used to perform an inventory cycle of 1 or 16 timeslots.
+//               Send command, receive response and send response to host.
+//  Parameters: *mask =     mask value
+//              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;
+
+    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
+    }
+    else {
+        no_slots = 1;                                   // 1 slot if bit5 is set
+    }
+    
+    p_slot_no = &slot_no[0];                            // slot number pointer
+    mask_size = (((length >> 2) + 1) >> 1);             // mask_size is 1 for length = 4 or 8
+    buf[0] = 0x8F;                                      // RESET
+    buf[1] = 0x91;                                      // send with CRC
+    buf[2] = 0x3D;                                      // write continuous from 1D
+    buf[5] = flags;                                     // ISO15693 flags
+    buf[6] = 0x01;                                      // anticollision command code
+    
+    if (flags & 0x10) {                                 // mask_size is 2 for length = 12 or 16 and so on
+        size = mask_size + 4;                           // mask value + mask length + afi + command code + flags
+        buf[7] = afi;
+        buf[8] = length;                                // mask length
+        if (length > 0) {
+            for(i = 0; i < mask_size; i++) {
+                buf[9 + i] = *(mask + i);
+            }
+        }
+        fifo_length = 9;
+    }
+    else {                                              // mask_size is 2 for length = 12 or 16 and so on
+        size = mask_size + 3;                           // mask value + mask length + command code + flags
+        buf[7] = length;                                // mask length
+        if(length > 0) {
+            for(i = 0; i < mask_size; i++) {
+                buf[8 + i] = *(mask + i);
+            }
+        }
+        fifo_length = 8;
+    }
+    
+    buf[3] = (char) (size >> 8);
+    buf[4] = (char) (size << 4);
+
+    resetIrqStatus();
+    
+    spiRawWrite(&buf[0], mask_size + fifo_length);      // Write to FIFO
+    irqRegister = 0x01;
+    irqFlag = 0x00;
+    readerInt.enable_irq();
+    
+    printf("Anticollision 1  \r\n"); wait_ms(100);
+    
+    while(irqFlag == 0x00);                             // Wait for end-of-TX interrupt
+    
+    printf("Anticollision 2  \r\n"); wait_ms(100);
     
+    for (j=1; j <= no_slots; j++) {                     // 1 or 16 available timeslots
+        rxtxState = 1;
+        irqFlag = 0x00;
+        while(irqFlag == 0x00);                         // Wait for interrupt
+        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: [ ");
+                for (i=3; i < 11; i++) {
+                    printf("%c", buf[i]);
+                }
+                printf(", %d ]\r\n", command[0]);
+            break;
+            
+            case 0x02:                  // Collision occurred
+                p_slot_no++;            // Remember a collision was detected
+                *p_slot_no = j;
+            break;
+            
+            case 0x00:                  // Timer interrupt
+            break;
+            
+            default:
+            break;
+        }   // switch
+        
+        command[0] = RESET;             // FIFO must be reset before receiving the next response
+        spiDirectCommand(command);
+        
+        if ((no_slots == 16) && (j < 16)) {         // If 16 slots used then send EOF (next slot)
+            stopDecoders();
+            runDecoders();
+            txNextSlot();
+        }
+        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
+            break;
+        }
+    }   // for
+    
+    if (found == 1) {
+        ISO15693LED = LED_ON;
+        printf("Found ISO15693 tag\r\n");
+    }
+    else {
+        ISO15693LED = LED_OFF;
+    }
+    
+    new_length = length + 4;                        // The mask length is a multiple of 4 bits
+    mask_size = (((new_length >> 2) + 1) >> 1);
+    while ((*p_slot_no != 0x00) && (no_slots == 16) && (new_length < 61) && (slot_no[16] != 16)) {
+        *p_slot_no = *p_slot_no - 1;
+
+        for(i = 0; i < 8; i++)
+        {
+            new_mask[i] = *(mask + i);              // First the whole mask is copied
+        }
+
+        if((new_length & BIT2) == 0x00)
+        {
+            *p_slot_no = *p_slot_no << 4;
+        }
+        else
+        {
+            for(i = 7; i > 0; i--)
+            {
+                new_mask[i] = new_mask[i - 1];
+            }
+            new_mask[0] &= 0x00;
+        }
+        new_mask[0] |= *p_slot_no;                  // The mask is changed
+        wait_ms(2);
+
+        Iso15693Anticollision(&new_mask[0], new_length);    // Recursive call with new Mask
+
+        p_slot_no--;
+    }
+    
+    readerInt.disable_irq();
 }   // End of Iso15693Anticollision()