diff options
author | Daniel Friesel <derf@finalrewind.org> | 2020-06-22 21:43:00 +0200 |
---|---|---|
committer | Daniel Friesel <derf@finalrewind.org> | 2020-06-22 21:43:00 +0200 |
commit | 9942173a2b46d5eb28fc41faf1627afc9929902d (patch) | |
tree | 6be86379dbb8e7684abf2b73509bd8babcb5ec4a /src/app/loratest/main.cc | |
parent | 7add7f43d77b5cd398a5e824dfae5bfd89c66268 (diff) |
loratest app. TODO: move SerialOutput and SerialInput to separate class
Or rather: TODO: make stdin/stdout configurable so it also works for eUSCI_A1.
Diffstat (limited to 'src/app/loratest/main.cc')
-rw-r--r-- | src/app/loratest/main.cc | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/src/app/loratest/main.cc b/src/app/loratest/main.cc new file mode 100644 index 0000000..5b03425 --- /dev/null +++ b/src/app/loratest/main.cc @@ -0,0 +1,165 @@ +#include "arch.h" +#include "driver/gpio.h" +#include "driver/stdout.h" + +class SerialOutput : public OutputStream { + private: + SerialOutput(const SerialOutput ©); + + public: + SerialOutput () {} + void setup(); + + virtual void put(char c) override; +}; + +/* + * Baud rate calculation according to datasheet: + * N := f_{BRCLK} / Baudrate = F_CPU / 115200 in our case + * if N <= 16: OS16 = 0, UCBR0 = int(N) + * if N > 16: OS16 = 1, UCBR0 = int(N/16), UCBRF0 = int(((n/16) - int(n/16)) * 16) = int(N)%16 + * Set UCBRS0 according to table 21-4 + */ + +void SerialOutput::setup() +{ + UCA1CTLW0 |= UCSWRST; +#if F_CPU == 16000000UL + // 16M / 9600 == 1666.6667 -> UCOS16 = 1, UCBR0 = 104, UCBRF0 = 2, UCBRS0 = 0xd6 ("0.6667") + UCA1CTLW0 = UCSWRST | UCSSEL__SMCLK; + UCA1MCTLW = UCOS16 | (2<<4) | 0xd600; + UCA1BR0 = 104; +#elif F_CPU == 8000000UL + // 8M / 9600 == 833.3333 -> UCOS16 = 1, UCBR0 = 52, UCBRF0 = 1, UCBRS0 = 0x49 ("0.3335") + UCA1CTLW0 = UCSWRST | UCSSEL__SMCLK; + UCA1MCTLW = UCOS16 | (1<<4) | 0x4900; + UCA1BR0 = 52; +#else +#error Unsupported F_CPU +#endif + + UCA1IRCTL = 0; + UCA1ABCTL = 0; + + P2REN &= ~(BIT5 | BIT6); + P2SEL0 &= ~(BIT5 | BIT6); + P2SEL1 |= BIT5 | BIT6; + + UCA1CTLW0 &= ~UCSWRST; + + //UCA1IE |= UCRXIE; +} + +void SerialOutput::put(char c) +{ + while (!(UCA1IFG & UCTXIFG)); + UCA1TXBUF = c; + + if (c == '\n') { + put('\r'); + } +} + +SerialOutput sout; + +class SerialInput { + private: + SerialInput(const SerialInput ©); + char buffer[64]; + unsigned char write_pos, read_pos; + + public: + SerialInput() : write_pos(0), read_pos(0) {} + void setup(); + bool hasKey(); + char getKey(); + + inline void addKey(char key) { + buffer[write_pos++] = key; + write_pos %= 64; + } +}; + +void SerialInput::setup() +{ + UCA1IE |= UCRXIE; +} + +bool SerialInput::hasKey() +{ + if (write_pos != read_pos) { + return true; + } + return false; +} + +char SerialInput::getKey() +{ + char ret = buffer[read_pos++]; + read_pos %= 64; + return ret; +} + +SerialInput sin; + +__attribute__((interrupt(USCI_A1_VECTOR))) __attribute__((wakeup)) void handle_stdin() +{ + if (UCA1IFG & UCRXIFG) { + sin.addKey(UCA1RXBUF); + } +} + +void loop(void) +{ + static unsigned int i = 0; + gpio.led_off(0); + // does not work on MSP430 3V3 + // works when connected to MSP430 5V0, AUX should be disconnected in that case + // RX seems to work best without intermittent TX + sout << "Hello! My value is " << i << endl; + if (sin.hasKey()) { + gpio.led_on(0); + kout << "RX: "; + while (sin.hasKey()) { + kout << sin.getKey(); + } + kout << endl; + } + i++; +} + +int main(void) +{ + arch.setup(); + gpio.setup(); + kout.setup(); + sout.setup(); + sin.setup(); + + gpio.led_on(1); + + // AUX + gpio.input(GPIO::p4_2); + + // set module to sleep mode + + // M0 + gpio.output(GPIO::p2_4, 1); + + // M1 + gpio.output(GPIO::p4_3, 1); + + arch.delay_ms(100); + sout << "\xc2\x00\x00\x1a\x17\x47"; + arch.delay_ms(50); + gpio.write(GPIO::p2_4, 0); + gpio.write(GPIO::p4_3, 0); + arch.delay_ms(10); + + gpio.led_off(1); + gpio.led_on(0); + + arch.idle_loop(); + + return 0; +} |