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

Fork of UI by Bradley Perry

Committer:
mzling
Date:
Mon May 11 21:48:03 2015 +0000
Revision:
6:e9e132f21f1b
Parent:
5:f8d7d4505bad
Comments

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mzling 0:6b5a3a0138ad 1 #include "mbed.h"
mzling 0:6b5a3a0138ad 2 #include "MODSERIAL.h"
mzling 0:6b5a3a0138ad 3 #include "initDatabed.h"
mzling 0:6b5a3a0138ad 4 #include "UserInterface.h"
mzling 0:6b5a3a0138ad 5
mzling 0:6b5a3a0138ad 6 // UI button variables
mzling 0:6b5a3a0138ad 7 //int buttonA = 1; // state of remote button
mzling 0:6b5a3a0138ad 8 //int buttonA_prev = 1;
mzling 0:6b5a3a0138ad 9
mzling 0:6b5a3a0138ad 10 // push hold vars
mzling 0:6b5a3a0138ad 11 //float tHold = .6; // hold time for sit/stand
mzling 0:6b5a3a0138ad 12 //float tIdle = 2; // time out to confirm sit or stance (s)
mzling 0:6b5a3a0138ad 13 //int SSconfirm = 0; // sit/stand variable for confirmation process
mzling 0:6b5a3a0138ad 14 //float tRelease = .3; // time since last transmission to determine button release
mzling 0:6b5a3a0138ad 15
mzling 0:6b5a3a0138ad 16
mzling 0:6b5a3a0138ad 17 // various timers
mzling 0:6b5a3a0138ad 18 //Timer time_StateChange;
mzling 0:6b5a3a0138ad 19 //Timer time_pressA;
mzling 0:6b5a3a0138ad 20 //Timer time_pressB;
mzling 0:6b5a3a0138ad 21
mzling 0:6b5a3a0138ad 22 //int buttonB = 1; // state of remote button
mzling 0:6b5a3a0138ad 23 //int buttonB_prev = 1;
mzling 0:6b5a3a0138ad 24 //char __xbeeBuffer[250];
mzling 0:6b5a3a0138ad 25 //int _dataCnt=0;
mzling 0:6b5a3a0138ad 26 int UI = 0;
mzling 0:6b5a3a0138ad 27
mzling 0:6b5a3a0138ad 28 //float _time_sinceA, _time_sinceB; //time since the button was first pressed
mzling 0:6b5a3a0138ad 29
perr1940 2:d6595294497c 30 UserInterface::UserInterface(void): _buttonA(1), _buttonA_prev(1), _tHold(.6), _tIdle(2), _SSconfirm(0), _tRelease(.3), _buttonB(1), _buttonB_prev(1), _dataCnt(0)
perr1940 2:d6595294497c 31 {
mzling 0:6b5a3a0138ad 32 }
mzling 0:6b5a3a0138ad 33
mzling 0:6b5a3a0138ad 34 void UserInterface::readBuffer()
mzling 0:6b5a3a0138ad 35 {
mzling 0:6b5a3a0138ad 36 while (xbeeUI.readable() && _dataCnt<250) {
mzling 0:6b5a3a0138ad 37 _xbeeBuffer[_dataCnt] = xbeeUI.getc();
mzling 0:6b5a3a0138ad 38 _dataCnt++;
mzling 0:6b5a3a0138ad 39 }
mzling 0:6b5a3a0138ad 40 }
mzling 0:6b5a3a0138ad 41
mzling 0:6b5a3a0138ad 42 /**
mzling 0:6b5a3a0138ad 43 * 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
mzling 0:6b5a3a0138ad 44 * of escape characters. count[2] is position of the first data byte.
mzling 0:6b5a3a0138ad 45 * @param idx char array containing received data, beginning with the start byte 0x7e
mzling 0:6b5a3a0138ad 46 * @param count array that will contain the returned values
mzling 0:6b5a3a0138ad 47 * @author Michael Ling
mzling 0:6b5a3a0138ad 48 * @date 2/2/2015
mzling 0:6b5a3a0138ad 49 */
mzling 0:6b5a3a0138ad 50 void UserInterface::find_length(char *idx, int *count)
mzling 0:6b5a3a0138ad 51 {
mzling 0:6b5a3a0138ad 52 int pos = 0;
mzling 0:6b5a3a0138ad 53 short length;
mzling 0:6b5a3a0138ad 54 //This segment reads the length bytes (bytes 2-3 of the message)
mzling 0:6b5a3a0138ad 55 if (*(idx+1) == 0x7d) {
mzling 0:6b5a3a0138ad 56 length = (*(idx+2) ^ 0x20) << 8;
mzling 0:6b5a3a0138ad 57 pos = 3;
mzling 0:6b5a3a0138ad 58 } else {
mzling 0:6b5a3a0138ad 59 length = *(idx+1) << 8;
mzling 0:6b5a3a0138ad 60 pos = 2;
mzling 0:6b5a3a0138ad 61 }
mzling 0:6b5a3a0138ad 62 if (*(idx+pos) == 0x7d) {
mzling 0:6b5a3a0138ad 63 length = length | (*(idx+pos+1)^0x20);
mzling 0:6b5a3a0138ad 64 pos += 2;
mzling 0:6b5a3a0138ad 65 } else {
mzling 0:6b5a3a0138ad 66 length = length | *(idx+pos);
mzling 0:6b5a3a0138ad 67 pos += 1;
mzling 0:6b5a3a0138ad 68 }
mzling 0:6b5a3a0138ad 69 count[0] = (int)length;
mzling 0:6b5a3a0138ad 70 //Length incremented by 1--we treat the checksum as a data byte, since it can also be escaped
mzling 0:6b5a3a0138ad 71 length += 1;
mzling 0:6b5a3a0138ad 72 //Checks for escape characters--for every escape char found, the data section gets 1 byte longer
mzling 0:6b5a3a0138ad 73 for (short i = 0; i < length; i += 1) {
mzling 0:6b5a3a0138ad 74 if (*(idx+i) == 0x7d) {
mzling 0:6b5a3a0138ad 75 length += 1;
mzling 0:6b5a3a0138ad 76 }
mzling 0:6b5a3a0138ad 77 }
mzling 4:48d23d12b3a3 78 pc.printf("Length: %d\r\n", length);
mzling 0:6b5a3a0138ad 79 count[1] = (int) length + 3;
mzling 0:6b5a3a0138ad 80 count[2] = pos;
mzling 0:6b5a3a0138ad 81 }
mzling 0:6b5a3a0138ad 82
mzling 0:6b5a3a0138ad 83 /**
mzling 0:6b5a3a0138ad 84 * This function returns true if calculated checksum matches the checksum at the end of the message.
mzling 0:6b5a3a0138ad 85 * @param idx char array containing received data, starting with start byte 0x7e
mzling 0:6b5a3a0138ad 86 * @param length number of data bytes in the message
mzling 0:6b5a3a0138ad 87 * @author Michael Ling
mzling 0:6b5a3a0138ad 88 * @date 2/2/2015
mzling 0:6b5a3a0138ad 89 */
mzling 0:6b5a3a0138ad 90 bool UserInterface::checksum_check(char *idx, int length)
mzling 0:6b5a3a0138ad 91 {
mzling 0:6b5a3a0138ad 92 int pos = 0;
mzling 0:6b5a3a0138ad 93 int sum = 0;
mzling 0:6b5a3a0138ad 94 for(int i = 0; i < length; i++) {
mzling 0:6b5a3a0138ad 95 //In case of an escape character, the true value of the byte is the following byte XOR with 0x20
mzling 0:6b5a3a0138ad 96 if (*(idx+pos) == 0x7d) {
mzling 0:6b5a3a0138ad 97 sum += (*(idx+pos+1) ^ 0x20);
mzling 0:6b5a3a0138ad 98 pos += 2;
mzling 0:6b5a3a0138ad 99 } else {
mzling 0:6b5a3a0138ad 100 sum += *(idx+pos);
mzling 0:6b5a3a0138ad 101 pos += 1;
mzling 0:6b5a3a0138ad 102 }
mzling 0:6b5a3a0138ad 103 }
mzling 0:6b5a3a0138ad 104 //XBEE checksum: sum all data bytes, truncate the sum to the rightmost 8 bytes, and subtract that from 0xff
mzling 0:6b5a3a0138ad 105 sum = sum & 0x0ff;
mzling 0:6b5a3a0138ad 106 char calcsum = (char)(0xff - sum);
mzling 0:6b5a3a0138ad 107 char checksum;
mzling 0:6b5a3a0138ad 108 if (*(idx+pos) == 0x7d) {
mzling 0:6b5a3a0138ad 109 checksum = *(idx+pos)^0x20;
mzling 0:6b5a3a0138ad 110 } else {
mzling 0:6b5a3a0138ad 111 checksum = *(idx+pos);
mzling 0:6b5a3a0138ad 112 }
mzling 0:6b5a3a0138ad 113 if (checksum != calcsum) {
mzling 0:6b5a3a0138ad 114 return false;
mzling 0:6b5a3a0138ad 115 }
perr1940 2:d6595294497c 116 return true;
mzling 0:6b5a3a0138ad 117 }
mzling 0:6b5a3a0138ad 118
mzling 6:e9e132f21f1b 119
mzling 6:e9e132f21f1b 120 /**
mzling 6:e9e132f21f1b 121 * This function pulls a crutch message from the XBee, and changes UI if the message is valid
mzling 6:e9e132f21f1b 122 * @author Michael Ling
mzling 6:e9e132f21f1b 123 * @date 5/11/2015
mzling 6:e9e132f21f1b 124 */
mzling 0:6b5a3a0138ad 125 void UserInterface::checkUI_XBee()
mzling 0:6b5a3a0138ad 126 {
mzling 3:19c08e8a552a 127 //int sum = 0;
mzling 0:6b5a3a0138ad 128 _buttonA_prev = _buttonA;
mzling 0:6b5a3a0138ad 129 _buttonB_prev = _buttonB;
mzling 6:e9e132f21f1b 130 //Find the start of a message in the xbee buffer
mzling 0:6b5a3a0138ad 131 char * idx = strchr(_xbeeBuffer,0x7e);
mzling 6:e9e132f21f1b 132
mzling 0:6b5a3a0138ad 133 if (idx != NULL) {
mzling 3:19c08e8a552a 134
mzling 0:6b5a3a0138ad 135 int size[3];
mzling 0:6b5a3a0138ad 136 find_length(idx, size);
mzling 1:7795fb7ee3f3 137 printf("Size: %d, Datacount: %d\r\n", size[1], _dataCnt);
mzling 3:19c08e8a552a 138 _buttonA = (_xbeeBuffer[idx-_xbeeBuffer+21]>>1) & 1; // on DIO1
mzling 3:19c08e8a552a 139 _buttonB = (_xbeeBuffer[idx-_xbeeBuffer+21]>>2) & 1; // on DIO2
mzling 6:e9e132f21f1b 140 //Proceed if the amount of data matches up with the calculated message length
mzling 0:6b5a3a0138ad 141 if(_dataCnt >= size[1]) {
mzling 6:e9e132f21f1b 142 //Compare calculated and actual checksums
mzling 0:6b5a3a0138ad 143 if (checksum_check(idx+size[2], size[0])) {
mzling 1:7795fb7ee3f3 144 printf("Checksums match\r\n");
mzling 0:6b5a3a0138ad 145 } else {
mzling 1:7795fb7ee3f3 146 printf("Checksums don't match\r\n");
mzling 3:19c08e8a552a 147 UI = _prev_UI;
mzling 3:19c08e8a552a 148 return;
mzling 0:6b5a3a0138ad 149 }
mzling 0:6b5a3a0138ad 150 _dataCnt = 0;
mzling 3:19c08e8a552a 151 } else {
mzling 4:48d23d12b3a3 152 //UI = _prev_UI;
mzling 5:f8d7d4505bad 153 // return;
mzling 0:6b5a3a0138ad 154 }
mzling 3:19c08e8a552a 155
perr1940 2:d6595294497c 156 if (_buttonA == 0 && _buttonA_prev == 1) {//buton was just pressed
perr1940 2:d6595294497c 157 _time_pressA.reset();
perr1940 2:d6595294497c 158 _time_pressA.start();
perr1940 2:d6595294497c 159 _time_sinceA = 0;
perr1940 2:d6595294497c 160 }
mzling 0:6b5a3a0138ad 161
perr1940 2:d6595294497c 162 else if(_buttonA == 0) {
perr1940 2:d6595294497c 163 printf("!\r\n");
perr1940 2:d6595294497c 164 _time_sinceA = _time_pressA; //button is still pressed
mzling 0:6b5a3a0138ad 165 }
mzling 0:6b5a3a0138ad 166
perr1940 2:d6595294497c 167 if (_buttonB == 0 && _buttonB_prev == 1) {//button was just pressed
mzling 0:6b5a3a0138ad 168 _time_pressB.reset();
perr1940 2:d6595294497c 169 _time_pressB.start();
perr1940 2:d6595294497c 170 _time_sinceB = 0;
perr1940 2:d6595294497c 171 } else if(_buttonB == 0) {
perr1940 2:d6595294497c 172 _time_sinceB = _time_pressB; //button is still pressed
mzling 0:6b5a3a0138ad 173 }
mzling 0:6b5a3a0138ad 174 }
perr1940 2:d6595294497c 175
perr1940 2:d6595294497c 176 if((_time_pressA-_time_sinceA) >= _tRelease) { //button was released
perr1940 2:d6595294497c 177 if(_time_pressA-_tRelease >= _tHold) { //if the button was held before released
perr1940 2:d6595294497c 178 UI = 3; //UI command is a held A button
perr1940 2:d6595294497c 179 } else {
perr1940 2:d6595294497c 180 UI = 1; //UI command is a pressed A button
perr1940 2:d6595294497c 181 }
perr1940 2:d6595294497c 182 _buttonA = 1; //button A is released
perr1940 2:d6595294497c 183 _time_pressA.stop(); //reset the button A timer
perr1940 2:d6595294497c 184 _time_pressA.reset();
perr1940 2:d6595294497c 185 }
perr1940 2:d6595294497c 186 if(_time_pressB-_time_sinceB >= _tRelease) { //button was released
perr1940 2:d6595294497c 187 if(_time_pressB-_tRelease >= _tHold) { //if the button was held before released
perr1940 2:d6595294497c 188 UI = 4; //UI command is a held B button
perr1940 2:d6595294497c 189 } else {
perr1940 2:d6595294497c 190 UI = 2; //UI command is a pressed B button
perr1940 2:d6595294497c 191 }
perr1940 2:d6595294497c 192 _buttonB = 1; //button B is released
perr1940 2:d6595294497c 193 _time_pressB.stop(); //reset the button B timer
perr1940 2:d6595294497c 194 _time_pressB.reset();
perr1940 2:d6595294497c 195 }
perr1940 2:d6595294497c 196
mzling 0:6b5a3a0138ad 197 memset(_xbeeBuffer,0xFF,250);
mzling 0:6b5a3a0138ad 198 _dataCnt = 0;
mzling 3:19c08e8a552a 199 _prev_UI = UI;
mzling 0:6b5a3a0138ad 200 }
mzling 0:6b5a3a0138ad 201
mzling 0:6b5a3a0138ad 202 void UserInterface::initializeUI()
mzling 0:6b5a3a0138ad 203 {
mzling 0:6b5a3a0138ad 204 xbeeUI.baud(115200);
mzling 0:6b5a3a0138ad 205 mainPower = 0;
mzling 0:6b5a3a0138ad 206
mzling 0:6b5a3a0138ad 207 }