Electrical – SPI Read Problem

spi

I have done the following changes and also followed the sequence as explained, to read response from the Si4455. As mentioned in the datasheet w.r.t Fig(1) below, i.e. Make CS low send API command followed parameters depending on the command, once this transaction is over make CS high.
enter image description here

I have written a functions which sends command as well as reads response bytes with the necessary changes.

   unsigned char GetResponse_CTS(unsigned char bytecount, unsigned char *pData)
{
    cts_flag = 0;
    unsigned int errcnt;
    errcnt = RADIO_CTS_TIMEOUT;
    unsigned char cts_byte=0;
    unsigned char cts_check_cmd = 0x44;  //CTS Command

    while(errcnt!=0)
            {
                MAP_SPICSEnable(GSPI_BASE); //Enable CS
                MAP_SPITransfer(GSPI_BASE,&cts_check_cmd,0,1,0);  //Send CTS
                MAP_SPITransfer(GSPI_BASE,0,&cts_byte,1,0);   //Get 0xFF
                if(cts_byte == 0xFF)
                {
                    if(bytecount)   //If need to further read response bytes
                    {
                        MAP_SPITransfer(GSPI_BASE,0,pData,bytecount,0);

                    }
                    MAP_SPICSDisable(GSPI_BASE);  //Disable CS after reads
                    break;
                }
                MAP_SPICSDisable(GSPI_BASE); //Disable CS after getting 0xFF
                errcnt--;
            }

    if(errcnt == 0)
    {
        while(1)
        {
            Message("CTS Time Out \r\n");
        }
    }
    if(cts_byte == 0xFF)
    {
        cts_flag = 1;

    }
    return cts_byte;

}

//Poll CTS and return CTS response
unsigned char PollCTS()
{
    return GetResponse_CTS(0,0);
}

//Transfer a byte to Si4455 from CC3200
void SpiWriteByte(unsigned char byteToWrite)
{
    MAP_SPITransfer(GSPI_BASE,&byteToWrite,0,1,0);
}



 void SendCmds(unsigned char ByteCount, unsigned char* pData)
{
    while(!cts_flag)
    {
        PollCTS();
    }
    MAP_SPICSEnable(GSPI_BASE);
    MAP_SPITransfer(GSPI_BASE,pData,0,ByteCount,0);
    MAP_SPICSDisable(GSPI_BASE);
    cts_flag=0;
}

 //Send commands and get response for Si4455
  unsigned char SendCmdGetResp(unsigned char cmdByteCount, unsigned char *pCmdData, unsigned char respByteCount, unsigned char* pRespData)
{
    SendCmds(cmdByteCount, pCmdData);
    return GetResponse_CTS(respByteCount, pRespData);
}

The below is the main function which sends a GET_INT_STATUS command i.e. 0x20 followed by 3 parameters. Then SendCmdGetResp,it sends the API command 0x20 followed by 3 parameters. Then it makes CS low and checks for CTS, if positive, it sends 8 dummy bytes to read the response bytes from Si4455. Once this transaction is over, the CS is pulled back high.

   void GetIntStatus(unsigned char PH_CLR_PEND,unsigned char MODEM_CLR_PEND, unsigned char CHIP_CLR_PEND)
{
    radioCmd[0] = SI4455_CMD_ID_GET_INT_STATUS;   //0x20 command
    radioCmd[1] = PH_CLR_PEND;         //parambyte0
    radioCmd[2] = MODEM_CLR_PEND;     //parambyte1
    radioCmd[3] = CHIP_CLR_PEND;      //parambyte2

   //SI4455_CMD_ARG_COUNT_GET_INT_STATUS = 4 (send 4 bytes)
   //SI4455_CMD_REPLY_COUNT_GET_INT_STATUS = 8 (read 8 response bytes)

    SendCmdGetResp(SI4455_CMD_ARG_COUNT_GET_INT_STATUS, radioCmd, SI4455_CMD_REPLY_COUNT_GET_INT_STATUS, radioCmd);

    Si4455Cmd.GET_INT_STATUS.INT_PEND       = radioCmd[0];
    Si4455Cmd.GET_INT_STATUS.INT_STATUS     = radioCmd[1];
    Si4455Cmd.GET_INT_STATUS.PH_PEND        = radioCmd[2];
    Si4455Cmd.GET_INT_STATUS.PH_STATUS      = radioCmd[3];
    Si4455Cmd.GET_INT_STATUS.MODEM_PEND     = radioCmd[4];
    Si4455Cmd.GET_INT_STATUS.MODEM_STATUS   = radioCmd[5];
    Si4455Cmd.GET_INT_STATUS.CHIP_PEND      = radioCmd[6];
    Si4455Cmd.GET_INT_STATUS.CHIP_STATUS    = radioCmd[7];
}

Even after doing the respective changes, I still receive the read response bytes as 0xFF. This time, I have read the explanation and and have carefully made the respective changes, yet the same response. Please, it would be of great help, if folks can check on my code and advise me if I have missed anything, I have cross check it and dont find anything wrong.

Link to the SPITransfer function

Best Answer

You have various problems in your code structure but the most glaring one is the improper use of the select line of the SPI interface. This signal must start from a high at the start of the transaction and go low and stay low during the entire transaction after which it must go back high again. Your code is flipping the select on and off for every eight clocks of the transfer.

This is very clearly depicted in the data sheet for the device....

enter image description here

Notice how the read process consists of a single SPI select transaction where the command byte is sent out and then immediately followed by a sequence of repetitive 8-bit reads until the CTS value changes from 0x00 to one with 0xFF. Immediately following the 0xFF value the next sequence of 0 -> N 8-bit values are clocked in as the read response value. Only after the final response byte is received is the SPI select line returned back high again.