UI--checksum checking functions. Updated to set UI to previous UI on error.

Fork of UI by Bradley Perry

UserInterface.cpp

Committer:
mzling
Date:
2015-02-26
Revision:
4:48d23d12b3a3
Parent:
3:19c08e8a552a
Child:
5:f8d7d4505bad

File content as of revision 4:48d23d12b3a3:

#include "mbed.h"
#include "MODSERIAL.h"
#include "initDatabed.h"
#include "UserInterface.h"

// UI button variables
//int buttonA = 1; // state of remote button
//int buttonA_prev = 1;

// push hold vars
//float tHold = .6;  // hold time for sit/stand
//float tIdle = 2; // time out to confirm sit or stance (s)
//int SSconfirm = 0; // sit/stand variable for confirmation process
//float tRelease = .3; // time since last transmission to determine button release


// various timers
//Timer time_StateChange;
//Timer time_pressA;
//Timer time_pressB;

//int buttonB = 1; // state of remote button
//int buttonB_prev = 1;
//char __xbeeBuffer[250];
//int _dataCnt=0;
int UI = 0;

//float _time_sinceA, _time_sinceB; //time since the button was first pressed

UserInterface::UserInterface(void): _buttonA(1), _buttonA_prev(1), _tHold(.6), _tIdle(2), _SSconfirm(0), _tRelease(.3), _buttonB(1), _buttonB_prev(1), _dataCnt(0)
{
}

void UserInterface::readBuffer()
{
    while (xbeeUI.readable() && _dataCnt<250) {
        _xbeeBuffer[_dataCnt] = xbeeUI.getc();
        _dataCnt++;
    }
}

/**
* This function returns an array of information about the received characters. count[0] is # of data bytes, count[1] is expected length of the message, given the data length bytes and presence
* of escape characters. count[2] is position of the first data byte.
* @param idx    char array containing received data, beginning with the start byte 0x7e
* @param count    array that will contain the returned values
* @author Michael Ling
* @date 2/2/2015
*/
void UserInterface::find_length(char *idx, int *count)
{
    int pos = 0;
    short length;
    //This segment reads the length bytes (bytes 2-3 of the message)
    if (*(idx+1) == 0x7d) {
        length = (*(idx+2) ^ 0x20) << 8;
        pos = 3;
    } else {
        length = *(idx+1) << 8;
        pos = 2;
    }
    if (*(idx+pos) == 0x7d) {
        length = length | (*(idx+pos+1)^0x20);
        pos += 2;
    } else {
        length = length | *(idx+pos);
        pos += 1;
    }
    count[0] = (int)length;
    //Length incremented by 1--we treat the checksum as a data byte, since it can also be escaped
    length += 1;
    //Checks for escape characters--for every escape char found, the data section gets 1 byte longer
    for (short i = 0; i < length; i += 1) {
        if (*(idx+i) == 0x7d) {
            length += 1;
        }
    }
    pc.printf("Length: %d\r\n", length);
    count[1] = (int) length + 3;
    count[2] = pos;
}

/**
* This function returns true if calculated checksum matches the checksum at the end of the message.
* @param idx    char array containing received data, starting with start byte 0x7e
* @param length    number of data bytes in the message
* @author Michael Ling
* @date 2/2/2015
*/
bool UserInterface::checksum_check(char *idx, int length)
{
    int pos = 0;
    int sum = 0;
    for(int i = 0; i < length; i++) {
        //In case of an escape character, the true value of the byte is the following byte XOR with 0x20
        if (*(idx+pos) == 0x7d) {
            sum += (*(idx+pos+1) ^ 0x20);
            pos += 2;
        } else {
            sum += *(idx+pos);
            pos += 1;
        }
    }
    //XBEE checksum: sum all data bytes, truncate the sum to the rightmost 8 bytes, and subtract that from 0xff
    sum = sum & 0x0ff;
    char calcsum = (char)(0xff - sum);
    char checksum;
    if (*(idx+pos) == 0x7d) {
        checksum = *(idx+pos)^0x20;
    } else {
        checksum = *(idx+pos);
    }
    if (checksum != calcsum) {
        return false;
    }
    return true;
}

void UserInterface::checkUI_XBee()
{
    //int sum = 0;
    _buttonA_prev = _buttonA;
    _buttonB_prev = _buttonB;
    char * idx = strchr(_xbeeBuffer,0x7e);
    if (idx != NULL) {
        
        int size[3];
        find_length(idx, size);
        printf("Size: %d, Datacount: %d\r\n", size[1], _dataCnt);
        _buttonA = (_xbeeBuffer[idx-_xbeeBuffer+21]>>1) & 1;  // on DIO1
        _buttonB = (_xbeeBuffer[idx-_xbeeBuffer+21]>>2) & 1;  // on DIO2
        if(_dataCnt >= size[1]) {

            if (checksum_check(idx+size[2], size[0])) {
                printf("Checksums match\r\n");
            } else {
                printf("Checksums don't match\r\n");
                UI = _prev_UI;
                return;
            }
            _dataCnt = 0;
        } else {
            //UI = _prev_UI;
            return;
        }
       
        if (_buttonA == 0 && _buttonA_prev == 1) {//buton was just pressed
            _time_pressA.reset();
            _time_pressA.start();
            _time_sinceA = 0;
        }

        else if(_buttonA == 0) {
            printf("!\r\n");
            _time_sinceA = _time_pressA; //button is still pressed
        }

        if (_buttonB == 0 && _buttonB_prev == 1) {//button was just pressed
            _time_pressB.reset();
            _time_pressB.start();
            _time_sinceB = 0;
        } else if(_buttonB == 0) {
            _time_sinceB = _time_pressB; //button is still pressed
        }
    }

    if((_time_pressA-_time_sinceA) >= _tRelease) { //button was released
        if(_time_pressA-_tRelease >= _tHold) { //if the button was held before released
            UI = 3; //UI command is a held A button
        } else {
            UI = 1; //UI command is a pressed A button
        }
        _buttonA = 1; //button A is released
        _time_pressA.stop(); //reset the button A timer
        _time_pressA.reset();
    }
    if(_time_pressB-_time_sinceB >= _tRelease) { //button was released
        if(_time_pressB-_tRelease >= _tHold) { //if the button was held before released
            UI = 4; //UI command is a held B button
        } else {
            UI = 2; //UI command is a pressed B button
        }
        _buttonB = 1; //button B is released
        _time_pressB.stop(); //reset the button B timer
        _time_pressB.reset();
    }

    memset(_xbeeBuffer,0xFF,250);
    _dataCnt = 0;
    _prev_UI = UI;
}

void UserInterface::initializeUI()
{
    xbeeUI.baud(115200);
    mainPower = 0;

}