interrupt handling

Dependencies:  

Committer:
rwclough
Date:
Fri Mar 20 19:51:01 2015 +0000
Revision:
4:9ab0d84bbd07
Parent:
3:eaae5433ab45
Child:
5:93c612f43ec2
Progress as of Friday 2015-03-20.

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