Experiment of serial command protocol
Dependencies: RingBuffer SerialInterfaceProtocol duinotech_16x2_LCD mbed
You can edit this area
Diff: main.cpp
- Revision:
- 2:54932809c7b2
- Parent:
- 0:2ba6a9f316b6
- Child:
- 3:0c4aa3cec685
diff -r d021198911c0 -r 54932809c7b2 main.cpp --- a/main.cpp Sat Jun 04 12:11:17 2016 +0000 +++ b/main.cpp Thu Jun 09 12:28:31 2016 +0000 @@ -2,251 +2,150 @@ #include "freetronicsLCDShield.h" #include "buffer.h" #include "CommandPacket.h" +#include "SerialInterfaceProtocol.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; +CircularBuffer<uint8_t> SerialInputBuffer; +CircularBuffer<uint8_t> SerialOutputBuffer; +SerialInterfaceProtocol SIP(&SerialInputBuffer, &SerialOutputBuffer); 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()) + if (SerialInputBuffer.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; + SerialInputBuffer.enqueue((uint8_t) c); } } -void commandDecoder() +int toggleLcdBackLight(uint8_t *payload, uint8_t payload_length, uint8_t *response, uint8_t *response_length) +{ + // wrong payload length + if (payload_length != 1) + { + sprintf((char *) response, "Wrong Payload Length\r\n"); + *response_length = 22; + return 1; + } + + // get payload + bool lcdBackLight = (bool) payload[0]; + + // set back light + lcd.setBackLight(lcdBackLight); + + return 0; +} + +int setLcdBackLightIntensity(uint8_t *payload, uint8_t payload_length, uint8_t *response, uint8_t *response_length) +{ + // set intensity + lcd.setBackLight((float) atof((char*) payload)); + + return 0; +} + +int resetLcd(uint8_t *payload, uint8_t payload_length, uint8_t *response, uint8_t *response_length) +{ + // no payload + if (payload_length != 0) + { + sprintf((char *) response, "Wrong Payload Length\r\n"); + *response_length = 22; + return 1; + } + + // reset display and settings + lcd.cls(); + + return 0; +} + +int setLcdCursorPosition(uint8_t *payload, uint8_t payload_length, uint8_t *response, uint8_t *response_length) { - static CommandPacket::State_t state = CommandPacket::NONE; - static uint8_t payload_counter = 0; - - while (SerialBuffer.getCounter() > 0) + // two payloads + if (payload_length != 2) { - 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; - } + sprintf((char *) response, "Wrong Payload Length\r\n"); + *response_length = 22; + return 1; + } + + // set current cursor location + lcd.setCursorPosition( + (bool) payload[0], + (bool) payload[1] + ); + + return 0; +} + +int setLcdCursorProperty(uint8_t *payload, uint8_t payload_length, uint8_t *response, uint8_t *response_length) +{ + // two payloads + if (payload_length != 2) + { + sprintf((char *) response, "Wrong Payload Length\r\n"); + *response_length = 22; + return 1; + } + + lcd.setCursor( + (bool) payload[0], + (bool) payload[1] + ); + + return 0; +} + +int lcdPrintToLine(uint8_t *payload, uint8_t payload_length, uint8_t *response, uint8_t *response_length) +{ + // set cursor position + lcd.setCursorPosition(payload[0], 0); + + // print to screen + lcd.printf((char *) (payload + 1)); + + return 0; +} + +int lcdAppendPrint(uint8_t *payload, uint8_t payload_length, uint8_t *response, uint8_t *response_length) +{ + // print to screen + lcd.printf((char *) payload); + + return 0; +} + +int toggleChecksum(uint8_t *payload, uint8_t payload_length, uint8_t *response, uint8_t *response_length) +{ + // one payload + if (payload_length != 1) + { + sprintf((char *) response, "Wrong Payload Length\r\n"); + *response_length = 22; + return 1; + } + + if ((bool) payload[0]) + { + SIP.enableChecksum(); } + else + { + SIP.disableChecksum(); + } + + return 0; } int main() { @@ -257,8 +156,23 @@ pc.attach(&serialInterruptHandler); + // control + SIP.registerCommand(0x00, toggleChecksum); + + // lcd + SIP.registerCommand(0xf0, toggleLcdBackLight); + SIP.registerCommand(0xf1, setLcdBackLightIntensity); + SIP.registerCommand(0xf2, resetLcd); + SIP.registerCommand(0xf3, setLcdCursorPosition); + SIP.registerCommand(0xf4, setLcdCursorProperty); + SIP.registerCommand(0xf5, lcdPrintToLine); + SIP.registerCommand(0xf6, lcdAppendPrint); + + + while (1) { + SIP.poll(); // button event switch (lcd.readButton()) { @@ -278,6 +192,12 @@ } - commandDecoder(); + // extract buffer + while (SerialOutputBuffer.getCounter() > 0) + { + uint8_t ch; + ch = SerialOutputBuffer.dequeue(); + pc.putc(ch); + } } } \ No newline at end of file