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.

Master SPI tx, when can I send the next byte?

Other Parts Discussed in Thread: MSP430F5528

I'm writing an SPI driver for MSP430F5528 chip.

I'm using the driverlib from TI for working with the SPI.

 I need to send 3 bytes.

When I'm sending the 3 bytes one after the other, only the third byte is actually sent, like the first two were overriden.

I tried waiting until the SPI bus won't be busy. but than I get gaps between the bytes, the CLK stops between them and the perihpheral doesn't work.

I tried also turning the SPI's TX interrupt, and wait until the interrupt occurr, but aperently, the bytes are overriden like before.

Here's some code for reference:

  GPIO_setAsOutputPin( GPIO_PORT_P6, GPIO_PIN6 );

  GPIO_setOutputHighOnPin(GPIO_PORT_P6, GPIO_PIN6 ); // Set CS UP
 
  GPIO_setAsPeripheralModuleFunctionInputPin(
        GPIO_PORT_P4,
        GPIO_PIN2
        );
 
  GPIO_setAsPeripheralModuleFunctionOutputPin(
      GPIO_PORT_P4,
      GPIO_PIN1 + GPIO_PIN3
      );
  retval = USCI_B_SPI_masterInit(USCI_B1_BASE,
                        USCI_B_SPI_CLOCKSOURCE_ACLK,
                        UCS_getACLK(__MSP430_BASEADDRESS_UCS__),
                        SPICLK,
                        USCI_B_SPI_MSB_FIRST,
                        USCI_B_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT, /* CPHA=0 */
                        USCI_B_SPI_CLOCKPOLARITY_INACTIVITY_LOW /* CPOL=0 */
                        );
 
   //Enable SPI module
  USCI_B_SPI_enable(USCI_B1_BASE);

/* Send few bytes with interrupt waiting.

    USCI_B_SPI_clearInterruptFlag ( USCI_B0_BASE, USCI_B_SPI_TRANSMIT_INTERRUPT );
    USCI_B_SPI_enableInterrupt ( USCI_B0_BASE, USCI_B_SPI_TRANSMIT_INTERRUPT );
    GPIO_setOutputLowOnPin(GPIO_PORT_P6, GPIO_PIN6 ); // Set CS DOWN

      USCI_B_SPI_transmitData(USCI_B1_BASE, 0x1);
      while ( !USCI_B_SPI_getInterruptStatus ( USCI_B0_BASE, USCI_B_SPI_TRANSMIT_INTERRUPT ) ) ;
      USCI_B_SPI_transmitData(USCI_B1_BASE, 0x2);
      while ( !USCI_B_SPI_getInterruptStatus ( USCI_B0_BASE, USCI_B_SPI_TRANSMIT_INTERRUPT ) ) ;
      USCI_B_SPI_transmitData(USCI_B1_BASE, 0x3);
      while ( !USCI_B_SPI_getInterruptStatus ( USCI_B0_BASE, USCI_B_SPI_TRANSMIT_INTERRUPT ) ) ;

    GPIO_setOutputHighOnPin(GPIO_PORT_P6, GPIO_PIN6 ); // Set CS UP
    USCI_B_SPI_disableInterrupt ( USCI_B0_BASE, USCI_B_SPI_TRANSMIT_INTERRUPT );

 

 

 

  • Ramon Fried said:
    I tried waiting until the SPI bus won't be busy. but than I get gaps between the bytes, the CLK stops between them and the perihpheral doesn't work.

    SPI peripheral shall tolerate clock gaps, even during byte transmission.

  • I don't know what all these library functions (or macros) actually do. Nor do I know what the ISR does. Possibly they aren't used as they are intended to be used.

    However, in general, SPI is synchronous. That means, the master defines the clock. SPI takes any clock speed from 0Hz (suspended, even mid-byte) to the maximum master and slave can handle. SO no problem with gaps (other than the reduced throughput).

    The USCI sets TXIFG bit (triggers interrupt) whenever the TXBUF register is ready to receive the next byte. The bit is reset by writing to TXBUF.
    So if you check for TXIFG before you write the next byte, you won't overwrite the previous.

    The interrupt waiting code should work (however, it does not really use interrupts, but it does the checking for TXIFG), except for one thing.
    After writing the last byte, you wait for TXIFG to be set, then de-assert CS. THis is wrong. When TXIFG is set, it means that TXBUF is ready for the next byte. But the previous one has just begun being sent. So you raise CS during the first bit of the last byte, which is of course wrong.
    Here you should instead check for UCBUSY, to ensure sending is complete. Also, many slaves require some additional delay after having received the last byte, before CS may go up.

    However, you should not enable interrupt. Either you wait for TXIFG bit (getInteruptStatus) or you enable interrupts and handle the interrupt inside an ISR. Which requires that the ISR knows the next byte to send.
    Note that the interrupt flag is always set when TXBUF is empty, whether interrupts are enabled or not.

    However, no knowing the exact code behind all these API calls, I might be wrong. I can only guess what they do.

  • Thanks for your response. it make sense :)

**Attention** This is a public forum