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.

MSP430 USCI A0 SPI transfer UCBUSY bit problem

Other Parts Discussed in Thread: MSP430FG4618

Hello,

I have setup my MSP430FG4618 to send data to an OLED display over SPI.  I am using IAR. I did not enable the MISO line since we are not receiving anything from the display. Here is the problem I am having.

>> Initially, the TXIFG is set since the TXBUF as well as the shift register are empty.  After checking for the TXIFG           flag to be 1, I fill the TXBUF with the data to send. 

>> I see in IAR that TXBUF now contains the correct data. TXIFG is low indicating the buffer is filled.

>> Now, according to how the USCI module works, the data is supposed to be transferred over to the shift register. This makes the TXBUF free to receive another byte of data, so the TXIFG flag is set. While the Shift register is still shifting the bits out, UCBUSY flag is set and the new data filled in TXBUF will remain there until the shifting is finished.

>> However, in my case, after TXBUF is filled for the first time and TXIFG is false, UCBUSY is not set, therefore the TXBUF never becomes available to take a new byte. TXIFG is therefore never set again. 

Here is my setup code

//////////////////////////////////////////

P3SEL = BIT1 | BIT3; // Route pins to USCI_A for SPI
                 // P7.1 - UCA0MOSI // SPI mode 0 needs CPOL=CKPL=0, CPHA=0 -> CKPH=1; msb first, master,
                 // P7.2 - UCA0MISO // 8 bit (default), 3-wire (default, mode 0), synchronous
                 // P7.3 - UCA0CLK

UCA0CTL0 = UCCKPH | UCCKPL | UCMSB | UCMST | UCMODE_0 | UCSYNC; // sunchronous mode
UCA0CTL1 = UCSSEL1 | UCSWRST; // Clock from SMCLK; hold in reset
UCA0BR1 = 0; // Upper byte of divider word
UCA0BR0 = 10; // Clock = SMCLK / 10 = 100kHz
UCA0CTL1 &= ~UCSWRST; // Release from reset

This is where I am checking the TXIFG buffer 

/////////////////////////////////////////////////////////////////////////////////

void oled_Data(unsigned char Data)
{

        char rx;
        OLED_SET_DATA(); // Set DC, RW, nRES pins as necessary
                                      // Data mode needs to be set before the buffer can be written to, because the buffer will
                                      // move its content to the SR which will starting pushing bits out immediately
        if(IFG2_bit.UCA0RXIFG) rx = UCA0RXBUF;

        while(IFG2_bit.UCA0TXIFG!=1){}
        DPORT_OUT = Data; // Data to be written to the display

        OLED_udelay(100); // Delay for 100 us
        OLED_udelay(100); // Delay for 100 us
}

I would appreciate any help on this! Thank you!

  • UCBUSY is only set while the USCI is doing a transfer. In your case (right after setup), it means for 80µs after writing to TXBUF. TXBUF keeps its content even if TXIFG is set and data has been sent. However, right after writing to TXBUF (on the next bit clock), TXIFG should be set again.
    It’s possible that your breakpoint and register inspection happens too fast, so the content of TXBUF hasn’t been copied to the output shift register yet (on 1MHz MCLK and 100kHz bit clock, it takes up to 10 MCLK cycles after writing to TXBUF).

    Writing to TXBUF and then immediately hitting a breakpoint to check for UCBUSY might be a bit too fast.

     What is DPORT_OUT? An alias for UCA0TXBUF?

     BTW: which OLED are you using?

**Attention** This is a public forum