diff options
Diffstat (limited to 'firmware/src/picc/iso14443a_manchester.c')
-rw-r--r-- | firmware/src/picc/iso14443a_manchester.c | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/firmware/src/picc/iso14443a_manchester.c b/firmware/src/picc/iso14443a_manchester.c new file mode 100644 index 0000000..aca832c --- /dev/null +++ b/firmware/src/picc/iso14443a_manchester.c @@ -0,0 +1,106 @@ +/* + * ISO14443A Manchester encoder + * (C) 2006 by Harald Welte <hwelte@hmw-consulting.de> + * + * Definitions for 106kBps, at sampling clock 1695kHz + * + * bit sample pattern for one bit cycle + * MSB first LSB first hex LSB first + * Sequence D 1010101000000000 0000000001010101 0x0055 + * Sequence E 0000000010101010 0101010100000000 0x5500 + * Sequence F 1010101010101010 0101010101010101 0x5555 + * + * Logic 1 Sequence D + * Logic 0 Sequence E + * SOF Sequence D + * EOF Sequence F + * + * 212/424/848kBps: BPSK. + * + * SOF: 32 subcarrier clocks + bit '0' + * + * SOF: hex LSB first: 0x55555555 55555555 + bit '0' + * + * EOF: even parity of last byte (!) + * + */ + +#define MANCHESTER_SEQ_D 0x0055 +#define MANCHESTER_SEQ_E 0x5500 +#define MANCHESTER_SEQ_F 0x5555 + +static u_int32_t manchester_sample_size(u_int8_t frame_bytelen) +{ + /* 16 bits (2 bytes) per bit => 16 bytes samples per data byte, + * plus 16bit (2 bytes) parity per data byte + * plus 16bit (2 bytes) SOF plus 16bit (2 bytes) EOF */ + return (frame_bytelen*18) + 2 + 2; + + /* this results in a maximum samples-per-frame size of 4612 bytes + * for a 256byte frame */ +} + +struct manch_enc_state { + const char *data; + char *samples; + u_int16_t *samples16; +}; + +static void manchester_enc_byte(struct manch_enc_state *mencs, u_int8_t data) +{ + int i; + u_int8_t sum_1 = 0; + + /* append 8 sample blobs, one for each bit */ + for (i = 0; i < 8; i++) { + if (data & (1 << i)) { + *(mencs->samples16) = MANCHESTER_SEQ_D; + sum_1++; + } else { + *(mencs->samples16) = MANCHESTER_SEQ_E; + } + mencs->samples16++ + } + /* append odd parity */ + if (sum_1 & 0x01) + *(mencs->samples16) = MANCHESTER_SEQ_E; + else + *(mencs->samples16) = MANCHESTER_SEQ_D; + mencs->samples16++ +} + +int manchester_encode(char *sample_buf, u_int16_t sample_buf_len, + const char *data, u_int8_t data_len) +{ + int i, enc_size; + struct manch_enc_state mencs + + enc_size = manchester_sample_size(data_len); + + if (sample_buf_len < enc_size) + return -EINVAL; + + /* SOF */ + *(mencs.samples16++) = MANCHESTER_SEQ_D; + + for (i = 0; i < data_len; i++) + manchester_enc_byte(mencs, data[i]); + + /* EOF */ + *(mencs.samples16++) = MANCHESTER_SEQ_F; + + return enc_size; +} + +#define BPSK_SPEED_212 + + +static u_int32_t bpsk_sample_size(u_int8_t frame_bytelen) + +int bpsk_encode(char *sample_buf, u_int16_t sample_buf_len, + const char *data, u_int8_t data_len) +{ + /* burst of 32 sub carrier cycles */ + memset(sample_buf, 0x55, 8); + +} |