![](/media/cache/profiles/aa03f7d585b4ae5554378b5843a73d11.jpg.50x50_q85.png)
Experiment of serial command protocol
Dependencies: RingBuffer SerialInterfaceProtocol duinotech_16x2_LCD mbed
You can edit this area
CommandPacket.cpp@2:54932809c7b2, 2016-06-09 (annotated)
- Committer:
- rba90
- Date:
- Thu Jun 09 12:28:31 2016 +0000
- Revision:
- 2:54932809c7b2
- Parent:
- 0:2ba6a9f316b6
- Child:
- 3:0c4aa3cec685
Add wrapper for protocol
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 | 0:2ba6a9f316b6 | 50 | return checksum == generate_checksum(payload, length); |
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 | 0:2ba6a9f316b6 | 71 | |
rba90 | 0:2ba6a9f316b6 | 72 | char *CommandPacket::getErrorCode() const |
rba90 | 0:2ba6a9f316b6 | 73 | { |
rba90 | 0:2ba6a9f316b6 | 74 | // clear error code |
rba90 | 0:2ba6a9f316b6 | 75 | memset(errorCode, 0x0, sizeof(errorCode)); |
rba90 | 0:2ba6a9f316b6 | 76 | |
rba90 | 0:2ba6a9f316b6 | 77 | // push into buffer |
rba90 | 0:2ba6a9f316b6 | 78 | snprintf(errorCode, sizeof(errorCode), "%c%02x%02x%02x%02x%c", |
rba90 | 0:2ba6a9f316b6 | 79 | sflag, |
rba90 | 0:2ba6a9f316b6 | 80 | 0xe0 | (errno & 0x0f), |
rba90 | 0:2ba6a9f316b6 | 81 | 0x1, |
rba90 | 0:2ba6a9f316b6 | 82 | command, |
rba90 | 0:2ba6a9f316b6 | 83 | 0x0, |
rba90 | 0:2ba6a9f316b6 | 84 | eflag |
rba90 | 0:2ba6a9f316b6 | 85 | ); |
rba90 | 0:2ba6a9f316b6 | 86 | |
rba90 | 0:2ba6a9f316b6 | 87 | return errorCode; |
rba90 | 0:2ba6a9f316b6 | 88 | } |
rba90 | 2:54932809c7b2 | 89 | |
rba90 | 2:54932809c7b2 | 90 | int CommandPacket::serialize(uint8_t *output) |
rba90 | 2:54932809c7b2 | 91 | { |
rba90 | 2:54932809c7b2 | 92 | // create buffer for payload |
rba90 | 2:54932809c7b2 | 93 | uint8_t buffer[length * 2]; |
rba90 | 2:54932809c7b2 | 94 | memset(buffer, 0x0, sizeof(buffer)); |
rba90 | 2:54932809c7b2 | 95 | |
rba90 | 2:54932809c7b2 | 96 | for (int i = 0; i < length; i++) |
rba90 | 2:54932809c7b2 | 97 | { |
rba90 | 2:54932809c7b2 | 98 | sprintf((char *) (buffer + i * 2), "%02X", payload[i]); |
rba90 | 2:54932809c7b2 | 99 | } |
rba90 | 2:54932809c7b2 | 100 | |
rba90 | 2:54932809c7b2 | 101 | // assume the user provide output buffer large enough |
rba90 | 2:54932809c7b2 | 102 | sprintf((char *) output, "%c%02X%02X%s%02X%c", |
rba90 | 2:54932809c7b2 | 103 | sflag, |
rba90 | 2:54932809c7b2 | 104 | command, |
rba90 | 2:54932809c7b2 | 105 | length, |
rba90 | 2:54932809c7b2 | 106 | (char *) buffer, |
rba90 | 2:54932809c7b2 | 107 | generate_checksum(payload, length), |
rba90 | 2:54932809c7b2 | 108 | eflag |
rba90 | 2:54932809c7b2 | 109 | ); |
rba90 | 2:54932809c7b2 | 110 | |
rba90 | 2:54932809c7b2 | 111 | return length; |
rba90 | 2:54932809c7b2 | 112 | } |
rba90 | 2:54932809c7b2 | 113 | |
rba90 | 2:54932809c7b2 | 114 | |
rba90 | 2:54932809c7b2 | 115 |