How to send SPI data on register level

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

How to send SPI data on register level

3,156 Views
remcohardeveld
Contributor I

Hi all,

I'm trying to get data transferred over SPI in linux and I want to try if I can acces it faster with the aid of mmap. I have set all the required register for the SPI to operate. With the following code I try to send data:

for(i=0;i<50;i++)
{
   spi_pointer[0][0x01] = 0xAA; //set data
   spi_pointer[0][0x02] |= 0x4; //set xch bit to start burst transfer
   while(((spi_pointer[0][0x02]>>2) & 1) == 1); //wait until burst is finished
}

Only when I try to measure the CLK with an oscilloscope, I don't get any signal at all. Also when looking in the status register it seems that there is no data in the TXFIFO register. Is there something that i'm missing?

Kind regards,

Remco

Labels (2)
Tags (3)
0 Kudos
Reply
8 Replies

2,554 Views
cplaton
Contributor I

Hi everybody,

I am facing quite the same issue : I want to use the SPI (ECSPI1) with mmap but when I try to read from the registers (with /dev/mem), linux hangs and I have to reboot.

Did you solve your problem ? How did you manage to set the registers with mmap ?

Any advice would be welcome.

Best regards,

Clement

0 Kudos
Reply

2,554 Views
remcohardeveld
Contributor I

Hi Clement platon,

I have succesfully accesed the registers directly in both WEC2013 and Linux. For Linux I had the following:

unsigned int *Offset_register_SPI[10] = {};

void init_register_SPI()
{
void *spi_map = 0;
void *CCGR_map = 0;
int mem_fd;

if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0)// open /dev/mem //
{
printf("can't open /dev/mem \n");
exit(-1);
}
spi_map = mmap(NULL,4,PROT_READ|PROT_WRITE,MAP_SHARED,mem_fd,0x0200C000);
if (spi_map == MAP_FAILED)
{
printf("mmap error\n");//errno also set!
exit(-1);
}
Offset_register_SPI[0] = spi_map + 0x00;// Always use volatile pointer!
Offset_register_SPI[1] = spi_map + 0x04;
Offset_register_SPI[2] = spi_map + 0x08;
Offset_register_SPI[3] = spi_map + 0x0C;
Offset_register_SPI[4] = spi_map + 0x10;
Offset_register_SPI[5] = spi_map + 0x14;
Offset_register_SPI[6] = spi_map + 0x18;
Offset_register_SPI[7] = spi_map + 0x1C;
Offset_register_SPI[8] = spi_map + 0x20;
Offset_register_SPI[9] = spi_map + 0x40;
close(mem_fd);
}

To read and write from the registers you have to use *. Also keep in mind to get it fully working you have to enable the ECSPI clock and set IOMUX correctly.

I hope that this can help you.

0 Kudos
Reply

2,554 Views
cplaton
Contributor I

Thank you for your reply,

Indeed, the ECSPI clock was disabled. It works fine now !

Thanks a lot for your help.

Best regards,

Clement

0 Kudos
Reply

2,554 Views
art
NXP Employee
NXP Employee

Have you first configured the IOMUX for the selected SPI signals? Please check.


Have a great day,
Artur

0 Kudos
Reply

2,554 Views
remcohardeveld
Contributor I

I have checked the IOMUX registery corresponding to the pins i use, and they are correctly set:

IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA04 = 2 //ALT2 — Select signal ECSPI1_SCLK

IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA04 = 2 //ALT2 — Select signal ECSPI1_MOSI

IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA04 = 2 //ALT2 — Select signal ECSPI1_MISO

IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA04 = 5 //101 ALT5 — Select signal GPIO5_IO25 (use GPIO as SS)

I also have checked the whole SPI config and they are also correct (same as a working SPI). Also check if the XCH bit is set, only i suspect  that that goes to fast to check. 

 

Do you have any other idea where I can check for?

Kind regards,

 

Remco

0 Kudos
Reply

2,554 Views
art
NXP Employee
NXP Employee

Are you sure you make all the SPI controller writes and reads on the correct physical addresses? Please double-check.

Also, try to make all the things manually, using the 'memtool' command line tool that is located in the /unit_tests directory of the default Linux BSP.

Best Regards,

Artur

0 Kudos
Reply

2,554 Views
remcohardeveld
Contributor I

I am 95% sure that I'm messing with the correct registers: These are the hardware address that I use (I get access to them with mmap to /dev/mem):

0x02008000 -> ECSPI1_RXDATA)

0x02008004 -> ECSPI1_TXDATA)

0x02008008 -> ECSPI1_CONREG

0x0200800C -> ECSPI1_CONFIGREG

0x02008010 -> ECSPI1_INTREG

0x02008014 -> ECSPI1_DMAREG

0x02008018 -> ECSPI1_STATREG

0x0200801C -> ECSPI1_PERIODREG

0x02008020 -> ECSPI1_TESTREG

0x02008040 -> ECSPI1_MSGDATA

Also when I use the memtool and read from the address that I use (like those above) I get the exact same results as when I do it with my code. Thus so far as I know I do it wright. 

When I initiate the transmit with setting XCH I still don't see any output. Also when writing to TXDATA I don't see any change in the TESTREG. I expected to see 0x01 to indicate that there is now 1 a 32-bit data package ready in the FIFO register.

0 Kudos
Reply

2,554 Views
remcohardeveld
Contributor I

Thank you for your reply.

I think they are OK because when I use the default driver i get a good output. And I use those settings when I try to output mine. So I use the correct interface for it to do the setting only I want to have a faster SPI access time so I put my data directly to the registers. 

But I will verify the IOMUX settings. I will post later the results.

Kind regards,

Remco

0 Kudos
Reply