XMC1300 Problems with FIFO USIC in UART configuration

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

cross mob
Not applicable
I'm experienced problems when using both channels of the USIC module in UART configuration.
The processor is the XMC1302.

Channel 0 is configured for use as RS232 port. Channel 1 is RS485.
I have configured the 64 entry FIFO to be split evenly among:
CH0-Transmit (16 entries)
CH0-Receive (16 entries)
CH1-Transmit (16 entries)
CH1-Receive (16 entries)

The problem I am having is the CH0-Transmit and CH1-Transmit buffers appear to be overwriting each other.

Channel 0 Initialization.
Transmit FIFO DPTR = 0, Size = 16
Receive FIFO DPTR = 16, Size = 16


// Initialize Channel 0 (RS232 port)
void Init_CH0()
{
// Configure Transmit Buffer

// Define start entry of Transmit Data FIFO buffer DPTR = 0
USIC0_CH0->TBCTR &= ~(USIC_CH_TBCTR_SIZE_Msk);
USIC0_CH0->TBCTR &= ~(USIC_CH_TBCTR_DPTR_Msk);

// Set Transmit Data Buffer size to 16
USIC0_CH0->TBCTR |= (0x04UL << USIC_CH_TBCTR_SIZE_Pos);

// Standard Transmit Buffer Interrupt Node Pointer - Output SR0 activated (STBINP = 0)
// USIC0_CH0->TBCTR &= ~(USIC_CH_TBCTR_STBINP_Msk ); /* Transmit interrupt not used for now

// Standard Transmit Buffer Interrupt Enabled
// USIC0_CH0->TBCTR |= USIC_CH_TBCTR_STBIEN_Msk; /* Transmit interrupt not used for now

// Configure Receive Buffer

// Define start entry of receive Data FIFO buffer DPTR = 16
USIC0_CH0->RBCTR &= ~(USIC_CH_RBCTR_SIZE_Msk);
USIC0_CH0->RBCTR |= (0x10UL << USIC_CH_RBCTR_DPTR_Pos);

// Set Receive Data Buffer size to 16
USIC0_CH0->RBCTR |= (0x04UL << USIC_CH_RBCTR_SIZE_Pos);

// Standard Receive Buffer Interrupt Node Pointer - Output SR1 activated (SRBINP = 1)
USIC0_CH0->RBCTR |= (0x01UL << USIC_CH_RBCTR_SRBINP_Pos);

// LIMIT for interrupt generation = 0 bytes. Interrupt if at least 1 byte in buffer
USIC0_CH0->RBCTR &= ~(USIC_CH_RBCTR_LIMIT_Msk );

// Event on Limit Overflow - Event occurs when filling level > Limit
USIC0_CH0->RBCTR |= USIC_CH_RBCTR_LOF_Msk;

// Standard Receive buffer interrupt is enabled
USIC0_CH0->RBCTR |= USIC_CH_RBCTR_SRBIEN_Msk;

// Initialize UART_RX (DX0)
P0_14_set_mode(INPUT);

// Select P0.14 as input for USIC DX0
USIC0_CH0->DX0CR &= ~(USIC_CH_DX0CR_DSEL_Msk);

// Initialize UART_TX (DOUT)
// P0.15 as output controlled by ALT6 = USIC0_CH0.DOUT0
P0_15_set_mode(OUTPUT_PP_AF6);

// Configuration of Channel Control Register
// CCR.PM = 00 ( Disable parity generation)
// CCR.MODE = 2 (UART mode enabled. )
USIC0_CH0->CCR &= ~(USIC_CH_CCR_PM_Msk | USIC_CH_CCR_MODE_Msk);
USIC0_CH0->CCR |= 0x02UL << USIC_CH_CCR_MODE_Pos;
}


Channel 1 Initialization.
Transmit FIFO DPTR = 32, Size = 16
Receive FIFO DPTR = 48, Size = 16


// Initialize Channel 1
void Init_CH1()
{
// Configure Transmit Buffer

// Define start entry of Transmit Data FIFO buffer DPTR = 32
USIC0_CH1->TBCTR &= ~(USIC_CH_TBCTR_SIZE_Msk);
USIC0_CH1->TBCTR |= (0x20UL << USIC_CH_TBCTR_DPTR_Pos);

// Set Transmit Data Buffer size to 16
USIC0_CH1->TBCTR |= (0x04UL << USIC_CH_TBCTR_SIZE_Pos);

// Standard Transmit Buffer Interrupt Node Pointer - Output SR2 activated (STBINP = 2)
// USIC0_CH1->TBCTR |= (0x02UL << USIC_CH_TBCTR_STBINP_Pos); /* Transmit Interrupt not used for now

// Standard Transmit buffer interrupt is enabled
// USIC0_CH1->TBCTR |= USIC_CH_TBCTR_STBIEN_Msk; /* Transmit Interrupt not used for now

// Configure Receive Buffer

// Define start entry of receive Data FIFO buffer DPTR = 48
USIC0_CH1->RBCTR &= ~(USIC_CH_RBCTR_SIZE_Msk);
USIC0_CH1->RBCTR |= (0x30UL << USIC_CH_RBCTR_DPTR_Pos);

// Set Receive Data Buffer size to 16
USIC0_CH1->RBCTR |= (0x04UL << USIC_CH_RBCTR_SIZE_Pos);

// Standard Receive Buffer Interrupt Node Pointer - Output SR3 activated (STBINP = 3)
USIC0_CH1->RBCTR |= (0x03UL << USIC_CH_RBCTR_SRBINP_Pos);

// LIMIT for interrupt generation = 0 bytes. Interrupt if at least 1 byte in buffer
USIC0_CH1->RBCTR &= ~(USIC_CH_RBCTR_LIMIT_Msk );

// Event on Limit Overflow - Event occurs when filling level > Limit
USIC0_CH1->RBCTR |= USIC_CH_RBCTR_LOF_Msk;

// Standard Receive buffer interrupt is enabled
USIC0_CH1->RBCTR |= USIC_CH_RBCTR_SRBIEN_Msk;

// Initialize UART_RX (DX0)
P0_6_set_mode(INPUT);

// Select P0.6 as input for USIC DX0
USIC0_CH1->DX0CR |= (0x02UL << USIC_CH_DX0CR_DSEL_Pos);

// Initialize UART_TX (DOUT)
// P0.7 as output controlled by ALT7 = U0C1.DOUT0
P0_7_set_mode(OUTPUT_PP_AF7);

// Configuration of Channel Control Register
// CCR.PM = 00 ( Disable parity generation)
// CCR.MODE = 2 (UART mode enabled. )
USIC0_CH1->CCR &= ~(USIC_CH_CCR_PM_Msk | USIC_CH_CCR_MODE_Msk);
USIC0_CH1->CCR |= 0x02UL << USIC_CH_CCR_MODE_Pos;
}


For Testing purposes, I have hard coded the transmitted responses for both channels:


// send the response to RS232 commands on Channel 0
void SendModbusResponse_RS232(void)
{

USIC0_CH0->IN[0] = 0x01;
USIC0_CH0->IN[0] = 0x03;
USIC0_CH0->IN[0] = 0x02;
USIC0_CH0->IN[0] = 0x00;
USIC0_CH0->IN[0] = 0x0a;
USIC0_CH0->IN[0] = 0x38;
USIC0_CH0->IN[0] = 0x43;
}

// send the response to RS485 commands on Channel 1
void SendModbusResponse_RS485(void)
{
USIC0_CH1->IN[0] = 0x01;
USIC0_CH1->IN[0] = 0x04;
USIC0_CH1->IN[0] = 0x02;
USIC0_CH1->IN[0] = 0x00;
USIC0_CH1->IN[0] = 0x03;
USIC0_CH1->IN[0] = 0xf9;
USIC0_CH1->IN[0] = 0x31;
}


During testing, data transmitted from Channel 0 sometimes contains characters from Channel 1.
Conversly, Channel 1 output contains characters from Channel 0.
The number of bytes sent is always 7 for both Channels.
It appears that the transmit FIFO areas are overlapping.

I suspect that I have not configured the DPTR and SIZE for each FIFO correctly.
Any ideas?

Regards,
Tom

0 Likes
1 Solution
Not applicable
Found the the answer to my own question.

TBCTR.SIZE and TBCTR.DPTR must be initialized at the same time with a single write to the control register.

So I change the following 2 statements:
// Define start entry of Transmit Data FIFO buffer DPTR = 32
USIC0_CH1->TBCTR |= (32UL << USIC_CH_TBCTR_DPTR_Pos);
// Set Transmit Data Buffer size to 16
USIC0_CH1->TBCTR |= (0x04UL << USIC_CH_TBCTR_SIZE_Pos);

To a single statement:
// Define start entry of Transmit Data FIFO buffer DPTR = 32 and SIZE = 16
USIC0_CH1->TBCTR |= ((32UL << USIC_CH_TBCTR_DPTR_Pos) | (0x04UL << USIC_CH_TBCTR_SIZE_Pos));

I changed the SIZE and DTPR initialization for all 4 FIFO buffers as shown above. (Channels 0 and 1, Transmit and Receive).
All works now.

View solution in original post

0 Likes
3 Replies
Not applicable
Found the the answer to my own question.

TBCTR.SIZE and TBCTR.DPTR must be initialized at the same time with a single write to the control register.

So I change the following 2 statements:
// Define start entry of Transmit Data FIFO buffer DPTR = 32
USIC0_CH1->TBCTR |= (32UL << USIC_CH_TBCTR_DPTR_Pos);
// Set Transmit Data Buffer size to 16
USIC0_CH1->TBCTR |= (0x04UL << USIC_CH_TBCTR_SIZE_Pos);

To a single statement:
// Define start entry of Transmit Data FIFO buffer DPTR = 32 and SIZE = 16
USIC0_CH1->TBCTR |= ((32UL << USIC_CH_TBCTR_DPTR_Pos) | (0x04UL << USIC_CH_TBCTR_SIZE_Pos));

I changed the SIZE and DTPR initialization for all 4 FIFO buffers as shown above. (Channels 0 and 1, Transmit and Receive).
All works now.
0 Likes
Bond_007
Level 3
Level 3
10 questions asked 25 sign-ins 10 replies posted

Hi,

I'm working on UART as above to receive data from serial terminal. Unable to generate interrupt can you please help me to receive data from terminal.
I'm using P1.2 -> TXD, P1.3 -> RXD. below is the configuration I had done. please check and let me know any mistakes.

  void UART_CH0_Init() {
		//UART initialization sequence  // loop back mode
		XMC_UART_CH_Init(UART0_Channel1, &uart_config);
		XMC_UART_CH_SetInputSource(UART0_Channel1, XMC_UART_CH_INPUT_RXD,
				USIC0_C1_DX0_P1_3); // loop back mode  XMC_USIC_CH_INPUT_DX0, USIC0_C0_DX0_DOUT0
		XMC_UART_CH_Start(UART0_Channel1);  // CCR.mode=UART

		//UART Rx pin configuration
		rx_pin_config.mode = XMC_GPIO_MODE_INPUT_PULL_UP; // Rx input with internal pull-up
		XMC_GPIO_Init(UART_RX_PIN, &rx_pin_config);
		//UART Tx pin configuration
		tx_pin_config.output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH;
		tx_pin_config.mode = XMC_GPIO_MODE_OUTPUT_ALT2; // Tx output in ALT2
		XMC_GPIO_Init(UART_TX_PIN, &tx_pin_config);
		
		// Define start entry of Transmit Data FIFO buffer DPTR = 32 and SIZE = 16
	    USIC0_CH1->TBCTR &= ~(USIC_CH_TBCTR_SIZE_Msk);
		USIC0_CH1->TBCTR |= ((32UL << USIC_CH_TBCTR_DPTR_Pos) | (0x04UL << USIC_CH_TBCTR_SIZE_Pos));

		// Define start entry of Transmit Data FIFO buffer DPTR = 32 and SIZE = 16
	    // Define start entry of receive Data FIFO buffer DPTR = 48
	    USIC0_CH1->RBCTR &= ~(USIC_CH_RBCTR_SIZE_Msk);
	    USIC0_CH1->RBCTR |= ((0x30UL << USIC_CH_RBCTR_DPTR_Pos) | (0x04UL << USIC_CH_RBCTR_SIZE_Pos));

	    // Standard Receive Buffer Interrupt Node Pointer - Output SR3 activated (STBINP = 3)
	    USIC0_CH1->RBCTR |= (0x03UL << USIC_CH_RBCTR_SRBINP_Pos);

	    // LIMIT for interrupt generation = 0 bytes. Interrupt if at least 1 byte in buffer
	    USIC0_CH1->RBCTR &= ~(USIC_CH_RBCTR_LIMIT_Msk );

	    // Event on Limit Overflow - Event occurs when filling level > Limit
	    USIC0_CH1->RBCTR |= USIC_CH_RBCTR_LOF_Msk;

	    // Standard Receive buffer interrupt is enabled
	    USIC0_CH1->RBCTR |= USIC_CH_RBCTR_SRBIEN_Msk;

		XMC_USIC_CH_EnableEvent(UART0_Channel1, XMC_USIC_CH_EVENT_STANDARD_RECEIVE); // enable interrupt RI
		XMC_USIC_CH_SetInterruptNodePointer(UART0_Channel1,
				XMC_USIC_CH_INTERRUPT_NODE_POINTER_RECEIVE, USIC0_SR0); // set USIC0 SR5 for RI
		XMC_USIC_CH_EnableEvent(UART0_Channel1,
				XMC_USIC_CH_EVENT_ALTERNATIVE_RECEIVE);   // 'USIC_AI.007' -> AIR ON
		XMC_USIC_CH_SetInterruptNodePointer(UART0_Channel1,
				XMC_USIC_CH_INTERRUPT_NODE_POINTER_ALTERNATE_RECEIVE, USIC0_SR0);
//
		NVIC_SetPriority(USIC0_0_IRQn, 2); //  NVIC control: NVIC_SetPriority(IRQn_t IRQn, uint32_t priority): priority=0..63
		NVIC_EnableIRQ(USIC0_0_IRQn);       // NVIC control: enable IRQn
  }
0 Likes

Hi,
I tried with above but no use. I'm using P1.2 -> TXD, P1.3 -> RXD.
Not getting data or interrupt with above P1.3 RXD pin why ?

Data is getting/interrupt is generating for the only P0.6 why ? 
What is the difference/reason behind that ?
Did I miss anything please check added code, which is working/receiving data for only P0.6 pin of XMC1302.

void UART_CH1_Init() {
//UART initialization sequence // loop back mode
XMC_UART_CH_Init(UART0_Channel1, &uart_config);
XMC_UART_CH_SetInputSource(UART0_Channel1, 0,
USIC0_C1_DX0_P0_6); //Select the Source DX0,DX3,DX5

XMC_UART_CH_Start(UART0_Channel1); // CCR.mode=UART

//UART Rx pin configuration
rx_pin_config.mode = XMC_GPIO_MODE_INPUT_PULL_UP; // Rx input with internal pull-up
XMC_GPIO_Init(UART_RX1_PIN, &rx_pin_config);
//UART Tx pin configuration
tx_pin_config.output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH;
tx_pin_config.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT7; // Tx output in ALT2
XMC_GPIO_Init(UART_TX_PIN, &tx_pin_config);
//XMC_GPIO_Init(XMC_GPIO_PORT1, 5, &tx_pin_config); // optional: configure pin1_5 as ALT2 output pin with '1'

XMC_USIC_CH_TXFIFO_Configure(UART0_Channel1, 0,
XMC_USIC_CH_FIFO_SIZE_8WORDS, 1); // 8 entries for TxFIFO from point 0, LIMIT=1
XMC_USIC_CH_RXFIFO_Configure(UART0_Channel1, 16,
XMC_USIC_CH_FIFO_SIZE_8WORDS, 7); // 8 entries for RxFIFO from point 16, LIMIT=7 (SRBI is set if all 8*data has been received)

XMC_USIC_CH_EnableEvent(UART0_Channel1, XMC_USIC_CH_EVENT_STANDARD_RECEIVE); // enable interrupt RI
XMC_USIC_CH_SetInterruptNodePointer(UART0_Channel1,
XMC_USIC_CH_INTERRUPT_NODE_POINTER_RECEIVE, USIC0_SR0); // set USIC0 SR5 for RI

XMC_USIC_CH_EnableEvent(UART0_Channel1,
XMC_USIC_CH_EVENT_ALTERNATIVE_RECEIVE); // 'USIC_AI.007' -> AIR ON
XMC_USIC_CH_SetInterruptNodePointer(UART0_Channel1,
XMC_USIC_CH_INTERRUPT_NODE_POINTER_ALTERNATE_RECEIVE, USIC0_SR0);

NVIC_SetPriority(USIC0_0_IRQn, 2); // NVIC control: NVIC_SetPriority(IRQn_t IRQn, uint32_t priority): priority=0..63
NVIC_EnableIRQ(USIC0_0_IRQn); // NVIC control: enable IRQn
}

void USIC0_0_IRQHandler() {
NVIC_ClearPendingIRQ(USIC0_SR0);
gu16RxData = XMC_USIC_CH_RXFIFO_GetData(UART0_Channel1);
}

0 Likes