diff options
author | Nao Pross <naopross@thearcway.org> | 2018-05-05 17:13:59 +0200 |
---|---|---|
committer | Nao Pross <naopross@thearcway.org> | 2018-05-05 17:13:59 +0200 |
commit | 601ee769f5ceeab7c71e61806804e4788f279c59 (patch) | |
tree | bc0479325be9e69b7039304deba663ad89422700 /hal/uart.tpp | |
parent | Add top comments (diff) | |
download | SAMLiquidSmoke-601ee769f5ceeab7c71e61806804e4788f279c59.tar.gz SAMLiquidSmoke-601ee769f5ceeab7c71e61806804e4788f279c59.zip |
Rename class pin to io_pin, add general gpio class, add uart echo
Diffstat (limited to '')
-rw-r--r-- | hal/uart.tpp | 75 |
1 files changed, 63 insertions, 12 deletions
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<unsigned dev> + inline bool echo(bool enabled) + { + static_assert(dev <= devices_count, "invalid device number"); + _echo[dev -1] = enabled; + } + + template<unsigned dev> + inline bool echo_enabled() + { + static_assert(dev <= devices_count, "invalid device number"); + return _echo[dev -1]; + } // read from serial device template<unsigned dev> @@ -51,6 +64,17 @@ namespace uart return byte; } + template<unsigned dev> + uint8_t read_wait() + { + while (rx_buffer<dev>().empty()); + + uint8_t byte = rx_buffer<dev>().front(); + rx_buffer<dev>().pop(); + + return byte; + } + #if 0 template<unsigned dev> std::string read(const unsigned len) @@ -121,11 +145,21 @@ namespace uart template<unsigned dev> 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<dev>(c); + // for (const char &c : str) { + // write<dev>(c); + // } + + // disable send data flag + IEC1bits.U1TXIE = 0; + + for (int i = 0; i < str.size(); i++) { + tx_buffer<1>().push(static_cast<uint8_t>(str[i])); } + + // enable send data flag + IEC1bits.U1TXIE = 1; } template<unsigned dev> @@ -138,6 +172,13 @@ namespace uart write<dev>(*(bptr++)); } } + + template<unsigned dev> + void print(const std::string &str) + { + write<dev>(str); + write<dev>("\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<uint8_t>(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<decltype(U1TXREG)>(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 { |