Clockfreq, clockmode and others: Agreement for what and where

in Propeller 2
What is the agreement for the placement of clockfreq and clockmode in HUB RAM?
IIRC it was $14 and $18? Which is which, what is the format, and what are the labels?
Perhaps this should be in the tricks and traps thread too???
IIRC it was $14 and $18? Which is which, what is the format, and what are the labels?
Perhaps this should be in the tricks and traps thread too???
Comments
2nd!
$10: reserved $14: clock frequency (integer, in Hz) $18: clock mode (integer, bottom 2 bits set to 0) $1c: serial baud rate (integer, e.g. 115200)
The long at $1c (baud rate) is optional, it's just $14 and $18 that are absolutely required for setting the clock.The need is because there's a hardware bug which can cause a lock-up if you change the clock mode. There is a work-around but it requires knowing the current clock mode. The tricks and traps thread has more details.
(Knowing the current clock frequency is also pretty useful for programs, and having it in a common location makes it possible for PASM code to get it easily.)
I've posted my code which I believe has been used by others to setup the xtal initially. Here I have already used _clockfreq and _baud, so I'd prefer something else, although it's not too late to change.
Is _CLOCKMODE set to the value of _SETFREQ below?
CON ' hub address ' _RESERVED = $0_0010 ' reserved _CLKFRQ = $0_0014 ' clock frequency (integer, in Hz) _CLKMODE = $0_0018 ' clock mode (integer, bottom 2 bits set to 0) _SERBAUD = 115_200 ' serial baud (integer, e.g. 115200)
Postedit: changed above to be _clkfreq, _clkmode, _serbaudHere is how I set the clock, etc
'+-------[ Select for P2-EVAL ]------------------------------------------------+ ' _XTALFREQ = 20_000_000 ' crystal frequency ' _XDIV = 2 '\ '\ crystal divider to give 10.0MHz ' _XMUL = 15 '| 150 MHz '| crystal / div * mul to give 150MHz ' _XDIVP = 1 '/ '/ crystal / div * mul /divp to give 150MHz ' _XOSC = %10 '15pF ' %00=OFF, %01=OSC, %10=15pF, %11=30pF '+-------[ Select for P2D2 ]---------------------------------------------------+ _XTALFREQ = 12_000_000 ' crystal frequency _XDIV = 4 '\ '\ crystal divider to give 3.0MHz _XMUL = 99 '| 148.5MHz '| crystal / div * mul to give 297.0MHz _XDIVP = 2 '/ '/ crystal / div * mul /divp to give 148.5MHz _XOSC = %01 'OSC ' %00=OFF, %01=OSC, %10=15pF, %11=30pF '+-----------------------------------------------------------------------------+ _XSEL = %11 'XI+PLL ' %00=rcfast(20+MHz), %01=rcslow(~20KHz), %10=XI(5ms), %11=XI+PLL(10ms) _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 _ENAFREQ = _SETFREQ + _XSEL ' %0000_000e_dddddd_mmmmmmmmmm_pppp_cc_ss ' enable oscillator _1us = _clockfreq/1_000_000 ' 1us '------------------------------------------------------------------------------------------------ ' _baud = 115_200 _baud = 230_400 _bitper = (_clockfreq / _baud) << 16 + 7 ' 115200 baud, 8 bits _txmode = %0000_0000_000_0000000000000_01_11110_0 'async tx mode, output enabled for smart output _rxmode = %0000_0000_000_0000000000000_00_11111_0 'async rx mode, input enabled for smart input '------------------------------------------------------------------------------------------------ rx_pin = 63 ' pin serial receiver tx_pin = 62 ' pin serial transmitter spi_cs = 61 ' pin SPI memory select (also sd_ck) spi_ck = 60 ' pin SPI memory clock (also sd_cs) spi_di = 59 ' pin SPI memory data in (also sd_di) spi_do = 58 ' pin SPI memory data out (also sd_do) '------------------------------------------------------------------------------------------------ DAT orgh 0 org 0 '+-------[ Set Xtal ]----------------------------------------------------------+ entry hubset #0 ' set 20MHz+ mode hubset ##_SETFREQ ' setup oscillator waitx ##20_000_000/100 ' ~10ms hubset ##_ENAFREQ ' enable oscillator '+-----------------------------------------------------------------------------+ waitx ##_clockfreq*5 ' just a delay to get pc terminal running ''-------[ Start Serial ]------------------------------------------------------ mov lmm_bufad, ##_HUBBUF ' locn of hub buffer for serial routine mov lmm_x, ##_bitper ' sets serial baud call #_SerialInit ' initialise serial
BTW It is baud, not baud rate. The definition of baud inherently means rate.
'=============================================================================================================== ' Initialisation code (gets copied to cog and run)... '=============================================================================================================== orgh 0 org 0 ''+-------[ Set Xtal ]---------------------------------------------------------+ init_entry hubset #0 ' set 20MHz+ mode hubset ##_SETFREQ ' setup oscillator waitx ##20_000_000/100 ' ~10ms hubset ##_ENAFREQ ' enable oscillator setq #3-1 '\ copy clkfreq/clockmode/serialbaud wrlong __clkfreq, #$14 '/ to hub $14/$18/$1C ''+----------------------------------------------------------------------------+ ..... ..... __clkfreq long _CLOCKFREQ __clkmode long _SETFREQ __serbaud long _BAUD
Using the RCFAST handover workaround will be fine without the first HUBSET instruction.
Using the reserved mailboxes workaround needs to actually use the prior clkmode value at the very least.
The above code is loaded by fastspin/spingui or pnut. The loader overwrites any value that may have been saved in hub $14-$18 so my code above cannot possibly know what the previous xtal mode was.
BTW I have never found a problem with this method. Perhaps that is because the same clock modes are being set as previously set???
The RCFAST handover workaround would involve the convention of the loader always changing back to RCFAST before COGINITing the loaded program. eg:
... andn clkmode, #3 'disable XI+PLL mode hubset clkmode 'switch to RCFAST mode hubset #0 'turn off all crystal/PLL modes waitx ##20_000_000/100 'wait 10 ms for crystal shutdown coginit #0,address 'launch cog 0 from address
The reserved mailbox workaround method can be found in the tricks and traps - https://forums.parallax.com/discussion/comment/1466702/#Comment_1466702
The way I've been doing it is to have my binary laid out so that $14-$18 contains 0 for the clock mode and 22000000 for frequency (or some other approximation to what RCFAST is). The clock frequency changing mode looks like:
pri clkset(mode, freq, xsel = 3) | oldmode oldmode := CLKMODE & !3 ' remove low bits, if any; this is paranoia, normally they should be clear mode := mode & !3 ' more paranoia CLKFREQ := freq ' save new frequency CLKMODE := mode ' save new mode asm hubset oldmode ' go to RCFAST using known prior mode hubset mode ' setup for new mode, still RCFAST waitx ##20_000_000/100 ' wait ~10ms add mode, xsel hubset mode ' activate new mode endasm
This is only ever an issue if you're changing from something other than RCFAST. If you use the ROM loader then it ends up in RCFAST so there's no problem. But loadp2's fast two-stage loader may leave the chip in a different frequency, and of course if you change mid-program then you have to use this sequence as well.
Ah, thanks. I see Chip had the same concerns with using $14 and $18 as I do. A shame. However, if Spin uses them, so will Catalina.
At least its all soft.