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.

CC3220SF-LAUNCHXL: SPI_transfer read is incorrect and different from correct value on logic analyzer

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

I am attempting to establish basic SPI communication between the CC3220SF-LAUNCHXL (SPI master) and an external sensor (Adafruit LIS3MDL) using SPI_transfer(). I am building an application in FreeRTOS which uses Simplelink SDK version 2.10.00.04.

I am successfully transmitting a device ID read command (0xCF) to the external sensor. On the logic analyzer, the sensor is responding with the expected value (0x3D). However, the read buffer is receiving a value of 0xE3. I can send transfer over and over and the value is consistently 0xE3.

Is there some basic configuration (software or hardware) that I could have wrong here?

Spi Config (index CC3220SF_LAUNCHXL_SPI1):

    {
        .baseAddr = GSPI_BASE,
        .intNum = INT_GSPI,
        .intPriority = (~0),
        .spiPRCM = PRCM_GSPI,
        .csControl = SPI_SW_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_NO_CONFIG
    }

SPI_open call:

    SPI_Params_init(&xSpiParams);
    xSpiParams.transferMode = SPI_MODE_BLOCKING;
    xSpiParams.transferTimeout = SPI_WAIT_FOREVER;
    xSpiParams.transferCallbackFxn = NULL;
    xSpiParams.mode = SPI_MASTER;
    xSpiParams.bitRate = 1000000;
//    xSpiParams.bitRate = 500000;
    xSpiParams.dataSize = 8;
    xSpiParams.frameFormat = SPI_POL0_PHA0;
//    xSpiParams.frameFormat = SPI_POL1_PHA1;
    xSpiHandle = SPI_open(CC3220SF_LAUNCHXL_SPI1, &xSpiParams);

SPI Read code:

static int32_t prlSpiRead(void *handle,
                          uint8_t reg,
                          uint8_t *bufp,
                          uint16_t len)
{
    int32_t lRetVal = 0;
    SPI_Transaction xSpiTransaction = {0};
    SPI_Handle xSpiHandle = *((SPI_Handle*) handle);

    memset(xSpiTxBuff, 0xA5, 100);
    memset(xSpiRxBuff, 0x00, 100);

    GPIO_write(CC3220_LIS3MDL_SPI_CS_PIN, 0);
    xSpiTxBuff[0] = (reg | 0xC0);   //read + auto increment
    xSpiTransaction.count = 1+len;  // 1 command byte + number of expected bytes
    xSpiTransaction.txBuf = (void*) xSpiTxBuff;
    xSpiTransaction.rxBuf = (void*) xSpiRxBuff;
    SPI_transfer(xSpiHandle, &xSpiTransaction);
    GPIO_write(CC3220_LIS3MDL_SPI_CS_PIN, 1);

    memcpy(bufp, &xSpiRxBuff[1], len);

    if(SPI_TRANSFER_COMPLETED != xSpiTransaction.status)
    {
        lRetVal = -1;
    }

    return lRetVal;
}

  • Hello Daniel,

    Because the data is there physically, most likely you have the incorrect SPI Phase or polarity set for the data transmission. Please could you please try changing frameFormat configuration?

  • I tried each of the 3 other polarity/phase combinations to no success.

    [Polarity 0 Phase 1] and [Polarity 1 Phase 0] each received the incorrect value in the code and on the scope.

    [Polarity 0 Phase 0] and [Polarity 1 Phase 1] each produce the correct response from the sensor on the scope (0x3D) and the incorrect value in the code (0xE3) and is repeatable.

    From the LIS3MDL datasheet for SPI communication (Section 5.2): "SDI and SDO are respectively the serial port data input and output. Those lines are driven at the falling edge of SPC and should be captured at the rising edge of SPC." To me this sounds like the correct setting should be Polarity 1 Phase 1 (Clock active low, sampling occurs on rising edge).

    I also tried decreasing the clock rate to 500KHz, no effect.

    CC3220SF SPI phase/polarity:

    lis3mdl.pdf

  • It sounds like you tried all 4 format modes. In that case, it sounds like the issue would be pointing towards the hardware, unless the pin configuration was done incorrectly.

    Could you check and see that the MISO line is not connected to any other components? Are you using a cc3220 TI launchpad or a custom board?

    Could you try running one of the SPI (both master and slave if you have 2 launchpads) examples from the SDK? This could serve as a baseline.

  • I am using a CC3220-LAUNCHXL (purchased recently) and yes the MISO line is not connect to any other components besides the sensor unless there is something internal.

    As far as the demo, I do not currently have access to a second launchpad to test the SPI demo. Is there a SPI demo that utilizes a single CC3220 dev board in some kind of loopback configuration or self-test? That being said, I have referenced the demo code and I do not see anything obvious that I am doing differently, including the spiCC3220SDMAHWAttrs configuration and transfer code.

    More datapoints:

    I tried to use pin 53 as the MISO pin (instead of pin 6). I only did a couple of tests with this pin and I still see the correct transfer on the logic analyzer but in this case I see an 0xFF value received in the code. I also hooked up a Rigol oscilloscope and the real voltage signals appear clean and match up with the logic analyzer. The disconnect continues to appear to be internal to the CC3220 SPI hardware.

    Are there other configuration parameters that could affect the internal SPI hardware? I tried changing GPIO parameters for pin 6 (GPIO_15) to no affect although I would assumer that SPI_init() overwrites any GPIO parameters (I am calling SPI_init() after GPIO_init()).

    I also came across the following forum post (https://e2e.ti.com/support/wireless-connectivity/wi-fi-group/wifi/f/wi-fi-forum/774668/ccs-cc3220sf-launchxl-spi-communication-reading-wrong-data) which indicates a similar situation to mine. I tried adding a 1000 ohm resister in series with the MISO connection which also had no effect on anything I am seeing. Are there other examples of requiring additional circuitry to correct a SPI (or other) signal for the CC3220SF?

  • Hi Daniel,

    I have seen an issue before with some devices connected to CC3220SF via SPI. Long story short, my issue was that the bits on MISO were not getting clocked in correctly. Sounds like a similar story here. Again, it only occurred with some peripherals. For example, I tried a CC3220 to CC3220 with SPI examples and did not experience the issue, but when I connected a second device instead of the second CC3220, I saw the data was read incorrectly. 

    When debugging, I found that when I placed a oscilloscope probe on the CLK line, the data was now read correctly. The permanent solution was to place a similar size capacitor of the oscillo-probe on that SPI_CLK pin. This was all done on the launchpad. My guess is that there is something high-frequency going on causing the data to be clocked in incorrectly, but ofcourse could not be visible because the probe was now a filter.  

    Assuming you have tried all possible software attempts, then this is my final suggestion. SDK 2 is quite old so I would suggest trying to read from this device with latest SDK. I understand you would like to use FreeRTOS, but this is simply a debug step. 

    I haven't tried to use the SPI master example as a loopback, i'm not sure if it's possible. 

  • Ok, wow, that was a trip down the rabbit hole.

    I finally got it working in combination with your story and the other forum post I mentioned previously (https://e2e.ti.com/support/wireless-connectivity/wi-fi-group/wifi/f/wi-fi-forum/774668/ccs-cc3220sf-launchxl-spi-communication-reading-wrong-data).

    Long story short, I added a 47ohm resistor in series with the SPI CLK pin and it finally worked (no adjustments to the other pins, Polarity 1 Phase 1, and 1000000 bit rate).

    Long story: At first I had tried a 100ohm resistor (and other values) on the MISO line because I misunderstood the forum post (I thought they had placed a 100ohm resistor on the MISO line) which accomplished nothing. Then, I thought to try it on the clock pin because you had specified your capacitance fix being on the clock pin. I tried a few capacitors on the clock pin which also did not appear to have any effect. However, a 100ohm resistor did not fix my issue but it did cause the logic analyzer, oscilloscope, and the final value in the RX buffer to all match. I tried a 1k ohm resistor which also resulted in the values matching up but still being incorrect (and also different from the 100 ohm resistor). Eventually, I tried a 47ohm resistor which did cause everything to match up correctly with the expected value (0x3D).