I'm trying to implement Uart Rx via DMA.
I don't understand very well the science behind that but I need DMA on Uart Rx.
I read example for Microchip but I don't understand the way they allocate buffer to DMA.
I have this simple code that doesn't work :
Code: Select all
//******************************************************************************
// Allocate one buffer for DMA transfers
//*****************************************************************************/
unsigned int Uart1_Rx_Buffer[25];
/*******************************************************************************
* Function InitMCU()
* ------------------------------------------------------------------------------
* Overview: Function Initialize controller
* Input: Nothing
* Output: Nothing
*******************************************************************************/
void InitMCU()
{
ANSELB = 0b0000000000000000;
ANSELC = 0b0000000000000000;
ANSELD = 0b0000000000000000;
ANSELE = 0b0000000000000000;
ANSELG = 0b0000000000000000;
ODCD4_bit = 1;
CNPUD4_bit=1;
//PLLFBD = 74; // M=76 = 140Mhz
PLLFBD = 41; // M=43 = 80 Mhz
CLKDIVbits.PLLPOST = 0; // N1=2
CLKDIVbits.PLLPRE = 0; // N2=2
OSCTUN = 0; // Tune FRC oscillator, if FRC is used
RCONbits.SWDTEN = 0;
while (OSCCONbits.NOSC != 0b001); // Wait for Clock switch to occur
while (OSCCONbits.LOCK != 1) {}; // Wait for PLL to lock
U1STAbits.URXISEL = 0;
INTCON1bits.NSTDIS = 1;
IFS0bits.U1RXIF = 0;
//IEC0bits.U1RXIE = 1;
//IPC2bits.U1RXIP = 7;
UART1_Init_Advanced(100000,
_UART_8BIT_EVENPARITY,
_UART_TWO_STOPBITS,
_UART_HI_SPEED);
U1MODEbits.URXINV=1;
Unlock_IOLOCK();
PPS_Mapping( 97, _INPUT, _U1RX );
PPS_Mapping(68, _INPUT , _INT1 );
//Lock_IOLOCK();
delay_ms(100);
DEBUG_Direction = OUTPUT;
DEBUG = 0;
OSCILLO_Direction = OUTPUT;
OSCILLO = 0;
LancPin_Direction = INPUT;
}
void cfgDma1UartRx()
{
//******************************************************************************
// Associate DMA Channel 1 with UART Rx
//*****************************************************************************/
DMA1REQ = 0x000B; // Select UART1 Receiver
DMA1PAD = &U1RXREG;
DMA1CONbits.AMODE = 0;
DMA1CONbits.MODE = 1; //One-Shot, Ping-Pong modes are disabled
DMA1CONbits.DIR = 0;
DMA1CONbits.SIZE = 1;
DMA1CNT = 24; // 25 DMA requests
DMA1STAL = &Uart1_Rx_Buffer;
DMA1STAH = &Uart1_Rx_Buffer;
//******************************************************************************
// Enable DMA Interrupts
//*****************************************************************************/
IFS0bits.DMA1IF = 0; // Clear DMA interrupt
IEC0bits.DMA1IE = 1; // Enable DMA interrupt
//******************************************************************************
// Enable DMA Channel 1 to receive UART data
//*****************************************************************************/
DMA1CONbits.CHEN = 1; // Enable DMA Channel
}
void DMA1_Interrupt() iv IVT_ADDR_DMA1INTERRUPT ics ICS_AUTO
{
DEBUG = 1;
delay_ms(2);
IFS0bits.DMA1IF = 0; // Clear the DMA1 Interrupt Flag
}
void main()
{
InitMCU();
cfgDma1UartRx();
INTCON2bits.GIE = 1; // global interrupt enable
while(1)
{
if(U1STA.OERR == 1) // Must clear the overrun error to keep UART receiving
{
U1STA.OERR = 0;
continue;
}
if(U1STAbits.FERR == 1)
{
U1STA.FERR = 0;
continue;
}
DEBUG = 0;
}
}
Is it possible to have some help ?
How can I configure this to have a working setup ?
Thank you for your help