diff options
Diffstat (limited to 'hal')
-rw-r--r-- | hal/uart.hpp | 4 | ||||
-rw-r--r-- | hal/uart.tpp | 57 |
2 files changed, 46 insertions, 15 deletions
diff --git a/hal/uart.hpp b/hal/uart.hpp index 096ac7b..0be5835 100644 --- a/hal/uart.hpp +++ b/hal/uart.hpp @@ -43,8 +43,8 @@ namespace uart tx_empty = 1<<4, }; - std::queue<uint8_t> rx_buffer[devices_count]; - std::queue<uint8_t> tx_buffer[devices_count]; + std::queue<uint8_t> _rx_buffer[devices_count]; + std::queue<uint8_t> _tx_buffer[devices_count]; template<unsigned dev> void initialize(); diff --git a/hal/uart.tpp b/hal/uart.tpp index 8c120ec..e4b722e 100644 --- a/hal/uart.tpp +++ b/hal/uart.tpp @@ -26,22 +26,22 @@ extern "C" { namespace uart { template<unsigned dev> - bool rx_buffer_empty() + inline std::queue<uint8_t>& rx_buffer() { - return rx_buffer[dev -1].empty(); + return uart::_rx_buffer[dev -1]; } template<unsigned dev> - bool tx_buffer_full() + inline std::queue<uint8_t>& tx_buffer() { - return !tx_buffer[dev -1].empty(); + return uart::_tx_buffer[dev -1]; } template<unsigned dev> uint8_t read() { - uint8_t byte = rx_buffer[dev -1].front(); - rx_buffer[dev -1].pop(); + uint8_t byte = rx_buffer<dev>().front(); + rx_buffer<dev>().pop(); return byte; } @@ -51,7 +51,7 @@ namespace uart { uint8_t *bptr = buffer; unsigned len = numbytes; - + while (len--) { *(bptr++) = read<dev>(); } @@ -60,12 +60,20 @@ namespace uart template<unsigned dev> void write(const uint8_t byte) { + // disable send data flag + IEC1bits.U1TXIE = 0; + + tx_buffer<dev>().push(byte); + // enable send data flag + IEC1bits.U1TXIE = 1; } template<unsigned dev> void write(const std::string &str) { + // 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); } @@ -74,7 +82,12 @@ namespace uart template<unsigned dev> unsigned write(const uint8_t *buffer, const unsigned numbytes) { + uint8_t *bptr = buffer; + unsigned len = numbytes; + while (len--) { + write<dev>(*(bptr++)); + } } } @@ -83,26 +96,44 @@ namespace uart // debug #include "pin.tpp" -pin<2> led_blue(&LATBbits, &TRISBbits, &PORTEbits); +pin<2> led_blue(&LATBbits, &TRISBbits, &PORTBbits); +pin<3> led_green(&LATBbits, &TRISBbits, &PORTBbits); void __ISR(_UART_1_VECTOR, IPL1AUTO) usart_1_isr() { if (IFS1bits.U1RXIF) { // debug led_blue.toggle(); - while (U1STAbits.URXDA) { - uart::rx_buffer[0].push(static_cast<uint8_t>(U1RXREG)); - } + + // wait for data to be available + while (!U1STAbits.URXDA); + uart::rx_buffer<1>().push(static_cast<uint8_t>(U1RXREG)); IFS1bits.U1RXIF = 0; - } else if (IFS1bits.U1TXIF) { + + } + // 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; + } + + led_green.toggle(); + + // write data + U1TXREG = static_cast<decltype(U1TXREG)>(uart::tx_buffer<1>().front()); + uart::tx_buffer<1>().pop(); + IFS1bits.U1TXIF = 0; + } else { if (U1STAbits.OERR == 1) { U1STAbits.OERR = 0; } - IFS1bits.U1TXIF = 0; + IFS1bits.U1EIF = 0; } } |