From 2a621fbaf9d90ef76c38b4825023d3c3e20e47d0 Mon Sep 17 00:00:00 2001 From: hg Date: Thu, 5 Jun 2014 19:32:34 +0200 Subject: [PATCH] uart stuff --- src/main.cpp | 14 +++--- src/uart.cpp | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/uart.h | 22 +++++++++ 3 files changed, 154 insertions(+), 8 deletions(-) create mode 100644 src/uart.cpp create mode 100644 src/uart.h diff --git a/src/main.cpp b/src/main.cpp index 7e346c8..4608656 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,15 +10,8 @@ #include #include -void delay(uint16_t c) { - volatile uint16_t i = c; - while (i--); -} +#include "uart.h" -/* -#pragma vector = TIMER0_A0_VECTOR -__interrupt void TA0_ISR() { -*/ ISR(TIMER0_A0, TA0_ISR) { static uint8_t state = 0; @@ -45,8 +38,13 @@ int main() { TACCR0 = 1000; TACCTL0 = CCIE; TACTL = MC_1 | ID_0 | TASSEL_1 | TACLR; + + uartInit(); + __enable_interrupt(); + uartWrite('W'); + while (1) { __bis_status_register(LPM0_bits); } diff --git a/src/uart.cpp b/src/uart.cpp new file mode 100644 index 0000000..ca8ac34 --- /dev/null +++ b/src/uart.cpp @@ -0,0 +1,126 @@ +#include +#include +#include + +#include "uart.h" + + + +volatile uint8_t txBuffer[UART_TX_BUFFER_SIZE+5]; + +volatile uint8_t txBufferReadIdx = 0; +volatile uint8_t txBufferWriteIdx = 0; + +volatile uint8_t rxBuffer[UART_RX_BUFFER_SIZE+5]; +volatile uint8_t rxBufferReadIdx = 0; +volatile uint8_t rxBufferWriteIdx = 0; + + +static inline void enableDataRegisterEmptyInterrupt() { + IE2 |= UCA0TXIE; +} + +static inline void disableDataRegisterEmptyInterrupt() { + IE2 &= ~UCA0TXIE; +} + +void uartInit() { + UCA0CTL1 |= UCSWRST; + + UCA0CTL1 |= UCSSEL0; // ACLK + + UCA0BR0 = 13; + UCA0BR1 = 0; + + UCA0MCTL = UCBRS1 | UCBRS2; + + UCA0CTL1 &= ~UCSWRST; + + IE2 |= UCA0RXIE; + + +// FILE *mystdout = fdevopen(uartPutchar, NULL); +// stdout = mystdout; +} + +void uartWrite(uint8_t o) { + if (txBufferWriteIdx == (UART_TX_BUFFER_SIZE - 1)) { + while (txBufferReadIdx == UART_TX_BUFFER_SIZE); + } else { + while (txBufferReadIdx == (txBufferWriteIdx + 1)); + } + + txBuffer[txBufferWriteIdx] = o; + txBufferWriteIdx++; + + if (txBufferWriteIdx > UART_TX_BUFFER_SIZE) { + txBufferWriteIdx = 0; + } + + enableDataRegisterEmptyInterrupt(); +} + + +//int uartPutchar(char c, FILE *stream) { +// if (c == '\n') +// uartPutchar('\r', stream); +// uartWrite((uint8_t) c); +// return 0; +//} + + +ISR(USCIAB0TX, UART_TX_ISR) { + if ((IFG2 | UCA0TXIE) != 0) { + if (txBufferReadIdx != txBufferWriteIdx) { + UCA0TXBUF = txBuffer[txBufferReadIdx]; + txBufferReadIdx++; + if (txBufferReadIdx > UART_TX_BUFFER_SIZE) { + txBufferReadIdx = 0; + } + } else { + disableDataRegisterEmptyInterrupt(); + } + } +} + +ISR(USCIAB0RX, UART_RX_ISR) { + if ((IFG2 | UCA0RXIE) != 0) { + if (rxBufferWriteIdx == UART_RX_BUFFER_SIZE - 1) { + if (rxBufferReadIdx == UART_RX_BUFFER_SIZE) { + // rx buffer overflow + } + } else { + if (rxBufferReadIdx == rxBufferWriteIdx + 1) { + // rx buffer overflow + } + } + + rxBuffer[rxBufferWriteIdx] = UCA0RXBUF; + rxBufferWriteIdx++; + + if (rxBufferWriteIdx > UART_RX_BUFFER_SIZE) { + rxBufferWriteIdx = 0; + } + } +} + +uint8_t uartHasChar() { + return rxBufferWriteIdx != rxBufferReadIdx; +} + +uint8_t uartGetChar() { + uint8_t c = rxBuffer[rxBufferReadIdx]; + rxBufferReadIdx++; + if (rxBufferReadIdx > UART_RX_BUFFER_SIZE) { + rxBufferReadIdx = 0; + } + return c; +} + +int uartRead() { + int res = -1; + if (uartHasChar()) { + res = uartGetChar(); + } + return res; +} diff --git a/src/uart.h b/src/uart.h new file mode 100644 index 0000000..185b9b2 --- /dev/null +++ b/src/uart.h @@ -0,0 +1,22 @@ +#ifndef UART_H_ +#define UART_H_ + +#include +// #include + + + +#define UART_TX_BUFFER_SIZE 32 +#define UART_RX_BUFFER_SIZE 32 + + +void uartInit(); +// int uartPutchar(char c, FILE *stream); +void uartWrite(uint8_t o); + +uint8_t uartHasChar(); +uint8_t uartGetChar(); + +int uartRead(); + +#endif /* UART_H_ */