Re: SPI slave in MQX 4.0

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

Re: SPI slave in MQX 4.0

963 Views
travis_l
Contributor III

Glad to be of assistance. I just happened to be working with the same component and knew a lot of the particulars that you were looking for.

0 Kudos
12 Replies

652 Views
mehdikarimibiuk
Contributor V

Hi travis_l

I have one more question. So I have my master and slave in RTOS setup (already included their modules in my bsp) and I see it is working (thanks a lot for previous help by the way). However, I need some way of synchronization between master and slave transactions.

I see that in master RX some data are being lost as it seems by the time that I go and take slave TX data, in master RX, they are partially lost.

Here is what I experimented:

I assigned two same priority tasks: one for master and the other for slave.

Then I used master/slave receive and send block functions:

#define BLOCK_SIZE 10

UINT32 OutDataSlave[BLOCK_SIZE] = {0x12345678, 0x9080706050};

UINT32 OutDataMaster[BLOCK_SIZE] = {0xaabbccdd, 0xeeff0011};

UINT32 InpDataSlave[BLOCK_SIZE];

UINT32 InpDataMaster[BLOCK_SIZE];

//slave task while loop:

while (TRUE)

  {

  printf ("\tSLAVE LOOP");

  err = SS1_ReceiveBlock(slaveDevData, InpDataSlave, BLOCK_SIZE); /* Request data block reception */

  if (err!=ERR_OK) printf("ERROR RX data (slave).\n");

   else printf("Slave Receive Block return is %d...OK.\n", err);

  err = SS1_SendBlock(slaveDevData, OutDataSlave, BLOCK_SIZE);    /* Start transmission */

  if (err!=ERR_OK) printf("ERROR TX data (slave).\n");

   else printf("Slave Send Block return is %d...OK.\n", err);

  printf("Slave Rx is 0x%x'\n",  InpDataSlave[0]);

  printf("Slave Rx is 0x%x'\n",  InpDataSlave[1]);

  _time_delay(0.003);

  }

//and on master task I have this similar loop:

while (TRUE)

  {

  printf ("\tMASTER LOOP");

   err = SM1_SendBlock(masterDevData, OutDataMaster, BLOCK_SIZE);    /* Start transmission/reception */

  if (err!=ERR_OK) printf("ERROR TX data (master).\n");

   else printf("Master Send Block return is %d...OK.\n", err);

  err = SM1_ReceiveBlock(masterDevData, InpDataMaster, BLOCK_SIZE); /* Request data block reception */

  if (err!=ERR_OK) printf("ERROR RX data (master).\n");

   else printf("Master Receive Block return is %d...OK.\n", err);

  printf("Master Rx is 0x%x'\n",  InpDataMaster[0]);

  printf("Master Rx is 0x%x'\n",  InpDataMaster[1]);

  printf("\n");

  _time_delay(0.003);

  }

----

and here is what output looks like:

        MASTER LOOP     1 time here.

Master Send Block return is 0...OK.

Master Receive Block return is 0...OK.

Master Rx is 0x0'

Master Rx is 0x0'

       SLAVE LOOP      2 time here.

Slave Receive Block return is 0...OK.

Slave Send Block return is 0...OK.

Slave Rx is 0xaabbccdd'

Slave Rx is 0xeeff0011'

        MASTER LOOP     2 time here.

Master Send Block return is 0...OK.

Master Receive Block return is 0...OK.

Master Rx is 0x56787800'

Master Rx is 0x60501234'

        SLAVE LOOP      3 time here.

Slave Receive Block return is 0...OK.

Slave Send Block return is 0...OK.

Slave Rx is 0xaabbccdd'

Slave Rx is 0xeeff0011'

        MASTER LOOP     3 time here.

Master Send Block return is 0...OK.

Master Receive Block return is 0...OK.

Master Rx is 0x78000000'

Master Rx is 0x50123456'

        SLAVE LOOP      4 time here.

Slave Receive Block return is 0...OK.

ERROR TX data (slave).

Slave Rx is 0xaabbccdd'

Slave Rx is 0xeeff0011'

        MASTER LOOP     4 time here.

Master Send Block return is 0...OK.

Master Receive Block return is 0...OK.

Master Rx is 0x80'

Master Rx is 0x0'

        SLAVE LOOP      5 time here.

Slave Receive Block return is 0...OK.

Slave Send Block return is 0...OK.

Slave Rx is 0xaabbccdd'

Slave Rx is 0xeeff0011'

        MASTER LOOP     5 time here.

Master Send Block return is 0...OK.

Master Receive Block return is 0...OK.

Master Rx is 0x34565678'

Master Rx is 0x70605012'

        SLAVE LOOP      6 time here.

Slave Receive Block return is 0...OK.

Slave Send Block return is 0...OK.

Slave Rx is 0xaabbccdd'

Slave Rx is 0xeeff0011'

        MASTER LOOP     6 time here.

Master Send Block return is 0...OK.

Master Receive Block return is 0...OK.

Master Rx is 0x56787800'

Master Rx is 0x60501234'

        SLAVE LOOP      7 time here.

Slave Receive Block return is 0...OK.

Slave Send Block return is 0...OK.

Slave Rx is 0xaabbccdd'

Slave Rx is 0xeeff0011'

        MASTER LOOP     7 time here.

Master Send Block return is 0...OK.

Master Receive Block return is 0...OK.

Master Rx is 0x78000000'

Master Rx is 0x50123456'

        SLAVE LOOP      8 time here.

Slave Receive Block return is 0...OK.

ERROR TX data (slave).

Slave Rx is 0xaabbccdd'

Slave Rx is 0xeeff0011'

        MASTER LOOP     8 time here.

Master Send Block return is 0...OK.

Master Receive Block return is 0...OK.

Master Rx is 0x80'

Master Rx is 0x0'

        SLAVE LOOP      9 time here.

Slave Receive Block return is 0...OK.

Slave Send Block return is 0...OK.

Slave Rx is 0xaabbccdd'

Slave Rx is 0xeeff0011'

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

data are not seem to be missing on the slave receive side from master, but, obviously, we see that data sent from slave are being lost...

now the question is, how I can come up with a synchronization strategy between my master and slave transactions?

Do you know of any functions that can help me with that?

Thanks

Another thing I need to know is that I see the buffer pointer for both master sendblock and receiveblock are same:

Is this allowed?

#define iteration 3

#define BLOCK_SIZE 10

UINT32 OutDataSlave[BLOCK_SIZE] = {0x12345678, 0x90807060};

UINT32 OutDataMaster[BLOCK_SIZE] = {0xaabbccdd, 0xeeff0011};

UINT32 InpDataSlave[BLOCK_SIZE];

UINT32 InpDataMaster[BLOCK_SIZE];

Here is my log:

        SLAVE LOOP      1 time here.

Slave Receive Block return is 0...OK.

Slave Send Block return is 0...OK.

0-Slave Rx is 0x0'

1-Slave Rx is 0x0'

2-Slave Rx is 0x0'

3-Slave Rx is 0x0'

4-Slave Rx is 0x0'

5-Slave Rx is 0x0'

6-Slave Rx is 0x0'

7-Slave Rx is 0x0'

8-Slave Rx is 0x0'

9-Slave Rx is 0x0'

10-Slave Rx is 0x0'

11-Slave Rx is 0x0'

12-Slave Rx is 0x0'

---> MASTER INITIALIZE ---------------------

        MASTER LOOP     1 time here.

Master Send Block return is 0...OK.

Master Receive Block return is 0...OK.

0-Master Rx is 0x0'

1-Master Rx is 0x0'

2-Master Rx is 0x0'

3-Master Rx is 0x0'

4-Master Rx is 0x0'

5-Master Rx is 0x0'

6-Master Rx is 0x0'

7-Master Rx is 0x0'

8-Master Rx is 0x0'

9-Master Rx is 0x0'

10-Master Rx is 0xaabbccdd'

11-Master Rx is 0xeeff0011'

12-Master Rx is 0x0'

        SLAVE LOOP      2 time here.

Slave Receive Block return is 0...OK.

Slave Send Block return is 0...OK.

0-Slave Rx is 0xaabbccdd'

1-Slave Rx is 0xeeff0011'

2-Slave Rx is 0x0'

3-Slave Rx is 0x0'

4-Slave Rx is 0x0'

5-Slave Rx is 0x0'

6-Slave Rx is 0x0'

7-Slave Rx is 0x0'

8-Slave Rx is 0x0'

9-Slave Rx is 0x0'

10-Slave Rx is 0x0'

11-Slave Rx is 0x0'

12-Slave Rx is 0x0'

        MASTER LOOP     2 time here.

Master Send Block return is 0...OK.

Master Receive Block return is 0...OK.

0-Master Rx is 0x56787800'

1-Master Rx is 0x70601234'

2-Master Rx is 0x9080'

3-Master Rx is 0x0'

4-Master Rx is 0x0'

5-Master Rx is 0x0'

6-Master Rx is 0x0'

7-Master Rx is 0x0'

8-Master Rx is 0x0'

9-Master Rx is 0x0'

10-Master Rx is 0xaabbccdd'

11-Master Rx is 0xeeff0011'

12-Master Rx is 0x0'

        SLAVE LOOP      3 time here.

Slave Receive Block return is 0...OK.

Slave Send Block return is 0...OK.

0-Slave Rx is 0xaabbccdd'

1-Slave Rx is 0xeeff0011'

2-Slave Rx is 0x0'

3-Slave Rx is 0x0'

4-Slave Rx is 0x0'

5-Slave Rx is 0x0'

6-Slave Rx is 0x0'

7-Slave Rx is 0x0'

8-Slave Rx is 0x0'

9-Slave Rx is 0x0'

10-Slave Rx is 0x0'

11-Slave Rx is 0x0'

12-Slave Rx is 0x0'

        MASTER LOOP     3 time here.

Master Send Block return is 0...OK.

Master Receive Block return is 0...OK.

0-Master Rx is 0x78000000'

1-Master Rx is 0x60123456'

2-Master Rx is 0x8070'

3-Master Rx is 0x0'

4-Master Rx is 0x0'

5-Master Rx is 0x0'

6-Master Rx is 0x0'

7-Master Rx is 0x0'

8-Master Rx is 0x0'

9-Master Rx is 0x0'

10-Master Rx is 0xaabbccdd'

11-Master Rx is 0xeeff0011'

12-Master Rx is 0x0'

        SLAVE LOOP      4 time here.

Slave Receive Block return is 0...OK.

ERROR TX data (slave).

0-Slave Rx is 0xaabbccdd'

1-Slave Rx is 0xeeff0011'

2-Slave Rx is 0x0'

3-Slave Rx is 0x0'

4-Slave Rx is 0x0'

5-Slave Rx is 0x0'

6-Slave Rx is 0x0'

7-Slave Rx is 0x0'

8-Slave Rx is 0x0'

9-Slave Rx is 0x0'

10-Slave Rx is 0x0'

11-Slave Rx is 0x0'

12-Slave Rx is 0x0'

        MASTER LOOP     4 time here.

Master Send Block return is 0...OK.

Master Receive Block return is 0...OK.

0-Master Rx is 0x90'

1-Master Rx is 0x0'

2-Master Rx is 0x0'

3-Master Rx is 0x0'

4-Master Rx is 0x0'

5-Master Rx is 0x0'

6-Master Rx is 0x0'

7-Master Rx is 0x0'

8-Master Rx is 0x0'

9-Master Rx is 0x0'

10-Master Rx is 0xaabbccdd'

11-Master Rx is 0xeeff0011'

12-Master Rx is 0x0'

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

Mehdi

0 Kudos

652 Views
travis_l
Contributor III

Mehdi,

I’ve seen some similar issues with my project I’m currently working on. You may need to add a little delay between characters sent by the master. If you are using the PE component for the master, there is a setting where you can do this. Bear in mind that the FIFO hardware buffer is only 16 bytes, so what I was seeing was that I was not getting characters out of the FIFO buffer fast enough on the slave side and would lose characters when there was a larger amount of data being transferred. You may wish to enable the DMA transfer of this data to RAM, which I’m currently trying to figure out in order to increase the data rate between master and slave. I can’t really offer much advise on the DMA setup yet as I’m still working on it, but that is what a Freescaler suggested to me.

0 Kudos

652 Views
mehdikarimibiuk
Contributor V

n/a

0 Kudos

652 Views
travis_l
Contributor III

mehdikarimibiuki

Yes the shift registers are 16 bits, but there are also four 32bit FIFO registers that the hardware can use to shift data out of the shift registers.  I'm still working on getting the DMA set up how I want it, but I think that is how you are going to get the 12MHz data rate that is advertised.  I don't have any problems getting that rate on the master side of the communication, but the slave is a bit more difficult.  I think it would be very useful if MQX would support the slave communication directly as it does the master SPI.

Keep me posted as to how it is working out for you as I am still working on a similar project.  I think I was able to overcome the lost data issue using the PE component without using DMA, but I had to copy it into my application project and make some modifications to how it works in order to do this. I am getting around 8 MHz data rates currently.

0 Kudos

652 Views
mehdikarimibiuk
Contributor V

n/a

0 Kudos

652 Views
travis_l
Contributor III

mehdikarimibiuki

You can customize the CPU component using processor expert as well.  I'm actually using a MK40DX256ZVLQ10 on my project, which is also a custom board and not a tower module.  Once you customize the CPU component there are a couple of gotcha's to look out for.  Don't go messing with the clock configurations too much, MQX requires all three that are in the PE CPU component.  If you are using a different crystal, then stuff like that is okay to change.  Also, something I have noticed is that PE has the MCG_AutoTrim in the Methods tab disabled by default and MQX needs this to trim the crystal input, so make sure you click on the Methods tab and enable this method before you generate code.  If you give me an idea of what differences your custom board has from the tower board, I might be able to give you a little more specific information on what you might need to change.  So far I've done about 4-5 different custom boards using kinetis MCU's and all I've had to do was set the proper crystal oscillator frequencies and the capacitance of the crystals and rtc oscillators.

0 Kudos

652 Views
mehdikarimibiuk
Contributor V

travis_l

My custom board has MK10 MCU. Is it possible to use BSP "twrk60d100m" for my K10 MCU on the custom board? I cannot find any other bsp close to MK10?

The other thing is when I add MCU MK10 to BSP "twrk60d100m" processor section as a component, I throws me a number of errors? Should it be done differently?

0 Kudos

652 Views
travis_l
Contributor III

There should be BSP’s for MK10 in MQX 4.0.2 I’ve not worked with the micro before so I can’t say for sure.

0 Kudos

652 Views
mehdikarimibiuk
Contributor V

travis_l

I am not sure about this too. I don't think if there is any bsp for MK10, as I cannot find any k10 bsp as I start a new MQX 4.0 project (there is nothing like "twrk10..." selection there). Our custom board currently has K10, and I need to find a way to match one of those available BSPs to it. Not sure if I use the bsp clone wizard and maybe add twrk60d100m as the base board in the wizard for my k10 bsp creation!

FYI, if you have not looked at it, MQX BSP Clone Wizard is handy:

~Freescale_MQX_4_0_2\doc\tools\MQX_BSP_Cloning_Wizard_Getting_Started.pdf

Just to note that, starting that wizard it also does not give me any option to choose any k10 bsp!!!!

0 Kudos

652 Views
mehdikarimibiuk
Contributor V

Hi travis_l

Happy new year!

How is your spi project going, have you been able to configure DMA for spi?

On my side I am having a custom board with MK10DN512Z VLL10 which is a LQFP 100pin device. It seems there is no MQX support for 100 pin packages? Later we are having MK60DN512 VLL10 which still is a 100-pin controller. We definitely need MQX for our project but I have to investigate MQX support for it.

As discussed before, I could do spi master slave on Freescale tower board however, and it worked fine.

One question here, once I figure out the MQX support, if I add components to PE of bsp would it work on my custom board? or should I change things in bsp? how about in PSP? have you done it? PSP I see there is no PE.

At the moment I have K10 on custom board. But we will be having K60 soon on our boards.

0 Kudos

652 Views
travis_l
Contributor III

Hi Mehdi,

Happy New Year to you as well. I’m not sure about the MQX and PE support for the MK10. I’ve really only worked with the K40, K60, and K70 MCU’s and they all have had MQX support for some time. In your processor expert CPU settings, do you have an option to pick from another chip package for the MK10?

The PE components should work on your custom board, as long as you make sure that the pin assignments are correct. The custom boards that my electrical engineer lays out don’t often use the same pin MUX as the tower board does and I successfully use PE components all the time. One thing to note in your BSP, if you are using the MQX drivers for something, you may have to edit the init_gpio.c file in order to have MQX initialize the correct pins for a peripheral when using a custom board. I have never had to edit the PSP for any of my custom projects as it gets all of the customization from your user_config.h file in your BSP.

I think you should have good luck with the k60 support in MQX and PE.

Travis

0 Kudos

652 Views
mehdikarimibiuk
Contributor V

Just to give an update, I realize that there is simply a counter that we can sync our spi read and write according to that. So as an example we can see whenever the counter counts, how much data are came in or got out (remember spi is full duplex).

by looking at the counter we won't need send block and receive block functions anymore.

I was able to extract data by reading rx shift register and also write to tx shift register (remember tx shift register can send only 16 bits at a time for spi slave).

the only problem i am facing is that sometimes I miss data, which I think I can queue them up.

loop

DataArrived = read_ctr() - SpicntRead;

if (DataArrived == 1) {

     read them

}

else if (DataArrived == 2) {

     read them

}...

like that...

0 Kudos