Classe de gestion du HTRC110

Dependents:   RFID_test

Revision:
0:ec877e8509d0
Child:
1:02db8b7c40fb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RFIDer.cpp	Tue May 02 13:45:17 2017 +0000
@@ -0,0 +1,386 @@
+#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;
+}
\ No newline at end of file