• AVR Freaks

Hot!DMA to PMP interrupt handshaking not working

Author
Valin0126
Starting Member
  • Total Posts : 38
  • Reward points : 0
  • Joined: 2020/02/07 04:53:15
  • Location: 0
  • Status: offline
2020/10/19 06:59:28 (permalink)
0

DMA to PMP interrupt handshaking not working

PIC32MZ with an LCD on the PMP bus.  DMA to PMP to drive the LCD via the LCC.
 
I have it all working, but the pixel clock is running 4x too fast for the screen. 
 
If I reduce the peripheral clock for the PMP the screen looks like the DMA is over-running the PMP (lost pixels, the graphics are compressed horizontally).  The compression changes directly proportional to the divider (the slower the PMP clock, the more the graphics are compressed).
If I change the PMP wait settings the graphics again are skewed. 
My understanding is that the DMA should only write another pixel once the PMP write interrupt fires but that doesn't seem to be the case.
 
PMP init code:
    asm volatile("di");
    PMCONCLR = 0x8000;      // Turn PMP peripheral off before setting it up
    PMAEN = 0;              // Disable all address bits

    PMCONbits.WRSP = 0;     // Set Write Strobe polarity to active low
    PMCONbits.RDSP = 0;     // Set Read Strobe polarity to active low
    PMCONbits.PTRDEN = 1;   // Enable Read Strobe (RS)
    PMCONbits.PTWREN = 1;   // Enable Write Strobe (WR)
    PMCONbits.ADRMUX = 0;   // No MUXing please, all 16-bits on PMD<0:15>
    PMCONbits.SIDL = 0;     // Continue operation in idle mode
    PMCONbits.CSF = 00;     // PMCS2 enabled, PMCS1 is PMA14
    PMCONbits.ALP = 0;      // Set Address Latch Polarity bit active low
    PMCONbits.DUALBUF = 0;  // Disable Dual Buffer mode (use PMDIN and PMADDR registers)

    PMMODEbits.IRQM = 1;    // IRQ at the end of the Read/Write cycle
    PMMODEbits.MODE16 = 0;  // 16-bit mode
    PMMODEbits.MODE = 0b10; // Master mode 2
    PMMODEbits.WAITB = 0;   // Maximum wait / slowest speed 3
    PMMODEbits.WAITM = 0;  // Maximum wait / slowest speed 15
    PMMODEbits.WAITE = 0;   // Maximum wait / slowest speed 3
    PMMODEbits.INCM = 0b01;   // Do not automatically increment address when writing

    PMCONSET = 0x8000;      // Turn PMP peripheral on
    asm volatile("ei");
 
 
DMA init code:
    SYS_DMA_ChannelSetup(dmaHandle,
                        SYS_DMA_CHANNEL_OP_MODE_BASIC,
                        DMA_TRIGGER_SOURCE_NONE);
        
    // set the transfer parameters: source & destination address,
    // source & destination size, number of bytes per event
    SYS_DMA_ChannelTransferSet(dmaHandle,
        cntxt->layer.active->buffers[cntxt->layer.active->buffer_read_idx].pb.pixels,
        HBackPorch, // << PMP_DATA_LENGTH,
        (void *) &PMDIN,
        1,
        1);
    
    DCH2ECONbits.CHSIRQ = _PMP_VECTOR; // Move data on PMP interrupt
    DCH2ECONbits.CHAIRQ = _PMP_ERROR_VECTOR; // Abort on PMP error
    DCH2ECONbits.SIRQEN = 1; // Enable Start IRQ
    DCH2ECONbits.AIRQEN = 1; // Enable Abort IRQ
    
    IPC34bits.DMA2IP = 3; // Set DMA 2 interrupt priority to 3
    IPC34bits.DMA2IS = 1; // Set DMA 2 interrupt sub-priority to 1
    IFS4bits.PMPIF = 0; // Clear the PMP interrupt flag
    IFS4bits.DMA2IF = 0; // Clear the DMA channel 2 interrupt flag
    IEC4bits.DMA2IE = 1; // Enable the DMA 0 interrupt
    DCH2INTbits.CHBCIE = 1; // Enable the Channel Block Transer Complete (CHBC) Interrupt
#1

8 Replies Related Threads

    MisterHemi
    Super Member
    • Total Posts : 305
    • Reward points : 0
    • Joined: 2017/11/02 12:24:21
    • Location: Commerce, CA USA
    • Status: offline
    Re: DMA to PMP interrupt handshaking not working 2020/10/19 16:03:54 (permalink)
    0
    I'm not an expert and haven't used the PMP but it's not shown in the code you posted but i'd think perhaps you have or need to have an Interrupt Service Routine (ISR) for the PMP and DMA2, then within those ISRs you'd have some type of flow control.
     
    For example:

    #include <sys/attribs.h> 
     
    // x = IPL#
    void __attribute__((interrupt(IPLxSRS), at_vector(_PMP_VECTOR), no_fpu, nomips16)) PMP_ISR(void){
    // Your PMP ISR code goes here - maybe some type of flow control
    }
     
    void __attribute__((interrupt(IPLxSRS), at_vector(_PMP_ERROR_VECTOR), no_fpu, nomips16)) PMP_ERROR(void){
    // Your PMP Error ISR code goes here - abort on error, ignore, or whatever
    }
     
    void __attribute__((interrupt(IPL3SRS), at_vector(_DMA2_VECTOR), no_fpu, nomips16)) PMP_ERROR(void){
    // Your DMA2 ISR code goes here - some type of notification upon DMA completion
    }

     
     
     

    My configuration:
    MacBook Pro (Retina, 15-inch, Mid 2015) with MacOS Mojave (10.14.6) and MPLAB X IDE v5.30
     
    Curiosity PIC32MZ EF 1 & 2, PIC24F Curiosity, XPRESS EVAL BOARD (PIC16F18855), SAMA5D3 Xplained and various custom boards.
    #2
    Valin0126
    Starting Member
    • Total Posts : 38
    • Reward points : 0
    • Joined: 2020/02/07 04:53:15
    • Location: 0
    • Status: offline
    Re: DMA to PMP interrupt handshaking not working 2020/10/20 03:27:30 (permalink)
    0
    Thanks, there is already a DMA ISR which handles the data to the DMA.  Though I do not have the PMP ISRs which I suspect may be the issue.  Since the PMP ISR flag isn't being cleared the DMA will just keep sending data.
     
    However, when I attempt to implement the PMP ISRs MPLAB is telling me the INT_SOURCE_PMP and INT_SOURCE_PMP_ERROR enums are undeclared even though they're in the INT_SOURCE enumeration.  The ISRs are in the same file as the DMA ISR and it recognizes the INT_SOURCE_DMA_0 so not sure why it doesn't recognize the PMP Sources.  
     
    Edit: I got around this by clearing the flag via the system register and it didn't solve the problem.  Any attempt to slow down the PMP results in dropped pixels between the DMA and PMP
    post edited by Valin0126 - 2020/10/20 03:39:54
    #3
    MisterHemi
    Super Member
    • Total Posts : 305
    • Reward points : 0
    • Joined: 2017/11/02 12:24:21
    • Location: Commerce, CA USA
    • Status: offline
    Re: DMA to PMP interrupt handshaking not working 2020/10/20 05:05:21 (permalink)
    4 (1)
    According to the PIC32MZ data sheet they should be:
    _PMP_VECTOR
    _PMP_ERROR_VECTOR

    My configuration:
    MacBook Pro (Retina, 15-inch, Mid 2015) with MacOS Mojave (10.14.6) and MPLAB X IDE v5.30
     
    Curiosity PIC32MZ EF 1 & 2, PIC24F Curiosity, XPRESS EVAL BOARD (PIC16F18855), SAMA5D3 Xplained and various custom boards.
    #4
    Valin0126
    Starting Member
    • Total Posts : 38
    • Reward points : 0
    • Joined: 2020/02/07 04:53:15
    • Location: 0
    • Status: offline
    Re: DMA to PMP interrupt handshaking not working 2020/10/20 05:12:03 (permalink)
    0
    That's for the vector to create the ISR.  To clear the interrupt flag there is a call which takes an INT_SOURCE, for example:
    SYS_INT_SourceStatusClear(INT_SOURCE_DMA_0)
     
    Per the INT_SOURCE documentation found here:
    https://microchip-mplab-harmony.github.io/csp/frames.html?frmname=topic&frmfile=02288.html
     
    They are INT_SOURCE_PMP and INT_SOURCE_PMP_ERROR
     
    I found a bug in the LCC code that was causing the DMA to spam the PMP, which reduced the PMP output to 5Mhz (goal is 6Mhz) and the LCC is also running fast enough to make the 60hz refresh rate (sending a horizontal row every 100 uSec (needs to be at least 70 uSec or less).  So working through that.
    #5
    Valin0126
    Starting Member
    • Total Posts : 38
    • Reward points : 0
    • Joined: 2020/02/07 04:53:15
    • Location: 0
    • Status: offline
    Re: DMA to PMP interrupt handshaking not working 2020/10/20 05:15:59 (permalink)
    0
    Meant to say NOT running fast enough but the forum won't let me edit it right now.
    #6
    MisterHemi
    Super Member
    • Total Posts : 305
    • Reward points : 0
    • Joined: 2017/11/02 12:24:21
    • Location: Commerce, CA USA
    • Status: offline
    Re: DMA to PMP interrupt handshaking not working 2020/10/20 06:18:31 (permalink)
    0
    Valin0126
    Meant to say NOT running fast enough but the forum won't let me edit it right now.




    Good! Glad you found it.
     

    My configuration:
    MacBook Pro (Retina, 15-inch, Mid 2015) with MacOS Mojave (10.14.6) and MPLAB X IDE v5.30
     
    Curiosity PIC32MZ EF 1 & 2, PIC24F Curiosity, XPRESS EVAL BOARD (PIC16F18855), SAMA5D3 Xplained and various custom boards.
    #7
    Valin0126
    Starting Member
    • Total Posts : 38
    • Reward points : 0
    • Joined: 2020/02/07 04:53:15
    • Location: 0
    • Status: offline
    Re: DMA to PMP interrupt handshaking not working 2020/10/20 06:43:56 (permalink)
    0
    Think you misunderstood my answer.  Also found several examples where the DMA cell size was set to the number of pixels, which is the "bug" I thought I found.  So back to the original issue of DMA->PMP data rates and the best approach to getting the correct result.
    #8
    MisterHemi
    Super Member
    • Total Posts : 305
    • Reward points : 0
    • Joined: 2017/11/02 12:24:21
    • Location: Commerce, CA USA
    • Status: offline
    Re: DMA to PMP interrupt handshaking not working 2020/10/20 10:38:02 (permalink)
    0
    Ok I understand now. The cell size should be the number of bytes rather than pixels. 
     
    I'm not sure how you could get the correct data rate unless you have it somehow start a transfer, of a known fixed size, at a regular interval. Hmmmm.
     
    2 bytes per pixel (16 bits) x Pixels per screen draw x 60 times per second
     
    What cell size are you using and how are you polling or triggering the DMA transfer? How frequently?

    My configuration:
    MacBook Pro (Retina, 15-inch, Mid 2015) with MacOS Mojave (10.14.6) and MPLAB X IDE v5.30
     
    Curiosity PIC32MZ EF 1 & 2, PIC24F Curiosity, XPRESS EVAL BOARD (PIC16F18855), SAMA5D3 Xplained and various custom boards.
    #9
    Jump to:
    © 2020 APG vNext Commercial Version 4.5