SPI: 24bit SPI Slave for KEA, different power on sequence of slave & master, different SO frame

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

SPI: 24bit SPI Slave for KEA, different power on sequence of slave & master, different SO frame

1,583 Views
fortunely
Contributor III

I have 2xFRDM-KEAZ128Q80, one used as SPI master, one used as SPI Slave. I want to simulate 24bit SPI communication, but I find that different power-on sequence results in different SO outputing SPI bytes' sequence.

I have no idea about what's wrong. How can I ensure the right SO output sequence?

KEA DEMO Board: FRDM-KEAZ128Q80,

Test Device: Logic Analyzer LA1010

IDE: CW11

SPI Port : master port connect to same slave port (PTG4-4, 5-5, 6-6, 7-7)

SPI Master Port:SPI1 , PTG_4_5_6_7

SPI Slave Port:SPI1 , PTG_4_5_6_7

I have uploaded the demo code to attachments.

Main SPI Master Code:

void SPIMaster_Task()
{
 uint8_t i = 0;
 for(i = 0; i < SPI1_TX_DATA_SIZE; i++)
 {
  gu8SPI1_TxBuff[i] = 0x55 + i;
 }
 
 // control cs manually
 GPIO_PinClear(GPIO_PTG7); //enable cs
 SPI_TransferWait(SPI1,gu8SPI1_RxBuff,gu8SPI1_TxBuff,SPI1_TX_DATA_SIZE); // size=3
 GPIO_PinSet(GPIO_PTG7);   //diable cs

}

Main SPI Slave Code:

void SPISlave_Task()
{
 uint32_t i = 0;
 gu8SPI1_TxBuff[0] = 0x55;
 gu8SPI1_TxBuff[1] = 0x80;
 gu8SPI1_TxBuff[2] = 0xAA;

 for(i = 0; i < SPI1_TX_DATA_SIZE; i++)
 {
  while(!SPI_IsSPRF(SPI1)){rxIntCnt ++;};
  gu8SPI1_RxBuff[i] = SPI_ReadDataReg(SPI1);
  while(!SPI_IsSPTEF(SPI1)){txIntCnt ++;};
  SPI_WriteDataReg(SPI1,gu8SPI1_TxBuff[i]);
 }

}

Result:

Right  SO sequence  should be 0x55 0x80 0xAA.

1.Master Power-on first:

1) error: 0xAA 0x55 0x80

MasterPowerOnFirst_1.png

2)error: 0xAA 0x55 0x80

MasterPowerOnFirst_2.png

2. SPI poweron first

1)error: 0x80 0xAA 0x55

SlavePowerOnFirst_1.png

2)right: 0x55 0x80 0xAA

SlavePowerOnFirst_2.png

Labels (1)
Tags (2)
0 Kudos
4 Replies

1,363 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Martin Zhang,

     Slave code need to do the modification.

    Please change it like this:

void SPISlave_Task()
{
 uint32_t i = 0;
 gu8SPI1_TxBuff[0] = 0x55;
 gu8SPI1_TxBuff[1] = 0x80;
 gu8SPI1_TxBuff[2] = 0xAA;

 for(i = 0; i < SPI1_TX_DATA_SIZE; i++)
 {
  while(!SPI_IsSPTEF(SPI1)){txIntCnt ++;};
  SPI_WriteDataReg(SPI1,gu8SPI1_TxBuff[i]);

  while(!SPI_IsSPRF(SPI1)){rxIntCnt ++;};
  gu8SPI1_RxBuff[i] = SPI_ReadDataReg(SPI1);
 }

}

Just send the according data to the buffer at first.

It means the slave need to prepare the code, flush the FIFO with the data which you need.

Otherwise, when the master SCK input, then the slave send out fifo still not prepared, it will have the problem.

Besides, about the power on sequence, your slave must need to power on at first, otherwise, it will also have problem.

Just let the slave prepared OK, then wait the Master SCK.

Please try it again.

If you still have question about it, please kindly let me know.

Have a great day,
Kerry

 

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

1,364 Views
fortunely
Contributor III

Hi Kerry,

Thanks you.

I have solve the problems.

The problem, CS abnormal 0->1->0 , results from forgeting to connect Logic Analyzer's GND to Slave &Master board.

But wrong SPI bytes sequence stiil exists. For example, I want to send 0x55 0x80 0xAA by MISO, but it sends 0xAA 0x55 0x80 actually.

I think it relates to SPI tx buffer & data register 's rule. I find out I can load 2 bytes into TX buffer register before reading any data from RX buffer register, if I use interrupt.

A valid way is restricting the Tx and Rx sequence to TX&RX buffer.

Key Point:

1. Use Tx&Rx interrupts, do not disable.

2. Should be load 1 byte to Tx buffer for wating for Tx first.

2. When Tx finish  loading 1 byte, pls to change to waiting for Rx 1byte.

e.g. Main Code

typedef enum
{
SPI_BYTES_STATUS_HEADER_BEGIN,
SPI_BYTES_STATUS_HEADER_END,
SPI_BYTES_STATUS_SECOND_BEGIN,
SPI_BYTES_STATUS_SECOND_END,
SPI_BYTES_STATUS_TAIL_BEGIN,
SPI_BYTES_STATUS_TAIL_END
}SPI_BYTES_STATUS_Type;

volatile SPI_BYTES_STATUS_Type spiBytesStatus = SPI_BYTES_STATUS_HEADER_BEGIN;

void SPISlave_CallBack()
{
if(SPI_IsSPRF(SPI1))
{// Rx full

switch(spiBytesStatus)
{
case SPI_BYTES_STATUS_HEADER_END:
gu8SPI1_RxBuff[0] = SPI_ReadDataReg(SPI1);
spiBytesStatus = SPI_BYTES_STATUS_SECOND_BEGIN;
break;
case SPI_BYTES_STATUS_SECOND_END:
gu8SPI1_RxBuff[1] = SPI_ReadDataReg(SPI1);
spiBytesStatus = SPI_BYTES_STATUS_TAIL_BEGIN;
break;
case SPI_BYTES_STATUS_TAIL_END:
gu8SPI1_RxBuff[2] = SPI_ReadDataReg(SPI1);
spiBytesStatus = SPI_BYTES_STATUS_HEADER_BEGIN;
u32SPI1_RxFrameCnt ++;
break;
}

u32SPI1_RxCnt ++;
}

if(SPI_IsSPTEF(SPI1))
{// Tx empty

switch(spiBytesStatus)
{
case SPI_BYTES_STATUS_HEADER_BEGIN:
SPI_WriteDataReg(SPI1, gu8SPI1_TxBuff[0]);
spiBytesStatus = SPI_BYTES_STATUS_HEADER_END;
break;
case SPI_BYTES_STATUS_SECOND_BEGIN:
SPI_WriteDataReg(SPI1, gu8SPI1_TxBuff[1]);
spiBytesStatus = SPI_BYTES_STATUS_SECOND_END;
break;
case SPI_BYTES_STATUS_TAIL_BEGIN:
SPI_WriteDataReg(SPI1, gu8SPI1_TxBuff[2]);
spiBytesStatus = SPI_BYTES_STATUS_TAIL_END;
u32SPI1_TxFrameCnt ++;
break;
}

u32SPI1_TxCnt ++;
}
}

main()

{

while(1)

{

//void SPISlave_Task(){
gu8SPI1_TxBuff[0] = 0x55;
gu8SPI1_TxBuff[1] = 0x80;
gu8SPI1_TxBuff[2] = 0xAA;

//}

}

}

0 Kudos

1,364 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Martin,

   Thanks for your updated information and the solutions sharing.

   If you still have the problems about it, just let me know.


Have a great day,
Kerry

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

1,364 Views
fortunely
Contributor III

Hi Kerry,

Thanks for your reply. 

I change the slave's code and then try to power on slave first.

It seems that it does not work. But I find the CS(SPI Enable) is innormal, that is, the CS line will change to high level about 100ns sometimes and the go back to low level. Maybe it result in my SPI Slave frame's bytes absence and then error byte sequence.

The bytes absense does not happen every time.

Do you have met the same problem?

I doubt my connection is not very reliable by 4 dupont lines between two FRDM-KEA128Q80 evbs. I do not know whether there is a better method to recognize a SPI frame head & tail on Slave. So the master will ignore the invalid frame, and there is no other effect on next SPI frame.

Result

4 different results.

1) error sequence: 0xAA 0x55 0x80

SlavePowerOnFirst0.png

2) error: 1 byte absence, CS 0~1 keep 100nsSlavePowerOnFirst1.png

3) error: 2 byte absence, CS 0~1 keep 100ns/every timeSlavePowerOnFirst2.png

4) error: 2 byte absence, CS 0~1 keep 100ns/every timeSlavePowerOnFirst3.png

0 Kudos