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