interrupt handling

Dependencies:  

Committer:
rwclough
Date:
Thu Mar 12 15:05:36 2015 +0000
Revision:
3:eaae5433ab45
Parent:
2:bd5afc5aa139
Child:
4:9ab0d84bbd07
Finally getting many, many IRQs. Now to see what's going on :)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rwclough 1:1eb96189824d 1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 2 Filename: readerComm.cpp
rwclough 1:1eb96189824d 3 Description: Functions used to communicate with the TRF7970 eval bd.
rwclough 1:1eb96189824d 4 Communication is by means of an SPI interface between
rwclough 1:1eb96189824d 5 the nRF51-DK board (nRF51422 MCU) and the TRF7970 eval bd.
rwclough 1:1eb96189824d 6 Copyright (C) 2015 Gymtrack, Inc.
rwclough 1:1eb96189824d 7 Author: Ron Clough
rwclough 1:1eb96189824d 8 Date: 2015-02-27
rwclough 1:1eb96189824d 9
rwclough 1:1eb96189824d 10 Changes:
rwclough 1:1eb96189824d 11 Rev Date Who Details
rwclough 1:1eb96189824d 12 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rwclough 2:bd5afc5aa139 13 0.0 2015-02-27 RWC Original version.
rwclough 1:1eb96189824d 14
rwclough 1:1eb96189824d 15 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
rwclough 1:1eb96189824d 16
rwclough 1:1eb96189824d 17 #include "mbed.h"
rwclough 1:1eb96189824d 18 #include "readerComm.h"
rwclough 3:eaae5433ab45 19 #include "interruptStuff.h"
rwclough 2:bd5afc5aa139 20 #include "main.h"
rwclough 1:1eb96189824d 21
rwclough 2:bd5afc5aa139 22 uint8_t afi = 0;
rwclough 2:bd5afc5aa139 23 uint8_t flags = 0; // Stores the mask value (used in anticollision)
rwclough 2:bd5afc5aa139 24 uint8_t command[2];
rwclough 2:bd5afc5aa139 25 uint8_t temp;
rwclough 2:bd5afc5aa139 26 extern DigitalOut ISO15693LED; // ISO15693 LED
rwclough 2:bd5afc5aa139 27 extern SPI spi; // main.cpp
rwclough 2:bd5afc5aa139 28 extern Serial pc; // main.cpp
rwclough 2:bd5afc5aa139 29 extern DigitalOut CS; // main.cpp
rwclough 2:bd5afc5aa139 30 extern InterruptIn readerInt; // main.cpp
rwclough 2:bd5afc5aa139 31 extern int8_t rxtxState; // Transmit/Receive byte count (main.cpp)
rwclough 2:bd5afc5aa139 32 extern uint8_t buf[300]; // main.cpp
rwclough 2:bd5afc5aa139 33 extern uint8_t irqRegister; // Interrupt register (main.cpp)
rwclough 3:eaae5433ab45 34 volatile extern uint8_t irqFlag; // main.cpp
rwclough 2:bd5afc5aa139 35 extern uint8_t rxErrorFlag; // main.cpp
rwclough 2:bd5afc5aa139 36 extern uint8_t readerMode; // Determines how interrupts will be handled (main.cpp)
rwclough 2:bd5afc5aa139 37 extern uint8_t buffer[2];
rwclough 2:bd5afc5aa139 38
rwclough 3:eaae5433ab45 39 extern uint8_t tagFlag;
rwclough 3:eaae5433ab45 40 extern DigitalIn irqPin;
rwclough 3:eaae5433ab45 41 extern DigitalOut debug1LED;
rwclough 3:eaae5433ab45 42 extern DigitalOut debug2LED;
rwclough 3:eaae5433ab45 43 extern DigitalOut ISO15693LED;
rwclough 3:eaae5433ab45 44 extern DigitalOut heartbeatLED;
rwclough 3:eaae5433ab45 45
rwclough 3:eaae5433ab45 46 extern DigitalOut testPin;
rwclough 3:eaae5433ab45 47
rwclough 2:bd5afc5aa139 48 void initialSettings(void)
rwclough 1:1eb96189824d 49 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 50 // initialSettings()
rwclough 1:1eb96189824d 51 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 52 {
rwclough 2:bd5afc5aa139 53 uint8_t mod_control[2];
rwclough 1:1eb96189824d 54
rwclough 1:1eb96189824d 55 mod_control[0] = SOFT_INIT;
rwclough 2:bd5afc5aa139 56 spiDirectCommand(mod_control);
rwclough 3:eaae5433ab45 57
rwclough 1:1eb96189824d 58 mod_control[0] = IDLE;
rwclough 2:bd5afc5aa139 59 spiDirectCommand(mod_control);
rwclough 3:eaae5433ab45 60
rwclough 1:1eb96189824d 61 mod_control[0] = MODULATOR_CONTROL;
rwclough 2:bd5afc5aa139 62 mod_control[1] = 0x21; // 6.78 MHz, OOK 100%
rwclough 2:bd5afc5aa139 63 spiWriteSingle(mod_control, 2);
rwclough 3:eaae5433ab45 64
rwclough 1:1eb96189824d 65 mod_control[0] = MODULATOR_CONTROL;
rwclough 2:bd5afc5aa139 66 spiReadSingle(mod_control, 1);
rwclough 2:bd5afc5aa139 67 } // End of initialSettings()
rwclough 1:1eb96189824d 68
rwclough 2:bd5afc5aa139 69 void spiDirectCommand(uint8_t *buffer)
rwclough 1:1eb96189824d 70 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 3:eaae5433ab45 71 // spiDirectCommand()
rwclough 1:1eb96189824d 72 // Description: Transmit a Direct Command to the reader chip.
rwclough 1:1eb96189824d 73 // Parameter: *buffer = the direct command.
rwclough 1:1eb96189824d 74 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 75 {
rwclough 1:1eb96189824d 76 *buffer = (0x80 | *buffer); // Setup command mode
rwclough 2:bd5afc5aa139 77 *buffer = (0x9F & *buffer); // Setup command mode
rwclough 1:1eb96189824d 78 CS = SELECT;
rwclough 1:1eb96189824d 79 spi.write(*buffer);
rwclough 3:eaae5433ab45 80
rwclough 3:eaae5433ab45 81 spi.write(0x00);
rwclough 3:eaae5433ab45 82
rwclough 1:1eb96189824d 83 CS = DESELECT;
rwclough 3:eaae5433ab45 84 } // End of spiDirectCommand()
rwclough 1:1eb96189824d 85
rwclough 2:bd5afc5aa139 86 void spiWriteSingle(uint8_t *buffer, uint8_t length)
rwclough 1:1eb96189824d 87 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 88 // spiWriteSingle()
rwclough 1:1eb96189824d 89 // Description: Writes to specified reader registers.
rwclough 1:1eb96189824d 90 // Parameters: *buffer = addresses of the registers followed by the
rwclough 2:bd5afc5aa139 91 // contents to write.
rwclough 1:1eb96189824d 92 // length = number of registers * 2.
rwclough 1:1eb96189824d 93 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 94 {
rwclough 2:bd5afc5aa139 95 uint8_t i=0;
rwclough 1:1eb96189824d 96
rwclough 1:1eb96189824d 97 CS = SELECT;
rwclough 1:1eb96189824d 98 while(length > 0) {
rwclough 2:bd5afc5aa139 99 *buffer = (0x1F & *buffer); // Register address
rwclough 1:1eb96189824d 100 for(i = 0; i < 2; i++) {
rwclough 1:1eb96189824d 101 spi.write(*buffer);
rwclough 1:1eb96189824d 102 buffer++;
rwclough 1:1eb96189824d 103 length--;
rwclough 2:bd5afc5aa139 104 }
rwclough 2:bd5afc5aa139 105 }
rwclough 1:1eb96189824d 106 CS = DESELECT;
rwclough 2:bd5afc5aa139 107 } // End of spiWriteSingle()
rwclough 1:1eb96189824d 108
rwclough 2:bd5afc5aa139 109 void spiReadSingle(uint8_t *buffer, uint8_t number)
rwclough 1:1eb96189824d 110 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 111 // spiReadSingle()
rwclough 1:1eb96189824d 112 // Description: Reads specified reader chip registers and
rwclough 1:1eb96189824d 113 // writes register contents to *buffer.
rwclough 1:1eb96189824d 114 // Parameters: *buffer = addresses of the registers.
rwclough 1:1eb96189824d 115 // number = number of registers.
rwclough 1:1eb96189824d 116 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 117 {
rwclough 1:1eb96189824d 118 CS = SELECT;
rwclough 1:1eb96189824d 119 while(number > 0) {
rwclough 1:1eb96189824d 120 *buffer = (0x40 | *buffer); // Address, read, single
rwclough 2:bd5afc5aa139 121 *buffer = (0x5F & *buffer); // Register address
rwclough 3:eaae5433ab45 122 spi.write(*buffer);
rwclough 2:bd5afc5aa139 123 *buffer = spi.write(0x00); // *buffer <- register contents
rwclough 1:1eb96189824d 124 buffer++;
rwclough 1:1eb96189824d 125 number--;
rwclough 2:bd5afc5aa139 126 }
rwclough 2:bd5afc5aa139 127 CS = DESELECT;
rwclough 2:bd5afc5aa139 128 } // End of spiReadSingle()
rwclough 2:bd5afc5aa139 129
rwclough 2:bd5afc5aa139 130 void spiReadContinuous(uint8_t *buffer, uint8_t length)
rwclough 2:bd5afc5aa139 131 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 132 // spiReadContinuous()
rwclough 2:bd5afc5aa139 133 // Description: Used in SPI mode to read a specified number of
rwclough 2:bd5afc5aa139 134 // reader chip registers from a specified address upwards.
rwclough 2:bd5afc5aa139 135 // Contents of the registers are stored in *buffer.
rwclough 2:bd5afc5aa139 136 // Parameters: *buffer = address of first register.
rwclough 2:bd5afc5aa139 137 // length = number of registers to read.
rwclough 2:bd5afc5aa139 138 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 139 {
rwclough 2:bd5afc5aa139 140 CS = SELECT;
rwclough 2:bd5afc5aa139 141 *buffer = (0x60 | *buffer); // Address, read, continuous
rwclough 3:eaae5433ab45 142 *buffer = (0x7F & *buffer); // Register address
rwclough 2:bd5afc5aa139 143 spi.write(*buffer);
rwclough 2:bd5afc5aa139 144 while(length > 0) {
rwclough 2:bd5afc5aa139 145 *buffer = spi.write(0x00);
rwclough 2:bd5afc5aa139 146 buffer++;
rwclough 2:bd5afc5aa139 147 length--;
rwclough 3:eaae5433ab45 148 }
rwclough 3:eaae5433ab45 149
rwclough 3:eaae5433ab45 150 spi.write(0x00); spi.write(0x00); // 16 clock cycles, see TRF7970A FW Design Hints SLOA159 section 7.3
rwclough 3:eaae5433ab45 151
rwclough 1:1eb96189824d 152 CS = DESELECT;
rwclough 2:bd5afc5aa139 153 } // End of spiReadContinuous()
rwclough 2:bd5afc5aa139 154
rwclough 2:bd5afc5aa139 155 void spiRawWrite(uint8_t *buffer, uint8_t length)
rwclough 2:bd5afc5aa139 156 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 157 // rawWrite()
rwclough 2:bd5afc5aa139 158 // Description: Used in SPI mode to write direct to the reader chip.
rwclough 2:bd5afc5aa139 159 // Parameters: *buffer = raw data
rwclough 2:bd5afc5aa139 160 // length = number of data bytes
rwclough 2:bd5afc5aa139 161 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 162 {
rwclough 2:bd5afc5aa139 163 CS = SELECT;
rwclough 2:bd5afc5aa139 164 while(length > 0) {
rwclough 2:bd5afc5aa139 165 temp = spi.write(*buffer);
rwclough 2:bd5afc5aa139 166 buffer++;
rwclough 2:bd5afc5aa139 167 length--;
rwclough 2:bd5afc5aa139 168 }
rwclough 2:bd5afc5aa139 169 CS = DESELECT;
rwclough 2:bd5afc5aa139 170 } // End of spiRawWrite()
rwclough 2:bd5afc5aa139 171
rwclough 2:bd5afc5aa139 172 void stopDecoders(void)
rwclough 2:bd5afc5aa139 173 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 174 // stopDecoders()
rwclough 2:bd5afc5aa139 175 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 176 {
rwclough 2:bd5afc5aa139 177 command[0] = STOP_DECODERS;
rwclough 2:bd5afc5aa139 178 spiDirectCommand(command);
rwclough 2:bd5afc5aa139 179 }
rwclough 1:1eb96189824d 180
rwclough 2:bd5afc5aa139 181 void runDecoders(void)
rwclough 2:bd5afc5aa139 182 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 183 // runDecoders()
rwclough 2:bd5afc5aa139 184 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 185 {
rwclough 2:bd5afc5aa139 186 command[0] = RUN_DECODERS;
rwclough 2:bd5afc5aa139 187 spiDirectCommand(command);
rwclough 2:bd5afc5aa139 188 }
rwclough 2:bd5afc5aa139 189
rwclough 2:bd5afc5aa139 190 void txNextSlot(void)
rwclough 2:bd5afc5aa139 191 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 192 // txNextSlot()
rwclough 2:bd5afc5aa139 193 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 194 {
rwclough 2:bd5afc5aa139 195 command[0] = TRANSMIT_NEXT_SLOT;
rwclough 2:bd5afc5aa139 196 spiDirectCommand(command);
rwclough 2:bd5afc5aa139 197 }
rwclough 2:bd5afc5aa139 198
rwclough 2:bd5afc5aa139 199 void disableSlotCounter(void)
rwclough 2:bd5afc5aa139 200 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 201 // disableSlotCounter()
rwclough 2:bd5afc5aa139 202 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 203 {
rwclough 2:bd5afc5aa139 204 buf[40] = IRQ_MASK;
rwclough 2:bd5afc5aa139 205 buf[41] = IRQ_MASK;
rwclough 2:bd5afc5aa139 206 spiReadSingle(&buf[41], 1);
rwclough 2:bd5afc5aa139 207 buf[41] &= 0xFE;
rwclough 2:bd5afc5aa139 208 spiWriteSingle(&buf[40], 2);
rwclough 2:bd5afc5aa139 209 }
rwclough 2:bd5afc5aa139 210
rwclough 2:bd5afc5aa139 211 void trf7970Reset(void)
rwclough 2:bd5afc5aa139 212 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 213 // trf7970Reset()
rwclough 2:bd5afc5aa139 214 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 215 {
rwclough 2:bd5afc5aa139 216 command[0] = RESET;
rwclough 2:bd5afc5aa139 217 spiDirectCommand(command);
rwclough 2:bd5afc5aa139 218 }
rwclough 2:bd5afc5aa139 219
rwclough 2:bd5afc5aa139 220 void turnRfOn(void)
rwclough 1:1eb96189824d 221 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 1:1eb96189824d 222 // turnRfOn()
rwclough 1:1eb96189824d 223 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 3:eaae5433ab45 224 {
rwclough 3:eaae5433ab45 225 command[0] = CHIP_STATUS_CONTROL;
rwclough 3:eaae5433ab45 226 command[1] = CHIP_STATUS_CONTROL;
rwclough 3:eaae5433ab45 227 spiReadSingle(&command[1], 1);
rwclough 3:eaae5433ab45 228 command[1] &= 0x3F;
rwclough 3:eaae5433ab45 229 command[1] |= 0x20;
rwclough 3:eaae5433ab45 230 spiWriteSingle(command, 2);
rwclough 1:1eb96189824d 231 } // End of turnRfOn()
rwclough 1:1eb96189824d 232
rwclough 2:bd5afc5aa139 233 void turnRfOff(void)
rwclough 1:1eb96189824d 234 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 1:1eb96189824d 235 // turnRfOff()
rwclough 1:1eb96189824d 236 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 237 {
rwclough 3:eaae5433ab45 238 command[0] = CHIP_STATUS_CONTROL;
rwclough 3:eaae5433ab45 239 command[1] = CHIP_STATUS_CONTROL;
rwclough 3:eaae5433ab45 240 spiReadSingle(&command[1], 1);
rwclough 3:eaae5433ab45 241 command[1] &= 0x1F;
rwclough 3:eaae5433ab45 242 spiWriteSingle(command, 2);
rwclough 1:1eb96189824d 243 } // End of turnRfOff()
rwclough 1:1eb96189824d 244
rwclough 2:bd5afc5aa139 245 void writeIsoControl(uint8_t iso_control)
rwclough 1:1eb96189824d 246 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 1:1eb96189824d 247 // writeIsoControl()
rwclough 1:1eb96189824d 248 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 249 {
rwclough 2:bd5afc5aa139 250 uint8_t write[4];
rwclough 1:1eb96189824d 251
rwclough 2:bd5afc5aa139 252 if ((iso_control & BIT5) == BIT5) {
rwclough 2:bd5afc5aa139 253 printf("iso_control bit5 != 0\r\n");
rwclough 2:bd5afc5aa139 254 return;
rwclough 2:bd5afc5aa139 255 }
rwclough 1:1eb96189824d 256
rwclough 1:1eb96189824d 257 write[0] = ISO_CONTROL;
rwclough 1:1eb96189824d 258 write[1] = iso_control;
rwclough 2:bd5afc5aa139 259 write[1] &= ~BIT5;
rwclough 2:bd5afc5aa139 260 spiWriteSingle(write, 2);
rwclough 1:1eb96189824d 261 iso_control &= 0x1F;
rwclough 1:1eb96189824d 262 } // End of writeIsoControl()
rwclough 1:1eb96189824d 263
rwclough 2:bd5afc5aa139 264 void iso15693FindTag(void)
rwclough 1:1eb96189824d 265 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 1:1eb96189824d 266 // iso15693FindTag()
rwclough 3:eaae5433ab45 267 // Description: Used to detect ISO15693 conforming tags.
rwclough 3:eaae5433ab45 268 // If an ISO15693 conforming tag is found ISO15693LED is turned ON.
rwclough 3:eaae5433ab45 269 // 1) Turn RF ON
rwclough 3:eaae5433ab45 270 // 2) Perform a complete anticollision sequence
rwclough 3:eaae5433ab45 271 // 3) Turn RF OFF
rwclough 1:1eb96189824d 272 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 273 {
rwclough 1:1eb96189824d 274 turnRfOn();
rwclough 1:1eb96189824d 275 writeIsoControl(0x02);
rwclough 3:eaae5433ab45 276 wait_ms(6); // The VCD should wait at least 1 ms after it activated the
rwclough 3:eaae5433ab45 277 // powering field before sending the first request, to
rwclough 3:eaae5433ab45 278 // ensure that the VICCs are ready to receive it. (ISO15693-3)
rwclough 3:eaae5433ab45 279 /*
rwclough 3:eaae5433ab45 280 // Field Level Test:
rwclough 3:eaae5433ab45 281 buffer[0] = CHIP_STATUS_CONTROL;
rwclough 3:eaae5433ab45 282 buffer[1] = 0x23;
rwclough 3:eaae5433ab45 283 spiWriteSingle(buffer, 2);
rwclough 3:eaae5433ab45 284 wait_ms(1);
rwclough 3:eaae5433ab45 285 buffer[0] = CHECK_INTERNAL_RF;
rwclough 3:eaae5433ab45 286 spiDirectCommand(buffer);
rwclough 3:eaae5433ab45 287 buffer[0] = RSSI_LEVELS;
rwclough 3:eaae5433ab45 288 spiReadSingle(buffer, 1);
rwclough 3:eaae5433ab45 289 printf("RSSI: 0x%X\r\n", buffer[0]);
rwclough 3:eaae5433ab45 290 // Result: RSSI = 0x40 (Range is 0x40 to 0x7F)
rwclough 3:eaae5433ab45 291 */
rwclough 3:eaae5433ab45 292 flags = SIXTEEN_SLOTS; // SIXTEEN_SLOTS = 0x06
rwclough 2:bd5afc5aa139 293 buf[20] = 0x00;
rwclough 2:bd5afc5aa139 294 Iso15693Anticollision(&buf[20], 0x00); // Send Inventory request
rwclough 1:1eb96189824d 295 turnRfOff();
rwclough 1:1eb96189824d 296 resetIrqStatus(); // Clear any IRQs
rwclough 1:1eb96189824d 297 } // End of iso15693FindTag()
rwclough 1:1eb96189824d 298
rwclough 2:bd5afc5aa139 299 void Iso15693Anticollision(uint8_t *mask, uint8_t length)
rwclough 1:1eb96189824d 300 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 1:1eb96189824d 301 // Iso15693Anticollision()
rwclough 2:bd5afc5aa139 302 // Description: Used to perform an inventory cycle of 1 or 16 timeslots.
rwclough 2:bd5afc5aa139 303 // Send command, receive response and send response to host.
rwclough 2:bd5afc5aa139 304 // Parameters: *mask = mask value
rwclough 2:bd5afc5aa139 305 // length = number of significant bits of mask value
rwclough 1:1eb96189824d 306 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 307 {
rwclough 3:eaae5433ab45 308 uint8_t i = 1, j = 1, command[2], no_slots, found = 0;
rwclough 3:eaae5433ab45 309 uint8_t *p_slot_no, slot_no[17];
rwclough 3:eaae5433ab45 310 uint8_t new_mask[8], new_length, mask_size;
rwclough 3:eaae5433ab45 311 uint32_t size;
rwclough 3:eaae5433ab45 312 uint8_t fifo_length = 0;
rwclough 3:eaae5433ab45 313 uint16_t k;
rwclough 3:eaae5433ab45 314 uint8_t irqStatus[2], iso_control;
rwclough 2:bd5afc5aa139 315
rwclough 2:bd5afc5aa139 316 slot_no[0] = 0x00;
rwclough 3:eaae5433ab45 317 if ((flags & BIT5) == 0x00) { // flags<5> is the number of slots indicator
rwclough 3:eaae5433ab45 318 no_slots = 16; // 16 slots if flags<5> is cleared
rwclough 2:bd5afc5aa139 319 }
rwclough 2:bd5afc5aa139 320 else {
rwclough 3:eaae5433ab45 321 no_slots = 1; // 1 slot if flags<5> is set
rwclough 2:bd5afc5aa139 322 }
rwclough 2:bd5afc5aa139 323
rwclough 2:bd5afc5aa139 324 p_slot_no = &slot_no[0]; // slot number pointer
rwclough 2:bd5afc5aa139 325 mask_size = (((length >> 2) + 1) >> 1); // mask_size is 1 for length = 4 or 8
rwclough 2:bd5afc5aa139 326 buf[0] = 0x8F; // RESET
rwclough 2:bd5afc5aa139 327 buf[1] = 0x91; // send with CRC
rwclough 2:bd5afc5aa139 328 buf[2] = 0x3D; // write continuous from 1D
rwclough 2:bd5afc5aa139 329 buf[5] = flags; // ISO15693 flags
rwclough 2:bd5afc5aa139 330 buf[6] = 0x01; // anticollision command code
rwclough 2:bd5afc5aa139 331
rwclough 2:bd5afc5aa139 332 if (flags & 0x10) { // mask_size is 2 for length = 12 or 16 and so on
rwclough 2:bd5afc5aa139 333 size = mask_size + 4; // mask value + mask length + afi + command code + flags
rwclough 2:bd5afc5aa139 334 buf[7] = afi;
rwclough 2:bd5afc5aa139 335 buf[8] = length; // mask length
rwclough 2:bd5afc5aa139 336 if (length > 0) {
rwclough 2:bd5afc5aa139 337 for(i = 0; i < mask_size; i++) {
rwclough 2:bd5afc5aa139 338 buf[9 + i] = *(mask + i);
rwclough 2:bd5afc5aa139 339 }
rwclough 2:bd5afc5aa139 340 }
rwclough 2:bd5afc5aa139 341 fifo_length = 9;
rwclough 2:bd5afc5aa139 342 }
rwclough 2:bd5afc5aa139 343 else { // mask_size is 2 for length = 12 or 16 and so on
rwclough 2:bd5afc5aa139 344 size = mask_size + 3; // mask value + mask length + command code + flags
rwclough 2:bd5afc5aa139 345 buf[7] = length; // mask length
rwclough 2:bd5afc5aa139 346 if(length > 0) {
rwclough 2:bd5afc5aa139 347 for(i = 0; i < mask_size; i++) {
rwclough 2:bd5afc5aa139 348 buf[8 + i] = *(mask + i);
rwclough 2:bd5afc5aa139 349 }
rwclough 2:bd5afc5aa139 350 }
rwclough 2:bd5afc5aa139 351 fifo_length = 8;
rwclough 2:bd5afc5aa139 352 }
rwclough 2:bd5afc5aa139 353
rwclough 2:bd5afc5aa139 354 buf[3] = (char) (size >> 8);
rwclough 2:bd5afc5aa139 355 buf[4] = (char) (size << 4);
rwclough 2:bd5afc5aa139 356
rwclough 2:bd5afc5aa139 357 resetIrqStatus();
rwclough 3:eaae5433ab45 358 // ***** Original code sets up a 30 ms counter here *****
rwclough 3:eaae5433ab45 359 // ***** Original code enables IRQ here *****
rwclough 3:eaae5433ab45 360 // ***** nRF51422 clear IRQ register *****
rwclough 3:eaae5433ab45 361 readerInt.enable_irq();
rwclough 2:bd5afc5aa139 362 spiRawWrite(&buf[0], mask_size + fifo_length); // Write to FIFO
rwclough 2:bd5afc5aa139 363 irqRegister = 0x01;
rwclough 2:bd5afc5aa139 364 irqFlag = 0x00;
rwclough 3:eaae5433ab45 365 // ***** Original code starts the counter here *****
rwclough 2:bd5afc5aa139 366
rwclough 3:eaae5433ab45 367 /*
rwclough 3:eaae5433ab45 368 // Continuously read the IRQ STATUS register
rwclough 3:eaae5433ab45 369 while(1) {
rwclough 3:eaae5433ab45 370 readIrqStatus(irqStatus);
rwclough 3:eaae5433ab45 371 printf("IRQ: 0x%X\r\n", irqStatus[1]);
rwclough 3:eaae5433ab45 372 wait_ms(100);
rwclough 3:eaae5433ab45 373 }
rwclough 3:eaae5433ab45 374 */
rwclough 3:eaae5433ab45 375
rwclough 3:eaae5433ab45 376 // Wait for end-of-TX interrupt:
rwclough 3:eaae5433ab45 377 // IRQ_STATUS<7> set at start of TX, but
rwclough 3:eaae5433ab45 378 // IRQ pin doesn't go high until TX ends.
rwclough 3:eaae5433ab45 379
rwclough 3:eaae5433ab45 380 while(irqFlag == 0x00) {};
rwclough 3:eaae5433ab45 381
rwclough 3:eaae5433ab45 382 // ***** Original code stops the counter here *****
rwclough 3:eaae5433ab45 383
rwclough 3:eaae5433ab45 384 // Begin: This code used to be in interruptStuff.cpp/trf7970IrqHandler()
rwclough 2:bd5afc5aa139 385
rwclough 3:eaae5433ab45 386 do {
rwclough 3:eaae5433ab45 387 iso_control = ISO_CONTROL;
rwclough 3:eaae5433ab45 388 spiReadSingle(&iso_control, 1);
rwclough 3:eaae5433ab45 389 readIrqStatus(irqStatus);
rwclough 3:eaae5433ab45 390
rwclough 3:eaae5433ab45 391 if (*irqStatus == 0xA0) { // TX active and only 3 bytes left in FIFO
rwclough 3:eaae5433ab45 392
rwclough 3:eaae5433ab45 393 break;
rwclough 3:eaae5433ab45 394 }
rwclough 3:eaae5433ab45 395
rwclough 3:eaae5433ab45 396 if ((iso_control & BIT5) != BIT5) { // RFID mode
rwclough 3:eaae5433ab45 397 howToHandleTrf7970Irq(irqStatus);
rwclough 3:eaae5433ab45 398 }
rwclough 3:eaae5433ab45 399 else { // NFC mode
rwclough 3:eaae5433ab45 400 if ((iso_control & BIT2) == BIT2) { // Tag emulation
rwclough 3:eaae5433ab45 401 tagFlag = 1;
rwclough 3:eaae5433ab45 402 nfcModeIrq(irqStatus);
rwclough 3:eaae5433ab45 403 }
rwclough 3:eaae5433ab45 404 else {
rwclough 3:eaae5433ab45 405 if ((iso_control & BIT4) == BIT4) { // Active mode
rwclough 3:eaae5433ab45 406 nfcModeIrq(irqStatus);
rwclough 3:eaae5433ab45 407 }
rwclough 3:eaae5433ab45 408 else { // Passive mode
rwclough 3:eaae5433ab45 409 targetIrq(irqStatus);
rwclough 3:eaae5433ab45 410 }
rwclough 3:eaae5433ab45 411 }
rwclough 3:eaae5433ab45 412 }
rwclough 3:eaae5433ab45 413 } while(irqPin); // While IRQ pin is high **********
rwclough 2:bd5afc5aa139 414
rwclough 3:eaae5433ab45 415 // End: This code used to be in interruptStuff.cpp/trf7970IrqHandler()
rwclough 1:1eb96189824d 416
rwclough 3:eaae5433ab45 417 for (j = 1; j <= no_slots; j++) { // 1 or 16 available timeslots
rwclough 2:bd5afc5aa139 418 rxtxState = 1;
rwclough 3:eaae5433ab45 419 // ***** Original code sets up a 20 ms counter and starts it here *****
rwclough 2:bd5afc5aa139 420 irqFlag = 0x00;
rwclough 2:bd5afc5aa139 421 while(irqFlag == 0x00); // Wait for interrupt
rwclough 3:eaae5433ab45 422
rwclough 3:eaae5433ab45 423 // ***** Original code stops the counter here *****
rwclough 2:bd5afc5aa139 424 while(irqRegister == 0x01) { // Wait for RX complete
rwclough 2:bd5afc5aa139 425 k++;
rwclough 2:bd5afc5aa139 426 if (k == 0xFFF0) {
rwclough 2:bd5afc5aa139 427 irqRegister = 0x00;
rwclough 2:bd5afc5aa139 428 rxErrorFlag = 0x00;
rwclough 2:bd5afc5aa139 429 }
rwclough 3:eaae5433ab45 430 }
rwclough 2:bd5afc5aa139 431 command[0] = RSSI_LEVELS; // Read RSSI levels
rwclough 2:bd5afc5aa139 432 spiReadSingle(command, 1);
rwclough 3:eaae5433ab45 433
rwclough 2:bd5afc5aa139 434 switch (irqRegister) {
rwclough 2:bd5afc5aa139 435 case 0xFF: // If received UID in buffer
rwclough 3:eaae5433ab45 436 found = 1;
rwclough 3:eaae5433ab45 437 printf("\r\nISO15693: [ ");
rwclough 2:bd5afc5aa139 438 for (i=3; i < 11; i++) {
rwclough 2:bd5afc5aa139 439 printf("%c", buf[i]);
rwclough 2:bd5afc5aa139 440 }
rwclough 2:bd5afc5aa139 441 printf(", %d ]\r\n", command[0]);
rwclough 2:bd5afc5aa139 442 break;
rwclough 2:bd5afc5aa139 443
rwclough 2:bd5afc5aa139 444 case 0x02: // Collision occurred
rwclough 2:bd5afc5aa139 445 p_slot_no++; // Remember a collision was detected
rwclough 2:bd5afc5aa139 446 *p_slot_no = j;
rwclough 2:bd5afc5aa139 447 break;
rwclough 2:bd5afc5aa139 448
rwclough 2:bd5afc5aa139 449 case 0x00: // Timer interrupt
rwclough 3:eaae5433ab45 450 // ***** Original code does nothing! *****
rwclough 2:bd5afc5aa139 451 break;
rwclough 2:bd5afc5aa139 452
rwclough 2:bd5afc5aa139 453 default:
rwclough 3:eaae5433ab45 454 // ***** Original code does nothing *****
rwclough 2:bd5afc5aa139 455 break;
rwclough 3:eaae5433ab45 456 } // switch (irqRegister)
rwclough 2:bd5afc5aa139 457
rwclough 2:bd5afc5aa139 458 command[0] = RESET; // FIFO must be reset before receiving the next response
rwclough 2:bd5afc5aa139 459 spiDirectCommand(command);
rwclough 2:bd5afc5aa139 460
rwclough 2:bd5afc5aa139 461 if ((no_slots == 16) && (j < 16)) { // If 16 slots used then send EOF (next slot)
rwclough 2:bd5afc5aa139 462 stopDecoders();
rwclough 2:bd5afc5aa139 463 runDecoders();
rwclough 3:eaae5433ab45 464 txNextSlot(); // RESET must precede txNextSlot, see "TRF7970A FW Design Hints SLOA159.
rwclough 2:bd5afc5aa139 465 }
rwclough 2:bd5afc5aa139 466 else if ((no_slots == 16) && (j == 16)) { // At end of slot 16, stop the slot counter
rwclough 2:bd5afc5aa139 467 stopDecoders();
rwclough 2:bd5afc5aa139 468 disableSlotCounter();
rwclough 2:bd5afc5aa139 469 }
rwclough 3:eaae5433ab45 470 else if (no_slots == 1) { // 1 slot is used
rwclough 2:bd5afc5aa139 471 break;
rwclough 2:bd5afc5aa139 472 }
rwclough 3:eaae5433ab45 473 } // for (j = 1; j <= no_slots; j++)
rwclough 2:bd5afc5aa139 474
rwclough 2:bd5afc5aa139 475 if (found == 1) {
rwclough 2:bd5afc5aa139 476 ISO15693LED = LED_ON;
rwclough 3:eaae5433ab45 477 // printf("Found ISO15693 tag\r\n");
rwclough 2:bd5afc5aa139 478 }
rwclough 2:bd5afc5aa139 479 else {
rwclough 2:bd5afc5aa139 480 ISO15693LED = LED_OFF;
rwclough 2:bd5afc5aa139 481 }
rwclough 2:bd5afc5aa139 482
rwclough 2:bd5afc5aa139 483 new_length = length + 4; // The mask length is a multiple of 4 bits
rwclough 2:bd5afc5aa139 484 mask_size = (((new_length >> 2) + 1) >> 1);
rwclough 2:bd5afc5aa139 485 while ((*p_slot_no != 0x00) && (no_slots == 16) && (new_length < 61) && (slot_no[16] != 16)) {
rwclough 2:bd5afc5aa139 486 *p_slot_no = *p_slot_no - 1;
rwclough 2:bd5afc5aa139 487
rwclough 2:bd5afc5aa139 488 for(i = 0; i < 8; i++)
rwclough 2:bd5afc5aa139 489 {
rwclough 2:bd5afc5aa139 490 new_mask[i] = *(mask + i); // First the whole mask is copied
rwclough 2:bd5afc5aa139 491 }
rwclough 2:bd5afc5aa139 492
rwclough 2:bd5afc5aa139 493 if((new_length & BIT2) == 0x00)
rwclough 2:bd5afc5aa139 494 {
rwclough 2:bd5afc5aa139 495 *p_slot_no = *p_slot_no << 4;
rwclough 2:bd5afc5aa139 496 }
rwclough 2:bd5afc5aa139 497 else
rwclough 2:bd5afc5aa139 498 {
rwclough 2:bd5afc5aa139 499 for(i = 7; i > 0; i--)
rwclough 2:bd5afc5aa139 500 {
rwclough 2:bd5afc5aa139 501 new_mask[i] = new_mask[i - 1];
rwclough 2:bd5afc5aa139 502 }
rwclough 2:bd5afc5aa139 503 new_mask[0] &= 0x00;
rwclough 2:bd5afc5aa139 504 }
rwclough 2:bd5afc5aa139 505 new_mask[0] |= *p_slot_no; // The mask is changed
rwclough 2:bd5afc5aa139 506 wait_ms(2);
rwclough 2:bd5afc5aa139 507
rwclough 2:bd5afc5aa139 508 Iso15693Anticollision(&new_mask[0], new_length); // Recursive call with new Mask
rwclough 2:bd5afc5aa139 509
rwclough 2:bd5afc5aa139 510 p_slot_no--;
rwclough 2:bd5afc5aa139 511 }
rwclough 3:eaae5433ab45 512 // ***** Original code disables IRQ here *****
rwclough 3:eaae5433ab45 513 //readerInt.disable_irq();
rwclough 2:bd5afc5aa139 514
rwclough 1:1eb96189824d 515 } // End of Iso15693Anticollision()