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.

Related