<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Is LPSPI Slave Read-Only Half-Duplex Possible on RT1176? in i.MX RT Crossover MCUs</title>
    <link>https://community.nxp.com/t5/i-MX-RT-Crossover-MCUs/Is-LPSPI-Slave-Read-Only-Half-Duplex-Possible-on-RT1176/m-p/1527961#M21764</link>
    <description>&lt;P&gt;Hi,&lt;/P&gt;
&lt;P&gt;Yes, my colleague had a test with LPSPI SIN to do data receive with Half duplex 1-bit receive.&lt;/P&gt;
&lt;P&gt;Please refer below test code for your reference:&lt;/P&gt;
&lt;P&gt;1. Use polling b2b example&lt;/P&gt;
&lt;P&gt;2. add these to LPSPI_MasterTransferNonBlocking() in fsl_lpspi.c&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* If there is not rxData , can mask the receive data (receive data is not stored in receive FIFO).&lt;BR /&gt;* For master transfer , we'd better not masked the transmit data in TCR since the transfer flow is hard to&lt;BR /&gt;* controlled by software.*/&lt;BR /&gt;if (handle-&amp;gt;rxData == NULL)&lt;BR /&gt;{&lt;BR /&gt;isRxMask = true;&lt;BR /&gt;handle-&amp;gt;rxRemainingByteCount = 0;&lt;BR /&gt;}&lt;BR /&gt;if (handle-&amp;gt;txData == NULL)&lt;BR /&gt;{&lt;BR /&gt;isTxMask = true;&lt;BR /&gt;handle-&amp;gt;txRemainingByteCount = 0U;&lt;BR /&gt;}&lt;/P&gt;
&lt;P&gt;3. change the master from blocking to nonblocking. (reference slave example)&lt;/P&gt;
&lt;P&gt;/*Start master transfer, transfer data to slave.*/&lt;BR /&gt;masterXfer.txData = masterTxData;&lt;BR /&gt;masterXfer.rxData = NULL;&lt;BR /&gt;masterXfer.dataSize = TRANSFER_SIZE;&lt;BR /&gt;masterXfer.configFlags =&lt;BR /&gt;EXAMPLE_LPSPI_MASTER_PCS_FOR_TRANSFER | kLPSPI_MasterPcsContinuous | kLPSPI_SlaveByteSwap;&lt;/P&gt;
&lt;P&gt;LPSPI_MasterTransferNonBlocking(EXAMPLE_LPSPI_MASTER_BASEADDR, &amp;amp;g_s_handle, &amp;amp;masterXfer);&lt;/P&gt;
&lt;P&gt;while (!isTransferCompleted)&lt;BR /&gt;{&lt;BR /&gt;}&lt;/P&gt;
&lt;P&gt;/* Set master transfer ready to receive data */&lt;BR /&gt;isTransferCompleted = false;&lt;BR /&gt;volatile uint32_t sr = LPSPI1-&amp;gt;SR;&lt;BR /&gt;PRINTF("%x\n", sr);&lt;/P&gt;
&lt;P&gt;/* Start master transfer, receive data from slave */&lt;BR /&gt;masterXfer.txData = NULL;&lt;BR /&gt;masterXfer.rxData = masterRxData;&lt;BR /&gt;masterXfer.dataSize = TRANSFER_SIZE;&lt;BR /&gt;masterXfer.configFlags =&lt;BR /&gt;EXAMPLE_LPSPI_MASTER_PCS_FOR_TRANSFER | kLPSPI_MasterPcsContinuous | kLPSPI_SlaveByteSwap;&lt;BR /&gt;LPSPI_MasterTransferNonBlocking(EXAMPLE_LPSPI_MASTER_BASEADDR, &amp;amp;g_s_handle, &amp;amp;masterXfer);&lt;/P&gt;
&lt;P&gt;LPSPI1-&amp;gt;TCR |= LPSPI_TCR_TXMSK_MASK;&lt;/P&gt;
&lt;P&gt;while (!isTransferCompleted)&lt;BR /&gt;{&lt;BR /&gt;}&lt;/P&gt;
&lt;P&gt;4. Add the following under MasterUserCallBack and SlaveUserCallBack, and must be before the PRINTF.&lt;/P&gt;
&lt;P&gt;#define LPSPI_TCR_RXTXMSK (LPSPI_TCR_RXMSK_MASK | LPSPI_TCR_TXMSK_MASK)&lt;/P&gt;
&lt;P&gt;void LPSPI_MasterUserCallback(LPSPI_Type *base, lpspi_master_handle_t *handle, status_t status, void *userData)&lt;BR /&gt;{&lt;BR /&gt;LPSPI1-&amp;gt;TCR &amp;amp;= ~LPSPI_TCR_RXTXMSK;&lt;BR /&gt;LPSPI1-&amp;gt;CFGR1 &amp;amp;= ~LPSPI_CFGR1_OUTCFG_MASK;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The requirements for half-duplex are - OUTCFG (set by LPSPI_Master/SlaveTransferNonBlocking when it detects PINCFG is 1 or 2), PINCFG, and RxMSK/TxMSK.&lt;/P&gt;</description>
    <pubDate>Mon, 26 Sep 2022 08:08:53 GMT</pubDate>
    <dc:creator>Hui_Ma</dc:creator>
    <dc:date>2022-09-26T08:08:53Z</dc:date>
    <item>
      <title>Is LPSPI Slave Read-Only Half-Duplex Possible on RT1176?</title>
      <link>https://community.nxp.com/t5/i-MX-RT-Crossover-MCUs/Is-LPSPI-Slave-Read-Only-Half-Duplex-Possible-on-RT1176/m-p/1525291#M21708</link>
      <description>&lt;P&gt;I have application where need to receive data from an external A/D converter through LPSPI port in slave mode. The A/D converter will be driving LPSPI2's PCS0 low and clocking data into the RT1176 using SCK and SIN. The RT1176 SOUT would not be used. All GPIO pins are used so I cannot allocate a pin for SOUT. My hope is that I can use half-duplex where SIN is input and also output via CFGR1[PINCFG] but to avoid contention I don't want SIN to ever be in the output direction.&lt;/P&gt;&lt;P&gt;Can someone confirm that I can force SIN to always be an input in half-duplex mode by setting the TXMSK bit in the TCR?&lt;/P&gt;&lt;P&gt;I've read chapter 70 LPSPI section in the RT1170 reference manual several times. It took me a while to realize that TXMSK=1 keeps SIN in the input direction when using half-duplex mode. Please let me know if I have this wrong.&lt;/P&gt;&lt;P&gt;If there is an application note describing how LPSPI half-duplex works, please let me know that too.&lt;/P&gt;&lt;P&gt;Thank you!&lt;/P&gt;</description>
      <pubDate>Tue, 20 Sep 2022 22:31:22 GMT</pubDate>
      <guid>https://community.nxp.com/t5/i-MX-RT-Crossover-MCUs/Is-LPSPI-Slave-Read-Only-Half-Duplex-Possible-on-RT1176/m-p/1525291#M21708</guid>
      <dc:creator>mrd</dc:creator>
      <dc:date>2022-09-20T22:31:22Z</dc:date>
    </item>
    <item>
      <title>Re: Is LPSPI Slave Read-Only Half-Duplex Possible on RT1176?</title>
      <link>https://community.nxp.com/t5/i-MX-RT-Crossover-MCUs/Is-LPSPI-Slave-Read-Only-Half-Duplex-Possible-on-RT1176/m-p/1527961#M21764</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;
&lt;P&gt;Yes, my colleague had a test with LPSPI SIN to do data receive with Half duplex 1-bit receive.&lt;/P&gt;
&lt;P&gt;Please refer below test code for your reference:&lt;/P&gt;
&lt;P&gt;1. Use polling b2b example&lt;/P&gt;
&lt;P&gt;2. add these to LPSPI_MasterTransferNonBlocking() in fsl_lpspi.c&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* If there is not rxData , can mask the receive data (receive data is not stored in receive FIFO).&lt;BR /&gt;* For master transfer , we'd better not masked the transmit data in TCR since the transfer flow is hard to&lt;BR /&gt;* controlled by software.*/&lt;BR /&gt;if (handle-&amp;gt;rxData == NULL)&lt;BR /&gt;{&lt;BR /&gt;isRxMask = true;&lt;BR /&gt;handle-&amp;gt;rxRemainingByteCount = 0;&lt;BR /&gt;}&lt;BR /&gt;if (handle-&amp;gt;txData == NULL)&lt;BR /&gt;{&lt;BR /&gt;isTxMask = true;&lt;BR /&gt;handle-&amp;gt;txRemainingByteCount = 0U;&lt;BR /&gt;}&lt;/P&gt;
&lt;P&gt;3. change the master from blocking to nonblocking. (reference slave example)&lt;/P&gt;
&lt;P&gt;/*Start master transfer, transfer data to slave.*/&lt;BR /&gt;masterXfer.txData = masterTxData;&lt;BR /&gt;masterXfer.rxData = NULL;&lt;BR /&gt;masterXfer.dataSize = TRANSFER_SIZE;&lt;BR /&gt;masterXfer.configFlags =&lt;BR /&gt;EXAMPLE_LPSPI_MASTER_PCS_FOR_TRANSFER | kLPSPI_MasterPcsContinuous | kLPSPI_SlaveByteSwap;&lt;/P&gt;
&lt;P&gt;LPSPI_MasterTransferNonBlocking(EXAMPLE_LPSPI_MASTER_BASEADDR, &amp;amp;g_s_handle, &amp;amp;masterXfer);&lt;/P&gt;
&lt;P&gt;while (!isTransferCompleted)&lt;BR /&gt;{&lt;BR /&gt;}&lt;/P&gt;
&lt;P&gt;/* Set master transfer ready to receive data */&lt;BR /&gt;isTransferCompleted = false;&lt;BR /&gt;volatile uint32_t sr = LPSPI1-&amp;gt;SR;&lt;BR /&gt;PRINTF("%x\n", sr);&lt;/P&gt;
&lt;P&gt;/* Start master transfer, receive data from slave */&lt;BR /&gt;masterXfer.txData = NULL;&lt;BR /&gt;masterXfer.rxData = masterRxData;&lt;BR /&gt;masterXfer.dataSize = TRANSFER_SIZE;&lt;BR /&gt;masterXfer.configFlags =&lt;BR /&gt;EXAMPLE_LPSPI_MASTER_PCS_FOR_TRANSFER | kLPSPI_MasterPcsContinuous | kLPSPI_SlaveByteSwap;&lt;BR /&gt;LPSPI_MasterTransferNonBlocking(EXAMPLE_LPSPI_MASTER_BASEADDR, &amp;amp;g_s_handle, &amp;amp;masterXfer);&lt;/P&gt;
&lt;P&gt;LPSPI1-&amp;gt;TCR |= LPSPI_TCR_TXMSK_MASK;&lt;/P&gt;
&lt;P&gt;while (!isTransferCompleted)&lt;BR /&gt;{&lt;BR /&gt;}&lt;/P&gt;
&lt;P&gt;4. Add the following under MasterUserCallBack and SlaveUserCallBack, and must be before the PRINTF.&lt;/P&gt;
&lt;P&gt;#define LPSPI_TCR_RXTXMSK (LPSPI_TCR_RXMSK_MASK | LPSPI_TCR_TXMSK_MASK)&lt;/P&gt;
&lt;P&gt;void LPSPI_MasterUserCallback(LPSPI_Type *base, lpspi_master_handle_t *handle, status_t status, void *userData)&lt;BR /&gt;{&lt;BR /&gt;LPSPI1-&amp;gt;TCR &amp;amp;= ~LPSPI_TCR_RXTXMSK;&lt;BR /&gt;LPSPI1-&amp;gt;CFGR1 &amp;amp;= ~LPSPI_CFGR1_OUTCFG_MASK;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The requirements for half-duplex are - OUTCFG (set by LPSPI_Master/SlaveTransferNonBlocking when it detects PINCFG is 1 or 2), PINCFG, and RxMSK/TxMSK.&lt;/P&gt;</description>
      <pubDate>Mon, 26 Sep 2022 08:08:53 GMT</pubDate>
      <guid>https://community.nxp.com/t5/i-MX-RT-Crossover-MCUs/Is-LPSPI-Slave-Read-Only-Half-Duplex-Possible-on-RT1176/m-p/1527961#M21764</guid>
      <dc:creator>Hui_Ma</dc:creator>
      <dc:date>2022-09-26T08:08:53Z</dc:date>
    </item>
    <item>
      <title>Re: Is LPSPI Slave Read-Only Half-Duplex Possible on RT1176?</title>
      <link>https://community.nxp.com/t5/i-MX-RT-Crossover-MCUs/Is-LPSPI-Slave-Read-Only-Half-Duplex-Possible-on-RT1176/m-p/1535078#M21967</link>
      <description>&lt;P&gt;Thank you to NXP support (Hui_Ma) for the response.&amp;nbsp; &amp;nbsp;There is good information in your code excerpts, but my application is a little simpler in that I only need to receive from an A/D converter in LPSPI slave mode on the SIN and be able to use what would normally be the SOUT GPIO for another purpose (ACMP input in this case).&amp;nbsp; I found that this works fine.&amp;nbsp; Setting the TXMSK bit is all that is required so that SIN doesn't turn around to transmit.&amp;nbsp; In case it helps anyone else, the code excerpt for the setup is below.&amp;nbsp; I did use Peripheral configurator to setup the driver instance, but I found it necessary to redo most of the configuration as shown in the code excerpt below the picture.&amp;nbsp; I haven't try to sort out why Peripheral configuration didn't set things up...I may have left something out in the code, but I do know that LPSPI2_init() is being called by BOARD_InitPeripherals(), which is called from main() at start-up.&amp;nbsp; Having to do the lpspi2 setup in code wasn't a problem so I didn't look into this.&lt;/P&gt;&lt;P&gt;The only slightly annoying thing is that the Peripherals configurator warns that lpspi_sout is not routed so if anyone knows how to eliminate the warning I'd appreciate it.&amp;nbsp; Picture of my Peripheral setup for LPSPI2 is below.&amp;nbsp; Thank you.&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Peripheral.png" style="width: 999px;"&gt;&lt;img src="https://community.nxp.com/t5/image/serverpage/image-id/196290iD62BD41F3A45E4F9/image-size/large?v=v2&amp;amp;px=999" role="button" title="Peripheral.png" alt="Peripheral.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;// Setup to receive data in LPSPI slave mode from the ADC&lt;BR /&gt;// The ADC is the SPI master. RT1176 is the slave.&lt;BR /&gt;lpspi_slave_config_t slaveConfig;&lt;BR /&gt;LPSPI_SlaveGetDefaultConfig(&amp;amp;slaveConfig);&lt;BR /&gt;slaveConfig.whichPcs = ADC_DATA_LPSPI_SLAVE_PCS;&lt;/P&gt;&lt;P&gt;// Set the SPI clock to idle low with active high.&lt;BR /&gt;// SPI shift happens on rising edge of DCLK&lt;BR /&gt;// and data bit is latched on DCLK falling edge&lt;BR /&gt;slaveConfig.cpol = kLPSPI_ClockPolarityActiveHigh;&lt;BR /&gt;slaveConfig.cpha = kLPSPI_ClockPhaseSecondEdge;&lt;/P&gt;&lt;P&gt;// Setup for half-duplex. Only want to read in ADC data on SIN.&lt;BR /&gt;// I.e., ADC_DO is always an output. It is connected to the RT1176&lt;BR /&gt;// LPSPI SIN pin, which must always be an input. Never transmit&lt;BR /&gt;// to the ADC on its data LPSPI connection.&lt;BR /&gt;slaveConfig.pinCfg = kLPSPI_SdiInSdiOut; // We won't be outputting anything&lt;BR /&gt;slaveConfig.dataOutConfig = kLpspiDataOutTristate; // Tristate data output&lt;/P&gt;&lt;P&gt;// Initialize the LPSPI slave interface.&lt;BR /&gt;// Note that the PCS# (peripheral chip select) in slaveConfig.whichPcs&lt;BR /&gt;// is only used to configure the polarity. The PCS# selection&lt;BR /&gt;// must be done separately below.&lt;BR /&gt;LPSPI_SlaveInit(ADC_DATA_LPSPI_SLAVE_BASEADDR, &amp;amp;slaveConfig);&lt;/P&gt;&lt;P&gt;// Clear buffer for receiving ADC data over LPSPI in ISR.&lt;BR /&gt;for (unsigned i = 0; i &amp;lt; SLAVE_RX_DATA_MAX; i++) {&lt;BR /&gt;_slaveRxData[i] = 0;&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;// Set the Receiver FIFO water mark so LPSPI interrupts only when have full-packet of data.&lt;BR /&gt;// See comments at top of LPSPI2_IRQHandler() for more info.&lt;BR /&gt;#define ADC_DATA_RECEIVE_WATERMARK (16-1) // Interrupt when have 16 bytes. I.e., More than 15.&lt;BR /&gt;LPSPI_SetFifoWatermarks(ADC_DATA_LPSPI_SLAVE_BASEADDR, 0, ADC_DATA_RECEIVE_WATERMARK);&lt;/P&gt;&lt;P&gt;// Disable LPSPI "stall transfers" when xmit FIFO is empty to prevent transmit FIFO underrun error.&lt;BR /&gt;// Note this is probably N/A since running in Slave mode, but NXP's demo code for Slave&lt;BR /&gt;// receive does this so copying it for now.&lt;BR /&gt;LPSPI_Enable(ADC_DATA_LPSPI_SLAVE_BASEADDR, false);&lt;BR /&gt;ADC_DATA_LPSPI_SLAVE_BASEADDR-&amp;gt;CFGR1 &amp;amp;= (~LPSPI_CFGR1_NOSTALL_MASK);&lt;BR /&gt;LPSPI_Enable(ADC_DATA_LPSPI_SLAVE_BASEADDR, true);&lt;/P&gt;&lt;P&gt;// Flush FIFO , clear status , disable all LPSPIx interrupts.&lt;BR /&gt;LPSPI_FlushFifo(ADC_DATA_LPSPI_SLAVE_BASEADDR, true, true);&lt;BR /&gt;LPSPI_ClearStatusFlags(ADC_DATA_LPSPI_SLAVE_BASEADDR, kLPSPI_AllStatusFlag);&lt;BR /&gt;LPSPI_DisableInterrupts(ADC_DATA_LPSPI_SLAVE_BASEADDR, kLPSPI_AllInterruptEnable);&lt;/P&gt;&lt;P&gt;// Select the PCS# that the ADC will be driving low (with its ODR output) when data is ready.&lt;BR /&gt;LPSPI_SelectTransferPCS(ADC_DATA_LPSPI_SLAVE_BASEADDR, ADC_DATA_LPSPI_SLAVE_PCS);&lt;/P&gt;&lt;P&gt;// Setup for half-duplex so can use the GPIO that would normally be the SDO output&lt;BR /&gt;// for another purpose. Only receive from the ADC. Need to disable the transmit direction.&lt;BR /&gt;ADC_DATA_LPSPI_SLAVE_BASEADDR-&amp;gt;TCR |= LPSPI_TCR_TXMSK_MASK;&lt;/P&gt;&lt;P&gt;// Enable the NVIC (Nested-Vector-Interrupt-Controller) for the LPSPI peripheral.&lt;BR /&gt;EnableIRQ(ADC_DATA_LPSPI_SLAVE_IRQN);&lt;/P&gt;&lt;P&gt;// TCR is also shared the FIFO , so wait for TCR written before enabling the interrupt.&lt;BR /&gt;while (LPSPI_GetTxFifoCount(ADC_DATA_LPSPI_SLAVE_BASEADDR) != 0) {&lt;BR /&gt;;&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;// Enable the Frame Complete and Receive Interrupts.&amp;nbsp;&lt;BR /&gt;LPSPI_EnableInterrupts(ADC_DATA_LPSPI_SLAVE_BASEADDR, (kLPSPI_FrameCompleteInterruptEnable | kLPSPI_RxInterruptEnable));&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 10 Oct 2022 19:46:53 GMT</pubDate>
      <guid>https://community.nxp.com/t5/i-MX-RT-Crossover-MCUs/Is-LPSPI-Slave-Read-Only-Half-Duplex-Possible-on-RT1176/m-p/1535078#M21967</guid>
      <dc:creator>mrd</dc:creator>
      <dc:date>2022-10-10T19:46:53Z</dc:date>
    </item>
  </channel>
</rss>

