Shop OBEX P1 Docs P2 Docs Learn Events
My stupid questions thread — Parallax Forums

My stupid questions thread

I've a ton of questions and rather than spread them out in irrelevant threads I'll just start this thread.

Right now I'm trying to figure out the best way to power and program the P2. I'd really like to use an external supply, not my pc's usb power. I also don't want to use the USB Aux connector, this would require cutting a cable. I really WANT to power from the 2pin header that I assume is for a fan. I've looked at the schematic and I don't quite understand what would happen if I inject 5v at this point and connect either usb (or both) to a computer.

I've looked at getting a cheap 3amp usb wart like used with the raspberry pi but I'm not sure I trust the cheap supplies. I'm about ready to cut up a usb cable but I don't really want to if I don't have to!
«13

Comments

  • evanhevanh Posts: 15,126
    edited 2019-02-19 03:49
    There is a big blurb on page two of the schematic. It basically says those two pads can be power input but must be 5 volts and don't use AUX-USB socket at the same time.

    I've solder in a two pin header and am using it. The soldering requires a lot of heat on the GND pad to get it to wet right through.
  • cheezuscheezus Posts: 295
    edited 2019-02-19 06:26
    I did study the schematic the day I got the board, but I confess I haven't looked at it since. I'm getting ready to finally hook stuff up to the P2 and just wanted to make sure before I start releasing the magic smoke.

    Okay next stupid question... I'm trying to do some inline asm with fastspin and I'm doing something wrong.
    pri send_asm(outv) | i,c
    '
    '   Send eight bits, then raise di.
    '
        i := |< di
        c := |< clk
    asm
        rol outv, #24     
        rep #4, #8-1
        rol     outv, #1      wc
        andn    outb, c
        muxc    outb, i
        or      outb, c 
    endasm
            
    {
       outv ><= 8
        repeat 8
            outb[clk] := 0
            outb[di] := outv
            outv >>= 1
            outb[clk] := 1
        outb[di] := 1
    }
    

    I THINK it should work, or at least compile but nothing I do will even get this to compile?

    *fixed asm labels, still doesn't compile?

    *EDIT*
    I think I got it, now the question is what's WRONG with it :p
  • msrobotsmsrobots Posts: 3,701
    edited 2019-02-19 07:06
    I personally like this syntax for rep
    		rep	@.endrep,		#10			'do 10 divisions
    …
    .endrep
    

    and whats wrong?

    My guess would be ROR not ROL
    {
       outv ><= 8
        repeat 8
            outb[clk] := 0
            outb[di] := outv
            outv >>= 1
            outb[clk] := 1
        outb[di] := 1
    }
    

    this shifts out the lower 8 bits, lsb first you are shifting out msb first

    not sure...

    Mike
  • cheezuscheezus Posts: 295
    edited 2019-02-19 08:31
    I finally got that one. I'm totally over my head right now but I guess I'm making progress. Working code is:
    pri send(outv) | i,c
    '
    '   Send eight bits, then raise di.
    '
    #ifdef __P2__
    
        i := |< di
        c := |< clk
    asm
        rol outv, #24     
        rep #.end_send, #8
        rol     outv, #1      wc
        andn    outb, c
        muxc    outb, i
        or      outb, c 
    .end_send    
        or      outb, i
    endasm
    
    #else   
        repeat 8
            outa[clk] := 0
            outa[di] := outv
            outv >>= 1
            outa[clk] := 1
        outa[di] := 1
    #endif  
    


    I'm not really sure about the efficiency of the decoding op. I'm thinking these should be prepared into a bitmask on init and then on each "pincall" the mask is sent as a parameter. I'm not sure the overhead in loading the parameters is any less than the inline decode. My guess is it's negligible.

    The move to inline asm using REP improves the time from 26 seconds to 20. Now to figure out the read! :smile:
        r := 0
        repeat 8
            outb[clk] := 0
            outb[clk] := 1
    '        waitcnt(cnt+wait_time)     '' c code needs wait here
            r += r + inb[do]
    


    Okay, now I'm trying to figure out how to set the clock for 80 MHz *facepalm*
  • If the P1 took 4 clocks to execute an instruction and the P2 only takes one now then the P1 at 80 is the same speed as a P2 at 20 right. 20 is the new 80?

    Mike
  • iseries wrote: »
    If the P1 took 4 clocks to execute an instruction and the P2 only takes one now then the P1 at 80 is the same speed as a P2 at 20 right. 20 is the new 80?

    Mike

    P2 takes two clocks per instruction not 1.
  • That's a rip. So the P2 is slower than a P1 at 20. We should be getting a 40Mhz crystal than.

    Mike
  • evanhevanh Posts: 15,126
    If you want speed then the Prop2 can exceed 200 MHz. Which is more than double the clock what the Prop1 could ever achieve. So that's at least 4x the MIPS. On a real world compare it'll be even more.
  • evanhevanh Posts: 15,126
    The extra configurability of the Prop2 clock frequency makes it way easier to choose what you want.
  • Do you really need the inline asm? I think just re-arranging the code slightly should get you the performance back. I presume di and clk are variables (if they're constants then everything is easier). fastspin has trouble optimizing global variables because another COG could (theoretically) change them at any time. If you copy them into locals and then use those, rather like you did in your inline ASM, then the optimizer can work on them. For example:
    VAR
      long di 
      long clk
      
    PUB send(outv) | i, c
      i := di
      c := clk
      repeat 8 
        outb[c] := 0
        outb[i] := outv
        outv >>= 1
        outb[c] := 1
      outb[i] := 1
    
    Produces the following assembly with fastspin -2 -O2:
    _send
    	mov	_var01, #1
    	shl	_var01, _var02
    	rdlong	_var02, objptr
    	add	objptr, #4
    	rdlong	_var03, objptr
    	sub	objptr, #4
    	mov	_var04, #1
    	shl	_var04, _var03
    	mov	_var05, #8
    	rep	@LR__0002, #8
    LR__0001
    	andn	outb, _var04
    	shr	arg01, #1 wc
    	muxc	outb, _var01
    	or	outb, _var04
    LR__0002
    	mov	_var06, #1
    	shl	_var06, _var02
    	or	outb, _var06
    _send_ret
    	reta
    
    The inner loop is just 4 instructions, which is the same as the hand written assembly. I can see a few places where the setup code could be improved (on P2 we should use the encode instruction instead of mov+shift, for example) but overall I think it's not too bad, and should be a lot easier to read and maintain than inline assembly.
  • tomcrawfordtomcrawford Posts: 1,126
    edited 2019-02-19 19:33
    moved out of cheezus' thread. Sorry
  • ersmith wrote: »
    Do you really need the inline asm? I think just re-arranging the code slightly should get you the performance back. I presume di and clk are variables (if they're constants then everything is easier). fastspin has trouble optimizing global variables because another COG could (theoretically) change them at any time. If you copy them into locals and then use those, rather like you did in your inline ASM, then the optimizer can work on them. For example:
    VAR
      long di 
      long clk
      
    PUB send(outv) | i, c
      i := di
      c := clk
      repeat 8 
        outb[c] := 0
        outb[i] := outv
        outv >>= 1
        outb[c] := 1
      outb[i] := 1
    
    Produces the following assembly with fastspin -2 -O2:
    _send
    	mov	_var01, #1
    	shl	_var01, _var02
    	rdlong	_var02, objptr
    	add	objptr, #4
    	rdlong	_var03, objptr
    	sub	objptr, #4
    	mov	_var04, #1
    	shl	_var04, _var03
    	mov	_var05, #8
    	rep	@LR__0002, #8
    LR__0001
    	andn	outb, _var04
    	shr	arg01, #1 wc
    	muxc	outb, _var01
    	or	outb, _var04
    LR__0002
    	mov	_var06, #1
    	shl	_var06, _var02
    	or	outb, _var06
    _send_ret
    	reta
    
    The inner loop is just 4 instructions, which is the same as the hand written assembly. I can see a few places where the setup code could be improved (on P2 we should use the encode instruction instead of mov+shift, for example) but overall I think it's not too bad, and should be a lot easier to read and maintain than inline assembly.

    Thanks @ersmith, I'll switch over to spin2gui and play with the compiler switches a bit. For P2 everything has been compiled with "fastspin.exe -2 -L". I was just trying to get something working, to set a baseline. I was trying to kill 2 birds with one stone, learning sd cards and learning the p2 a little more. It will be interesting to see how long the test takes with some changes to the compiler and a few tweaks to the spin code.

    The inline asm probably isn't necessary, I was just trying to understand it so when it is necessary I have some idea what I'm doing.
  • iseries wrote: »
    That's a rip. So the P2 is slower than a P1 at 20. We should be getting a 40Mhz crystal than.

    Mike

    With my first test (and mind you the compiler is not set to "do the magic yet") The P1 vs P2 code shows 2x improvement, at double the clock speed. So the MHZ improvement is the only effect I seem to see right now. IIRC the clock toggled about double the rate. Only about half the expected 4x improvement although this is probably compiler settings as I stated before. Still, I'm working out how to lower the clock speed because my LA can't keep up. I guess it's time to get my hands on a scope :smile:
  • cheezus wrote: »
    I did study the schematic the day I got the board, but I confess I haven't looked at it since. I'm getting ready to finally hook stuff up to the P2 and just wanted to make sure before I start releasing the magic smoke.

    Okay next stupid question... I'm trying to do some inline asm with fastspin and I'm doing something wrong.
    pri send_asm(outv) | i,c
    '
    '   Send eight bits, then raise di.
    '
        i := |< di
        c := |< clk
    asm
        rol outv, #24     
        rep #4, #8-1
        rol     outv, #1      wc
        andn    outb, c
        muxc    outb, i
        or      outb, c 
    endasm
            
    {
       outv ><= 8
        repeat 8
            outb[clk] := 0
            outb[di] := outv
            outv >>= 1
            outb[clk] := 1
        outb[di] := 1
    }
    

    I THINK it should work, or at least compile but nothing I do will even get this to compile?

    *fixed asm labels, still doesn't compile?

    *EDIT*
    I think I got it, now the question is what's WRONG with it :p

    Don't asm/endasm have to be indented to be included in the PRI method? Or are they a special case?
  • Okay, here's a stupid question. I'm fiddling with feedback servo and trying to use smart pin mode 4 to generate the control pulses.
    CON
                
        oscmode = $010c3f04               'standard stuff
        freq    = 160_000_000
        baud = 115200                     'must configure RUN command to match this
        msec20 = freq/50                  'tics in 20 millisec
        microsec = freq/1_000_000
        thepin = 48
        sync = 49
        pulseMode = %00100_0                'smart pin mode
    
    OBJ
        ser: "PrintfSerial"     'access to Propellor output (output only)
    
    var
        long  param
        byte  cog
        byte  theservo
    
    pub main
        clkset(oscmode, freq)
        ser.start(baud)                  'start up serial terminal
        ser.str(string("hello, world"))
        ser.nl
    
         param := microsec*1500            '1500 usec
         cog := cognew(@entry, @param)     'send ADDRESS of param
         ser.str(string("cog started: "))
         ser.dec(cog)
         ser.nl
    
        repeat                              'forever.
    
    DAT
    entry     ORG 0
              mov  hubAdrs, ptra          'boss cog passed an address:  save it
              rdlong PWidth, hubAdrs      'fetch the pulse width
              dirh #sync                  'scope sync
              wrpin #pulseMode, #thepin   'set smart pin mode
              wxpin #0, #thepin           'x[31:16] = 0
              getct target
              addct1 target, ##msec20     'set up 20 msec timer
    loop      waitct1                     'remainder of 20 msec
              addct1 target, ##msec20     'set up for next pass
              outh #sync                  'scope sync
              waitx ##160
              outl #sync
              wypin pWidth, #thepin       'start a pulse
              jmp  #loop
    
    hubadrs   res  1             'address in hub memory
    target    res  1              'target time
    pWidth    res  1
    

    I have a 20 msec heartbeat which I can see on sync, but noting happens on ThePin. I think I am setting the smartpin mode correctly, and am setting x[31..16] to zero so it just does a pulse for the duration in y. I would be grateful if some kind soul could help. AdThanksVance

    I have 0 knowledge with the smartpins right now but... I don't see you setting DIR any on the pin, and might possibly need OUT as well?
  • David Betz wrote: »
    cheezus wrote: »
    I did study the schematic the day I got the board, but I confess I haven't looked at it since. I'm getting ready to finally hook stuff up to the P2 and just wanted to make sure before I start releasing the magic smoke.

    Okay next stupid question... I'm trying to do some inline asm with fastspin and I'm doing something wrong.
    pri send_asm(outv) | i,c
    '
    '   Send eight bits, then raise di.
    '
        i := |< di
        c := |< clk
    asm
        rol outv, #24     
        rep #4, #8-1
        rol     outv, #1      wc
        andn    outb, c
        muxc    outb, i
        or      outb, c 
    endasm
            
    {
       outv ><= 8
        repeat 8
            outb[clk] := 0
            outb[di] := outv
            outv >>= 1
            outb[clk] := 1
        outb[di] := 1
    }
    

    I THINK it should work, or at least compile but nothing I do will even get this to compile?

    *fixed asm labels, still doesn't compile?

    *EDIT*
    I think I got it, now the question is what's WRONG with it :p

    Don't asm/endasm have to be indented to be included in the PRI method? Or are they a special case?

    It seemed like indention didn't matter. I'm still trying to understand how to use them properly but I can see them being REALLY handy :smiley:
  • cheezus wrote: »
    David Betz wrote: »
    cheezus wrote: »
    I did study the schematic the day I got the board, but I confess I haven't looked at it since. I'm getting ready to finally hook stuff up to the P2 and just wanted to make sure before I start releasing the magic smoke.

    Okay next stupid question... I'm trying to do some inline asm with fastspin and I'm doing something wrong.
    pri send_asm(outv) | i,c
    '
    '   Send eight bits, then raise di.
    '
        i := |< di
        c := |< clk
    asm
        rol outv, #24     
        rep #4, #8-1
        rol     outv, #1      wc
        andn    outb, c
        muxc    outb, i
        or      outb, c 
    endasm
            
    {
       outv ><= 8
        repeat 8
            outb[clk] := 0
            outb[di] := outv
            outv >>= 1
            outb[clk] := 1
        outb[di] := 1
    }
    

    I THINK it should work, or at least compile but nothing I do will even get this to compile?

    *fixed asm labels, still doesn't compile?

    *EDIT*
    I think I got it, now the question is what's WRONG with it :p

    Don't asm/endasm have to be indented to be included in the PRI method? Or are they a special case?

    It seemed like indention didn't matter. I'm still trying to understand how to use them properly but I can see them being REALLY handy :smiley:

    The indentation of the "asm" matters -- it needs to be indented like any other statement. "endasm" really should be lined up with "asm", although I suspect the compiler won't care too much. Everything between "asm"and "endasm" can be indented any way you want (it's PASM code, so format it as though it were in a DAT section).
  • cheezus wrote: »
    iseries wrote: »
    That's a rip. So the P2 is slower than a P1 at 20. We should be getting a 40Mhz crystal than.

    With my first test (and mind you the compiler is not set to "do the magic yet") The P1 vs P2 code shows 2x improvement, at double the clock speed. So the MHZ improvement is the only effect I seem to see right now.

    @iseries: The P2 can clocked up to 180 MHz "officially", and in practice people have gone well beyond this. Don't confuse the crystal with the processor clock rate -- P1 board typically use a 5 MHz crystal with 16x PLL to give an 80 MHz system clock, whereas the P2 ES board uses a 20 MHz crystal with what is basically an 8x or 9x PLL to give 160 MHz or 180 MHz system clock.

    @cheezus: You're probably comparing apples and oranges with the P1 vs P2 code. On P1 fastspin puts small loops into COG memory (using "FCACHE"), so if your program spends a lot of time in such loops you're comparing P1 COG execution speed with P2 HUB execution speed (FCACHE isn't implemented for P2 yet).

  • iseries wrote: »
    That's a rip. So the P2 is slower than a P1 at 20. We should be getting a 40Mhz crystal than.

    Mike

    Uh no. P2 is twice as fast as the P1 for a given clock speed, plus there are new instructions and smart pins that allow more efficient operations.
  • @ersmith ,

    We all know the P2 can go faster. It just that out of the box the designer choose a 20Mhz clock speed which makes it slower than an out of the box P1. Well I guess that's not all true either since the P1 wakes up not knowing what speed it's at and gets configured for 80 by default where as the P2 does.

    In any case determining how fast is imported if we are going to drive I2C and SPI devices that may require slower speeds just to interface them.

    Mike
  • ersmithersmith Posts: 5,900
    edited 2019-02-19 22:29
    iseries wrote: »
    We all know the P2 can go faster. It just that out of the box the designer choose a 20Mhz clock speed which makes it slower than an out of the box P1. Well I guess that's not all true either since the P1 wakes up not knowing what speed it's at and gets configured for 80 by default where as the P2 does.
    The P1 does not get configured to 80 MHz by default. You have to explicitly configure it. One way to do this with appropriate Spin CON declarations (_clkmode and _clkfreq), which will implicitly add a clkset() call to the beginning of your program. Without that the P1 boots in a very slow mode (I can't remember offhand, but rcfast would be at best ~5Mhz).

  • evanhevanh Posts: 15,126
    edited 2019-02-19 22:32
    You get to set the frequency you like. In the Prop2 the HUBSET instruction is for that. Cluso made a nice set of constants for making it easy to read and choose. - https://forums.parallax.com/discussion/comment/1452025/#Comment_1452025
  • @cheezus
    I like this thread. I have had a steep learning curve for asm. The folks on the forums for the P2 are great. And have a lot of patience.
    Thanks to all!!!!!!!!!!!!!!!!!
  • pilot0315 wrote: »
    @cheezus
    I like this thread. I have had a steep learning curve for asm. The folks on the forums for the P2 are great. And have a lot of patience.
    Thanks to all!!!!!!!!!!!!!!!!!

    +1


    I'm feeling pretty dumb right now (as usual) and I'm still stuck on "my clock problem". I've looked at Cluso's example and have even used it in a few basic ASM programs I was playing with. But what I don't understand is how that alias's to Spin2 command CLKSET.
  • evanhevanh Posts: 15,126
    cheezus wrote: »
    But what I don't understand is how that alias's to Spin2 command CLKSET.

    I've just bumped into Eric's own code for doing this in his VGA tile demo. He uses the following line:
        clkset(_SETFREQ, _CLOCKFREQ)
    
  • evanh wrote: »
    cheezus wrote: »
    But what I don't understand is how that alias's to Spin2 command CLKSET.

    I've just bumped into Eric's own code for doing this in his VGA tile demo. He uses the following line:
        clkset(_SETFREQ, _CLOCKFREQ)
    

    I think I finally get it after looking at the assembled code, although I need to study this more. I had to follow the code back to see that arg3 =3. Now to figure out some standard values and possibly how to use this for RCSLOW and RCFAST!
    __system__clkset
    '       $f == free
    	wrlong	arg02, #20
    '     $10 = reserved   (never free automatically)
    	wrlong	arg01, #24
    '     $20 = inuse      (block was observed to be in use during GC)
    	hubset	#0
    	hubset	arg01
    	waitx	##200000
    	add	arg01, arg03
    	hubset	arg01
    __system__clkset_ret
    	reta
    
  • evanh wrote: »
    You get to set the frequency you like. In the Prop2 the HUBSET instruction is for that. Cluso made a nice set of constants for making it easy to read and choose. - https://forums.parallax.com/discussion/comment/1452025/#Comment_1452025

    I've noticed that there are many combinations of parameters that result in the same _CLOCKFREQ with different values of _SETFREQ, and that different programs use different values of _SETFREQ for the same _CLOCKFREQ. Last night I tried a few different values (some by putting different numbers into Cluso's program that resulted in the CLOCKFREQ I wanted.) All worked with my ADC programs (spin2, or basic) that use either smartpin ADC or an external ADC.

    Is there any guidance on the values to use? (probably should be in P2 Tricks thread.)
    Thanks
    Tom
  • evanhevanh Posts: 15,126
    edited 2019-02-21 03:49
    twm47099 wrote: »
    I've noticed that there are many combinations of parameters that result in the same _CLOCKFREQ with different values of _SETFREQ, and that different programs use different values of _SETFREQ for the same _CLOCKFREQ....

    Is there any guidance on the values to use? (probably should be in P2 Tricks thread.)
    Correct, namely _XDIV and _XMUL. They are like that to provide both great range and fine adjustment of the system clockrate.

    I will recommend _XOSC be set to %10 instead of %01. JMG and Saucy I think went over this.
    And obviously _XTALFREQ should be 20_000_000 for the P2ES-EVAL board. Cluso's 12 MHz number suits Peter's P2D2 board.

    With the P2ES chip there is a general recommendation to keep _XDIV at 1 or 2 to achieve best stability. It's supposed to help with sensitive video timings and the like. But this is far from being a must do. The final Prop2 is expected to be free of this niggle. When I'm experimenting with lots of adjustments I'll usually set _XDIV to 20 for the P2ES-EVAL board. This means that _XMUL is easy to read as a MHz number.

    CORRECTION: _XDIVP should be used for when wanting less than 100 MHz from the PLL. Set PLL to 100 MHz or above then use this to divide down.
  • twm47099 wrote: »
    evanh wrote: »
    You get to set the frequency you like. In the Prop2 the HUBSET instruction is for that. Cluso made a nice set of constants for making it easy to read and choose. - https://forums.parallax.com/discussion/comment/1452025/#Comment_1452025

    I've noticed that there are many combinations of parameters that result in the same _CLOCKFREQ with different values of _SETFREQ, and that different programs use different values of _SETFREQ for the same _CLOCKFREQ. Last night I tried a few different values (some by putting different numbers into Cluso's program that resulted in the CLOCKFREQ I wanted.) All worked with my ADC programs (spin2, or basic) that use either smartpin ADC or an external ADC.

    Is there any guidance on the values to use? (probably should be in P2 Tricks thread.)
    Thanks
    Tom

    It took me a few but I was able to figure out... if you change CLKSET as follows, you can use cluso's code very easily.
      _XTALFREQ     = 20_000_000                                    ' crystal frequency
      _XDIV         = 1                                             ' crystal divider to give 20MHz
      _XMUL         = 5                                          ' crystal / div * mul (100mhz)
      _XDIVP        = 4                                             ' crystal / div * mul /divp to give _CLKFREQ (1,2,4..30)
      _XOSC         = %10                                  'OSC    ' %00=OFF, %01=OSC, %10=15pF, %11=30pF 
      _XPPPP        = ((_XDIVP>>1) + 15) & $F                       ' 1->15, 2->0, 4->1, 6->2...30->14
      _CLOCKFREQ    = _XTALFREQ / _XDIV * _XMUL / _XDIVP            ' internal clock frequency                
      _SETFREQ      = 1<<24 + (_XDIV-1)<<18 + (_XMUL-1)<<8 + _XPPPP<<4 + _XOSC<<2  ' %0000_000e_dddddd_mmmmmmmmmm_pppp_cc_00  ' setup  oscillator '' this is used by clkset
    
    ...
       clkset(_SETFREQ, _CLOCKFREQ)
    

    From what I understand it's best to keep xdiv low.. while keeping 100 MHz =< (xtal / xdiv * xmul) >= 200MHz. In my example I'm setting for 20 mhz. I've been using c/ 2 * 16 /2 to match my P1 80mhz clock. Hope this helps a little!
  • evanh wrote: »
    The final _XDIVP would always be set at 1 for most people. It'll be intended for when a crystal oscillator module is being used without the Prop's PLL circuit.

    AHHH, this was one detail I missed. Is there any disadvantage to the way I'm doing things?
Sign In or Register to comment.