Classe de gestion du HTRC110
RFIDer.cpp
- Committer:
- gr66
- Date:
- 2017-12-04
- Revision:
- 1:02db8b7c40fb
- Parent:
- 0:ec877e8509d0
File content as of revision 1:02db8b7c40fb:
#include "mbed.h" #include "RFIDer.h" RFIDer::RFIDer(PinName clk, PinName mosi, PinName miso) : clk(DigitalOut(clk)), mosi(DigitalOut(mosi)), miso(DigitalIn(miso)), data(InterruptIn(miso)) { Tserial = 40; Tdata = 250; lastBit = 2; tagAvailable = 0; } void RFIDer::setSamplingTime(char ts) { sendCmd((0b10 << 6) | (ts & 0b00111111)); // no response } char RFIDer::getSamplingTime() { return sendCmd(0b00000010); // reponse : 0 0 D5-D0 } void RFIDer::setComPeriod(short half_period) { Tserial = half_period; } short RFIDer::getComPeriod() { return Tserial; } void RFIDer::setConfigPage(char mode, char data) { /* Format : 0 1 P1 P0 D3 D2 D1 D0 * P1,P0 - D3,D2,D1,D0 * 0,0 - GAIN1,GAIN0,FILTERH,FILTERL * 0,1 - PD_MODE,PD_HYSTERESIS,TXDIS * 1,0 - THRESET,ACQAMP,FREEZ1,FREEZ0 * 1,1 - DIPSL1,DISSMARTCOMP,FSEL1,FSEL0 */ switch(mode) { case 0 : sendCmd((0b0100 << 4) | (0b00001111 & data)); // no response break; case 1 : sendCmd((0b0101 << 4) | (0b00001111 & data)); // no response break; case 2 : sendCmd((0b0110 << 4) | (0b00001111 & data)); // no response break; case 3 : sendCmd((0b0111 << 4) | (0b00001111 & data)); // no response printf("Config sent : %X\r\n", (0b0111 << 4) | (0b00001111 & data)); break; } } char RFIDer::getConfigPage(char mode) { char response; switch(mode) { case 0 : response = sendCmd(0b00000100); // no response break; case 1 : response = sendCmd(0b00000101); // no response break; case 2 : response = sendCmd(0b00000110); // no response break; case 3 : response = sendCmd(0b00000111); // no response break; } return response; } void RFIDer::setClockFrequency(int frequency) { // Get value char data = getConfigPage(3); printf("Get initial config : %X\r\n", data); switch(frequency) { case 4000000: //4Mhz => FSEL = 00 setConfigPage(3, ((data & 0b1100) | 0b00) & 0b00001111); break; case 8000000: //8Mhz => FSEL = 01 setConfigPage(3, ((data & 0b1100) | 0b01) & 0b00001111); break; case 12000000: //12Mhz => FSEL = 10 setConfigPage(3, ((data & 0b1100) | 0b10) & 0b00001111); break; case 16000000: //16Mhz => FSEL = 11 setConfigPage(3, ((data & 0b1100) | 0b11) & 0b00001111); break; default: // default 8Mhz setConfigPage(3, ((data & 0b1100) | 0b00) & 0b00001111); break; } } int RFIDer::getClockFrequency() { char page = getConfigPage(3); switch(page & 0b00000011) { case 0 : return 4000000; case 1 : return 8000000; case 2 : return 12000000; case 3 : return 16000000; default : return 0; } } int RFIDer::getAntennaStatus() { char page = getConfigPage(3); return ((page & 0b00010000) >> 4); } char RFIDer::readPhase() { return sendCmd(0b00001000); // response : 0 0 D5-D0 } char RFIDer::sendCmd(char cmd) { int i; bool b; char response = 0; // initialisation clk = 1; //CLK High wait_us(Tserial); mosi = 0; wait_us(Tserial); mosi = 1; wait_us(Tserial); //8 clock periods to send the commands for (i=7; i>=0; i--) { // Falling edge clk = 0; b = (cmd & ( 1 << i )) >> i; mosi = b; wait_us(Tserial); // Rising edge clk = 1; wait_us(Tserial); } // 8 clocks period for data for (i=7; i>=0; i--) { // Falling edge clk = 0; wait_us(Tserial); clk = 1; //Rising edge b = miso; response = response | (b << i); wait_us(Tserial); } clk = 0; mosi = 1; return response; } void RFIDer::startReadingTag() { int i; // initialisation clk = 1; //CLK High wait_us(Tserial); mosi = 0; wait_us(Tserial); mosi = 1; wait_us(Tserial); //8 clock periods to send the commands for (i=2; i>=0; i--) { // Falling edge clk = 0; mosi = 1; wait_us(Tserial); // Rising edge clk = 1; wait_us(Tserial); } clk = 0; mosi = 0; // Preparing for decoding timer.reset(); tagAvailable = 0; // Attach interrupt for tag reading data.rise(this, &RFIDer::ISR_tag_reading); data.fall(this, &RFIDer::ISR_tag_reading); data.enable_irq(); // gr } void RFIDer::stopReadingTag() { // Disable isr data.disable_irq(); clk = 0; //CLK low wait_us(Tserial); clk = 1; //CLK high } void RFIDer::ISR_tag_reading() { // Timer management timer.stop(); int delay = timer.read_us(); // Save delay between the last 2 rises timer.reset(); timer.start(); static char counter = 0; // '1' header counter static char bit_i = 0; // bit Array index static TagReaderState tagReaderState = IDLE; // Decoding bit char bit = decodeBit(delay); if(bit == -1) { // Not synchronized or an error occurred tagReaderState = IDLE; // Reset the tag reader counter = 0; bit_i = 0; return; } else if(bit == 2) // Single short edge detected : bit value is unknown return; // Nothing to do : wait for the next edge // FSM : TAG READER switch(tagReaderState) { /* * Looking for the nine 1 header */ case IDLE : if(bit == 1) { // If '1' is read counter++; } else { // If '0' is read counter = 0; // Start again } if(counter == 9) { // If 9 following '1' are read counter = 0; bit_i = 0; tagReaderState = READING; } break; /* * Header has been found : Reading stream */ case READING: array[bit_i] = bit; bit_i++; if(bit_i > 54) { // A complete transponder memory has been read timer.stop(); // Stop timer timer.reset(); // Reset timer data.disable_irq(); // Disable interrupts // Check data integrity (row even parity, column even parity and stop bit) if(checkDataIntegrity()) { // Data is ok decodeTag(); // Read tag tagAvailable = 1; // Set flag tagReaderState = DONE; // Change FSM state } else { // Corrupted data : start again ! tagReaderState = IDLE; } data.enable_irq(); // Reactivating interrupts } break; /* * A tag reading has been done : immediately relaunching the FSM */ case DONE : counter = 0; bit_i = 0; // Reset array pointer data.enable_irq(); tagReaderState = IDLE; break; /* * Default case */ default : tagReaderState = IDLE; break; } } char RFIDer::decodeBit(int delay) { static DecoderState decoderState = SYNC; static char lastBit = 0; static char TdelayCounter = 0; char currentBit = -1; // Error default value switch(decoderState) { /* Synchronisation with the clock * The routine looks for a Tdatarate-delay between 2 edges */ case SYNC : if(delay > 0.75*2*Tdata && delay < 1.25*2*Tdata) { lastBit = miso; decoderState = READY; } break; /* Decoder is ready to decode stream */ case READY : if(delay > 0.70*Tdata && delay < 1.30*Tdata) { TdelayCounter++; if(TdelayCounter == 2) { // 2nd consecutive T-delay edge TdelayCounter = 0; currentBit = lastBit; } else currentBit = 2; // Undetermined value : waiting for a second edge } else if(delay > 0.70*2*Tdata && delay < 1.30*2*Tdata) { if(TdelayCounter == 1) { // Error TdelayCounter = 0; decoderState = SYNC; // Try to resynchronize } else { currentBit = !lastBit; lastBit = !lastBit; } } else { // Error (delay too small or too big) TdelayCounter = 0; decoderState = SYNC; // Try to resynchronize } break; default : // Error TdelayCounter = 0; decoderState = SYNC; // Try to resynchronize break; } return currentBit; } char RFIDer::checkDataIntegrity(void) { char sum = 0; // Check if last bit is not Stop bit if(array[54] != 0) { return 0; } // Even parity row check for (int row = 0 ; row <= 9 ; row++) { sum = 0; for (int i = 0; i <=4 ; i++) { //printf("%d",array[5*row+i]); if(i == 4) { // End of row if(sum%2 != array[5*row+i]) { //printf("Row parity error!\n\r"); return 0; } //else printf("\n\r"); } sum+=array[5*row+i]; } } // Even parity column check for (int col=0 ; col <= 3 ; col++) { sum = 0; for (int i = 0; i <=10 ; i++) { if(i == 10) { // End of column if(sum%2 != array[col+5*i]) { //printf("Col parity error!\n\r"); return 0; } } sum+=array[col+5*i]; } } return 1; } void RFIDer::decodeTag(void) { /* Init tag */ for(char i = 0 ; i < 10 ; i++) { tag[i] = 0; // init } /* Get 10-hex half bytes id */ for (char row = 0 ; row < 10 ; row++) { for (char col = 0; col < 4 ; col++) { tag[row/2]+=array[5*row+col] << ((3-col) + 4*((row+1)%2)); } } } /* void RFIDer::decodeTag(void) { // Get 8-hex word id for (int row = 0 ; row <= 7 ; row++) { tag[row] = 0; // init for (int i = 0; i <=3 ; i++) { tag[row]+=array[5*(row+2)+i] << (3-i); } } } */ char* RFIDer::getTag(void) { tagAvailable = 0; // Reset flag return tag; } bool RFIDer::isTagAvailable(void) { return tagAvailable; }