This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

SCI FIFO interrupt occurs one more time than expected

Hi,

I am learning the C2000 DSC with the F28069 and working on the SCI module these days.

I used the RX/TX FIFO and the RX FIFO worked well but I had some difficulty in using the TX FIFO.

I set the FIFO level of RX/TX both 2 and I want to send two chars to the DSC and then it will sent the same chars back.

I notice that the TX interrupt should be disabled if there is nothing to send or the interrupt will occur all the time. So I just disable the TX interrupt in the TX ISR.

But every time I send two chars to the DSC, it will send the same chars back TWICE.

For example, I send "Hi" to the DSC and it will send "HiHi" back.

The initialization codes are shown below.

// Test 1,SCIA  DLB, 8-bit word, baud rate 0x0103, default, 1 STOP bit, no parity
void scia_echoback_init()
{
    // Note: Clocks were turned on to the SCIA peripheral
    // in the InitSysCtrl() function
	SciaRegs.SCICCR.bit.STOPBITS = 0;			// 1 stop bit
	SciaRegs.SCICCR.bit.PARITY = 0; 			// Odd parity
	SciaRegs.SCICCR.bit.PARITYENA = 0;			// No parity
	SciaRegs.SCICCR.bit.LOOPBKENA = 0;			//No loopback
	SciaRegs.SCICCR.bit.ADDRIDLE_MODE = 0;		//Idle-line mode
	SciaRegs.SCICCR.bit.SCICHAR = 7;			//8 char bits

	SciaRegs.SCICTL1.bit.RXERRINTENA = 0;		// Disable RX ERR
	SciaRegs.SCICTL1.bit.SWRESET = 0;			// SCI software reset
	SciaRegs.SCICTL1.bit.TXWAKE = 0;			// Disable TXWAKE
	SciaRegs.SCICTL1.bit.SLEEP = 0;				// Disable SLEEP
	SciaRegs.SCICTL1.bit.TXENA = 1;				// Transmitter enabled
	SciaRegs.SCICTL1.bit.RXENA = 1;				// Receiver enabled

	SciaRegs.SCICTL2.bit.TXINTENA =1;			// Enable TXRDY interrupt
	SciaRegs.SCICTL2.bit.RXBKINTENA =1;			// Enable RXRDY/BRKDT interrupt

	SciaRegs.SCIHBAUD    =0x0001;				// 9600 baud @LSPCLK = 22.5MHz (90 MHz SYSCLK).
    SciaRegs.SCILBAUD    =0x0024;				// 22500000/(9600*8)-1=291.968

}

// Initalize the SCI FIFO
void scia_fifo_init()
{
	// SCIFFTX
	SciaRegs.SCIFFTX.bit.SCIRST = 1;			// resume transmit or receive
	SciaRegs.SCIFFTX.bit.SCIFFENA = 1;			// Enable SCI FIFO
	SciaRegs.SCIFFTX.bit.TXFIFOXRESET = 1;		// Re-enable transmit FIFO operation
	SciaRegs.SCIFFTX.bit.TXFFINTCLR = 1;		// Clear TXFFINT flag
	//SciaRegs.SCIFFTX.bit.TXFFIENA = 1;		// TX FIFO interrupt based on TXFFIVL match is enabled
	SciaRegs.SCIFFTX.bit.TXFFIL = FifoLevel;	// Transmit FIFO interrupt level

	// SCIFFRX
	SciaRegs.SCIFFRX.bit.RXFFOVRCLR = 1;		// Clear RXFFOVF flag
	SciaRegs.SCIFFRX.bit.RXFIFORESET = 1;		// Re-enable receive FIFO operation
	SciaRegs.SCIFFRX.bit.RXFFINTCLR = 1;		// Clear RXFFINT flag
	SciaRegs.SCIFFRX.bit.RXFFIENA = 1;			// RX FIFO interrupt based on RXFFIVL match is disabled
	SciaRegs.SCIFFRX.bit.RXFFIL = FifoLevel;	// Receive FIFO interrupt level


    // SCIFFCT
    SciaRegs.SCIFFCT.bit.CDC = 0;				// Disables auto-baud alignment
    SciaRegs.SCIFFCT.bit.FFTXDLY = 0;			// FIFO transfer delay

    SciaRegs.SCICTL1.bit.SWRESET = 1;			// Relinquish SCI from Reset
    SciaRegs.SCIFFTX.bit.TXFIFOXRESET=1;
    SciaRegs.SCIFFRX.bit.RXFIFORESET=1;

}

The RX ISR.

interrupt void sciaRxFifoIsr(void)
{
	uint16 i = 0;
	RxIsrCount++;
	for (i = 0;i < FifoLevel;i++)
	{
		RxData[i] = SciaRegs.SCIRXBUF.all;
	}

	SciaRegs.SCIFFTX.bit.TXFFIENA = 1;			// TX FIFO interrupt based on TXFFIVL match is enabled

    SciaRegs.SCIFFRX.bit.RXFFOVRCLR = 1;   		// Clear Overflow flag
    SciaRegs.SCIFFRX.bit.RXFFINTCLR = 1;   		// Clear Interrupt flag

    PieCtrlRegs.PIEACK.all |= M_INT9;       	// Issue PIE ack
}

The TX ISR.

interrupt void sciaTxFifoIsr(void)
{
	TxIsrCount++;
	uint16 j = 0;
	for (j = 0;j < FifoLevel;j++)
	{
		SciaRegs.SCITXBUF = RxData[j];
	}

    SciaRegs.SCIFFTX.bit.TXFFINTCLR = 1;  		// Clear SCI Interrupt flag
    SciaRegs.SCIFFTX.bit.TXFFIENA = 0;			// TX FIFO interrupt based on TXFFIVL match is disabled

    PieCtrlRegs.PIEACK.all |= M_INT9;      		// Issue PIE ACK
}

And I find that if I change the order of clearance the SCI Interrupt flag and the TX FIFO interrupt enable bit in the TX ISR as shown below, the DSC will work well and just send me the correct chars.

interrupt void sciaTxFifoIsr(void)
{
	TxIsrCount++;
	uint16 j = 0;
	for (j = 0;j < FifoLevel;j++)
	{
		SciaRegs.SCITXBUF = RxData[j];
	}
    
    SciaRegs.SCIFFTX.bit.TXFFIENA = 0;			// TX FIFO interrupt based on TXFFIVL match is disabled
    SciaRegs.SCIFFTX.bit.TXFFINTCLR = 1;  		// Clear SCI Interrupt flag

    PieCtrlRegs.PIEACK.all |= M_INT9;      		// Issue PIE ACK
}

I really don't know why.

I put my whole project as the attachment.

7776.F28069SCI_3.rar

I am looking forward for your help.

:)

thanks and regards

Di

  • Hi Di,

    One thing you can do is 1) eliminate the TxISR and 2) inside the RxISR, write the RxData to the TXBUF directly. This is similar to the Sci_Echoback example in conrtolSUITE. Your configuration of the SCI will send the data out once the TxBuffer reaches the FifoLevel (2 in this case). You no longer need to have a TXISR and handle the TXFFIENA and TXFFINTCLR bits.

    We will look into why that particular order of writes to TXFFIENA and TXFFINTCLR is causing it to send data twice and get back to you.

    Best Regards,
    sal
  • Hi Di,

    Can you confirm that the TXISR is being entered twice as often as the RXSIR when you are getting the data back twice?

    Is TXISRCount double RXISRCount when you are getting the data sent back twice?

    sal
  • Hi,
    Sal, thanks for your help.
    I am sure the TXISR is being entered twice as often as the RXSIR.
    And I have put my whole project as the attachment you can download it and have a try.
    I am looking forward for your reply.
    :)
    -Di
  • Hi Di,

    I have looked at and run your code and have also gotten it to work when I first disable the interrupt and then clear the flag. When you first clear the flag and then disable the interrupt, an unintended interrupt is being generated before the interrupt is completely disabled.
    You can also see this thread e2e.ti.com/.../1480549

    Generally, when enabling an interrupt it is best practice to 1) clear the flag then 2) enable the interrupt. When disabling the interrupt it is best practice to 1) disable the interrupt then 2) clear the flag.

    Both of these help to prevent unnecessary or unintended interrupts from occurring when the interrupt gets re-enabled.

    Best Regards,
    sal