X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/dc4300bafb4dd3917a230b27fa2d1efa9ef08dd0..f1b74c30899b5c1ce916f2a5c42d679e61aaa5ac:/armsrc/lfops.c?ds=inline diff --git a/armsrc/lfops.c b/armsrc/lfops.c index dc7ffd88..9f3d9ab3 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -321,7 +321,7 @@ void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc) { -FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); if(crc == 0) { crc = update_crc16(crc, (idlo)&0xff); crc = update_crc16(crc, (idlo>>8)&0xff); @@ -768,7 +768,7 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) // Configure to go in 125Khz listen mode LFSetupFPGAForADC(95, true); - while(!BUTTON_PRESS()) { + while(!BUTTON_PRESS() && !usb_poll_validate_length()) { WDT_HIT(); if (ledcontrol) LED_A_ON(); @@ -857,7 +857,7 @@ void CmdAWIDdemodFSK(int findone, int *high, int *low, int ledcontrol) // Configure to go in 125Khz listen mode LFSetupFPGAForADC(95, true); - while(!BUTTON_PRESS()) { + while(!BUTTON_PRESS() && !usb_poll_validate_length()) { WDT_HIT(); if (ledcontrol) LED_A_ON(); @@ -948,7 +948,7 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol) // Configure to go in 125Khz listen mode LFSetupFPGAForADC(95, true); - while(!BUTTON_PRESS()) { + while(!BUTTON_PRESS() && !usb_poll_validate_length()) { WDT_HIT(); if (ledcontrol) LED_A_ON(); @@ -1007,7 +1007,7 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) // Configure to go in 125Khz listen mode LFSetupFPGAForADC(95, true); - while(!BUTTON_PRESS()) { + while(!BUTTON_PRESS() && !usb_poll_validate_length()) { WDT_HIT(); if (ledcontrol) LED_A_ON(); DoAcquisition_default(-1,true); @@ -1085,6 +1085,7 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) #define T55x7_MODULATION_FSK2a 0x00007000 #define T55x7_MODULATION_MANCHESTER 0x00008000 #define T55x7_MODULATION_BIPHASE 0x00010000 +#define T55x7_MODULATION_DIPHASE 0x00018000 #define T55x7_BITRATE_RF_8 0 #define T55x7_BITRATE_RF_16 0x00040000 #define T55x7_BITRATE_RF_32 0x00080000 @@ -1119,21 +1120,38 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) * Relevant times in microsecond * To compensate antenna falling times shorten the write times * and enlarge the gap ones. + * Q5 tags seems to have issues when these values changes. */ #define START_GAP 31*8 // was 250 // SPEC: 1*8 to 50*8 - typ 15*8 (or 15fc) #define WRITE_GAP 20*8 // was 160 // SPEC: 1*8 to 20*8 - typ 10*8 (or 10fc) #define WRITE_0 18*8 // was 144 // SPEC: 16*8 to 32*8 - typ 24*8 (or 24fc) #define WRITE_1 50*8 // was 400 // SPEC: 48*8 to 64*8 - typ 56*8 (or 56fc) 432 for T55x7; 448 for E5550 +#define READ_GAP 52*8 + +// VALUES TAKEN FROM EM4x function: SendForward +// START_GAP = 440; (55*8) cycles at 125Khz (8us = 1cycle) +// WRITE_GAP = 128; (16*8) +// WRITE_1 = 256 32*8; (32*8) + +// These timings work for 4469/4269/4305 (with the 55*8 above) +// WRITE_0 = 23*8 , 9*8 SpinDelayUs(23*8); -#define T55xx_SAMPLES_SIZE 12000 // 32 x 32 x 10 (32 bit times numofblock (7), times clock skip..) +// Sam7s has several timers, we will use the source TIMER_CLOCK1 (aka AT91C_TC_CLKS_TIMER_DIV1_CLOCK) +// TIMER_CLOCK1 = MCK/2, MCK is running at 48 MHz, Timer is running at 48/2 = 24 MHz +// Hitag units (T0) have duration of 8 microseconds (us), which is 1/125000 per second (carrier) +// T0 = TIMER_CLOCK1 / 125000 = 192 +// 1 Cycle = 8 microseconds(us) == 1 field clock + +void TurnReadLFOn(int delay) { + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + // Give it a bit of time for the resonant antenna to settle. + SpinDelayUs(delay); //155*8 //50*8 +} // Write one bit to card -void T55xxWriteBit(int bit) -{ - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz +void T55xxWriteBit(int bit) { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - if (bit == 0) + if (!bit) SpinDelayUs(WRITE_0); else SpinDelayUs(WRITE_1); @@ -1142,147 +1160,135 @@ void T55xxWriteBit(int bit) } // Write one card block in page 0, no lock -void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode) -{ +void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode) { + LED_A_ON(); + uint32_t i = 0; // Set up FPGA, 125kHz - // Wait for config.. (192+8190xPOW)x8 == 67ms - LFSetupFPGAForADC(0, true); + LFSetupFPGAForADC(95, true); - // Now start writting + // Trigger T55x7 in mode. FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); SpinDelayUs(START_GAP); - // Opcode + // Opcode 10 T55xxWriteBit(1); T55xxWriteBit(0); //Page 0 if (PwdMode == 1){ - // Pwd + // Send Pwd for (i = 0x80000000; i != 0; i >>= 1) T55xxWriteBit(Pwd & i); } - // Lock bit + // Send Lock bit T55xxWriteBit(0); - // Data + // Send Data for (i = 0x80000000; i != 0; i >>= 1) T55xxWriteBit(Data & i); - // Block + // Send Block number for (i = 0x04; i != 0; i >>= 1) T55xxWriteBit(Block & i); - // Now perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550, + // Perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550, // so wait a little more) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - SpinDelay(20); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); -} + TurnReadLFOn(20 * 1000); -void TurnReadLFOn(){ - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // Give it a bit of time for the resonant antenna to settle. - SpinDelayUs(8*150); + // turn field off + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + cmd_send(CMD_ACK,0,0,0,0,0); + LED_A_OFF(); } - // Read one card block in page 0 -void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode) -{ +void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode) { + LED_A_ON(); + uint32_t i = 0; - uint8_t *dest = BigBuf_get_addr(); - uint16_t bufferlength = BigBuf_max_traceLen(); - if ( bufferlength > T55xx_SAMPLES_SIZE ) - bufferlength = T55xx_SAMPLES_SIZE; - // Clear destination buffer before sending the command - memset(dest, 0x80, bufferlength); + //clear buffer now so it does not interfere with timing later + BigBuf_Clear_ext(false); + + //make sure block is at max 7 + Block &= 0x7; // Set up FPGA, 125kHz - // Wait for config.. (192+8190xPOW)x8 == 67ms - LFSetupFPGAForADC(0, true); + LFSetupFPGAForADC(95, true); + /* + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + + // Connect the A/D to the peak-detected low-frequency path. + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); + + // Give it a bit of time for the resonant antenna to settle. + //SpinDelayUs(8*200); //192FC + SpinDelay(50); + */ + + // Trigger T55x7 Direct Access Mode FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); SpinDelayUs(START_GAP); - // Opcode + // Opcode 10 T55xxWriteBit(1); T55xxWriteBit(0); //Page 0 + if (PwdMode == 1){ - // Pwd + // Send Pwd for (i = 0x80000000; i != 0; i >>= 1) T55xxWriteBit(Pwd & i); } - // Lock bit + // Send a zero bit separation T55xxWriteBit(0); - // Block + + // Send Block number for (i = 0x04; i != 0; i >>= 1) T55xxWriteBit(Block & i); // Turn field on to read the response - TurnReadLFOn(); - // Now do the acquisition - i = 0; - for(;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - LED_D_ON(); - } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - i++; - LED_D_OFF(); - if (i >= bufferlength) break; - } - } + TurnReadLFOn(READ_GAP); - cmd_send(CMD_ACK,0,0,0,0,0); + // Acquisition + doT55x7Acquisition(); + + // Turn the field off FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); + cmd_send(CMD_ACK,0,0,0,0,0); + LED_A_OFF(); } // Read card traceability data (page 1) void T55xxReadTrace(void){ - - uint32_t i = 0; - uint8_t *dest = BigBuf_get_addr(); - uint16_t bufferlength = BigBuf_max_traceLen(); - if ( bufferlength > T55xx_SAMPLES_SIZE ) - bufferlength= T55xx_SAMPLES_SIZE; + LED_A_ON(); - // Clear destination buffer before sending the command - memset(dest, 0x80, bufferlength); + //clear buffer now so it does not interfere with timing later + BigBuf_Clear_ext(false); - LFSetupFPGAForADC(0, true); + // Set up FPGA, 125kHz + LFSetupFPGAForADC(95, true); + + // Trigger T55x7 Direct Access Mode FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); SpinDelayUs(START_GAP); - // Opcode + // Opcode 11 T55xxWriteBit(1); T55xxWriteBit(1); //Page 1 // Turn field on to read the response - TurnReadLFOn(); + TurnReadLFOn(READ_GAP); - // Now do the acquisition - for(;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - LED_D_ON(); - } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - i++; - LED_D_OFF(); - - if (i >= bufferlength) break; - } - } + // Acquisition + doT55x7Acquisition(); + // Turn the field off + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); cmd_send(CMD_ACK,0,0,0,0,0); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); + LED_A_OFF(); } /*-------------- Cloning routines -----------*/ @@ -1501,8 +1507,11 @@ void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo) // Clock rate is stored in bits 8-15 of the card value clock = (card & 0xFF00) >> 8; Dbprintf("Clock rate: %d", clock); - switch (clock) - { + switch (clock) { + case 50: + clock = T55x7_BITRATE_RF_50; + case 40: + clock = T55x7_BITRATE_RF_40; case 32: clock = T55x7_BITRATE_RF_32; break; @@ -1582,280 +1591,6 @@ void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int } - -#define abs(x) ( ((x)<0) ? -(x) : (x) ) -#define max(x,y) ( x GraphBuffer[0]) { - while(i < GraphTraceLen) { - if( !(GraphBuffer[i] > GraphBuffer[i-1]) && GraphBuffer[i] > lmax) - break; - i++; - } - dir = 0; - } - else { - while(i < GraphTraceLen) { - if( !(GraphBuffer[i] < GraphBuffer[i-1]) && GraphBuffer[i] < lmin) - break; - i++; - } - dir = 1; - } - - lastval = i++; - half_switch = 0; - pmc = 0; - block_done = 0; - - for (bitidx = 0; i < GraphTraceLen; i++) - { - if ( (GraphBuffer[i-1] > GraphBuffer[i] && dir == 1 && GraphBuffer[i] > lmax) || (GraphBuffer[i-1] < GraphBuffer[i] && dir == 0 && GraphBuffer[i] < lmin)) - { - lc = i - lastval; - lastval = i; - - // Switch depending on lc length: - // Tolerance is 1/8 of clock rate (arbitrary) - if (abs(lc-clock/4) < tolerance) { - // 16T0 - if((i - pmc) == lc) { /* 16T0 was previous one */ - /* It's a PMC ! */ - i += (128+127+16+32+33+16)-1; - lastval = i; - pmc = 0; - block_done = 1; - } - else { - pmc = i; - } - } else if (abs(lc-clock/2) < tolerance) { - // 32TO - if((i - pmc) == lc) { /* 16T0 was previous one */ - /* It's a PMC ! */ - i += (128+127+16+32+33)-1; - lastval = i; - pmc = 0; - block_done = 1; - } - else if(half_switch == 1) { - BitStream[bitidx++] = 0; - half_switch = 0; - } - else - half_switch++; - } else if (abs(lc-clock) < tolerance) { - // 64TO - BitStream[bitidx++] = 1; - } else { - // Error - warnings++; - if (warnings > 10) - { - Dbprintf("Error: too many detection errors, aborting."); - return 0; - } - } - - if(block_done == 1) { - if(bitidx == 128) { - for(j=0; j<16; j++) { - Blocks[num_blocks][j] = 128*BitStream[j*8+7]+ - 64*BitStream[j*8+6]+ - 32*BitStream[j*8+5]+ - 16*BitStream[j*8+4]+ - 8*BitStream[j*8+3]+ - 4*BitStream[j*8+2]+ - 2*BitStream[j*8+1]+ - BitStream[j*8]; - } - num_blocks++; - } - bitidx = 0; - block_done = 0; - half_switch = 0; - } - if(i < GraphTraceLen) - { - if (GraphBuffer[i-1] > GraphBuffer[i]) dir=0; - else dir = 1; - } - } - if(bitidx==255) - bitidx=0; - warnings = 0; - if(num_blocks == 4) break; - } - memcpy(outBlocks, Blocks, 16*num_blocks); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - - return num_blocks; -} - -int IsBlock0PCF7931(uint8_t *Block) { - // Assume RFU means 0 :) - if((memcmp(Block, "\x00\x00\x00\x00\x00\x00\x00\x01", 8) == 0) && memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) // PAC enabled - return 1; - if((memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) && Block[7] == 0) // PAC disabled, can it *really* happen ? - return 1; - return 0; -} - -int IsBlock1PCF7931(uint8_t *Block) { - // Assume RFU means 0 :) - if(Block[10] == 0 && Block[11] == 0 && Block[12] == 0 && Block[13] == 0) - if((Block[14] & 0x7f) <= 9 && Block[15] <= 9) - return 1; - - return 0; -} - -#define ALLOC 16 - -void ReadPCF7931() { - uint8_t Blocks[8][17]; - uint8_t tmpBlocks[4][16]; - int i, j, ind, ind2, n; - int num_blocks = 0; - int max_blocks = 8; - int ident = 0; - int error = 0; - int tries = 0; - - memset(Blocks, 0, 8*17*sizeof(uint8_t)); - - do { - memset(tmpBlocks, 0, 4*16*sizeof(uint8_t)); - n = DemodPCF7931((uint8_t**)tmpBlocks); - if(!n) - error++; - if(error==10 && num_blocks == 0) { - Dbprintf("Error, no tag or bad tag"); - return; - } - else if (tries==20 || error==10) { - Dbprintf("Error reading the tag"); - Dbprintf("Here is the partial content"); - goto end; - } - - for(i=0; i= 0; ind--,ind2--) { - if(ind2 < 0) - ind2 = max_blocks; - if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found - // Dbprintf("Tmp %d -> Block %d", ind, ind2); - memcpy(Blocks[ind2], tmpBlocks[ind], 16); - Blocks[ind2][ALLOC] = 1; - num_blocks++; - if(num_blocks == max_blocks) goto end; - } - } - for(ind=i+1,ind2=j+1; ind < n; ind++,ind2++) { - if(ind2 > max_blocks) - ind2 = 0; - if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found - // Dbprintf("Tmp %d -> Block %d", ind, ind2); - memcpy(Blocks[ind2], tmpBlocks[ind], 16); - Blocks[ind2][ALLOC] = 1; - num_blocks++; - if(num_blocks == max_blocks) goto end; - } - } - } - } - } - } - } - tries++; - if (BUTTON_PRESS()) return; - } while (num_blocks != max_blocks); - end: - Dbprintf("-----------------------------------------"); - Dbprintf("Memory content:"); - Dbprintf("-----------------------------------------"); - for(i=0; i", i); - } - Dbprintf("-----------------------------------------"); - - - return ; -} - - //----------------------------------- // EM4469 / EM4305 routines //----------------------------------- @@ -1967,14 +1702,8 @@ void SendForward(uint8_t fwd_bit_count) { LED_D_ON(); - //Field on - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - - // Give it a bit of time for the resonant antenna to settle. - // And for the tag to fully power up - SpinDelay(150); + // Set up FPGA, 125kHz + LFSetupFPGAForADC(95, true); // force 1st mod pulse (start gap must be longer for 4305) fwd_bit_sz--; //prepare next bit modulation @@ -2019,7 +1748,11 @@ void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) { uint8_t fwd_bit_count; uint8_t *dest = BigBuf_get_addr(); - int m=0, i=0; + uint16_t bufferlength = BigBuf_max_traceLen(); + uint32_t i = 0; + + // Clear destination buffer before sending the command + memset(dest, 0x80, bufferlength); //If password mode do login if (PwdMode == 1) EM4xLogin(Pwd); @@ -2028,9 +1761,6 @@ void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) { fwd_bit_count = Prepare_Cmd( FWD_CMD_READ ); fwd_bit_count += Prepare_Addr( Address ); - m = BigBuf_max_traceLen(); - // Clear destination buffer before sending the command - memset(dest, 128, m); // Connect the A/D to the peak-detected low-frequency path. SetAdcMuxFor(GPIO_MUXSEL_LOPKD); // Now set up the SSC to get the ADC samples that are now streaming at us. @@ -2047,10 +1777,11 @@ void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) { if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; i++; - if (i >= m) break; + if (i >= bufferlength) break; } } FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + cmd_send(CMD_ACK,0,0,0,0,0); LED_D_OFF(); } @@ -2073,261 +1804,3 @@ void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off LED_D_OFF(); } - - -#define T0_PCF 8 //period for the pcf7931 in us - -/* Write on a byte of a PCF7931 tag - * @param address : address of the block to write - @param byte : address of the byte to write - @param data : data to write - */ -void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data) -{ - - uint32_t tab[1024]={0}; // data times frame - uint32_t u = 0; - uint8_t parity = 0; - bool comp = 0; - - - //BUILD OF THE DATA FRAME - - //alimentation of the tag (time for initializing) - AddPatternPCF7931(init_delay, 0, 8192/2*T0_PCF, tab); - - //PMC - Dbprintf("Initialization delay : %d us", init_delay); - AddPatternPCF7931(8192/2*T0_PCF + 319*T0_PCF+70, 3*T0_PCF, 29*T0_PCF, tab); - - Dbprintf("Offsets : %d us on the low pulses width, %d us on the low pulses positions", l, p); - - //password indication bit - AddBitPCF7931(1, tab, l, p); - - - //password (on 56 bits) - Dbprintf("Password (LSB first on each byte) : %02x %02x %02x %02x %02x %02x %02x", pass1,pass2,pass3,pass4,pass5,pass6,pass7); - AddBytePCF7931(pass1, tab, l, p); - AddBytePCF7931(pass2, tab, l, p); - AddBytePCF7931(pass3, tab, l, p); - AddBytePCF7931(pass4, tab, l, p); - AddBytePCF7931(pass5, tab, l, p); - AddBytePCF7931(pass6, tab, l, p); - AddBytePCF7931(pass7, tab, l, p); - - - //programming mode (0 or 1) - AddBitPCF7931(0, tab, l, p); - - //block adress on 6 bits - Dbprintf("Block address : %02x", address); - for (u=0; u<6; u++) - { - if (address&(1< 0xFFFF){ - tab[u] -= 0xFFFF; - comp = 0; - } - } - } - - SendCmdPCF7931(tab); -} - - - -/* Send a trame to a PCF7931 tags - * @param tab : array of the data frame - */ - -void SendCmdPCF7931(uint32_t * tab){ - uint16_t u=0; - uint16_t tempo=0; - - Dbprintf("SENDING DATA FRAME..."); - - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU ); - - LED_A_ON(); - - // steal this pin from the SSP and use it to control the modulation - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - - //initialization of the timer - AT91C_BASE_PMC->PMC_PCER |= (0x1 << 12) | (0x1 << 13) | (0x1 << 14); - AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE; - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable - AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK; //clock at 48/32 MHz - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN; - AT91C_BASE_TCB->TCB_BCR = 1; - - - tempo = AT91C_BASE_TC0->TC_CV; - for(u=0;tab[u]!= 0;u+=3){ - - - // modulate antenna - HIGH(GPIO_SSC_DOUT); - while(tempo != tab[u]){ - tempo = AT91C_BASE_TC0->TC_CV; - } - - // stop modulating antenna - LOW(GPIO_SSC_DOUT); - while(tempo != tab[u+1]){ - tempo = AT91C_BASE_TC0->TC_CV; - } - - - // modulate antenna - HIGH(GPIO_SSC_DOUT); - while(tempo != tab[u+2]){ - tempo = AT91C_BASE_TC0->TC_CV; - } - - - } - - LED_A_OFF(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelay(200); - - - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable - DbpString("FINISH !"); - DbpString("(Could be usefull to send the same trame many times)"); - LED(0xFFFF, 1000); -} - - -/* Add a byte for building the data frame of PCF7931 tags - * @param b : byte to add - * @param tab : array of the data frame - * @param l : offset on low pulse width - * @param p : offset on low pulse positioning - */ - -bool AddBytePCF7931(uint8_t byte, uint32_t * tab, int32_t l, int32_t p){ - - uint32_t u; - for (u=0; u<8; u++) - { - if (byte&(1<