summaryrefslogtreecommitdiffstats
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
parentImplement most of basic HAL (diff)
downloadSAMLiquidSmoke-e68e31de1c419fe4e500cdf1d0f8ca6de2964dcc.tar.gz
SAMLiquidSmoke-e68e31de1c419fe4e500cdf1d0f8ca6de2964dcc.zip
Implement uart TX features
-rw-r--r--hal/uart.hpp4
-rw-r--r--hal/uart.tpp57
-rw-r--r--main.cpp20
3 files changed, 57 insertions, 24 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;
}
}
diff --git a/main.cpp b/main.cpp
index 119e5ce..d95bc74 100644
--- a/main.cpp
+++ b/main.cpp
@@ -5,8 +5,7 @@
* Created on May 1, 2018, 6:18 PM
*/
-#include <stdio.h>
-#include <stdlib.h>
+#include <string>
// basic devices
#include "hal/confbits.hpp"
@@ -18,7 +17,7 @@
extern "C" {
#include <xc.h>
- #include <proc/p32mx470f512h.h>
+ // #include <proc/p32mx470f512h.h>
}
@@ -36,15 +35,18 @@ int main(int argc, char** argv)
led1.set(1);
led2.set(1);
led3.set(1);
+
+ uart::write<1>("started\n\r");
while (true) {
- while (uart::rx_buffer_empty<1>());
-// while (!uart::rx_buffer_empty<1>()) {
-// uart::write<1>(uart::read<1>());
-// uart::write<1>("\n\rk")
-// }
+ while (uart::rx_buffer<1>().empty());
+
+ while (!uart::rx_buffer<1>().empty()) {
+ uint8_t c = uart::read<1>();
+ uart::write<1>(c);
+ uart::write<1>("\n\r");
+ }
- uart::read<1>();
led1.toggle();
}