From bca8a6fd862753e358ef5ae546beceac533cc337 Mon Sep 17 00:00:00 2001 From: Romain Goyet Date: Mon, 27 Feb 2017 14:13:19 +0100 Subject: [PATCH] [ion] Add a console facility Change-Id: I34b406ae8589fdd2a5d6b826b34ac411359b58dc --- apps/hwtest/lowlevel/lowlevel.cpp | 98 +++---------------------------- ion/include/ion.h | 1 + ion/include/ion/console.h | 15 +++++ ion/src/device/Makefile | 1 + ion/src/device/console.cpp | 98 +++++++++++++++++++++++++++++++ ion/src/device/console.h | 31 ++++++++++ ion/src/device/device.cpp | 2 + 7 files changed, 155 insertions(+), 91 deletions(-) create mode 100644 ion/include/ion/console.h create mode 100644 ion/src/device/console.cpp create mode 100644 ion/src/device/console.h diff --git a/apps/hwtest/lowlevel/lowlevel.cpp b/apps/hwtest/lowlevel/lowlevel.cpp index 016266635..40ade73a9 100644 --- a/apps/hwtest/lowlevel/lowlevel.cpp +++ b/apps/hwtest/lowlevel/lowlevel.cpp @@ -1,88 +1,6 @@ #include #include -#include "../../../ion/src/device/regs/regs.h" - -// PB3 = UART1_RX = SWO -// PB6 = UART1_TX = QuadSPI NCS - -// On Rpi, from top to bottom -// 6 = GND -// 8 = TX -// 10 = RX - -constexpr USART uartPort = USART(1); - -void init_uart_port() { - RCC.APB2ENR()->setUSART1EN(true); - - GPIOB.MODER()->setMode(3, GPIO::MODER::Mode::AlternateFunction); - GPIOB.MODER()->setMode(6, GPIO::MODER::Mode::AlternateFunction); - - GPIOB.AFR()->setAlternateFunction(3, GPIO::AFR::AlternateFunction::AF7); - GPIOB.AFR()->setAlternateFunction(6, GPIO::AFR::AlternateFunction::AF7); - - uartPort.CR1()->setUE(true); - uartPort.CR1()->setTE(true); - uartPort.CR1()->setRE(true); - - // Set the Baud rate - // base clock = 16 MHz - // Baud rate = fAPB2/(16*USARTDIV) - // USARTDIV = 104.16667 - // - // DIV_Fraction = 16*0.16666667 - // = 2.666667 -> 3 - // DIV_Mantissa = 104 = 0x68 - // USART_BRR = 0x683 - uartPort.BRR()->setDIV_FRAC(3); - uartPort.BRR()->setDIV_MANTISSA(104); -} - -char uart_read_char() { - while (uartPort.SR()->getRXNE() == 0) { - } - return (char)uartPort.DR()->get(); -} - -void uart_write_char(char c) { - while (uartPort.SR()->getTXE() == 0) { - } - uartPort.DR()->set(c); -} - -bool readLine(char * buffer, int bufferSize) { - char * endBuffer = buffer + bufferSize - 1; - while (true) { - *buffer = uart_read_char(); - if (*buffer == NULL) { - /* Time for a comment : - * - Building DEBUG=0 might make the device fast enough - * - Reading on the HOST... ALSO sends data to the device !! - * So we were being overflowed with zeroes here... */ - continue; - } - if (*buffer == '\r') { - break; - } - buffer++; - if (buffer == endBuffer) { - return false; - } - } - *buffer = 0; - return true; -} - -void reply(const char * buffer) { - while (*buffer != NULL) { - uart_write_char(*buffer); - buffer++; - } - uart_write_char('\r'); - uart_write_char('\n'); -} - typedef void (*CommandFunction)(const char * input); void command_ping(const char * input); @@ -150,17 +68,17 @@ void CommandList::dispatch(const char * command) const { } handler++; } - reply("NOT_FOUND"); + Ion::Console::writeLine("NOT_FOUND"); } void command_ping(const char * input) { - reply("PONG"); + Ion::Console::writeLine("PONG"); } void command_mcu_serial(const char * input) { - reply("UNKNOWN"); + Ion::Console::writeLine("UNKNOWN"); } @@ -185,13 +103,13 @@ static inline uint32_t hexNumber(const char * s) { void command_led(const char * input) { // Input must be of the form "0xAABBCC" if (input == nullptr || input[0] != '0' || input[1] != 'x' || !isHex(input[2]) ||!isHex(input[3]) || !isHex(input[4]) || !isHex(input[5]) || !isHex(input[6]) || !isHex(input[7]) || input[8] != NULL) { - reply("SYNTAX_ERROR"); + Ion::Console::writeLine("SYNTAX_ERROR"); return; } uint32_t hexColor = hexNumber(input+2); KDColor ledColor = KDColor::RGB24(hexColor); Ion::LED::setColor(ledColor); - reply("OK"); + Ion::Console::writeLine("OK"); } constexpr CommandHandler handles[] = { @@ -205,12 +123,10 @@ constexpr const CommandList sCommandList = CommandList(handles); constexpr int kMaxCommandLength = 255; void ion_app() { - init_uart_port(); char command[kMaxCommandLength]; while (true) { - if (readLine(command, kMaxCommandLength)) { - sCommandList.dispatch(command); - } + Ion::Console::readLine(command, kMaxCommandLength); + sCommandList.dispatch(command); } } diff --git a/ion/include/ion.h b/ion/include/ion.h index 3c7b281ad..d15dbb4fe 100644 --- a/ion/include/ion.h +++ b/ion/include/ion.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include diff --git a/ion/include/ion/console.h b/ion/include/ion/console.h new file mode 100644 index 000000000..4f9600999 --- /dev/null +++ b/ion/include/ion/console.h @@ -0,0 +1,15 @@ +#ifndef ION_CONSOLE_H +#define ION_CONSOLE_H + +namespace Ion { +namespace Console { + +// The lines are NULL-terminated + +void writeLine(const char * line); +void readLine(char * line, int maxLineLength); + +} +} + +#endif diff --git a/ion/src/device/Makefile b/ion/src/device/Makefile index 986970daf..230131df6 100644 --- a/ion/src/device/Makefile +++ b/ion/src/device/Makefile @@ -7,6 +7,7 @@ objs += $(addprefix ion/src/shared/, \ objs += $(addprefix ion/src/device/, \ backlight.o \ battery.o\ + console.o \ device.o\ display.o\ keyboard.o\ diff --git a/ion/src/device/console.cpp b/ion/src/device/console.cpp new file mode 100644 index 000000000..febd68445 --- /dev/null +++ b/ion/src/device/console.cpp @@ -0,0 +1,98 @@ +#include +#include "console.h" + +/* This file implements a serial console. + * We use a 9600 8N1 serial port */ + +namespace Ion { +namespace Console { + +void writeLine(const char * line) { + while (*line != NULL) { + Device::sendChar(*line++); + } + Device::sendChar('\r'); + Device::sendChar('\n'); +} + +void readLine(char * line, int maxLineLength) { + if (maxLineLength <= 0) { + return; + } + char * cursor = line; + char * last = line+maxLineLength-1; + while (true) { + *cursor = Device::recvChar(); + if (*cursor == '\r' || cursor == last) { + *cursor = 0; + return; + } + cursor++; + } +} +/* + + lastChar + + char c = Device::recvChar(); + + char * lineEnd = line + maxLineLength; + + while (line < lineEnd) { + *line++ = Device::recvChar(); + if (*line == '\r') { + break; + } + } + *line = 0; +} +*/ + +} +} + +namespace Ion { +namespace Console { +namespace Device { + +void init() { + RCC.APB2ENR()->setUSART1EN(true); + + GPIOB.MODER()->setMode(3, GPIO::MODER::Mode::AlternateFunction); + GPIOB.MODER()->setMode(6, GPIO::MODER::Mode::AlternateFunction); + + GPIOB.AFR()->setAlternateFunction(3, GPIO::AFR::AlternateFunction::AF7); + GPIOB.AFR()->setAlternateFunction(6, GPIO::AFR::AlternateFunction::AF7); + + UARTPort.CR1()->setUE(true); + UARTPort.CR1()->setTE(true); + UARTPort.CR1()->setRE(true); + + // Set the Baud rate + // base clock = 16 MHz + // Baud rate = fAPB2/(16*USARTDIV) + // USARTDIV = 104.16667 + // + // DIV_Fraction = 16*0.16666667 + // = 2.666667 -> 3 + // DIV_Mantissa = 104 = 0x68 + // USART_BRR = 0x683 + UARTPort.BRR()->setDIV_FRAC(3); + UARTPort.BRR()->setDIV_MANTISSA(104); +} + +char recvChar() { + while (UARTPort.SR()->getRXNE() == 0) { + } + return (char)UARTPort.DR()->get(); +} + +void sendChar(char c) { + while (UARTPort.SR()->getTXE() == 0) { + } + UARTPort.DR()->set(c); +} + +} +} +} diff --git a/ion/src/device/console.h b/ion/src/device/console.h new file mode 100644 index 000000000..107fdf5ce --- /dev/null +++ b/ion/src/device/console.h @@ -0,0 +1,31 @@ +#ifndef ION_DEVICE_CONSOLE_H +#define ION_DEVICE_CONSOLE_H + +#include +#include "regs/regs.h" + +namespace Ion { +namespace Console { +namespace Device { + +/* Pin | Role | Mode + * -----+-------------------+-------------------- + * PC11 | UART1 RX | Alternate Function + * PD8 | UART1 TX | Alternate Function + */ + +void init(); +void shutdown(); + +constexpr USART UARTPort = USART(1); +constexpr static GPIOPin RxPin = GPIOPin(GPIOB, 14); +constexpr static GPIOPin TxPin = GPIOPin(GPIOE, 9); + +void sendChar(char c); +char recvChar(); + +} +} +} + +#endif diff --git a/ion/src/device/device.cpp b/ion/src/device/device.cpp index a71efd04f..e9a900932 100644 --- a/ion/src/device/device.cpp +++ b/ion/src/device/device.cpp @@ -10,6 +10,7 @@ extern "C" { #include "battery.h" #include "sd_card.h" #include "backlight.h" +#include "console.h" #define USE_SD_CARD 0 @@ -85,6 +86,7 @@ void initPeripherals() { #if USE_SD_CARD SDCard::Device::init(); #endif + Console::Device::init(); } void shutdownPeripherals() {