SPI SendBlock

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

SPI SendBlock

1,474 Views
mehdikarimibiuk
Contributor V

n/a

Tags (2)
0 Kudos
7 Replies

652 Views
Petr_H
NXP Employee
NXP Employee

Hi,

There might be issues related to the fact that the slave can send only when it receives clock and data from the master. Please ensure that your master is sending enough charatcters to match what you need from slave. You code also doesn't seem to wait until the data are received/sent.

Please take a look to the Typical usage page of the SPISlave_LDD component help which you can get using the pop-up menu command "Help on component"  (I suppose you are using SPISlave_LDD).

Here is a part of code copied from that example (mode with interrupts enabled):

...

void main(void)

{

  ...

  MySPIPtr = SS1_Init(NULL); /* Initialization of SS1 component */

  Error = SS1_ReceiveBlock(MySPIPtr, InpData, BLOCK_SIZE); /* Request data block reception */

  Error = SS1_SendBlock(MySPIPtr, OutData, BLOCK_SIZE); /* Start transmission/reception */

  while (!DataReceivedFlag) {}; /* Wait until data block is transmitted/received */

}

Best regards

Petr Hradsky

Processor Expert Support Team

652 Views
mehdikarimibiuk
Contributor V

n/a

0 Kudos

652 Views
mehdikarimibiuk
Contributor V

I was able to sort it out.


Here is the similar snippet how I did it:

for (;;)

{

   err = SS1_ReceiveBlock(slaveDevData1, InpDataSlave1, 2); /* Request data block reception */

   err = SS1_SendBlock(slaveDevData1, &out, 2);    /* Start transmission/reception */

   while (DataReceivedFlagSlave1 != TRUE); /* Wait until data block is transmitted/received */

   Read_MOSI();

  

   printf("TX0 = %x\n", IO_READ32(0x4002c03c));

   printf("TX1 = %x\n", IO_READ32(0x4002c040));

   printf("TX2 = %x\n", IO_READ32(0x4002c044));

   printf("TX3 = %x\n", IO_READ32(0x4002c048));

}

and as discussed before in events.c

void SS1_OnBlockReceived(LDD_TUserData *UserDataPtr)

{

  DataReceivedFlagSlave1 = TRUE;

}

0 Kudos

652 Views
Petr_H
NXP Employee
NXP Employee

Great!

To reply to your question in previous post: "I expect that SS1_ReceiveBlock block the for loop until it receives data, is this true?" :

No, this is not true. Both ReceiveBlock and SendBlock methods do not wait for end of the operation (they are not "blocking").

You have to use the event handler, or you can call GetBlockReceivedStatus and GetBlockSendStatus to check if the reception/sending has finished (you need to enable these methods then).

So your code could optionally be:

...

   err = SS1_ReceiveBlock(slaveDevData1, InpDataSlave1, 2); /* Request data block reception */

   err = SS1_SendBlock(slaveDevData1, &out, 2);    /* Start transmission/reception */

   while (!SS1_GetBlockReceivedStatus(slaveDevData1)); /* Wait until data block is transmitted/received */

...

This way you can completely omit the event code if you just need to wait till it's send.

I have noticed one more thing in the code, that I would like to warn about:

The boolean values like check while (DataReceivedFlagSlave1 != TRUE)  may not generally always work in all cases.

The problem is that true logical value is in C defined as any non-zero value, so if you test to only TRUE which is a number constant (typically 1), it won't work when the value hidden inside the bool variable will be e.g. 255 (which still fulfills the definition of "true" value).

There should be instead used while (!DataReceivedFlagSlave1) ... .

Best regards

Petr Hradsky

Processor Expert Support Team

0 Kudos

652 Views
mehdikarimibiuk
Contributor V

Petr_H

Thank you!

I have one more question, I sometimes need to send back one block of data and sometimes need to send two blocks of data. How is it possible to handle this in one iteration?

So, in my for loop after I got all block, I go and check my RX FIFO in my function Read_MOSI(). I know that my data are also in InpDataSlave1, but this is for time being. I check my RX FIFO directly at the moment in my Read_MOSI().

for (;;)

{

  err = SS1_ReceiveBlock(slaveDevData1, InpDataSlave1, 1); /* Request data block reception */

  err = SS1_SendBlock(slaveDevData1, &out, 1);    /* Start transmission/reception */

while (SS1_GetBlockReceivedStatus(slaveDevData1)); /* Wait until data block is transmitted/received */

  Read_MOSI();

}

what if I read my data and see based on my opcode, I have to send two blocks back instead of one block. In my sendblock I am sending one block back at the moment. Is there possible to switch between one and two blocks for sending data out?

One solution I could think of is, according to the opcode I receive, I tell one block or two block, then I create a vector:

UINT16 outblock[2];

and put data in each element of it for two blocks and then pass one by one to the out:

out = outblock[0];

out= outblock[1];

but the problem with this is, I don't know where to put my second outblock for proper send out on the second reading?

0 Kudos

652 Views
Petr_H
NXP Employee
NXP Employee

Hi,

Just a note regarding my previous post - I've overlooked that there is missing ! in my last example in the while (in the while(!SS1_GetBlockReceivedStatus(slaveDevData1)) )...  I fixed it now there.

I'm not sure if I understand, but if you need to send sometimes one character and sometimes two, you can just use a variable as a length parameter, like this:

uint8_t OutBlock[2];

uint8_t InBlock[2];

uint8_t length;

...

if (...) {

  OutBlock[0]= 'a';

  length = 1;

} else {

  OutBlock[0]= 'b';

  OutBlock[1]= 'c';

  length = 2;

}

err = SS1_ReceiveBlock(slaveDevData1, InBlock, length); /* Request data block reception */

err = SS1_SendBlock(slaveDevData1, OutBlock, length);    /* Start transmission/reception */

while (!SS1_GetBlockReceivedStatus(slaveDevData1)); /* Wait until data block is transmitted/received */

...

What does the Read_MOSI(); do in your code? I think there should not be anything like this. You should use just functions the component to access the hardware.

Best regards

Petr Hradsky

Processor Expert Support Team

652 Views
mehdikarimibiuk
Contributor V

Petr_H

Yes, I realized that "!" was missing. Thanks for reminding. :smileyhappy:

Mehdi

0 Kudos