Question about 3 SPI Device Control....

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

Question about 3 SPI Device Control....

Jump to solution
4,369 Views
OOLife
Contributor III

Hello,

 

I'm new and using MQX3.4 & MCF52259.

 

My MCF52259 board has 3 SPI devices which are connected to MCF52259.

each device has their own CHIP Select pin. (QSPI_CS0, QSPI_CS2, QSPI_CS3)

 

My code is based on the mqx/example/spi example from Freescale.

 

There is set_CS() function for controling CS pin.

But, I wondering about that this function really need for me?

Because, all I used pins are default pin.

MQX_IO_Driver_User_Guide described IO_IOCTL_SPI_SET_CS_CALLBACK function

is used for only for MCF51 family.

Is that right?

 

And, one more question...

How to fill the param when using IO_IOCTL_SPI_SET_CS function?

 

param = ????; 

 if(ioctl(spi_fd, IO_IOCTL_SPI_SET_CS, &param) == SPI_OK) {
  printf ("OK\n");
 }
 else {
  printf ("ERROR\n");
 }

 

What's the best way to control 3 SPI devices simultaneously?

Thanks in advance

 

Message Edited by OOLife on 2010-02-09 02:32 PM
0 Kudos
Reply
1 Solution
1,406 Views
PetrM
Senior Contributor I

Sorry for confusion. In IO_IOCTL_SPI_SET_CS command, you can use only macros MCF5XXX_QSPI_QDR_QSPI_CSx (any combination, so you can assert/deassert multiple CS signals at a time), e.g. param = (MCF5XXX_QSPI_QDR_QSPI_CS3) is correct.

 

The other thing is proper GPIO setting, to enable the processor pins as QSPI chip selects. This is by default done only for CS0. You can find it in BSP function _bsp_qspi_io_init() in gpio_init.c file. You must add MCF5225_GPIO_PQSPAR_PQSPA5 and MCF5225_GPIO_PQSPAR_PQSPA6, which control CS2 and CS3 signals. Warning: this setting conflicts with USB.

 

PetrM

 

View solution in original post

0 Kudos
Reply
9 Replies
1,406 Views
PetrM
Senior Contributor I

Hello,

 

no, you don't need to use callbacks for CS handling when using QSPI. This functionality was added just for compatibility reasons. By default, chip selects are driven by HW here.

You have to include spi_mcf5xxx_qspi.h header and then you can use macros MCF5XXX_QSPI_QDR_QSPI_CSx (any combination, it's bitmask) to set proper chip selects.

Remember that the CS change takes place during next read/write in polled mode and during next byte transfer in interrupt mode. In interrupt mode, use flush command to wait/delimit communication (and then switch CS).

 

PetrM

 

0 Kudos
Reply
1,404 Views
OOLife
Contributor III

Thank you for your comment.

 

I tested several cases according to your comments.
But, I can't control QSPI_PCS2 and QSPI_PCS3 on MCF52259EVB.


Followings are my code snippet.

Is there any missing from my source code?

 

Thanks in advance.

 

....#include <spi_mcf5xxx_qspi.h>#include <mcf5xxx_qspi.h>....FILE_PTR spi_fd;...... spi_fd = fopen("spi0:", NULL); if (spi_fd==NULL ) {  TRACE(1, "SPI_DriverOpen() Failed. Exiting...\n");  _time_delay(200L);  _mqx_exit(-1); }uint_32  param;...... // I want to select the appropriate CS_PIN in HERE. //  // MCF52259 pin assign is following from MCF52259DS.pdf //     ----------------------------------------------- //     Pramary    Secondary    Tertiary      Quaternary //     ----------------------------------------------- //     QSPI_CS3   SYNCA        USB_DP_PDOWN  PQS6 //     QSPI_CS2   SYNCB        USB_DM_PDOWN  PQS5 //     QSPI_CS0   I2C_SDA0     UCTS1         PQS3 //     ----------------------------------------------- // param = (GPIO_PORT_QS | GPIO_PIN3);  // Works fine with QSPI_CS0 // param = (GPIO_PORT_QS | GPIO_PIN5);  // Works fine with QSPI_CS0 --> Why CS0? // param = (MCF5XXX_QSPI_QDR_QSPI_CS0);  // Works fine with QSPI_CS0 //  // param = (MCF5XXX_QSPI_QDR_QSPI_CS2);  // Not Working with QSPI_CS0. It's good. But, Not working with CS2 // param = (MCF5XXX_QSPI_QDR_QSPI_CS3);  // Not Working with QSPI_CS0. It's good. But, Not working with CS3 //  // param = (GPIO_PORT_QS | MCF5XXX_QSPI_QDR_QSPI_CS0); // Works fine with CS0. // param = (GPIO_PORT_QS | MCF5XXX_QSPI_QDR_QSPI_CS2); // Works fine with CS0. // if(ioctl(spi_fd, IO_IOCTL_SPI_SET_CS, &param) == SPI_OK) {  TRACE(3, "IO_IOCTL_SPI_SET_CS----OK %d\n", param); } else {  TRACE(3, "IO_IOCTL_SPI_SET_CS----ERROR %d\n", param); } // Set Baud rate param = 2000000; if (SPI_OK == ioctl (spi_fd, IO_IOCTL_SPI_SET_BAUD, &param))  {  TRACE(3, "Changing the baud rate to %d Hz ... OK\n", param); } else {  TRACE(3, "Changing the baud rate to %d Hz ... ERROR\n", param); } // Set Clock Mode param = SPI_CLK_POL_PHA_MODE0; if (SPI_OK == ioctl (spi_fd, IO_IOCTL_SPI_SET_MODE, &param))  {  TRACE(3, "Setting clock mode to %d ... OK\n", param); } else {  TRACE(3, "Setting clock mode to %d ... ERROR\n", param); } // Set Transfer Mode param = SPI_DEVICE_MASTER_MODE; if (SPI_OK == ioctl (spi_fd, IO_IOCTL_SPI_SET_TRANSFER_MODE, &param))  {  TRACE(3, "Setting transfer mode to %d ... OK\n", param); } else {  TRACE(3, "Setting transfer mode to %d ... ERROR\n", param); } // Write instruction result = fwrite(send_buffer, 1, 1, spi_fd); if(result != 1) {  // Stop transfer  TRACE(3, "First SPI Dev ... FAILED (1)!\n");  return status; } // Read SPI #1 status result = fread(&status, 1, 1, spi_fd); if(result != 1) {  TRACE(3, "First SPI Dev status ... FAILED (2)!\n"); } else {  TRACE(3, "First SPI Dev status ... OK ............ Status = 0x%02X\n", status); } // Wait till transfer end (and deactivate CS) fflush(spi_fd);

 

 

0 Kudos
Reply
1,407 Views
PetrM
Senior Contributor I

Sorry for confusion. In IO_IOCTL_SPI_SET_CS command, you can use only macros MCF5XXX_QSPI_QDR_QSPI_CSx (any combination, so you can assert/deassert multiple CS signals at a time), e.g. param = (MCF5XXX_QSPI_QDR_QSPI_CS3) is correct.

 

The other thing is proper GPIO setting, to enable the processor pins as QSPI chip selects. This is by default done only for CS0. You can find it in BSP function _bsp_qspi_io_init() in gpio_init.c file. You must add MCF5225_GPIO_PQSPAR_PQSPA5 and MCF5225_GPIO_PQSPAR_PQSPA6, which control CS2 and CS3 signals. Warning: this setting conflicts with USB.

 

PetrM

 

0 Kudos
Reply
1,404 Views
Ardoster
Contributor III

Hi PetrM

 

I'm so sorry, but, how can you know MCF5225_GPIO_PQSPAR_PQSPA5 is controlling CS2. Where did you find that? The last two hours I've been looking for that data in the documents and I found nothing.

 

Thanks


PetrM wrote:

Sorry for confusion. In IO_IOCTL_SPI_SET_CS command, you can use only macros MCF5XXX_QSPI_QDR_QSPI_CSx (any combination, so you can assert/deassert multiple CS signals at a time), e.g. param = (MCF5XXX_QSPI_QDR_QSPI_CS3) is correct.

 

The other thing is proper GPIO setting, to enable the processor pins as QSPI chip selects. This is by default done only for CS0. You can find it in BSP function _bsp_qspi_io_init() in gpio_init.c file. You must add MCF5225_GPIO_PQSPAR_PQSPA5 and MCF5225_GPIO_PQSPAR_PQSPA6, which control CS2 and CS3 signals. Warning: this setting conflicts with USB.

 

PetrM

 




0 Kudos
Reply
1,404 Views
eGuy
Contributor IV

Hi PetrM,

 

I am trying to use multiple spi devices following your comments in this thread.

 

However, whenever qspi_cs2 is enabled ( logic low), qspi_cs0 is also enabled, below is the code snip.

Do I miss something in configuration?

 

Thanks in advance

 

eGuy.

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

 

    param = MCF5XXX_QSPI_QDR_QSPI_CS2;    
    if(ioctl(spi_fd, IO_IOCTL_SPI_SET_CS, &param) == SPI_OK) {
        printf("x");
    }

 

    // Write instruction
    result = fwrite(send_buffer, 1, 1, spi_fd);

 

 

_mqx_int _bsp_qspi_io_init (    uint_8 dev_num )
{
    VMCF5225_STRUCT_PTR reg_ptr = _PSP_GET_IPSBAR();
    
    if (0 != dev_num) return -1;

    reg_ptr->GPIO.PQSPAR &= (~ (MCF5225_GPIO_PQSPAR_PQSPA0(3) | MCF5225_GPIO_PQSPAR_PQSPA1(3) | MCF5225_GPIO_PQSPAR_PQSPA2(3) | MCF5225_GPIO_PQSPAR_PQSPA3(3) | MCF5225_GPIO_PQSPAR_PQSPA5(3)| MCF5225_GPIO_PQSPAR_PQSPA6(3)));
    reg_ptr->GPIO.PQSPAR |= (MCF5225_GPIO_PQSPAR_PQSPA0(1) | MCF5225_GPIO_PQSPAR_PQSPA1(1) | MCF5225_GPIO_PQSPAR_PQSPA2(1) | MCF5225_GPIO_PQSPAR_PQSPA3(1) | MCF5225_GPIO_PQSPAR_PQSPA5(1)| MCF5225_GPIO_PQSPAR_PQSPA6(1));

    return 0;
} /* Endbody */

0 Kudos
Reply
1,404 Views
eGuy
Contributor IV

Look deep into the driver code.

 

I found in spi_pol_mcf5xxx_qspi.c  _mcf5xxx_qspi_polled_tx_rx()

 

This statement causes all QSPI_CSx active low:

    /* CS inactive low for tranfers longer than 16 words */
//    qspi_ptr->QWR &= (~ MCF5XXX_QSPI_QWR_CSIV);

 

My code works by commenting it out.

 

Any problems here?

 

Regards,

 

Jeff

0 Kudos
Reply
1,404 Views
elel
Contributor III

Hi Jeff

 

I can confirm you the problem you saw, because I've had the same problem when I started to work with the SPI driver in my application.

I've solved the problem in this way:

    if((qspi_ptr->QMR&MCF5XXX_QSPI_QMR_CPOL)==0x00)
    {
        /* CS inactive low for tranfers longer than 16 words */
        qspi_ptr->QWR &= (~ MCF5XXX_QSPI_QWR_CSIV);
    }
    else
    {
        qspi_ptr->QWR |= MCF5XXX_QSPI_QWR_CSIV;
    }

 

In this way the chip select returns always in the idle state you have setted at the end of a trasmission.

 

Stefano

0 Kudos
Reply
1,406 Views
eGuy
Contributor IV

Hi Stefano,

 

Thanks for your reply.

 

Regards,

 

Jeff

 

0 Kudos
Reply
1,406 Views
OOLife
Contributor III

That's really what I want.

Your comments are really helpful to save my time.

Thank you so much.

 

0 Kudos
Reply