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.

TMS570LC4357-EP: SCI multi buffered mode

Part Number: TMS570LC4357-EP
Other Parts Discussed in Thread: HALCOGEN

Hi,

I have a problem using multi-buffered mode on SCI-A/lin.

Basically, I want to generate an interrupt every n bytes in order to not overload the cpu too much.
I thought that with multi-buffered mode I can choose after how many bytes generate an interrupt RXDY but it seems not working.
Here is my code:

void sciInit(void)
{
	/** - bring SCI1 out of reset */
        sci->GCR0 = 0U;
        sci->GCR0 = 1U;

        /** - Disable all interrupts */
        sci->CLEARINT    = 0xFFFFFFFFU;
        sci->CLEARINTLVL = 0xFFFFFFFFU;

        /** - global control 1 */
        sci->GCR1 =  (uint32)((uint32)1U << 25U)  /* enable transmit */
                      | (uint32)((uint32)1U << 24U)  /* enable receive */
                      | (uint32)((uint32)1U << 5U)   /* internal clock (device has no clock pin) */
                      | (uint32)((uint32)(1U-1U) << 4U)  /* number of stop bits */
                      | (uint32)((uint32)0U << 3U)  /* even parity, otherwise odd */
                      | (uint32)((uint32)0U << 2U)  /* enable parity */
                      | (uint32)((uint32)1U << 1U)  /* asynchronous timing mode */
                      | (uint32)((uint32)1U << 16U) /* LOOP BACK MODE enabled for test*/
                      | (uint32)((uint32)1U << 10U); /* multi buffered mode enabled */

        /** - set baudrate */
        sci->BRS = 650U;  /* baudrate */

        /** - transmission length */
        sci->FORMAT = /*0x0700 |*/ (8U - 1U);  /* length (8 characters of size 8, according to datasheet) */

        /** - set SCI1 pins functional mode */
        sci->PIO0 = (uint32)((uint32)1U << 2U)  /* tx pin */
                     | (uint32)((uint32)1U << 1U); /* rx pin */

        /** - set SCI1 pins default output value */
        sci->PIO3 = (uint32)((uint32)0U << 2U)  /* tx pin */
                     | (uint32)((uint32)0U << 1U); /* rx pin */

        /** - set SCI1 pins output direction */
        sci->PIO1 = (uint32)((uint32)0U << 2U)  /* tx pin */
                     | (uint32)((uint32)0U << 1U); /* rx pin */

        /** - set SCI1 pins open drain enable */
        sci->PIO6 = (uint32)((uint32)0U << 2U)  /* tx pin */
                     | (uint32)((uint32)0U << 1U); /* rx pin */

        /** - set SCI1 pins pullup/pulldown enable */
        sci->PIO7 = (uint32)((uint32)0U << 2U)  /* tx pin */
                     | (uint32)((uint32)0U << 1U); /* rx pin */

        /** - set SCI1 pins pullup/pulldown select */
        sci->PIO8 = (uint32)((uint32)1U << 2U)  /* tx pin */
                     | (uint32)((uint32)1U << 1U);  /* rx pin */

        /** - set interrupt level */
        sci->SETINTLVL = (uint32)((uint32)0U << 26U)  /* Framing error */
                          | (uint32)((uint32)0U << 25U)  /* Overrun error */
                          | (uint32)((uint32)0U << 24U)  /* Parity error */
                          | (uint32)((uint32)0U << 9U)  /* Receive */
                          | (uint32)((uint32)0U << 8U)  /* Transmit */
                          | (uint32)((uint32)0U << 1U)  /* Wakeup */
                          | (uint32)((uint32)0U << 0U);  /* Break detect */

        /** - set interrupt enable */
        sci->SETINT = (uint32)((uint32)0U << 26U)  /* Framing error */
                       | (uint32)((uint32)0U << 25U)  /* Overrun error */
                       | (uint32)((uint32)0U << 24U)  /* Parity error */
                       | (uint32)((uint32)1U << 9U)  /* Receive interrupt*/
                       | (uint32)((uint32)0U << 1U)  /* Wakeup */
                       | (uint32)((uint32)0U << 0U);  /* Break detect */

        /** - Finaly start SCI1 */
        sci->GCR1 |= 0x80U;

}

To test the peripheral I just send a bunch of dummy bytes and check if ISR is executed (since I'm working in loopback).
Without multi-buffer I can have an interrupt every byte sent and it's working fine, so the interrupts are well configurated but with multi-buffered mode ISR is never executed (I though ISR was executed every 8 bytes trasmitted).

Is it possible to generate an interrupt after n bytes without using DMA? If yes, how to get data? SCIRD register is only 1byte-length and I'm not understanding where the data will be available.

Thanks,

Marco.

  • Hi,

      You should be able to do multi-buffer SCI without using the DMA. 

    29.2.1.5 SCI Multi Buffered Mode
    To reduce CPU load when Receiving or Transmitting data in interrupt mode or DMA mode, the SCI/LIN
    module has eight separate Receive and transmit buffers. Multi buffered mode is enabled by setting the
    MBUF MODE bit.
    The multi-buffer 3-bit counter counts the data bytes transferred from the SCIRXSHF register to the RDy
    receive buffers and TDy transmit buffers register to SCITXSHF register. The 3-bit compare register
    contains the number of data bytes expected to be received or transmitted. the LENGTH value in
    SCIFORMAT register indicates the expected length and is used to load the 3-bit compare register.
    A receive interrupt (RX interrupt; see the SCIINTVECT0 and SCIINTVECT1registers), and a receive ready
    RXRDY flag set in SCIFLR register, as well as a DMA request (RXDMA) could occur after receiving a
    response if there are no response receive errors for the frame (such as, there is, frame error, and overrun
    error).

    29.2.4.1.2 Receiving Data in Multi-Buffer Mode
    Multi-Buffer Mode is selected when MBUF MODE bit is 1. In this mode SCI sets the RXRDY bit when
    programmed number of data are received in the receive buffer, the complete frame. The error condition
    detection logic is same as Single Buffer Mode, except that it monitors for the complete frame. Like Single
    Buffer Mode, you can use either Interrupt, DMA or polling method to read the data. The received data has
    to be read from the LINRD0 and LINRD1 register, based on the number of bytes. For LENGTH less than
    or equal to 4, Read to LINRD0 register will clear the “RXRDY” flag. For LENGTH greater than 4, Read to
    LINRD1 register will clear the “RXRDY” flag.

    I think you miss to define the LENGTH which indicates the number of bytes to transfer from the shift register to the receive buffer. 

  • Hi Charles,

    In the code that I posted earlier is commented-out but I already done a bunch of tests:

    /** - transmission length */
            sci->FORMAT = 0x0700 | (8U - 1U);  /* length */

    This line makes length = 8 and char = 8, so I'm expecting 8 bytes.

    In this configuration

    /** - global control 1 */
            sci->GCR1 =  (uint32)((uint32)1U << 25U)  /* enable transmit */
                          | (uint32)((uint32)1U << 24U)  /* enable receive */
                          | (uint32)((uint32)1U << 5U)   /* internal clock (device has no clock pin) */
                          | (uint32)((uint32)(1U-1U) << 4U)  /* number of stop bits */
                          | (uint32)((uint32)0U << 3U)  /* even parity, otherwise odd */
                          | (uint32)((uint32)0U << 2U)  /* enable parity */
                          | (uint32)((uint32)1U << 1U)  /* asynchronous timing mode */
                          | (uint32)((uint32)1U << 16U) /* LOOP BACK MODE */
                          | (uint32)((uint32)1U << 10U); /* multi buffered */
    /** - transmission length */
            sci->FORMAT = 0x0700 | (8U - 1U);  /* length */

    doesn't work but in this configuration:

    /** - global control 1 */
            sci->GCR1 =  (uint32)((uint32)1U << 25U)  /* enable transmit */
                          | (uint32)((uint32)1U << 24U)  /* enable receive */
                          | (uint32)((uint32)1U << 5U)   /* internal clock (device has no clock pin) */
                          | (uint32)((uint32)(1U-1U) << 4U)  /* number of stop bits */
                          | (uint32)((uint32)0U << 3U)  /* even parity, otherwise odd */
                          | (uint32)((uint32)0U << 2U)  /* enable parity */
                          | (uint32)((uint32)1U << 1U)  /* asynchronous timing mode */
                          | (uint32)((uint32)1U << 16U) /* LOOP BACK MODE */
                          | (uint32)((uint32)1U << 10U); /* multi buffered */
    /** - transmission length */
            sci->FORMAT = (8U - 1U);  /* length */

    works.

    The code to send the bytes is simple as follow:

    int i,m;
    for(i=0;i<200;i++)
    	    {
    	        sciSendByte(sciREG1, dummy + i);
    	        for(n = 0;n<1000;n++) /* tried putting a delay */
    	                    {
    	                        m++;
    	                    }
    	    }

    And the code to receive interrupt is auto generated by HalCoGen and is:

    void lin1HighLevelInterrupt(void)
    {
        uint32 vec = sciREG1->INTVECT0;
    	uint8 byte;
    /* USER CODE BEGIN (28) */
    	imHere = 1;
    /* USER CODE END */
    
        switch (vec)
        {
        case 1U:
            sciNotification(sciREG1, (uint32)SCI_WAKE_INT);
            break;
        case 3U:
            sciNotification(sciREG1, (uint32)SCI_PE_INT);
            break;
        case 6U:
            sciNotification(sciREG1, (uint32)SCI_FE_INT);
            break;
        case 7U:
            sciNotification(sciREG1, (uint32)SCI_BREAK_INT);
            break;
        case 9U:
            sciNotification(sciREG1, (uint32)SCI_OE_INT);
            break;
    
        case 11U:
            /* receive */
            byte = (uint8)(sciREG1->RD & 0x000000FFU);
    
                if (g_sciTransfer_t[0U].rx_length > 0U)
                {
                    *g_sciTransfer_t[0U].rx_data = byte;
                    g_sciTransfer_t[0U].rx_data++;
                    
                    g_sciTransfer_t[0U].rx_length--;
                    if (g_sciTransfer_t[0U].rx_length == 0U)
                    {
                        sciNotification(sciREG1, (uint32)SCI_RX_INT);
                    }
                }
            
            break;
    
        case 12U:
            /* transmit */
    		/*SAFETYMCUSW 30 S MR:12.2,12.3 <APPROVED> "Used for data count in Transmit/Receive polling and Interrupt mode" */
    		--g_sciTransfer_t[0U].tx_length;
            if (g_sciTransfer_t[0U].tx_length > 0U)
            {
    			uint8 txdata = *g_sciTransfer_t[0U].tx_data;
                sciREG1->TD = (uint32)txdata;
                g_sciTransfer_t[0U].tx_data++;
            }
            else
            {
                sciREG1->CLEARINT = SCI_TX_INT;
                sciNotification(sciREG1, (uint32)SCI_TX_INT);
            }
            break;
    
        default:
            /* phantom interrupt, clear flags and return */
            sciREG1->FLR = sciREG1->SETINTLVL & 0x07000303U;
             break;
        }
    /* USER CODE BEGIN (29) */
    /* USER CODE END */
    }
    

    Finally, my vin init function appears as follow: (not sure if I'm missing something but, again, the interrupt with single byte works fine:

    void vimInit(void)
    {
    /* USER CODE BEGIN (1) */
    /* USER CODE END */
    
        /* Enable ECC for VIM RAM */
        /* Errata VIM#28 Workaround: Disable Single Bit error correction */
        vimREG->ECCCTL = (uint32)((uint32)0xAU << 0U) | (uint32)((uint32)0x5U << 16U);
    
        /* Initialize VIM table */
        {
            uint32 i;
    
            for (i = 0U; i < VIM_CHANNELS; i++)
            {
                vimRAM->ISR[i] = s_vim_init[i];
            }
        }
        vimREG->FBVECADDR = (uint32)&vimECCErrorHandler;
    
        /* set IRQ/FIQ priorities */
        vimREG->FIRQPR0 = (uint32)((uint32)SYS_FIQ << 0U)
                        | (uint32)((uint32)SYS_FIQ << 1U)
                        | (uint32)((uint32)SYS_IRQ << 2U)
                        | (uint32)((uint32)SYS_IRQ << 3U)
                        | (uint32)((uint32)SYS_IRQ << 4U)
                        | (uint32)((uint32)SYS_IRQ << 5U)
                        | (uint32)((uint32)SYS_IRQ << 6U)
                        | (uint32)((uint32)SYS_IRQ << 7U)
                        | (uint32)((uint32)SYS_IRQ << 8U)
                        | (uint32)((uint32)SYS_IRQ << 9U)
                        | (uint32)((uint32)SYS_IRQ << 10U)
                        | (uint32)((uint32)SYS_IRQ << 11U)
                        | (uint32)((uint32)SYS_IRQ << 12U)
                        | (uint32)((uint32)SYS_IRQ << 13U)
                        | (uint32)((uint32)SYS_IRQ << 14U)
                        | (uint32)((uint32)SYS_IRQ << 15U)
                        | (uint32)((uint32)SYS_IRQ << 16U)
                        | (uint32)((uint32)SYS_IRQ << 17U)
                        | (uint32)((uint32)SYS_IRQ << 18U)
                        | (uint32)((uint32)SYS_IRQ << 19U)
                        | (uint32)((uint32)SYS_IRQ << 20U)
                        | (uint32)((uint32)SYS_IRQ << 21U)
                        | (uint32)((uint32)SYS_IRQ << 22U)
                        | (uint32)((uint32)SYS_IRQ << 23U)
                        | (uint32)((uint32)SYS_IRQ << 24U)
                        | (uint32)((uint32)SYS_IRQ << 25U)
                        | (uint32)((uint32)SYS_IRQ << 26U)
                        | (uint32)((uint32)SYS_IRQ << 27U)
                        | (uint32)((uint32)SYS_IRQ << 28U)
                        | (uint32)((uint32)SYS_IRQ << 29U)
                        | (uint32)((uint32)SYS_IRQ << 30U)
                        | (uint32)((uint32)SYS_IRQ << 31U);
    
        vimREG->FIRQPR1 = (uint32)((uint32)SYS_IRQ << 0U)
                        | (uint32)((uint32)SYS_IRQ << 1U)
                        | (uint32)((uint32)SYS_IRQ << 2U)
                        | (uint32)((uint32)SYS_IRQ << 3U)
                        | (uint32)((uint32)SYS_IRQ << 4U)
                        | (uint32)((uint32)SYS_IRQ << 5U)
                        | (uint32)((uint32)SYS_IRQ << 6U)
                        | (uint32)((uint32)SYS_IRQ << 7U)
                        | (uint32)((uint32)SYS_IRQ << 8U)
                        | (uint32)((uint32)SYS_IRQ << 9U)
                        | (uint32)((uint32)SYS_IRQ << 10U)
                        | (uint32)((uint32)SYS_IRQ << 11U)
                        | (uint32)((uint32)SYS_IRQ << 12U)
                        | (uint32)((uint32)SYS_IRQ << 13U)
                        | (uint32)((uint32)SYS_IRQ << 14U)
                        | (uint32)((uint32)SYS_IRQ << 15U)
                        | (uint32)((uint32)SYS_IRQ << 16U)
                        | (uint32)((uint32)SYS_IRQ << 17U)
                        | (uint32)((uint32)SYS_IRQ << 18U)
                        | (uint32)((uint32)SYS_IRQ << 19U)
                        | (uint32)((uint32)SYS_IRQ << 20U)
                        | (uint32)((uint32)SYS_IRQ << 21U)
                        | (uint32)((uint32)SYS_IRQ << 22U)
                        | (uint32)((uint32)SYS_IRQ << 23U)
                        | (uint32)((uint32)SYS_IRQ << 24U)
                        | (uint32)((uint32)SYS_IRQ << 25U)
                        | (uint32)((uint32)SYS_IRQ << 26U)
                        | (uint32)((uint32)SYS_IRQ << 27U)
                        | (uint32)((uint32)SYS_IRQ << 28U)
                        | (uint32)((uint32)SYS_IRQ << 29U)
                        | (uint32)((uint32)SYS_IRQ << 30U)
                        | (uint32)((uint32)SYS_IRQ << 31U);
    
    
        vimREG->FIRQPR2 = (uint32)((uint32)SYS_IRQ << 0U)
                        | (uint32)((uint32)SYS_IRQ << 1U)
                        | (uint32)((uint32)SYS_IRQ << 2U)
                        | (uint32)((uint32)SYS_IRQ << 3U)
                        | (uint32)((uint32)SYS_IRQ << 4U)
                        | (uint32)((uint32)SYS_IRQ << 5U)
                        | (uint32)((uint32)SYS_IRQ << 6U)
                        | (uint32)((uint32)SYS_IRQ << 7U)
                        | (uint32)((uint32)SYS_IRQ << 8U)
                        | (uint32)((uint32)SYS_IRQ << 9U)
                        | (uint32)((uint32)SYS_IRQ << 10U)
                        | (uint32)((uint32)SYS_IRQ << 11U)
                        | (uint32)((uint32)SYS_IRQ << 12U)
                        | (uint32)((uint32)SYS_IRQ << 13U)
                        | (uint32)((uint32)SYS_IRQ << 14U)
                        | (uint32)((uint32)SYS_IRQ << 15U)
                        | (uint32)((uint32)SYS_IRQ << 16U)
                        | (uint32)((uint32)SYS_IRQ << 17U)
                        | (uint32)((uint32)SYS_IRQ << 18U)
                        | (uint32)((uint32)SYS_IRQ << 19U)
                        | (uint32)((uint32)SYS_IRQ << 20U)
                        | (uint32)((uint32)SYS_IRQ << 21U)
                        | (uint32)((uint32)SYS_IRQ << 22U)
                        | (uint32)((uint32)SYS_IRQ << 23U)
                        | (uint32)((uint32)SYS_IRQ << 24U)
                        | (uint32)((uint32)SYS_IRQ << 25U)
                        | (uint32)((uint32)SYS_IRQ << 26U)
                        | (uint32)((uint32)SYS_IRQ << 27U)
                        | (uint32)((uint32)SYS_IRQ << 28U)
                        | (uint32)((uint32)SYS_IRQ << 29U)
                        | (uint32)((uint32)SYS_IRQ << 30U)
                        | (uint32)((uint32)SYS_IRQ << 31U);
    
        vimREG->FIRQPR3 = (uint32)((uint32)SYS_IRQ << 0U)
                        | (uint32)((uint32)SYS_IRQ << 1U)
                        | (uint32)((uint32)SYS_IRQ << 2U)
                        | (uint32)((uint32)SYS_IRQ << 3U)
                        | (uint32)((uint32)SYS_IRQ << 4U)
                        | (uint32)((uint32)SYS_IRQ << 5U)
                        | (uint32)((uint32)SYS_IRQ << 6U)
                        | (uint32)((uint32)SYS_IRQ << 7U)
                        | (uint32)((uint32)SYS_IRQ << 8U)
                        | (uint32)((uint32)SYS_IRQ << 9U)
                        | (uint32)((uint32)SYS_IRQ << 10U)
                        | (uint32)((uint32)SYS_IRQ << 11U)
                        | (uint32)((uint32)SYS_IRQ << 12U)
                        | (uint32)((uint32)SYS_IRQ << 13U)
                        | (uint32)((uint32)SYS_IRQ << 14U)
                        | (uint32)((uint32)SYS_IRQ << 15U)
                        | (uint32)((uint32)SYS_IRQ << 16U)
                        | (uint32)((uint32)SYS_IRQ << 17U)
                        | (uint32)((uint32)SYS_IRQ << 18U)
                        | (uint32)((uint32)SYS_IRQ << 19U)
                        | (uint32)((uint32)SYS_IRQ << 20U)
                        | (uint32)((uint32)SYS_IRQ << 21U)
                        | (uint32)((uint32)SYS_IRQ << 22U)
                        | (uint32)((uint32)SYS_IRQ << 23U)
                        | (uint32)((uint32)SYS_IRQ << 24U)
                        | (uint32)((uint32)SYS_IRQ << 25U)
                        | (uint32)((uint32)SYS_IRQ << 26U)
                        | (uint32)((uint32)SYS_IRQ << 27U)
                        | (uint32)((uint32)SYS_IRQ << 28U)
                        | (uint32)((uint32)SYS_IRQ << 29U)
                        | (uint32)((uint32)SYS_IRQ << 30U)
                        | (uint32)((uint32)SYS_IRQ << 31U);
    
    
        /* enable interrupts */
        vimREG->REQMASKSET0 = (uint32)((uint32)1U << 0U)
                            | (uint32)((uint32)1U << 1U)
                            | (uint32)((uint32)1U << 2U)
                            | (uint32)((uint32)0U << 3U)
                            | (uint32)((uint32)0U << 4U)
                            | (uint32)((uint32)0U << 5U)
                            | (uint32)((uint32)0U << 6U)
                            | (uint32)((uint32)0U << 7U)
                            | (uint32)((uint32)0U << 8U)
                            | (uint32)((uint32)0U << 9U)
                            | (uint32)((uint32)0U << 10U)
                            | (uint32)((uint32)0U << 11U)
                            | (uint32)((uint32)0U << 12U)
                            | (uint32)((uint32)1U << 13U)
                            | (uint32)((uint32)0U << 14U)
                            | (uint32)((uint32)0U << 15U)
                            | (uint32)((uint32)0U << 16U)
                            | (uint32)((uint32)0U << 17U)
                            | (uint32)((uint32)0U << 18U)
                            | (uint32)((uint32)0U << 19U)
                            | (uint32)((uint32)0U << 20U)
                            | (uint32)((uint32)0U << 21U)
                            | (uint32)((uint32)0U << 22U)
                            | (uint32)((uint32)0U << 23U)
                            | (uint32)((uint32)0U << 24U)
                            | (uint32)((uint32)0U << 25U)
                            | (uint32)((uint32)0U << 26U)
                            | (uint32)((uint32)0U << 27U)
                            | (uint32)((uint32)0U << 28U)
                            | (uint32)((uint32)0U << 29U)
                            | (uint32)((uint32)0U << 30U)
                            | (uint32)((uint32)0U << 31U);
    
        vimREG->REQMASKSET1 = (uint32)((uint32)0U << 0U)
                            | (uint32)((uint32)0U << 1U)
                            | (uint32)((uint32)0U << 2U)
                            | (uint32)((uint32)0U << 3U)
                            | (uint32)((uint32)0U << 4U)
                            | (uint32)((uint32)0U << 5U)
                            | (uint32)((uint32)0U << 6U)
                            | (uint32)((uint32)0U << 7U)
                            | (uint32)((uint32)0U << 8U)
                            | (uint32)((uint32)0U << 9U)
                            | (uint32)((uint32)0U << 10U)
                            | (uint32)((uint32)0U << 11U)
                            | (uint32)((uint32)0U << 12U)
                            | (uint32)((uint32)0U << 13U)
                            | (uint32)((uint32)0U << 14U)
                            | (uint32)((uint32)0U << 15U)
                            | (uint32)((uint32)0U << 16U)
                            | (uint32)((uint32)0U << 17U)
                            | (uint32)((uint32)0U << 18U)
                            | (uint32)((uint32)0U << 19U)
                            | (uint32)((uint32)0U << 20U)
                            | (uint32)((uint32)0U << 21U)
                            | (uint32)((uint32)0U << 22U)
                            | (uint32)((uint32)0U << 23U)
                            | (uint32)((uint32)0U << 24U)
                            | (uint32)((uint32)0U << 25U)
                            | (uint32)((uint32)0U << 26U)
                            | (uint32)((uint32)0U << 27U)
                            | (uint32)((uint32)0U << 28U)
                            | (uint32)((uint32)0U << 29U)
                            | (uint32)((uint32)0U << 30U)
                            | (uint32)((uint32)0U << 31U);
    
        vimREG->REQMASKSET2 = (uint32)((uint32)0U << 0U)
                            | (uint32)((uint32)0U << 1U)
                            | (uint32)((uint32)0U << 2U)
                            | (uint32)((uint32)0U << 3U)
                            | (uint32)((uint32)0U << 4U)
                            | (uint32)((uint32)0U << 5U)
                            | (uint32)((uint32)0U << 6U)
                            | (uint32)((uint32)0U << 7U)
                            | (uint32)((uint32)0U << 8U)
                            | (uint32)((uint32)0U << 9U)
                            | (uint32)((uint32)0U << 10U)
                            | (uint32)((uint32)0U << 11U)
                            | (uint32)((uint32)0U << 12U)
                            | (uint32)((uint32)1U << 13U)
                            | (uint32)((uint32)0U << 14U)
                            | (uint32)((uint32)1U << 15U)
                            | (uint32)((uint32)0U << 16U)
                            | (uint32)((uint32)0U << 17U)
                            | (uint32)((uint32)0U << 18U)
                            | (uint32)((uint32)0U << 19U)
                            | (uint32)((uint32)0U << 20U)
                            | (uint32)((uint32)0U << 21U)
                            | (uint32)((uint32)0U << 22U)
                            | (uint32)((uint32)0U << 23U)
                            | (uint32)((uint32)0U << 24U)
                            | (uint32)((uint32)0U << 25U)
                            | (uint32)((uint32)0U << 26U)
                            | (uint32)((uint32)0U << 27U)
                            | (uint32)((uint32)0U << 28U)
                            | (uint32)((uint32)0U << 29U)
                            | (uint32)((uint32)0U << 30U)
                            | (uint32)((uint32)0U << 31U);
    
        vimREG->REQMASKSET3 = (uint32)((uint32)0U << 0U)
                            | (uint32)((uint32)0U << 1U)
                            | (uint32)((uint32)0U << 2U)
                            | (uint32)((uint32)0U << 3U)
                            | (uint32)((uint32)0U << 4U)
                            | (uint32)((uint32)0U << 5U)
                            | (uint32)((uint32)0U << 6U)
                            | (uint32)((uint32)0U << 7U)
                            | (uint32)((uint32)0U << 8U)
                            | (uint32)((uint32)0U << 9U)
                            | (uint32)((uint32)0U << 10U)
                            | (uint32)((uint32)0U << 11U)
                            | (uint32)((uint32)0U << 12U)
                            | (uint32)((uint32)0U << 13U)
                            | (uint32)((uint32)0U << 14U)
                            | (uint32)((uint32)0U << 15U)
                            | (uint32)((uint32)0U << 16U)
                            | (uint32)((uint32)0U << 17U)
                            | (uint32)((uint32)0U << 18U)
                            | (uint32)((uint32)0U << 19U)
                            | (uint32)((uint32)0U << 20U)
                            | (uint32)((uint32)0U << 21U)
                            | (uint32)((uint32)0U << 22U)
                            | (uint32)((uint32)0U << 23U)
                            | (uint32)((uint32)0U << 24U)
                            | (uint32)((uint32)0U << 25U)
                            | (uint32)((uint32)0U << 26U)
                            | (uint32)((uint32)0U << 27U)
                            | (uint32)((uint32)0U << 28U)
                            | (uint32)((uint32)0U << 29U)
                            | (uint32)((uint32)0U << 30U)
                            | (uint32)((uint32)0U << 31U);
    
        /* Set Capture event sources */
        vimREG->CAPEVT = ((uint32)((uint32)0U << 0U)
                         |(uint32)((uint32)0U << 16U));
    
    /* USER CODE BEGIN (2) */
    /* USER CODE END */
    }
    

    Another difference I've noticed is that my paragraph 29.2.4.1.2 is slicely different from yours:

    29.2.4.1.2 Receiving Data in Multi-Buffer Mode
    Multi-buffer mode is selected when the MBUF MODE bit in SCIGCR1 is set to 1. In this mode, SCI sets
    the RXRDY bit after receiving the programmed number of data in the receive buffer, the complete frame.
    The error condition detection logic is similar to the single-buffer mode, except that it monitors for the
    complete frame. Like single-buffer mode, you can use the polling, interrupt, or DMA method to read the
    data. The SCI clears the RXRDY bit after the new data in SCIRD has been read.

    I'm using TMS570LC43x 16/32-Bit RISC Flash Microcontroller - Technical Reference Manual" March 2018.

    Where's the issue?

    Thanks for help,

    Marco.

  • Hi Marco,

      I want to be sure if you are using the SCI/LIN module or just the SCI module. Please refer to the below 4 modules in the datasheet. The SCI3 and SCI4 will not have support for Multi-buffer mode. Only the LIN1 and LIN2 in their SCI mode can support Multi-buffer. 

    Please also refer to this below post for some clarify. 

    https://e2e.ti.com/support/microcontrollers/hercules/f/312/t/928837?tisearch=e2e-sitesearch&keymatch=multi%252520buffer%252520sci

    Marco Semenzato said:

    Another difference I've noticed is that my paragraph 29.2.4.1.2 is slicely different from yours:

    1
    2
    3
    4
    5
    6
    29.2.4.1.2 Receiving Data in Multi-Buffer Mode
    Multi-buffer mode is selected when the MBUF MODE bit in SCIGCR1 is set to 1. In this mode, SCI sets
    the RXRDY bit after receiving the programmed number of data in the receive buffer, the complete frame.
    The error condition detection logic is similar to the single-buffer mode, except that it monitors for the
    complete frame. Like single-buffer mode, you can use the polling, interrupt, or DMA method to read the
    data. The SCI clears the RXRDY bit after the new data in SCIRD has been read.

    I'm using TMS570LC43x 16/32-Bit RISC Flash Microcontroller - Technical Reference Manual" March 2018.

    Sorry, I was using a older release (SPNU56.pdf) of the TRM dated May 2014. Please use what you have which is the latest TRM (SPNU563A.pdf) dated March-2018.

  • Hi Charles,

    thanks for the answer.

    I verified the address of the register and seems ok:

    I checked the link provided by you, and the settings are the same (enable on GR1 + data format).

    Maybe there's an other setting at the CPU level? Maybe anything in VIM? I really don't know..

    /** @def sciREG1
    * @brief Register Frame Pointer
    *
    * This pointer is used by the SCI driver to access the sci1 module registers.
    */
    #define sciREG1 ((sciBASE_t *)0xFFF7E400U)

    P.s. Ok, no problem. I keep using my version of reference manual.

    Thanks for the replies and regards,

    Marco.

  • Hi,

      Can you please send me the complete CCS project? I would like to run your project.

  • Hi,

      I wrote a simple piece of code. If I don't enable multibuffer mode then I will get interrupt and receive each character correctly. However, as soon as I enable multibuffer mode then no interrupt is generated. Looks like there is some hardware issue. I need to check with my colleagues if they are aware of the issue or they know some software workaround. In the meantime, I will suggest you do with single buffer mode. 

    /* USER CODE BEGIN (0) */
    #include "HL_system.h"
    #include "HL_sci.h"

    /* USER CODE END */

    /* Include Files */

    #include "HL_sys_common.h"

    /* USER CODE BEGIN (1) */
    int UART_RX_RDY = 0;
    /* USER CODE END */

    /** @fn void main(void)
    * @brief Application main function
    * @note This function is empty by default.
    *
    * This function is called after startup.
    * The user can use this function to implement the application.
    */

    /* USER CODE BEGIN (2) */
    #define TSIZE1 8
    uint8 TEXT1[TSIZE1]= {0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88};
    uint8 pData[TSIZE1] = {0};

    /* USER CODE BEGIN (4) */
    void sciDisplayText(sciBASE_t *sci, uint8 *text,uint32 length)
    {
    int i;
    while(length--)
    {
    while ((sci->FLR & 0x4) == 4); /* wait until busy */
    sciSendByte(sci,*text++); /* send out text */
    for (i=0;i<=10000;i++);
    };
    }

    void sciNotification(sciBASE_t *sci, uint32 flags)
    {
    /* enter user code between the USER CODE BEGIN and USER CODE END. */
    /* USER CODE BEGIN (29) */
    UART_RX_RDY = 1;
    sciREG1->CLEARINT = SCI_RX_INT;
    }
    /* USER CODE END */

    int main(void)
    {
    /* USER CODE BEGIN (3) */
    /* Enable interrupts. */
    _enable_IRQ_interrupt_();

    sciInit();
    sciREG1->GCR1 |= ((uint32)1U << 16U
    | (uint32)((uint32)1U << 10U) ); // Loopback mode enabled for test, enable multibuffer mode,
    sciREG1->FORMAT |= (7U << 16U); // 8 characters to transfer before interrupt
    sciREG1->SETINT |= (1U << 17U); // Enable RX DMA
    sciEnableNotification(sciREG1, SCI_RX_INT);
    sciReceive(sciREG1, TSIZE1, pData);
    sciDisplayText(sciREG1,&TEXT1[0],TSIZE1); /* send text code 1 */
    while(UART_RX_RDY == 0U); /* Wait */
    UART_RX_RDY = 0;

    while (1);
    /* USER CODE END */

    return 0;
    }


    /* USER CODE BEGIN (4) */
    /* USER CODE END */

  • Hello,

    www.ti.com/.../spna213

    The example in this application note transmits data using SCI in multi-buffered mode. 

  • Hello, thanks for the example provided. I'll try to reproduce it in my firmware.

    Thanks,

    Marco.