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.

RTOS/CC3220SF-LAUNCHXL: Inconsistent Behavior with Different Modes of SPI Master

Part Number: CC3220SF-LAUNCHXL
Other Parts Discussed in Thread: CC3220SF

Tool/software: TI-RTOS

Dear Support:

I am experiencing some weirdness with the CC3220 SPI driver that was hoping you could explain.  I am using the CC3220SF LP and SDK v1.50 and using the following code to start a master SPI transaction:

SPI_Params_init(&MasterSpiParams);
MasterSpiParams.bitRate = 1000000;
MasterSpiParams.mode = SPI_MASTER;
MasterSpiParams.frameFormat = SPI_POL0_PHA1;
MasterSpiParams.transferCallbackFxn = HostSPI_CallbackFxn;
MasterSpiParams.transferMode = SPI_MODE_CALLBACK;
MasterSpiParams.transferTimeout = 100000;
MasterSpiParams.dataSize = 8;
hMasterSPI = SPI_open(CC3220SF_LAUNCHXL_SPI1, &MasterSpiParams);
if( hMasterSPI == NULL )
{
    System_printf("SPI initialization failed! Leaving task...\n");
    System_abort("Error initializing SPI\n");
    return;
}
else
{
    System_printf("SPI successfully initialized\n");
}
masterTransaction.rxBuf = NULL;
masterTransaction.txBuf = (uint8_t *)SPITaskInfo.TxtBuffer;
masterTransaction.count = 128;
transferOK = SPI_transfer(hMasterSPI, &masterTransaction);
if( transferOK )
{
    Semaphore_pend( hSemaSPIVoice, BIOS_WAIT_FOREVER );
}
else
{
    Message("Unsuccessful master SPI transfer");
}

This code is using a callback with the following callback function:

void HostSPI_CallbackFxn(SPI_Handle handle, SPI_Transaction *transaction)
{
Semaphore_post(hSemaSPIVoice);
}

where it posts a semaphore when the SPI transaction is completed.  It is working, however it only transfer 2 bytes instead of the desired 128.   In fact, no matter what I set the transfercount to, it only sends 2 bytes.  However if I change this code to use a callback as such:

SPI_Params_init(&MasterSpiParams);
MasterSpiParams.bitRate = 1000000;
MasterSpiParams.mode = SPI_MASTER;
MasterSpiParams.frameFormat = SPI_POL0_PHA1;
MasterSpiParams.transferMode = SPI_MODE_BLOCKING;
MasterSpiParams.transferTimeout = 100000;
MasterSpiParams.dataSize = 8;
hMasterSPI = SPI_open(CC3220SF_LAUNCHXL_SPI1, &MasterSpiParams);
if( hMasterSPI == NULL )
{
    System_printf("SPI initialization failed! Leaving task...\n");
    System_abort("Error initializing SPI\n");
    return;
}
else
{
    System_printf("SPI successfully initialized\n");
}
masterTransaction.rxBuf = NULL;
masterTransaction.txBuf = (uint8_t *)SPITaskInfo.TxtBuffer;
masterTransaction.count = 128; 
transferOK = SPI_transfer(hMasterSPI, &masterTransaction);
if( !transferOK )
{
    Message("Unsuccessful master SPI transfer");
}

this works too, but except it only transfer 2 bytes instead of the desired 128.  Reducing transfercount to 64 or less causes the desired number of bytes to transfer properly.  To get it to transfer 128 bytes, I had to change the spiCC3220SDMAHWAttrs array in the CC3220SF_LAUNCHXL.c file as such:

const SPICC32XXDMA_HWAttrsV1 spiCC3220SDMAHWAttrs[CC3220SF_LAUNCHXL_SPICOUNT] = {
/* index 0 is reserved for LSPI that links to the NWP */
{
.baseAddr = LSPI_BASE,
.intNum = INT_LSPI,
.intPriority = (~0),
.spiPRCM = PRCM_LSPI,
.csControl = SPI_SW_CTRL_CS,
.csPolarity = SPI_CS_ACTIVEHIGH,
.pinMode = SPI_4PIN_MODE,
.turboMode = SPI_TURBO_OFF,
.scratchBufPtr = &spiCC3220SDMAscratchBuf[CC3220SF_LAUNCHXL_SPI0],
.defaultTxBufValue = 0,
.rxChannelIndex = UDMA_CH12_LSPI_RX,
.txChannelIndex = UDMA_CH13_LSPI_TX,
.minDmaTransferSize = 100,
.mosiPin = SPICC32XXDMA_PIN_NO_CONFIG,
.misoPin = SPICC32XXDMA_PIN_NO_CONFIG,
.clkPin = SPICC32XXDMA_PIN_NO_CONFIG,
.csPin = SPICC32XXDMA_PIN_NO_CONFIG
},
{
.baseAddr = GSPI_BASE,
.intNum = INT_GSPI,
.intPriority = (~0),
.spiPRCM = PRCM_GSPI,
.csControl = SPI_HW_CTRL_CS,
.csPolarity = SPI_CS_ACTIVELOW,
.pinMode = SPI_4PIN_MODE,
.turboMode = SPI_TURBO_OFF,
.scratchBufPtr = &spiCC3220SDMAscratchBuf[CC3220SF_LAUNCHXL_SPI1],
.defaultTxBufValue = 0,
.rxChannelIndex = UDMA_CH6_GSPI_RX,
.txChannelIndex = UDMA_CH7_GSPI_TX,
.minDmaTransferSize = 100,
.mosiPin = SPICC32XXDMA_PIN_07_MOSI,
.misoPin = SPICC32XXDMA_PIN_06_MISO,
.clkPin = SPICC32XXDMA_PIN_05_CLK,
.csPin = SPICC32XXDMA_PIN_08_CS
}
};

more specifically, I had to change the .minDmaTransferSize of the 2nd SPI entry from 100 to something greater that 128 like 130 and then the SPI transfer would perform a 128 byte transfer.  

So by setting the .minDmaTransferSize to 130, all SPI transfers up to 128 worked successfully, but only when using blocking mode.  However with .minDmaTransferSize at 100, a 128 byte transfercount only transfers 2 bytes.  And when using the callback mode, all SPI transfers only transfer 2 bytes no matter what I set to transfercount to between 2 and 128.  

Do you know what is going on here and preventing me from using the callback method and why i have to set .minDmaTransferSize to something greater that the transfercount to get it to work?  Your thoughts?

Thanks,
Tim

  • just correcting a typo - the 2nd SPI example is using blocking mode, not "callback" like I mistyped.  So to be clear, the 1st method uses a callback and the 2nd method uses blocking mode.  The blocking mode works no problem, but had to change .minDMATransferSize to something greater than the transfer count to get it to work.  Does this make sense as to why I am having to do this and using the callback method only transfer 2 bytes no matter what I set the transfer count to @ 2 or greater.

    Thanks,
    Tim

  • Dear Support:

    One other important and pertinent piece of information. The big reason this is so weird is that this used to work before. I was using SDK v1.30 before and both blocking and callback methods worked with no issues this code. So I went through the exercise of taking this same code that I had moved up to use SDK v.150 and back ported to run with v.130 and wahla - it still works just as it did before. So bottom line - it appears something has happened between SDK v1.30 and SDK v1.50 where my SPI master code worked fine in blocking and callback modes and now, it no longer works correctly using the same code between these 2 SDKs, yet now moving to SDK v1.50 - it acts weird as described in my earlier messages. Any thoughts on what would cause my code to not work with SPI master mode by going from v1.30 to v1.50?

    BTW - I have a lot of code in this project doing a lot of stuff. So it's rather amazing that everything else works by moving to SDK v1.50 except for SPI Master mode. Your thoughts on what changed and what is going on here?

    Thanks,
    Tim
  • HI Tim,

    The 1.50 version of the SDK has a bugged SPI driver.
    e2e.ti.com/.../647943

    If you are unable to either revert from 1.50 to 1.40 or upgrade to 1.60/later, what you could do is take the SPICC32XXMDA.c file from the 1.60 SDK and diff it against the 1.50 for the fix, or copy it into your 1.50 SDK and overwrite the bugged driver.

    Let me know if that doesn't work.

    Regards,
    Michael
  • Hey Michael:

    Indeed that fixed it - thanks for your help and advice.  I took the file you indicated from SDK v1.60 and moved it to my SDK v1.50 and rebuilt the drivers file (i.e., drivers_cc32xx.aem4) in the lib directory of the drivers directory and it's now back to working. 

    Thanks,
    Tim