Experiment of serial command protocol
Dependencies: RingBuffer SerialInterfaceProtocol duinotech_16x2_LCD mbed
You can edit this area
CommandPacket.cpp@3:0c4aa3cec685, 2016-06-16 (annotated)
- Committer:
- rba90
- Date:
- Thu Jun 16 03:52:01 2016 +0000
- Revision:
- 3:0c4aa3cec685
- Parent:
- 2:54932809c7b2
1. Update definition for checksum; 2. Add more examples of SIP
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
rba90 | 0:2ba6a9f316b6 | 1 | #include "CommandPacket.h" |
rba90 | 0:2ba6a9f316b6 | 2 | #include "mbed.h" |
rba90 | 0:2ba6a9f316b6 | 3 | |
rba90 | 0:2ba6a9f316b6 | 4 | #define CHECKSUM_DEBUG |
rba90 | 0:2ba6a9f316b6 | 5 | |
rba90 | 0:2ba6a9f316b6 | 6 | uint8_t generate_checksum(uint8_t *data, uint8_t length, uint8_t offset) |
rba90 | 0:2ba6a9f316b6 | 7 | { |
rba90 | 0:2ba6a9f316b6 | 8 | uint8_t s = 0; |
rba90 | 0:2ba6a9f316b6 | 9 | |
rba90 | 0:2ba6a9f316b6 | 10 | if (data) |
rba90 | 0:2ba6a9f316b6 | 11 | { |
rba90 | 0:2ba6a9f316b6 | 12 | // take the sum of all data bytes preceding checksum field |
rba90 | 0:2ba6a9f316b6 | 13 | for(uint8_t i = 0; i < length; i++) |
rba90 | 0:2ba6a9f316b6 | 14 | { |
rba90 | 0:2ba6a9f316b6 | 15 | s += data[i + offset]; |
rba90 | 0:2ba6a9f316b6 | 16 | } |
rba90 | 0:2ba6a9f316b6 | 17 | |
rba90 | 0:2ba6a9f316b6 | 18 | // calculate two's complement of the remainder |
rba90 | 0:2ba6a9f316b6 | 19 | s = 0xff - s + 1; |
rba90 | 0:2ba6a9f316b6 | 20 | } |
rba90 | 0:2ba6a9f316b6 | 21 | |
rba90 | 0:2ba6a9f316b6 | 22 | return s; |
rba90 | 0:2ba6a9f316b6 | 23 | } |
rba90 | 0:2ba6a9f316b6 | 24 | |
rba90 | 0:2ba6a9f316b6 | 25 | uint8_t hexchar_to_uint8(uint8_t ch) |
rba90 | 0:2ba6a9f316b6 | 26 | { |
rba90 | 0:2ba6a9f316b6 | 27 | uint8_t val = 0; |
rba90 | 0:2ba6a9f316b6 | 28 | |
rba90 | 0:2ba6a9f316b6 | 29 | if (ch >= '0' && ch <= '9') |
rba90 | 0:2ba6a9f316b6 | 30 | { |
rba90 | 0:2ba6a9f316b6 | 31 | val = ch - '0'; |
rba90 | 0:2ba6a9f316b6 | 32 | } |
rba90 | 0:2ba6a9f316b6 | 33 | else if (ch >= 'A' && ch <= 'F') |
rba90 | 0:2ba6a9f316b6 | 34 | { |
rba90 | 0:2ba6a9f316b6 | 35 | val = ch - 'A'; |
rba90 | 0:2ba6a9f316b6 | 36 | val += 10; |
rba90 | 0:2ba6a9f316b6 | 37 | } |
rba90 | 0:2ba6a9f316b6 | 38 | else if (ch >= 'a' && ch <= 'f') |
rba90 | 0:2ba6a9f316b6 | 39 | { |
rba90 | 0:2ba6a9f316b6 | 40 | val = ch - 'a'; |
rba90 | 0:2ba6a9f316b6 | 41 | val += 10; |
rba90 | 0:2ba6a9f316b6 | 42 | } |
rba90 | 0:2ba6a9f316b6 | 43 | |
rba90 | 0:2ba6a9f316b6 | 44 | return val; |
rba90 | 0:2ba6a9f316b6 | 45 | } |
rba90 | 2:54932809c7b2 | 46 | |
rba90 | 0:2ba6a9f316b6 | 47 | |
rba90 | 0:2ba6a9f316b6 | 48 | bool CommandPacket::verify() |
rba90 | 0:2ba6a9f316b6 | 49 | { |
rba90 | 3:0c4aa3cec685 | 50 | return checksum == generate_checksum(); |
rba90 | 0:2ba6a9f316b6 | 51 | } |
rba90 | 0:2ba6a9f316b6 | 52 | |
rba90 | 0:2ba6a9f316b6 | 53 | CommandPacket::CommandPacket() |
rba90 | 0:2ba6a9f316b6 | 54 | { |
rba90 | 0:2ba6a9f316b6 | 55 | // reset internal error number |
rba90 | 0:2ba6a9f316b6 | 56 | errno = NO_ERROR; |
rba90 | 0:2ba6a9f316b6 | 57 | |
rba90 | 0:2ba6a9f316b6 | 58 | // set public variables |
rba90 | 0:2ba6a9f316b6 | 59 | sflag = '<'; |
rba90 | 0:2ba6a9f316b6 | 60 | command = 0x0; |
rba90 | 0:2ba6a9f316b6 | 61 | length = 0x0; |
rba90 | 0:2ba6a9f316b6 | 62 | memset(payload, 0x0, sizeof(payload)); |
rba90 | 0:2ba6a9f316b6 | 63 | checksum = 0x0; |
rba90 | 0:2ba6a9f316b6 | 64 | eflag = '>'; |
rba90 | 0:2ba6a9f316b6 | 65 | } |
rba90 | 0:2ba6a9f316b6 | 66 | |
rba90 | 0:2ba6a9f316b6 | 67 | const char *CommandPacket::getErrorString() const |
rba90 | 0:2ba6a9f316b6 | 68 | { |
rba90 | 0:2ba6a9f316b6 | 69 | return errorString[errno]; |
rba90 | 0:2ba6a9f316b6 | 70 | } |
rba90 | 2:54932809c7b2 | 71 | |
rba90 | 2:54932809c7b2 | 72 | int CommandPacket::serialize(uint8_t *output) |
rba90 | 2:54932809c7b2 | 73 | { |
rba90 | 2:54932809c7b2 | 74 | // create buffer for payload |
rba90 | 2:54932809c7b2 | 75 | uint8_t buffer[length * 2]; |
rba90 | 2:54932809c7b2 | 76 | memset(buffer, 0x0, sizeof(buffer)); |
rba90 | 2:54932809c7b2 | 77 | |
rba90 | 2:54932809c7b2 | 78 | for (int i = 0; i < length; i++) |
rba90 | 2:54932809c7b2 | 79 | { |
rba90 | 2:54932809c7b2 | 80 | sprintf((char *) (buffer + i * 2), "%02X", payload[i]); |
rba90 | 2:54932809c7b2 | 81 | } |
rba90 | 2:54932809c7b2 | 82 | |
rba90 | 2:54932809c7b2 | 83 | // assume the user provide output buffer large enough |
rba90 | 2:54932809c7b2 | 84 | sprintf((char *) output, "%c%02X%02X%s%02X%c", |
rba90 | 2:54932809c7b2 | 85 | sflag, |
rba90 | 2:54932809c7b2 | 86 | command, |
rba90 | 2:54932809c7b2 | 87 | length, |
rba90 | 2:54932809c7b2 | 88 | (char *) buffer, |
rba90 | 3:0c4aa3cec685 | 89 | generate_checksum(), |
rba90 | 2:54932809c7b2 | 90 | eflag |
rba90 | 2:54932809c7b2 | 91 | ); |
rba90 | 2:54932809c7b2 | 92 | |
rba90 | 2:54932809c7b2 | 93 | return length; |
rba90 | 2:54932809c7b2 | 94 | } |
rba90 | 3:0c4aa3cec685 | 95 | |
rba90 | 3:0c4aa3cec685 | 96 | uint8_t CommandPacket::generate_checksum() |
rba90 | 3:0c4aa3cec685 | 97 | { |
rba90 | 3:0c4aa3cec685 | 98 | // checksum is defined by the sum of all characters between sflag and checksum field |
rba90 | 3:0c4aa3cec685 | 99 | uint8_t s = 0; |
rba90 | 3:0c4aa3cec685 | 100 | |
rba90 | 3:0c4aa3cec685 | 101 | // include command |
rba90 | 3:0c4aa3cec685 | 102 | s += command; |
rba90 | 3:0c4aa3cec685 | 103 | |
rba90 | 3:0c4aa3cec685 | 104 | // include length |
rba90 | 3:0c4aa3cec685 | 105 | s += length; |
rba90 | 3:0c4aa3cec685 | 106 | |
rba90 | 3:0c4aa3cec685 | 107 | // include payload |
rba90 | 3:0c4aa3cec685 | 108 | for (int i = 0; i < length; i++) |
rba90 | 3:0c4aa3cec685 | 109 | { |
rba90 | 3:0c4aa3cec685 | 110 | s += payload[i]; |
rba90 | 3:0c4aa3cec685 | 111 | } |
rba90 | 3:0c4aa3cec685 | 112 | |
rba90 | 3:0c4aa3cec685 | 113 | // calculate two's complement of the remainder |
rba90 | 3:0c4aa3cec685 | 114 | s = 0xff - s + 1; |
rba90 | 3:0c4aa3cec685 | 115 | |
rba90 | 3:0c4aa3cec685 | 116 | return s; |
rba90 | 3:0c4aa3cec685 | 117 | } |
rba90 | 2:54932809c7b2 | 118 | |
rba90 | 2:54932809c7b2 | 119 |