Shop OBEX P1 Docs P2 Docs Learn Events
Auto Detect P2ASM for P2D2 and P2EVAL boards — Parallax Forums

Auto Detect P2ASM for P2D2 and P2EVAL boards

Cluso99Cluso99 Posts: 18,066
edited 2019-09-16 10:50 in Propeller 2
The attached P2asm code automatically detects the P2D2 or P2EVAL boards.

A pull-down resistor is needed on Pin 25 of the P2D2 and not be present on the P2EVAL. There is a ground pad 0.4" from pin 25. I suggest using 10K.
You can change these Pin constants to something other that the values I have chosen.

The program determines whether the pull-dwon exists and sets the xtal and baud appropriately and then outputs a message to the serial port every 1 second, and flashes Pin 0 on the P2D2 (I have a green led on this pin) or flashes the blue led on Pin 56 of the P2EVAL every second.

I have provided duplicate CON calculations for each board and select the appropriate set for further use.
Perhaps someone might like to work out the pasm code to calculate the clock and baud values as variables???
«1

Comments

  • evanhevanh Posts: 15,126
    Those two HUBSET #0 instructions are redundant. In fact they would be redundant even without the flaw.

    If the prop2 is already operating from RCFAST/RCSLOW clock mode then they do nothing. If the prop2 is in some other clock mode prior then the two step rapid change is of no benefit and may even increase the chances of triggering a lock up because the PLL and crystal both are being issued a shutdown immediately followed by a startup.

    There is two known ways to work around the lock-ups with the PLL sourced sysclock selector, either know and use the prior PLL config so as to change clock source selection orderly, or assume that RCFAST hand-over is in effect.
  • evanhevanh Posts: 15,126
    If using RCFAST handover method (in the loader for example), make sure you give the PLL and crystal time to completely shutdown before issuing the COGINIT.

    This would look pretty much like the "use known prior mode" method but is internal to the loader. It doesn't require any parameter passing. Here's earlier snippets on the subject - https://forums.parallax.com/discussion/comment/1475472/#Comment_1475472
  • evanhevanh Posts: 15,126
    Ah, "prior mode handover" would be a better name for known prior mode method. So take your pick:

    1: Prior mode handover
    2: RCFAST handover

  • Cluso99Cluso99 Posts: 18,066
    @evanh,
    Since you’re the master of the clock section, would you like to fix up the code to do it properly?

    I did presume it’s use would be from power up and loaded from Flash or SD. But of course it could be downloaded, or loaded from FAT following some other code.

    It should also save the correct values in hub $00010... and some ID too.

    I looked for some difference between the boards but I couldn’t see anything that I could see by software so I had to resort to a pull down. I could have used a pull-up similarly too. I have pin sockets on my P2D2s so it was easy to plug in a resistor permanently like I’ve done for SD booting.
  • evanhevanh Posts: 15,126
    edited 2019-09-17 02:34
    RCFAST handover will work as is. It needs no changes to that code. All the changes for RCFAST handover are in the loader. EDIT: Which means no use of any global mailboxes.

    So the first choice is which of those two methods to use. Your choice.

  • Cluso99Cluso99 Posts: 18,066
    Here is an update...
    Checks hub to see if clkmode is set and if !0 will disable the oscillator
    Then sets up the new clkmode, and also saves clkmode and clkfreq to hub $14 & $18

    @evanh,
    would you mind checking this out please?
    extract only...
    '+-------[ Select desired clock frequency ]------------------------------------+  
      _CLOCKFREQ     = 160_000_000                                   ' clock frequency
      _BASEFREQ      = 4_000_000                                     ' common base freq after XDIV
    '+-------[ Crystal Parameters ]------------------------------------------------+  
      _XTALFREQ2     = 12_000_000                                    ' P2D2   crystal frequency
      _XOSC2         = %01                                   'OSC    ' %00=OFF, %01=OSC, %10=15pF, %11=30pF
    '+-----------------------------------------------------------------------------+
      _XTALFREQV     = 20_000_000                                    ' P2EVAL crystal frequency
      _XOSCV         = %10                                   '15pF   ' %00=OFF, %01=OSC, %10=15pF, %11=30pF
    '+-----------------------------------------------------------------------------+
    ' calculate values (auto)...
      _XDIV2         = _XTALFREQ2 / _BASEFREQ                        ' P2D2   crystal divider
      _XDIVV         = _XTALFREQV / _BASEFREQ                        ' P2EVAL crystal divider
      _XDIVP         = (_CLOCKFREQ > 200_000_000) ? 2 : 1            ' if >200MHz /2 else /1
      _XMUL          = _CLOCKFREQ / _XDIVP / _BASEFREQ               ' clockfreq = crystal / div * mul /divp
      _XPPPP         = ((_XDIVP>>1) + 15) & $F                       ' 1->15, 2->0, 4->1, 6->2...30->14
      _CLKMODE2      = 1<<24 + (_XDIV2-1)<<18 + (_XMUL-1)<<8 + _XPPPP<<4 + _XOSC2<<2  ' %0000_000e_dddddd_mmmmmmmmmm_pppp_cc_00  ' P2D2   setup
      _CLKMODEV      = 1<<24 + (_XDIVV-1)<<18 + (_XMUL-1)<<8 + _XPPPP<<4 + _XOSCV<<2  ' %0000_000e_dddddd_mmmmmmmmmm_pppp_cc_00  ' P2EVAL setup
      _XSEL          = %11    ' %00=rcfast(20+MHz), %01=rcslow(~20KHz), %10=XI(5ms), %11=XI+PLL(10ms)        ......._...._.._11  ' XI+PLL
    '+-----------------------------------------------------------------------------+
    DAT           org       0                               'hubaddr if first loaded into hub $0
    entry         jmp       #begin                          '00000 skip over hub
    pcb           long      0                               '00004  0=P2D2, 1=P2EVAL
    clkmode_p2d2  long      _CLKMODE2                       '00008  clockmode for P2D2
    clkmode_p2ev  long      _CLKMODEV                       '0000C  clockmode for P2EVAL
    baud          long      _BAUD                           '00010  -spare-
    clkmode       long      0                               '00014  will store clkmode
    clkfreq       long      _CLOCKFREQ                      '00018  will store clkfreq
    bitper        long      _BITPER                         '0001C  bit period to load into smartpins
    '+-----------------------------------------------------------------------------+
    
    '+-------[ check for 10K pull-down on pincfg ]---------------------------------+ 
    begin         drvh      #pincfg                         '\ drive pin hi
                  waitx     #30*1                           '| wait >1us
                  flth      #pincfg                         '| float pin
                  waitx     #30*5                           '| wait >5us
                  testp     #pincfg                     wc  '/ P2D2=nc=pull-dn
                  
                  mov       pcb,              #0            ' P2D2: preset = 0
                  mov       clkmode,          clkmode_p2d2  ' P2D2: preset val
            if_c  mov       pcb,              #1            ' P2EVAL: set  = 1
            if_c  mov       clkmode,          clkmode_p2ev  ' P2EVAL: set val
    
    '+-------[ Set Xtal for P2D2 ]-------------------------------------------------+ 
                  rdlong    lmm_x,            #$14      wz  ' if 0 skip pll fixup
            if_z  jmp       #.skip 
                  andn      lmm_x,            #_XSEL        ' remove enable bit just in case
                  hubset    lmm_x                           ' ... and disable
                  waitx     ##20_000_000/30                 ' ... ~33ms 
    .skip         wrlong    clkmode,          #$14          ' write to hub $00014
                  wrlong    clkfreq,          #$18          ' write to hub $00018
                  hubset    clkmode                         ' setup oscillator
                  waitx     ##20_000_000/100                ' ... ~10ms
                  or        clkmode,          #_XSEL        ' ... add enable bits for XI+PLL
                  hubset    clkmode                         ' ... enable oscillator
    
  • evanhevanh Posts: 15,126
    Yep, that works. I generally don't bother with any of the hubRAM accesses since the prior mode is already copied into cogRAM and all my init code runs in cog0 anyway.

    The first 33 ms WAITX probably isn't useful either since you're already treating the PLL as engaged and just needs an update for the desired clock frequency. The reason for having a PLL shutdown pause in the loader code is to fully replicate RCFAST boot conditions if implimenting the RCFAST handover method.

  • evanhevanh Posts: 15,126
    There is one flaw, "clkfreq" can be overwritten by the loader. So all is happening is the COGINIT is copying the loader's changes into cogRAM and your code is copying it back to hubRAM. The value of _CLOCKFREQ is lost then.
  • Cluso99Cluso99 Posts: 18,066
    If my code is loaded from boot then yes, it will overwrite from hub $0 onwards.

    So, if you look at my code, the clkmode will be loaded as zero, so when the code gets copied into cog and run I check for 0 and if so, I skip it.

    If however, my code is loaded by some other method and it does not overwrite hub $0 (specifically $14) and it has a non-zero value, I use it to reset the oscillator, then write hub $14 and $18 with the new clkmode and clkfreq and then set the new values into the oscillator.
  • evanhevanh Posts: 15,126
    Yep, it works.

    Even though it's not used, you should fix up the filling of clkfreq with the _CLOCKFREQ value though. Could do similar to clkmode where you've MOV'ed the update into it. My working code has variable XMUL so clkfreq is recomputed even on first init:
    'recalculate sysclock hertz using cordic
    		qmul	xtalmul, ##(XTALFREQ / XDIV / XDIVP)	'integer component of pre-divided crystal frequency
    		mov	pa, xtalmul
    		mul	pa, ##round((float(XDIV*XDIVP)+0.5) * (float(XTALFREQ)/float(XDIV)/float(XDIVP) - float(XTALFREQ/XDIV/XDIVP)))
    		qdiv	pa, ##(XDIV * XDIVP)		'fractional component of pre-divided crystal frequency
    		getqx	clk_freq			'result of integer component
    		getqx	pa				'result of fractional component
    		add	clk_freq, pa			'de-error the integer rounding
    
    
    		...
    
  • Cluso99Cluso99 Posts: 18,066
    evan,
    I wasn't intending at this stage to allow for changing the clock frequency in this program. Probably that will be in another program.
    But I'll add this info into the comments in my program for later use. So thanks for that :smiley:
  • evanhevanh Posts: 15,126
    edited 2019-09-17 08:07
    Your clkfreq is still likely being overwritten by the loader assuming the loader uses prior-mode handover. That's a bug that you are not updating clkfreq.
  • Cluso99Cluso99 Posts: 18,066
    edited 2019-09-17 11:08
    evanh wrote: »
    Your clkfreq is still likely being overwritten by the loader assuming the loader uses prior-mode handover. That's a bug that you are not updating clkfreq.
    Is this what you mean? I am doing this.
    .skip         wrlong    clkmode,          #$14          ' write to hub $00014
                  wrlong    clkfreq,          #$18          ' write to hub $00018
                  hubset    clkmode                         ' setup oscillator
    

    BTW when I fixed the (_CLOCKFREQ > 180_000_000) ? 1 : 2 statement I discovered a bug where I was dividing divp instead of multiplying. Here is the fix. I'll post an update later.
      _XDIVP         = (_CLOCKFREQ > 180_000_000) ? 1 : 2            ' if >180MHz /1 else /2
      _XMUL          = _CLOCKFREQ * _XDIVP / _BASEFREQ               ' clockfreq = crystal / div * mul * divp
    
  • Cluso99Cluso99 Posts: 18,066
    New version with _XMUL calculation fixed
  • evanhevanh Posts: 15,126
    Cluso99 wrote: »
    [/code]
    evanh wrote: »
    Your clkfreq is still likely being overwritten by the loader assuming the loader uses prior-mode handover. That's a bug that you are not updating clkfreq.
    Is this what you mean? I am doing this.
    .skip         wrlong    clkmode,          #$14          ' write to hub $00014
                  wrlong    clkfreq,          #$18          ' write to hub $00018
                  hubset    clkmode                         ' setup oscillator
    
    That part is fine ... what's missing is clkfreq needs set to match your updated clkmode. The assembled value of _CLOCKFREQ is lost if the loader overwrites clkfreq along with clkmode.

    All you need is a MOV clkfreq, ##_CLOCKFREQ before the above code.
  • Cluso99Cluso99 Posts: 18,066
    WHOAA!
    Are you saying that the loader will load the binary into hub starting at hub $0, then overwrite hub location(s) $14 and or $18 with new values, change the clock, and then load my program into cog $0 and execute it???

    That will kill many programs that do not account for the hub $14/$18. That would be a disaster waiting to happen!!! Have I got this right???
  • evanhevanh Posts: 15,126
    edited 2019-09-17 13:11
    Correct, that's the hypothetical prior mode to be handled via the prior-mode handover method.

    EDIT: RCFAST handover method avoids all that by having the loader always reset back to RCFAST before doing the COGINIT.

  • evanhevanh Posts: 15,126
    edited 2019-09-17 13:56
    At the moment, I think loadp2 has three handover methods depending on the -SINGLE and -PATCH options:

    - With -SINGLE option, loadp2 downloads the prop2 binary as Prop_Hex ROM routine, so is effectively using the RCFAST handover then. The binary is not modified.

    - With -PATCH option, loadp2 uses its "mainloader" code to configure the prop2 clock frequency and patches the prop2 binary in loadp2 memory before downloading as 8-bit binary. This downloads faster than -SINGLE.

    - Without either option, loadp2 uses its "mainloader" code, programs the prop2 clock frequency, but leaves the binary untouched. This is the original method that's proven unreliable.

  • evanhevanh Posts: 15,126
    edited 2019-09-17 14:07
    Pnut probably uses one of the ROM routines for downloading so presumably is also effectively RCFAST handover. EDIT: Although, it is possible to also set the clock frequency with the Prop_Clk ROM routine so I can't be sure without some investigation.

  • Cluso99Cluso99 Posts: 18,066
    edited 2019-09-17 14:44
    Ok, it’s an option to explicitly patch the downloaded code. That makes sense.
    Thanks for the explanation :smiley:
  • evanhevanh Posts: 15,126
    It's been informative for me too. I saw misunderstandings going back many weeks but the size of the disconnect in perceived use of the mailboxes didn't sink in.

    I'm personally in favour of universally adopting RCFAST handover as the only method - removing prior-mode handover as an option. Let the resevered mailboxes be the same as on the prop1.

  • evanh wrote: »
    At the moment, I think loadp2 has three handover methods depending on the -SINGLE and -PATCH options:

    - With -SINGLE option, loadp2 downloads the prop2 binary as Prop_Hex ROM routine, so is effectively using the RCFAST handover then. The binary is not modified.

    - With -PATCH option, loadp2 uses its "mainloader" code to configure the prop2 clock frequency and patches the prop2 binary in loadp2 memory before downloading as 8-bit binary. This downloads faster than -SINGLE.

    - Without either option, loadp2 uses its "mainloader" code, programs the prop2 clock frequency, but leaves the binary untouched. This is the original method that's proven unreliable.

    The three loading methods are -CHIP, -FPGA and -SINGLE. -CHIP and -FPGA use a secondary loader, and are used to load either into the silicon chip or the FPGA. -CHIP and -FPGA will also setup the clock frequency.

    -SINGLE does not use a secondary loader, and it does not change the clock frequency.

    -PATCH is use to patch locations $14, $18 and $1C with the clock frequency, clock mode and user baud rate. These locations will not be changed if -PATCH is not specified.
  • Cluso99Cluso99 Posts: 18,066
    Dave Hein wrote: »
    evanh wrote: »
    At the moment, I think loadp2 has three handover methods depending on the -SINGLE and -PATCH options:

    - With -SINGLE option, loadp2 downloads the prop2 binary as Prop_Hex ROM routine, so is effectively using the RCFAST handover then. The binary is not modified.

    - With -PATCH option, loadp2 uses its "mainloader" code to configure the prop2 clock frequency and patches the prop2 binary in loadp2 memory before downloading as 8-bit binary. This downloads faster than -SINGLE.

    - Without either option, loadp2 uses its "mainloader" code, programs the prop2 clock frequency, but leaves the binary untouched. This is the original method that's proven unreliable.

    The three loading methods are -CHIP, -FPGA and -SINGLE. -CHIP and -FPGA use a secondary loader, and are used to load either into the silicon chip or the FPGA. -CHIP and -FPGA will also setup the clock frequency.

    -SINGLE does not use a secondary loader, and it does not change the clock frequency.

    -PATCH is use to patch locations $14, $18 and $1C with the clock frequency, clock mode and user baud rate. These locations will not be changed if -PATCH is not specified.

    Thanks for the enlightenment on the $1C baud location. I was setting baud at $10 and bitper at $1C so I'll fix that.

    BTW it's baud not baud rate even tho it sounds better. Something that was ingrained into me in the 70's :wink:
  • Cluso99Cluso99 Posts: 18,066
    latest version (007)...
    * store BAUD in hub $1C
    * locals bitper,clkfreq,clkmode,baud --> bitperx,clkfreqx,clkmodex,baudx
  • Adding further to detecting boards, here's one for Rev A/B silicon detect.
    'Silicon Rev A/B detect
    
    dat	org
    
    	getscp	pa	'save current scope mode
    	mov	pb,pa
    	add	pb,#1
    	setscp	pb	'change scope mode
    	getscp	pb	'read back scope mode
    	setscp	pa	'restore scope mode
    
    	cmp	pa,pb wz
    	drvnz	#56	'no match = Rev B silicon
    	jmp	#$
    
  • Cluso99Cluso99 Posts: 18,066
    There is an id in the chip.

    First silicon is "A" which is the same for Prop123-A9 / BeMicro-A9, 8 cogs, 64 smart pins
    Second silicon is "G"

    Here are strings that may also be checked...
    first silicon
    fc260 14d 72500a0d text_ver byte 13,10,"Prop_Ver ",ver,13,10,0,0
    fd014 4d2d3250 _str_vers byte "P2-MONITOR V1.0",$0D,$0A,0

    second silicon
    fc260 14d 72500a0d text_ver byte 13,10,"Prop_Ver ",ver,13,10,0,0
    fd014 4d2d3250 _str_vers byte "P2-MONITOR V1.3",$0D,$0A,0

    Don't forget these are copied from ROM into the top of hub so they can subsequently be overwritten!
    Note the Monitor & Serial driver in ROM uses (ie overwrites once invoked) the first 80 bytes from $FC000.
  • evanhevanh Posts: 15,126
    Cluso,
    I thought you'd have the that bug sorted in AutoDetect-007.
  • Cluso99Cluso99 Posts: 18,066
    evanh wrote: »
    Cluso,
    I thought you'd have the that bug sorted in AutoDetect-007.
    Not sure what you think is wrong???
  • evanhevanh Posts: 15,126
    Hmm, only the entire conversation yesterday - You are using prior-mode handover but not completely.
  • evanhevanh Posts: 15,126
    With loadp2, you've got a choice of two options:
    -SINGLE for RCFAST handover, or
    -PATCH for prior-mode handover.

    Loadp2's old method is only reliable with the FPGAs, since they don't have the PLL select flaw, so you shouldn't be using that option with the real chips. It will only cause future grief.

Sign In or Register to comment.