summaryrefslogtreecommitdiffstats
path: root/hal
diff options
context:
space:
mode:
authorNao Pross <naopross@thearcway.org>2018-05-04 19:13:38 +0200
committerNao Pross <naopross@thearcway.org>2018-05-04 19:13:38 +0200
commite68e31de1c419fe4e500cdf1d0f8ca6de2964dcc (patch)
tree32547408c2f03da9552df7f1200457ea20ed7a7a /hal
parentImplement most of basic HAL (diff)
downloadSAMLiquidSmoke-e68e31de1c419fe4e500cdf1d0f8ca6de2964dcc.tar.gz
SAMLiquidSmoke-e68e31de1c419fe4e500cdf1d0f8ca6de2964dcc.zip
Implement uart TX features
Diffstat (limited to 'hal')
-rw-r--r--hal/uart.hpp4
-rw-r--r--hal/uart.tpp57
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;
}
}