summaryrefslogtreecommitdiffstats
path: root/hal/uart.tpp
diff options
context:
space:
mode:
Diffstat (limited to 'hal/uart.tpp')
-rw-r--r--hal/uart.tpp75
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 {