This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Force MOSI low in between SPIM transactions

We are using the SPIM driver to support a propriety 1-wire protocol used by a TI LED driver (TLC59731). To do this, we're using the MOSI pin exclusively and, for it to work properly, we need to guarantee that the pin is low in between SPI transfers writes to the device.

For reasons specific to the topology of our system, there is a weak pull-up that appears to pull the line high in between transactions, which prevents the driver from functioning properly for our needs. The data transfers themselves look fine, but it appears we have no control of what happens to the line in between them. I am assuming this is because the pin goes into a high-impedance state when not transferring data. Is this correct? If so, is there any way to modify this behavior?

I've attempted enabling the internal pull-down resistor on the pin, but this doesn't have a noticeable effect. I've also tried initializing the SPI peripheral immediately before a transaction and uninitializing it immediately after the transaction completes, but there is still a small period of time where the line remains high, interfering with our ability to properly format the 1-wire packet

Below is a scope shot of the behavior we are seeing with and without SPI init/uninit around transactions:

Here is our initialization code:

    nrfx_spim_config_t spi_config = NRFX_SPIM_DEFAULT_CONFIG;
    spi_config.frequency      = SPI_FREQUENCY;
    spi_config.ss_pin         = NRFX_SPIM_PIN_NOT_USED;
    spi_config.miso_pin       = NRFX_SPIM_PIN_NOT_USED;
    spi_config.mosi_pin       = inLEDDevice->data;
    spi_config.sck_pin        = NRFX_SPIM_PIN_NOT_USED;
    spi_config.ss_active_high = false;
    spi_config.orc            = 0x00;
    errCode = nrfx_spim_init(&spi, &spi_config, _SPIMEventHandler, NULL);

And here is our code to initiate a SPI transfer:

    require_action( mTLC59731Info.spiTransferDone, exit, errCode = NRF_ERROR_BUSY );

    _BytesToSPIBuffer( &commandByte, TLC59731_NUM_COMMAND_BYTES, mTLC59731Info.txBuf.commandBytes );
    _BytesToSPIBuffer( ( uint8_t * ) inColor, sizeof( Color_t ), mTLC59731Info.txBuf.colorBytes );

    nrfx_spim_xfer_desc_t xfer_desc = NRFX_SPIM_XFER_TRX(
            (uint8_t *) &mTLC59731Info.txBuf,
            sizeof( TLC59731SPITransferBuf_t ),
            NULL,
            0 );

    errCode = nrfx_spim_xfer( &spi, &xfer_desc, 0 );
    require_noerr( errCode, exit );

    mTLC59731Info.spiTransferDone = false;

Note that we are using SDK 15 and nrfx 1.6.1.

Parents
  • Hi, if the MSB in the last byte in the tx buffer is 1, MOSI will go high again after the transaction is done. You can try to add a 0x00 byte at the end of the tx buffer. This should keep the MOSI line low between the transactions.

  • Hi Stian,

    Thanks for your reply! In both cases the last byte in the buffer has a value of zero, so the MSB will be zero as well. I should also note that the line does go low when it is left open. The issue occurs when it is attached to a level shifter, which has an internal pull-up resistor. It looks like the line just stops being driven and is allowed to reach the pull-up voltage. I'm looking for a way to actively drive the line low in between transactions.

  • Hi, I'm sorry but I'm not able to reproduce the behavior. I tried attaching a 10k pull up to the MOSI line and it is nice and stable at 0 volts between the transactions. Using the same init code as you posted earlier (except that it seems to be failing if I set sck pin to not used), and same nrfx driver version.

    Are you doing anything specific in the SPI event handler after the transaction is done? You are using nRF52840 right? Which version of the chip is it? It's written on the chip.

  • I'm doing nothing specific in between SPI transactions, but I believe I found the discrepancy. I left out an important detail: I've been using SPIM3 for the duration of my testing here. When I switch over to other SPI peripherals, such as SPIM2, I see behavior that's consistent with what you've described, where the line goes low in between transactions even if there's a pull-up in place. Looks to me like a difference in the SPI hardware peripheral instances. Could you try on SPIM3 and see if you can reproduce the behavior that I'm seeing?

    I am using an NRF52840, Rev. C, so I think SPIM3 should be fully supported. The exact version printed on the chip is NRF52840 Q1AAC0 1833DZ.

Reply
  • I'm doing nothing specific in between SPI transactions, but I believe I found the discrepancy. I left out an important detail: I've been using SPIM3 for the duration of my testing here. When I switch over to other SPI peripherals, such as SPIM2, I see behavior that's consistent with what you've described, where the line goes low in between transactions even if there's a pull-up in place. Looks to me like a difference in the SPI hardware peripheral instances. Could you try on SPIM3 and see if you can reproduce the behavior that I'm seeing?

    I am using an NRF52840, Rev. C, so I think SPIM3 should be fully supported. The exact version printed on the chip is NRF52840 Q1AAC0 1833DZ.

Children
Related