SPI frame

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Not applicable
In SPI communication SCTR.FLE=63 means that frame is endless?
In this case how will end the frame? (so how will SELO again pulled up?)
0 Likes
5 Replies
chismo
Employee
Employee
First like received
Hello,

Yes, with this setting, the HW does not trigger a frame end condition based on number of bits transmitted.
Therefore, effectively an infinite frame can be sent.

The frame will end based on a SW triggered end of frame (EOF) condition.
There are 6 ways the SW can do this. For details, you can refer to the reference manual, search for "End-of-Frame Control".
1) Set the bit TCSR.SOF before writing to TBUF the word intended to be the start of the new frame.
2) Set the bit TCSR.EOF before writing to TBUF the word intended to be the last word of the current frame.
3) Using TCI feature (TCSR.WLEMD=1) to dynamically switch the word length and trigger EOF condition based on TBUF buffer location.
4) Same as 3) but using FIFO instead, hence IN location.
5) When the standard or FIFO buffer is empty while PCR.FEM = 0.
6) Deassert SELO directly by setting bit 0 of PSCR register to 1.

Regards,
Min Wei
0 Likes
Not applicable
Using this methods the SELO pin will change also? (or this is an internal change only)
0 Likes
chismo
Employee
Employee
First like received
Yes, all these refers to the control of the SELO signal to trigger its deassertion, which indicates the frame end.
0 Likes
Not applicable
Hello,
I looked for informations about end of frame control :
I want to transfert some data, wait during a long time and then transmit a dummy word to get an answer, while the SPI connection is still active (the slave is always selected), so everything will be in the same frame.

I tried to use the SCTR.EOF bit, where I "set the bit TCSR.EOF before writing to TBUF the word intended to be the last word of the current frame" before a delay loop but it doesn't work.

The slave is active low in the sample code, and during the for loop delay, the slave select cone high (slave deselected) automatically.

Do you have any ideas to solve this issue ?

Here my sample code :



/*
* main.c
*/

#include

#define DEBUG_ENABLED 1

// Choice of an USIC module registers and channel registers : prefix USICx_CHn
#define SPI_CH USIC2_CH0

/* ===================== Global variable declaration ===================== */

/* ===================== Initialisation function ===================== */
void SPI_CH_MasterInit(void)
{

/// ------------------------------------------------------------
/// 1.Enable USICx channel n
/// ------------------------------------------------------------
// Mode Control RM 18.2.2.2, Kernel State Configuration Register RM 18.11.3.3 :
// BPMODEN MODEN
SPI_CH->KSCFG |= (1 << 1)| (1 << 0);
// Run mode 0 : Channel operation as specified, no impact on data transfer

/// ------------------------------------------------------------
/// 2.Configure baud rate generator
/// - Normal divider mode
/// - Baud rate = 1 Mbit/s
/// - leading edge delay set (10 us)
/// ------------------------------------------------------------
/// DM = 01b STEP = 0x3FF
SPI_CH->FDR = (1 << 14) | ( 1023 << 0);
/// SCLKCFG PDIV = 287 DCTQ CTQSEL
SPI_CH->BRG = (2 << 30) | (71 << 16) | (10 << 10) | (2 << 6);;
/// ------------------------------------------------------------

/// ------------------------------------------------------------
/// 3.Configure input stages
/// - Select input DX0C
/// - Derive input of data shift unit directly from input pin
/// - DSEN = 1
/// ------------------------------------------------------------
/// DSEN INSW DSEL = 010b = 2d
SPI_CH->DX0CR = (1 << 6) | (1 << 4) |(2 << 0);
/// ------------------------------------------------------------

/// ------------------------------------------------------------
/// 4.Configure data format
/// - Data word = 8 bits
/// - Frame infinite
/// - MSB first
/// ------------------------------------------------------------
// WLE FLE TRM SDIR
SPI_CH->SCTR = (7<<24)|(63<<16)|(1<<8)|(1<<0);

/// ------------------------------------------------------------
/// 5.Configure data transfer parameters
/// - Single shot transmission of data word when a valid word
/// is available
/// ------------------------------------------------------------
// TDEN TDSSM
SPI_CH->TCSR = (1 << 10) |(1 << 8);
/// ------------------------------------------------------------

/// ------------------------------------------------------------
/// 6.Configure SSC protocol-specific parameters
/// - Slave select generation is enabled
/// - Direct slave select mode with inversion (SELINV = 1) is selected
/// - End of frame condition is required for the frame to be
/// considered as finished
/// - SELO0 is selected as the active select signal
/// - Inter-word delay and inter-frame delay set (10us)
/// ------------------------------------------------------------
// TIWEN SELO SELINV SELCTR MSLSEN CTQSEL1 DCTQ1
SPI_CH->PCR = (1 << 24 ) | (1 << 16) | (1 << 2) | (1 << 1) | (1 << 0) | (2<<4) | (9<<8);
/// ------------------------------------------------------------

/// ------------------------------------------------------------
/// 7.Enable SSC protocol
/// ------------------------------------------------------------
// MODE
SPI_CH->CCR =(1 << 0);
}


/* ===================== Main ===================== */
int main(void)
{

/* ===================== Variable declaration ===================== */
uint32_t i,j = 0;
uint16_t data_received[9];
uint16_t dummy;
uint8_t cpt = 0;
uint8_t MSLS = 5;

/* De-assert USIC2 reset */
/* Release reset of USIC module by writing a 1 to the USICxRS bit in SCU_PRCLR0 or SCU_PRCLR1 registers */
SCU_RESET->PRCLR1 |= (1<<8);
/* Initialize USIC channel */
SPI_CH_MasterInit();

/* Initialize USIC output pin functions */
/* INPUT - MISO - P3.7 - USIC2_CH0.DX0C -> P3_IOCR4 -> PC7 (because P3.7) -> bits [31-27] */
//PORT3->IOCR4 |= 0b00000000000000000000000000000000;
/* OUTPUT - MOSI - P3.8 -> P3_IOCR8 -> PC8 ( because P3.8) -> bits [7-3]
Alternate function 1 (cf RM p 2814 26.10 ) -> 10001b */
PORT3->IOCR8 |= 0b00000000000000000000000010001000;
/* CLK - P3.9 -> P3_IOCR9 -> PC9 ( because P3.9) -> bits [15-11]
Alternate function 1 (cf RM p 2814 26.10 ) -> 10001b */
PORT3->IOCR8 |= 0b00000000000000001000100000000000;
/* Slave Select SELO0 - P3.10, cf RM table 18-29 p1998
P3.10 -> P3_IOCR8 -> PC10 ( because P3.10) -> bits [23-19]
Alternate function 1(cf RM p 2814 26.10 ) -> 10001b */
PORT3->IOCR8 |= 0b00000000100010000000000000000000;
/// ------------------------------------------------------------

/* Slave Select */
// MSLSEN - activate master mode
SPI_CH->PCR |= (1<<0);

/* ============================ LOOP ============================ */
while(1U)
{


#if (DEBUG_ENABLED)
// test PCR.MSLS value
if ((SPI_CH->PSR & 0b1))
{MSLS = 1;} // chip select activated
else if (!(SPI_CH->PSR & 0b1))
MSLS = 0; // chip select deactivated
//breakpoint
MSLS = 5;
//breakpoint
#endif

// counter set at 0 :
cpt = 0;

// reset table
for (i=0; i<9; i++)
{
data_received = 0;
}

//------------------------------------
// Exchange data

while((SPI_CH->TCSR & 0x80)>>7);
/* transmit dummy frame to the slave */
SPI_CH->TBUF[0] = 0x0000;
dummy = SPI_CH->RBUF;

/* Poll TCSR.TDV bit */
while((SPI_CH->TCSR & 0x80)>>7);
/* transmit data 10 to the slave */
SPI_CH->TBUF[0] = 0x000A;
/* Wait as long as the Register RBUF1 does not contain data that has not yet been read out.
RBUF01SR.RDV01 = 0b0
*/
while( !( ((SPI_CH->RBUF01SR & 0x4000)>>14) ) );
data_received[cpt] = SPI_CH->RBUF;
cpt++;

while((SPI_CH->TCSR & 0x80)>>7);
/* transmit dummy frame to the slave */
SPI_CH->TBUF[0] = 0x0000;
while( !( ((SPI_CH->RBUF01SR & 0x4000)>>14) ) );
data_received[cpt] = SPI_CH->RBUF;
cpt++;


while((SPI_CH->TCSR & 0x0080)>>7);
/* transmit data 17 to the slave */
SPI_CH->TBUF[0] = 0x0011;
/* received previous data sent, so 10 + 15 */
while( !( ((SPI_CH->RBUF01SR & 0x4000)>>14) ) );
data_received[cpt] = SPI_CH->RBUF;
cpt++;

while((SPI_CH->TCSR & 0x80)>>7);
/* transmit dummy frame to the slave */
SPI_CH->TBUF[0] = 0x0000;
while( !( ((SPI_CH->RBUF01SR & 0x4000)>>14) ) );
data_received[cpt] = SPI_CH->RBUF;
cpt++;


// EOF activated: finish the frame with the next data word
// Aim : keep the slave select active during the delay
SPI_CH->TCSR |= (1 << 6);

// wait 100 us
for (i=0; i<1000; i++)
{
j = i+1;
}
j = 0;


while((SPI_CH->TCSR & 0x80)>>7);
/* transmit data 33 to the slave */
SPI_CH->TBUF[0] = 0x0021;
while( !( ((SPI_CH->RBUF01SR & 0x4000)>>14) ) );
data_received[cpt] = SPI_CH->RBUF;
cpt++;

while((SPI_CH->TCSR & 0x80)>>7);
/* transmit dummy frame to the slave */
SPI_CH->TBUF[0] = 0x0000;
while( !( ((SPI_CH->RBUF01SR & 0x4000)>>14) ) );
data_received[cpt] = SPI_CH->RBUF;
cpt++;

while((SPI_CH->TCSR & 0x80)>>7);
/* transmit data 42 to the slave */
SPI_CH->TBUF[0] = 0x002A;
while( !( ((SPI_CH->RBUF01SR & 0x4000)>>14) ) );
data_received[cpt] = SPI_CH->RBUF;
cpt++;

while((SPI_CH->TCSR & 0x80)>>7);
/* transmit dummy frame to the slave */
SPI_CH->TBUF[0] = 0x0000;
while( !( ((SPI_CH->RBUF01SR & 0x4000)>>14) ) );
data_received[cpt] = SPI_CH->RBUF;
cpt++;

while((SPI_CH->TCSR & 0x80)>>7);
/* transmit dummy frame to the slave */
SPI_CH->TBUF[0] = 0x0000;
while( !( ((SPI_CH->RBUF01SR & 0x4000)>>14) ) );
data_received[cpt] = SPI_CH->RBUF;

dummy = SPI_CH->RBUF;


// wait for 2 sec
for (i=0; i<36500000; i++)
{
j = i+1;
}
j = 0;
//---------------------------------------------------

#if (DEBUG_ENABLED)
// test PCR.MSLS value
if ((SPI_CH->PCR & 0b1))
{MSLS = 1;}
else if (!(SPI_CH->PCR & 0b1))
{MSLS = 0;}
//breakpoint
MSLS = 5;
#endif


#if (DEBUG_ENABLED)
// test PCR.MSLS value
if ((SPI_CH->PCR & 0b1))
{MSLS = 1;}
else if (!(SPI_CH->PCR & 0b1))
{MSLS = 0;}
//breakpoint
MSLS = 5;
#endif

}
}




Thank you,
Nicolas
0 Likes
chismo
Employee
Employee
First like received
Hello Nicolas,

There is a frame end mode (FEM) control bit in PCR_SSCMode register.
FEM = 0 (default) - The current data frame is considered as finished when the last bit of a data word has been sent out and the transmit buffer TBUF does not contain new data (TDV = 0).
FEM = 1 - The MSLS signal is kept active also while no new data is available and no other end of frame condition is reached. In this case, the software can accept delays in delivering the data without automatic deactivation of MSLS in multi-word data frames.

Therefore for your use case, FEM needs to be additionally set to 1.

Regards,
Min Wei
0 Likes