diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/arduino-nano/driver/dmx.cc | 6 | ||||
-rw-r--r-- | src/arch/msp430fr5969lp/Kconfig | 4 | ||||
-rw-r--r-- | src/arch/msp430fr5969lp/Makefile.inc | 4 | ||||
-rw-r--r-- | src/arch/msp430fr5969lp/driver/dmx.cc | 66 | ||||
-rw-r--r-- | src/arch/msp430fr5994lp/Kconfig | 4 | ||||
-rw-r--r-- | src/arch/msp430fr5994lp/Makefile.inc | 4 | ||||
-rw-r--r-- | src/arch/msp430fr5994lp/driver/dmx.cc | 66 |
7 files changed, 151 insertions, 3 deletions
diff --git a/src/arch/arduino-nano/driver/dmx.cc b/src/arch/arduino-nano/driver/dmx.cc index 20a7332..c18d5a8 100644 --- a/src/arch/arduino-nano/driver/dmx.cc +++ b/src/arch/arduino-nano/driver/dmx.cc @@ -23,7 +23,7 @@ void DMX::setup() #endif UCSR0B |= _BV(TXEN0); - UCSR0C = _BV(USBS0) | _BV(UCSZ01) | _BV(UCSZ00); // 8 bits + UCSR0C = _BV(USBS0) | _BV(UCSZ01) | _BV(UCSZ00); // MSB first, 8 data bits, 2 stop bits, no parity } void DMX::write() @@ -31,9 +31,9 @@ void DMX::write() // Disable UART for reset and mark signals UCSR0B &= ~_BV(TXEN0); gpio.output(GPIO::pd1, 0); - arch.delay_us(88); // break + arch.delay_us(88); // break / reset gpio.output(GPIO::pd1, 1); - arch.delay_us(8); + arch.delay_us(8); // mark UCSR0B |= _BV(TXEN0); // causes line to go high for (uint8_t i = 0; i < 16; i++) { while (!(UCSR0A & _BV(UDRE0))); diff --git a/src/arch/msp430fr5969lp/Kconfig b/src/arch/msp430fr5969lp/Kconfig index 80d74e4..008df31 100644 --- a/src/arch/msp430fr5969lp/Kconfig +++ b/src/arch/msp430fr5969lp/Kconfig @@ -9,6 +9,10 @@ config arch_msp430fr5969lp_driver_counter bool "Cycle Counter" select meta_driver_counter +config arch_msp430fr5969lp_driver_dmx +bool "DMX" +select meta_driver_dmx + config arch_msp430fr5969lp_driver_i2c bool "I2C on eUSCI_B0" select meta_driver_hardware_i2c diff --git a/src/arch/msp430fr5969lp/Makefile.inc b/src/arch/msp430fr5969lp/Makefile.inc index 98e7ad3..978696c 100644 --- a/src/arch/msp430fr5969lp/Makefile.inc +++ b/src/arch/msp430fr5969lp/Makefile.inc @@ -75,6 +75,10 @@ ifdef CONFIG_arch_msp430fr5969lp_driver_adc CXX_TARGETS += src/arch/msp430fr5969lp/driver/adc.cc endif +ifdef CONFIG_arch_msp430fr5969lp_driver_dmx + CXX_TARGETS += src/arch/msp430fr5969lp/driver/dmx.cc +endif + ifdef CONFIG_arch_msp430fr5969lp_driver_stdin CXX_TARGETS += src/arch/msp430fr5969lp/driver/stdin.cc endif diff --git a/src/arch/msp430fr5969lp/driver/dmx.cc b/src/arch/msp430fr5969lp/driver/dmx.cc new file mode 100644 index 0000000..162c2c7 --- /dev/null +++ b/src/arch/msp430fr5969lp/driver/dmx.cc @@ -0,0 +1,66 @@ +/* + * Copyright 2022 Daniel Friesel + * + * SPDX-License-Identifier: BSD-2-Clause + */ +#include <msp430.h> +#include "arch.h" +#include "driver/dmx.h" +#include "driver/gpio.h" + +/* + * 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 DMX::setup() +{ + UCA1CTLW0 |= UCSWRST; +#if F_CPU == 16000000UL + // 16M / 250000 == 64 -> UCOS16 = 1, UCBR0 = 4, UCBRF0 = 0, UCBRS0 = 0x00 + UCA1CTLW0 = UCSWRST | UCSPB | UCSSEL__SMCLK; // MSB first, 8 data bits, 2 stop bits + UCA1MCTLW = UCOS16; + UCA1BR0 = 4; +#else +#error Unsupported F_CPU +#endif + + UCA1IRCTL = 0; + UCA1ABCTL = 0; + + P2SEL0 &= ~BIT5; + P2SEL1 |= BIT5; + P2DIR |= BIT5; + + UCA1CTLW0 &= ~UCSWRST; +} + +void DMX::write() +{ + // Disable UART for reset and mark signals + UCA1CTLW0 |= UCSWRST; + P2SEL1 &= ~BIT5; + gpio.output(GPIO::p2_5, 0); + arch.delay_us(88); // break / reset + gpio.output(GPIO::p2_5, 1); + arch.delay_us(8); // mark + P2SEL1 |= BIT5; + UCA1CTLW0 &= ~UCSWRST; // causes line to go high + for (unsigned char i = 0; i < 16; i++) { + while (!(UCA1IFG & UCTXIFG)); + UCA1TXBUF = frames[i]; + } + for (unsigned char i = 0; i < 241; i++) { + while (!(UCA1IFG & UCTXIFG)); + UCA1TXBUF = 0; + } + for (unsigned char i = 0; i < 255; i++) { + while (!(UCA1IFG & UCTXIFG)); + UCA1TXBUF = 0; + } +} + +DMX dmx; diff --git a/src/arch/msp430fr5994lp/Kconfig b/src/arch/msp430fr5994lp/Kconfig index 73d8b57..b162154 100644 --- a/src/arch/msp430fr5994lp/Kconfig +++ b/src/arch/msp430fr5994lp/Kconfig @@ -9,6 +9,10 @@ config arch_msp430fr5994lp_driver_counter bool "Cycle Counter" select meta_driver_counter +config arch_msp430fr5994lp_driver_dmx +bool "DMX" +select meta_driver_dmx + config arch_msp430fr5994lp_driver_i2c bool "I2C on eUSCI_B1" select meta_driver_hardware_i2c diff --git a/src/arch/msp430fr5994lp/Makefile.inc b/src/arch/msp430fr5994lp/Makefile.inc index cd160a0..9eaab2e 100644 --- a/src/arch/msp430fr5994lp/Makefile.inc +++ b/src/arch/msp430fr5994lp/Makefile.inc @@ -90,6 +90,10 @@ ifdef CONFIG_arch_msp430fr5994lp_driver_adc CXX_TARGETS += src/arch/msp430fr5994lp/driver/adc.cc endif +ifdef CONFIG_arch_msp430fr5994lp_driver_dmx + CXX_TARGETS += src/arch/msp430fr5994lp/driver/dmx.cc +endif + ifdef CONFIG_arch_msp430fr5994lp_driver_stdin CXX_TARGETS += src/arch/msp430fr5994lp/driver/stdin.cc endif diff --git a/src/arch/msp430fr5994lp/driver/dmx.cc b/src/arch/msp430fr5994lp/driver/dmx.cc new file mode 100644 index 0000000..d032aaf --- /dev/null +++ b/src/arch/msp430fr5994lp/driver/dmx.cc @@ -0,0 +1,66 @@ +/* + * Copyright 2022 Daniel Friesel + * + * SPDX-License-Identifier: BSD-2-Clause + */ +#include <msp430.h> +#include "arch.h" +#include "driver/dmx.h" +#include "driver/gpio.h" + +/* + * 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 DMX::setup() +{ + UCA3CTLW0 |= UCSWRST; +#if F_CPU == 16000000UL + // 16M / 250000 == 64 -> UCOS16 = 1, UCBR0 = 4, UCBRF0 = 0, UCBRS0 = 0x00 + UCA3CTLW0 = UCSWRST | UCSPB | UCSSEL__SMCLK; // MSB first, 8 data bits, 2 stop bits + UCA3MCTLW = UCOS16; + UCA3BR0 = 4; +#else +#error Unsupported F_CPU +#endif + + UCA3IRCTL = 0; + UCA3ABCTL = 0; + + P6SEL0 |= BIT0; + P6SEL1 &= ~BIT0; + P6DIR |= BIT0; + + UCA3CTLW0 &= ~UCSWRST; +} + +void DMX::write() +{ + // Disable UART for reset and mark signals + UCA3CTLW0 |= UCSWRST; + P6SEL0 &= ~BIT0; + gpio.output(GPIO::p2_5, 0); + arch.delay_us(88); // break / reset + gpio.output(GPIO::p2_5, 1); + arch.delay_us(8); // mark + P6SEL0 |= BIT0; + UCA3CTLW0 &= ~UCSWRST; // causes line to go high + for (unsigned char i = 0; i < 16; i++) { + while (!(UCA3IFG & UCTXIFG)); + UCA3TXBUF = frames[i]; + } + for (unsigned char i = 0; i < 241; i++) { + while (!(UCA3IFG & UCTXIFG)); + UCA3TXBUF = 0; + } + for (unsigned char i = 0; i < 255; i++) { + while (!(UCA3IFG & UCTXIFG)); + UCA3TXBUF = 0; + } +} + +DMX dmx; |