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.

CCS/MSP430F5529: SPI-communication USCIB0, no transfer

Part Number: MSP430F5529

Tool/software: Code Composer Studio

Hello,
I want to setup a SPI-communication from a MSP430F5529 to a Display. I am using a libary to control the display, but I have to setup a SPI-protocol for faster transmittion.

The libary has four function (for the transfer), which are called up in this order:

  1. U8X8_MSG_BYTE_INIT
  2. U8X8_MSG_BYTE_START_TRANSFER
  3. Any mix of U8X8_MSG_BYTE_SEND and U8X8_MSG_BYTE_SET_DC
  4. U8X8_MSG_BYTE_END_TRANSFER

U8X8_MSG_BYTE_INIT is for the initialisation of the SPI. The U8X8_MSG_BYTE_SEND  function is for the transmition of the data. I need to send arg_int bytes, because arg_ptr will point to a buffer of size arg_int. The Chip-Select/Slave-Select is handeld in U8X8_MSG_BYTE_START_TRANSFER and U8X8_MSG_BYTE_END_TRANSFER, so I don't have to deal with it.

The two statements I hve to replace in the tmeplate:

case U8X8_MSG_BYTE_INIT:

    	 P3SEL |= BIT0+BIT1+BIT2;							// P3.0,1,2 option select MOSI MISO CLK
    	 UCB0CTL1 |= UCSWRST;								// **Put state machine in reset**
    	 UCB0CTL0 |= UCMST+UCSYNC+UCMSB;//UCMODE_2;			// 3-pin, 8-bit SPI master
    	                                        			// MSB, clock polarity high
    	 UCB0CTL1 |= UCSSEL_2;								// SMCLK Clock Auswahl
    	 UCB0BR0 = 0x04;									// Baudrate 13Mhz/4
    	 UCB0BR1 = 0;										// The clock frequency is scaled by UCB0BR0 + UCB0BR1 * 256
    	 UCB0CTL0 &= ~UCCKPL;								// Clock polarity
    	 UCB0CTL0 &= ~UCCKPH;								// Clock phase



    	 UCB0CTL1 &= ~UCSWRST;
    	 UCB0IE |= UCRXIE+UCTXIE;                   	    // Enable USCI_B0 RX+TX interrupt
         break;

and:

uint8_t *data;    

case U8X8_MSG_BYTE_SEND: data = (uint8_t *)arg_ptr; while (!(UCB0IFG&UCTXIFG)); // USCI_B0 TX buffer ready? while( arg_int > 0 ) { while (!(UCB0IFG&UCTXIFG)); // USCI_B0 TX buffer ready? __delay_cycles(20); P2DIR |= BIT3; P2OUT |= BIT3; UCB0TXBUF = *data; arg_int--; data++; } break;

I am stuck in the troubleshooting a few days now. I already checked many examples and the datasheet but I can't find the fault/faults,
I would really appreciate some help. Thanks

  • I'm not sure I understand what symptom you're describing, but this looks suspicious:
    > UCB0IE |= UCRXIE+UCTXIE; // Enable USCI_B0 RX+TX interrupt
    Your other code fragment indicates that you're not using interrupts, so you shouldn't enable them (specifically: Remove this line).
  • I don't have a transfer of data to the display. Ok, i removed that line. Thanks.
    On PIN 2.3 is only a little LED.

  • So did that have any effect on your symptom?
  • I do have a transmittion of data to the Display. Thanks

  • Part Number: MSP430F5529

    Tool/software: Code Composer Studio

    Hello,
    I want to setup a fast SPI-communication from a MSP430F5529 to a Display. I am using a libary to control the display, but I have to setup a SPI-protocol for faster transmittion.

    The libary has four function (for the transfer), which are called up in this order:

    1. U8X8_MSG_BYTE_INIT
    2. U8X8_MSG_BYTE_START_TRANSFER
    3. Any mix of U8X8_MSG_BYTE_SEND and U8X8_MSG_BYTE_SET_DC
    4. U8X8_MSG_BYTE_END_TRANSFER

    U8X8_MSG_BYTE_INIT is for the initialisation of the SPI. The U8X8_MSG_BYTE_SEND  function is for the transmition of the data. I need to send arg_int bytes, because arg_ptr will point to a buffer of size arg_int. The Chip-Select/Slave-Select is handeld in U8X8_MSG_BYTE_START_TRANSFER and U8X8_MSG_BYTE_END_TRANSFER, so I don't have to deal with it.

    The two statements I have to replace in the template:

    case U8X8_MSG_BYTE_SEND:
            data = (uint8_t *)arg_ptr;
            while( arg_int > 0 )
                      {
                        while (!(UCB0IFG&UCTXIFG));             // USCI_B0 TX buffer ready?
                        UCB0TXBUF = *data;
                        while (UCB0STAT & UCBUSY);
                        arg_int--;
                        data++;
                      }
    break;
    case U8X8_MSG_BYTE_INIT:
            P3SEL |= BIT0+BIT1+BIT2;                            // P3.0,1,2 option select MOSI MISO CLK
            UCB0CTL1 |= UCSWRST;                                // **Put state machine in reset**
            UCB0CTL0 |= UCMST+UCMSB+UCSYNC+UCCKPL;              // 3-pin, 8-bit SPI master
                                                                // MSB
            UCB0CTL1 |= UCSSEL_2;                               // SMCLK Clock Auswahl
            UCB0BR0 = 140;                                      // Baudrate 13Mhz
            UCB0BR1 = 0;                                        // The clock frequency is scaled by UCB0BR0 + UCB0BR1 * 256
            UCB0CTL0 &= ~UCCKPH;                                // Clock phase
            //UCB0CTL0 &= ~UCCKPL;
            //UCB0CTL0 &= ~UC7BIT;
            UCB0CTL1 &= ~UCSWRST;
            break;

    The problem I have is, that the transmittion only works fine with a frequency up to 10kHz. If I raise the frequency it doesn't transmit correctly. Isn't it possible to have a faster SPI transmittion without interrupts? Thanks

  • 10kHz isn't very fast; I wouldn't expect a malfunction at that speed. Can you see what the incorrect data looks like (on a scope, e.g.)?

    Some things to check:
    1) Is this a speed limitation in the slave (display)? The data sheet should say.
    2) Are you fairly certain about the clock phase and polarity settings? It's possible for a slow transmission to "forgive" some mis-configurations. (In a pinch, I sometimes just try all four combinations.)
    3) How long are your wires? I have seen propagation errors over long-ish wires (though admittedly those were 10" wires running at 8MHz).

    I routinely run multi-MHz SPI, so it's not a USCI limitation. With a fast clock, I don't recommend interrupts.
  • The transmittion looks correct to my point of view. Should I still upload a screenshot from the logic analyser?

    1) The maximum speed is at ~8.3MHz. (from the display datasheet)

    2) I've tried no every combination: it does work with

    • KPL = 0; KPH = 1
    • KPL = 1; KPH = 0
    • KPL = 1; KPH = 1

    but only with 10kHz......

    A screenshot from the datasheet:

    3) There are about 15cm long. So there shouldn't be a problem.

  • > If I raise the frequency it doesn't transmit correctly.
    vs
    > The transmittion looks correct to my point of view.
    I'm just trying to figure out whether this is a malfunction or just a not-fast-enough question. Is the symptom you're seeing elsewhere?

    Another thing came to mind: I've seen display data sheets which prescribe delays following certain transactions (typically commands during initialization) to give the device time to process them. I suppose these delays are enforced by your library, but if one of them were incorrect a slow SPI would introduce an implicit delay (one byte at 10kHz is 800usec) that may be "fixing" things. Do you have the source for the library?
  • Gabriel,

    Take a look at the following application note. It will help you debug this issue from the MSP430 SPI side of things. http://www.ti.com/lit/slaa734
  • Bruce McKenney47378 said:
    Do you have the source for the library?

    The libary is open source: github.com/.../u8g2

    Bruce McKenney47378 said:
    I'm just trying to figure out whether this is a malfunction or just a not-fast-enough question.

    The display works fine up to a clock frequency of 10kHz, but the display is able to handle 7MHz and I need at least 500MHz.

    I already implemented the delays for the general use of the libary with a different microcontroller than the Arduino and with software SPI. I have used  "__delay_cycles()"  for the delays. Could that be the problem? 

    Bruce McKenney47378 said:
    Another thing came to mind: I've seen display data sheets which prescribe delays following certain transactions (typically commands during initialization) to give the device time to process them.

    I didn't find any prescribed delays in the datasheet: www.lcd-module.de/.../uc1611s_v1_0.pdf

    The display works properly with 700MHz and a different controller, so I don't think that there is any need of delays after some commands.

  • What is the symptom when you run it too fast?

    Also: How do you handle U8X8_MSG_BYTE_SET_DC? Yes, I expect it's pretty simple, but sometimes all it takes is a typo.
  • Bruce McKenney47378 said:
    What is the symptom when you run it too fast?

    It doesn't display anything, although there is a transmission. 

    Bruce McKenney47378 said:
    Also: How do you handle U8X8_MSG_BYTE_SET_DC? Yes, I expect it's pretty simple, but sometimes all it takes is a typo.

    The output level of data/command line is already handled in the gpio mapping.


    case U8X8_MSG_BYTE_SET_DC: u8x8_gpio_SetDC(u8x8, arg_int); break; //in the gpio mapping case U8X8_MSG_GPIO_DC: // DC (data/cmd, A0, register select) pin: Output level in arg_int if(arg_int) { P4OUT |= BIT2; } else { P4OUT &= ~BIT2; } break;

  • Hello,

    form the info on the LCD, you should have UCKPH =0 and UCKPL =1. Also, you cancalculate the max speed the MSP430F5529 can connect to the LCD using the formula described in the app note I posted about earlier. I haven't done the calculation, but you are not going to get anywhere near 500MHz. 500kHz is a possibility though. It seems this LCD needs an extra line to tell it if you are giving a command or data, and it seems this needs to be held high for at least a SPI clock cycle. I would double check this timing on your logic analyzer or o-scope to make sure this is being held for the correct amount of time.

**Attention** This is a public forum