interrupt handling

Dependencies:  

Committer:
rwclough
Date:
Thu Mar 05 20:16:40 2015 +0000
Revision:
2:bd5afc5aa139
Parent:
1:1eb96189824d
Child:
3:eaae5433ab45
Correction to last commit: This program is NOT able to write/read TRF7970 registers! I don't know why not. ; According to my logic analyzer, 2 IRQs are generated. They are NOT recognized by this program. A simple test IRQ handler does recognize them.

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 2:bd5afc5aa139 19 #include "main.h"
rwclough 1:1eb96189824d 20
rwclough 2:bd5afc5aa139 21 uint8_t afi = 0;
rwclough 2:bd5afc5aa139 22 uint8_t flags = 0; // Stores the mask value (used in anticollision)
rwclough 2:bd5afc5aa139 23 uint8_t command[2];
rwclough 2:bd5afc5aa139 24 uint8_t temp;
rwclough 2:bd5afc5aa139 25 extern DigitalOut ISO15693LED; // ISO15693 LED
rwclough 2:bd5afc5aa139 26 extern SPI spi; // main.cpp
rwclough 2:bd5afc5aa139 27 extern Serial pc; // main.cpp
rwclough 2:bd5afc5aa139 28 extern DigitalOut CS; // main.cpp
rwclough 2:bd5afc5aa139 29 extern InterruptIn readerInt; // main.cpp
rwclough 2:bd5afc5aa139 30 extern int8_t rxtxState; // Transmit/Receive byte count (main.cpp)
rwclough 2:bd5afc5aa139 31 extern uint8_t buf[300]; // main.cpp
rwclough 2:bd5afc5aa139 32 extern uint8_t irqRegister; // Interrupt register (main.cpp)
rwclough 2:bd5afc5aa139 33 extern uint8_t irqFlag; // main.cpp
rwclough 2:bd5afc5aa139 34 extern uint8_t rxErrorFlag; // main.cpp
rwclough 2:bd5afc5aa139 35 extern uint8_t readerMode; // Determines how interrupts will be handled (main.cpp)
rwclough 2:bd5afc5aa139 36 extern uint8_t buffer[2];
rwclough 2:bd5afc5aa139 37
rwclough 2:bd5afc5aa139 38 void initialSettings(void)
rwclough 1:1eb96189824d 39 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 40 // initialSettings()
rwclough 1:1eb96189824d 41 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 42 {
rwclough 2:bd5afc5aa139 43 uint8_t mod_control[2];
rwclough 1:1eb96189824d 44
rwclough 1:1eb96189824d 45 mod_control[0] = SOFT_INIT;
rwclough 2:bd5afc5aa139 46 spiDirectCommand(mod_control);
rwclough 1:1eb96189824d 47 mod_control[0] = IDLE;
rwclough 2:bd5afc5aa139 48 spiDirectCommand(mod_control);
rwclough 1:1eb96189824d 49 mod_control[0] = MODULATOR_CONTROL;
rwclough 2:bd5afc5aa139 50 mod_control[1] = 0x21; // 6.78 MHz, OOK 100%
rwclough 2:bd5afc5aa139 51 spiWriteSingle(mod_control, 2);
rwclough 1:1eb96189824d 52 mod_control[0] = MODULATOR_CONTROL;
rwclough 2:bd5afc5aa139 53 spiReadSingle(mod_control, 1);
rwclough 2:bd5afc5aa139 54 } // End of initialSettings()
rwclough 1:1eb96189824d 55
rwclough 2:bd5afc5aa139 56 void spiDirectCommand(uint8_t *buffer)
rwclough 1:1eb96189824d 57 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 1:1eb96189824d 58 // directCommand()
rwclough 1:1eb96189824d 59 // Description: Transmit a Direct Command to the reader chip.
rwclough 1:1eb96189824d 60 // Parameter: *buffer = the direct command.
rwclough 1:1eb96189824d 61 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 62 {
rwclough 1:1eb96189824d 63 *buffer = (0x80 | *buffer); // Setup command mode
rwclough 2:bd5afc5aa139 64 *buffer = (0x9F & *buffer); // Setup command mode
rwclough 1:1eb96189824d 65 CS = SELECT;
rwclough 1:1eb96189824d 66 spi.write(*buffer);
rwclough 1:1eb96189824d 67 CS = DESELECT;
rwclough 1:1eb96189824d 68 } // End of directCommand()
rwclough 1:1eb96189824d 69
rwclough 2:bd5afc5aa139 70 void spiWriteSingle(uint8_t *buffer, uint8_t length)
rwclough 1:1eb96189824d 71 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 72 // spiWriteSingle()
rwclough 1:1eb96189824d 73 // Description: Writes to specified reader registers.
rwclough 1:1eb96189824d 74 // Parameters: *buffer = addresses of the registers followed by the
rwclough 2:bd5afc5aa139 75 // contents to write.
rwclough 1:1eb96189824d 76 // length = number of registers * 2.
rwclough 1:1eb96189824d 77 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 78 {
rwclough 2:bd5afc5aa139 79 uint8_t i=0;
rwclough 1:1eb96189824d 80
rwclough 1:1eb96189824d 81 CS = SELECT;
rwclough 1:1eb96189824d 82 while(length > 0) {
rwclough 2:bd5afc5aa139 83 *buffer = (0x1F & *buffer); // Register address
rwclough 1:1eb96189824d 84 for(i = 0; i < 2; i++) {
rwclough 1:1eb96189824d 85 spi.write(*buffer);
rwclough 2:bd5afc5aa139 86 temp = spi.write(0x00);
rwclough 1:1eb96189824d 87 buffer++;
rwclough 1:1eb96189824d 88 length--;
rwclough 2:bd5afc5aa139 89 }
rwclough 2:bd5afc5aa139 90 }
rwclough 1:1eb96189824d 91 CS = DESELECT;
rwclough 2:bd5afc5aa139 92 } // End of spiWriteSingle()
rwclough 1:1eb96189824d 93
rwclough 2:bd5afc5aa139 94 void spiReadSingle(uint8_t *buffer, uint8_t number)
rwclough 1:1eb96189824d 95 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 96 // spiReadSingle()
rwclough 1:1eb96189824d 97 // Description: Reads specified reader chip registers and
rwclough 1:1eb96189824d 98 // writes register contents to *buffer.
rwclough 1:1eb96189824d 99 // Parameters: *buffer = addresses of the registers.
rwclough 1:1eb96189824d 100 // number = number of registers.
rwclough 1:1eb96189824d 101 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 102 {
rwclough 1:1eb96189824d 103 CS = SELECT;
rwclough 1:1eb96189824d 104 while(number > 0) {
rwclough 1:1eb96189824d 105 *buffer = (0x40 | *buffer); // Address, read, single
rwclough 2:bd5afc5aa139 106 *buffer = (0x5F & *buffer); // Register address
rwclough 1:1eb96189824d 107 temp = spi.write(*buffer);
rwclough 2:bd5afc5aa139 108 // *buffer = spi.write(*buffer);
rwclough 2:bd5afc5aa139 109 // temp = spi.write(0x00); // dummy read
rwclough 2:bd5afc5aa139 110 *buffer = spi.write(0x00); // *buffer <- register contents
rwclough 1:1eb96189824d 111 buffer++;
rwclough 1:1eb96189824d 112 number--;
rwclough 2:bd5afc5aa139 113 }
rwclough 2:bd5afc5aa139 114 CS = DESELECT;
rwclough 2:bd5afc5aa139 115 } // End of spiReadSingle()
rwclough 2:bd5afc5aa139 116
rwclough 2:bd5afc5aa139 117 void spiReadContinuous(uint8_t *buffer, uint8_t length)
rwclough 2:bd5afc5aa139 118 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 119 // spiReadContinuous()
rwclough 2:bd5afc5aa139 120 // Description: Used in SPI mode to read a specified number of
rwclough 2:bd5afc5aa139 121 // reader chip registers from a specified address upwards.
rwclough 2:bd5afc5aa139 122 // Contents of the registers are stored in *buffer.
rwclough 2:bd5afc5aa139 123 // Parameters: *buffer = address of first register.
rwclough 2:bd5afc5aa139 124 // length = number of registers to read.
rwclough 2:bd5afc5aa139 125 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 126 {
rwclough 2:bd5afc5aa139 127 CS = SELECT;
rwclough 2:bd5afc5aa139 128 *buffer = (0x60 | *buffer); // Address, read, continuous
rwclough 2:bd5afc5aa139 129 *buffer = (0x7f & *buffer); // Register address
rwclough 2:bd5afc5aa139 130 spi.write(*buffer);
rwclough 2:bd5afc5aa139 131 temp = spi.write(0x00);
rwclough 2:bd5afc5aa139 132 while(length > 0) {
rwclough 2:bd5afc5aa139 133 spi.write(0x00);
rwclough 2:bd5afc5aa139 134 *buffer = spi.write(0x00);
rwclough 2:bd5afc5aa139 135 buffer++;
rwclough 2:bd5afc5aa139 136 length--;
rwclough 1:1eb96189824d 137 } // while
rwclough 1:1eb96189824d 138 CS = DESELECT;
rwclough 2:bd5afc5aa139 139 } // End of spiReadContinuous()
rwclough 2:bd5afc5aa139 140
rwclough 2:bd5afc5aa139 141 void spiRawWrite(uint8_t *buffer, uint8_t length)
rwclough 2:bd5afc5aa139 142 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 143 // rawWrite()
rwclough 2:bd5afc5aa139 144 // Description: Used in SPI mode to write direct to the reader chip.
rwclough 2:bd5afc5aa139 145 // Parameters: *buffer = raw data
rwclough 2:bd5afc5aa139 146 // length = number of data bytes
rwclough 2:bd5afc5aa139 147 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 148 {
rwclough 2:bd5afc5aa139 149 CS = SELECT;
rwclough 2:bd5afc5aa139 150 while(length > 0) {
rwclough 2:bd5afc5aa139 151 temp = spi.write(*buffer);
rwclough 2:bd5afc5aa139 152 buffer++;
rwclough 2:bd5afc5aa139 153 length--;
rwclough 2:bd5afc5aa139 154 }
rwclough 2:bd5afc5aa139 155 CS = DESELECT;
rwclough 2:bd5afc5aa139 156 } // End of spiRawWrite()
rwclough 2:bd5afc5aa139 157
rwclough 2:bd5afc5aa139 158 void stopDecoders(void)
rwclough 2:bd5afc5aa139 159 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 160 // stopDecoders()
rwclough 2:bd5afc5aa139 161 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 162 {
rwclough 2:bd5afc5aa139 163 command[0] = STOP_DECODERS;
rwclough 2:bd5afc5aa139 164 spiDirectCommand(command);
rwclough 2:bd5afc5aa139 165 }
rwclough 1:1eb96189824d 166
rwclough 2:bd5afc5aa139 167 void runDecoders(void)
rwclough 2:bd5afc5aa139 168 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 169 // runDecoders()
rwclough 2:bd5afc5aa139 170 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 171 {
rwclough 2:bd5afc5aa139 172 command[0] = RUN_DECODERS;
rwclough 2:bd5afc5aa139 173 spiDirectCommand(command);
rwclough 2:bd5afc5aa139 174 }
rwclough 2:bd5afc5aa139 175
rwclough 2:bd5afc5aa139 176 void txNextSlot(void)
rwclough 2:bd5afc5aa139 177 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 178 // txNextSlot()
rwclough 2:bd5afc5aa139 179 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 180 {
rwclough 2:bd5afc5aa139 181 command[0] = TRANSMIT_NEXT_SLOT;
rwclough 2:bd5afc5aa139 182 spiDirectCommand(command);
rwclough 2:bd5afc5aa139 183 }
rwclough 2:bd5afc5aa139 184
rwclough 2:bd5afc5aa139 185 void disableSlotCounter(void)
rwclough 2:bd5afc5aa139 186 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 187 // disableSlotCounter()
rwclough 2:bd5afc5aa139 188 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 189 {
rwclough 2:bd5afc5aa139 190 buf[40] = IRQ_MASK;
rwclough 2:bd5afc5aa139 191 buf[41] = IRQ_MASK;
rwclough 2:bd5afc5aa139 192 spiReadSingle(&buf[41], 1);
rwclough 2:bd5afc5aa139 193 buf[41] &= 0xFE;
rwclough 2:bd5afc5aa139 194 spiWriteSingle(&buf[40], 2);
rwclough 2:bd5afc5aa139 195 }
rwclough 2:bd5afc5aa139 196
rwclough 2:bd5afc5aa139 197 void trf7970Reset(void)
rwclough 2:bd5afc5aa139 198 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 199 // trf7970Reset()
rwclough 2:bd5afc5aa139 200 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 201 {
rwclough 2:bd5afc5aa139 202 command[0] = RESET;
rwclough 2:bd5afc5aa139 203 spiDirectCommand(command);
rwclough 2:bd5afc5aa139 204 }
rwclough 2:bd5afc5aa139 205
rwclough 2:bd5afc5aa139 206 void turnRfOn(void)
rwclough 1:1eb96189824d 207 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 1:1eb96189824d 208 // turnRfOn()
rwclough 1:1eb96189824d 209 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 210 {
rwclough 2:bd5afc5aa139 211 uint8_t cmd[2];
rwclough 1:1eb96189824d 212
rwclough 2:bd5afc5aa139 213 cmd[0] = CHIP_STATUS_CONTROL;
rwclough 2:bd5afc5aa139 214 cmd[1] = CHIP_STATUS_CONTROL;
rwclough 2:bd5afc5aa139 215 spiReadSingle(&cmd[1], 1);
rwclough 2:bd5afc5aa139 216 cmd[1] &= 0x3F;
rwclough 2:bd5afc5aa139 217 cmd[1] |= 0x20;
rwclough 2:bd5afc5aa139 218 spiWriteSingle(cmd, 2);
rwclough 2:bd5afc5aa139 219
rwclough 2:bd5afc5aa139 220 // wait_ms(100);
rwclough 2:bd5afc5aa139 221 // spiReadSingle(cmd, 1);
rwclough 2:bd5afc5aa139 222 // printf("Cmd[0]: 0x%X\r\n", cmd[0]);
rwclough 2:bd5afc5aa139 223 // printf("Cmd[1]: 0x%X\r\n", cmd[1]);
rwclough 2:bd5afc5aa139 224
rwclough 1:1eb96189824d 225 } // End of turnRfOn()
rwclough 1:1eb96189824d 226
rwclough 2:bd5afc5aa139 227 void turnRfOff(void)
rwclough 1:1eb96189824d 228 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 1:1eb96189824d 229 // turnRfOff()
rwclough 1:1eb96189824d 230 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 231 {
rwclough 2:bd5afc5aa139 232 uint8_t cmd[2];
rwclough 1:1eb96189824d 233
rwclough 2:bd5afc5aa139 234 cmd[0] = CHIP_STATUS_CONTROL;
rwclough 2:bd5afc5aa139 235 cmd[1] = CHIP_STATUS_CONTROL;
rwclough 2:bd5afc5aa139 236 spiReadSingle(&cmd[1], 1);
rwclough 2:bd5afc5aa139 237 cmd[1] &= 0x1F;
rwclough 2:bd5afc5aa139 238 spiWriteSingle(cmd, 2);
rwclough 1:1eb96189824d 239 } // End of turnRfOff()
rwclough 1:1eb96189824d 240
rwclough 2:bd5afc5aa139 241 void writeIsoControl(uint8_t iso_control)
rwclough 1:1eb96189824d 242 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 1:1eb96189824d 243 // writeIsoControl()
rwclough 1:1eb96189824d 244 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 245 {
rwclough 2:bd5afc5aa139 246 uint8_t write[4];
rwclough 1:1eb96189824d 247
rwclough 2:bd5afc5aa139 248 if ((iso_control & BIT5) == BIT5) {
rwclough 2:bd5afc5aa139 249 printf("iso_control bit5 != 0\r\n");
rwclough 2:bd5afc5aa139 250 return;
rwclough 2:bd5afc5aa139 251 }
rwclough 1:1eb96189824d 252
rwclough 1:1eb96189824d 253 write[0] = ISO_CONTROL;
rwclough 1:1eb96189824d 254 write[1] = iso_control;
rwclough 2:bd5afc5aa139 255 write[1] &= ~BIT5;
rwclough 2:bd5afc5aa139 256 spiWriteSingle(write, 2);
rwclough 2:bd5afc5aa139 257
rwclough 2:bd5afc5aa139 258 // wait_ms(100);
rwclough 2:bd5afc5aa139 259 // spiReadSingle(write, 1);
rwclough 2:bd5afc5aa139 260 // printf("Reg[0]: 0x%X\r\n", write[0]);
rwclough 2:bd5afc5aa139 261 // printf("Reg[1]: 0x%X\r\n", write[1]);
rwclough 1:1eb96189824d 262
rwclough 1:1eb96189824d 263 iso_control &= 0x1F;
rwclough 1:1eb96189824d 264 } // End of writeIsoControl()
rwclough 1:1eb96189824d 265
rwclough 2:bd5afc5aa139 266 void resetIrqStatus(void)
rwclough 1:1eb96189824d 267 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 1:1eb96189824d 268 // resetIrqStatus()
rwclough 1:1eb96189824d 269 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 270 {
rwclough 2:bd5afc5aa139 271 uint8_t irq_status[4];
rwclough 2:bd5afc5aa139 272
rwclough 2:bd5afc5aa139 273 irq_status[0] = IRQ_STATUS;
rwclough 2:bd5afc5aa139 274 irq_status[1] = IRQ_MASK;
rwclough 2:bd5afc5aa139 275
rwclough 2:bd5afc5aa139 276 spiReadContinuous(irq_status, 2); // Read second register as dummy read
rwclough 1:1eb96189824d 277 }
rwclough 1:1eb96189824d 278
rwclough 2:bd5afc5aa139 279 void iso15693FindTag(void)
rwclough 1:1eb96189824d 280 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 1:1eb96189824d 281 // iso15693FindTag()
rwclough 1:1eb96189824d 282 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 283 {
rwclough 1:1eb96189824d 284 turnRfOn();
rwclough 1:1eb96189824d 285 writeIsoControl(0x02);
rwclough 1:1eb96189824d 286 // The VCD should wait at least 1 ms after it activated the
rwclough 1:1eb96189824d 287 // powering field before sending the first request, to
rwclough 1:1eb96189824d 288 // ensure that the VICCs are ready to receive it. (ISO15693-3)
rwclough 1:1eb96189824d 289 wait_ms(6);
rwclough 2:bd5afc5aa139 290 flags = SIXTEEN_SLOTS; // 0x06
rwclough 2:bd5afc5aa139 291 buf[20] = 0x00;
rwclough 2:bd5afc5aa139 292 Iso15693Anticollision(&buf[20], 0x00); // Send Inventory request
rwclough 1:1eb96189824d 293 turnRfOff();
rwclough 1:1eb96189824d 294 resetIrqStatus(); // Clear any IRQs
rwclough 1:1eb96189824d 295 } // End of iso15693FindTag()
rwclough 1:1eb96189824d 296
rwclough 2:bd5afc5aa139 297 void Iso15693Anticollision(uint8_t *mask, uint8_t length)
rwclough 1:1eb96189824d 298 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 1:1eb96189824d 299 // Iso15693Anticollision()
rwclough 2:bd5afc5aa139 300 // Description: Used to perform an inventory cycle of 1 or 16 timeslots.
rwclough 2:bd5afc5aa139 301 // Send command, receive response and send response to host.
rwclough 2:bd5afc5aa139 302 // Parameters: *mask = mask value
rwclough 2:bd5afc5aa139 303 // length = number of significant bits of mask value
rwclough 1:1eb96189824d 304 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rwclough 2:bd5afc5aa139 305 {
rwclough 2:bd5afc5aa139 306 uint8_t i = 1, j = 1, command[2], no_slots, found = 0;
rwclough 2:bd5afc5aa139 307 uint8_t *p_slot_no, slot_no[17];
rwclough 2:bd5afc5aa139 308 uint8_t new_mask[8], new_length, mask_size;
rwclough 2:bd5afc5aa139 309 uint32_t size;
rwclough 2:bd5afc5aa139 310 uint8_t fifo_length = 0;
rwclough 2:bd5afc5aa139 311 uint16_t k;
rwclough 2:bd5afc5aa139 312
rwclough 2:bd5afc5aa139 313 slot_no[0] = 0x00;
rwclough 2:bd5afc5aa139 314 if ((flags & BIT5) == 0x00) { // flag bit5 is the number of slots indicator
rwclough 2:bd5afc5aa139 315 no_slots = 16; // 16 slots if bit5 is cleared
rwclough 2:bd5afc5aa139 316 }
rwclough 2:bd5afc5aa139 317 else {
rwclough 2:bd5afc5aa139 318 no_slots = 1; // 1 slot if bit5 is set
rwclough 2:bd5afc5aa139 319 }
rwclough 2:bd5afc5aa139 320
rwclough 2:bd5afc5aa139 321 p_slot_no = &slot_no[0]; // slot number pointer
rwclough 2:bd5afc5aa139 322 mask_size = (((length >> 2) + 1) >> 1); // mask_size is 1 for length = 4 or 8
rwclough 2:bd5afc5aa139 323 buf[0] = 0x8F; // RESET
rwclough 2:bd5afc5aa139 324 buf[1] = 0x91; // send with CRC
rwclough 2:bd5afc5aa139 325 buf[2] = 0x3D; // write continuous from 1D
rwclough 2:bd5afc5aa139 326 buf[5] = flags; // ISO15693 flags
rwclough 2:bd5afc5aa139 327 buf[6] = 0x01; // anticollision command code
rwclough 2:bd5afc5aa139 328
rwclough 2:bd5afc5aa139 329 if (flags & 0x10) { // mask_size is 2 for length = 12 or 16 and so on
rwclough 2:bd5afc5aa139 330 size = mask_size + 4; // mask value + mask length + afi + command code + flags
rwclough 2:bd5afc5aa139 331 buf[7] = afi;
rwclough 2:bd5afc5aa139 332 buf[8] = length; // mask length
rwclough 2:bd5afc5aa139 333 if (length > 0) {
rwclough 2:bd5afc5aa139 334 for(i = 0; i < mask_size; i++) {
rwclough 2:bd5afc5aa139 335 buf[9 + i] = *(mask + i);
rwclough 2:bd5afc5aa139 336 }
rwclough 2:bd5afc5aa139 337 }
rwclough 2:bd5afc5aa139 338 fifo_length = 9;
rwclough 2:bd5afc5aa139 339 }
rwclough 2:bd5afc5aa139 340 else { // mask_size is 2 for length = 12 or 16 and so on
rwclough 2:bd5afc5aa139 341 size = mask_size + 3; // mask value + mask length + command code + flags
rwclough 2:bd5afc5aa139 342 buf[7] = length; // mask length
rwclough 2:bd5afc5aa139 343 if(length > 0) {
rwclough 2:bd5afc5aa139 344 for(i = 0; i < mask_size; i++) {
rwclough 2:bd5afc5aa139 345 buf[8 + i] = *(mask + i);
rwclough 2:bd5afc5aa139 346 }
rwclough 2:bd5afc5aa139 347 }
rwclough 2:bd5afc5aa139 348 fifo_length = 8;
rwclough 2:bd5afc5aa139 349 }
rwclough 2:bd5afc5aa139 350
rwclough 2:bd5afc5aa139 351 buf[3] = (char) (size >> 8);
rwclough 2:bd5afc5aa139 352 buf[4] = (char) (size << 4);
rwclough 2:bd5afc5aa139 353
rwclough 2:bd5afc5aa139 354 resetIrqStatus();
rwclough 2:bd5afc5aa139 355
rwclough 2:bd5afc5aa139 356 spiRawWrite(&buf[0], mask_size + fifo_length); // Write to FIFO
rwclough 2:bd5afc5aa139 357 irqRegister = 0x01;
rwclough 2:bd5afc5aa139 358 irqFlag = 0x00;
rwclough 2:bd5afc5aa139 359 readerInt.enable_irq();
rwclough 2:bd5afc5aa139 360
rwclough 2:bd5afc5aa139 361 printf("Anticollision 1 \r\n"); wait_ms(100);
rwclough 2:bd5afc5aa139 362
rwclough 2:bd5afc5aa139 363 while(irqFlag == 0x00); // Wait for end-of-TX interrupt
rwclough 2:bd5afc5aa139 364
rwclough 2:bd5afc5aa139 365 printf("Anticollision 2 \r\n"); wait_ms(100);
rwclough 1:1eb96189824d 366
rwclough 2:bd5afc5aa139 367 for (j=1; j <= no_slots; j++) { // 1 or 16 available timeslots
rwclough 2:bd5afc5aa139 368 rxtxState = 1;
rwclough 2:bd5afc5aa139 369 irqFlag = 0x00;
rwclough 2:bd5afc5aa139 370 while(irqFlag == 0x00); // Wait for interrupt
rwclough 2:bd5afc5aa139 371 while(irqRegister == 0x01) { // Wait for RX complete
rwclough 2:bd5afc5aa139 372 k++;
rwclough 2:bd5afc5aa139 373 if (k == 0xFFF0) {
rwclough 2:bd5afc5aa139 374 irqRegister = 0x00;
rwclough 2:bd5afc5aa139 375 rxErrorFlag = 0x00;
rwclough 2:bd5afc5aa139 376 }
rwclough 2:bd5afc5aa139 377 } // while
rwclough 2:bd5afc5aa139 378 command[0] = RSSI_LEVELS; // Read RSSI levels
rwclough 2:bd5afc5aa139 379 spiReadSingle(command, 1);
rwclough 2:bd5afc5aa139 380 switch (irqRegister) {
rwclough 2:bd5afc5aa139 381 case 0xFF: // If received UID in buffer
rwclough 2:bd5afc5aa139 382 printf("ISO15693: [ ");
rwclough 2:bd5afc5aa139 383 for (i=3; i < 11; i++) {
rwclough 2:bd5afc5aa139 384 printf("%c", buf[i]);
rwclough 2:bd5afc5aa139 385 }
rwclough 2:bd5afc5aa139 386 printf(", %d ]\r\n", command[0]);
rwclough 2:bd5afc5aa139 387 break;
rwclough 2:bd5afc5aa139 388
rwclough 2:bd5afc5aa139 389 case 0x02: // Collision occurred
rwclough 2:bd5afc5aa139 390 p_slot_no++; // Remember a collision was detected
rwclough 2:bd5afc5aa139 391 *p_slot_no = j;
rwclough 2:bd5afc5aa139 392 break;
rwclough 2:bd5afc5aa139 393
rwclough 2:bd5afc5aa139 394 case 0x00: // Timer interrupt
rwclough 2:bd5afc5aa139 395 break;
rwclough 2:bd5afc5aa139 396
rwclough 2:bd5afc5aa139 397 default:
rwclough 2:bd5afc5aa139 398 break;
rwclough 2:bd5afc5aa139 399 } // switch
rwclough 2:bd5afc5aa139 400
rwclough 2:bd5afc5aa139 401 command[0] = RESET; // FIFO must be reset before receiving the next response
rwclough 2:bd5afc5aa139 402 spiDirectCommand(command);
rwclough 2:bd5afc5aa139 403
rwclough 2:bd5afc5aa139 404 if ((no_slots == 16) && (j < 16)) { // If 16 slots used then send EOF (next slot)
rwclough 2:bd5afc5aa139 405 stopDecoders();
rwclough 2:bd5afc5aa139 406 runDecoders();
rwclough 2:bd5afc5aa139 407 txNextSlot();
rwclough 2:bd5afc5aa139 408 }
rwclough 2:bd5afc5aa139 409 else if ((no_slots == 16) && (j == 16)) { // At end of slot 16, stop the slot counter
rwclough 2:bd5afc5aa139 410 stopDecoders();
rwclough 2:bd5afc5aa139 411 disableSlotCounter();
rwclough 2:bd5afc5aa139 412 }
rwclough 2:bd5afc5aa139 413 else if (no_slots == 1) { // 1 slot is uesd
rwclough 2:bd5afc5aa139 414 break;
rwclough 2:bd5afc5aa139 415 }
rwclough 2:bd5afc5aa139 416 } // for
rwclough 2:bd5afc5aa139 417
rwclough 2:bd5afc5aa139 418 if (found == 1) {
rwclough 2:bd5afc5aa139 419 ISO15693LED = LED_ON;
rwclough 2:bd5afc5aa139 420 printf("Found ISO15693 tag\r\n");
rwclough 2:bd5afc5aa139 421 }
rwclough 2:bd5afc5aa139 422 else {
rwclough 2:bd5afc5aa139 423 ISO15693LED = LED_OFF;
rwclough 2:bd5afc5aa139 424 }
rwclough 2:bd5afc5aa139 425
rwclough 2:bd5afc5aa139 426 new_length = length + 4; // The mask length is a multiple of 4 bits
rwclough 2:bd5afc5aa139 427 mask_size = (((new_length >> 2) + 1) >> 1);
rwclough 2:bd5afc5aa139 428 while ((*p_slot_no != 0x00) && (no_slots == 16) && (new_length < 61) && (slot_no[16] != 16)) {
rwclough 2:bd5afc5aa139 429 *p_slot_no = *p_slot_no - 1;
rwclough 2:bd5afc5aa139 430
rwclough 2:bd5afc5aa139 431 for(i = 0; i < 8; i++)
rwclough 2:bd5afc5aa139 432 {
rwclough 2:bd5afc5aa139 433 new_mask[i] = *(mask + i); // First the whole mask is copied
rwclough 2:bd5afc5aa139 434 }
rwclough 2:bd5afc5aa139 435
rwclough 2:bd5afc5aa139 436 if((new_length & BIT2) == 0x00)
rwclough 2:bd5afc5aa139 437 {
rwclough 2:bd5afc5aa139 438 *p_slot_no = *p_slot_no << 4;
rwclough 2:bd5afc5aa139 439 }
rwclough 2:bd5afc5aa139 440 else
rwclough 2:bd5afc5aa139 441 {
rwclough 2:bd5afc5aa139 442 for(i = 7; i > 0; i--)
rwclough 2:bd5afc5aa139 443 {
rwclough 2:bd5afc5aa139 444 new_mask[i] = new_mask[i - 1];
rwclough 2:bd5afc5aa139 445 }
rwclough 2:bd5afc5aa139 446 new_mask[0] &= 0x00;
rwclough 2:bd5afc5aa139 447 }
rwclough 2:bd5afc5aa139 448 new_mask[0] |= *p_slot_no; // The mask is changed
rwclough 2:bd5afc5aa139 449 wait_ms(2);
rwclough 2:bd5afc5aa139 450
rwclough 2:bd5afc5aa139 451 Iso15693Anticollision(&new_mask[0], new_length); // Recursive call with new Mask
rwclough 2:bd5afc5aa139 452
rwclough 2:bd5afc5aa139 453 p_slot_no--;
rwclough 2:bd5afc5aa139 454 }
rwclough 2:bd5afc5aa139 455
rwclough 2:bd5afc5aa139 456 readerInt.disable_irq();
rwclough 1:1eb96189824d 457 } // End of Iso15693Anticollision()