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.

RM48L950 LIN Rx DMA : bytes received at wrong address and no DMA interrupt

Other Parts Discussed in Thread: RM48L950, HALCOGEN

Hi All

I try to set up an UART receiver with DMA using the LIN peripheral on RM48L950

I am already able
> to transmit bytes using DMA channel 0 and BTCA interrupt
> to receive bytes using the UART interrupt without DMA support (which works but does 1 byte per interrupt)

the point is about switching to DMA for the receiver part :

- I set a 1st DMA channel  on LIN TX and set a transfer complete interrupt after 8 bytes
- I set a 2nd DMA channel on LIN RX and set an interrupt after 8 received bytes

the test case is :
- the LIN TX is plugged (externally) to the LIN RX
- LIN TX sends 8 bytes at a time with the DMA channel
- the transmit part works (the 8 sent bytes sequence is OK, the transfer complete interrupt is OK)
- then I got no DMA receive interrupt (BTCA interrupt) although the received bytes are in memory

except the bytes are transferred at address RX_DATA1+8 (not RX_DATA1)

no matter how many bytes I transmit say if I transmit 5 bytes, the target address is still target address+8

I have checked the registers - without success.

I have enabled all the DMA interrupts on channel 1, still no interrupt

here is the source code for reference.

we are *not* using the multi buffer mode perhaps it will be a good idea.

    uint8 TX_DATA1[8] = {8, 2, 4, 3, 1, 5, 6, 9};    /* transmit buffer */
    uint8 RX_DATA1[8] = {0, 0, 0, 0, 0, 0, 0, 0};    /* receive  buffer */
    uint32 l_intDecl = 0;

    dmaEnable();

    linInit();
    
    // ============== UART CONFIGURATION ============================
    l_intDecl = ( (1U << 26U) | // FE ERROR
                  (1U << 25U) | // OE ERROR
                  (1U << 24U) | // PARITY ERROR
                  (1U << 9U)  | // SET RX INT LVL
                  (1U << 8U)    // SET TX INT LVL
                 );

    scilinREG->SETINTLVL = l_intDecl;  

    scilinREG->GCR1 &= ~( (1U << 7U) );
    // Baudrate
    UDWord32 Prescaler = 0;
    UDWord32 FreqHz = privGetGCLKFreqHz( systemREG1, CPU_CLK_MHZ*1000000);
    Prescaler = privGetVclkDiv( systemREG1, VCLK_PRESCALER);
    FreqHz = FreqHz/Prescaler;

    sciSetBaudrate( scilinREG, 9600, FreqHz ); // 9600
    // Stop Bits
    scilinREG->GCR1 &= ~(  (1U << 4U) ); // 1_Bit
    // Parity
    scilinREG->GCR1 &= ~( (1U << 2U) );  // None
    // swnRst
    scilinREG->GCR1 |= ( (1U << 7U) );
    // RXRDY
    scilinREG->FLR = (1U << 9U);
    // ============== UART CONFIGURATION END ============================

    // ============== VIM ============================
    // DMA
    vimEnableInterrupt( uint32( 39U ), boolean( SYS_IRQ ) );  // First half of block complete
    vimEnableInterrupt( uint32( 40U ), boolean( SYS_IRQ ) );  // Block transfer complete
    vimEnableInterrupt( uint32( 33U ), boolean( SYS_IRQ ) );  // Frame transfer complete
    vimEnableInterrupt( uint32( 34U ), boolean( SYS_IRQ ) );  //  Last frame transfer started

    /* ========= RX DMA =========== */
    dmaReqAssign(DMA_CH1, 28U);
    dmaSetChEnable(DMA_CH1, DMA_HW);
    dmaSetPriority( DMA_CH1, LOWPRIORITY );
    dmaEnableInterrupt(DMA_CH1, BTC);
    dmaEnableInterrupt(DMA_CH1, HBC);
    dmaEnableInterrupt(DMA_CH1, FTC);
    dmaEnableInterrupt(DMA_CH1, LFS);
    dmaConfigCtrlRxPacket((uint32)(&(scilinREG->RD)),
                          (uint32)(&RX_DATA1[0]),
                          8);
    dmaSetCtrlPacket(DMA_CH1,g_dmaCTRLPKT);
    dmaREG->GCHIENAS |= 1<< DMA_CH1;
    /* ========= RX DMA END =========== */

    /* Enable RX Dma */
    scilinREG->SETINT = (1U << 17U) | // UART_SETINT_RXDMA
                        (1U << 26U) | // UART_SETINT_FE
                        (1U << 25U) | // UART_SETINT_OE
                        (1U << 24U) ; //UART_SETINT_PE


    /* =========== TX DMA =========== */
    dmaReqAssign(DMA_CH0, 29U);
     /* - setting the dma channel to trigger on h/w request */
    dmaSetChEnable(DMA_CH0, DMA_HW);
    dmaSetPriority( DMA_CH0, LOWPRIORITY );
    /* Enable Interrupt after reception of data */
    dmaEnableInterrupt(DMA_CH0, BTC);
    /* - Populate dma control packets structure */
    dmaConfigCtrlTxPacket((uint32)(&TX_DATA1[0]),
                         (uint32)(&(scilinREG->TD)),
                          8);
    /* - setting dma control packets for transmit */
    dmaSetCtrlPacket(DMA_CH0,g_dmaCTRLPKT);
    // enable the channel global interrupt
    dmaREG->GCHIENAS |= 1<< DMA_CH0;
    /* =========== TX DMA END =========== */


    /* ========= */
    scilinREG->FLR = (1U << 9U) |   // UART_FLR_RXRDY
                    ((1U << 26U)) | // UART_FLR_FE
                    ((1U << 25U)) | // UART_FLR_OE
                    ((1U << 24U)) | // UART_FLR_PE
                      0;

     /* Enable TX DMA */
     scilinREG->SETINT |= ( (1U << 16U) );

    /* Wait for the DMA interrupt ISR */
    while(1);
    
    
    void dmaConfigCtrlTxPacket(uint32 sadd,uint32 dadd,uint32 dsize)
{
    g_dmaCTRLPKT.SADD      = sadd;              /* source address             */
    g_dmaCTRLPKT.DADD      = dadd;              /* destination  address       */
    g_dmaCTRLPKT.CHCTRL    = DMA_CH0;           /* channel control            */
    g_dmaCTRLPKT.FRCNT     = dsize;             /* frame count                */
    g_dmaCTRLPKT.ELCNT     = 1;                 /* element count              */
    g_dmaCTRLPKT.ELDOFFSET = 0;                 /* element destination offset */
    g_dmaCTRLPKT.ELSOFFSET = 0;                 /* element source offset */
    g_dmaCTRLPKT.FRDOFFSET = 0;                 /* frame destination offset   */
    g_dmaCTRLPKT.FRSOFFSET = 0;                 /* frame source offset   */
    g_dmaCTRLPKT.PORTASGN  = 4;                 /* port b                     */
    g_dmaCTRLPKT.RDSIZE    = ACCESS_8_BIT;     /* read size                  */
    g_dmaCTRLPKT.WRSIZE    = ACCESS_8_BIT;     /* write size                 */
    g_dmaCTRLPKT.TTYPE     = FRAME_TRANSFER ;   /* transfer type              */
    g_dmaCTRLPKT.ADDMODERD = ADDR_INC1;         /* address mode read          */
    g_dmaCTRLPKT.ADDMODEWR = ADDR_FIXED;        /* address mode write         */
    g_dmaCTRLPKT.AUTOINIT  = AUTOINIT_OFF;      /* autoinit                   */
}

void dmaConfigCtrlRxPacket(uint32 sadd,uint32 dadd,uint32 dsize)
{
    g_dmaCTRLPKT.SADD      = sadd;              /* source address             */
    g_dmaCTRLPKT.DADD      = dadd;              /* destination  address       */
    g_dmaCTRLPKT.CHCTRL    = DMA_CH1;           /* channel control            */
    g_dmaCTRLPKT.FRCNT     = dsize;             /* frame count                */
    g_dmaCTRLPKT.ELCNT     = 1;                 /* element count              */
    g_dmaCTRLPKT.ELDOFFSET = 0;                 /* element destination offset */
    g_dmaCTRLPKT.ELSOFFSET = 0;                 /* element source offset */
    g_dmaCTRLPKT.FRDOFFSET = 0;                 /* frame destination offset   */
    g_dmaCTRLPKT.FRSOFFSET = 0;                 /* frame source offset   */
    g_dmaCTRLPKT.PORTASGN  = 4;                 /* port b                     */
    g_dmaCTRLPKT.RDSIZE    = ACCESS_8_BIT;     /* read size                  */
    g_dmaCTRLPKT.WRSIZE    = ACCESS_8_BIT;     /* write size                 */
    g_dmaCTRLPKT.TTYPE     = FRAME_TRANSFER ;   /* transfer type              */
    g_dmaCTRLPKT.ADDMODERD = ADDR_FIXED;        /* address mode read          */
    g_dmaCTRLPKT.ADDMODEWR = ADDR_INC1;         /* address mode write         */
    g_dmaCTRLPKT.AUTOINIT  = AUTOINIT_OFF;      /* autoinit                   */

}