XMC4300 SPI master configuration

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

cross mob
Not applicable
Hello,
I am trying to use a XMC4300 instead of a XMC4800 for SPI communication.
This code is working on a XMC4800, I changed the pin configurations.


Could you tell me is something wrong ?



Here my code :



#include


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

/* ===================== 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 = 250 kbit/s
/// - SCLKCFG = 10b : data transmitted on the falling edge (CPOL = 0, CPHA = 1)
/// ------------------------------------------------------------
/// ------------------------------------------------------------
// DM = 01b STEP = 1023d = 3FFh = 001111111111b
SPI_CH->FDR = (1 << 14) | ( 2013 << 0);
// SCLKCFG PDIV = 287
SPI_CH->BRG = (2 << 30) | (287 << 16);

/// ------------------------------------------------------------


/// ------------------------------------------------------------
/// 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 = data frame = 8 bits
/// - Data transfer allowed with passive level = 0 and MSB first
/// ------------------------------------------------------------
// WLE FLE TRM SDIR
SPI_CH->SCTR = (7<<24)|(7<<16)|(1<<8)|(1<<0);
// Not Frame settle
/// ------------------------------------------------------------

/// ------------------------------------------------------------
/// 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
/// ------------------------------------------------------------
// SELO SELINV SELCTR MSLSEN
SPI_CH->PCR = (1<<16)|(1<<2)|(1<<1)|(1<<0);
/// ------------------------------------------------------------



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


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

/* ===================== Variable declaration ===================== */
uint32_t i,j = 0;

uint8_t a, b, c, d;

uint16_t data_received[9];
uint16_t dummy;
uint8_t cpt = 0;

/* 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 - P2.2 - P2_IOCR0 -> PC2 (because P2.2) -> bits [23-19] - direct input */
//PORT2->IOCR0 &= 0b11111111000001111111111111111111; -> No need to use it, because it is 00000b
/* OUTPUT - MOSI - P2.5 -> P2_IOCR4 -> PC4 ( because P2.5) -> bits [15-11]
Alternate function 2 */
PORT2->IOCR4 |= 0b00000000000000001001000000000000;
/* CLK - P2.4 -> P2_IOCR4 -> PC4 ( because P2.4) -> bits [7-3]
Alternate function 2 */
PORT2->IOCR4 |= 0b00000000000000000000000010010000;
/* Slave Select SELO0 - P2.3,
P2.3 -> P2_IOCR0 -> PC3 ( because P2.3) -> bits [31-27]
Alternate function 2(cf RM p 2496 23.10 ) -> 10010b */
PORT2->IOCR0 |= 0b10010000000000000000000000000000;
/// ------------------------------------------------------------


/* ============================ LOOP ============================ */
while(1U)
{
/* Slave Select */
// MSLSEN - activate slave
SPI_CH->PCR |= (1<<0);

// counter set at 0 :
cpt = 0;
// reset table
for (i=0; i<9; i++)
{
data_received = 0;
}

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++;


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;
/* Close SPI connection */
// MSLSEN - deactivate slave
SPI_CH->PCR = (0<<0);


// wait for 0.25 sec with time machine = 144 MHz
for (i=0; i<36500000; i++)
{
j = i+1;
}
j = 0;
debug_TDV++;
if ( debug_TDV >= 200)
debug_TDV = 0;

}
}



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

Do you mean the same code is not working on a XMC4300? Can you describe the problem?

The USIC module is similar across the XMC family and I also expect pinout compatibility between XMC4300 and XMC4800 though there might be pins no longer available with the smaller XMC4300 package. Also I understand both devices are running at 144 MHz.
Therefore, I expect the same code to be usable in XMC4300.
Of course, the include file must be changed accordingly.

Regards,
Min Wei
0 Likes
Not applicable
Hello,
I have a code for the XMC4800, and I want to transfer it on the XMC4300.

The code is about testing SPI connection.

The pins are not the same :
in the XMC4700 :


/* 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;


In the XMC4300, the SPI pins are
CS/2.3
SCK/2.4
MISO/2.2
MOSI/2.5


/* INPUT - MISO - P2.2 - P2_IOCR0 -> PC2 (because P2.2) -> bits [23-19] - direct input */
//PORT2->IOCR0 &= 0b11111111000001111111111111111111; -> No need to use it, because it is 00000b
/* OUTPUT - MOSI - P2.5 -> P2_IOCR4 -> PC4 ( because P2.5) -> bits [15-11]
Alternate function 2 */
PORT2->IOCR4 |= 0b00000000000000001001000000000000;
/* CLK - P2.4 -> P2_IOCR4 -> PC4 ( because P2.4) -> bits [7-3]
Alternate function 2 */
PORT2->IOCR4 |= 0b00000000000000000000000010010000;
/* Slave Select SELO0 - P2.3,
P2.3 -> P2_IOCR0 -> PC3 ( because P2.3) -> bits [31-27]
Alternate function 2(cf RM p 2496 23.10 ) -> 10010b */
PORT2->IOCR0 |= 0b10010000000000000000000000000000;



Everything else is the same.

I don't have XMC4300.h, does it exist ?

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

Which tool are you using?

For example with DAVE4.2.6, I can create a new project and select the device XMC4300. All the relevant files (xmc4300.h, startup, system, etc) will be generated accordingly.

Regards,
Min Wei
0 Likes
Not applicable
Hello,
Yes, by creating a new project with Dave, the inclusion of XMC4300.h works.
However, my code still has a problem :
Do you see something in it ?


/*
* main.c

*/

#include

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

/* ===================== Global variable declaration ===================== */
uint8_t debug_tcsr_sof;
uint8_t debug_TDV = 0;
uint8_t debug_RBUF01, debug_RBUF10;

/* ===================== 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 = 250 kbit/s
/// - SCLKCFG = 10b, cf RM p1828 : data transmitted on the falling edge (CPOL = 0, CPHA = 1)
/// ------------------------------------------------------------
/// ------------------------------------------------------------
// DM = 01b STEP = 1023d = 3FFh = 001111111111b
SPI_CH->FDR = (1 << 14) | ( 1023 << 0);
// SCLKCFG PDIV = 287
SPI_CH->BRG = (2 << 30) | (287 << 16);

/// ------------------------------------------------------------

/// ------------------------------------------------------------
/// 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 = data frame = 8 bits
/// - Data transfer allowed with passive level = 0 and MSB first
/// ------------------------------------------------------------
// WLE FLE TRM SDIR
SPI_CH->SCTR = (7<<24)|(7<<16)|(1<<8)|(1<<0);
// Not Frame settle
// WLE TRM SDIR
// SPI_CH->SCTR = (7<<24)|(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
/// ------------------------------------------------------------
// SELO SELINV SELCTR MSLSEN
SPI_CH->PCR = (1<<16)|(1<<2)|(1<<1)|(1<<0);
/// ------------------------------------------------------------


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


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

/* ===================== Variable declaration ===================== */
uint32_t i,j = 0;

uint8_t a, b, c, d;

uint16_t data_received[9];
uint16_t dummy;
uint8_t cpt = 0;

/* 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 - P2.2 - P2_IOCR0 -> PC2 (because P2.2) -> bits [23-19] - direct input */
PORT2->IOCR0 &= 0b11111111000001111111111111111111;
/* OUTPUT - MOSI - P2.5 -> P2_IOCR4 -> PC4 ( because P2.5) -> bits [15-11]
Alternate function 2 */
PORT2->IOCR4 |= 0b00000000000000001001000000000000;
/* CLK - P2.4 -> P2_IOCR4 -> PC4 ( because P2.4) -> bits [7-3]
Alternate function 2 */
PORT2->IOCR4 |= 0b00000000000000000000000010010000;
/* Slave Select SELO0 - P2.3,
P2.3 -> P2_IOCR0 -> PC3 ( because P2.3) -> bits [31-27]
Alternate function 2(cf RM p 2496 23.10 ) -> 10010b */
PORT2->IOCR0 |= 0b10010000000000000000000000000000;
/// ------------------------------------------------------------

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

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


// counter set at 0 :
cpt = 0;
// reset table
for (i=0; i<9; i++)
{
data_received = 0;
}

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++;


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 0.25 sec with time machine = 144 MHz
for (i=0; i<36500000; i++)
{
j = i+1;
}
j = 0;
debug_TDV++;
if ( debug_TDV >= 200)
debug_TDV = 0;


}
}



Thank you,
Nicolas
0 Likes
Not applicable
Someone has any leads ?
Thank,
Nicolas
0 Likes