├── LICENSE
├── README.md
├── grovedupont.jpg
├── image.jpg
├── platformio.ini
└── src
├── display.cpp
├── display.h
├── event.cpp
├── event.h
├── input.cpp
├── input.h
├── main.cpp
├── serial.cpp
└── serial.h
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MicroCOM
2 |
3 | Microcom is a lightweight serial UART communication software for the M5Cardputer. This allows users to configure and manage serial communication with external devices over UART.
4 |
5 |
6 | 
7 |
8 |
9 | ## Features:
10 | - Easy configuration for baud rate, data bits, parity, stop bits, flow control, and inverted signal settings.
11 | - Send and receive serial data
12 |
13 | ## Installation
14 | - M5Burner : Search into M5CARDPUTER section and simply burn it
15 | - Github : Get the firmware from the latest github release.
16 |
17 | ## Pin Configuration:
18 | The pins used are on the Grove connector:
19 |
20 | - RX Pin: GPIO1 (can be changed in the configuration menu)
21 | - TX Pin: GPIO2 (can be changed in the configuration menu)
22 |
23 | You could use Grove/Dupont connector to interface with the Cardputer:
24 |
25 | 
26 |
27 | ## Keybinds:
28 |
29 | - Config: Use `Arrows` and `OK` button to toggle configuration options.
30 | - Terminal: Use `Keys` and `OK` button to send commands
31 |
32 | ## ⚠️ Caution:
33 |
34 | The M5Cardputer operate at 3.3V logic levels. Connecting any UART device that uses a different voltage can damage the device. Always ensure that your connected UART device that uses 3.3V.
--------------------------------------------------------------------------------
/grovedupont.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geo-tp/MicroCOM/8b4d10c5c17706dafd29759c3c6e9e7b1733351e/grovedupont.jpg
--------------------------------------------------------------------------------
/image.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geo-tp/MicroCOM/8b4d10c5c17706dafd29759c3c6e9e7b1733351e/image.jpg
--------------------------------------------------------------------------------
/platformio.ini:
--------------------------------------------------------------------------------
1 | ; PlatformIO Project Configuration File
2 | ;
3 | ; Build options: build flags, source filter
4 | ; Upload options: custom upload port, speed and extra flags
5 | ; Library options: dependencies, extra library storages
6 | ; Advanced options: extra scripting
7 | ;
8 | ; Please visit documentation for the other options and examples
9 | ; https://docs.platformio.org/page/projectconf.html
10 |
11 | [env:m5stack-stamps3]
12 | platform = espressif32
13 | board = m5stack-stamps3
14 | framework = arduino
15 | lib_deps =
16 | m5stack/M5Cardputer@^1.0.3
--------------------------------------------------------------------------------
/src/display.cpp:
--------------------------------------------------------------------------------
1 | #include "display.h"
2 |
3 | void displayInit() {
4 | // Initialize display
5 | M5.Lcd.begin();
6 | M5.Lcd.setRotation(1);
7 | M5.Lcd.setTextColor(TFT_LIGHTGREY);
8 | }
9 |
10 | void displayWelcome() {
11 | M5.Lcd.fillScreen(BACKGROUND_COLOR);
12 |
13 | // Main title
14 | M5.Lcd.setTextSize(3);
15 | M5.Lcd.setTextColor(PRIMARY_COLOR);
16 | M5.Lcd.setCursor(50, 50);
17 | M5.Lcd.printf("Micro");
18 |
19 | M5.Lcd.setTextSize(2.5);
20 | M5.Lcd.setTextColor(TEXT_COLOR);
21 | M5.Lcd.setCursor(146, 54);
22 | M5.Lcd.printf("COM");
23 |
24 | // Sub title
25 | M5.Lcd.setTextSize(1.2);
26 | M5.Lcd.setTextColor(TEXT_COLOR);
27 | M5.Lcd.setCursor(50, 78);
28 | M5.Lcd.printf("Serial");
29 |
30 | M5.Lcd.setTextSize(1.3);
31 | M5.Lcd.setCursor(98, 78);
32 | M5.Lcd.printf("Communication");
33 |
34 | };
35 |
36 | void displayConfig(int baud, uint8_t rx, uint8_t tx, uint8_t dataBits,
37 | std::string parity, uint8_t stopBits, bool flowControl,
38 | bool inverted, uint8_t selectedIndex) {
39 |
40 | std::vector configStrings = {
41 | "Rx Pin: " + std::to_string(rx),
42 | "Tx Pin: " + std::to_string(tx),
43 | "Baud: " + std::to_string(baud),
44 | "Data Bits: " + std::to_string(dataBits),
45 | "Parity: " + parity,
46 | "Stop Bits: " + std::to_string(stopBits),
47 | "Flow Ctrl: " + std::string(flowControl ? "Yes" : "No"),
48 | "Inverted: " + std::string(inverted ? "Yes" : "No")
49 | };
50 |
51 | uint8_t halfWidth = (M5Cardputer.Display.width() - 20) / 2; // largeur de chaque bloc dans une colonne
52 | uint8_t sizeY = 22; // hauteur de chaque bloc
53 | uint8_t startY = 5; // position de départ en Y pour le premier bloc
54 | uint8_t stepY = 26; // intervalle entre chaque bloc
55 | uint8_t margin = DEFAULT_MARGIN;
56 | uint8_t startText = 13; // position de départ du texte
57 | bool selected;
58 |
59 | displayClearMainView();
60 | M5.Lcd.setTextSize(1.3);
61 |
62 | for (size_t i = 0; i < configStrings.size(); ++i) {
63 | selected = (i == selectedIndex);
64 |
65 | // Calculer la position en X pour la colonne (gauche ou droite)
66 | uint8_t col = i / 4; // 0 pour la colonne de gauche, 1 pour la colonne de droite
67 | uint8_t xPos = margin + col * (halfWidth + margin);
68 |
69 | // Calculer la position en Y pour chaque ligne
70 | uint8_t yPos = startY + (i % 4) * stepY;
71 |
72 | drawRect(selected, xPos, yPos, halfWidth, sizeY);
73 |
74 | uint8_t marginText = margin + 5;
75 | M5.Lcd.setCursor(xPos + marginText, yPos + startText - startY);
76 |
77 | M5.Lcd.printf(configStrings[i].c_str());
78 | }
79 |
80 | if (selectedIndex == configStrings.size()) {
81 | displayStart(true);
82 | } else {
83 | displayStart(false);
84 | }
85 | }
86 |
87 | void displayStart(bool selected) {
88 | drawRect(selected, DEFAULT_MARGIN, 110,M5.Lcd.width() - 15, 25);
89 | M5.Lcd.setCursor(79, 118);
90 | M5.Lcd.print("START SERIAL");
91 | };
92 |
93 | void displayTerminal(std::string receiveString) {
94 | const uint8_t charsPerLine = 34;
95 | const uint8_t linesPerScreen = 10;
96 |
97 | // Split receiveString by \n and wrap text
98 | std::vector lines;
99 | std::string currentLine;
100 | for (size_t i = 0; i < receiveString.length(); ++i) {
101 | char c = receiveString[i];
102 | if (c == '\n') {
103 | lines.push_back(currentLine); // Add the current line and reset
104 | currentLine.clear();
105 | } else {
106 | currentLine += c;
107 | // If the current line exceeds the allowed number of characters per line, wrap it
108 | if (currentLine.length() >= charsPerLine) {
109 | lines.push_back(currentLine);
110 | currentLine.clear();
111 | }
112 | }
113 | }
114 | // Push the last remaining part of the string (if any)
115 | if (!currentLine.empty()) {
116 | lines.push_back(currentLine);
117 | }
118 |
119 | // Now, calculate the number of lines and only display the last ones that fit on the screen
120 | size_t totalLines = lines.size();
121 | size_t startLine = 0;
122 | if (totalLines > linesPerScreen) {
123 | startLine = totalLines - linesPerScreen;
124 | }
125 |
126 | // Clear the terminal view before displaying the new content
127 | displayClearTerminalView();
128 | M5.Lcd.setCursor(0, DEFAULT_MARGIN);
129 |
130 | // Print only the visible portion of the terminal string
131 | for (size_t i = startLine; i < totalLines; ++i) {
132 | M5.Lcd.println(lines[i].c_str());
133 | }
134 | }
135 |
136 |
137 | void displayPrompt(std::string sendString) {
138 |
139 | if (sendString.length() > 26) {
140 | sendString = sendString.substr(sendString.length() - 26);
141 | }
142 | drawRect(false, DEFAULT_MARGIN, 110,M5.Lcd.width() - 15, 25);
143 | M5.Lcd.setCursor(DEFAULT_MARGIN*2, 118);
144 | M5.Lcd.print(" > ");
145 | M5.Lcd.print(sendString.c_str());
146 | }
147 |
148 | void drawRect(bool selected, uint8_t margin, uint16_t startY, uint16_t sizeX, uint16_t sizeY) {
149 | // Draw rect
150 | if (selected) {
151 | M5.Lcd.fillRoundRect(margin, startY, sizeX, sizeY, DEFAULT_ROUND_RECT, PRIMARY_COLOR);
152 | M5.Lcd.setTextColor(TEXT_COLOR);
153 | } else {
154 | M5.Lcd.fillRoundRect(margin, startY, sizeX, sizeY, DEFAULT_ROUND_RECT, RECT_COLOR_DARK);
155 | M5.Lcd.drawRoundRect(margin, startY, sizeX, sizeY, DEFAULT_ROUND_RECT, PRIMARY_COLOR);
156 | M5.Lcd.setTextColor(TEXT_COLOR);
157 | }
158 | }
159 |
160 | void displayClearMainView(uint8_t offsetY) {
161 | M5.Lcd.fillRect(0, 0,M5.Lcd.width(),M5.Lcd.height(), BACKGROUND_COLOR);
162 | }
163 |
164 | void displayClearTerminalView() {
165 | M5.Lcd.fillRect(0, 0,M5.Lcd.width(),M5.Lcd.height()-30, BACKGROUND_COLOR);
166 | }
167 |
--------------------------------------------------------------------------------
/src/display.h:
--------------------------------------------------------------------------------
1 | #ifndef DISPLAY_H
2 | #define DISPLAY_H
3 |
4 | #include
5 | #include
6 | #include // Assurez-vous que cette bibliothèque est la bonne selon votre matériel (M5Stack, M5Cardputer, etc.)
7 |
8 | #define BACKGROUND_COLOR TFT_BLACK
9 | #define PRIMARY_COLOR 0xfa03
10 | #define RECT_COLOR_DARK 0x0841
11 | #define RECT_COLOR_LIGHT 0xd69a
12 | #define TEXT_COLOR 0xef7d
13 | #define TEXT_COLOR_ALT TFT_DARKGRAY
14 |
15 | #define DEFAULT_MARGIN 5
16 | #define DEFAULT_ROUND_RECT 5
17 |
18 | void displayInit();
19 | void displayWelcome();
20 | void displayConfig(int baud, uint8_t rx, uint8_t tx, uint8_t dataBits,
21 | std::string parity, uint8_t stopBits, bool flowControl,
22 | bool inverted, uint8_t selectedIndex);
23 | void displayStart(bool selected);
24 | void displayTerminal(std::string terminalSting);
25 | void displayPrompt(std::string sendString);
26 | void displayClearMainView(uint8_t offsetY=0);
27 | void displayClearTerminalView();
28 |
29 | // Utility Function (forward declaration if needed)
30 | void drawRect(bool selected, uint8_t margin, uint16_t startY, uint16_t sizeX, uint16_t sizeY);
31 |
32 | #endif // DISPLAY_CONFIG_H
33 |
--------------------------------------------------------------------------------
/src/event.cpp:
--------------------------------------------------------------------------------
1 | #include "event.h"
2 |
3 | uint8_t handleIndexSelection(char input, uint8_t currentIndex) {
4 | switch (input) {
5 | case KEY_ARROW_UP:
6 | if (currentIndex == LAUNCH_INDEX) return BITS_INDEX;
7 | if (currentIndex == PARITY_INDEX) return LAUNCH_INDEX;
8 | return currentIndex > 0 ? currentIndex - 1 : LAUNCH_INDEX;
9 | case KEY_ARROW_DOWN:
10 | if (currentIndex == BITS_INDEX) return LAUNCH_INDEX;
11 | return (currentIndex < LAUNCH_INDEX) ? currentIndex + 1 : 0;
12 | case KEY_ARROW_LEFT:
13 | return currentIndex >= 4 ? currentIndex - 4 : currentIndex;
14 | case KEY_ARROW_RIGHT:
15 | return currentIndex < 4 ? currentIndex + 4 : currentIndex;
16 | default:
17 | return currentIndex;
18 | }
19 | }
20 |
21 | void handleConfigSelection(char input, BaudRate &baudRate, uint8_t &rxPin, uint8_t &txPin,
22 | uint8_t &dataBits, ParityType &parity, uint8_t &stopBits,
23 | bool &flowControl, bool &inverted, uint8_t selectedIndex) {
24 | if (input != KEY_OK) return;
25 |
26 | switch (selectedIndex) {
27 | case RXPIN_INDEX:
28 | case TXPIN_INDEX:
29 | rxPin = (rxPin == 1) ? 2 : 1;
30 | txPin = (txPin == 1) ? 2 : 1;
31 | break;
32 | case BAUD_INDEX:
33 | baudRate = static_cast((baudRate == BAUDRATE_COUNT - 1) ? 0 : baudRate + 1);
34 | break;
35 | case BITS_INDEX:
36 | dataBits = (dataBits < 8) ? dataBits + 1 : 5;
37 | break;
38 | case PARITY_INDEX:
39 | parity = static_cast((parity == PARITY_COUNT - 1) ? 0 : parity + 1);
40 | break;
41 | case STOP_BITS_INDEX:
42 | stopBits = (stopBits == 1) ? 2 : 1;
43 | break;
44 | case FLOW_CONTROL_INDEX:
45 | flowControl = !flowControl;
46 | break;
47 | case INVERTED_INDEX:
48 | inverted = !inverted;
49 | break;
50 | default:
51 | break;
52 | }
53 | }
54 |
55 | void handlePrompt(std::atomic &sendDataFlag, std::string &sendString,
56 | std::atomic &running, std::mutex &sendMutex) {
57 | while (running) {
58 | char input = promptInputHandler();
59 |
60 | switch (input) {
61 | case KEY_NONE:
62 | break;
63 | case KEY_OK:
64 | sendDataFlag = true;
65 | break;
66 | case KEY_DEL:
67 | {
68 | std::lock_guard lock(sendMutex);
69 | if (!sendString.empty()) {
70 | sendString.pop_back();
71 | }
72 | }
73 | break;
74 | default:
75 | {
76 | std::lock_guard lock(sendMutex);
77 | sendString += input;
78 | }
79 | break;
80 | }
81 | delay(30);
82 | }
83 | }
--------------------------------------------------------------------------------
/src/event.h:
--------------------------------------------------------------------------------
1 | #ifndef EVENT_H
2 | #define EVENT_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include "serial.h"
8 | #include "input.h"
9 |
10 | enum ConfigIndex {
11 | RXPIN_INDEX = 0,
12 | TXPIN_INDEX,
13 | BAUD_INDEX,
14 | BITS_INDEX,
15 | PARITY_INDEX,
16 | STOP_BITS_INDEX,
17 | FLOW_CONTROL_INDEX,
18 | INVERTED_INDEX,
19 | LAUNCH_INDEX,
20 | };
21 |
22 | uint8_t handleIndexSelection(char input, uint8_t currentIndex);
23 | void handleConfigSelection(char input, BaudRate &baudRate, uint8_t &rxPin, uint8_t &txPin,
24 | uint8_t &dataBits, ParityType &parity, uint8_t &stopBits,
25 | bool &flowControl, bool &inverted, uint8_t selectedIndex);
26 | void handlePrompt(std::atomic &sendDataFlag, std::string &sendString,
27 | std::atomic &running, std::mutex &sendMutex);
28 | #endif
--------------------------------------------------------------------------------
/src/input.cpp:
--------------------------------------------------------------------------------
1 | #include "input.h"
2 |
3 | char configInputHandler() {
4 | // Update keyboard state
5 | M5Cardputer.update();
6 |
7 | if (M5Cardputer.Keyboard.isChange()) {
8 |
9 | if (M5Cardputer.Keyboard.isPressed()) {
10 | Keyboard_Class::KeysState status = M5Cardputer.Keyboard.keysState();
11 |
12 | if (status.enter) {
13 | return KEY_OK;
14 | }
15 | if(M5Cardputer.Keyboard.isKeyPressed(KEY_ARROW_LEFT)) {
16 | return KEY_ARROW_LEFT;
17 | }
18 | if(M5Cardputer.Keyboard.isKeyPressed(KEY_ARROW_RIGHT)) {
19 | return KEY_ARROW_RIGHT;
20 | }
21 | if(M5Cardputer.Keyboard.isKeyPressed(KEY_ARROW_UP)) {
22 | return KEY_ARROW_UP;
23 | }
24 | if(M5Cardputer.Keyboard.isKeyPressed(KEY_ARROW_DOWN)) {
25 | return KEY_ARROW_DOWN;
26 | }
27 | }
28 | delay(10); // debounce
29 | }
30 | return KEY_NONE;
31 | }
32 |
33 | char promptInputHandler() {
34 | // Update keyboard state
35 | M5Cardputer.update();
36 |
37 | // Bouton G0
38 | if (M5Cardputer.BtnA.isPressed()) {
39 | delay(100); // debounce
40 | return KEY_RETURN;
41 | }
42 |
43 | if (M5Cardputer.Keyboard.isChange()) {
44 |
45 | if (M5Cardputer.Keyboard.isPressed()) {
46 | Keyboard_Class::KeysState status = M5Cardputer.Keyboard.keysState();
47 |
48 | if (status.enter) {
49 | return KEY_OK;
50 | }
51 | else if (status.del) {
52 | return KEY_DEL;
53 | }
54 |
55 | for (auto c : status.word) {
56 | return c; // retourner le premier char saisi
57 | }
58 | }
59 | delay(10); // debounce
60 | }
61 | return KEY_NONE;
62 | }
--------------------------------------------------------------------------------
/src/input.h:
--------------------------------------------------------------------------------
1 | #ifndef INPUT_H
2 | #define INPUT_H
3 |
4 | #include
5 |
6 | #define KEY_OK '\n'
7 | #define KEY_DEL '\b'
8 | #define KEY_NONE '\0'
9 | #define KEY_RETURN '\r'
10 | #define KEY_ARROW_UP ';'
11 | #define KEY_ARROW_DOWN '.'
12 | #define KEY_ARROW_LEFT ','
13 | #define KEY_ARROW_RIGHT '/'
14 |
15 | char configInputHandler();
16 | char promptInputHandler();
17 | #endif
--------------------------------------------------------------------------------
/src/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #include "input.h"
6 | #include "display.h"
7 | #include "serial.h"
8 | #include "event.h"
9 |
10 | // Config
11 | BaudRate baudRate = BAUD_9600;
12 | uint8_t rxPin = 1;
13 | uint8_t txPin = 2;
14 | uint8_t dataBits = 8;
15 | ParityType parity = NONE;
16 | uint8_t stopBits = 1;
17 | bool flowControl = false;
18 | bool inverted = false;
19 | uint8_t selectedIndex = LAUNCH_INDEX;
20 |
21 | // Var atomic for input thread
22 | std::atomic sendDataFlag(false);
23 | std::atomic running(true);
24 |
25 | // Strings for serial send/receive
26 | std::string sendString;
27 | std::string receiveString;
28 |
29 | // Lock sendString for thread safe purpose
30 | std::mutex sendMutex;
31 |
32 | void config() {
33 | bool firstRender = true;
34 | while (true) {
35 | char input = configInputHandler();
36 | selectedIndex = handleIndexSelection(input, selectedIndex);
37 | handleConfigSelection(input, baudRate, rxPin, txPin, dataBits, parity, stopBits, flowControl, inverted, selectedIndex);
38 |
39 | if (input != KEY_NONE || firstRender) {
40 | displayConfig(baudRateToInt(baudRate), rxPin, txPin, dataBits, parityToString(parity), stopBits, flowControl, inverted, selectedIndex);
41 | firstRender = false;
42 | }
43 |
44 | // If user presses the start button, we leave config screen
45 | if (input == KEY_OK && selectedIndex == LAUNCH_INDEX) {
46 | displayClearMainView();
47 | running = true;
48 | break;
49 | }
50 | }
51 | }
52 |
53 | void terminal() {
54 | int16_t promptSize = -1;
55 | int16_t terminalSize = -1;
56 |
57 | // Limit serial read per iteration
58 | const int maxReadSize = 1024;
59 | char buffer[maxReadSize + 1];
60 |
61 | while (running) {
62 |
63 | if (Serial1.available()) {
64 | int bytesRead = Serial1.readBytes(buffer, maxReadSize);
65 | buffer[bytesRead] = '\0';
66 |
67 | if (receiveString.size() > maxReadSize) {
68 | // Only keep last chars
69 | receiveString.erase(0, receiveString.size() - maxReadSize);
70 | terminalSize = -1; // trigger screen render
71 | }
72 |
73 | receiveString += std::string(buffer);
74 | }
75 |
76 | if (sendDataFlag) {
77 | Serial1.println(sendString.c_str());
78 | sendDataFlag = false;
79 | std::lock_guard lock(sendMutex);
80 | sendString.clear();
81 | }
82 |
83 | if (terminalSize != receiveString.size()) {
84 | displayTerminal(receiveString);
85 | terminalSize = receiveString.size();
86 | }
87 |
88 | if (promptSize != sendString.size()) {
89 | displayPrompt(sendString);
90 | promptSize = sendString.size();
91 | }
92 | }
93 | }
94 |
95 | void setup() {
96 | auto cfg = M5.config();
97 | M5Cardputer.begin(cfg);
98 |
99 | displayInit();
100 | displayWelcome();
101 | delay(2000);
102 |
103 | // Serial config
104 | config();
105 | auto serialConfig = serialGetConfig(dataBits, parity, stopBits, flowControl);
106 | Serial.begin(9600); // for some reason, we have to init Serial to make Serial1 works
107 | Serial1.begin(baudRateToInt(baudRate), serialConfig, rxPin, txPin);
108 | Serial1.setTimeout(100); // Timeout for readBytes
109 |
110 | // Prompt thread
111 | std::thread inputThread(handlePrompt, std::ref(sendDataFlag), std::ref(sendString),
112 | std::ref(running), std::ref(sendMutex));
113 | inputThread.detach();
114 | }
115 |
116 | void loop() {
117 | terminal();
118 | }
--------------------------------------------------------------------------------
/src/serial.cpp:
--------------------------------------------------------------------------------
1 | #include "serial.h"
2 |
3 | std::string parityToString(ParityType parity) {
4 | switch (parity) {
5 | case NONE:
6 | return "None";
7 | case ODD:
8 | return "Odd";
9 | case EVEN:
10 | return "Even";
11 | default:
12 | return "Unknown";
13 | }
14 | }
15 |
16 | int baudRateToInt(BaudRate baud) {
17 | switch (baud) {
18 | case BAUD_9600:
19 | return 9600;
20 | case BAUD_14400:
21 | return 14400;
22 | case BAUD_19200:
23 | return 19200;
24 | case BAUD_38400:
25 | return 38400;
26 | case BAUD_57600:
27 | return 57600;
28 | case BAUD_115200:
29 | return 115200;
30 | case BAUD_230400:
31 | return 230400;
32 | case BAUD_460800:
33 | return 460800;
34 | case BAUD_921600:
35 | return 921600;
36 | default:
37 | return -1;
38 | }
39 | }
40 |
41 | SerialMode serialGetConfig(uint8_t dataBits, ParityType parity, uint8_t stopBits, bool flowControl) {
42 | SerialMode config = M_SERIAL_8N1;
43 |
44 | // Bits
45 | switch (dataBits) {
46 | case 5:
47 | config = (stopBits == 1) ? M_SERIAL_5N1 : M_SERIAL_5N2;
48 | break;
49 | case 6:
50 | config = (stopBits == 1) ? M_SERIAL_6N1 : M_SERIAL_6N2;
51 | break;
52 | case 7:
53 | config = (stopBits == 1) ? M_SERIAL_7N1 : M_SERIAL_7N2;
54 | break;
55 | case 8:
56 | config = (stopBits == 1) ? M_SERIAL_8N1 : M_SERIAL_8N2;
57 | break;
58 | }
59 |
60 | // Parity
61 | if (parity == ODD) {
62 | config = static_cast(config | 0x1);
63 | } else if (parity == EVEN) {
64 | config = static_cast(config | 0x2);
65 | }
66 |
67 | if (flowControl) {
68 | // TODO: Should we handle this ?
69 | }
70 |
71 | return config;
72 | }
73 |
74 |
--------------------------------------------------------------------------------
/src/serial.h:
--------------------------------------------------------------------------------
1 | #ifndef SERIAL_H
2 | #define SERIAL_H
3 |
4 | #include
5 |
6 | enum SerialMode {
7 | M_SERIAL_5N1 = 0x8000010,
8 | M_SERIAL_6N1 = 0x8000014,
9 | M_SERIAL_7N1 = 0x8000018,
10 | M_SERIAL_8N1 = 0x800001c,
11 | M_SERIAL_5N2 = 0x8000030,
12 | M_SERIAL_6N2 = 0x8000034,
13 | M_SERIAL_7N2 = 0x8000038,
14 | M_SERIAL_8N2 = 0x800003c,
15 | M_SERIAL_5E1 = 0x8000012,
16 | M_SERIAL_6E1 = 0x8000016,
17 | M_SERIAL_7E1 = 0x800001a,
18 | M_SERIAL_8E1 = 0x800001e,
19 | M_SERIAL_5E2 = 0x8000032,
20 | M_SERIAL_6E2 = 0x8000036,
21 | M_SERIAL_7E2 = 0x800003a,
22 | M_SERIAL_8E2 = 0x800003e,
23 | M_SERIAL_5O1 = 0x8000013,
24 | M_SERIAL_6O1 = 0x8000017,
25 | M_SERIAL_7O1 = 0x800001b,
26 | M_SERIAL_8O1 = 0x800001f,
27 | M_SERIAL_5O2 = 0x8000033,
28 | M_SERIAL_6O2 = 0x8000037,
29 | M_SERIAL_7O2 = 0x800003b,
30 | M_SERIAL_8O2 = 0x800003f
31 | };
32 |
33 | enum ParityType {
34 | NONE,
35 | ODD,
36 | EVEN,
37 | PARITY_COUNT
38 | };
39 | std::string parityToString(ParityType parity);
40 |
41 | enum BaudRate {
42 | BAUD_9600,
43 | BAUD_14400,
44 | BAUD_19200,
45 | BAUD_38400,
46 | BAUD_57600,
47 | BAUD_115200,
48 | BAUD_230400,
49 | BAUD_460800,
50 | BAUD_921600,
51 | BAUDRATE_COUNT
52 | };
53 | int baudRateToInt(BaudRate baud);
54 |
55 | SerialMode serialGetConfig(uint8_t dataBits, ParityType parity, uint8_t stopBits, bool flowControl);
56 |
57 | #endif
58 |
--------------------------------------------------------------------------------