Other Parts Discussed in Thread: MSP430WARE
Tool/software: Code Composer Studio
I'm working on a project with an MSP430F67621A, in which I need to send data from two MSP430s to a Linux-based host. The three devices are connected over SPI, with a chip select line from the Linux host to each MSP430. The Linux host is the SPI master, and the MSP430s are slaves.
I am seeing a strange issue, whereby if I have the MSP430 eUSCI module configure in 3-pin SPI slave mode everything seems to be OK, but when I try to use 4-pin mode the MSP430 only responds to the master on the very first occasion - every time after that, the slave does not respond. (Note that although I do have two MSP430s to talk to, this example is running on just one of them, with the second being disabled).
It seems to not matter how many bytes I read in the one transfer from the master, I always get data the first time and then get zeroes on subsequent transfers. I've mapped the STE pin to P2.7.
I've set up a basic Code Composer Studio project that demonstrates the problem, this is the main.c file:
#include <stdio.h>
#include <msp430.h>
#include <stdint.h>
uint8_t send_bytes[] = \
{
0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x01,
0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x02,
0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x03,
0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x04,
0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x05,
0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x06,
0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x07,
0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x08,
0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x09,
0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x0A,
0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x0B,
0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x0C,
0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x0D,
0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x0E,
0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x0F
};
const uint8_t send_len = 120;
uint8_t send_ctr = 0;
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
// Enable global interrupt
__bis_SR_register(GIE);
// Configure SPI pins to secondary function mode
P1SEL |= BIT4 | BIT5; // P1.4 + P1.5 (UCA1SOMI, UCA1SIMO)
P2SEL |= BIT4; // P2.4 (UCA1CLK)
// Configure SPI 'STE' pin
PMAPPWD = PMAPPW; // Enable Write-access to modify port mapping registers
P2SEL |= BIT7; // Set P2.7 as secondary function mode
P2MAP7 = PM_UCA1STE; // Map to UCA1STE function
// Put USCI state machine into reset, so that options can be changed
UCA1CTLW0 = UCSWRST;
/*
* UCA1CTLW0: USCI_A1 Control Register
* Bit fields mean the following:
* UCCKPH: Clock phase select
* UCCKPL: Clock polarity select
* UCMSB: MSB first select
* UC7BIT: Character length
* UCMST: Master mode select
* UCMODEx: USCI mode
* UCSYNC: Synchronous mode enable
*/
UCA1CTLW0 =
UCCKPH | // 1b = Data is captured on the first UCLK edge and changed on the following edge
//UCCKPL | // 0b = The inactive state is low
UCMSB | // 1b = MSB first
//UC7BIT | // 0b = 8-bit data
//UCMST | // 0b = Slave mode
UCMODE_2 | // 10b = 4-pin SPI with UCxSTE active low: Slave enabled when UCxSTE = 0
UCMODE_0 | // 00b = 3-pin SPI
UCSYNC; // 1b = Synchronous mode
/*
* UCA1BR0: USCI_A1 Bit Rate Control Register 0
* UCA1BR1: USCI_A1 Bit Rate Control Register 1
* Bit clock prescaler bytes. The 16-bit value of
* (UCA1BR0 + UCA1BR1 × 256) forms the prescaler
* value UCBR1.
*/
UCA1BR0 = 0x02;
UCA1BR1 = 0;
// Take USCI state machine out of reset, starting it with the given options
UCA1CTLW0 &= ~UCSWRST;
/*
* UCA1IE: USCI_A1 Interrupt Enable Register
* UCTXIE: Transmit interrupt enable
* UCRXIE: Receive interrupt enable
*/
UCA1IE |= UCRXIE; // Enable the RX interrupt
// UCA1IE |= UCTXIE; // Enable the TX interrupt
}
//// USCI_A1 interrupt vector service routine.
#if defined(__TI_COMPILER_VERSION__)
#pragma vector=USCI_A1_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(USCI_A1_VECTOR)))
#endif
void USCI_A1_ISR (void)
{
switch (__even_in_range(UCA1IV,2)){
//Vector 2 - RXIFG
case 2:
// Wait for USCI_A1 TX buffer to be ready
while (!(UCA1IFG & UCTXIFG));
// Send over SPI
UCA1TXBUF = send_bytes[send_ctr];
send_ctr++;
if(send_ctr > send_len){
send_ctr = 0;
}
break;
default: break;
}
}
EDIT: Updated array and length in example
Is there something I need to do to re-enable the eUSCI module after it has been triggered as a slave by the STE pin?




