Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NXP drivers: spi: spi_mcux_lpspi: enable CONFIG_SPI_ASYNC mode with DMA #78194

Closed
wants to merge 6 commits into from

Conversation

DerekSnell
Copy link
Contributor

@DerekSnell DerekSnell commented Sep 9, 2024

Updates LPSPI driver to support async mode with DMA. Enables spi_loopback testing async mode on all the NXP boards with the LPSPI peripherals. Resolves #74907.

spi_loopback test with CONFIG_SPI_ASYNC passes on the following boards. The test failed on 1 board which needs more investigation, a separate issue created for that board at #78238.

  • Mimxrt1010_evk
  • Mimxrt1020_evk
  • Mimxrt1024_evk
  • Mimxrt1040_evk
  • Mimxrt1170_evk_cm7
  • Frdm_ke17z512
  • frdm_mcxn947//cpu0
  • frdm_mcxn236

@DerekSnell DerekSnell added area: SPI SPI bus area: DMA Direct Memory Access platform: NXP NXP area: Tests Issues related to a particular existing or missing test platform: NXP Drivers NXP Semiconductors, drivers labels Sep 9, 2024
@DerekSnell DerekSnell marked this pull request as ready for review September 10, 2024 14:33
Copy link
Member

@decsny decsny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in Kconfig.mcux_lpspi can you please add something like depends on DMA if SPI_ASYNC to the LPSPI driver kconfig

tests/drivers/spi/spi_loopback/src/spi.c Outdated Show resolved Hide resolved
@@ -532,6 +532,12 @@ static int dma_mcux_edma_reload(const struct device *dev, uint32_t channel,
ret = -EFAULT;
}

if (data->edma_handle.tcdPool == NULL) {
/* Not using scatter/gather mode, re-enable the hardware request */
EDMA_EnableChannelRequest(DEV_EDMA_HANDLE(dev, channel)->base,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you give an explanation of "why" in the commit message at least, maybe also in the comment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added details in comment and commit message

drivers/spi/spi_mcux_lpspi.c Outdated Show resolved Hide resolved
dma_size = MIN(data->ctx.tx_len, data->ctx.rx_len);

if (dma_size == 0) {
dma_size = MAX(data->ctx.tx_len, data->ctx.rx_len);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is it not always max?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @decsny ,
Making this change (always MAX) here in spi_mcux_dma_callback(), the spi_loopback test passes. However, if I make this same change in spi_mcux_dma_rxtx_load(), the "half start" test fails. I believe this existing code is keeping the RX and TX transfers equal size until one completes, and then it finishes the other.

drivers/spi/spi_mcux_lpspi.c Outdated Show resolved Hide resolved
drivers/spi/spi_mcux_lpspi.c Outdated Show resolved Hide resolved
drivers/spi/spi_mcux_lpspi.c Outdated Show resolved Hide resolved
drivers/spi/spi_mcux_lpspi.c Outdated Show resolved Hide resolved
With some compiler optimizations, compiler error occurs when trying to test
tx_buf_size in BUILD_ASSERT.

Signed-off-by: Derek Snell <[email protected]>
If not using scatter/gather mode, re-enable the hardware channel requests.
The fsl_edma driver uses the eDMA DREQ bit to automatically disable the
hardware DMA request at the end of the major loop.



Signed-off-by: Derek Snell <[email protected]>
DMA scatter/gather mode was unused in this driver.

Signed-off-by: Derek Snell <[email protected]>
If CONFIG_SPI_ASYNC, select the DMA feature

Signed-off-by: Derek Snell <[email protected]>
…ards

Enable testing async mode on all the NXP boards with the LPSPI peripherals.

Signed-off-by: Derek Snell <[email protected]>
}

/* Restart the TX DMA */
ret = dma_reload(dev,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have we verified this works correctly when the SPI is only sending or only receiving data? If memory serves, we usually configure the TX DMA or RX DMA with a step size of zero and a dummy buffer in these cases, so that DMA will run on both channels. My concern is that if we (for example) are sending TX data and not receiving anything, the LPSPI RX FIFO will overflow since the DMA will not be reading from it.

Copy link
Contributor Author

@DerekSnell DerekSnell Sep 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, @danieldegrasse .
No, that has not been tested here. the spi_loopback test does not enable RX without TX.

Adding DNM label until we test further.

Thanks

@DerekSnell DerekSnell added the DNM This PR should not be merged (Do Not Merge) label Sep 16, 2024
@LukasTaroza
Copy link

Hello, I'm testing with mimxrt1060_evk. The tests are passing, but the functionality is incorrect. I am getting chip select for every byte when I should only get chip select for one block.
#78732 PR adds continuous mode (base->TCR |= LPSPI_TCR_CONT_MASK), which completely breaks dma spi (no test pass, chip select is never deselected). With this mode additional command end dma block should be sent to deselect chip select. I could add more information if needed.

@decsny
Copy link
Member

decsny commented Oct 21, 2024

#78732 PR adds continuous mode (base->TCR |= LPSPI_TCR_CONT_MASK), which completely breaks dma spi (no test pass, chip select is never deselected). With this mode additional command end dma block should be sent to deselect chip select. I could add more information if needed.

what do you mean by this, are you saying that PR breaks it? because if so, that's not my observations.

@LukasTaroza
Copy link

I'm using main branch of zephyr, and executing west build -p always -b mimxrt1060_evk -t flash tests/drivers/spi/spi_loopback the results are:

*** Booting Zephyr OS build v3.7.0-4815-g6773f3344575 ***                                                                                                                                       
Running TESTSUITE spi_loopback                                                                                                                                                                  
===================================================================                                                                                                                             
START - test_spi_loopback                                                                                                                                                                       
I: SPI test on buffers TX/RX 0x800040a0/0x80004080, frame size = 8, DMA enabled                                                                                                                 
I: SPI test slow config                                                                                                                                                                         
I: Start complete multiple                                                                                                                                                                      
E: Timeout waiting for transfer complete                                                                                                                                                        
E: Code -116                                                                                                                                                                                    
                                                                                                                                                                                                
    Assertion failed at WEST_TOPDIR/zephyr/tests/drivers/spi/spi_loopback/src/spi.c:142: spi_complete_multiple: (ret is true)                                                                   
SPI transceive failed                                                                                                                                                                           
 FAIL - test_spi_loopback in 0.231 seconds                                                                                                                                                      
===================================================================                                                                                                                             
TESTSUITE spi_loopback failed.                                                                                                                                                                  
                                                                                                                                                                                                
------ TESTSUITE SUMMARY START ------                                                                                                                                                           
                                                                                                                                                                                                
SUITE FAIL -   0.00% [spi_loopback]: pass = 0, fail = 1, skip = 0, total = 1 duration = 0.231 seconds                                                                                           
 - FAIL - [spi_loopback.test_spi_loopback] duration = 0.231 seconds                                                                                                                             
                                                                                                                                                                                                
------ TESTSUITE SUMMARY END ------                                                                                                                                                             
                                                                                                                                                                                                
===================================================================
PROJECT EXECUTION FAILED

image

If I remove the base->TCR |= LPSPI_TCR_CONT_MASK in trasceive_dma function I get:

*** Booting Zephyr OS build v3.7.0-4815-g6773f3344575 ***                                                                                                                                       
Running TESTSUITE spi_loopback                                                                                                                                                                  
===================================================================                                                                                                                             
START - test_spi_loopback                                                                                                                                                                       
I: SPI test on buffers TX/RX 0x800040a0/0x80004080, frame size = 8, DMA enabled                                                                                                                 
I: SPI test slow config                                                                                                                                                                         
I: Start complete multiple                                                                                                                                                                      
I: Passed                                                                                                                                                                                       
I: Start complete loop                                                                                                                                                                          
I: Passed                                                                                                                                                                                       
I: Start null tx                                                                                                                                                                                
I: Passed                                                                                                                                                                                       
I: Start half start                                                                                                                                                                             
I: Passed
I: Start half end
I: Passed
I: Start every 4
I: Passed
I: Start rx bigger than tx
I: Passed
I: Start complete large transfers
I: Passed
I: SPI test fast config
I: Start complete multiple
I: Passed
I: Start complete loop
I: Passed
I: Start null tx
I: Passed
I: Start half start
I: Passed
I: Start half end
I: Passed
I: Start every 4
I: Passed
I: Start rx bigger than tx
I: Passed
I: Start complete large transfers
I: Passed
I: SPI test fast config
I: Start complete multiple
I: Passed
I: Start complete loop
I: Passed
I: Start null tx
I: Passed
I: Start half start
I: Passed
I: Start half end
I: Passed
I: Start every 4
I: Passed
I: Start rx bigger than tx
I: Passed
I: Start complete large transfers
I: Passed
I: Start complete loop
I: Passed
I: Start complete loop
I: Passed
I: All tx/rx passed
 PASS - test_spi_loopback in 0.205 seconds
===================================================================
TESTSUITE spi_loopback succeeded

------ TESTSUITE SUMMARY START ------

SUITE PASS - 100.00% [spi_loopback]: pass = 1, fail = 0, skip = 0, total = 1 duration = 0.205 seconds
 - PASS - [spi_loopback.test_spi_loopback] duration = 0.205 seconds

------ TESTSUITE SUMMARY END ------

===================================================================
PROJECT EXECUTION SUCCESSFUL

image

I think the flag is correct because otherwise, you could only send one byte commands. The documentation says that to use this function, you need to send extra command to deselect chip-select.

CONT Continuous transfer Configures LPSPI for a continuous transfer that keeps PCS asserted between frames (as specified by FRAMESZ). You must write a new command word to cause PCS to negate. Also supports changing the command word at the frame size boundaries.

Copy link

This pull request has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this pull request will automatically be closed in 14 days. Note, that you can always re-open a closed pull request at any time.

@github-actions github-actions bot added the Stale label Dec 22, 2024
@github-actions github-actions bot closed this Jan 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: DMA Direct Memory Access area: SPI SPI bus area: Tests Issues related to a particular existing or missing test DNM This PR should not be merged (Do Not Merge) platform: NXP Drivers NXP Semiconductors, drivers platform: NXP NXP Stale
Projects
None yet
Development

Successfully merging this pull request may close these issues.

drivers: NXP LPSPI Async API broken
5 participants