From e14f6bccd62b631c23fc595054bc163232eace86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?King=20K=C3=A9vin?= Date: Sun, 18 Feb 2018 15:20:01 +0100 Subject: [PATCH] cherry-pick from busvoodoo branch, part 2 --- .gitignore | 2 + Rakefile | 1 + application.c | 8 +- lib/terminal.c | 436 +++++++++++++++++++++++++++++++++++++++++++++++++ lib/terminal.h | 34 ++++ lib/uart.c | 12 +- lib/uart.h | 14 +- lib/usart.c | 148 ----------------- lib/usart.h | 47 ------ 9 files changed, 493 insertions(+), 209 deletions(-) create mode 100644 lib/terminal.c create mode 100644 lib/terminal.h delete mode 100644 lib/usart.c delete mode 100644 lib/usart.h diff --git a/.gitignore b/.gitignore index f694fc4..1720a1b 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,6 @@ *.elf *.bin *.swp +*.swo +.gdb_history doc/ diff --git a/Rakefile b/Rakefile index cad0c21..8216fd0 100644 --- a/Rakefile +++ b/Rakefile @@ -88,6 +88,7 @@ archflags = "-mthumb -mcpu=cortex-m3 -msoft-float" desc "compile firmwares" task :default => FIRMWARES +task :compile => FIRMWARES FIRMWARES.each do |firmware| desc "compile #{firmware} firmware" diff --git a/application.c b/application.c index be84e23..ed35d7d 100644 --- a/application.c +++ b/application.c @@ -98,7 +98,10 @@ static void process_command(char* str) // parse command if (0==strcmp(word,"h") || 0==strcmp(word,"help") || 0==strcmp(word,"?")) { printf("available commands:\n"); - printf("led [on|off|toggle]\n"); + printf("l|led [on|off|toggle]\n"); + printf("s|self-test\n"); + printf("p|pin-test\n"); + printf("r|reset\n"); } else if (0==strcmp(word,"l") || 0==strcmp(word,"led")) { word = strtok(NULL,delimiter); if (!word) { @@ -156,6 +159,9 @@ static void process_command(char* str) rtc_set_counter_val(time_rtc); // save time to internal RTC printf("date set\n"); } + } else if (0==strcmp(word,"r") || 0==strcmp(word,"reset")) { + scb_reset_system(); // reset device + while (true); // wait for the reset to happen } else { goto error; } diff --git a/lib/terminal.c b/lib/terminal.c new file mode 100644 index 0000000..feffe4e --- /dev/null +++ b/lib/terminal.c @@ -0,0 +1,436 @@ +/* This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +/** terminal prompt interface (code) + * @note allows line editing and supports some ANSI escape codes + * @file terminal.c + * @author King Kévin + * @date 2018 + */ +/* standard libraries */ +#include // standard integer types +#include // boolean type +#include // standard utilities +#include // string utilities + +/* own libraries */ +#include "global.h" // global definitions +#include "terminal.h" // own definitions +#include "print.h" // printing utilities + +char* terminal_prefix = NULL; +void (*terminal_process)(char* line) = NULL; + +/** buffer to store user input and keep history */ +static char terminal_buffer[16] = {0}; +/** how much of the buffer is user */ +static uint16_t terminal_end = 0; +/** current position in the buffer */ +static uint16_t terminal_pos = 0; +/** start position or current line in the buffer */ +static uint16_t terminal_line = 0; +/** is the current line the last one */ +static bool terminal_last = true; +/** currently inserting or replacing characters */ +static bool terminal_insert = true; +/** current escape code */ +static char escape_code[8] = {0}; +/** current position in the escape code */ +static uint8_t escape_pos = 0; + +/** remove one line from buffer start and shift rest to start + * @return if one line has been removed + */ +static bool terminal_remove_line(void) +{ + if (0==terminal_line) { // be sure we are currently not on the first line + return false; + } + uint16_t line_end = strlen(&terminal_buffer[0]); // get end of line + if (terminal_end<=line_end) { // be sure there is a line to delete + return false; + } + for (uint16_t i=line_end+1; i<=terminal_end && iline_end+1) { // update buffer end + terminal_end -= line_end+1; + } else { + terminal_end = 0; + } + if (terminal_pos>line_end+1) { // update buffer position + terminal_pos -= line_end+1; + } else { + terminal_pos = 0; + } + if (terminal_line>line_end+1) { // update line position + terminal_line -= line_end+1; + } else { + terminal_line = 0; + } + if (0==terminal_line) { // update if we are on the last line + terminal_last = true; + } + return true; +} + +/** shift with rotate current characters to other position + * @note this uses a recursive function + * @param[in] to_copy position of character(s) to shift + * @param[in] nb_copy number of characters to shift + * @param[in] to_shift where to shift the characters to + */ +static void terminal_shift_line(uint16_t to_copy, uint16_t nb_copy, uint16_t to_shift) +{ + char c = terminal_buffer[to_copy]; + terminal_buffer[to_copy] = terminal_buffer[to_shift]; + if (to_shift0 ? nb_copy-1 : 0, to_shift+1); // shift next character + } + if (nb_copy>0) { + terminal_buffer[terminal_end-nb_copy] = c; // place back + } +} + +/** copy current line to last line */ +static void terminal_copy_line(void) +{ + if (terminal_last) { // current line is already last line + return; // do nothing + } + uint16_t line_len = strlen(&terminal_buffer[terminal_line]); + while (terminal_end>=LENGTH(terminal_buffer)-line_len-1 && terminal_remove_line()); // delete line if not enough space + if (terminal_end2) { // number of cells provided + escape_code[escape_pos-1] = '\0'; // terminate string + n = atoi(&escape_code[1]); // get number of cells + } + while (n--) { // go up number of line + if (0==terminal_line) { // stop if we are already at the top line + break; + } + uint16_t terminal_line_new=0; // new line start + for (uint16_t pos=0; posterminal_line_new+strlen(&terminal_buffer[terminal_line_new])) { // position is outside of line + terminal_pos = terminal_line_new+strlen(&terminal_buffer[terminal_line_new]); // set new position to end of line + } + } + terminal_line = terminal_line_new; // set new line start + terminal_last = (terminal_end==terminal_line+strlen(&terminal_buffer[terminal_line])); // check if we are on the last line + } + } + break; + case 'B': // CUD - cursor down + { + uint16_t n = 1; // number of cells to move + if (escape_pos>2) { // number of cells provided + escape_code[escape_pos-1] = '\0'; // terminate string + n = atoi(&escape_code[1]); // get number of cells + } + while (n--) { // go down number of line + if (terminal_last) { // stop if we are already at the last line + break; + } + uint16_t terminal_line_new = terminal_line+strlen(&terminal_buffer[terminal_line])+1; // line start for the next line + if (terminal_pos==terminal_line+strlen(&terminal_buffer[terminal_line])) { // if the position is the end of the current line + terminal_pos=terminal_line_new+strlen(&terminal_buffer[terminal_line_new]); // set position to end of new line + } else { + terminal_pos += (terminal_line_new-terminal_line); // move position to new line + if (terminal_pos>terminal_line_new+strlen(&terminal_buffer[terminal_line_new])) { // position is outside of line + terminal_pos = terminal_line_new+strlen(&terminal_buffer[terminal_line_new]); // set new position to end of line + } + } + terminal_line = terminal_line_new; // set new line start + terminal_last = (terminal_end==terminal_line+strlen(&terminal_buffer[terminal_line])); // check if we are on the last line + } + } + break; + case 'C': // CUF - cursor forward + { + uint16_t n = 1; // number of cells to move + if (escape_pos>2) { // number of cells provided + escape_code[escape_pos-1] = '\0'; // terminate string + n = atoi(&escape_code[1]); // get number of cells + } + while (n--) { // go right number of moves + if (terminal_pos>=terminal_line+strlen(&terminal_buffer[terminal_line])) { // stop if we are already at the end + break; + } + terminal_pos++; + } + } + break; + case 'D': // CUB - cursor back + { + uint16_t n = 1; // number of cells to move + if (escape_pos>2) { // number of cells provided + escape_code[escape_pos-1] = '\0'; // terminate string + n = atoi(&escape_code[1]); // get number of cells + } + while (n--) { // go left number of moves + if (terminal_pos<=terminal_line) { // stop if we are already at the beginning + break; + } + terminal_pos--; + } + } + break; + case '~': // special key + if (3==escape_pos) { // we only expect one parameter bytes + switch (escape_code[1]) { + case '2': // insert + terminal_insert = !terminal_insert; // toggle insert/replace mode + break; + case '3': // delete + if (!terminal_last) { // we are not editing the last line + terminal_copy_line(); // make current line the last line + } + if (terminal_pos0) { + uint16_t terminal_line_new = 0; // set to first line + if (terminal_pos==terminal_line+strlen(&terminal_buffer[terminal_line])) { // if the position is the end of the current line + terminal_pos=terminal_line_new+strlen(&terminal_buffer[terminal_line_new]); // set position to end of new line + } else { + terminal_pos -= (terminal_line-terminal_line_new); // move position to new line + if (terminal_pos>terminal_line_new+strlen(&terminal_buffer[terminal_line_new])) { // position is outside of line + terminal_pos = terminal_line_new+strlen(&terminal_buffer[terminal_line_new]); // set new position to end of line + } + } + terminal_line = terminal_line_new; // set new line start + terminal_last = (terminal_end==terminal_line+strlen(&terminal_buffer[terminal_line])); // check if we are on the last line + } + break; + case '6': // page down + if (!terminal_last) { // stop if we are already at the last line + uint16_t terminal_line_new = terminal_line; // start last line search + for (uint16_t i=terminal_line_new; iterminal_line_new+strlen(&terminal_buffer[terminal_line_new])) { // position is outside of line + terminal_pos = terminal_line_new+strlen(&terminal_buffer[terminal_line_new]); // set new position to end of line + } + } + terminal_line = terminal_line_new; // set new line start + terminal_last = (terminal_end==terminal_line+strlen(&terminal_buffer[terminal_line])); // check if we are on the last line + } + break; + } + } + break; + default: // we don't handle other codes + break; // do nothing + } + break; + default: // we don't handle this code + break; // do nothing + } +} + +/** print current line and set position */ +static void terminal_print_line(void) +{ + printf("\r\x1b[K%s%s", terminal_prefix ? terminal_prefix : "", &terminal_buffer[terminal_line]); // erase line and display last one + if (terminal_pos=0x40 && c<=0x5f) { // data is in the right range + escape_code[0] = c; // save C1 + escape_pos++; // got to next position + } else { // this is not a C1 code + escape_pos = 0; // stop saving the escape code + terminal_send(c); // process data as non-escape code + } + } else { // after C1 we expect a parameters, intermediate, or final byte + if (c>=0x20 && c<=0x3f) { // received parameter (0x30-0x3f) or intermediate (0x20-0x2f) byte + if (escape_pos<=LENGTH(escape_code)) { + escape_code[escape_pos-1] = c; // save parameter byte + escape_pos++; // go to next position + } + } else if (c>=0x40 && c<=0x7f) { // received final byte + if (escape_pos<=LENGTH(escape_code)) { + escape_code[escape_pos-1] = c; // save final byte + } + terminal_process_escape(); // process escape code since we received the final byte + escape_pos = 0; // stop saving the escape code + terminal_print_line(); // print current line since if might have changed + } else { // this is not a expected byte + escape_pos = 0; // stop saving the escape code + terminal_send(c); // process data as non-escape code + } + } + } else { + if (0==c) { // string end received + terminal_print_line(); // only update line + } else if (0x1b==c) { // receiving new escape code (ESC) + escape_pos = 1; // start filling buffer + } else if (0x03==c) { // received CRTL+C + if (!terminal_last) { // we are not on the last line + uint16_t terminal_line_new = terminal_line; // start last line search + for (uint16_t i=terminal_line_new; i=LENGTH(terminal_buffer)-1 && terminal_remove_line()); // delete line if not enough space + if (terminal_end erase it + terminal_end = 0; // update end + } + terminal_buffer[terminal_end] = '\0'; // ensure end is terminated + } + terminal_pos = terminal_end; // set position to new line + terminal_line = terminal_end; // update line position + printf("\n"); // go to new line + terminal_print_line(); // print current empty line + } else { // all other bytes do some line editing + if (!terminal_last) { // we are not editing the last line + terminal_copy_line(); // make current line the last line + } + if ('\r'== c || '\n'==c) { // line finished + if ('\r'==newline_last && '\n'==c) { // windows newline received + // this newline has already been handled before + } else { + printf("\n"); // print new line + if (terminal_process) { + (*terminal_process)(&terminal_buffer[terminal_line]); // process line + } + if (strlen(&terminal_buffer[terminal_line])>0) { // only store non-empty line + while (terminal_end>=LENGTH(terminal_buffer)-1 && terminal_remove_line()); // delete line if not enough space + if (terminal_end erase it + terminal_end = 0; // update end + } + terminal_buffer[terminal_end] = '\0'; // ensure end is terminated + terminal_pos = terminal_end; // set position to new line + terminal_line = terminal_pos; // update line position + } + } + newline_last = c; // remember last character + } else if (0x7f==c) { // backspace + if (terminal_pos>terminal_line) { // we are not at the beginning of the line + for (uint16_t i=terminal_pos-1; i=LENGTH(terminal_buffer)-1 && terminal_remove_line()); // delete line if not enough space + if (terminal_end=terminal_pos; i--) { // shift buffer + terminal_buffer[i+1] = terminal_buffer[i]; + } + terminal_buffer[terminal_pos++] = c; // insert new character + terminal_buffer[++terminal_end] = '\0'; // update end + } + } else { // replace current character + while (terminal_pos==terminal_end && terminal_end>=LENGTH(terminal_buffer)-1 && terminal_remove_line()); // delete line if not enough space + terminal_buffer[terminal_pos] = c; // replace current character + if (terminal_posterminal_end) { // update end if it moved + terminal_end = terminal_pos; // move end + terminal_buffer[terminal_end] = '\0'; // ensure end is terminated + } + } + terminal_print_line(); // print current line + } + } +} + diff --git a/lib/terminal.h b/lib/terminal.h new file mode 100644 index 0000000..4bd108a --- /dev/null +++ b/lib/terminal.h @@ -0,0 +1,34 @@ +/* This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +/** terminal prompt interface (API) + * @note allows line editing and supports some ANSI escape codes + * @file terminal.h + * @author King Kévin + * @date 2018 + */ + +/** terminal prompt prefix */ +extern char* terminal_prefix; + +/** initialize terminal prompt */ +void terminal_setup(void); + +/** send character to terminal */ +void terminal_send(char c); + +/** called when a line is entered + * @param[in] line line entered by user (NULL on CTRL+D) + */ +extern void (*terminal_process)(char* line); diff --git a/lib/uart.c b/lib/uart.c index dfbc7ea..5049510 100644 --- a/lib/uart.c +++ b/lib/uart.c @@ -15,7 +15,7 @@ /** library for UART communication (code) * @file uart.c * @author King Kévin - * @date 2016 + * @date 2016-2017 * @note peripherals used: USART @ref uart */ @@ -34,19 +34,19 @@ #include "uart.h" // UART header and definitions #include "global.h" // common methods -/** @defgroup uart UART peripheral used for UART communication +/** @defgroup uart USART peripheral used for UART communication * @{ */ -#define UART_ID 1 /**< UART peripheral */ +#define UART_ID 1 /**< USART peripheral */ /** @} */ #define UART_BAUDRATE 921600 /**< serial baudrate, in bits per second (with 8N1 8 bits, no parity bit, 1 stop bit settings) */ /* input and output ring buffer, indexes, and available memory */ -static uint8_t rx_buffer[UART_BUFFER] = {0}; /**< ring buffer for received data */ +static volatile uint8_t rx_buffer[UART_BUFFER] = {0}; /**< ring buffer for received data */ static volatile uint8_t rx_i = 0; /**< current position of read received data */ static volatile uint8_t rx_used = 0; /**< how much data has been received and not red */ -static uint8_t tx_buffer[UART_BUFFER] = {0}; /**< ring buffer for data to transmit */ +static volatile uint8_t tx_buffer[UART_BUFFER] = {0}; /**< ring buffer for data to transmit */ static volatile uint8_t tx_i = 0; /**< current position of transmitted data */ static volatile uint8_t tx_used = 0; /**< how much data needs to be transmitted */ @@ -101,8 +101,8 @@ char uart_getchar(void) while (!rx_used) { // idle until data is available __WFI(); // sleep until interrupt } - char to_return = rx_buffer[rx_i]; // get the next available character usart_disable_rx_interrupt(USART(UART_ID)); // disable receive interrupt to prevent index corruption + volatile char to_return = rx_buffer[rx_i]; // get the next available character rx_i = (rx_i+1)%LENGTH(rx_buffer); // update used buffer rx_used--; // update used buffer uart_received = (rx_used!=0); // update available data diff --git a/lib/uart.h b/lib/uart.h index 8aa5501..4c10ab8 100644 --- a/lib/uart.h +++ b/lib/uart.h @@ -15,7 +15,7 @@ /** library for UART communication (API) * @file uart.h * @author King Kévin - * @date 2016 + * @date 2016-2018 * @note peripherals used: USART @ref uart */ #pragma once @@ -25,9 +25,9 @@ /** how many bytes available in the received buffer since last read */ extern volatile bool uart_received; -/** setup USART peripheral */ +/** setup UART peripheral */ void uart_setup(void); -/** send character over USART (blocking) +/** send character over UART (blocking) * @param[in] c character to send * @note blocks until character transmission started */ void uart_putchar_blocking(char c); @@ -35,12 +35,12 @@ void uart_putchar_blocking(char c); * @note block until all data has been transmitted */ void uart_flush(void); -/** get character received over USART (blocking) - * @return character received over USART - * @note blocks until character is received over USART when received buffer is empty +/** get character received over UART (blocking) + * @return character received over UART + * @note blocks until character is received over UART when received buffer is empty */ char uart_getchar(void); -/** send character over USART (non-blocking) +/** send character over UART (non-blocking) * @param[in] c character to send * @note blocks if transmit buffer is full, else puts in buffer and returns */ diff --git a/lib/usart.c b/lib/usart.c deleted file mode 100644 index 17794fd..0000000 --- a/lib/usart.c +++ /dev/null @@ -1,148 +0,0 @@ -/* This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -/** library for USART communication (code) - * @file usart.c - * @author King Kévin - * @date 2016 - * @note peripherals used: USART @ref usart - */ - -/* standard libraries */ -#include // standard integer types -#include // standard I/O facilities -#include // general utilities - -/* STM32 (including CM3) libraries */ -#include // real-time control clock library -#include // general purpose input output library -#include // universal synchronous asynchronous receiver transmitter library -#include // interrupt handler -#include // Cortex M3 utilities - -#include "usart.h" // USART header and definitions -#include "global.h" // common methods - -/** @defgroup usart USART peripheral used for UART communication - * @{ - */ -#define USART_ID 1 /**< USART peripheral */ -/** @} */ - -#define USART_BAUDRATE 921600 /**< serial baudrate, in bits per second (with 8N1 8 bits, no parity bit, 1 stop bit settings) */ - -/* input and output ring buffer, indexes, and available memory */ -static uint8_t rx_buffer[USART_BUFFER] = {0}; /**< ring buffer for received data */ -static volatile uint8_t rx_i = 0; /**< current position of read received data */ -static volatile uint8_t rx_used = 0; /**< how much data has been received and not red */ -static uint8_t tx_buffer[USART_BUFFER] = {0}; /**< ring buffer for data to transmit */ -static volatile uint8_t tx_i = 0; /**< current position of transmitted data */ -static volatile uint8_t tx_used = 0; /**< how much data needs to be transmitted */ - -volatile bool usart_received = false; - -void usart_setup(void) -{ - /* enable USART I/O peripheral */ - rcc_periph_clock_enable(USART_PORT_RCC(USART_ID)); // enable clock for USART port peripheral - rcc_periph_clock_enable(USART_RCC(USART_ID)); // enable clock for USART peripheral - rcc_periph_clock_enable(RCC_AFIO); // enable pin alternate function (USART) - gpio_set_mode(USART_PORT(USART_ID), GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, USART_PIN_TX(USART_ID)); // setup GPIO pin USART transmit - gpio_set_mode(USART_PORT(USART_ID), GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, USART_PIN_RX(USART_ID)); // setup GPIO pin USART receive - gpio_set(USART_PORT(USART_ID), USART_PIN_RX(USART_ID)); // pull up to avoid noise when not connected - - /* setup USART parameters */ - usart_set_baudrate(USART(USART_ID), USART_BAUDRATE); - usart_set_databits(USART(USART_ID), 8); - usart_set_stopbits(USART(USART_ID), USART_STOPBITS_1); - usart_set_mode(USART(USART_ID), USART_MODE_TX_RX); - usart_set_parity(USART(USART_ID), USART_PARITY_NONE); - usart_set_flow_control(USART(USART_ID), USART_FLOWCONTROL_NONE); - - nvic_enable_irq(USART_IRQ(USART_ID)); // enable the USART interrupt - usart_enable_rx_interrupt(USART(USART_ID)); // enable receive interrupt - usart_enable(USART(USART_ID)); // enable USART - - /* reset buffer states */ - tx_i = 0; - tx_used = 0; - rx_i = 0; - rx_used = 0; - usart_received = false; -} - -void usart_putchar_blocking(char c) -{ - usart_flush(); // empty buffer first - usart_send_blocking(USART(USART_ID), c); // send character -} - -void usart_flush(void) -{ - while (tx_used) { // idle until buffer is empty - __WFI(); // sleep until interrupt - } - usart_wait_send_ready(USART(USART_ID)); // wait until transmit register is empty (transmission might not be complete) -} - -char usart_getchar(void) -{ - while (!rx_used) { // idle until data is available - __WFI(); // sleep until interrupt - } - char to_return = rx_buffer[rx_i]; // get the next available character - usart_disable_rx_interrupt(USART(USART_ID)); // disable receive interrupt to prevent index corruption - rx_i = (rx_i+1)%LENGTH(rx_buffer); // update used buffer - rx_used--; // update used buffer - usart_received = (rx_used!=0); // update available data - usart_enable_rx_interrupt(USART(USART_ID)); // enable receive interrupt - return to_return; -} - -void usart_putchar_nonblocking(char c) -{ - while (tx_used>=LENGTH(tx_buffer)) { // idle until buffer has some space - usart_enable_tx_interrupt(USART(USART_ID)); // enable transmit interrupt - __WFI(); // sleep until something happened - } - usart_disable_tx_interrupt(USART(USART_ID)); // disable transmit interrupt to prevent index corruption - tx_buffer[(tx_i+tx_used)%LENGTH(tx_buffer)] = c; // put character in buffer - tx_used++; // update used buffer - usart_enable_tx_interrupt(USART(USART_ID)); // enable transmit interrupt -} - -/** USART interrupt service routine called when data has been transmitted or received */ -void USART_ISR(USART_ID)(void) -{ - if (usart_get_flag(USART(USART_ID), USART_SR_TXE)) { // data has been transmitted - if (!tx_used) { // no data in the buffer to transmit - usart_disable_tx_interrupt(USART(USART_ID)); // disable transmit interrupt - } else { - usart_send(USART(USART_ID),tx_buffer[tx_i]); // put data in transmit register - tx_i = (tx_i+1)%LENGTH(rx_buffer); // update location on buffer - tx_used--; // update used size - } - } - while (usart_get_flag(USART(USART_ID), USART_SR_RXNE)) { // data has been received (repeat while receiving) - char c = usart_recv(USART(USART_ID)); // save character and free USART buffer - // only save data if there is space in the buffer - if (rx_used>=LENGTH(rx_buffer)) { // if buffer is full - rx_i = (rx_i+1)%LENGTH(rx_buffer); // drop oldest data - rx_used--; // update used buffer information - } - rx_buffer[(rx_i+rx_used)%LENGTH(rx_buffer)] = c; // put character in buffer - rx_used++; // update used buffer - usart_received = true; // update available data - } -} diff --git a/lib/usart.h b/lib/usart.h deleted file mode 100644 index dddcadb..0000000 --- a/lib/usart.h +++ /dev/null @@ -1,47 +0,0 @@ -/* This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -/** library for USART communication (API) - * @file usart.h - * @author King Kévin - * @date 2016 - * @note peripherals used: USART @ref usart - */ -#pragma once - -/** transmit and receive buffer sizes */ -#define USART_BUFFER 128 -/** how many bytes available in the received buffer since last read */ -extern volatile bool usart_received; - -/** setup USART peripheral */ -void usart_setup(void); -/** send character over USART (blocking) - * @param[in] c character to send - * @note blocks until character transmission started */ -void usart_putchar_blocking(char c); -/** ensure all data has been transmitted (blocking) - * @note block until all data has been transmitted - */ -void usart_flush(void); -/** get character received over USART (blocking) - * @return character received over USART - * @note blocks until character is received over USART when received buffer is empty - */ -char usart_getchar(void); -/** send character over USART (non-blocking) - * @param[in] c character to send - * @note blocks if transmit buffer is full, else puts in buffer and returns - */ -void usart_putchar_nonblocking(char c);