interrupt handling
readerComm.cpp@3:eaae5433ab45, 2015-03-12 (annotated)
- 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?
User | Revision | Line number | New 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() |