Fork of the GitHub

Committer:
DiegoOstuni
Date:
Thu Nov 14 14:34:50 2019 +0000
Revision:
0:75fc82583a41
Add files

Who changed what in which revision?

UserRevisionLine numberNew contents of line
DiegoOstuni 0:75fc82583a41 1
DiegoOstuni 0:75fc82583a41 2 /******************************************************************************
DiegoOstuni 0:75fc82583a41 3 * @attention
DiegoOstuni 0:75fc82583a41 4 *
DiegoOstuni 0:75fc82583a41 5 * <h2><center>&copy; COPYRIGHT 2016 STMicroelectronics</center></h2>
DiegoOstuni 0:75fc82583a41 6 *
DiegoOstuni 0:75fc82583a41 7 * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
DiegoOstuni 0:75fc82583a41 8 * You may not use this file except in compliance with the License.
DiegoOstuni 0:75fc82583a41 9 * You may obtain a copy of the License at:
DiegoOstuni 0:75fc82583a41 10 *
DiegoOstuni 0:75fc82583a41 11 * http://www.st.com/myliberty
DiegoOstuni 0:75fc82583a41 12 *
DiegoOstuni 0:75fc82583a41 13 * Unless required by applicable law or agreed to in writing, software
DiegoOstuni 0:75fc82583a41 14 * distributed under the License is distributed on an "AS IS" BASIS,
DiegoOstuni 0:75fc82583a41 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
DiegoOstuni 0:75fc82583a41 16 * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
DiegoOstuni 0:75fc82583a41 17 * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
DiegoOstuni 0:75fc82583a41 18 * See the License for the specific language governing permissions and
DiegoOstuni 0:75fc82583a41 19 * limitations under the License.
DiegoOstuni 0:75fc82583a41 20 *
DiegoOstuni 0:75fc82583a41 21 ******************************************************************************/
DiegoOstuni 0:75fc82583a41 22
DiegoOstuni 0:75fc82583a41 23 /*
DiegoOstuni 0:75fc82583a41 24 * PROJECT: ST25R391x firmware
DiegoOstuni 0:75fc82583a41 25 * $Revision: $
DiegoOstuni 0:75fc82583a41 26 * LANGUAGE: ISO C99
DiegoOstuni 0:75fc82583a41 27 */
DiegoOstuni 0:75fc82583a41 28
DiegoOstuni 0:75fc82583a41 29 /*! \file rfal_iso15693_2.c
DiegoOstuni 0:75fc82583a41 30 *
DiegoOstuni 0:75fc82583a41 31 * \author Ulrich Herrmann
DiegoOstuni 0:75fc82583a41 32 *
DiegoOstuni 0:75fc82583a41 33 * \brief Implementation of ISO-15693-2
DiegoOstuni 0:75fc82583a41 34 *
DiegoOstuni 0:75fc82583a41 35 */
DiegoOstuni 0:75fc82583a41 36
DiegoOstuni 0:75fc82583a41 37 /*
DiegoOstuni 0:75fc82583a41 38 ******************************************************************************
DiegoOstuni 0:75fc82583a41 39 * INCLUDES
DiegoOstuni 0:75fc82583a41 40 ******************************************************************************
DiegoOstuni 0:75fc82583a41 41 */
DiegoOstuni 0:75fc82583a41 42 #include "rfal_iso15693_2.h"
DiegoOstuni 0:75fc82583a41 43 #include "rfal_crc.h"
DiegoOstuni 0:75fc82583a41 44 #include "utils.h"
DiegoOstuni 0:75fc82583a41 45 #include "platform1.h"
DiegoOstuni 0:75fc82583a41 46
DiegoOstuni 0:75fc82583a41 47 /*
DiegoOstuni 0:75fc82583a41 48 ******************************************************************************
DiegoOstuni 0:75fc82583a41 49 * ENABLE SWITCH
DiegoOstuni 0:75fc82583a41 50 ******************************************************************************
DiegoOstuni 0:75fc82583a41 51 */
DiegoOstuni 0:75fc82583a41 52
DiegoOstuni 0:75fc82583a41 53 #ifndef RFAL_FEATURE_NFCV
DiegoOstuni 0:75fc82583a41 54 #error " RFAL: Module configuration missing. Please enable/disable NFC-V module by setting: RFAL_FEATURE_NFCV "
DiegoOstuni 0:75fc82583a41 55 #endif
DiegoOstuni 0:75fc82583a41 56
DiegoOstuni 0:75fc82583a41 57 #if RFAL_FEATURE_NFCV
DiegoOstuni 0:75fc82583a41 58
DiegoOstuni 0:75fc82583a41 59 /*
DiegoOstuni 0:75fc82583a41 60 ******************************************************************************
DiegoOstuni 0:75fc82583a41 61 * LOCAL MACROS
DiegoOstuni 0:75fc82583a41 62 ******************************************************************************
DiegoOstuni 0:75fc82583a41 63 */
DiegoOstuni 0:75fc82583a41 64
DiegoOstuni 0:75fc82583a41 65 /* #define ISO_15693_DEBUG dbgLog */
DiegoOstuni 0:75fc82583a41 66 #define ISO_15693_DEBUG(...) /*!< Macro for the log method */
DiegoOstuni 0:75fc82583a41 67
DiegoOstuni 0:75fc82583a41 68 /*
DiegoOstuni 0:75fc82583a41 69 ******************************************************************************
DiegoOstuni 0:75fc82583a41 70 * LOCAL DEFINES
DiegoOstuni 0:75fc82583a41 71 ******************************************************************************
DiegoOstuni 0:75fc82583a41 72 */
DiegoOstuni 0:75fc82583a41 73 #define ISO15693_DAT_SOF_1_4 0x21 /* LSB constants */
DiegoOstuni 0:75fc82583a41 74 #define ISO15693_DAT_EOF_1_4 0x04
DiegoOstuni 0:75fc82583a41 75 #define ISO15693_DAT_00_1_4 0x02
DiegoOstuni 0:75fc82583a41 76 #define ISO15693_DAT_01_1_4 0x08
DiegoOstuni 0:75fc82583a41 77 #define ISO15693_DAT_10_1_4 0x20
DiegoOstuni 0:75fc82583a41 78 #define ISO15693_DAT_11_1_4 0x80
DiegoOstuni 0:75fc82583a41 79
DiegoOstuni 0:75fc82583a41 80 #define ISO15693_DAT_SOF_1_256 0x81
DiegoOstuni 0:75fc82583a41 81 #define ISO15693_DAT_EOF_1_256 0x04
DiegoOstuni 0:75fc82583a41 82 #define ISO15693_DAT_SLOT0_1_256 0x02
DiegoOstuni 0:75fc82583a41 83 #define ISO15693_DAT_SLOT1_1_256 0x08
DiegoOstuni 0:75fc82583a41 84 #define ISO15693_DAT_SLOT2_1_256 0x20
DiegoOstuni 0:75fc82583a41 85 #define ISO15693_DAT_SLOT3_1_256 0x80
DiegoOstuni 0:75fc82583a41 86
DiegoOstuni 0:75fc82583a41 87 #define ISO15693_PHY_DAT_MANCHESTER_1 0xaaaa
DiegoOstuni 0:75fc82583a41 88
DiegoOstuni 0:75fc82583a41 89 #define ISO15693_PHY_BIT_BUFFER_SIZE 1000 /*!<
DiegoOstuni 0:75fc82583a41 90 size of the receiving buffer. Might be adjusted
DiegoOstuni 0:75fc82583a41 91 if longer datastreams are expected. */
DiegoOstuni 0:75fc82583a41 92
DiegoOstuni 0:75fc82583a41 93
DiegoOstuni 0:75fc82583a41 94 /*
DiegoOstuni 0:75fc82583a41 95 ******************************************************************************
DiegoOstuni 0:75fc82583a41 96 * LOCAL VARIABLES
DiegoOstuni 0:75fc82583a41 97 ******************************************************************************
DiegoOstuni 0:75fc82583a41 98 */
DiegoOstuni 0:75fc82583a41 99 static iso15693PhyConfig_t iso15693PhyConfig; /*!< current phy configuration */
DiegoOstuni 0:75fc82583a41 100
DiegoOstuni 0:75fc82583a41 101 /*
DiegoOstuni 0:75fc82583a41 102 ******************************************************************************
DiegoOstuni 0:75fc82583a41 103 * LOCAL FUNCTION PROTOTYPES
DiegoOstuni 0:75fc82583a41 104 ******************************************************************************
DiegoOstuni 0:75fc82583a41 105 */
DiegoOstuni 0:75fc82583a41 106 static ReturnCode iso15693PhyVCDCode1Of4(const uint8_t data, uint8_t* outbuf, uint16_t maxOutBufLen, uint16_t* outBufLen);
DiegoOstuni 0:75fc82583a41 107 static ReturnCode iso15693PhyVCDCode1Of256(const uint8_t data, uint8_t* outbuf, uint16_t maxOutBufLen, uint16_t* outBufLen);
DiegoOstuni 0:75fc82583a41 108
DiegoOstuni 0:75fc82583a41 109 static struct iso15693StreamConfig stream_config = {
DiegoOstuni 0:75fc82583a41 110 .useBPSK = 0, /* 0: subcarrier, 1:BPSK */
DiegoOstuni 0:75fc82583a41 111 .din = 5, /* 2^5*fc = 423750 Hz: divider for the in subcarrier frequency */
DiegoOstuni 0:75fc82583a41 112 .dout = 7, /*!< 2^7*fc = 105937 : divider for the in subcarrier frequency */
DiegoOstuni 0:75fc82583a41 113 .report_period_length = 3, /*!< 8=2^3 the length of the reporting period */
DiegoOstuni 0:75fc82583a41 114 };
DiegoOstuni 0:75fc82583a41 115
DiegoOstuni 0:75fc82583a41 116 /*
DiegoOstuni 0:75fc82583a41 117 ******************************************************************************
DiegoOstuni 0:75fc82583a41 118 * GLOBAL FUNCTIONS
DiegoOstuni 0:75fc82583a41 119 ******************************************************************************
DiegoOstuni 0:75fc82583a41 120 */
DiegoOstuni 0:75fc82583a41 121 ReturnCode iso15693PhyConfigure(const iso15693PhyConfig_t* config, const struct iso15693StreamConfig ** needed_stream_config )
DiegoOstuni 0:75fc82583a41 122 {
DiegoOstuni 0:75fc82583a41 123
DiegoOstuni 0:75fc82583a41 124 /* make a copy of the configuration */
DiegoOstuni 0:75fc82583a41 125 ST_MEMCPY(&iso15693PhyConfig, (uint8_t*)config, sizeof(iso15693PhyConfig_t));
DiegoOstuni 0:75fc82583a41 126
DiegoOstuni 0:75fc82583a41 127 /* If in fast mode the report period is half: 4=2^2 */
DiegoOstuni 0:75fc82583a41 128 stream_config.report_period_length = ( config->fastMode ? 2 : 3 );
DiegoOstuni 0:75fc82583a41 129
DiegoOstuni 0:75fc82583a41 130 *needed_stream_config = &stream_config;
DiegoOstuni 0:75fc82583a41 131
DiegoOstuni 0:75fc82583a41 132 return ERR_NONE;
DiegoOstuni 0:75fc82583a41 133 }
DiegoOstuni 0:75fc82583a41 134
DiegoOstuni 0:75fc82583a41 135 ReturnCode iso15693PhyGetConfiguration(iso15693PhyConfig_t* config)
DiegoOstuni 0:75fc82583a41 136 {
DiegoOstuni 0:75fc82583a41 137 ST_MEMCPY(config, &iso15693PhyConfig, sizeof(iso15693PhyConfig_t));
DiegoOstuni 0:75fc82583a41 138
DiegoOstuni 0:75fc82583a41 139 return ERR_NONE;
DiegoOstuni 0:75fc82583a41 140 }
DiegoOstuni 0:75fc82583a41 141
DiegoOstuni 0:75fc82583a41 142 ReturnCode iso15693VCDCode(uint8_t* buffer, uint16_t length, bool sendCrc, bool sendFlags, bool picopassMode,
DiegoOstuni 0:75fc82583a41 143 uint16_t *subbit_total_length, uint16_t *offset,
DiegoOstuni 0:75fc82583a41 144 uint8_t* outbuf, uint16_t outBufSize, uint16_t* actOutBufSize)
DiegoOstuni 0:75fc82583a41 145 {
DiegoOstuni 0:75fc82583a41 146 ReturnCode err = ERR_NONE;
DiegoOstuni 0:75fc82583a41 147 uint8_t eof, sof;
DiegoOstuni 0:75fc82583a41 148 uint8_t transbuf[2];
DiegoOstuni 0:75fc82583a41 149 uint16_t crc = 0;
DiegoOstuni 0:75fc82583a41 150 ReturnCode (*txFunc)(const uint8_t, uint8_t*, uint16_t, uint16_t*);
DiegoOstuni 0:75fc82583a41 151 uint8_t crc_len;
DiegoOstuni 0:75fc82583a41 152
DiegoOstuni 0:75fc82583a41 153 crc_len = ((sendCrc)?2:0);
DiegoOstuni 0:75fc82583a41 154
DiegoOstuni 0:75fc82583a41 155 *actOutBufSize = 0;
DiegoOstuni 0:75fc82583a41 156
DiegoOstuni 0:75fc82583a41 157 if (ISO15693_VCD_CODING_1_4 == iso15693PhyConfig.coding)
DiegoOstuni 0:75fc82583a41 158 {
DiegoOstuni 0:75fc82583a41 159 sof = ISO15693_DAT_SOF_1_4;
DiegoOstuni 0:75fc82583a41 160 eof = ISO15693_DAT_EOF_1_4;
DiegoOstuni 0:75fc82583a41 161 txFunc = iso15693PhyVCDCode1Of4;
DiegoOstuni 0:75fc82583a41 162 *subbit_total_length = (
DiegoOstuni 0:75fc82583a41 163 ( 1 /* SOF */
DiegoOstuni 0:75fc82583a41 164 + (length + crc_len) * 4
DiegoOstuni 0:75fc82583a41 165 + 1) /* EOF */
DiegoOstuni 0:75fc82583a41 166 );
DiegoOstuni 0:75fc82583a41 167 if (outBufSize < 5) /* 5 should be safe: enough for sof + 1byte data in 1of4 */
DiegoOstuni 0:75fc82583a41 168 return ERR_NOMEM;
DiegoOstuni 0:75fc82583a41 169 }
DiegoOstuni 0:75fc82583a41 170 else
DiegoOstuni 0:75fc82583a41 171 {
DiegoOstuni 0:75fc82583a41 172 sof = ISO15693_DAT_SOF_1_256;
DiegoOstuni 0:75fc82583a41 173 eof = ISO15693_DAT_EOF_1_256;
DiegoOstuni 0:75fc82583a41 174 txFunc = iso15693PhyVCDCode1Of256;
DiegoOstuni 0:75fc82583a41 175 *subbit_total_length = (
DiegoOstuni 0:75fc82583a41 176 ( 1 /* SOF */
DiegoOstuni 0:75fc82583a41 177 + (length + crc_len) * 64
DiegoOstuni 0:75fc82583a41 178 + 1) /* EOF */
DiegoOstuni 0:75fc82583a41 179 );
DiegoOstuni 0:75fc82583a41 180
DiegoOstuni 0:75fc82583a41 181 if (*offset)
DiegoOstuni 0:75fc82583a41 182 {
DiegoOstuni 0:75fc82583a41 183 if (outBufSize < 64) /* 64 should be safe: enough a single byte data in 1of256 */
DiegoOstuni 0:75fc82583a41 184 return ERR_NOMEM;
DiegoOstuni 0:75fc82583a41 185 }
DiegoOstuni 0:75fc82583a41 186 else
DiegoOstuni 0:75fc82583a41 187 {
DiegoOstuni 0:75fc82583a41 188 if (outBufSize < 65) /* At beginning of a frame we need at least 65 bytes to start: enough for sof + 1byte data in 1of256 */
DiegoOstuni 0:75fc82583a41 189 return ERR_NOMEM;
DiegoOstuni 0:75fc82583a41 190 }
DiegoOstuni 0:75fc82583a41 191 }
DiegoOstuni 0:75fc82583a41 192
DiegoOstuni 0:75fc82583a41 193 if (length == 0)
DiegoOstuni 0:75fc82583a41 194 {
DiegoOstuni 0:75fc82583a41 195 *subbit_total_length = 1;
DiegoOstuni 0:75fc82583a41 196 }
DiegoOstuni 0:75fc82583a41 197
DiegoOstuni 0:75fc82583a41 198 if (length && (0 == *offset) && sendFlags && !picopassMode)
DiegoOstuni 0:75fc82583a41 199 {
DiegoOstuni 0:75fc82583a41 200 /* set high datarate flag */
DiegoOstuni 0:75fc82583a41 201 buffer[0] |= ISO15693_REQ_FLAG_HIGH_DATARATE;
DiegoOstuni 0:75fc82583a41 202 /* clear sub-carrier flag - we only support single sub-carrier */
DiegoOstuni 0:75fc82583a41 203 buffer[0] &= ~ISO15693_REQ_FLAG_TWO_SUBCARRIERS;
DiegoOstuni 0:75fc82583a41 204 }
DiegoOstuni 0:75fc82583a41 205
DiegoOstuni 0:75fc82583a41 206 /* Send SOF if at 0 offset */
DiegoOstuni 0:75fc82583a41 207 if (length && 0 == *offset)
DiegoOstuni 0:75fc82583a41 208 {
DiegoOstuni 0:75fc82583a41 209 *outbuf = sof;
DiegoOstuni 0:75fc82583a41 210 (*actOutBufSize)++;
DiegoOstuni 0:75fc82583a41 211 outBufSize--;
DiegoOstuni 0:75fc82583a41 212 outbuf++;
DiegoOstuni 0:75fc82583a41 213 }
DiegoOstuni 0:75fc82583a41 214
DiegoOstuni 0:75fc82583a41 215 while (*offset < length && err == ERR_NONE)
DiegoOstuni 0:75fc82583a41 216 {
DiegoOstuni 0:75fc82583a41 217 uint16_t filled_size;
DiegoOstuni 0:75fc82583a41 218 /* send data */
DiegoOstuni 0:75fc82583a41 219 err = txFunc(buffer[*offset], outbuf, outBufSize, &filled_size);
DiegoOstuni 0:75fc82583a41 220 (*actOutBufSize) += filled_size;
DiegoOstuni 0:75fc82583a41 221 outbuf+=filled_size;
DiegoOstuni 0:75fc82583a41 222 outBufSize -= filled_size;
DiegoOstuni 0:75fc82583a41 223 if (!err) (*offset)++;
DiegoOstuni 0:75fc82583a41 224 }
DiegoOstuni 0:75fc82583a41 225 if (err) return ERR_AGAIN;
DiegoOstuni 0:75fc82583a41 226
DiegoOstuni 0:75fc82583a41 227 while (!err && sendCrc && *offset < length + 2)
DiegoOstuni 0:75fc82583a41 228 {
DiegoOstuni 0:75fc82583a41 229 uint16_t filled_size;
DiegoOstuni 0:75fc82583a41 230 if (0==crc)
DiegoOstuni 0:75fc82583a41 231 {
DiegoOstuni 0:75fc82583a41 232 crc = rfalCrcCalculateCcitt( ((picopassMode) ? 0xE012 : 0xFFFF), /* In PicoPass Mode a different Preset Value is used */
DiegoOstuni 0:75fc82583a41 233 ((picopassMode) ? (buffer + 1) : buffer), /* CMD byte is not taken into account in PicoPass mode */
DiegoOstuni 0:75fc82583a41 234 ((picopassMode) ? (length - 1) : length)); /* CMD byte is not taken into account in PicoPass mode */
DiegoOstuni 0:75fc82583a41 235
DiegoOstuni 0:75fc82583a41 236 crc = ((picopassMode) ? crc : ~crc);
DiegoOstuni 0:75fc82583a41 237 }
DiegoOstuni 0:75fc82583a41 238 /* send crc */
DiegoOstuni 0:75fc82583a41 239 transbuf[0] = crc & 0xff;
DiegoOstuni 0:75fc82583a41 240 transbuf[1] = (crc >> 8) & 0xff;
DiegoOstuni 0:75fc82583a41 241 err = txFunc(transbuf[*offset - length], outbuf, outBufSize, &filled_size);
DiegoOstuni 0:75fc82583a41 242 (*actOutBufSize) += filled_size;
DiegoOstuni 0:75fc82583a41 243 outbuf+=filled_size;
DiegoOstuni 0:75fc82583a41 244 outBufSize -= filled_size;
DiegoOstuni 0:75fc82583a41 245 if(!err) (*offset)++;
DiegoOstuni 0:75fc82583a41 246 }
DiegoOstuni 0:75fc82583a41 247 if (err) return ERR_AGAIN;
DiegoOstuni 0:75fc82583a41 248
DiegoOstuni 0:75fc82583a41 249 if ((!sendCrc && (*offset) == length)
DiegoOstuni 0:75fc82583a41 250 || (sendCrc && (*offset) == length + 2))
DiegoOstuni 0:75fc82583a41 251 {
DiegoOstuni 0:75fc82583a41 252 *outbuf = eof;
DiegoOstuni 0:75fc82583a41 253 (*actOutBufSize)++;
DiegoOstuni 0:75fc82583a41 254 outBufSize--;
DiegoOstuni 0:75fc82583a41 255 outbuf++;
DiegoOstuni 0:75fc82583a41 256 }
DiegoOstuni 0:75fc82583a41 257 else return ERR_AGAIN;
DiegoOstuni 0:75fc82583a41 258
DiegoOstuni 0:75fc82583a41 259 return err;
DiegoOstuni 0:75fc82583a41 260 }
DiegoOstuni 0:75fc82583a41 261
DiegoOstuni 0:75fc82583a41 262 ReturnCode iso15693VICCDecode(uint8_t *inBuf,
DiegoOstuni 0:75fc82583a41 263 uint16_t inBufLen,
DiegoOstuni 0:75fc82583a41 264 uint8_t* outBuf,
DiegoOstuni 0:75fc82583a41 265 uint16_t outBufLen,
DiegoOstuni 0:75fc82583a41 266 uint16_t* outBufPos,
DiegoOstuni 0:75fc82583a41 267 uint16_t* bitsBeforeCol,
DiegoOstuni 0:75fc82583a41 268 uint16_t ignoreBits,
DiegoOstuni 0:75fc82583a41 269 bool picopassMode )
DiegoOstuni 0:75fc82583a41 270 {
DiegoOstuni 0:75fc82583a41 271 ReturnCode err = ERR_NONE;
DiegoOstuni 0:75fc82583a41 272 uint16_t crc;
DiegoOstuni 0:75fc82583a41 273 uint16_t mp; /* Current bit position in manchester bit inBuf*/
DiegoOstuni 0:75fc82583a41 274 uint16_t bp; /* Current bit postion in outBuf */
DiegoOstuni 0:75fc82583a41 275
DiegoOstuni 0:75fc82583a41 276 *bitsBeforeCol = 0;
DiegoOstuni 0:75fc82583a41 277 *outBufPos = 0;
DiegoOstuni 0:75fc82583a41 278
DiegoOstuni 0:75fc82583a41 279 /* first check for valid SOF. Since it starts with 3 unmodulated pulses it is 0x17. */
DiegoOstuni 0:75fc82583a41 280 if ((inBuf[0] & 0x1f) != 0x17)
DiegoOstuni 0:75fc82583a41 281 {
DiegoOstuni 0:75fc82583a41 282 ISO_15693_DEBUG("0x%x\n", iso15693PhyBitBuffer[0]);
DiegoOstuni 0:75fc82583a41 283 err = ERR_FRAMING;
DiegoOstuni 0:75fc82583a41 284 goto out;
DiegoOstuni 0:75fc82583a41 285 }
DiegoOstuni 0:75fc82583a41 286 ISO_15693_DEBUG("SOF\n");
DiegoOstuni 0:75fc82583a41 287
DiegoOstuni 0:75fc82583a41 288 if (!outBufLen)
DiegoOstuni 0:75fc82583a41 289 {
DiegoOstuni 0:75fc82583a41 290 goto out;
DiegoOstuni 0:75fc82583a41 291 }
DiegoOstuni 0:75fc82583a41 292
DiegoOstuni 0:75fc82583a41 293 mp = 5; /* 5 bits were SOF, now manchester starts: 2 bits per payload bit */
DiegoOstuni 0:75fc82583a41 294 bp = 0;
DiegoOstuni 0:75fc82583a41 295
DiegoOstuni 0:75fc82583a41 296 memset(outBuf,0,outBufLen);
DiegoOstuni 0:75fc82583a41 297
DiegoOstuni 0:75fc82583a41 298 for ( ; mp < inBufLen * 8 - 2; mp+=2 )
DiegoOstuni 0:75fc82583a41 299 {
DiegoOstuni 0:75fc82583a41 300 uint8_t man;
DiegoOstuni 0:75fc82583a41 301 man = (inBuf[mp/8] >> mp%8) & 0x1;
DiegoOstuni 0:75fc82583a41 302 man |= ((inBuf[(mp+1)/8] >> (mp+1)%8) & 0x1) << 1;
DiegoOstuni 0:75fc82583a41 303 if (1 == man)
DiegoOstuni 0:75fc82583a41 304 {
DiegoOstuni 0:75fc82583a41 305 bp++;
DiegoOstuni 0:75fc82583a41 306 }
DiegoOstuni 0:75fc82583a41 307 if (2 == man)
DiegoOstuni 0:75fc82583a41 308 {
DiegoOstuni 0:75fc82583a41 309 outBuf[bp/8] |= 1 << (bp%8);
DiegoOstuni 0:75fc82583a41 310 bp++;
DiegoOstuni 0:75fc82583a41 311 }
DiegoOstuni 0:75fc82583a41 312 if (bp%8 == 0)
DiegoOstuni 0:75fc82583a41 313 { /* Check for EOF */
DiegoOstuni 0:75fc82583a41 314 ISO_15693_DEBUG("ceof %hhx %hhx\n", inBuf[mp/8], inBuf[mp/8+1]);
DiegoOstuni 0:75fc82583a41 315 if ( ((inBuf[mp/8] & 0xe0) == 0xa0)
DiegoOstuni 0:75fc82583a41 316 &&(inBuf[mp/8+1] == 0x03))
DiegoOstuni 0:75fc82583a41 317 { /* Now we know that it was 10111000 = EOF */
DiegoOstuni 0:75fc82583a41 318 ISO_15693_DEBUG("EOF\n");
DiegoOstuni 0:75fc82583a41 319 break;
DiegoOstuni 0:75fc82583a41 320 }
DiegoOstuni 0:75fc82583a41 321 }
DiegoOstuni 0:75fc82583a41 322 if (0 == man || 3 == man)
DiegoOstuni 0:75fc82583a41 323 {
DiegoOstuni 0:75fc82583a41 324 if (bp >= ignoreBits)
DiegoOstuni 0:75fc82583a41 325 {
DiegoOstuni 0:75fc82583a41 326 err = ERR_RF_COLLISION;
DiegoOstuni 0:75fc82583a41 327 break;
DiegoOstuni 0:75fc82583a41 328 }
DiegoOstuni 0:75fc82583a41 329 /* ignored collision: leave as 0 */
DiegoOstuni 0:75fc82583a41 330 bp++;
DiegoOstuni 0:75fc82583a41 331 }
DiegoOstuni 0:75fc82583a41 332 if (bp >= outBufLen * 8)
DiegoOstuni 0:75fc82583a41 333 { /* Don't write beyond the end */
DiegoOstuni 0:75fc82583a41 334 break;
DiegoOstuni 0:75fc82583a41 335 }
DiegoOstuni 0:75fc82583a41 336 }
DiegoOstuni 0:75fc82583a41 337
DiegoOstuni 0:75fc82583a41 338 *outBufPos = bp / 8;
DiegoOstuni 0:75fc82583a41 339 *bitsBeforeCol = bp;
DiegoOstuni 0:75fc82583a41 340
DiegoOstuni 0:75fc82583a41 341 if (err) goto out;
DiegoOstuni 0:75fc82583a41 342
DiegoOstuni 0:75fc82583a41 343 if (bp%8 != 0)
DiegoOstuni 0:75fc82583a41 344 {
DiegoOstuni 0:75fc82583a41 345 err = ERR_CRC;
DiegoOstuni 0:75fc82583a41 346 goto out;
DiegoOstuni 0:75fc82583a41 347 }
DiegoOstuni 0:75fc82583a41 348
DiegoOstuni 0:75fc82583a41 349 if (*outBufPos > 2)
DiegoOstuni 0:75fc82583a41 350 {
DiegoOstuni 0:75fc82583a41 351 /* finally, check crc */
DiegoOstuni 0:75fc82583a41 352 ISO_15693_DEBUG("Calculate CRC, val: 0x%x, outBufLen: ", *outBuf);
DiegoOstuni 0:75fc82583a41 353 ISO_15693_DEBUG("0x%x ", *outBufPos - 2);
DiegoOstuni 0:75fc82583a41 354
DiegoOstuni 0:75fc82583a41 355 crc = rfalCrcCalculateCcitt( ((picopassMode) ? 0xE012 : 0xFFFF), outBuf, *outBufPos - 2);
DiegoOstuni 0:75fc82583a41 356 crc = ((picopassMode) ? crc : ~crc);
DiegoOstuni 0:75fc82583a41 357
DiegoOstuni 0:75fc82583a41 358 if (((crc & 0xff) == outBuf[*outBufPos-2]) &&
DiegoOstuni 0:75fc82583a41 359 (((crc >> 8) & 0xff) == outBuf[*outBufPos-1]))
DiegoOstuni 0:75fc82583a41 360 {
DiegoOstuni 0:75fc82583a41 361 err = ERR_NONE;
DiegoOstuni 0:75fc82583a41 362 ISO_15693_DEBUG("OK\n");
DiegoOstuni 0:75fc82583a41 363 }
DiegoOstuni 0:75fc82583a41 364 else
DiegoOstuni 0:75fc82583a41 365 {
DiegoOstuni 0:75fc82583a41 366 ISO_15693_DEBUG("error! Expected: 0x%x, got ", crc);
DiegoOstuni 0:75fc82583a41 367 ISO_15693_DEBUG("0x%hhx 0x%hhx\n", outBuf[*outBufPos-2], outBuf[*outBufPos-1]);
DiegoOstuni 0:75fc82583a41 368 err = ERR_CRC;
DiegoOstuni 0:75fc82583a41 369 }
DiegoOstuni 0:75fc82583a41 370 }
DiegoOstuni 0:75fc82583a41 371 else
DiegoOstuni 0:75fc82583a41 372 {
DiegoOstuni 0:75fc82583a41 373 err = ERR_CRC;
DiegoOstuni 0:75fc82583a41 374 }
DiegoOstuni 0:75fc82583a41 375 out:
DiegoOstuni 0:75fc82583a41 376 return err;
DiegoOstuni 0:75fc82583a41 377 }
DiegoOstuni 0:75fc82583a41 378
DiegoOstuni 0:75fc82583a41 379 /*
DiegoOstuni 0:75fc82583a41 380 ******************************************************************************
DiegoOstuni 0:75fc82583a41 381 * LOCAL FUNCTIONS
DiegoOstuni 0:75fc82583a41 382 ******************************************************************************
DiegoOstuni 0:75fc82583a41 383 */
DiegoOstuni 0:75fc82583a41 384 /*!
DiegoOstuni 0:75fc82583a41 385 *****************************************************************************
DiegoOstuni 0:75fc82583a41 386 * \brief Perform 1 of 4 coding and send coded data
DiegoOstuni 0:75fc82583a41 387 *
DiegoOstuni 0:75fc82583a41 388 * This function takes \a length bytes from \a buffer, perform 1 of 4 coding
DiegoOstuni 0:75fc82583a41 389 * (see ISO15693-2 specification) and sends the data using stream mode.
DiegoOstuni 0:75fc82583a41 390 *
DiegoOstuni 0:75fc82583a41 391 * \param[in] sendSof : send SOF prior to data.
DiegoOstuni 0:75fc82583a41 392 * \param[in] buffer : data to send.
DiegoOstuni 0:75fc82583a41 393 * \param[in] length : number of bytes to send.
DiegoOstuni 0:75fc82583a41 394 *
DiegoOstuni 0:75fc82583a41 395 * \return ERR_IO : Error during communication.
DiegoOstuni 0:75fc82583a41 396 * \return ERR_NONE : No error.
DiegoOstuni 0:75fc82583a41 397 *
DiegoOstuni 0:75fc82583a41 398 *****************************************************************************
DiegoOstuni 0:75fc82583a41 399 */
DiegoOstuni 0:75fc82583a41 400 static ReturnCode iso15693PhyVCDCode1Of4(const uint8_t data, uint8_t* outbuf, uint16_t maxOutBufLen, uint16_t* outBufLen)
DiegoOstuni 0:75fc82583a41 401 {
DiegoOstuni 0:75fc82583a41 402 uint8_t tmp;
DiegoOstuni 0:75fc82583a41 403 ReturnCode err = ERR_NONE;
DiegoOstuni 0:75fc82583a41 404 uint16_t a;
DiegoOstuni 0:75fc82583a41 405
DiegoOstuni 0:75fc82583a41 406 *outBufLen = 0;
DiegoOstuni 0:75fc82583a41 407
DiegoOstuni 0:75fc82583a41 408 if (maxOutBufLen < 4)
DiegoOstuni 0:75fc82583a41 409 return ERR_NOMEM;
DiegoOstuni 0:75fc82583a41 410
DiegoOstuni 0:75fc82583a41 411 tmp = data;
DiegoOstuni 0:75fc82583a41 412 for (a = 0; a < 4; a++)
DiegoOstuni 0:75fc82583a41 413 {
DiegoOstuni 0:75fc82583a41 414 switch (tmp & 0x3)
DiegoOstuni 0:75fc82583a41 415 {
DiegoOstuni 0:75fc82583a41 416 case 0:
DiegoOstuni 0:75fc82583a41 417 *outbuf = ISO15693_DAT_00_1_4;
DiegoOstuni 0:75fc82583a41 418 break;
DiegoOstuni 0:75fc82583a41 419 case 1:
DiegoOstuni 0:75fc82583a41 420 *outbuf = ISO15693_DAT_01_1_4;
DiegoOstuni 0:75fc82583a41 421 break;
DiegoOstuni 0:75fc82583a41 422 case 2:
DiegoOstuni 0:75fc82583a41 423 *outbuf = ISO15693_DAT_10_1_4;
DiegoOstuni 0:75fc82583a41 424 break;
DiegoOstuni 0:75fc82583a41 425 case 3:
DiegoOstuni 0:75fc82583a41 426 *outbuf = ISO15693_DAT_11_1_4;
DiegoOstuni 0:75fc82583a41 427 break;
DiegoOstuni 0:75fc82583a41 428 }
DiegoOstuni 0:75fc82583a41 429 outbuf++;
DiegoOstuni 0:75fc82583a41 430 (*outBufLen)++;
DiegoOstuni 0:75fc82583a41 431 tmp >>= 2;
DiegoOstuni 0:75fc82583a41 432 }
DiegoOstuni 0:75fc82583a41 433 return err;
DiegoOstuni 0:75fc82583a41 434 }
DiegoOstuni 0:75fc82583a41 435
DiegoOstuni 0:75fc82583a41 436 /*!
DiegoOstuni 0:75fc82583a41 437 *****************************************************************************
DiegoOstuni 0:75fc82583a41 438 * \brief Perform 1 of 256 coding and send coded data
DiegoOstuni 0:75fc82583a41 439 *
DiegoOstuni 0:75fc82583a41 440 * This function takes \a length bytes from \a buffer, perform 1 of 256 coding
DiegoOstuni 0:75fc82583a41 441 * (see ISO15693-2 specification) and sends the data using stream mode.
DiegoOstuni 0:75fc82583a41 442 * \note This function sends SOF prior to the data.
DiegoOstuni 0:75fc82583a41 443 *
DiegoOstuni 0:75fc82583a41 444 * \param[in] sendSof : send SOF prior to data.
DiegoOstuni 0:75fc82583a41 445 * \param[in] buffer : data to send.
DiegoOstuni 0:75fc82583a41 446 * \param[in] length : number of bytes to send.
DiegoOstuni 0:75fc82583a41 447 *
DiegoOstuni 0:75fc82583a41 448 * \return ERR_IO : Error during communication.
DiegoOstuni 0:75fc82583a41 449 * \return ERR_NONE : No error.
DiegoOstuni 0:75fc82583a41 450 *
DiegoOstuni 0:75fc82583a41 451 *****************************************************************************
DiegoOstuni 0:75fc82583a41 452 */
DiegoOstuni 0:75fc82583a41 453 static ReturnCode iso15693PhyVCDCode1Of256(const uint8_t data, uint8_t* outbuf, uint16_t maxOutBufLen, uint16_t* outBufLen)
DiegoOstuni 0:75fc82583a41 454 {
DiegoOstuni 0:75fc82583a41 455 uint8_t tmp;
DiegoOstuni 0:75fc82583a41 456 ReturnCode err = ERR_NONE;
DiegoOstuni 0:75fc82583a41 457 uint16_t a;
DiegoOstuni 0:75fc82583a41 458
DiegoOstuni 0:75fc82583a41 459 *outBufLen = 0;
DiegoOstuni 0:75fc82583a41 460
DiegoOstuni 0:75fc82583a41 461 if (maxOutBufLen < 64)
DiegoOstuni 0:75fc82583a41 462 return ERR_NOMEM;
DiegoOstuni 0:75fc82583a41 463
DiegoOstuni 0:75fc82583a41 464 tmp = data;
DiegoOstuni 0:75fc82583a41 465 for (a = 0; a < 64; a++)
DiegoOstuni 0:75fc82583a41 466 {
DiegoOstuni 0:75fc82583a41 467 switch (tmp)
DiegoOstuni 0:75fc82583a41 468 {
DiegoOstuni 0:75fc82583a41 469 case 0:
DiegoOstuni 0:75fc82583a41 470 *outbuf = ISO15693_DAT_SLOT0_1_256;
DiegoOstuni 0:75fc82583a41 471 break;
DiegoOstuni 0:75fc82583a41 472 case 1:
DiegoOstuni 0:75fc82583a41 473 *outbuf = ISO15693_DAT_SLOT1_1_256;
DiegoOstuni 0:75fc82583a41 474 break;
DiegoOstuni 0:75fc82583a41 475 case 2:
DiegoOstuni 0:75fc82583a41 476 *outbuf = ISO15693_DAT_SLOT2_1_256;
DiegoOstuni 0:75fc82583a41 477 break;
DiegoOstuni 0:75fc82583a41 478 case 3:
DiegoOstuni 0:75fc82583a41 479 *outbuf = ISO15693_DAT_SLOT3_1_256;
DiegoOstuni 0:75fc82583a41 480 break;
DiegoOstuni 0:75fc82583a41 481 default:
DiegoOstuni 0:75fc82583a41 482 *outbuf = 0;
DiegoOstuni 0:75fc82583a41 483 }
DiegoOstuni 0:75fc82583a41 484 outbuf++;
DiegoOstuni 0:75fc82583a41 485 (*outBufLen)++;
DiegoOstuni 0:75fc82583a41 486 tmp -= 4;
DiegoOstuni 0:75fc82583a41 487 }
DiegoOstuni 0:75fc82583a41 488
DiegoOstuni 0:75fc82583a41 489 return err;
DiegoOstuni 0:75fc82583a41 490 }
DiegoOstuni 0:75fc82583a41 491
DiegoOstuni 0:75fc82583a41 492 #endif /* RFAL_FEATURE_NFCV */