diff options
-rw-r--r-- | include/msp430fr5969lp/driver/spi.h | 18 | ||||
-rw-r--r-- | include/msp430fr5969lp/driver/spi_b.h | 18 | ||||
-rw-r--r-- | src/arch/msp430fr5969lp/driver/spi.cc | 61 | ||||
-rw-r--r-- | src/arch/msp430fr5969lp/driver/spi_b.cc | 58 |
4 files changed, 155 insertions, 0 deletions
diff --git a/include/msp430fr5969lp/driver/spi.h b/include/msp430fr5969lp/driver/spi.h new file mode 100644 index 0000000..8c593ee --- /dev/null +++ b/include/msp430fr5969lp/driver/spi.h @@ -0,0 +1,18 @@ +#ifndef SPI_H +#define SPI_H + +class SPI { + private: + SPI(const SPI ©); + + public: + SPI () {} + signed char setup(); + signed char xmit( + unsigned char tx_len, unsigned char *tx_buf, + unsigned char rx_len, unsigned char *rx_buf); +}; + +extern SPI spi; + +#endif diff --git a/include/msp430fr5969lp/driver/spi_b.h b/include/msp430fr5969lp/driver/spi_b.h new file mode 100644 index 0000000..8c593ee --- /dev/null +++ b/include/msp430fr5969lp/driver/spi_b.h @@ -0,0 +1,18 @@ +#ifndef SPI_H +#define SPI_H + +class SPI { + private: + SPI(const SPI ©); + + public: + SPI () {} + signed char setup(); + signed char xmit( + unsigned char tx_len, unsigned char *tx_buf, + unsigned char rx_len, unsigned char *rx_buf); +}; + +extern SPI spi; + +#endif diff --git a/src/arch/msp430fr5969lp/driver/spi.cc b/src/arch/msp430fr5969lp/driver/spi.cc new file mode 100644 index 0000000..981bc53 --- /dev/null +++ b/src/arch/msp430fr5969lp/driver/spi.cc @@ -0,0 +1,61 @@ +#include "driver/spi.h" +#include <msp430.h> + +signed char SPI::setup() +{ + /* UCA1CLK Pin 2.4 */ + P2SEL0 &= ~BIT4; + P2SEL1 |= BIT4; + P2DIR |= BIT4; + + /* UCA1SIMO Pin 2.5 */ + P2SEL0 &= ~BIT5; + P2SEL1 |= BIT5; + P2DIR |= BIT5; + + /* UCA1SOMI Pin 2.6 */ + P2SEL0 &= ~BIT6; + P2SEL1 |= BIT6; + P2DIR &= ~BIT6; + //P2REN |= BIT6; + + UCA1CTLW0 |= UCSWRST; + UCA1MCTLW = 0; // no modulation + + UCA1CTLW0 = UCCKPH | UCMSB | UCMST | UCSYNC | UCMODE_0 | UCSSEL__SMCLK | UCSWRST; + UCA1BRW = 15; // /16 -> 1MHz + UCA1CTLW0 &= ~UCSWRST; +} + +signed char SPI::xmit(unsigned char tx_len, unsigned char *tx_buf, + unsigned char rx_len, unsigned char *rx_buf) +{ + volatile char rxbuf_cache; + if (tx_len < 1) { + return -1; + } + + UCA1IE &= ~(UCTXIE | UCRXIE); + + while (UCA1STATW & UCBUSY) ; + + rxbuf_cache = UCA1RXBUF; + UCA1TXBUF = tx_buf[0]; + + unsigned char tx_pos = 1; + unsigned char rx_pos = 0; + + while (tx_pos < tx_len || rx_pos < rx_len) { + if ((tx_pos < tx_len) && (UCA1IF & UCTXIFG)) { + UCBA1TXBUF = tx_buf[tx_pos++]; + } + if (UCA1IFG & UCRXIFG) { + if (rx_pos < rx_len) { + rx_buf[rx_pos] = UCA1RXBUF; + } else { + rxbuf_cache = UCA1RXBUF; + } + } + rx_pos++; + } +} diff --git a/src/arch/msp430fr5969lp/driver/spi_b.cc b/src/arch/msp430fr5969lp/driver/spi_b.cc new file mode 100644 index 0000000..eafb94e --- /dev/null +++ b/src/arch/msp430fr5969lp/driver/spi_b.cc @@ -0,0 +1,58 @@ +#include "driver/spi.h" +#include <msp430.h> + +signed char SPI::setup() +{ + /* UCB0CLK Pin 2.2 */ + P2SEL0 &= ~BIT2; + P2SEL1 |= BIT2; + P2DIR |= BIT2; + + /* UCB0SIMO Pin 1.6 */ + P1SEL0 &= ~BIT6; + P1SEL1 |= BIT6; + P1DIR |= BIT6; + + /* UCB0SOMI Pin 1.7 */ + P1SEL0 &= ~BIT7; + P1SEL1 |= BIT7; + P1DIR &= ~BIT7; + //P1REN |= BIT6; + + UCB0CTLW0 = UCCKPH | UCMSB | UCMST | UCSYNC | UCMODE_0 | UCSSEL__SMCLK | UCSWRST; + UCB0BRW = 15; // /16 -> 1MHz + UCB0CTLW0 &= ~UCSWRST; +} + +signed char SPI::xmit(unsigned char tx_len, unsigned char *tx_buf, + unsigned char rx_len, unsigned char *rx_buf) +{ + volatile char rxbuf_cache; + if (tx_len < 1) { + return -1; + } + + UCB0IE &= ~(UCTXIE | UCRXIE); + + while (UCB0STATW & UCBUSY) ; + + rxbuf_cache = UCB0RXBUF; + UCB0TXBUF = tx_buf[0]; + + unsigned char tx_pos = 1; + unsigned char rx_pos = 0; + + while (tx_pos < tx_len || rx_pos < rx_len) { + if ((tx_pos < tx_len) && (UCB0IFG & UCTXIFG)) { + UCB0TXBUF = tx_buf[tx_pos++]; + } + if (UCB0IFG & UCRXIFG) { + if (rx_pos < rx_len) { + rx_buf[rx_pos] = UCB0RXBUF; + } else { + rxbuf_cache = UCB0RXBUF; + } + rx_pos++; + } + } +} |