• AVR Freaks

Hot!Can I speed up simple capture loop ?

Page: 12 > Showing page 1 of 2
Author
nigelwright7557
Super Member
  • Total Posts : 284
  • Reward points : 0
  • Joined: 2006/11/06 08:15:51
  • Location: 0
  • Status: offline
2019/07/10 17:42:56 (permalink)
0

Can I speed up simple capture loop ?

I am clocking in data from an external a2d.
I clock high then low the read data.
However I am a bit disappointed with maximum speed which is 5MHz.
Is there anything I can do to speed it up ?
PIC32MZ1024EFM running at 200MHz.
 

                    for (fastptr=0;fastptr<bufferlength;fastptr++)
                    {
clock=1;
clock=0;
                        buffer[fastptr]=PORTB;
                    }

#1

22 Replies Related Threads

    ric
    Super Member
    • Total Posts : 23609
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: Can I speed up simple capture loop ? 2019/07/10 17:45:54 (permalink)
    0
    What is "clock" ?
    (I'm assuming it's some sort of #define )
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #2
    NKurzman
    A Guy on the Net
    • Total Posts : 17723
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: offline
    Re: Can I speed up simple capture loop ? 2019/07/10 18:02:39 (permalink)
    0
    Why didn’t you use the PMP or EBI and DMA?

    You are getting 5Mhz. What do you need?
    #3
    nigelwright7557
    Super Member
    • Total Posts : 284
    • Reward points : 0
    • Joined: 2006/11/06 08:15:51
    • Location: 0
    • Status: offline
    Re: Can I speed up simple capture loop ? 2019/07/10 18:25:20 (permalink)
    0
    NKurzman
    Why didn’t you use the PMP or EBI and DMA?

    You are getting 5Mhz. What do you need?



    I cant use DMA because I need to clock out the data of a a2d and in via an I/o port..
    I would like 20MHz but I suspect I am asking too much.
     
    I found "LATGINV 2" works quite a bit faster than setting the I/o pin i.e. clock=1;
    That has bumped me up to 8MHz but I would still like more.
     
    #4
    ric
    Super Member
    • Total Posts : 23609
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: Can I speed up simple capture loop ? 2019/07/10 18:32:44 (permalink)
    5 (2)
    At a guess, if the hidden defines are updated, something like this would be quicker
        unsigned int * ptr = buffer;    //point at start of buffer
        fastptr = bufferlength;    // item count
        do
        {
            clock_high;
            clock_low;
            *ptr++ = PORTB;
        } while (--fastptr);

     
    Of course, I have had to guess how "buffer", "bufferlength", and "clock" are defined.
    These are all details that should have been revealed in your initial question.
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #5
    NKurzman
    A Guy on the Net
    • Total Posts : 17723
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: offline
    Re: Can I speed up simple capture loop ? 2019/07/10 18:39:48 (permalink)
    0
    You NEED?  Because the Board is already layed out?
     
    LATGINV 2" works quite a bit faster? Faster than  and  LATGCLR 2? 
     
    20 Mhz assumes 10 instructions per loop.  In the Free compiler I assume?
     
    Option 1 is ASM.
     
    But you can try something like:
     
    fastptr = 0;pointer = buffer; 
    do
    {
       LATGSET = 2;
       LATGCLR = 2;
       *pointer++  = PORTB; 
    }
     
    while(fastptr++ < BUFFER_LENGTH); // Use a Constant
    post edited by NKurzman - 2019/07/10 18:41:06
    #6
    NKurzman
    A Guy on the Net
    • Total Posts : 17723
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: offline
    Re: Can I speed up simple capture loop ? 2019/07/10 18:42:04 (permalink)
    0
    ric in Faster and a little better than me.
    #7
    ric
    Super Member
    • Total Posts : 23609
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: Can I speed up simple capture loop ? 2019/07/10 18:44:21 (permalink)
    0
    Almost the same as mine Neil, although I suspect counting down to zero may be fractionally faster.
    (Can't be sure, I'm not that familiar with PIC32 assembler)
    Nigel, whenever you are chasing ultimate speed, examine the assembly code output by the compiler.
    That will very quickly show you what C constructs are costing you in time.
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #8
    nigelwright7557
    Super Member
    • Total Posts : 284
    • Reward points : 0
    • Joined: 2006/11/06 08:15:51
    • Location: 0
    • Status: offline
    Re: Can I speed up simple capture loop ? 2019/07/10 19:07:28 (permalink)
    0
    Using the pointer instead of buffer[fastptr]=PORTB makes it a bit faster.
    I am now at 10MHz.
    Many thanks for all the help.
     

         unsigned short *ptr;
                there:
             
                ptr=scopebuffer;
               
                fastptr=scopebufferlength;
               
                do
                {
                    LATGINV = setbit8; //fast setting bit 
                    LATGINV = setbit8; //fast 
      
      *ptr++ = PORTB;
      } while (--fastptr);
      goto there;
     
    post edited by nigelwright7557 - 2019/07/10 19:28:24
    #9
    NorthGuy
    Super Member
    • Total Posts : 5592
    • Reward points : 0
    • Joined: 2014/02/23 14:23:23
    • Location: Northern Canada
    • Status: offline
    Re: Can I speed up simple capture loop ? 2019/07/11 05:34:50 (permalink)
    0
    It is hard to tell whether it's a bad code generated, processor stalls while accessing peripheral registers, bad cache settings. PIC32MZ is complex.
     
    I suggest you post the disassembly of your best code, and then we can see if this has some glaring inefficiencies.
     
    Meanwhile you check your cache settings, check the PORT peripheral clock (is it at 200 MHz?) etc etc
     
    A side question - looks like you're bit-banging PMP. Is there any reason you don't use PMP peripheral instead - it should be faster.
    #10
    nigelwright7557
    Super Member
    • Total Posts : 284
    • Reward points : 0
    • Joined: 2006/11/06 08:15:51
    • Location: 0
    • Status: offline
    Re: Can I speed up simple capture loop ? 2019/07/11 07:28:49 (permalink)
    0
    Here is disassembly of the relevant code.
    It already looks pretty tight  to me.
           
    792:                 paul:           
    793:                             ptr=scopebuffer;
    9D000F60  3C028000   LUI V0, -32768
    9D000F64  2442009C   ADDIU V0, V0, 156
    794:                            
    795:                             fastptr=scopebufferlength;
    9D000F58  AF828070   SW V0, -32656(GP)
    9D000F5C  24030800   ADDIU V1, ZERO, 2048
    796:                            
    797:                             do
    798:                             {
    799:                                  LATBSET = setbit1;
    9D000F68  3C08BF86   LUI T0, -16506
    9D000F6C  24040002   ADDIU A0, ZERO, 2
    9D000F78  AD040138   SW A0, 312(T0)
    800:                                  LATBCLR = setbit1;
    9D000F70  3C07BF86   LUI A3, -16506
    9D000F7C  ACE40134   SW A0, 308(A3)
    801:                  
    802:                               *ptr++ = PORTB;
    9D000F74  3C06BF86   LUI A2, -16506
    9D000F80  24420002   ADDIU V0, V0, 2
    9D000F84  8CC50120   LW A1, 288(A2)
    803:                             } while (--fastptr);
    9D000F88  2463FFFF   ADDIU V1, V1, -1
    9D000F8C  1460FFFA   BNE V1, ZERO, .LVL41
    9D000F90  A445FFFE   SH A1, -2(V0)
    9D000F94  AF808070   SW ZERO, -32656(GP)
    804:                
    805:                  
    #11
    andersm
    Super Member
    • Total Posts : 2639
    • Reward points : 0
    • Joined: 2012/10/07 14:57:44
    • Location: 0
    • Status: offline
    Re: Can I speed up simple capture loop ? 2019/07/11 08:42:02 (permalink)
    5 (1)
    Don't try to use the MPLAB X disassembly view, it rearranges the instructions into some approximation of source code order, rendering it completely useless. It looks like the main loop is 7 instructions long, meaning that with absolutely zero overhead anywhere, the best you could do is ~28MHz. You also couldn't write it any faster by hand, except by unrolling.
     
    9D000F58  AF828070   SW V0, -32656(GP)
    9D000F5C  24030800   ADDIU V1, ZERO, 2048
    9D000F60  3C028000   LUI V0, -32768
    9D000F64  2442009C   ADDIU V0, V0, 156
    9D000F68  3C08BF86   LUI T0, -16506
    9D000F6C  24040002   ADDIU A0, ZERO, 2
    9D000F70  3C07BF86   LUI A3, -16506
    9D000F74  3C06BF86   LUI A2, -16506
     
    .LVL41:
    9D000F78  AD040138   SW A0, 312(T0)
    9D000F7C  ACE40134   SW A0, 308(A3)
    9D000F80  24420002   ADDIU V0, V0, 2
    9D000F84  8CC50120   LW A1, 288(A2)
    9D000F88  2463FFFF   ADDIU V1, V1, -1
    9D000F8C  1460FFFA   BNE V1, ZERO, .LVL41
    9D000F90  A445FFFE   SH A1, -2(V0)

    9D000F94  AF808070   SW ZERO, -32656(GP)

    #12
    simong123
    Lab Member No. 003
    • Total Posts : 1310
    • Reward points : 0
    • Joined: 2012/02/07 18:21:03
    • Location: Future Gadget Lab (UK Branch)
    • Status: offline
    Re: Can I speed up simple capture loop ? 2019/07/11 08:54:06 (permalink)
    0
    You can use DMA to reduce overhead. There is no reason a PORT cannot be used as the source for a DMA transfer.
    You can use PPS to connect your clock output pin to an interrupt. You can also configure this output to be an OC pin if you don't want to toggle it manually (you will get less jitter).
    The interrupt is used to initiate the DMA cell transfer. The DMA source is PORTB with cell size = block size = 1. The destination is your buffer, cell size 1, block size your buffer length in bytes.
    All you need to do is set up the DMA transfer, enable the OC output, and wait for the DMA to complete!
    (The above assumes an 8 bit ADC. For 16bit set cell size = 2).
    post edited by simong123 - 2019/07/11 08:56:01
    #13
    NKurzman
    A Guy on the Net
    • Total Posts : 17723
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: offline
    Re: Can I speed up simple capture loop ? 2019/07/11 10:01:38 (permalink)
    0
    simong.  So you are saying setup the read as DMA.  Then just toggle the clock in the code ( Or with a timer and output compare).  The clock would trigger the interrupt which would trigger the DMA.
    Clever.
    #14
    simong123
    Lab Member No. 003
    • Total Posts : 1310
    • Reward points : 0
    • Joined: 2012/02/07 18:21:03
    • Location: Future Gadget Lab (UK Branch)
    • Status: offline
    Re: Can I speed up simple capture loop ? 2019/07/11 11:10:12 (permalink)
    0
    @NKurzman. Yes. I have used a similar technique before, although using a timer and DMA to a port to drive the various clocks (incl. ADC clock) for a CCD as well, instead of the OC module (iirc 8 different clocks with different phases/duty cycles).
    I also use a similar setup (Interrupt/DMA from PORT) for reading CMOS sensors, although here the clock is from the CMOS sensor itself. It is possible to achieve higher speeds than possible using the PMP module.
     
    #15
    nigelwright7557
    Super Member
    • Total Posts : 284
    • Reward points : 0
    • Joined: 2006/11/06 08:15:51
    • Location: 0
    • Status: offline
    Re: Can I speed up simple capture loop ? 2019/07/11 16:09:56 (permalink)
    0
    Best  I can get is 12.5MHz today.
    Tried running capture from RAM but it didn't help.
    post edited by nigelwright7557 - 2019/07/11 16:15:44
    #16
    nigelwright7557
    Super Member
    • Total Posts : 284
    • Reward points : 0
    • Joined: 2006/11/06 08:15:51
    • Location: 0
    • Status: offline
    Re: Can I speed up simple capture loop ? 2019/07/28 22:02:31 (permalink)
    0
    Just to tie up this thread.
    In the end I used a loop without clocking the data in software and it gives me 14MHz.
    I clocked the A2D using OC4 PWM pin.
     
    I tried, after many hours of trying to get it to work, DMA but this only gave about 10MHz.
     
    #17
    moser
    Super Member
    • Total Posts : 504
    • Reward points : 0
    • Joined: 2015/06/16 02:53:47
    • Location: Germany
    • Status: offline
    Re: Can I speed up simple capture loop ? 2019/07/29 04:26:39 (permalink)
    0
    Did you consider partial or full loop unrolling, as previously mentioned by andersm? If your read length is it constant or at least a multiple of a constant, then this might be possible.
     
    Partial unrolling means, you do now in one cycle the same what you previously did in two (or more) cycles. It reduces the loop overhead in relation to the actual work you do in the loop. The more you do in one cycle, the better this relation gets. If you go all the way, then you just have all the instruction in one cycle, which means, you just can get rid of the loop. However, be aware that the more you go into this direction, the more instructions are needed for the data read. As long as all instructions still fit into the instruction cache, this is OK. But if not, then that much unrolling might be slower. Also the reads won't occur in regular intervals, so it might difficult or impossible to work with the PWM clock.
    #18
    NorthGuy
    Super Member
    • Total Posts : 5592
    • Reward points : 0
    • Joined: 2014/02/23 14:23:23
    • Location: Northern Canada
    • Status: offline
    Re: Can I speed up simple capture loop ? 2019/07/29 06:22:35 (permalink)
    0
    You can also use PWM to produce clock and read port with CPU.
     
    With PWM clock, dsPIC33 running at 100 MHz can read port in 2 instruction cycles and has no overhead looping, which would give you 50 MHz. Cannot do such things with PIC32.
     
    If you produce clock by CPU, dsPIC33 will need 2 extra instructions to manipulate clock, so it's 4 cycles per loop - 25 MHz.
     
    Or, if you need even faster, go with an FPGA. A $15 entry-level Spartan-7 can do it at 600 MHz.
    #19
    nigelwright7557
    Super Member
    • Total Posts : 284
    • Reward points : 0
    • Joined: 2006/11/06 08:15:51
    • Location: 0
    • Status: offline
    Re: Can I speed up simple capture loop ? 2019/07/29 07:56:01 (permalink)
    0
    moser
    Did you consider partial or full loop unrolling, as previously mentioned by andersm? If your read length is it constant or at least a multiple of a constant, then this might be possible.
     
    Partial unrolling means, you do now in one cycle the same what you previously did in two (or more) cycles. It reduces the loop overhead in relation to the actual work you do in the loop. The more you do in one cycle, the better this relation gets. If you go all the way, then you just have all the instruction in one cycle, which means, you just can get rid of the loop. However, be aware that the more you go into this direction, the more instructions are needed for the data read. As long as all instructions still fit into the instruction cache, this is OK. But if not, then that much unrolling might be slower. Also the reads won't occur in regular intervals, so it might difficult or impossible to work with the PWM clock.


    The code now is just one line per read.
    *ptr++=PORTB;
    My current code is:

                ptr=scopebuffer;
                fastptr=scopebufferlength/32;
              
                     
               
                do
                {
                     *ptr++ = PORTB;
                     *ptr++ = PORTB;
                     *ptr++ = PORTB;
                     *ptr++ = PORTB;
                     *ptr++ = PORTB;
                     *ptr++ = PORTB;
                     *ptr++ = PORTB;
                     *ptr++ = PORTB;
                     *ptr++ = PORTB;
                     *ptr++ = PORTB;
                     *ptr++ = PORTB;
                     *ptr++ = PORTB;
                     *ptr++ = PORTB;
                     *ptr++ = PORTB;
                     *ptr++ = PORTB;
                     *ptr++ = PORTB;
                     *ptr++ = PORTB;
                     *ptr++ = PORTB;
                     *ptr++ = PORTB;
                     *ptr++ = PORTB;
                     *ptr++ = PORTB;
                     *ptr++ = PORTB;
                     *ptr++ = PORTB;
                     *ptr++ = PORTB;
                     *ptr++ = PORTB;
                     *ptr++ = PORTB;
                     *ptr++ = PORTB;
                     *ptr++ = PORTB;
                     *ptr++ = PORTB;
                     *ptr++ = PORTB;
                     *ptr++ = PORTB;
                     *ptr++ = PORTB;
                 
                } while (--fastptr);
              
    #20
    Page: 12 > Showing page 1 of 2
    Jump to:
    © 2019 APG vNext Commercial Version 4.5