interrupt handling
readerComm.cpp@2:bd5afc5aa139, 2015-03-05 (annotated)
- 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?
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 | 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() |