I'm trying to setup the SPI communication (with USCI) on MSP430FG4618. I couldn't find it anywhere talking about 16-bit transmit buffer. Basically I'm trying to use FG4618 to communicate with an ADC that requires a 16-bit data.
I have used the 16-bit SPI with USI on MSP430F2013 and it worked fine (setting the USI16B bit). Does USCI support 16-bit SPI? If not, can I transmit 2 8-bit cycles? How?
Thanks.
Here's the sample code that only does 8-bit. (By. Davies)
// uscispiloop1.c - test SPI using USCI_B with loopback (int and ext)
// 8-bit transfer, SPI mode 3 (CPOL = CPHA = 1), every (1/4)ms after BT
// FG4619 on TI Experimenter's Board, 32KHz crystal, DCO at 6MHz
// SPI clock = SMCLK / 60 = 100kHz, so about 80us for transfer
// SCLK on P3.3, MOSI on P3.1, MISO on P3.2
// P3.0 used as _SS (nSS) but TIMING IS NOT PRECISE (done in software)
// J H Davies, 2007-11-05; IAR Kickstart version 4.09A
//----------------------------------------------------------------------
#include <io430xG46x.h> // Specific device
#include <intrinsics.h> // Intrinsic functions
#include <stdint.h> // Integers of defined sizes
//#include "LCDutils2.h" // TI exp board utility functions
#define nSS P3OUT_bit.P3OUT_0 // Output pin for _SS (active low)
//uint8_t RXdata, TXdata = 0x5A; // Received and transmitted data,
uint16_t RXdata, TXdata = 0x385A; //16 bit data
// subsequent values incremented
void main (void)
{
volatile uint16_t i; // Loop counter to stabilize FLL+
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
FLL_CTL0 = DCOPLUS | XCAP14PF; // FLL+ divider, 14pF load caps
SCFQCTL = 91; // f_DCO = 2(91 + 1)f_ACLK = 6.03MHz (Default D=2)
SCFI0 = FLLD_2 | FN_3; // Multiply by 2, 2.2 - 17MHz range
do { // Wait until FLL has locked
for (i = 0xFFFF; i > 0; --i) {
} // Delay for FLL+ to lock
IFG1_bit.OFIFG = 0; // Attempt to clear osc fault flag
} while (IFG1_bit.OFIFG != 0); // Repeat if not yet clear
// P3OUT = BIT1 | BIT2 | BIT5; // F2013 might tie 1,2 high;
// P3DIR = 0xFF; // P3.5 high for buzzer off
P3OUT_bit.P3OUT_0 = 1; // High for nSS inactive
P3DIR_bit.P3DIR_0 = 1; // Enable for nSS output
P3SEL = BIT1 | BIT2 | BIT3; // Route pins to USCI_B for SPI
// SPI mode 3 needs CPOL=CKPL=1, CPHA=1 -> CKPH=0; msb first, master,
// 8 bit (default), 3-wire (default, mode 0), synchronous
UCB0CTL0 = UCCKPL | UCMSB | UCMST | UCMODE_0 | UCSYNC;
UCB0CTL1 = UCSSEL1 | UCSWRST; // Clock from SMCLK; hold in reset
UCB0BR1 = 0; // Upper byte of divider word
UCB0BR0 = 60; // Clock = SMCLK / 60 = 100kHz
UCB0STAT = UCLISTEN; // Internal loopback
UCB0CTL1 &= ~UCSWRST; // Release from reset
IE2_bit.UCB0RXIE = 1; // Enable interrupts on receive
// Basic Timer: hold, counter 2 from ACLK, period = 8 (cntr 1 not used)
// BTCTL = BTHOLD | BT_fCLK2_ACLK | BT_fCLK2_DIV8;
BTCTL = BT_fCLK2_ACLK | BT_fCLK2_DIV16;
BTCNT2 = 0; // Clear counter
BTCTL &= ~BTHOLD; // Start basic timer
IE2_bit.BTIE = 1; // Enable basic timer interrupts
for (;;) { // Transmissions triggered by BT
__low_power_mode_3(); // LPM3 between interrupts
}
}
//----------------------------------------------------------------------
// ISR for basic timer: check TXIFG, activate nSS, start new SPI transfr
//----------------------------------------------------------------------
#pragma vector = BASICTIMER_VECTOR
__interrupt void BASICTIMER_ISR (void) // Acknowledged automatically
{
if (IFG2_bit.UCB0TXIFG == 1) { // Ready for new data?
nSS = 0; // Lower nSS (make active)
UCB0TXBUF = TXdata; // Load shift register for transfer
} // SMCLK remains active for USCI automatically
}
//----------------------------------------------------------------------
// ISR for USCI_A,B0 RX: deactivate nSS, store rec'd data (acknowledges)
//----------------------------------------------------------------------
#pragma vector = USCIAB0RX_VECTOR
__interrupt void USCIAB0RX_ISR (void) // Not acknowledged automaticaly
{
nSS = 1; // Raise nSS (make inactive)
RXdata = UCB0RXBUF; // Store received data, clears flag
TXdata = RXdata;// + 1; // Slightly different next time!
}