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: msp430 : SPI slave mode return the data is wrong

Part Number: MSP430F5529

Tool/software: Code Composer Studio

hi everyone

I now need two EXP_MSP430F5529LP development boards to verify SPI communications, one of the master mode (running ti-rtos), the other running SPI slave mode (without ti-rtos), and now I use the 【MSP430F55xx_usci_spi_standard_slave】 example code of SPI slave mode.

now I found that the spi master mode is only normal for the first time reading data, the rest is failing, you have to reset the slave mode development board once to read the normal data.I don't know why? Now just want to simulate the slave module board as spi flash, who has better advice?

thank you 

xc_mo

MSP430F55xx_usci_spi_standard_slave code

//******************************************************************************
//   MSP430F552x Demo - USCI_A0, SPI 3-Wire Slave multiple byte RX/TX
//
//   Description: SPI master communicates to SPI slave sending and receiving
//   3 different messages of different length. SPI slave will enter LPM0
//   while waiting for the messages to be sent/receiving using SPI interrupt.
//   ACLK = NA, MCLK = SMCLK = DCO 16MHz.
//
//
//                   MSP430F5529
//                 -----------------
//            /|\ |             P2.0|<- Master's GPIO (Chip Select)
//             |  |                 |
//             ---|RST          RST |<- Master's GPIO (To reset slave)
//                |                 |
//                |             P3.3|<- Data In (UCA0SIMO)
//                |                 |
//                |             P3.4|-> Data Out (UCA0SOMI)
//                |                 |
//                |             P2.7|<- Serial Clock In (UCA0CLK)
//
//   Nima Eskandari
//   Texas Instruments Inc.
//   April 2017
//   Built with CCS V7.0
//******************************************************************************

#include <msp430.h> 
#include <stdint.h>
#include <stdbool.h>

//******************************************************************************
// Example Commands ************************************************************
//******************************************************************************

#define DUMMY   0xFF

#define SLAVE_CS_IN     P2IN
#define SLAVE_CS_DIR    P2DIR
#define SLAVE_CS_PIN    BIT0

/* CMD_TYPE_X_SLAVE are example commands the master sends to the slave.
 * The slave will send example SlaveTypeX buffers in response.
 *
 * CMD_TYPE_X_MASTER are example commands the master sends to the slave.
 * The slave will initialize itself to receive MasterTypeX example buffers.
 * */

#define CMD_TYPE_0_SLAVE               0
#define CMD_TYPE_1_SLAVE               1
#define CMD_TYPE_2_SLAVE               2

#define CMD_TYPE_0_MASTER              3
#define CMD_TYPE_1_MASTER              4
#define CMD_TYPE_2_MASTER              5

#define TYPE_0_LENGTH                  1
#define TYPE_1_LENGTH                  2
#define TYPE_2_LENGTH                  6

#define MAX_BUFFER_SIZE                20

/* MasterTypeX are example buffers initialized in the master, they will be
 * sent by the master to the slave.
 * SlaveTypeX are example buffers initialized in the slave, they will be
 * sent by the slave to the master.
 * */

uint8_t MasterType2 [TYPE_2_LENGTH] = {0};
uint8_t MasterType1 [TYPE_1_LENGTH] = {0, 0};
uint8_t MasterType0 [TYPE_0_LENGTH] = {0};

uint8_t SlaveType2 [TYPE_2_LENGTH]  = {'A', 'B', 'C', 'D', '1', '2'};
uint8_t SlaveType1 [TYPE_1_LENGTH]  = {0x15, 0x16};
uint8_t SlaveType0 [TYPE_0_LENGTH]  = {0x11};

//******************************************************************************
// General SPI State Machine ***************************************************
//******************************************************************************

typedef enum SPI_ModeEnum{
    IDLE_MODE,
    TX_REG_ADDRESS_MODE,
    RX_REG_ADDRESS_MODE,
    TX_DATA_MODE,
    RX_DATA_MODE,
    TIMEOUT_MODE
} SPI_Mode;

/* Used to track the state of the software state machine*/
SPI_Mode SlaveMode = RX_REG_ADDRESS_MODE;

/* The Register Address/Command to use*/
uint8_t ReceiveRegAddr = 0;

/* ReceiveBuffer: Buffer used to receive data in the ISR
 * RXByteCtr: Number of bytes left to receive
 * ReceiveIndex: The index of the next byte to be received in ReceiveBuffer
 * TransmitBuffer: Buffer used to transmit data in the ISR
 * TXByteCtr: Number of bytes left to transfer
 * TransmitIndex: The index of the next byte to be transmitted in TransmitBuffer
 * */
uint8_t ReceiveBuffer[MAX_BUFFER_SIZE] = {0};
uint8_t RXByteCtr = 0;
uint8_t ReceiveIndex = 0;
uint8_t TransmitBuffer[MAX_BUFFER_SIZE] = {0};
uint8_t TXByteCtr = 0;
uint8_t TransmitIndex = 0;

/* Initialized the software state machine according to the received cmd
 *
 * cmd: The command/register address received
 * */
void SPI_Slave_ProcessCMD(uint8_t cmd);

/* The transaction between the slave and master is completed. Uses cmd
 * to do post transaction operations. (Place data from ReceiveBuffer
 * to the corresponding buffer based in the last received cmd)
 *
 * cmd: The command/register address corresponding to the completed
 * transaction
 */
void SPI_Slave_TransactionDone(uint8_t cmd);
void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count);
void SendUCA0Data(uint8_t val);

void SendUCA0Data(uint8_t val)
{
    while (!(UCA0IFG & UCTXIFG));              // USCI_A0 TX buffer ready?
    UCA0TXBUF = val;
}

void SPI_Slave_ProcessCMD(uint8_t cmd)
{
    ReceiveIndex = 0;
    TransmitIndex = 0;
    RXByteCtr = 0;
    TXByteCtr = 0;

    switch (cmd)
    {
        case (CMD_TYPE_0_SLAVE):                        //Send slave device id (This device's id)
            SlaveMode = TX_DATA_MODE;
            TXByteCtr = TYPE_0_LENGTH;
            //Fill out the TransmitBuffer
            CopyArray(SlaveType0, TransmitBuffer, TYPE_0_LENGTH);
            //Send First Byte
            SendUCA0Data(TransmitBuffer[TransmitIndex++]);
            TXByteCtr--;
            break;
        case (CMD_TYPE_1_SLAVE):                      //Send slave device time (This device's time)
            SlaveMode = TX_DATA_MODE;
            TXByteCtr = TYPE_1_LENGTH;
            //Fill out the TransmitBuffer
            CopyArray(SlaveType1, TransmitBuffer, TYPE_1_LENGTH);
            //Send First Byte
            SendUCA0Data(TransmitBuffer[TransmitIndex++]);
            TXByteCtr--;
            break;
        case (CMD_TYPE_2_SLAVE):                  //Send slave device location (This device's location)
            SlaveMode = TX_DATA_MODE;
            TXByteCtr = TYPE_2_LENGTH;
            //Fill out the TransmitBuffer
            CopyArray(SlaveType2, TransmitBuffer, TYPE_2_LENGTH);
            //Send First Byte
            SendUCA0Data(TransmitBuffer[TransmitIndex++]);
            TXByteCtr--;
            break;
        case (CMD_TYPE_0_MASTER):
            SlaveMode = RX_DATA_MODE;
            RXByteCtr = TYPE_0_LENGTH;
            break;
        case (CMD_TYPE_1_MASTER):
            SlaveMode = RX_DATA_MODE;
            RXByteCtr = TYPE_1_LENGTH;
            break;
        case (CMD_TYPE_2_MASTER):
            SlaveMode = RX_DATA_MODE;
            RXByteCtr = TYPE_2_LENGTH;
            break;
        default:
            //while(1);
            __no_operation();
            break;
    }
}


void SPI_Slave_TransactionDone(uint8_t cmd)
{
    switch (cmd)
    {
        case (CMD_TYPE_0_SLAVE):                        //Slave device id was sent(This device's id)
            break;
        case (CMD_TYPE_1_SLAVE):                      //Slave device time was sent(This device's time)
            break;
        case (CMD_TYPE_2_SLAVE):                  //Send slave device location (This device's location)
            break;
        case (CMD_TYPE_0_MASTER):
            CopyArray(ReceiveBuffer, MasterType0, TYPE_0_LENGTH);
            break;
        case (CMD_TYPE_1_MASTER):
            CopyArray(ReceiveBuffer, MasterType1, TYPE_1_LENGTH);
            break;
        case (CMD_TYPE_2_MASTER):
            CopyArray(ReceiveBuffer, MasterType2, TYPE_2_LENGTH);
            break;
        default:
            __no_operation();
            break;
    }
}

void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count)
{
    uint8_t copyIndex = 0;
    for (copyIndex = 0; copyIndex < count; copyIndex++)
    {
        dest[copyIndex] = source[copyIndex];
    }
}


//******************************************************************************
// Device Initialization *******************************************************
//******************************************************************************

void initGPIO()
{
  //LEDs
  P1OUT = 0x00;                             // P1 setup for LED & reset output
  P1DIR |= BIT0 + BIT5;

  P4DIR |= BIT7;
  P4OUT &= ~(BIT7);

  //SPI Pins
  P3SEL |= BIT3 + BIT4;                     // P3.3,4 option select
  P2SEL |= BIT7;                            // P2.7 option select

}

void initSPI()
{
  //Clock Polarity: The inactive state is high
  //MSB First, 8-bit, Master, 3-pin mode, Synchronous
  UCA0CTL1  = UCSWRST;                       // **Put state machine in reset**
  UCA0CTL0 |= UCCKPL + UCMSB + UCSYNC;       // 3-pin, 8-bit SPI Slave
  UCA0CTL1 &= ~UCSWRST;                      // **Initialize USCI state machine**
  UCA0IE   |= UCRXIE;                        // Enable USCI0 RX interrupt

  SLAVE_CS_DIR &= ~(SLAVE_CS_PIN);

}

void initClockTo16MHz()
{
    UCSCTL3 |= SELREF_2;                      // Set DCO FLL reference = REFO
    UCSCTL4 |= SELA_2;                        // Set ACLK = REFO
    __bis_SR_register(SCG0);                  // Disable the FLL control loop
    UCSCTL0 = 0x0000;                         // Set lowest possible DCOx, MODx
    UCSCTL1 = DCORSEL_5;                      // Select DCO range 16MHz operation
    UCSCTL2 = FLLD_0 + 487;                   // Set DCO Multiplier for 16MHz
                                              // (N + 1) * FLLRef = Fdco
                                              // (487 + 1) * 32768 = 16MHz
                                              // Set FLL Div = fDCOCLK
    __bic_SR_register(SCG0);                  // Enable the FLL control loop

    // Worst-case settling time for the DCO when the DCO range bits have been
    // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
    // UG for optimization.
    // 32 x 32 x 16 MHz / 32,768 Hz = 500000 = MCLK cycles for DCO to settle
    __delay_cycles(500000);//
    // Loop until XT1,XT2 & DCO fault flag is cleared
    do
    {
        UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags
        SFRIFG1 &= ~OFIFG;                          // Clear fault flags
    }while (SFRIFG1&OFIFG);                         // Test oscillator fault flag
}

void SetVcoreUp (unsigned int level)
{
  // Open PMM registers for write
  PMMCTL0_H = PMMPW_H;
  // Set SVS/SVM high side new level
  SVSMHCTL = SVSHE + SVSHRVL0 * level + SVMHE + SVSMHRRL0 * level;
  // Set SVM low side to new level
  SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 * level;
  // Wait till SVM is settled
  while ((PMMIFG & SVSMLDLYIFG) == 0);
  // Clear already set flags
  PMMIFG &= ~(SVMLVLRIFG + SVMLIFG);
  // Set VCore to new level
  PMMCTL0_L = PMMCOREV0 * level;
  // Wait till new level reached
  if ((PMMIFG & SVMLIFG))
    while ((PMMIFG & SVMLVLRIFG) == 0);
  // Set SVS/SVM low side to new level
  SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level;
  // Lock PMM registers for write access
  PMMCTL0_H = 0x00;
}



//******************************************************************************
// Main ************************************************************************
// Enters LPM0 and waits for SPI interrupts. The data sent from the master is  *
// then interpreted and the device will respond accordingly                    *
//******************************************************************************

void main(void) {
    WDTCTL = WDTPW + WDTHOLD;               // Stop watchdog timer

    //while (!(P1IN & BIT4));                 // If clock sig from mstr stays low,
                                            // it is not yet in SPI mode
                                            // ????
    //Set VCore = 2 for 16MHz clock
    SetVcoreUp(0x01);
    SetVcoreUp(0x02);


    initClockTo16MHz();
    initGPIO();
    initSPI();

    __bis_SR_register(LPM0_bits + GIE);                 // Enter LPM0, enable interrupts
    __no_operation();


}


//******************************************************************************
// SPI Interrupt ***************************************************************
//******************************************************************************

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_A0_VECTOR))) USCI_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
  uint8_t uca0_rx_val = 0;
  switch(__even_in_range(UCA0IV,4))
  {
    case 0:break;                             // Vector 0 - no interrupt
    case 2:
        uca0_rx_val = UCA0RXBUF;
        if (!(SLAVE_CS_IN & SLAVE_CS_PIN))    //!!!!!!!!!!!!!!!!
        {
            switch (SlaveMode)
            {
                  case (RX_REG_ADDRESS_MODE):
                      ReceiveRegAddr = uca0_rx_val;
                      SPI_Slave_ProcessCMD(ReceiveRegAddr);
                      break;
                  case (RX_DATA_MODE):
                      ReceiveBuffer[ReceiveIndex++] = uca0_rx_val;
                      RXByteCtr--;
                      if (RXByteCtr == 0)
                      {
                          //Done Receiving MSG
                          SlaveMode = RX_REG_ADDRESS_MODE;
                          SPI_Slave_TransactionDone(ReceiveRegAddr);
                      }
                      break;
                  case (TX_DATA_MODE):
                      if (TXByteCtr > 0)
                      {
                          SendUCA0Data(TransmitBuffer[TransmitIndex++]);
                          TXByteCtr--;
                      }
                      if (TXByteCtr == 0)
                      {
                          //Done Transmitting MSG
                          SlaveMode = RX_REG_ADDRESS_MODE;
                          SPI_Slave_TransactionDone(ReceiveRegAddr);
                      }
                      break;
                  default:
                      __no_operation();
                      break;
            }
        }
        break;
    case 4:break;                             // Vector 4 - TXIFG
    default: break;
  }
}

  • CRT return data as as follows and master spi send CMD_TYPE_2_SLAVE

    ABC12^^
    AAAAA^^
    AAAAA^^
    AAAAA^^
    AAAAA^^
    AAAAA^^
    BBBBB^^
    ABC12^^ // When I appear to reset the slave module board
    ABC12^^
    AAAAA^^
    AAAAA^^
    AAAAA^^
    AAAAA^^
  • This looks like its a problem on your master side, so I dont know why resetting the slave fixes it, unless you are resettting the master as well. Even the first transaction is wrong, which should be ABCD12.

    How are you observing the data? Using break points and examining the buffer on the master side?
  • Also, can you check this with our Master Example Code?

    You might also take a look at the SPI section (section 4) of this appnote and make sure your Master code follows the suggestions.
  • I'm sorry I didn't have time to reply to you yesterday. I took a day to verify that spi slave and master mode communications. You're right. It's true that the problem is on the master side, The first time the data is "ABCD12," as you call it, the master also has to be reset.

    1. -- Yesterday I reverified that there was no problem with example slave and master communication without ti-rios spi, and I don't understand why there was a problem before. as follow

    2. -- When I changed master to SPI under my ti-rtos, I found that there was a problem with reading and writing the same slave module. The data I read now were completely chaotic, and I don't know why!  Although I know that the problem arises when I use the spi function SPI _Master_Read_Byte() read  or write slave module data. but I don't know how to modify it! 

    Here are my read and write functions and initialization

    void SPI_Master_Write_Byte(uint8_t cmd, uint8_t *txBuf, uint8_t txBuf_Size)
    {
        uint8_t i;
        uint8_t txBuffer[20];
    
        if(cmd == NULL || txBuf_Size <= 0 || txBuf_Size > 19)
            return;
    
        txBuffer[0] = cmd;
         for(i=1;i<txBuf_Size+1;i++)
             txBuffer[i] = txBuf[i-1];
    
        SPI_Transaction spiTransaction;
        spiTransaction.txBuf = txBuffer;
        spiTransaction.rxBuf = NULL;
        spiTransaction.count = txBuf_Size;
    
        IArg key;
        //
        key = GateMutex_enter(gatemutex_handle);
    
        //cs low
        GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN0);
    
    
    
        if (SPI_transfer(spiA1_master, &spiTransaction) == NULL) {
            System_printf("SPI Bus fault\n");
            System_flush();
        }
    
        //cs hight
        GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN0);
    
        //
        GateMutex_leave(gatemutex_handle, key);
    
    }
    
    void SPI_Master_Read_Byte(uint8_t cmd, uint8_t *rxBuf,uint8_t rxBuf_Size)
    {
        //if(cmd == NULL || rxBuf_Size <= 0 || rxBuf_Size > 19)
         //   return;
    
        SPI_Transaction spiTransaction;
    
        //
        IArg key;
        key = GateMutex_enter(gatemutex_handle);
    
        //cs low
        GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN0);
    
        uint8_t txBuf[1];
        txBuf[0] = cmd;
    
        spiTransaction.txBuf = txBuf;
        spiTransaction.rxBuf = NULL;
        spiTransaction.count = 1;
    
        if (SPI_transfer(spiA1_master, &spiTransaction) == NULL) {
            System_printf("SPI Bus fault\n");
            System_flush();
        }
    
    
        spiTransaction.txBuf = NULL;
        spiTransaction.rxBuf = rxBuf;
        spiTransaction.count = rxBuf_Size;
    
        if (SPI_transfer(spiA1_master, &spiTransaction) == NULL) {
            System_printf("SPI Bus fault\n");
            System_flush();
        }
    
    
        //cs hight
        GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN0);
    
        //
        GateMutex_leave(gatemutex_handle, key);
    
    }
    
    /*
     *  ======== uscia1_spi taskFxn ========
     *  Task for this function is created statically. See the project's .cfg file.
     */
    Void spiA1_master_taskFxn(UArg arg0, UArg arg1)
    {
        /* Create I2C for usage */
        SPI_Params_init(&spiA1_master_Params);
        spiA1_master_Params.transferMode          = SPI_MODE_BLOCKING;
        //spiA1_master_Params.transferCallbackFxn   = spitransferCallbackFxn;
        spiA1_master_Params.mode                  = SPI_MASTER;
        spiA1_master_Params.bitRate               = 500000,            /* bitRate Hz*/
        spiA1_master_Params.dataSize              = 8;
    
        //spiA1_master_Params.frameFormat   = SPI_POL1_PHA0;
    
        spiA1_master = SPI_open(Board_SPIA1_MASTER, &spiA1_master_Params);
        if (spiA1_master == NULL) {
            System_abort("Error Initializing SPI\n");
        }
        else {
            System_printf("SPI Initialized!\n");
        }
        System_flush();
    
        //gatemute
        GateMutex_Params_init(&gatemutex_params);
        gatemutex_handle = GateMutex_create(&gatemutex_params, NULL);
        if (gatemutex_handle == NULL) {
            System_abort("Error GateMutex_create\n");
        }
        else {
            System_printf("GateMutex_create OK!\n");
        }
    
    
    
        while(1){
    
            SPI_Master_Read_Byte(CMD_TYPE_2_SLAVE,SlaveType2,TYPE_2_LENGTH);
            SlaveType0[TYPE_2_LENGTH] = 0;
            printf("SlaveType2:%s\r\n",SlaveType2);
       
            Task_sleep(1000);
            GPIO_toggle(Board_LED_P4_7);;
        }
    
        /* Deinitialized SPI */
        //SPI_close(spiA1_master);
        //System_printf("SPI closed!\n");
        //System_flush();
    }
    
    /*
     *  ======== main ========
     */
    int main(void)
    {
        /* Call board init functions */
        Board_initGeneral();
        Board_initGPIO();
        Board_initUART();
        Board_initI2C();
        Board_initSPI();
    
    
        //i2c master
        taskParams.arg0         = 1000;
        taskParams.stackSize    = TASKSTACKSIZE;
        taskParams.stack        = &i2cB0_master_taskStack;
        Task_construct(&i2cB0_master_taskStruct, (Task_FuncPtr)i2cB0_master_taskFxn, &taskParams, NULL);
    
    
        /* Start BIOS */
        BIOS_start();
    
        return (0);
    }
    

    Printf results

    3. --Finally. I used an oscilloscope to check the SOMIs, and the data returned was the same as the data I had printed. I was a little confused about the SPI_transfer function, which used DMA instead of example code without ti-rtos. I don't know if it's caused by DMA, If so, how do I change my SPI_Master_Read_Byte() and SPI_Master_Write_Byte() function?

    Thanks,

    --xc_mo

  • Can you get rid of the printf() calls? When you use printf() and have CCS attached, CCS will stop the target to read the output (and then resume it).

    Todd
  • hi todd
    I've tried to block printf calls, but the problem isn't with printf,  I looked at the data today with the logic analyzer, The problem occurs when the clock is offset by the data returned by the spi slave module. TI-RTOS 's SPI module data is sent and received on the same function(), and I really don't know what to do with it.

    code 

    Void spiA1_master_taskFxn(UArg arg0, UArg arg1)
    {
        /* Create I2C for usage */
        SPI_Params_init(&spiA1_master_Params);
        spiA1_master_Params.transferMode          = SPI_MODE_BLOCKING;
        //spiA1_master_Params.transferCallbackFxn   = spitransferCallbackFxn;
        spiA1_master_Params.mode                  = SPI_MASTER;
        spiA1_master_Params.bitRate               = 500000,            /* bitRate Hz*/
        spiA1_master_Params.dataSize              = 8;
    
        //spiA1_master_Params.frameFormat   = SPI_POL0_PHA1;
    
        spiA1_master = SPI_open(Board_SPIA1_MASTER, &spiA1_master_Params);
        if (spiA1_master == NULL) {
            System_abort("Error Initializing SPI\n");
        }
        else {
            System_printf("SPI Initialized!\n");
        }
        System_flush();
    
        //gatemute
        GateMutex_Params_init(&gatemutex_params);
        gatemutex_handle = GateMutex_create(&gatemutex_params, NULL);
        if (gatemutex_handle == NULL) {
            System_abort("Error GateMutex_create\n");
        }
        else {
            System_printf("GateMutex_create OK!\n");
        }
    
    
    
        while(1){
    
            txbuf[0] = 0xf0;//cmd;
            txbuf[1] = 0xff;
            txbuf[2] = 0xff;
            txbuf[3] = 0xff;
            txbuf[4] = 0xff;
            txbuf[5] = 0xff;
            spiTransaction.count = 6;
            spiTransaction.rxBuf = rxBuf;
            spiTransaction.txBuf = txbuf;
    
            if (!SPI_transfer(spiA1_master, &spiTransaction)) {
               System_printf("SPI Bus fault\n");
               System_flush();
               return;
            }
    
    }

    thank

    xc.mo

  • txbuf[0]=0xf2,slave module should return “ABCD12”
  • hi everyones

    unconscious I have solved my problem, now take the time to update the status and submit my solution.

    issue1 : the picture I posted is right shift 17 clocks.  In fact, 1 clock offset , and 2 byte(16 clock) is a problem for other reasons. For how to resolve a clock offset, refer to the link below

    https://e2e.ti.com/support/microcontrollers/msp430/f/166/t/616900?tisearch=e2e-sitesearch&keymatch=msp430%20spi

    issue2 : 2 byte(16 clock) offset .  I don't know how, but I hope the code I post will help people who have the same problems as me.

    void SPI_Master_Read_Byte(uint8_t cmd, uint8_t *rxBuf,uint8_t rxBuf_Size)
    {
        uint8_t txBuffer[20];
    
        if(cmd == NULL || rxBuf_Size <= 0)
            return;
    
        SPI_Transaction spiTransaction;
    
        IArg key;
        //
        key = GateMutex_enter(gatemutex_handle);
    
        //cs low
        Board_SPIA1_MASTER_CS_LOW;
    
    
        txBuffer[0] = cmd;
        txBuffer[1] = 0;
        spiTransaction.txBuf = txBuffer;
        spiTransaction.rxBuf = NULL;
        spiTransaction.count = 1;
        if (SPI_transfer(spiA1_master, &spiTransaction) == NULL) {
            System_printf("SPI Bus fault\n");
            System_flush();
        }
    
        uint8_t count;
        count = rxBuf_Size;
        while(count--){
            spiTransaction.txBuf = NULL;
            spiTransaction.rxBuf = rxBuf++;
            spiTransaction.count = 1;
            if (SPI_transfer(spiA1_master, &spiTransaction) == NULL) {
                System_printf("SPI Bus fault\n");
                System_flush();
            }
        }
    
        //cs hight
        Board_SPIA1_MASTER_CS_HIGH;
    
        //
        GateMutex_leave(gatemutex_handle, key);
    
    }
    
    Void spiA1_master_taskFxn(UArg arg0, UArg arg1)
    {
        /* Create spi for usage */
        SPI_Params_init(&spiA1_master_Params);
        spiA1_master_Params.transferMode          = SPI_MODE_BLOCKING;
        //spiA1_master_Params.transferCallbackFxn   = spitransferCallbackFxn;
        spiA1_master_Params.mode                  = SPI_MASTER;
        spiA1_master_Params.bitRate               = 500000,            /* bitRate Hz*/
        spiA1_master_Params.dataSize              = 8;
    
        spiA1_master_Params.frameFormat   = SPI_POL1_PHA1;
    
        spiA1_master = SPI_open(Board_SPIA1_MASTER, &spiA1_master_Params);
        if (spiA1_master == NULL) {
            System_abort("Error Initializing SPI\n");
        }
        else {
            System_printf("SPI Initialized!\n");
        }
        System_flush();
    
        //gatemute
        GateMutex_Params_init(&gatemutex_params);
        gatemutex_handle = GateMutex_create(&gatemutex_params, NULL);
        if (gatemutex_handle == NULL) {
            System_abort("Error GateMutex_create\n");
        }
        else {
            System_printf("GateMutex_create OK!\n");
        }
    
    
        while(1){
    
            
            SPI_Master_Read_Byte(CMD_TYPE_0_SLAVE,SlaveType0,TYPE_0_LENGTH);
            //SlaveType0[TYPE_0_LENGTH] = 0;
            printf("SlaveType0:0x%x\r\n",SlaveType0[0]);
            Task_sleep(200);
    
            SPI_Master_Read_Byte(CMD_TYPE_1_SLAVE,SlaveType1,TYPE_1_LENGTH);
            //SlaveType0[TYPE_1_LENGTH] = 0;
            printf("SlaveType1:0x%x  0x%x\r\n",SlaveType1[0],SlaveType1[1]);
            Task_sleep(200);
    
            SPI_Master_Read_Byte(CMD_TYPE_2_SLAVE,SlaveType2,TYPE_2_LENGTH);
            //SlaveType0[TYPE_2_LENGTH] = 0;
            printf("SlaveType2:%s\r\n",SlaveType2);
    
            //System_printf("%s\r\n",rxbuf);
            //System_flush();
            
            Task_sleep(1000);
            GPIO_toggle(Board_LED_P1_0);;
        }
    
    
        /* Deinitialized SPI */
        //SPI_close(spiA1_master);
        //System_printf("SPI closed!\n");
        //System_flush();
    }
    
    /*
     *  ======== main ========
     */
    int main(void)
    {
        /* Call board init functions */
        Board_initGeneral();
        Board_initGPIO();
        Board_initUART();
        Board_initI2C();
        Board_initSPI();
        //spi master
        taskParams.arg0         = 1000;
        taskParams.stackSize    = spiA1_TASKSTACKSIZE;
        taskParams.stack        = &spiA1_master_taskStack;
        Task_construct(&spiA1_master_taskStruct, (Task_FuncPtr)spiA1_master_taskFxn, &taskParams, NULL);
    
        /* Start BIOS */
        BIOS_start();
    
        return (0);
    }
    
    

    best regards

    xc.mo

**Attention** This is a public forum