3-line SPI configuration for send and receive data at the same time

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

3-line SPI configuration for send and receive data at the same time

3,871 Views
Gamka
Contributor III

I am using i.mxrt 1064 and MCUXpresso. I am trying to use 3-line SPI, as described in the attached figure Interface I. (The interface II is for normal 4-line SPI). How should I configure the lpspi_transfer_t *transfer for LPSPI_MasterTransferBlocking?

In Peripherals I have configured:
Single bit data pins: SDI input/SDI output

I have tried the following:
lpspi_transfer_t masterXfer;
masterXfer.txData = rxBuffer;
masterXfer.rxData = txBuffer;
masterXfer.dataSize = 10;
masterXfer.configFlags =
kLPSPI_MasterPcs0 | kLPSPI_MasterPcsContinuous | kLPSPI_SlaveByteSwap;
status_t retval = LPSPI_MasterTransferBlocking(LPSPI1, &masterXfer);
But with this configuration I will get error 4 (i.e. invalid argument), since in fsl_lspi.c it is commented
/* The 3-wire mode can't send and receive data at the same time. */. 

So is there a way to send and receive at the same time, i.e. get the situation in attached figure?

Labels (1)
0 Kudos
Reply
5 Replies

3,169 Views
PhilP
Contributor I

I'm trying to do this too, on the i.MX RT1176. Did the applications team provide a solution please?

0 Kudos
Reply

3,731 Views
alank
Contributor II

Hello @Gamka 

We're having the same problem, how to connect a 3-wire SPI half-duplex (SCK, CSn, SDIO) to a 4-wire SPI full-duplex port (SCK, CSn, MOSI, MISO). We're using the NXP i.MX RT1050 family.

In hardware we plan to do the following:-

alank_0-1621589643253.png

Only connect one of the datelines, doesn't matter which, MISO or MISO of a LPSPI port up to the SDIO pin. In this case MOSI-->SDIO and left MISO floating.

Then in the MCUXpresso Config tool, define the PINCFG register used MOSI (SDO) pin in LPSPI port (its under 'Single bit data pins'). In this case choose 'SDO input/SDO output'.

alank_2-1621589900212.png

alank_3-1621590047841.png

Note: this is just theory, we haven't tried it out yet.

0 Kudos
Reply

3,779 Views
Alexis_A
NXP TechSupport
NXP TechSupport

Hello @Gamka ,

Use polling b2b example and try adding this to the project,  to LPSPI_MasterTransferNonBlocking() in fsl_lpspi.c:

/* If there is not rxData , can mask the receive data (receive data is not stored in receive FIFO).
* For master transfer , we'd better not masked the transmit data in TCR since the transfer flow is hard to
* controlled by software.*/
if (handle->rxData == NULL)
{
isRxMask = true;
handle->rxRemainingByteCount = 0;
}
if (handle->txData == NULL)
{
isTxMask = true;
handle->txRemainingByteCount = 0U;
}

 

Change the master from blocking to nonblocking. (reference slave example)

 

/*Start master transfer, transfer data to slave.*/
masterXfer.txData = masterTxData;
masterXfer.rxData = NULL;
masterXfer.dataSize = TRANSFER_SIZE;
masterXfer.configFlags =
EXAMPLE_LPSPI_MASTER_PCS_FOR_TRANSFER | kLPSPI_MasterPcsContinuous | kLPSPI_SlaveByteSwap;

LPSPI_MasterTransferNonBlocking(EXAMPLE_LPSPI_MASTER_BASEADDR, &g_s_handle, &masterXfer);

while (!isTransferCompleted)
{
}

/* Set master transfer ready to receive data */
isTransferCompleted = false;
volatile uint32_t sr = LPSPI1->SR;
PRINTF("%x\n", sr);

/* Start master transfer, receive data from slave */
masterXfer.txData = NULL;
masterXfer.rxData = masterRxData;
masterXfer.dataSize = TRANSFER_SIZE;
masterXfer.configFlags =
EXAMPLE_LPSPI_MASTER_PCS_FOR_TRANSFER | kLPSPI_MasterPcsContinuous | kLPSPI_SlaveByteSwap;
LPSPI_MasterTransferNonBlocking(EXAMPLE_LPSPI_MASTER_BASEADDR, &g_s_handle, &masterXfer);

LPSPI1->TCR |= LPSPI_TCR_TXMSK_MASK;

while (!isTransferCompleted)
{
}

 Add the following under MasterUserCallBack and SlaveUserCallBack, and must be before the PRINTF.

#define LPSPI_TCR_RXTXMSK (LPSPI_TCR_RXMSK_MASK | LPSPI_TCR_TXMSK_MASK)

void LPSPI_MasterUserCallback(LPSPI_Type *base, lpspi_master_handle_t *handle, status_t status, void *userData)
{
LPSPI1->TCR &= ~LPSPI_TCR_RXTXMSK;
LPSPI1->CFGR1 &= ~LPSPI_CFGR1_OUTCFG_MASK;

 The requirements for half-duplex are - OUTCFG (set by LPSPI_Master/SlaveTransferNonBlocking when it detects PINCFG is 1 or 2), PINCFG, and RxMSK/TxMSK.

Best Regards,

Alexis Andalon

0 Kudos
Reply

3,554 Views
yklee1
Contributor II

Hello Alexis,

 

I could not find where I should add below code you mentioned.

Could you please let me know where I should add it?

#define LPSPI_TCR_RXTXMSK (LPSPI_TCR_RXMSK_MASK | LPSPI_TCR_TXMSK_MASK)

void LPSPI_MasterUserCallback(LPSPI_Type *base, lpspi_master_handle_t *handle, status_t status, void *userData)
{
LPSPI1->TCR &= ~LPSPI_TCR_RXTXMSK;
LPSPI1->CFGR1 &= ~LPSPI_CFGR1_OUTCFG_MASK;

I am using SDK2.10.1 for i.mxRT1060 EVK.

And should the pin configuration be modified together?

 

Best Regards,

YK Lee

0 Kudos
Reply

3,849 Views
Alexis_A
NXP TechSupport
NXP TechSupport

Hello @Gamka,

Unfortunately, there isn't any information about how to configure the SPI in 3-wire mode, I'm looking with the applications team how to set up this mode. I will let you know when I receive some feedback.

Best Regards,

Alexis Andalon

0 Kudos
Reply