PropBasic: Launch program in ram
VonSzarvas
Posts: 3,522
Hello!
Have been experimenting with a self-executing program, but am failing to understand the launch code (chip's code).
There is a valid eeprom image stored in the upper part of a 64kB eeprom at pins 28/29 ($8000 - $FFFF)
I tested the image by launching it with a spin loader from the obex.
The plan is to launch this eeprom image using PropBasic, or inline pasm.
I added the following code at the end of the PropBasic file:
My code file copies the image from eeprom to ram, then does a "GOTO launch" to run the above code. I tested the image in ram after copying it... It can read it back and write it to PST, and all the bytes seem to match the original code.eeprom file.
-- I suspect the problem is with the copy/pasted launch code. Regrettably I do not really understand it all!!. So my question would be...:
Q: Should this snippet of inline ASM code actually work, or is something seriously wrong with this approach ?
Ultimately I would like to be able to call a simple PropBasic command to restart the propeller running whatever code is in ram. Ie. (A kind of soft reboot!)
(A few months ago Bean told that this might be tough to implement... Some months on I am not ready to admit defeat, but I am feeling he was right!)
Have been experimenting with a self-executing program, but am failing to understand the launch code (chip's code).
There is a valid eeprom image stored in the upper part of a 64kB eeprom at pins 28/29 ($8000 - $FFFF)
I tested the image by launching it with a spin loader from the obex.
The plan is to launch this eeprom image using PropBasic, or inline pasm.
I added the following code at the end of the PropBasic file:
tmpAddr long smode CON 0 time_xtal CON 100000 ' 20 * 20000 / 4 / 1 '20ms (@20MHz, 1 inst/loop) interpreter CON $43C010 ' $0001 << 18 + $3C01 << 4 + %0000 ASM ' ' Launch program in ram ' launch mov tmpAddr,#0 'set tmpAddr to zero rdword tmpAddr,#$0004+2 'if pbase address invalid, shutdown cmp tmpAddr,#$0010 wz if_nz jmp #shutdown rdbyte tmpAddr,#$0004 'if xtal/pll enabled, start up now and tmpAddr,#$F8 '..while remaining in rcfast mode clkset tmpAddr :delay djnz time_xtal,#:delay 'allow 20ms @20MHz for xtal/pll to settle rdbyte tmpAddr,#$0004 'switch to selected clock clkset tmpAddr coginit interpreter 'reboot cog with interpreter ' ' ' Shutdown ' shutdown nop ' mov ee_jmp,#0 'deselect eeprom (replace jmp with nop) :call nop ' call #ee_stop '(always returns) ' cmp smode,#0 wz 'if serial mode, send error (z=0) 'if_nz mov smode,#0 '(only do once) 'if_nz mov :call,#0 '(replace call with nop) 'if_nz call #tx_bit_align '(may return to shutdown, no problem) mov dira,#0 'cancel any outputs mov smode,#$02 'stop clock clkset smode '(suspend until reset) ENDASM
My code file copies the image from eeprom to ram, then does a "GOTO launch" to run the above code. I tested the image in ram after copying it... It can read it back and write it to PST, and all the bytes seem to match the original code.eeprom file.
-- I suspect the problem is with the copy/pasted launch code. Regrettably I do not really understand it all!!. So my question would be...:
Q: Should this snippet of inline ASM code actually work, or is something seriously wrong with this approach ?
Ultimately I would like to be able to call a simple PropBasic command to restart the propeller running whatever code is in ram. Ie. (A kind of soft reboot!)
(A few months ago Bean told that this might be tough to implement... Some months on I am not ready to admit defeat, but I am feeling he was right!)
Comments
Jeff T.
I am a little concerned about: Not certain that it actually moves the propbasic defined long array into the asm address- and in the correct format, and not sure yet how to test that in pasm.
At the moment I call the task like this from the main program (cog0):
Cog0 does seem to immediately stop as my status leds driven from the main cog program go off. But then it hangs.
Maybe I should not be launching a cog into cog0 from cog0? I tried an intermediate cog1 which simply stopped the first cog0 and launched the new cog0, but that did not seem to help.
If I run the obex bootloader (spin code), it correctly runs the image I have stored in the upper eeprom- so I believe that part is ok.
... another day of probing begins !
taskparam(1) should =0 which is the default EEPROM that comes with the Prop boards
taskparam(2) should =$8000 which is the location in memory that you want your read to begin
Jeff T.
I am using a PPDB and have changed the supplied eeprom to a 64kB version, 24FC512
So I have the params set as you noted above (pin, chipaddress, eeprommem) = (28, 0, $8000).
Thanks for your help- I am struggling to debug this! I am currently trying to craft some simple ASM to write bytes to the attached (via usb) onboard PST. I hope that would at least help me discover when the program dies by sending a byte at various points in the code and "seeing" where the code gets to.
This is what Jeff ("Hi!") referred to a few posts up:
taskparam(1) is equivalent to chip address, taskparam(2) is memory start
Sorry, I had reversed them a couple times whilst testing. I have set them back to the following, but still no joy.
(I have updated the files attached to post 7.)
--
I did notice something which may or maynot be an issue... to do with the timings.
and
I was running the code at 80MHz, not 20 MHz as is assumed by the time_xtal formula
I tried changing to PLL4X, and also adjusting the time_xtal delay to make it 20ms at 80MHz, but it did not seem to make a difference.
Not sure if the bootloader operation is timing critical...???
I just checked again the original code from unsoundcode (post #2.)
the only difference seems to be that he calls the coginit (starts the task) like this
Could the clkset be vital here? I don't seem to be able to handle that with PropBasic, but maybe there is a PASM alternative?
http://forums.parallax.com/showthread.php?122326-CLKSET-in-ASM&p=905516&viewfull=1#post905516
It does not solve the matter, but surely it proves the frequency is now set the same as the original program.
Also I changed 2 lines thus, to "ensure / hope" the pin_num setting is correct
I have added some extra led flashes through the code. The codes executes until this block, but hangs at [ call #ee_read ] - so an led before this line flashes, but not after. It might be a PIN issue yet... Is it possible somewhere between PropBasic and PASM, the PIN is not being defined or init'd correctly? How would I do that in PASM?
I have found the problematic code here
It would seem the code loops until it gives-up and does the jmp #shutdown.
The RCFAST settings seem to make no difference either.
I have attached revised version of the code to reflect all the adjustments.
I have attempted to implement the same parameter loading as Jeff used, and set the clk to RCFAST, so in theory everything "should" be exactly the same (except for the compiler of course).
time for a little gardening / head recharging!
mask_sda long $2
mask_scl long $1
pin_num long $1C
mem_start long $8000
chip_address long 0
cs_write long $A0
cs_read long $A1
you could also try deleting the following lines from the "boot" label they are probably not needed in you app
cmp count,first_byte wz 'calculate the file length
if_z mov low_byte,eedata 'from the word value in
cmp count,second_byte wz 'bytes at address $0008 and $0009
if_z call #getcount
Jeff T.
When PropBasic creates the spin file, it starts with something like this:
By manually inserting a clkset, the problem was solved.
Maybe an advanced option of the PropBasic COGINIT command might allow a parameter for setting the clkspeed of the new cog.
Or maybe I can work around this somehow... I already tried changing the clk when the new task starts without success., but maybe I just need to twiddle with some delays...
Will report back!
So here is a work around.... No need for the manual clkset edit of the spin file
Just ensure this appears at the start of the task. I found that not only should we set the clock speed, but also zero the pin registers. I believe it might be an issue with the PropBasic compiler which could be easily solved, so I will post an explanation on the PropBasic thread.
Again, BIG BIG thanks for your persistence - it feels really good to crack this nut !
Max.
Jeff T.