• AVR Freaks

Hot!Pattern matching mode of DMA

Author
BHUSHAN
Starting Member
  • Total Posts : 59
  • Reward points : 0
  • Joined: 2019/02/04 23:17:18
  • Location: 0
  • Status: offline
2019/06/11 04:21:42 (permalink)
0

Pattern matching mode of DMA

Hi!
I am using PIC32MX795F512L for my project. In this project I have enabled DMA channel 0 with source as U2RXREG and destination as a buffer in RAM. On receiving of character '9' a pattern match event is to happen. On pattern match the the transfer from UART receive register to RAM buffer will be terminated. Finally to check the correct DMA operation I am just transmitting bytes of RAM buffer through TX line of UART2. Following is my code:-
 
#include<proc/p32mx795f512l.h> //header for PIC32MX795F512L as provided by C32 compiler
/* Fosc = 80MHz and PBClk = 80MHz*/
#pragma config FPLLMUL =MUL_20            
#pragma config FPLLIDIV = DIV_2
#pragma config FPLLODIV = DIV_1, FWDTEN = OFF         
#pragma config POSCMOD = XT, FNOSC = PRIPLL
#pragma config FPBDIV = DIV_1


typedef unsigned long _paddr_t; /* a physical address */
typedef unsigned long _vaddr_t; /* a virtual address */

/*
 * Translate a kernel virtual address in KSEG0 or KSEG1 to a real
 * physical address
 */
#define KVAd_TO_PAd(v)      ((_paddr_t)(v) & 0x1fffffff)

volatile unsigned char Uart_Rx, DMABlockTransferComplete_flag=0;

__attribute__(( vector(_UART_2_VECTOR), interrupt))
void UART2_isr(){
 unsigned char x;
//Uart_Rx = U2RXREG;
 IFS1bits.U2RXIF=0;
}

__attribute__(( vector(_DMA_0_VECTOR), interrupt))
void DMA0_isr(){
  LATB = 0xff ; //just to check whether this isr is getting evoked or not
  DMABlockTransferComplete_flag = 1;
  IFS1bits.DMA0IF = 0;
}


void UART_init()
{
  U2MODEbits.ON = 0;//initially turn-off the module
  U2BRG = 88;//56kbps at 80MHz
  U2MODEbits.SIDL = 0;//Continue operation in ideal mode   U2MODEbits.IREN = 0;//disable IrDA
  U2MODEbits.UEN0 = 0; //UxTX and UxRX pins are enabled
  U2MODEbits.UEN1 = 0;
  U2MODEbits.WAKE = 0;//Disable Wake-up on Start bit Detect During Sleep Mode bit
  U2MODEbits.LPBACK = 0;//Disable loop back
  U2MODEbits.ABAUD = 0;//Disable auto-baud
  U2MODEbits.RXINV = 0;//UxRX Idle state is '1'
  U2MODEbits.BRGH = 0;//Standard Speed mode ? 16x baud clock enabled
  U2MODEbits.PDSEL0 = 0;//8-bit data, no parity
  U2MODEbits.PDSEL1 = 0;
  U2MODEbits.STSEL = 0;//1 Stop bit
  U2STAbits.ADM_EN = 0;//Automatic Address Detect mode is disabled
  U2STAbits.UTXINV = 0;//UxTX Idle state is ?1?
  U2STAbits.UTXBRK = 0;//Break transmission is disabled or completed
  U2STAbits.UTXEN = 1;//UARTx transmitter is enabled
  U2STAbits.ADDEN = 0;//Address Detect mode is disabled
  U2STAbits.URXEN = 1;//UARTx receiver is enabled
  INTCONbits.MVEC = 1;
  asm volatile("di"); //disable all interrupts to set new ones
  U2STAbits.URXISEL = 0;//Interrupt flag bit is asserted while receive buffer is not empty (has at least 1 data character)
  U2STAbits.URXISEL1 = 0;
 U2STAbits.UTXISEL = 1;//Interrupt generated and asserted while the transmit buffer contains at least one empty space
  IPC8bits.U2IP = 4; //Give priority level
  IPC8bits.U2IS = 0;
  IFS1bits.U2RXIF = 0;//clear interrupt flag
  IFS1bits.U2TXIF = 0;
  IEC1bits.U2RXIE = 1;//Enable UART2 RX interrupt 
}

void Uart_Tx(unsigned char dat)
{
    while(U2STAbits.UTXBF);
    U2TXREG = dat;
}

void main(){
unsigned char ramBuff[20] ={0},count;
 UART_init();
 TRISB = 0 ;
IEC1CLR=0x00010000; // disable DMA channel 0 interrupts
IFS1CLR=0x00010000; // clear any existing DMA channel 0 interrupt flag
DMACONSET=0x00008000; // enable the DMA controller
DCH0CON=0x03; // channe0 off, priority 3, no chaining
DCH0ECON=(38 <<8)| 0x30; // start irq is UART2 RX, pattern match enabled
DCH0DAT= '9' ; // pattern value, character '9'
DCH0SSA=KVAd_TO_PAd(&U2RXREG); // transfer source physical address
DCH0DSA=KVAd_TO_PAd(ramBuff); // transfer destination physical address
DCH0SSIZ=1; // source size is 1 byte
DCH0DSIZ=20; // destination size at most 20 bytes
DCH0CSIZ=1; // one byte per UART transfer request

DCH0INTCLR=0x00ff00ff; // clear existing events, disable all interrupts
DCH0INTSET=0x00090000; // enable Block Complete and error interrupts
IPC9CLR=0x0000001f; // clear the DMA channel 0 priority and sub-priority
IPC9bits.DMA0IP = 5; //Give priority level
IPC9bits.DMA0IS = 0;
IEC1bits.DMA0IE = 1; // enable DMA channel 0 interrupt
asm volatile("ei");
DCH0CONSET=0x80; // turn channel on
 U2MODEbits.ON = 1;//turn UART2 ON
while(1)
{

if(DMABlockTransferComplete_flag == 1) //when DMA has completed its task
{
for(count=0;count<10;count++)
Uart_Tx(ramBuff[count]); // check for validity of stored data in buffer
}
}
}
 
My DMA0 isr is not getting fired. I am unable to resolve this issue after giving the whole day to it. Need help. Thanks in advance.
#1

3 Replies Related Threads

    BHUSHAN
    Starting Member
    • Total Posts : 59
    • Reward points : 0
    • Joined: 2019/02/04 23:17:18
    • Location: 0
    • Status: offline
    Re: Pattern matching mode of DMA 2019/06/11 21:41:18 (permalink)
    0
    I think problem is with configuration. I will try solving this issue by myself and will notify the issue.
    Thanks to all. Keep rocking grin: grin
    #2
    BHUSHAN
    Starting Member
    • Total Posts : 59
    • Reward points : 0
    • Joined: 2019/02/04 23:17:18
    • Location: 0
    • Status: offline
    Re: Pattern matching mode of DMA 2019/06/12 23:26:25 (permalink)
    0
    Hi PALs!
    I trimmed my previous code  (keep configuration bit settings same as of before). In this code I have initialized DMA interrupt for 1 cell transfer event(DMA cell transfer will take place when UART2 RX interrupt will raise the flag according to settings of U2STAbits.URXISEL). Still ISR of DMA is not getting evoked. Where am I wrong? Is there any conceptual mistake or something else? Kindly look at my code and give suggestions.
     
    typedef unsigned long _paddr_t; /* a physical address */
    typedef unsigned long _vaddr_t; /* a virtual address */

    /*
     * Translate a kernel virtual address in KSEG0 or KSEG1 to a real
     * physical address and back.
     */
    #define KVAd_TO_PAd(v)      ((_paddr_t)(v) & 0x1fffffff)
    #define PAd_TO_KVAd0(pa)    ((void *) ((pa) | 0x80000000))
    #define PAd_TO_KVAd1(pa)    ((void *) ((pa) | 0xa0000000))


     __attribute__(( vector(_DMA_0_VECTOR), interrupt))
    void DMA0_isr(){
         LATB = 0x71 ; // I just want to check I am entering this ISR on cell transfer or not
         IFS1bits.DMA0IF = 0;
    }


    void UART_init()
    {
      U2MODEbits.ON = 0;//initially turn-off the module
      U2BRG = 88;//56kbps at 80MHz
      U2MODEbits.SIDL = 0;//Continue operation in ideal mode   U2MODEbits.IREN = 0;//disable IrDA
      U2MODEbits.UEN0 = 0; //UxTX and UxRX pins are enabled
      U2MODEbits.UEN1 = 0;
      U2MODEbits.WAKE = 0;//Disable Wake-up on Start bit Detect During Sleep Mode bit
      U2MODEbits.LPBACK = 0;//Disable loop back
      U2MODEbits.ABAUD = 0;//Disable auto-baud
      U2MODEbits.RXINV = 0;//UxRX Idle state is ?1?
      U2MODEbits.BRGH = 0;//Standard Speed mode ? 16x baud clock enabled
      U2MODEbits.PDSEL0 = 0;//8-bit data, no parity
      U2MODEbits.PDSEL1 = 0;
      U2MODEbits.STSEL = 0;//1 Stop bit
      U2STAbits.ADM_EN = 0;//Automatic Address Detect mode is disabled
      U2STAbits.UTXINV = 0;//UxTX Idle state is ?1?
      U2STAbits.UTXBRK = 0;//Break transmission is disabled or completed
      U2STAbits.UTXEN = 1;//UARTx transmitter is enabled
      U2STAbits.ADDEN = 0;//Address Detect mode is disabled
      U2STAbits.URXEN = 1;//UARTx receiver is enabled
      INTCONbits.MVEC = 1;
      U2STAbits.URXISEL = 0;//Interrupt flag bit is asserted while receive buffer is not empty (has at least 1 data //character) that is whenever there will be data in receive buffer UART will raise a flag and DMA will initiate a //transfer
       U2MODEbits.ON = 1;
    }

    void main(){
    unsigned char ramBuff[20] ={0};
    unsigned char count;
     UART_init();
     TRISB = 0 ;
     LATB = 0x00 ;
    IEC1CLR=0x00010000; // disable DMA channel 0 interrupts
    IFS1CLR=0x00010000; // clear any existing DMA channel 0 interrupt flag
    DMACONSET=0x00008000; // enable the DMA controller
    DCH0CON=0x03; // channe0 off, priority 3, no chaining
    DCH0ECON=(38 <<8)| 0x30; // start irq is UART2 RX, pattern match enabled
    DCH0DAT= '9' ; // pattern value, character '9'
    DCH0SSA=KVAd_TO_PAd(&U2RXREG); // transfer source physical address
    DCH0DSA=KVAd_TO_PAd(ramBuff); // transfer destination physical address
    DCH0SSIZ=1; // source size is 1 byte
    DCH0DSIZ=20; // destination size at most 20 bytes
    DCH0CSIZ=1; // one byte per UART transfer request
    DCH0INTCLR=0x00ff00ff; // clear existing events, disable all interrupts
    DCH0INTSET=0x00050000; // enable cell transfer and error interrupts
    IPC9CLR=0x0000001f; // clear the DMA channel 0 priority and sub-priority
    IPC9bits.DMA0IP = 7; //Give priority level
    IPC9bits.DMA0IS = 0;
    IEC1bits.DMA0IE = 1; // enable DMA channel 0 interrupt
    asm volatile("ei");//enable interrupts
    DCH0CONSET=0x80; // turn channel on
    for(count=0;count<250;count++);//random delay
    while(1)
    {
     for(count=0;count<250;count++);//keeping looping here.
    }
    }
    #3
    BHUSHAN
    Starting Member
    • Total Posts : 59
    • Reward points : 0
    • Joined: 2019/02/04 23:17:18
    • Location: 0
    • Status: offline
    Re: Pattern matching mode of DMA 2019/06/20 05:15:11 (permalink)
    0
    Change only 1 instruction to make the code run.
    DCH0ECON=(42 <<8)| 0x30; //in datasheet the Interrupt number of UART TX interrupt is wrong
    #4
    Jump to:
    © 2019 APG vNext Commercial Version 4.5