Classe de gestion du HTRC110
RFIDer.cpp
- Committer:
- garivetm
- Date:
- 2017-05-02
- Revision:
- 0:ec877e8509d0
- Child:
- 1:02db8b7c40fb
File content as of revision 0:ec877e8509d0:
#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); } 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){ // 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; }