This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430F5528 - SPI test



Hi,

Im trying to use UCB1 as SPI, however it doesnt work. Therefore I removed my peripheral and connected SI and SO pins together. Unfortunately I only get 0xFF in UCRXBUF.

Any idea what could be wrong? Here is the code:

#include <msp430.h>

unsigned char MST_Data,SLV_Data;
unsigned char temp;

int main(void)
{
volatile unsigned int i;

WDTCTL = WDTPW+WDTHOLD; // Stop watchdog timer

P1OUT |= BIT2; // Set P1.2 for LED
P1DIR |= BIT2; // Set P1.2 to output direction

P4SEL |= BIT2+BIT3; // Initialize SPI pins
P4SEL |= BIT1; //

UCB1CTL1 |= UCSWRST; // **Put state machine in reset**
UCB1CTL0 |= UCMST+UCSYNC+UCCKPL+UCMSB; // 3-pin, 8-bit SPI master
// Clock polarity high, MSB
UCB1CTL1 |= UCSSEL_2; // SMCLK
UCB1BR0 = 0x02; // /2
UCB1BR1 = 0; //
//UCB1MCTL = 0; // No modulation
UCB1CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
UCB1IE |= UCRXIE; // Enable USCI_A0 RX interrupt

for(i=50;i>0;i--); // Wait for slave to initialize

MST_Data = 0x01; // Initialize data values
SLV_Data = 0x00; //

while (!(UCB1IFG&UCTXIFG)); // USCI_A0 TX buffer ready?
UCB1TXBUF = MST_Data; // Transmit first character

__bis_SR_register(LPM0_bits + GIE); // CPU off, enable interrupts
}

#pragma vector=USCI_B1_VECTOR
__interrupt void USCI_B1_ISR(void)
{
volatile unsigned int i;

switch(__even_in_range(UCB1IV,4))
{
case 0: break; // Vector 0 - no interrupt
case 2: // Vector 2 - RXIFG
while (!(UCB1IFG&UCTXIFG)); // USCI_A0 TX buffer ready?

if (UCB1RXBUF==SLV_Data) // Test for correct character RX'd
P1OUT |= BIT2; // If correct, light LED
else
P1OUT &= ~BIT2; // If incorrect, clear LED

MST_Data++; // Increment data
SLV_Data++;
UCB1TXBUF = MST_Data; // Send next value

for(i = 20; i>0; i--); // Add time between transmissions to
// make sure slave can process information
break;
case 4: break; // Vector 4 - TXIFG
default: break;
}
}

  • Actually it produces garbage, not always 0xFF but sometimes other values.

  • Sergey Vladimirov said:
    for(i=50;i>0;i--); // Wait for slave to initialize

    Well, even if CCS won't optimize code on a local volatile variable, it could (and any other compiler would) do it in compliance with the C language rules. Use _-delay_cycles() or a tiemr for a sufficient delay.
    Also, are you sure that the tiny amount of time required to do a loop of 50 increments is long enough to let the slave come up?

    YOu are doing a busy-waiting for TXIFG winside teh RXIFG handler. Which is very bad coding practice (yes, I've seen it in Ti demo code too, still bad parctice). You should never wait for somethign inside an ISR. in this case, this line is superfluous too - since RX and TX are synchronous, when you received a byte, you have definitely sent the last byte.
    But you're also wasting time. You only stuff the next byte to TXBUF when you received the byte that was sent during sending the last byte. So TXBUF was empty and the sending is not continuous (it stops for the execution time of your ISR), limiting the throughput. Not critical but you're not using the double-buffering here. However, with your loopback test, it is of course good as it is.

    I don't know why you receive 0xff when you connect SOMI and SIMO (sure the connection is okay?), but in the current constellation, you will never get the LED lit (you send 0x01 and compare it with 0x00, then you send 0x02 and compare it with 0x01 etc.)

**Attention** This is a public forum