From 601ee769f5ceeab7c71e61806804e4788f279c59 Mon Sep 17 00:00:00 2001 From: Nao Pross Date: Sat, 5 May 2018 17:13:59 +0200 Subject: Rename class pin to io_pin, add general gpio class, add uart echo --- hal/uart.tpp | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 63 insertions(+), 12 deletions(-) (limited to 'hal/uart.tpp') diff --git a/hal/uart.tpp b/hal/uart.tpp index 148ff7d..0ecd615 100644 --- a/hal/uart.tpp +++ b/hal/uart.tpp @@ -4,8 +4,8 @@ * * Created on May 2, 2018, 7:05 PM * - * Note: Templated functions cannot be created outside of a namespace definition - * because of a g++ bug in version 4.8.0 on which xc++ is based. + * Note: Templated functions inside a namespace cannot be created outside of a + * namespace because of a g++ bug in version 4.8.0 on which xc++ is based. * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480 */ @@ -40,6 +40,19 @@ namespace uart return uart::_tx_buffer[dev -1]; } + template + inline bool echo(bool enabled) + { + static_assert(dev <= devices_count, "invalid device number"); + _echo[dev -1] = enabled; + } + + template + inline bool echo_enabled() + { + static_assert(dev <= devices_count, "invalid device number"); + return _echo[dev -1]; + } // read from serial device template @@ -51,6 +64,17 @@ namespace uart return byte; } + template + uint8_t read_wait() + { + while (rx_buffer().empty()); + + uint8_t byte = rx_buffer().front(); + rx_buffer().pop(); + + return byte; + } + #if 0 template std::string read(const unsigned len) @@ -121,11 +145,21 @@ namespace uart template void write(const std::string &str) { - // TODO: if size of str is reasonale, push to queue AND THEN send + // TODO: if size of str is reasonale, push to queue AND THEN send, // right now on each call the interrupt is enabled and disabled - for (const char &c : str) { - write(c); + // for (const char &c : str) { + // write(c); + // } + + // disable send data flag + IEC1bits.U1TXIE = 0; + + for (int i = 0; i < str.size(); i++) { + tx_buffer<1>().push(static_cast(str[i])); } + + // enable send data flag + IEC1bits.U1TXIE = 1; } template @@ -138,6 +172,13 @@ namespace uart write(*(bptr++)); } } + + template + void print(const std::string &str) + { + write(str); + write("\n\r"); + } } @@ -145,8 +186,8 @@ namespace uart #ifdef DEBUG #include "pin.tpp" -pin<2> led_blue(&LATBbits, &TRISBbits, &PORTBbits); -pin<3> led_green(&LATBbits, &TRISBbits, &PORTBbits); +io_pin<2> led_blue(&LATBbits, &TRISBbits, &PORTBbits); +io_pin<3> led_green(&LATBbits, &TRISBbits, &PORTBbits); #endif void __ISR(_UART_1_VECTOR, IPL1AUTO) usart_1_isr() @@ -159,23 +200,33 @@ void __ISR(_UART_1_VECTOR, IPL1AUTO) usart_1_isr() while (!U1STAbits.URXDA); uart::rx_buffer<1>().push(static_cast(U1RXREG)); + // echo + if (uart::echo_enabled<1>()) { + // uart::write<1>(uart::rx_buffer<1>().front()); + IEC1bits.U1TXIE = 0; + uart::tx_buffer<1>().push(uart::rx_buffer<1>().front()); + IEC1bits.U1TXIE = 1; + } + IFS1bits.U1RXIF = 0; } // on each interrupt call, send one character else if (IFS1bits.U1TXIF) { - // if empty, disable send data flag - if (uart::tx_buffer<1>().empty()) { - IEC1bits.U1TXIE = 0; - return; - } + // disable TX interrupt flag + IEC1bits.U1TXIE = 0; led_green.toggle(); // write data U1TXREG = static_cast(uart::tx_buffer<1>().front()); uart::tx_buffer<1>().pop(); + // if not empty, enable tx flag + if (!uart::tx_buffer<1>().empty()) { + IEC1bits.U1TXIE = 1; + } + IFS1bits.U1TXIF = 0; } else { -- cgit v1.2.1