![](/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
main.cpp
- Committer:
- rba90
- Date:
- 2016-06-04
- Revision:
- 0:2ba6a9f316b6
- Child:
- 2:54932809c7b2
File content as of revision 0:2ba6a9f316b6:
#include "mbed.h" #include "freetronicsLCDShield.h" #include "buffer.h" #include "CommandPacket.h" // #define DEBUG_MESSAGE freetronicsLCDShield lcd(D8, D9, D4, D5, D6, D7, D10, A0); // rs, e, d0, d1, d2, d3, bl, a0 Serial pc(USBTX, USBRX); CircularBuffer<uint8_t> SerialBuffer; CommandPacket SerialCommandProtocol; void serialInterruptHandler() { // Note: you need to actually read from the serial to clear the RX interrupt int c = pc.getc(); // add to buffer if (SerialBuffer.isLocked()) { printf("Mutex Locked\r\n"); } else { SerialBuffer.enqueue((uint8_t) c); } } void lcdCommandController() { switch (SerialCommandProtocol.command & 0xf) // lower four bits { case 0x0: // turn on or off lcd back light lcd.setBackLight((bool) SerialCommandProtocol.payload[0]); break; case 0x1: // adjust the duty cycle of lcd lcd.setBackLight((float) atof((char *)SerialCommandProtocol.payload)); break; case 0x2: // clear the display and reset the cursor lcd.cls(); break; case 0x3: // set current cursor position (line, col) lcd.setCursorPosition( SerialCommandProtocol.payload[0], SerialCommandProtocol.payload[1] ); break; case 0x4: // set cursor visible or not and if it blink lcd.setCursor( (bool) SerialCommandProtocol.payload[0], (bool) SerialCommandProtocol.payload[1] ); break; case 0x5: // print to line lcd.setCursorPosition(SerialCommandProtocol.payload[0], 0); lcd.printf((char *) &SerialCommandProtocol.payload[1]); break; case 0x6: // append text to current position lcd.printf((char *) SerialCommandProtocol.payload); break; default: break; } } void commandExecutor() { #ifdef DEBUG_MESSAGE printf("SFLAG: 0x%x\r\nCMD: 0x%x\r\nLEN: 0x%x\r\n", SerialCommandProtocol.sflag, SerialCommandProtocol.command, SerialCommandProtocol.length ); printf("PL: "); for (int i = 0; i < SerialCommandProtocol.length; i++) { printf("0x%x ", SerialCommandProtocol.payload[i]); } printf("\r\n"); printf("CS: 0x%x\r\nEFLAG: 0x%x\r\n", SerialCommandProtocol.checksum, SerialCommandProtocol.eflag ); #endif // execute switch (SerialCommandProtocol.command >> 4) // higher four bits { case 0xf: // lcd control lcdCommandController(); break; default: break; } } void commandDecoder() { static CommandPacket::State_t state = CommandPacket::NONE; static uint8_t payload_counter = 0; while (SerialBuffer.getCounter() > 0) { uint8_t ch; ch = SerialBuffer.dequeue(); // reset state to keep sync if (ch == CommandPacket::CP_SFLAG) { state = CommandPacket::SFLAG; // reset variable payload_counter = 0; memset(SerialCommandProtocol.payload, 0x0, sizeof(SerialCommandProtocol.payload)); } switch (state) { case CommandPacket::SFLAG: SerialCommandProtocol.sflag = ch; state = CommandPacket::COMMAND_H; #ifdef DEBUG_MESSAGE printf("CommandPacket::SFLAG: 0x%x\r\n", SerialCommandProtocol.sflag); #endif break; case CommandPacket::COMMAND_H: SerialCommandProtocol.command = hexchar_to_uint8(ch) << 4; state = CommandPacket::COMMAND_L; #ifdef DEBUG_MESSAGE printf("CommandPacket::COMMAND_H: 0x%x\r\n", SerialCommandProtocol.command); #endif break; case CommandPacket::COMMAND_L: SerialCommandProtocol.command |= (hexchar_to_uint8(ch) & 0x0f); state = CommandPacket::LENGTH_H; #ifdef DEBUG_MESSAGE printf("CommandPacket::COMMAND_L: 0x%x\r\n", SerialCommandProtocol.command); #endif break; case CommandPacket::LENGTH_H: SerialCommandProtocol.length = hexchar_to_uint8(ch) << 4; state = CommandPacket::LENGTH_L; #ifdef DEBUG_MESSAGE printf("CommandPacket::LENGTH_H: 0x%x\r\n", SerialCommandProtocol.length); #endif break; case CommandPacket::LENGTH_L: SerialCommandProtocol.length |= (hexchar_to_uint8(ch) & 0x0f); if (SerialCommandProtocol.length != 0) // if the length is not zero, then proceed to payload state { state = CommandPacket::PAYLOAD_H; } else // otherwise proceed to checksum state { state = CommandPacket::CHECKSUM_H; } #ifdef DEBUG_MESSAGE printf("CommandPacket::LENGTH_L: 0x%x\r\n", SerialCommandProtocol.length); #endif break; case CommandPacket::PAYLOAD_H: SerialCommandProtocol.payload[payload_counter] = hexchar_to_uint8(ch) << 4; // store higher 4 bits of payload state = CommandPacket::PAYLOAD_L; #ifdef DEBUG_MESSAGE printf("CommandPacket::PAYLOAD_H: 0x%x\r\n", SerialCommandProtocol.payload[payload_counter]); #endif break; case CommandPacket::PAYLOAD_L: SerialCommandProtocol.payload[payload_counter++] |= (hexchar_to_uint8(ch) & 0x0f); // store lower 4 bits of payload if (payload_counter < SerialCommandProtocol.length) // append ch to payload until reach the length { state = CommandPacket::PAYLOAD_H; } else { state = CommandPacket::CHECKSUM_H; } #ifdef DEBUG_MESSAGE printf("CommandPacket::PAYLOAD_L: 0x%x\r\n", SerialCommandProtocol.payload[payload_counter - 1]); #endif break; case CommandPacket::CHECKSUM_H: SerialCommandProtocol.checksum = hexchar_to_uint8(ch) << 4; state = CommandPacket::CHECKSUM_L; #ifdef DEBUG_MESSAGE printf("CommandPacket::CHECKSUM_H: 0x%x\r\n", SerialCommandProtocol.checksum); #endif break; case CommandPacket::CHECKSUM_L: SerialCommandProtocol.checksum |= (hexchar_to_uint8(ch) & 0x0f); if (true) // disable the checksum { state = CommandPacket::EFLAG; } else { SerialCommandProtocol.errno = CommandPacket::INVALID_CS_ERROR; pc.printf("%s\r\n", SerialCommandProtocol.getErrorCode()); state = CommandPacket::NONE; } #ifdef DEBUG_MESSAGE printf("CommandPacket::CHECKSUM_L: 0x%x\r\n", SerialCommandProtocol.checksum); #endif break; case CommandPacket::EFLAG: if (ch == CommandPacket::CP_EFLAG) { SerialCommandProtocol.eflag = ch; // TODO:: execute command here commandExecutor(); } state = CommandPacket::NONE; #ifdef DEBUG_MESSAGE printf("CommandPacket::EFLAG: 0x%x\r\n", SerialCommandProtocol.eflag); #endif break; case CommandPacket::NONE: SerialCommandProtocol.errno = CommandPacket::INVALID_SFLAG_ERROR; pc.printf("%s\r\n", SerialCommandProtocol.getErrorCode()); #ifdef DEBUG_MESSAGE printf("CommandPacket::NONE\r\n"); #endif break; default: break; } } } int main() { // turn on the back light (it's off by default) lcd.setBackLight(true); lcd.setCursor(true, true); lcd.cls(); pc.attach(&serialInterruptHandler); while (1) { // button event switch (lcd.readButton()) { case freetronicsLCDShield::BTN_SELECT: lcd.cls(); break; case freetronicsLCDShield::BTN_UP: break; case freetronicsLCDShield::BTN_DOWN: break; case freetronicsLCDShield::BTN_LEFT: break; case freetronicsLCDShield::BTN_RIGHT: break; default: break; } commandDecoder(); } }