In a project based on KEAZ128 , the PE component "SPIMaster_Ldd" was used .
The slave select signals were configured as GPIO . But the CS output is wrong as shown in the following picture:
SPI CLOCK=500KHz
The IDE:
- CodeWarrior for MCU
Version: 10.7
Build Id:160721
The spi write code :
#define SPI0_SLAVE_CS_CTRL (UI_PTE->PDOR)
#define SPI0_SLAVE_CS_ALL 0x00000038
#define SPI0_SLAVE_CS_MASK 0x00000008
void spi0_write(uint8_t spi_slave_id,uint8_t data)
{
SPI0_SLAVE_CS_CTRL |= SPI0_SLAVE_CS_ALL; // all cs bit set to 1
SPI0_SLAVE_CS_CTRL &= ~(SPI0_SLAVE_CS_MASK << spi_slave_id); //active the slave
(void)SM1_SendBlock(SM1_DeviceData, &data, sizeof(data));
while(! SM1_GetBlockSentStatus(SM1_DeviceData)){}
SPI0_SLAVE_CS_CTRL |= SPI0_SLAVE_CS_ALL; // all cs bit set to 1
}
Why the CS single goes HIGH before the clock?
**************************************************************************************************************
I tried different setting:
SPI CLOCK=250KHz
SPI CLOCK=1MHz
SO, the function "SM1_GetBlockSentStatus" DO NOT work! A bug?
Need dig into the SPIMaster_Ldd code to check how the function to work.
Solved! Go to Solution.
The key point in that document is to check the SPRF flag.
Only this flat is able to indicate the shift register is received in(sent out) done.
Best Regards,
Robin
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi kiger Zhang,
Sorry for my late reply!
Please refer the answer in Trouble using SPI GetBlockSentStatus():
It actually set the SerFlag when you push all the bytes in the TxFIFO and it doesn´t wait for the data to be shifted
Best Regards,
Robin
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Dear Robin,
Thanks for your reply.
But I check the datasheet and the SPI PDD code ,it seems that the SPI module in KEAZ128 device does NOT have a "EOQ" bit. So the solution for K64 does not work for Keaz128.
Any more suggestion?
Yes. The SPI module of KEAZ128 does NOT have a "EOQ" bit.
Due to lack of EOQ flag, you may need to refer the Solution described in L-Series SPI GPIO CS/SS.
Best Regards,
Robin
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Dear Robin,
Thank you so much for your support.
I checked the document ( L-Series SPI GPIO CS/SS.) that you pointed to .
The key point in that document is to check the SPTEF flag .
I digged into the function "SM1_GetBlockSentStatus" of SPIMaster_Ldd ,it does the same thing.
***************************************
In file SPI_PDD.h
...
#define SPI_PDD_TX_BUFFER_EMPTYG SPI_S_SPTEF_MASK /**< Transmit buffer or FIFO empty flag. */
...
In file SM1.C
uint8_t StatReg = SPI_PDD_ReadStatusReg(SPI0_BASE_PTR); /* Read status register */
...
if ((StatReg & SPI_PDD_TX_BUFFER_EMPTYG) != 0U) { /* Is HW Tx buffer empty? */
if (DeviceDataPrv->OutSentDataNum < DeviceDataPrv->OutDataNumReq) { /* Is number of sent characters less than the number of requested incoming characters? */
SPI_PDD_WriteData8Bit(SPI0_BASE_PTR, (*((uint8_t *)DeviceDataPrv->OutDataPtr++))); /* Put a character with command to the transmit register and increment pointer to the transmitt buffer */
DeviceDataPrv->OutSentDataNum++; /* Increment the counter of sent characters. */
if (DeviceDataPrv->OutSentDataNum == DeviceDataPrv->OutDataNumReq) {
DeviceDataPrv->OutDataNumReq = 0x00U; /* Clear the counter of characters to be send by SendBlock() */
DeviceDataPrv->SerFlag |= BLOCK_SENT; /* Set data block sent flag */
SM1_OnBlockSent(DeviceDataPrv->UserData);
}
} else {
SPI_PDD_DisableInterruptMask(SPI0_BASE_PTR, SPI_PDD_TX_BUFFER_EMPTY); /* Disable TX interrupt */
}
}
********************************************
In fact the root cause is : the data in the TX buffer is moved to shift register so fast , but the data in the shift register should be sent out to the pin based on the SCK .
In page 534 of KEA128RM , the STPEF description:
" ...
SPTEF is automatically set when all data from the transmit buffer transfers into the transmit shift register. For an idle SPI, data written to D is transferred to the shifter almost immediately so that SPTEF is set within two bus cycles, allowing a second set of data to be queued into the transmit buffer. After completion of the transfer
of the data in the shift register, the queued data from the transmit buffer automatically moves to the shifter,
and SPTEF is set to indicate that room exists for new data in the transmit buffer. ..."
So ,what I want to know is : whether is there a flat to indicate that the shift register is sent out done, at that time the CS pin can be toggled.
The key point in that document is to check the SPRF flag.
Only this flat is able to indicate the shift register is received in(sent out) done.
Best Regards,
Robin
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Dear Robin,
Got it !
Thank you so much!