MQX SPI timing / CS issue

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

MQX SPI timing / CS issue

1,799 Views
bfac
NXP Employee
NXP Employee

Hello,

This question also relates to reduce read/write time in SPI driver on MQX 4.0.2 .

We are using MQX on the Cortex M4 of a Vybrid processor, for time sensitive operations on a very fast control loop application.

For that, we need fast execution of SPI driver for both send and receive functions.

Doing tests with newer MQX versions, 4.0.2, we noticed the SPI driver takes a long time to run, specially when the Chip Select by hardware is selected, as I would believe the driver depends on the OS scheduler to give it the control periodically.

This seems like a known limitation/feature, the issue is better described on the other post commented above, is this a correct assumption?

What we mean is, was the MQX SPI driver designed to support very fast transfers as fast as 1 - 2us (for 2 bytes data only)?

Due to that, we are trying to use the Chip Select manually, so the idea is to directly control the IO, and use the SPI driver just for data transfer.

The problem is: on this version of MQX 4.0.2, it seems the driver does not allow us to do that, the transfer is never completed.

While, on older versions of MQX, like the 4.0.1, the exact same code worked fine.

The QUESTIONS then are:

1) Why manually setting the CS does not work for newer MQX versions? (although there were no changes on documentation).

2) Do you see any other strategy as a faster option for even faster SPI send/receive functions?

The implementation was:

1) High Level application:

--------------

/* Open the SPI driver */

spiFD = fopen("spi0:0", NULL);

--------------

We use "spi0:0" as we dont want to use hardware chipselect. The CS is being controlled by GPIO.

/*

* ===  FUNCTION  ======================================================================

*         Name:  adcRw

*  Description: write/read data to adc module by spi driver

* =====================================================================================

*/

uint_16 adcRw(  uint_16 data )

{

   SPI_READ_WRITE_STRUCT  rw;

   uint_8 uiChannel;

   uint_16   result=0;

/* Test simultaneous write and read */

memset (send_buffer, 0, sizeof (send_buffer));

send_buffer[0] = (uint_8)((data&0xFF00)>>8);

send_buffer[1] = (uint_8)(data&0xFF);

rw.BUFFER_LENGTH = 2;

rw.WRITE_BUFFER = (char_ptr)send_buffer;

if (SPI_OK == ioctl (spiFD, IO_IOCTL_SPI_READ_WRITE, &rw))

{

//TRACE ("ad OK");

} else {

TRACE ("ad ERROR");

}

//fflush (spiFD);

ioctl (spiFD, IO_IOCTL_FLUSH_OUTPUT, 0);

bufferAD[uiChannel] = ((((uint_16)rw.READ_BUFFER[0])<<8)&0x0FFF)|((uint_16)rw.READ_BUFFER[1]);

//TRACE("v:%d",result);

return(result);

}

2) BSP lower level modifications:

- On pcm052_m4.h fiel, enabled PTB18 and 19 as GPIOs

-----------------

#define BSP_ADC                            (LWGPIO_PORT_B | LWGPIO_PIN8)

#define BSP_DAC                            (LWGPIO_PORT_B | LWGPIO_PIN9)


#define BSP_ADC_MUX_GPIO                   (LWGPIO_MUX_B8_GPIO)

#define BSP_DAC_MUX_GPIO                   (LWGPIO_MUX_B9_GPIO)

------------------


- Removed those pins functions as CS1 and CS0 on fileinit_gpio.c

---------------------------

_mqx_int _bsp_dspi_io_init

(

    uint_32 dev_num

)

{

    switch (dev_num)

    {

        case 0:

/*            IOMUXC_RGPIO(40) =

                IOMUXC_SW_MUX_CTL_PAD_PAD_IBE(1) |

                IOMUXC_SW_MUX_CTL_PAD_PAD_OBE(1) |

                IOMUXC_SW_MUX_CTL_PAD_PAD_PUE(1) |

                IOMUXC_SW_MUX_CTL_PAD_PAD_PKE(1) |

                IOMUXC_SW_MUX_CTL_PAD_PAD_PUS(2) |

                IOMUXC_SW_MUX_CTL_PAD_PAD_DSE(7) |

                IOMUXC_SW_MUX_CTL_PAD_PAD_SPEED(3) |

                IOMUXC_SW_MUX_CTL_PAD_PAD_MUX_MODE(1); // PTB18.CS


       IOMUXC_RGPIO(41) =

                IOMUXC_SW_MUX_CTL_PAD_PAD_IBE(1) |

                IOMUXC_SW_MUX_CTL_PAD_PAD_OBE(1) |

                IOMUXC_SW_MUX_CTL_PAD_PAD_PUE(1) |

                IOMUXC_SW_MUX_CTL_PAD_PAD_PKE(1) |

                IOMUXC_SW_MUX_CTL_PAD_PAD_PUS(2) |

                IOMUXC_SW_MUX_CTL_PAD_PAD_DSE(7) |

                IOMUXC_SW_MUX_CTL_PAD_PAD_SPEED(3) |

                IOMUXC_SW_MUX_CTL_PAD_PAD_MUX_MODE(1); */// PTB19.CS

---------------------------

Then, compiled the BSP again.

Thanks,

Bruno

Tags (1)
0 Kudos
3 Replies

681 Views
pato3
Contributor III

VybridSPI.JPG.jpg

Related to your 2nd question: for reference I get 446ns (41.5MHz SCK) for a 16bits transfer using bare-metal drivers (SPI1 + eDMA) with CS controlled directly from the drivers (see attached screenshot). TFT 320x240 is completely filled up in 34.12ms.

Same performances for A5 & M4.

0 Kudos

681 Views
DavidS
NXP Employee
NXP Employee

Hi Bruno,

I think you have found issues with MQX4.0.2 and also MQX4.1 SPI driver.  I plan to investigate this further after FTF (April 8-11th) (i.e. start looking at week of April 14th).

I did a test recently with MQX4.1 and it defaulted to using DMA SPI driver for Kinetis.  I'm assuming that would be the case for Vybrid too but you may want to try MQX4.1 (http://www.freescale.com/mqx) .

bits of PUSHR should contain the CTARx and SPI CS (other options too) to use and the lower 16-bit value containing the data to write.

If anyone beats me to looking into this....Thanks!  Otherwise I will report back after my efforts.

Regards,

David

681 Views
pbanta
Contributor IV

Here is a data point.  I've been trying to get the MQX 4.1 DSPI driver working with DMA as I convert a project from MQX 3.8.1 to MQX 4.1 on a Kinetis K70.  I'm seeing huge latency between CS and SCLK on both sides of the transaction.  In this case I'm not using the CS callback -- I'm letting the driver handle the CS.  The actual data transfer is about the same but the total transaction time is very large with the MQX 4.1 driver compared to the driver in MQX 3.8.1.  Look at the chip select line in the screen shot below. 81.65us.  For comparison, the total transaction time for MQX 3.8.1's SPI driver is about 37us.

MQX_4_1_DSPI_wDMA.png

0 Kudos