What was really interesting when migrating to EEWORDS was coming up with a simple indexing/hashing method that would return with a 6-bit index rather than the 7-bit I used in SDWORDS. Previously I used part of the count and the first character to form an index to tell the search system which "sector" to look in where matching words were stored (reducing the search dramatically) and this worked quite well but I wasn't sure it would distribute as well with only half the number of sectors, which it didn't once the dictionary grew too much. So instead I used part of the count and instead of the first character I simply added up all the characters together and used the lower 4-bits along with 2 bits from the count to form an index.
How well does that work? Well on a full dictionary I can see that there are no sectors that even use up half of their 512 bytes so that means it's quite possible to reduce the eeprom sector size down to 256. That's only 16kB which is only a little more than the original dictionary in RAM, quite surprising I thought.
BTW, this is without reclaiming private headers, I just leave them all in the dictionary.
Here is the sector dump from eeprom: (some IP config data at $FF00)
What was really interesting when migrating to EEWORDS was coming up with a simple indexing/hashing method that would return with a 6-bit index rather than the 7-bit I used in SDWORDS. Previously I used part of the count and the first character to form an index to tell the search system which "sector" to look in where matching words were stored (reducing the search dramatically) and this worked quite well but I wasn't sure it would distribute as well with only half the number of sectors, which it didn't once the dictionary grew too much. So instead I used part of the count and instead of the first character I simply added up all the characters together and used the lower 4-bits along with 2 bits from the count to form an index.
How well does that work? Well on a full dictionary I can see that there are no sectors that even use up half of their 512 bytes so that means it's quite possible to reduce the eeprom sector size down to 256. That's only 16kB which is only a little more than the original dictionary in RAM, quite surprising I thought.
BTW, this is without reclaiming private headers, I just leave them all in the dictionary.
Here is the sector dump from eeprom: (some IP config data at $FF00)
Peter,
Here is my routine to program the EEPROM (lower or upper, or in fact anywhere on a page boundary) from my PropOS.
Should be easy for you to modify to what you require.
The forum is broken so here is the source code pasted. It uses the I2C driver - do you require that too?
'' +--------------------------------------------------------------------------+'' | Cluso's Propeller Operating System - OS module: _EEPROM --> _EEPROM.CMD |'' +--------------------------------------------------------------------------+'' | Authors: (c)2012,2013 "Cluso99" (Ray Rodrick) |'' | Modifications: |'' | License: MIT License - See end of file for terms of use |'' +--------------------------------------------------------------------------+'' Each module is called from, and returns to, the prop binary "_CMD.CMD"'' This OS module uses an included module "__MODULE.SPIN" to perform most of'' the housekeeping - see this for history, details and acknowledgements.'''' This module......'' Copies an SD File "<filename>.EEP" to the EEPROM (lower or upper 32KB of 64KB)'''' RR20130724 start'''''#include "__MODULE.spin" ' include the common code for OS modules #include"__MODULE.spin"CON
PAGESIZE = 32'eeprom pagesize
MAXPGMSIZE = 16*1024'max program size to be placed into eeprom !!!OBJ
i2c : "Basic_I2C_Driver"' eeprom routinesVARbyte filename0[13] ' FAT source filename (string)byte fname0[13] ' filename w/o dotbyte param[13] ' options: -WL, -WUlong e_offset ' eeprom offsetlong hardware ' hw def & pinslong DO, CLK, DI, CS, SI, SO
byte Mounted
long ioControl[2] '\\long i0Control_sector '// sdspiFemto passes ioControl[3] ==> sd sector no long fbase ' SD first sectorlong fsize ' SD filesize'--------------- buffer for eeprom 16KB!!! --------------------------long ndx ' index of chars in pgmbuff 0..16K-1byte pgmbuff[MAXPGMSIZE] ' buffer for program to be copied to eeprom (16KB max!!!)DAT
_ModuleStr byte"=== COPY ===",0'module's name (string)PRIexecuteCommand(stringPointer) | sector[512], errorString, bytes, n, r'get the parameters
str.stringCopy(@filename0, str.tokenizeString(0)) ' source filename
str.stringCopy(@param, str.tokenizeString(0)) ' optionsifstrsize(@filename0) == 0' if no parameters, display usage
printStringCR(string(" Program an SD file to lower/upper EEPROM..."))
printStringCR(string(" PROGRAM <source_filename> [-WL][-WU]"))
return0'------------------------------------------------------------------------------' ensure file exists and is 32KB
errorString := \fat.openfile(@filename0, "R") ' open source file
checkError(@filename0, fat.partitionError, errorString) ' if error, display & abort
fsize := fat.fileSize ' get sizeif fsize <> 32768
printString(string("t) File size "))
printString(str.integerToDecimal(fsize,8))
printStringCR(string(" - must be 32KB"))
crlf
abort -2' validateParams ' validate the params
param[1] := param[1] & $DF' simple convert to uppercase
param[2] := param[2] & $DF' simple convert to uppercaseif ((param[0] == "-") and (param[1] == "W") and (param[2] == "L"))
e_offset := $0000elseif ((param[0] == "-") and (param[1] == "W") and (param[2] == "U"))
e_offset := $8000else
checkError(string(" parameter error"), $F0, @param) ' if error, display & abort'------------------------------------------------------------------------------
printString(string("i) Program "))
printString(@filename0)
printString(string(" to EEPROM "))
if e_offset == 0
printStringCR(string("Lower 32KB"))
else
printStringCR(string("Upper 32KB"))
'------------------------------------------------------------------------------
r := \Program32KB(@filename0) ' get file & program to eepromif r == 0
printString(string(" Eeprom programmed successfully"))
crlf
else
printString(string("*** Programming Failed *** code "))
printString(str.integerToDecimal(r,3))
crlf
abort -1'-----------------------------------------------------------------' Close up
fat.closeFile
printStringCR(string("i) EEPROM written."))
return0'------------------------------------------------------------------------------PriProgram32KB(st) | r' Program the EEPROM from file{{
bytes := \fat.readData(@sector, 64) ' if good, returns the byte count
checkError(@filename0, fat.partitionError, bytes) ' if error, display & abort
}}
r := FindFile(st) ' eeprom file present?' program eeprom lower 16KB
r := LoadFile16KB ' load lower 16KB of file
DisplayBuffer(e_offset + $0000)
printString(string(" Programming first 16KB block..."))
printString(str.integerToHexadecimal(ndx,8))
crlf
r := ProgramEeprom(e_offset + $0000) ' program lower eeprom from buffer
printString(string(" Programmed first 16KB block"))
crlf
bytefill(@pgmbuff, $00, MAXPGMSIZE) ' clear the buffer
r := LoadEeprom(e_offset + $0000) ' readback lower eeprom
DisplayBuffer(e_offset + $0000)
' verify eeprom_lo
r := FindFile(st) ' eeprom file
printString(string(" Verifying first 16KB block..."))
crlf
r := VerifyFile16KB(e_offset + $0000) ' verify lower 16KB of file
printString(string(" Verified first 16KB block"))
crlf
' program eeprom upper 16KB (file already points to start of second 16KB)' bytefill(@pgmbuff, $00, MAXPGMSIZE) ' clear the buffer
r := LoadFile16KB ' load upper 16KB of file
DisplayBuffer(e_offset + $4000)
printString(string(" Programming second 16KB block..."))
printString(str.integerToHexadecimal(ndx,8))
crlf
r := ProgramEeprom(e_offset + $4000) ' program upper eeprom from buffer
printString(string(" Programmed second 16KB block"))
crlf
'now we need to reposition the file at the upper 16KB block
r := FindFile(st) ' eeprom file
r := LoadFile16KB ' load(skip) lower 16KB of filebytefill(@pgmbuff, $00, MAXPGMSIZE) ' clear the buffer
printString(string(" Verifying second 16KB block..."))
crlf
r := LoadEeprom(e_offset + $4000) ' readback second 16KB from eeprom
DisplayBuffer(e_offset + $4000)
' verify eeprom_hi
r := VerifyFile16KB(e_offset + $4000) ' verify 16KB of file
printString(string(" Verified second 16KB block"))
crlf
PRIFindFile(st) | errorString, r
printString(string(" Locating "))
printStringCR(st)
' r := fsrw.popen(st,"r") 'Open file for read ' Open the FAT source file
errorString := \fat.openfile(st, "R") ' open source file
checkError(st, fat.partitionError, errorString) ' if error, display & abortPriLoadFile16KB | r' Load a 16KB block from file
ndx~
repeatwhile ndx < MAXPGMSIZE
' r := fsrw.pgetc ' read a byte at a time from the file
r := fat.readByte
if r < 0
printString(string("t) File error"))
crlf
abort -3else
pgmbuff[ndx++] := r ' save bytes to bufferreturn0PriVerifyFile16KB(offset) | r' Verify 16KB block of file
ndx~
repeatwhile ndx < MAXPGMSIZE
' r := fsrw.pgetc ' read a byte at a time from the file
r := fat.readByte
if r < 0
printString(string("t) File error"))
crlf
abort -3elseif r <> pgmbuff[ndx] ' compare bytes
printString(string("t) Verify Error at $"))
printString(str.integerToHexadecimal(ndx+offset,4))
crlf
abort -4
ndx++
return0PriProgramEeprom(offset) | i, start_time'program 16KB to eepromrepeat i from0toconstant(MAXPGMSIZE/PAGESIZE)-1if i2c.WritePage(i2c#BootPin, i2c#EEPROM, offset+(i*PAGESIZE), @pgmbuff[i*PAGESIZE], PAGESIZE)
abort -1'error during write
start_time := cnt'prepare to check for a timeoutrepeatwhile i2c.WriteWait(i2c#BootPin, i2c#EEPROM, offset+(i*PAGESIZE))
ifcnt - start_time > clkfreq / 10abort -2'waited more than 100msPriLoadEeprom(offset) | i'readback 16KB onlyrepeat i from0toconstant(MAXPGMSIZE/PAGESIZE)-1if i2c.ReadPage(i2c#BootPin, i2c#EEPROM, offset+(i*PAGESIZE), @pgmbuff[i*PAGESIZE], PAGESIZE)
abort -1'error during readPRIDisplayBuffer(offset) | r, c, lc[16], w, adx'display first 16KB
w := 16
adx~
ndx~
' repeat while ndx < MAXPGMSIZE' repeat while ndx < (MAXPGMSIZE / 16) '<==== only show 1KBrepeatwhile ndx < (MAXPGMSIZE / 64) '<==== only show 0.25KB' printChar(spc)
printString(str.integerToHexadecimal((adx + offset),4))
printString(string(":"))
c := 0repeatwhile c < w
r := pgmbuff[ndx++] ' get next char
printChar(" ")
printString(str.integerToHexadecimal(r,2))
lc[c] := r
c++
c := 0
printChar(" ")
repeatwhile c < w
r := lc[c]
if r < $20or r > $7E
printChar(".")
else
printChar(r)
c++
adx += w
crlf
dat{{
+------------------------------------------------------------------------------------------------------------------------------+
| TERMS OF USE: MIT License |
+------------------------------------------------------------------------------------------------------------------------------+
|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation |
|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, |
|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software|
|is furnished to do so, subject to the following conditions: |
| |
|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.|
| |
|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE |
|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR |
|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
+------------------------------------------------------------------------------------------------------------------------------+
}}
Okay the changes are comming fast, do you have 1 2 3 procedure to build the new system on say a quickstart?
Yes, the procedure is fairly straightforward now and MJB also has a TeraTerm script for loading the source files automatically. However this is the procedure I use for a new board.
1. Use Spin tool/BST to load the "Spin" kernel to bring the Prop to life.
2. Connect terminal at 230,400 baud and check coms
3. Load (paste or send) P8.SET to set the build required
4. Load EXTEND.FTH
5. Load EEWORDS.FTH (may be included in EXTEND later)
6. Load P8DEFS.FTH to define the P8 hardware (like a header file)
7. Load SDFS (combo of SDCARD and EASYFILE)
8. Run COMPACT
9. Load NET5500.FTH (combo of W5500 plus EASYNET)
10. Optional COMPACT which leaves around 7K free
Quickstart is even easier as there is no SD or Ethernet etc so really it only needs steps 1,2, and 4 and then QS.FTH optionally.
So the serial load could be reduced to P8EXTEND.FTH (combo of P8.SET + EXTEND + EEWORDS + P8DEFS) then SDFS then NET5500. In fact I load the networking source files straight from the SD card since SDFS is in place.
For production I only have to build once and then SAVEROM and use that 64K binary file from my programming Prop which directly loads the EEPROM of the target Prop, so each Prop only takes a couple of seconds to program.
Peter,
Here is my routine to program the EEPROM (lower or upper, or in fact anywhere on a page boundary) from my PropOS.
Should be easy for you to modify to what you require.
The forum is broken so here is the source code pasted. It uses the I2C driver - do you require that too?
Thanks Ray, I was sort of looking for a PC based loader that did it automatically over serial to make it easy for the user if I update a binary. I use a Prop configured as a programmer stick to clone all my boards quickly so the problem really is how does the end user load a new binary that is more than 32k? My kernel is incorporating a bootloader directly into the serial receive driver so that it transparently loads the EEPROM if it detects a valid hex file being loaded, regardless of what the O/S is doing. Of course certain checks need to be made to prevent corruption of the bootloader itself but that's a minor detail. I figure that if I buffer each line of hex and it's ok then I reprogram EEPROM directly then and there or maybe even accumulate a programming page's worth first. The thing is to prevent the startup code from being reprogrammed until the rest of the file has loaded correctly so that the bootloader never loses control. So this means that the user never has to use the Spin tool and then send a hex file through the terminal as well, just sending the file which can be done even from a smartphone is all that is needed.
If the target system is connected to the Ethernet at present I only have to FTP the binary to it and then execute LOADROM which just programs the whole 64k EEPROM from the FIRMWARE.ROM file. For these networked systems I may even make them automatically search for and apply firmware updates if this option is enabled by the user. It's quite a powerful system that's running, and I've still got 7K of RAM left and over four cogs free!
Yes, the procedure is fairly straightforward now and MJB also has a TeraTerm script for loading the source files automatically.
if anybody is interrested - here is the build script I have been using for TeraTerm.
If you set up propellent you can compile and load the spin kernel automatically as well
To confige TeraTerm you need to create a custom ini file with the correct linedelay and baud rate settings.
Here I have a lot of messageboxes active, which you can comment out, when it works for you.
The created log file shows exactly what has been done.
If you want even more diagnostics comment the [~ word in the fth files.
Current pause timings a very conservative.
btw. I save the Google docs documents locally with the google docs time stamp of last change in the name.
This way I can get reproducable builds and know exactly what is in there.
Very important with Peter's lightning speed of change ;-)
' That's all, but to sweep in 500Hz spacings from 37kHz to 42kHz every 50 ms perhaps try this:15 APIN BEGIN 37,0005,000 ADO I HZ 50 ms 500 +LOOP AGAIN
' To lock that into the system so it does it on startup is straightforward:pubJAMMER 15 APIN BEGIN 37000 5000 ADO I HZ 50 ms 500 +LOOP AGAIN ;
AUTORUN JAMMER
But shouldn't it be this?
#15 APIN BEGIN #42,000 #37,000 ADO I HZ #50 ms #500 +LOOP AGAIN
' To lock that into the system so it does it on startup is straightforward:pubJAMMER #15 APIN BEGIN #42,000 #37000 ADO I HZ #50 ms #500 +LOOP AGAIN ;
AUTORUN JAMMER
#s added just for clarification is system is not set to decimal but the ADO bounds
' That's all, but to sweep in 500Hz spacings from 37kHz to 42kHz every 50 ms perhaps try this:15 APIN BEGIN 37,0005,000 ADO I HZ 50 ms 500 +LOOP AGAIN
' To lock that into the system so it does it on startup is straightforward:pubJAMMER 15 APIN BEGIN 37000 5000 ADO I HZ 50 ms 500 +LOOP AGAIN ;
AUTORUN JAMMER
But shouldn't it be this?
#15 APIN BEGIN #42,000 #37,000 ADO I HZ #50 ms #500 +LOOP AGAIN
' To lock that into the system so it does it on startup is straightforward:pubJAMMER #15 APIN BEGIN #42,000 #37000 ADO I HZ #50 ms #500 +LOOP AGAIN ;
AUTORUN JAMMER
#s added just for clarification is system is not set to decimal but the ADO bounds
don't know what you mean ...
from Tachyon.spin
' ADO ( from cnt -- )
...
' DO ( to from -- )
...
and number base default is decimal now, but good to prefix anyhow.
and number base default is decimal now, but good to prefix anyhow.
you are correct, should have check the source!
but from 32500 for 5000 times incrementing by 500 each time we end up with 2,500,000 + 32500 = 2,825,000?
so wouldn't you loop 140 times to increment 32500 to 42500 by increments of 500?
you are correct, should have check the source!
but from 32500 for 5000 times incrementing by 500 each time we end up with 2,500,000 + 32500 = 2,825,000?
so wouldn't you loop 140 times to increment 32500 to 42500 by increments of 500?
? You are confusing me David!
I left the # prefix off just to simplify it as I didn't want to clutter the simple straightforward thing that we know it is but for some reason people are afraid of
So 37,000 5,000 ADO will work the same as 42,000 37,000 DO and if we just used LOOP it would step 1 Hz each time for 5,000 times. Using 500 +LOOP means it jumps 500 at a time so the index would be 37,000 then 37,500 then 38,000 right up to 42,000 when +LOOP detects that boundary of 42,000 has been reached or crossed so it terminates the loop.
ADO grew out a distatse for those traditional Forth DO LOOP parameters and the use of BOUNDS at times to convert to that format. It was more efficient and looked cleaner when I combined the BOUNDS DO into a simple clean operation. I didn't know what to name it at the time and didn't want to make much "ado" about such a little thing so it was named ADO and it stuck!
you are correct, should have check the source!
but from 32500 for 5000 times incrementing by 500 each time we end up with 2,500,000 + 32500 = 2,825,000?
so wouldn't you loop 140 times to increment 32500 to 42500 by increments of 500?
15 APIN BEGIN 37,0005,000 ADO I HZ 50 ms 500 +LOOP AGAIN
the loop is taken only 10 times
start is 37000
end is start + 5000
step is 500
I left the # prefix off just to simplify it as I didn't want to clutter the simple straightforward thing that we know it is but for some reason people are afraid of
So 37,000 5,000 ADO will work the same as 42,000 37,000 DO and if we just used LOOP it would step 1 Hz each time for 5,000 times. Using 500 +LOOP means it jumps 500 at a time so the index would be 37,000 then 37,500 then 38,000 right up to 42,000 when +LOOP detects that boundary of 42,000 has been reached or crossed so it terminates the loop.
ADO grew out a distatse for those traditional Forth DO LOOP parameters and the use of BOUNDS at times to convert to that format. It was more efficient and looked cleaner when I combined the BOUNDS DO into a simple clean operation. I didn't know what to name it at the time and didn't want to make much "ado" about such a little thing so it was named ADO and it stuck!
woah how does the syntax below know it crossed 42,000?
pub JAMMER 15 APIN BEGIN 370005000 ADO I HZ 50 ms 500 +LOOP AGAIN ;
woah how does the syntax below know it crossed 42,000?
pub JAMMER 15 APIN BEGIN 370005000 ADO I HZ 50 ms 500 +LOOP AGAIN ;
completely understand DO
with Tachyon reading the code helps in such cases ... ;-)
' ADO = BOUNDS DO - just a quick and direct way as BOUNDS is most often never used elsewhere ' ADO ( from cnt -- )
ADO mov X,tos+1add tos+1,tos
mov tos,X
' DO ( to from -- )
DO call #_PUSHLP ' PUSH index onto loop stack
the params are simply converted and then DO is used
woah how does the syntax below know it crossed 42,000?
pub JAMMER 15 APIN BEGIN 370005000 ADO I HZ 50 ms 500 +LOOP AGAIN ;
completely understand DO
Forth <> syntax
Have a look at LOOP an +LOOP in the kernel source, it detects it crossing each time it executes a loop. That's also why you can manipulate the loop stack parameters with words such as LEAVE which will simply set the index to the value of the limit, when LOOP comes around it checks and says "I'm done for the day" and exits the loop.
' (+loop) ( n1 -- ) adds n1 to the loop index and branches back if not equal to the loop limit
PLOOP jmpret POPX_ret,pDELTA wc' DELTA calls POPX (code cramming)' The comparison above is between the call insn (wr) at DELTA and the jump insn (nr) at POPX_ret,' this will alwaye be carry set. The call itself is indirect.' 400ns execution time including bytecode read and execute
LOOP if_ncmov X,#1' default loop increment of 1add loopstk+1,X ' increment indexcmps loopstk,loopstk+1wz,wc
BRANCH if_amov IP,branchstk ' Branch to the address that is saved in branchif_ajmp unext
jmpret LPOPX_ret,forNEXT+1wc' discard top of loop index stack' then next loop and its branch address
Have a look at LOOP an +LOOP in the kernel source, it detects it crossing each time it executes a loop. That's also why you can manipulate the loop stack parameters with words such as LEAVE which will simply set the index to the value of the limit, when LOOP comes around it checks and says "I'm done for the day" and exits the loop.
' (+loop) ( n1 -- ) adds n1 to the loop index and branches back if not equal to the loop limit
PLOOP jmpret POPX_ret,pDELTA wc' DELTA calls POPX (code cramming)' The comparison above is between the call insn (wr) at DELTA and the jump insn (nr) at POPX_ret,' this will alwaye be carry set. The call itself is indirect.' 400ns execution time including bytecode read and execute
LOOP if_ncmov X,#1' default loop increment of 1add loopstk+1,X ' increment indexcmps loopstk,loopstk+1wz,wc
BRANCH if_amov IP,branchstk ' Branch to the address that is saved in branchif_ajmp unext
jmpret LPOPX_ret,forNEXT+1wc' discard top of loop index stack' then next loop and its branch address
Got it, thanks for cheer leading me over the learning hump.
Since I developed the compact dictionary in upper EEPROM I haven't had a chance to go back and do new binaries for the Spinneret as most of my work has concentrated on the IoT5500 modules. But the good thing is that all the files are the same except for the Spinneret header file SPINNERET.FTH and of course using the W5100.FTH driver.
To make this a little easier to load the full 64k image I have created a spinneret.binary image which has the SD filesystem but does not have the networking so that it fits in 32K which can be loaded onto the Spinneret with your favorite Prop loader tool.
(make sure you copy the FIRMWARE.ROM file to your Spinneret's microSD)
Once you fire up the Spinneret you can connect your serial terminal at 230,400 and talk to the Forth shell and ask it to load the full 64k networking image into EEPROM by typing LOADROM, then reboot (either REBOOT or ^C or <break>). Once rebooted the Spinneret will automatically launch the network servers for WEB, FTP, and Telnet while still providing an interactive shell over the serial console. You can easily change the IP addresses and even the MAC which BTW is a random 32-bit number on a cold start (new and blank) with a fixed OUI of $02.FF. Here is the response to an ifconfig command (Linux equivalent of ipconfig):
[B]ifconfig[/B]
************ NETWORK STATUS ************
HARDWARE: SPINNERET using WIZnet W5100 (indirect)
SRC IP 192.168.016.150.
MASK 255.255.255.000.
GATEWAY 192.168.016.001.
MAC 02.FF.42.C5.F3.F6.
SKT HH:MM:SS MODE PORT DEST TXRD TXWR RXRD RXWR RXSZ IR STATUS IP ADDR
#015:30:23 TCP 2154923 . . . . . 0014 LISTEN
#115:30:23 TCP 8028777 . . . . . 0014 LISTEN
#215:30:23 TCP 10001 . . . . . 0014 LISTEN
#315:30:23 IPRW 51143024 . .2800. . . A8 10
ok
You can change the IP address via the terminal by typing the IP address in using a & prefix to force the number to "decimal bytes", that is, each group of decimal digits represent one byte.
&192.168.0.14 SIP
To change the gateway:
&192.168.0.254 GATEWAY
To change the port number of the socket which btw is locked in software to a server, so socket 2 is locked to Telnet which actually connects to the Forth shell:
2 SOCKET 23 PORT!
This changes the Telnet port to the standard port 23
All these changes are automatically backed up in the topmost part of the 64k EEPROM and reloaded at network boot.
The Spinneret is online at the moment at tachyonforth.com but you can play with it a bit more using FTP and Chrome at ftp://tachyonforth.com or Telnet to port 10001
(EDIT: looks like my socket reporting is off a bit for some reason on the latest W5100 driver but it everything seems to work, I will fix it up shortly) - FIXED - updated Dropbox
I haven't been able to use Firefox for some time now to ftp to my Tachyon network servers. What happens when it tries to connect is that FIrefox comes up with an alert "200 Type is now I" which is actually the correct response message for a request. However here is a quick text dump from wireshark to see how this became an alert:
No. Time Source Destination Protocol Length Info
2134.225855000192.168.16.2192.168.16.150 FTP 59 Request: PWD
2234.225875000192.168.16.2192.168.16.150 FTP 62 Request: TYPE I
2334.238073000192.168.16.150192.168.16.2 FTP 88 Response: 257"/" is your current location
2434.238266000192.168.16.2192.168.16.150 FTP 60 Request: PASV
2534.249351000192.168.16.150192.168.16.2 FTP 73 Response: 200 TYPE is now I
2634.271760000192.168.16.150192.168.16.2 FTP 114 Response: 227 Entering Passive Mode with port (192,168,16,150,176,5)
2734.271854000192.168.16.2192.168.16.150 TCP 5449121 > ftp [RST, ACK] Seq=74 Ack=302 Win=29200 Len=0
So for some reason FF is sending two requests together (PWD and TYPE I) and when it receives a response for the first request it shoots off a request for PASV while the second response is still on it's way. So when PASV looks for a response it gets the previous response that it hadn't read.
I've tried this with a local NAS and FF doesn't try to send two requests together as perhaps the FEAT response cause it to take a different path. It seems like a FF bug to me but I can't see any mention of it anywhere and although it should be possible for me to process all receive packets and combine the responses before sending it just seems like a kludge to me when all other clients behave.
I haven't been able to use Firefox for some time now to ftp to my Tachyon network servers. What happens when it tries to connect is that FIrefox comes up with an alert "200 Type is now I" which is actually the correct response message for a request.
Any ideas anyone?
I just tried to connect using Firefox and got a popup window with the same error.
I just tried to connect using Firefox and got a popup window with the same error.
I've tested this on Windows, Android, and Linux, same thing. Yet I can connect to a local NAS server and it doesn't try to send TYPE I before it receives the response for PWD:
No. Time Source Destination Protocol Length Info
2214.091912000192.168.16.2192.168.16.19 FTP 71 Request: PWD
2314.092189000192.168.16.19192.168.16.2 FTP 100 Response: 257"/" is your current location
2414.092415000192.168.16.2192.168.16.19 FTP 74 Request: TYPE I
2514.092667000192.168.16.19192.168.16.2 FTP 96 Response: 200 TYPE is now 8-bit binary
2614.092810000192.168.16.2192.168.16.19 FTP 72 Request: PASV
2714.093258000192.168.16.19192.168.16.2 FTP 116 Response: 227 Entering Passive Mode (192,168,16,19,62,227)
the handling of the FEAT OPTS command seems not implemented yet.
so maybe better go with the minimum
211 no Features supported
reply.
fixed in EASYNET.fth
quick fix: just paste the above code into your terminal window. The next FTP request will automatically use the new code.
No rebuild required. then do a BACKUP if you want it permanently in the image.
better even use the following code for now
pub FEAT IMMEDIATE
ON LANLED
autosend C~
PRINT"211no Features supported" CR
autosend C~~ CR
;
the handling of the FEAT OPTS command seems not implemented yet.
so maybe better go with the minimum
211 no Features supported
reply.
fixed in EASYNET.fth
quick fix: just paste the above code into your terminal window. The next FTP request will automatically use the new code.
No rebuild required. then do a BACKUP if you want it permanently in the image.
better even use the following code for now
pub FEAT IMMEDIATE
ON LANLED
autosend C~
PRINT"211no Features supported" CR
autosend C~~ CR
;
Thanks for tracking that one down MJB, it's so sweet not having to sweat over it and still having the problem solved
So there is still a bug with FF as Chrome and other FTP clients work anyway but I will look at the FEAT response in more detail later.
BTW, the code for FEAT can be even simpler, and yes, we only need to paste this code through the console for it to work although I did reload EASYNET as that only took several seconds anyway.
pub FEAT
ON LANLED
PRINT" 211 no Features supported" CR
;
the handling of the FEAT OPTS command seems not implemented yet.
so maybe better go with the minimum
211 no Features supported
reply.
fixed in EASYNET.fth
quick fix: just paste the above code into your terminal window. The next FTP request will automatically use the new code.
No rebuild required. then do a BACKUP if you want it permanently in the image.
better even use the following code for now
pub FEAT IMMEDIATE
ON LANLED
autosend C~
PRINT"211no Features supported" CR
autosend C~~ CR
;
1. Use Spin tool/BST to load the "Spin" kernel to bring the Prop to life.
2. Connect terminal at 230,400 baud and check coms 3. Load (paste or send) P8.SET to set the build required
4. Load EXTEND.FTH
5. Load EEWORDS.FTH (may be included in EXTEND later)
6. Load P8DEFS.FTH to define the P8 hardware (like a header file)
7. Load SDFS (combo of SDCARD and EASYFILE)
8. Run COMPACT
9. Load NET5500.FTH (combo of W5500 plus EASYNET)
10. Optional COMPACT which leaves around 7K free
Renaming these to P8SET.FTH so that extensions are recognized by various clients.
BTW, decided that the HELP: word really needs to be in the form {HELP ............. } as I can insert this into the kernel document to keep the Spin compiler happy, even though I'm not using Spin of course. So this looks like this:
{HELP UM* ( u1 u2 -- u1*u2L u1*u2H )
DESC: unsigned 32bit * 32bit multiply -- 64bit result
TIME: 1..11.8us
}
UMMUL mov R0,tos+1min R0,tos ' max(tos, tos+1)mov R2,tos+1max R2,tos ' min(tos, tos+1)mov R1,#0mov tos,#0' zero resultmov tos+1,#0
UMMULLP shr R2,#1wz,wc' test next bit of u1if_ncjmp #UMMUL1 ' skip if no bit hereadd tos+1,R0 wc' add in shifted u2addx tos,R1 ' carry into upper long
UMMUL1 add R0,R0 wc' shift u2 leftaddx R1,R1 ' carry into 64-bitsif_nzjmp #UMMULLP ' exhausted u1?jmp unext
Which means we can type HELP UM* for the kernel as well as the .FTH files.
As many of you know the bytecode calls in TF are comprised of a single CALL opcode followed by an 8-bit index into a vector table which holds the 16-bit address to the code to call. There are several very good reasons for this and with 4 types of CALLs the system can have up to 1,024 vectors for high-level bytecode words including constants and variables etc. Normally this is more than enough even for a fully loaded SDFS and network system but just to be on the safe side plus MJB needs more to implement his dynamic webpages, I have now fully implemented the CALL16 method which compiles a CALL16 opcode plus the 16-bit address making this a 3-byte call without the need for a vector.
So when a new word is created and TF has run out of spare vectors in the 2K vector table it will compile a header with an attribute that indicates the 2 bytecodes in its header are actually the 16-bit direct address and that to reference this it needs to compile a CALL16 followed by these two bytes. This doesn't make a lot of difference to the code memory consumed because by this time all the important stuff has been compiled and is very compact and any references to words with a CALL16 attribute will automatically compile the correct bytecodes. Of course, all references to opcodes and vectored bytecodes will still compile one or two bytes.
So here is a system with a full EXTEND.fth with all the trimmings along with SDFS and networking, amounting to 1,223 words including 144 opcodes which means there are 1,024 vectored words plus 55 CALL16s. Notice that it has 0 vectors free which is in fact what it had before the EASYNET.fth network server module was loaded. To further test this out I then loaded an application on top of this and it all fits and works.
Do you have to do anything different? NO! You don't even need to force a SMALL EXTEND.fth or use the include filter sets such as P8SET.FTH etc.
wow Peter, this is great news.
Regarding the webserver, I think, that in most webserver applications there is no need for a full PWM32 and some of the other special modules in EXTEND.fth.
So for me it is absolutely fine to selectively load things from EXTEND and have enough space even without the CALL16.
But applications will grow - so good to be prepared.
My JSON writer for example needs 20 words / 278 bytes
I had some instability in my dynamic webserver Spinneret tests so hope to be able to clean this out soon.
As many of you know the bytecode calls in TF are comprised of a single CALL opcode followed by an 8-bit index into a vector table which holds the 16-bit address to the code to call. There are several very good reasons for this and with 4 types of CALLs the system can have up to 1,024 vectors for high-level bytecode words including constants and variables etc. Normally this is more than enough even for a fully loaded SDFS and network system but just to be on the safe side plus MJB needs more to implement his dynamic webpages, I have now fully implemented the CALL16 method which compiles a CALL16 opcode plus the 16-bit address making this a 3-byte call without the need for a vector.
So when a new word is created and TF has run out of spare vectors in the 2K vector table it will compile a header with an attribute that indicates the 2 bytecodes in its header are actually the 16-bit direct address and that to reference this it needs to compile a CALL16 followed by these two bytes. This doesn't make a lot of difference to the code memory consumed because by this time all the important stuff has been compiled and is very compact and any references to words with a CALL16 attribute will automatically compile the correct bytecodes. Of course, all references to opcodes and vectored bytecodes will still compile one or two bytes.
So here is a system with a full EXTEND.fth with all the trimmings along with SDFS and networking, amounting to 1,223 words including 144 opcodes which means there are 1,024 vectored words plus 55 CALL16s. Notice that it has 0 vectors free which is in fact what it had before the EASYNET.fth network server module was loaded. To further test this out I then loaded an application on top of this and it all fits and works.
Do you have to do anything different? NO! You don't even need to force a SMALL EXTEND.fth or use the include filter sets such as P8SET.FTH etc.
Just so I'm clear on this how does COMPACT fit into this? Are the steps for a build different now that CALL16 is alive and well?
My little brain really likes the 1 2 3s as long as I don't run out of fingers I'm happy.
The build still works the same as before except that your code is no longer limited by the number of available vectors, although in practice this takes quite a bit and you may not have gotten anywhere now the limit. What happens is that if you have a fully loaded system with SDFS and NET that before there were only about 80 vectors left over, more than enough for most apps but tight if you perhaps had an assembler loaded which would use a vector for every instruction and mode etc. Now when the system runs out of vectors it will implement the CALL16 method transparently so there is no need to worry about it really. What you won't be able to do with these words is revector them since they don't have a vector, but that's minor.
You can do a full build like this:
F11 the Tachyon kernel
* Load EXTEND.fth (optional CREATE SMALL and/or load an include SET)
* Load EEWORDS.fth
* Load your hardware header such as P8DEFS.fth
* Load SDCARD.fth
* Load EASYNET.fth
At this point it hasn't yet been compacted and I like to save my system to SD with SAVEROM. This makes it easy later on if I want to reload modules as I can easily restore to this point with a LOADROM and reboot without having to start right from the beginning.
* Run COMPACT which will now convert the dictionary in RAM to an indexed list in upper EEPROM and release the RAM space.
* Load W5500.fth or other WIZnet driver
* Load EASYNET.fth after which the system will BACKUP
At this point then the dictionary for the network modules is still in RAM but the earlier stuff has been compacted into the EEPROM. If you don't need a lot more room you can leave it like this or else do an optional COMPACT again which will add the new words to the existing dictionary in EEPROM and release the memory it used in RAM.
* Optional COMPACT if desired.
So out of a total of 32K RAM the system does really well by making practically all of this available for code space with the remainder taken up with various buffers such as 2K for four file buffers etc. There's also no need to worry about reclaiming headers because they don't take up any RAM any more and neither is the dictionary searching speed impacted any appreciable amount.
I'm fixing up WORDS and some other functions now so that they work the same with the EEPROM dictionary as they do with RAM.
is V2.4 YY=15 MM=01 DD=04. Putting it in this format is logical as a new revision/version number will always be a larger number than an old revision as is the YYMMDD which also avoids that American MMDDYY or English DDMMYY confusion thing, both of which are not in logical order especially when compared to HHMM.
Comments
How well does that work? Well on a full dictionary I can see that there are no sectors that even use up half of their 512 bytes so that means it's quite possible to reduce the eeprom sector size down to 256. That's only 16kB which is only a little more than the original dictionary in RAM, quite surprising I thought.
BTW, this is without reclaiming private headers, I just leave them all in the dictionary.
Here is the sector dump from eeprom: (some IP config data at $FF00)
0000.8000: .sDIP.....SKT....HTTP....FEAT....=dtk....sdwr....FILE....SDWR.. 0000.8040: .file..5.DIR!..Q.(ls)..[.WKEY..6.TRUE....LONG....HIGH..8.(op)... 0000.8080: .EERD....+NFA................................................... 0000.80C0: ................................................................ 0000.8100: ................................................................ 0000.8140: ................................................................ 0000.8180: ................................................................ 0000.81C0: ................................................................ 0000.8200: .@mac..s.contimer....(.")..Z.ANDN.<..BOLD....@SCK....FIND....yea 0000.8240: r....WATCHDOG....days........................................... 0000.8280: ................................................................ 0000.82C0: ................................................................ 0000.8300: ................................................................ 0000.8340: ................................................................ 0000.8380: ................................................................ 0000.83C0: ................................................................ 0000.8400: .@gateway..q.SKT@..~.sDISCON?....type....TYPE....MDTM....cwd$... 0000.8440: .HEAD....sdhc....EASYFILE.fth..(.CLUSTER@..@.FREE....[PWM32!]..! 0000.8480: .mod2load....BITS..M.@SCL....COLD....NFA>SECT................... 0000.84C0: ................................................................ 0000.8500: ................................................................ 0000.8540: ................................................................ 0000.8580: ................................................................ 0000.85C0: ................................................................ 0000.8600: .autosend....QUIT....SYST....RNTO....@CMS..;.dir$..A.TASK..r.LEN 0000.8640: $..[..HEX....timerstk........................................... 0000.8680: ................................................................ 0000.86C0: ................................................................ 0000.8700: ................................................................ 0000.8740: ................................................................ 0000.8780: ................................................................ 0000.87C0: ................................................................ 0000.8800: .myGW..f.WR_WCTRL..i.sPRO.....PTR....FlushSkt....GET$....?LED... 0000.8840: .root....udir..\.HERE....here....BYTE.. .TASKREGS....boot....dic 0000.8880: t............................................................... 0000.88C0: ................................................................ 0000.8900: ................................................................ 0000.8940: ................................................................ 0000.8980: ................................................................ 0000.89C0: ................................................................ 0000.8A00: .txwr....ifconfig.....NET....PORT....SDERRLED....ACMD.....ATR..Y 0000.8A40: .(CREATE)....>PFA..C.unum....@PAD..Q.[PLAYER]..#.MYOP..R.DROP... 0000.8A80: .CNT@..C.@CNT....KEEP........................................... 0000.8AC0: ................................................................ 0000.8B00: ................................................................ 0000.8B40: ................................................................ 0000.8B80: ................................................................ 0000.8BC0: ................................................................ 0000.8C00: .&CON..|.skt$....!PCB....FGET..G.STOP....[PRIVATE....DUMP....ESC 0000.8C40: [....TIMEOUT?................................................... 0000.8C80: ................................................................ 0000.8CC0: ................................................................ 0000.8D00: ................................................................ 0000.8D40: ................................................................ 0000.8D80: ................................................................ 0000.8DC0: ................................................................ 0000.8E00: .mySN..g.GETFNAME....PASS...._!SD....@ATR..;.HOLD..R.FILL....PIN 0000.8E40: @..6..MODULES................................................... 0000.8E80: ................................................................ 0000.8EC0: ................................................................ 0000.8F00: ................................................................ 0000.8F40: ................................................................ 0000.8F80: ................................................................ 0000.8FC0: ................................................................ 0000.9000: ..IP1....LEDS....nettimer....RNFR....STOR....?EASYNET....SPLITDE 0000.9040: C..U.UNSMUDGE..|.?DUP....PRIVATE]....PIN!..4.VCLS....(VA)....(FO 0000.9080: RGET).....ASMONTH....term....................................... 0000.90C0: ................................................................ 0000.9100: ................................................................ 0000.9140: ................................................................ 0000.9180: ................................................................ 0000.91C0: ................................................................ 0000.9200: .?FTP....PCB$....SD2@....sect/fat..-..FAT..4.@RCD..N.ELSE..i.COG 0000.9240: @..F.C@++._..KEY@.._.PRINTDEC....HOME........................... 0000.9280: ................................................................ 0000.92C0: ................................................................ 0000.9300: ................................................................ 0000.9340: ................................................................ 0000.9380: ................................................................ 0000.93C0: ................................................................ 0000.9400: .LREADSKT.....SOCKETS....READYLED....PASV....SENDFILE....?CONTEN 0000.9440: T....SDBSYLED....RES@....FREM..F.KOLD.....DEC..^.COG!..L.EXIT... 0000.9480: .LOOP....AVAR....CONSTANT..%.KEY!..`.ESC?..c.REVECTOR........... 0000.94C0: ................................................................ 0000.9500: ................................................................ 0000.9540: ................................................................ 0000.9580: ................................................................ 0000.95C0: ................................................................ 0000.9600: .!WIZ.....IPD....SIZE....SD4@....@FAT..2.FRUN..S.base.....VER..I 0000.9640: .SET?....2DUP....(OPCODE)....SWAP.!..[CON..k.COMPARE$.....LAP... 0000.9680: ................................................................ 0000.96C0: ................................................................ 0000.9700: ................................................................ 0000.9740: ................................................................ 0000.9780: ................................................................ 0000.97C0: ................................................................ 0000.9800: .@sip..r.sCLOSED?....CDUP....LIST....TERMINAL..L.GRAB..O.NFA'..A 0000.9840: .>VEC..B.word..M.SWITCH><....CASE....JUMP....CALL....MASK.P..OVE 0000.9880: R....NOOP....WORD....I2CSTART.....DAY....timerjob....TIMERJOB... 0000.98C0: ..AUTORUN....................................................... 0000.9900: ................................................................ 0000.9940: ................................................................ 0000.9980: ................................................................ 0000.99C0: ................................................................ 0000.9A00: .&TIMEOUT..z.sCONNECT.....@SKTBUF....#CONNECT....RETR....sdrd... 0000.9A40: .SDRD.....DIR..Z.NOTFOUND....CON]..l.PRINTNUM................... 0000.9A80: ................................................................ 0000.9AC0: ................................................................ 0000.9B00: ................................................................ 0000.9B40: ................................................................ 0000.9B80: ................................................................ 0000.9BC0: ................................................................ 0000.9C00: .sSENDMAC.....BYTEDEC....REST....fats..,.DIR?..A.FCREATE$..M.FCR 0000.9C40: C..d.IDLE..s.ukey.....NUM....SARX....MID$....I2C@....date....DAY 0000.9C80: @............................................................... 0000.9CC0: ................................................................ 0000.9D00: ................................................................ 0000.9D40: ................................................................ 0000.9D80: ................................................................ 0000.9DC0: ................................................................ 0000.9E00: .myIP..g.oui2....WAITSEND.....IPX....dataport....USER....XADR..# 0000.9E40: .rsvd..,.>F83..9.fkey..G.FPUT..H.BELL..,.EMIT..*.[WS2812]..&.THE 0000.9E80: N..j.NEXT....ECHO....<CR>..a.I2C!....time....DAY!............... 0000.9EC0: ................................................................ 0000.9F00: ................................................................ 0000.9F40: ................................................................ 0000.9F80: ................................................................ 0000.9FC0: ................................................................ 0000.A000: .?SENDPOLL....&SDDO....@FILE....&sdto....!SDIO....XADR!..#.fat32 0000.A040: ..*.FILE@..C.(DIR)..].ERASE....AGAIN..m.@.f..0....CALL$....TIME! 0000.A080: ................................................................ 0000.A0C0: ................................................................ 0000.A100: ................................................................ 0000.A140: ................................................................ 0000.A180: ................................................................ 0000.A1C0: ................................................................ 0000.A200: .sINTS....sCLOSING?....&WNCS....sdres....SDCLK....FPUTB..H.[COMP 0000.A240: ILE]..~.BCOMP..`.!.r..1....eeadr....TIMER....hours....CountDown. 0000.A280: ................................................................ 0000.A2C0: ................................................................ 0000.A300: ................................................................ 0000.A340: ................................................................ 0000.A380: ................................................................ 0000.A3C0: ................................................................ 0000.A400: .vread..o.sDHAR....sSENDKEEP....ledon....DISCONNECTED?....sddst. 0000.A440: ...FLUSH..".byte/sect..+.fread..D.fstat..E..BYTE....[SSD]....".. 0000.A480: f.SPIRD....2.~..TIMES....EMITS..g..DECX....DUMPL....TASK?....STR 0000.A4C0: IP.............................................................. 0000.A500: ................................................................ 0000.A540: ................................................................ 0000.A580: ................................................................ 0000.A5C0: ................................................................ 0000.A600: .IPRAW....sRECV....user$....&SDCS....FILE#....mount..0.MOUNT..6. 0000.A640: #..V.RESET....3....HELP:....LONGS..".ttint...................... 0000.A680: ................................................................ 0000.A6C0: ................................................................ 0000.A700: ................................................................ 0000.A740: ................................................................ 0000.A780: ................................................................ 0000.A7C0: ................................................................ 0000.A800: .PPPoE....LANCONKEY....SDBUF....@ROOT..1.@BOOT..2.file$..8.FILE$ 0000.A840: ..8.lscnt..[.names....uemit....U/MOD.3..4.}..(NULLOUT)..,.PLAIN. 0000.A880: ...ESAVE....TIMERTASK....cache....FI2C@......................... 0000.A8C0: ................................................................ 0000.A900: ................................................................ 0000.A940: ................................................................ 0000.A980: ................................................................ 0000.A9C0: ................................................................ 0000.AA00: .RETRYTIME..x.sOPEN....@txwr....fsave....&SFCS....BREAK....BEGIN 0000.AA40: ..k.DEPTH....SPIWR....+LOOP....CTYPE..e.(rnd)..v.%..x.lpace....E 0000.AA80: LOAD....FI2C!................................................... 0000.AAC0: ................................................................ 0000.AB00: ................................................................ 0000.AB40: ................................................................ 0000.AB80: ................................................................ 0000.ABC0: ................................................................ 0000.AC00: .&RECV..{.PORT!....!TXWR....LSEND....KEEPALIVE....RCDSZ..M.FLOAD 0000.AC40: ..S.ufind....tasks..t.ENDIF..j.COGID..).month................... 0000.AC80: ................................................................ 0000.ACC0: ................................................................ 0000.AD00: ................................................................ 0000.AD40: ................................................................ 0000.AD80: ................................................................ 0000.ADC0: ................................................................ 0000.AE00: .@FEXT..:.+CALL....'..?.DEBUG....2DROP....BYTES..$.DUMPA.....dif 0000.AE40: f............................................................... 0000.AE80: ................................................................ 0000.AEC0: ................................................................ 0000.AF00: ................................................................ 0000.AF40: ................................................................ 0000.AF80: ................................................................ 0000.AFC0: ................................................................ 0000.B000: .LREAD..p.sMODE....sCMD!....sPORT....QUIET....contd....&WNDI.... 0000.B040: &WINT....=SPIO....FOPEN..L.?AUTOLOAD..e.(....3DROP....8.|..TABLE 0000.B080: ..!.radix..&.RADIX..'.CONIO..*.navar..|.BDUMP....@MOSI....@MISO. 0000.B0C0: ....ATRS....(end)....dboot....(COMPACT)......................... 0000.B100: ................................................................ 0000.B140: ................................................................ 0000.B180: ................................................................ 0000.B1C0: ................................................................ 0000.B200: .WCOLD....?SEND....&WNCK....card?....CARD?....sdstk..'.(cat)..T. 0000.B240: ALLOCATED..u.?EXIT..D.WHILE..h.I....(WAITPNE)....SMALL....modloa 0000.B280: ded../.(SEP).....ADDR....+CHAR....uboot......................... 0000.B2C0: ................................................................ 0000.B300: ................................................................ 0000.B340: ................................................................ 0000.B380: ................................................................ 0000.B3C0: ................................................................ 0000.B400: .UPORT..y.&SDDI....?SPIO....parts..).fboot..6..LIST..`.ERROR.... 0000.B440: AUTO!.....WORD....(KEY)..4.:..x.*....DELTA..@.CMOVE..#.0EXIT.... 0000.B480: ALIAS....PINS@..=.J..D.>CSTR.................................... 0000.B4C0: ................................................................ 0000.B500: ................................................................ 0000.B540: ................................................................ 0000.B580: ................................................................ 0000.B5C0: ................................................................ 0000.B600: .sendtimer....pass$....&SDCK....sdcmd....SDCMD....+DIR!..V.ROMSZ 0000.B640: ..b.lines....delim....{....;..}.+.)..FALSE....LEMIT....K..E.ALIG 0000.B680: N..{.ERSCN....MASK?............................................. 0000.B6C0: ................................................................ 0000.B700: ................................................................ 0000.B740: ................................................................ 0000.B780: ................................................................ 0000.B7C0: ................................................................ 0000.B800: .wctrl..h.WCTRL..i.wMODE..t.RNFR$....STAT@...._SDRD....READFAT32 0000.B840: ..3.ALLOT..t.>CHAR..S.SPACE..+.<....,..d.|..b.\....UNTIL..l.(WAI 0000.B880: TPEQ)....CLOCK.........UPPER..i.(ESC)....EFILL.....DATE......... 0000.B8C0: ................................................................ 0000.B900: ................................................................ 0000.B940: ................................................................ 0000.B980: ................................................................ 0000.B9C0: ................................................................ 0000.BA00: .sSEND....SWAPB....COMMA....getsz....flags....}....=.W..-.(..PRI 0000.BA40: NT..].LEAVE..G.DUMPW....ENDRD....ALARM.....TIME................. 0000.BA80: ................................................................ 0000.BAC0: ................................................................ 0000.BB00: ................................................................ 0000.BB40: ................................................................ 0000.BB80: ................................................................ 0000.BBC0: ................................................................ 0000.BC00: .INTS@..w.&WNDO....FILE>..I.>FILE..J..FILE..a.codes.......]..LON 0000.BC40: G....HDUMP....IFDEF....>.\..~..Y.(BDW)....(COGINIT)....(RECLAIM) 0000.BC80: ....I2C!?....DATE@.............................................. 0000.BCC0: ................................................................ 0000.BD00: ................................................................ 0000.BD40: ................................................................ 0000.BD80: ................................................................ 0000.BDC0: ................................................................ 0000.BE00: .sSTAT....?HTTP....ucard....sdsrc....PROCESS_TOKEN...._SDWR.. .S 0000.BE40: CRUB..;.@HATR....IMMEDIATE....MASKS..>./..t.NULL$....COPY$....LE 0000.BE80: FT$.....NAME....WORDS....TIME@....DATE!......................... 0000.BEC0: ................................................................ 0000.BF00: ................................................................ 0000.BF40: ................................................................ 0000.BF80: ................................................................ 0000.BFC0: ................................................................ 0000.C000: .LANLED....sector....scanch....SECTOR..!.serial....CREATEWORD... 0000.C040: .ms....."..g.(EMIT)..0.R>....>R....>B.U..STREND....RETURN..}.P@. 0000.C080: .2.QWORDS....VirtualRTC....FIXBIN............................... 0000.C0C0: ................................................................ 0000.C100: ................................................................ 0000.C140: ................................................................ 0000.C180: ................................................................ 0000.C1C0: ................................................................ 0000.C200: .vwrite..p.SUBNET..u.sSSIZE....WBUFSZ....FTPMSG....SDCARD.fth... 0000.C240: .sdpins....SDPINS....SDDAT!....fatptr..).@CDATE..<.@FSIZE..?.FSI 0000.C280: ZE@..B.fwrite..D..FILES..a.PRINT$..Y.#>..T..S....U<....REPEAT..n 0000.C2C0: .2/.J..OR.>..P!..3.IX..F.C~..].XY....$=....(EESEARCH)........... 0000.C300: ................................................................ 0000.C340: ................................................................ 0000.C380: ................................................................ 0000.C3C0: ................................................................ 0000.C400: .CONNECTED?....WPWRDN....sdsize....@WRFLG....?MOUNT..7.@CTIME..< 0000.C440: .@FREAD..E..FDATE..X..UTIME..^.prompt....switch....SWITCH....LST 0000.C480: ACK..P.RIGHT$................................................... 0000.C4C0: ................................................................ 0000.C500: ................................................................ 0000.C540: ................................................................ 0000.C580: ................................................................ 0000.C5C0: ................................................................ 0000.C600: .!WIZIO....NETMAN....FTPDAT....un....BUFSIZ....sdinfo....FPRINT. 0000.C640: .T..FTIME..Y.U...\.WITHIN....[SPIO]....TO..v.INPUTS....C@.b..DO. 0000.C680: ...PINSET..8.U>..s.(+COMPACT)................................... 0000.C6C0: ................................................................ 0000.C700: ................................................................ 0000.C740: ................................................................ 0000.C780: ................................................................ 0000.C7C0: ................................................................ 0000.C800: .!WIZIP....LANKEY....@FDATE..>.CREATE....[NFA']..@.create....dig 0000.C840: its....SHRINP....OUTSET....NEGATE.1..U/.5..C!.j..@NAMES....GETRN 0000.C880: D..z.dwidth....ERASE$....timers................................. 0000.C8C0: ................................................................ 0000.C900: ................................................................ 0000.C940: ................................................................ 0000.C980: ................................................................ 0000.C9C0: ................................................................ 0000.CA00: .sINACTIVE?....wrflgs....SDCMD:..'.@FTIME..>.FSECT@..B.FDATE!..V 0000.CA40: ..FYEAR..X..FNAME..^.CR..-.BINARY..0.[SDRD]....RUNMOD....SHROUT. 0000.CA80: ...>W..L.W~..[.U@..~.$!....E@.....BOOTS....(DICT)............... 0000.CAC0: ................................................................ 0000.CB00: ................................................................ 0000.CB40: ................................................................ 0000.CB80: ................................................................ 0000.CBC0: ................................................................ 0000.CC00: .RD..j.RXREAD....GO....diradr..4.FINPUT..I.FTIME!..W.<CMOVE..(.# 0000.CC40: S..W.SEARCH..E.>RADIX..(.RADIX>..).++..S.U!..}..INDEX....VP....W 0000.CC80: WORDS....E!....ESAVEB....BACKUP................................. 0000.CCC0: ................................................................ 0000.CD00: ................................................................ 0000.CD40: ................................................................ 0000.CD80: ................................................................ 0000.CDC0: ................................................................ 0000.CE00: .LWRITE..q.txsize....?CTRLS....SD..&.@FNAME..:.QV..e.[PLOT]..".X 0000.CE40: CALLS....COGREG..J.SPIWRB....W@.d..16.{..IN..7.DS..p.STRING....F 0000.CE80: ORGET........................................................... 0000.CEC0: ................................................................ 0000.CF00: ................................................................ 0000.CF40: ................................................................ 0000.CF80: ................................................................ 0000.CFC0: ................................................................ 0000.D000: .@ports..t.TXREAD....UpdateTXWR....disreq....blklen...._CARD?... 0000.D040: .WRSECT..".X@..$.CLUST>SECT..3.APPEND..P.RENAME..R.[SDWR]....||. 0000.D080: .c.W!.n..INVERT.8..EXTEND.fth....us....PINCLR..9.<<.D..|<.P..QW. 0000.D0C0: ...EEPROM.....EEMOD............................................. 0000.D100: ................................................................ 0000.D140: ................................................................ 0000.D180: ................................................................ 0000.D1C0: ................................................................ 0000.D200: .WR..j.@wcold..s.RETRYS..x.socket..|.SOCKET..}.sCLOSE....(STOR). 0000.D240: ...X!..$.sect/clust..+.RW..Q.NUMBER..K.STACKS..e.CMPSTR....OUTCL 0000.D280: R....[~....WORDS:..#.<=....VC................................... 0000.D2C0: ................................................................ 0000.D300: ................................................................ 0000.D340: ................................................................ 0000.D380: ................................................................ 0000.D3C0: ................................................................ 0000.D400: .CLOSED....LANCONEMIT....ledcnt....DISCONNECT....>UPPER....WRESE 0000.D440: T....sdbusy....sdtask....SDBUSY....LOOKUP..q.<>.WY.SPIRDX....L>. 0000.D480: ...>L....OK....--..T.consav..j.==..q.%%..y.>|....OPCODE....EE... 0000.D4C0: ................................................................ 0000.D500: ................................................................ 0000.D540: ................................................................ 0000.D580: ................................................................ 0000.D5C0: ................................................................ 0000.D600: .MACRAW....txtime....LANCON....fname$..9.FOPEN#..K.FSTAMP..W.[WA 0000.D640: VE]..$.REBOOT....BOUNDS. ..]~....DOUBLE....=>................... 0000.D680: ................................................................ 0000.D6C0: ................................................................ 0000.D700: ................................................................ 0000.D740: ................................................................ 0000.D780: ................................................................ 0000.D7C0: ................................................................ 0000.D800: .L@..o.sDPORT....sRXMEM.....SKTHD....TELNET....dirbuf..5.@FCLST. 0000.D840: .?.FCLOSE..K.FOPEN$..L.0<....IFNDEF....+!.p..>N.T..2*.L..1+.,..S 0000.D880: ETMOD..0.~~..Z.>>.B..second....+TIMER........................... 0000.D8C0: ................................................................ 0000.D900: ................................................................ 0000.D940: ................................................................ 0000.D980: ................................................................ 0000.D9C0: ................................................................ 0000.DA00: .L!..m.LANSKT....C:....?SDTIMEOUT....errors....2+.~).SPIWRX....0 0000.DA40: =.Y..ON....UNLOOP..H.m@....M@.....DTFMT.....STATS....dictwr..... 0000.DA80: ................................................................ 0000.DAC0: ................................................................ 0000.DB00: ................................................................ 0000.DB40: ................................................................ 0000.DB80: ................................................................ 0000.DBC0: ................................................................ 0000.DC00: .sTXMEM....(RETR)....extbuf....(SDRD)....D:....(.DIR)..Z.LOGSZ?. 0000.DC40: ._.[WS2812CL]..'.''....1-.+..BL.z..-1....//....PININP..<.@.....C 0000.DC80: URSOR........................................................... 0000.DCC0: ................................................................ 0000.DD00: ................................................................ 0000.DD40: ................................................................ 0000.DD80: ................................................................ 0000.DDC0: ................................................................ 0000.DE00: .sktbuf....SDERR?....@ADATE..=.APPEND.BLK..P.ls..`.<#..U.>DIGIT. 0000.DE40: .J.C,..b.IF..h.2-.~(.PUBLIC....PRINT"..g.SPACES..f.(.NUM)....ERL 0000.DE80: INE....BLKSIZ................................................... 0000.DEC0: ................................................................ 0000.DF00: ................................................................ 0000.DF40: ................................................................ 0000.DF80: ................................................................ 0000.DFC0: ................................................................ 0000.E000: .LC!..l.UNKNOWN....BYE....blkpoll....GET....cid....?SDCARD..7.>| 0000.E040: RCDSZ..N.(SLIST)..].keypoll....LOADMOD..:.4TH....CON..+.MODULE:. 0000.E080: .1.MOD..u.DPL....mc@....MC@....RAM....(WORDS)................... 0000.E0C0: ................................................................ 0000.E100: ................................................................ 0000.E140: ................................................................ 0000.E180: ................................................................ 0000.E1C0: ................................................................ 0000.E200: .@subnet..r.MAC..v.sESTAB?....SetPORT....#ftpmin....MARKER?....@ 0000.E240: FWRITE..F.baudcnt....[PWM32].. .CLR....-NEGATE....NOT.Y..L>W..N. 0000.E280: W>L..P.W--..V.U.N....tid........................................ 0000.E2C0: ................................................................ 0000.E300: ................................................................ 0000.E340: ................................................................ 0000.E380: ................................................................ 0000.E3C0: ................................................................ 0000.E400: .GATEWAY..u.SKT..}.sLISTEN....SDCARD.TASK..(.oemname..*.volname. 0000.E440: ./.CLS..).SWITCH@....LOW..9.DS+..o.(.MODS)....SCL............... 0000.E480: ................................................................ 0000.E4C0: ................................................................ 0000.E500: ................................................................ 0000.E540: ................................................................ 0000.E580: ................................................................ 0000.E5C0: ................................................................ 0000.E600: .LW@..n.sDISCON....#ftpmax....BLKSEND....netflgs....+P8.fth....s 0000.E640: ectors..-.rootdir..1.-FERASE..O.CONSOLE..M.EXECUTE..G.!RP..-.?NE 0000.E680: GATE./..W+!.l..ROR.H..AND.:..NULLOUT..-.W~~..\.(STRIP).......... 0000.E6C0: ................................................................ 0000.E700: ................................................................ 0000.E740: ................................................................ 0000.E780: ................................................................ 0000.E7C0: ................................................................ 0000.E800: .wizpins..h.LW!..m.ocr....filesel....CMD....@FCLSTH..=.SP!....!S 0000.E840: P....OUTPUTS....ADO....INCLUDE....\\\....MIN..I.RND..w.mw@....MW 0000.E880: @....I2CSTOP....runtime....nfasect.............................. 0000.E8C0: ................................................................ 0000.E900: ................................................................ 0000.E940: ................................................................ 0000.E980: ................................................................ 0000.E9C0: ................................................................ 0000.EA00: .RXSIZE@....RXWRITE....sCONNECTED?....LANSEND....RESTART....PCB. 0000.EA40: ...HEX..2.ROT.%..RUN....LISTKEY....?BACKUP....minutes........... 0000.EA80: ................................................................ 0000.EAC0: ................................................................ 0000.EB00: ................................................................ 0000.EB40: ................................................................ 0000.EB80: ................................................................ 0000.EBC0: ................................................................ 0000.EC00: .&DISCON..{.SDRDBLK....TACHYON....BCA..%.ABS....MAX..J.SPIPINS.. 0000.EC40: ..SETPINS....SAR.....DT......................................... 0000.EC80: ................................................................ 0000.ECC0: ................................................................ 0000.ED00: ................................................................ 0000.ED40: ................................................................ 0000.ED80: ................................................................ 0000.EDC0: ................................................................ 0000.EE00: .INTMASK..w.TXWRITE....TCP.....IP.....SOCKET....ECHOREQ....sectc 0000.EE40: rc....SD@....scanpos....FOUTPUT..J..STACKS....[SPIOD]....pub..z. 0000.EE80: SHL.D..FOR....NIP.6..---....COGREG@..@.W>B..O.B>W..Q.TAB..b.TIME 0000.EEC0: OUT....END....COMPACT........................................... 0000.EF00: ................................................................ 0000.EF40: ................................................................ 0000.EF80: ................................................................ 0000.EFC0: ................................................................ 0000.F000: .KEEPTMR....crc....SD!....sdtimer....!SD....cat..U.[ESPIO]....CR 0000.F040: EATE$....OUT..5.COGREG!..?.WAITPNE..A.GETLINE..d.org..m.ORG..n.C 0000.F080: LKFREQ..r.@CE....SDA....I2CPINS....EC@.....SW................... 0000.F0C0: ................................................................ 0000.F100: ................................................................ 0000.F140: ................................................................ 0000.F180: ................................................................ 0000.F1C0: ................................................................ 0000.F200: .@COMMON..l.@SOCKET..~.UDP....EASYNET.fth....?DISCONNECT....EASY 0000.F240: NET....KEY..5.READBUF..3.3RD....XOR.@..DUP....C++..W.EC!....EEWO 0000.F280: RDS.fth....EERDBLK....EEWORDS................................... 0000.F2C0: ................................................................ 0000.F300: ................................................................ 0000.F340: ................................................................ 0000.F380: ................................................................ 0000.F3C0: ................................................................ 0000.F400: .@RX..k.&SENDOK..z.LANEMIT....WIZ....FTP....CONNECT....SDC....cs 0000.F440: d....scancnt....FC!..C.eof..O.DISCARD....FINDSTR..F.0<>.YY.WAITC 0000.F480: NT..D.PFA>NFA..K.MODPINS....@EE....EXTEND.boot.................. 0000.F4C0: ................................................................ 0000.F500: ................................................................ 0000.F540: ................................................................ 0000.F580: ................................................................ 0000.F5C0: ................................................................ 0000.F600: .LAN....DISCREQ....?TELNET....PWD....CONTENT....SDD....ACTIVE?.. 0000.F640: !.XC@..%.(.LIST).._.pri..{.(:)..y.OFF....PRIVATE....WAITPEQ..B.F 0000.F680: RESHEN.......................................................... 0000.F6C0: ................................................................ 0000.F700: ................................................................ 0000.F740: ................................................................ 0000.F780: ................................................................ 0000.F7C0: ................................................................ 0000.F800: .@TX..k.SIP..v.constat....XC!..%.fatname../.@DIRBUF..@.RENAME$.. 0000.F840: R.SAVEIMG..c.GETWORD..=.SET....SPIWR16....BRANCH>....UM*....B>L. 0000.F880: .R.REVERSE....APPEND$....LOCATE$....EW@....EEWRBLK.............. 0000.F8C0: ................................................................ 0000.F900: ................................................................ 0000.F940: ................................................................ 0000.F980: ................................................................ 0000.F9C0: ................................................................ 0000.FA00: .!TXBUFS....GETPAGE....clshift..0.SAVEROM..b.LOADIMG..d.BUFFERS. 0000.FA40: ...LITERAL.._.lastkey....VER..H.NFA>CFA....LAP....NOP....REV.N.. 0000.FA80: SHR.B..ROL.F..W++..U.C--..X.bdw....@SPISCK....COGINIT....ackI2C@ 0000.FAC0: ....EW!....RECLAIM.............................................. 0000.FB00: ................................................................ 0000.FB40: ................................................................ 0000.FB80: ................................................................ 0000.FBC0: ................................................................ 0000.FC00: .UIP..y.TXFREE@....CWD....LOADROM..c.aUTORUN....autorun....REG.. 0000.FC40: ..WAITKEY..h.day....COUNTUP....AUTORUN.......................... 0000.FC80: ................................................................ 0000.FCC0: ................................................................ 0000.FD00: ................................................................ 0000.FD40: ................................................................ 0000.FD80: ................................................................ 0000.FDC0: ................................................................ 0000.FE00: .LC@..n.@SKTBUF....XW@..&.DIR..\.[']..>.SPINNER../.COGDUMP....DE 0000.FE40: CIMAL..1.SWITCH=....C+!.h..C~~..^.LSP....seconds....@EEWAIT....w 0000.FE80: dt.............................................................. 0000.FEC0: ................................................................ 0000.FF00: .............B.zZ................'..P........................... 0000.FF40: ................................................................ 0000.FF80: ................................................................ 0000.FFC0: ................................................................ ok
Okay the changes are comming fast, do you have 1 2 3 procedure to build the new system on say a quickstart?
Here is my routine to program the EEPROM (lower or upper, or in fact anywhere on a page boundary) from my PropOS.
Should be easy for you to modify to what you require.
The forum is broken so here is the source code pasted. It uses the I2C driver - do you require that too?
'' +--------------------------------------------------------------------------+ '' | Cluso's Propeller Operating System - OS module: _EEPROM --> _EEPROM.CMD | '' +--------------------------------------------------------------------------+ '' | Authors: (c)2012,2013 "Cluso99" (Ray Rodrick) | '' | Modifications: | '' | License: MIT License - See end of file for terms of use | '' +--------------------------------------------------------------------------+ '' Each module is called from, and returns to, the prop binary "_CMD.CMD" '' This OS module uses an included module "__MODULE.SPIN" to perform most of '' the housekeeping - see this for history, details and acknowledgements. '' '' This module...... '' Copies an SD File "<filename>.EEP" to the EEPROM (lower or upper 32KB of 64KB) '' '' RR20130724 start '' '' '#include "__MODULE.spin" ' include the common code for OS modules #include "__MODULE.spin" CON PAGESIZE = 32 'eeprom pagesize MAXPGMSIZE = 16*1024 'max program size to be placed into eeprom !!! OBJ i2c : "Basic_I2C_Driver" ' eeprom routines VAR byte filename0[13] ' FAT source filename (string) byte fname0[13] ' filename w/o dot byte param[13] ' options: -WL, -WU long e_offset ' eeprom offset long hardware ' hw def & pins long DO, CLK, DI, CS, SI, SO byte Mounted long ioControl[2] '\\ long i0Control_sector '// sdspiFemto passes ioControl[3] ==> sd sector no long fbase ' SD first sector long fsize ' SD filesize '--------------- buffer for eeprom 16KB!!! -------------------------- long ndx ' index of chars in pgmbuff 0..16K-1 byte pgmbuff[MAXPGMSIZE] ' buffer for program to be copied to eeprom (16KB max!!!) DAT _ModuleStr byte "=== COPY ===",0 'module's name (string) PRI executeCommand(stringPointer) | sector[512], errorString, bytes, n, r 'get the parameters str.stringCopy(@filename0, str.tokenizeString(0)) ' source filename str.stringCopy(@param, str.tokenizeString(0)) ' options if strsize(@filename0) == 0 ' if no parameters, display usage printStringCR(string(" Program an SD file to lower/upper EEPROM...")) printStringCR(string(" PROGRAM <source_filename> [-WL][-WU]")) return 0 '------------------------------------------------------------------------------ ' ensure file exists and is 32KB errorString := \fat.openfile(@filename0, "R") ' open source file checkError(@filename0, fat.partitionError, errorString) ' if error, display & abort fsize := fat.fileSize ' get size if fsize <> 32768 printString(string("t) File size ")) printString(str.integerToDecimal(fsize,8)) printStringCR(string(" - must be 32KB")) crlf abort -2 ' validateParams ' validate the params param[1] := param[1] & $DF ' simple convert to uppercase param[2] := param[2] & $DF ' simple convert to uppercase if ((param[0] == "-") and (param[1] == "W") and (param[2] == "L")) e_offset := $0000 elseif ((param[0] == "-") and (param[1] == "W") and (param[2] == "U")) e_offset := $8000 else checkError(string(" parameter error"), $F0, @param) ' if error, display & abort '------------------------------------------------------------------------------ printString(string("i) Program ")) printString(@filename0) printString(string(" to EEPROM ")) if e_offset == 0 printStringCR(string("Lower 32KB")) else printStringCR(string("Upper 32KB")) '------------------------------------------------------------------------------ r := \Program32KB(@filename0) ' get file & program to eeprom if r == 0 printString(string(" Eeprom programmed successfully")) crlf else printString(string("*** Programming Failed *** code ")) printString(str.integerToDecimal(r,3)) crlf abort -1 '----------------------------------------------------------------- ' Close up fat.closeFile printStringCR(string("i) EEPROM written.")) return 0 '------------------------------------------------------------------------------ Pri Program32KB(st) | r ' Program the EEPROM from file {{ bytes := \fat.readData(@sector, 64) ' if good, returns the byte count checkError(@filename0, fat.partitionError, bytes) ' if error, display & abort }} r := FindFile(st) ' eeprom file present? ' program eeprom lower 16KB r := LoadFile16KB ' load lower 16KB of file DisplayBuffer(e_offset + $0000) printString(string(" Programming first 16KB block...")) printString(str.integerToHexadecimal(ndx,8)) crlf r := ProgramEeprom(e_offset + $0000) ' program lower eeprom from buffer printString(string(" Programmed first 16KB block")) crlf bytefill(@pgmbuff, $00, MAXPGMSIZE) ' clear the buffer r := LoadEeprom(e_offset + $0000) ' readback lower eeprom DisplayBuffer(e_offset + $0000) ' verify eeprom_lo r := FindFile(st) ' eeprom file printString(string(" Verifying first 16KB block...")) crlf r := VerifyFile16KB(e_offset + $0000) ' verify lower 16KB of file printString(string(" Verified first 16KB block")) crlf ' program eeprom upper 16KB (file already points to start of second 16KB) ' bytefill(@pgmbuff, $00, MAXPGMSIZE) ' clear the buffer r := LoadFile16KB ' load upper 16KB of file DisplayBuffer(e_offset + $4000) printString(string(" Programming second 16KB block...")) printString(str.integerToHexadecimal(ndx,8)) crlf r := ProgramEeprom(e_offset + $4000) ' program upper eeprom from buffer printString(string(" Programmed second 16KB block")) crlf 'now we need to reposition the file at the upper 16KB block r := FindFile(st) ' eeprom file r := LoadFile16KB ' load(skip) lower 16KB of file bytefill(@pgmbuff, $00, MAXPGMSIZE) ' clear the buffer printString(string(" Verifying second 16KB block...")) crlf r := LoadEeprom(e_offset + $4000) ' readback second 16KB from eeprom DisplayBuffer(e_offset + $4000) ' verify eeprom_hi r := VerifyFile16KB(e_offset + $4000) ' verify 16KB of file printString(string(" Verified second 16KB block")) crlf PRI FindFile (st) | errorString, r printString(string(" Locating ")) printStringCR(st) ' r := fsrw.popen(st,"r") 'Open file for read ' Open the FAT source file errorString := \fat.openfile(st, "R") ' open source file checkError(st, fat.partitionError, errorString) ' if error, display & abort Pri LoadFile16KB | r ' Load a 16KB block from file ndx~ repeat while ndx < MAXPGMSIZE ' r := fsrw.pgetc ' read a byte at a time from the file r := fat.readByte if r < 0 printString(string("t) File error")) crlf abort -3 else pgmbuff[ndx++] := r ' save bytes to buffer return 0 Pri VerifyFile16KB (offset) | r ' Verify 16KB block of file ndx~ repeat while ndx < MAXPGMSIZE ' r := fsrw.pgetc ' read a byte at a time from the file r := fat.readByte if r < 0 printString(string("t) File error")) crlf abort -3 else if r <> pgmbuff[ndx] ' compare bytes printString(string("t) Verify Error at $")) printString(str.integerToHexadecimal(ndx+offset,4)) crlf abort -4 ndx++ return 0 Pri ProgramEeprom (offset) | i, start_time 'program 16KB to eeprom repeat i from 0 to constant(MAXPGMSIZE/PAGESIZE)-1 if i2c.WritePage(i2c#BootPin, i2c#EEPROM, offset+(i*PAGESIZE), @pgmbuff[i*PAGESIZE], PAGESIZE) abort -1 'error during write start_time := cnt 'prepare to check for a timeout repeat while i2c.WriteWait(i2c#BootPin, i2c#EEPROM, offset+(i*PAGESIZE)) if cnt - start_time > clkfreq / 10 abort -2 'waited more than 100ms Pri LoadEeprom (offset) | i 'readback 16KB only repeat i from 0 to constant(MAXPGMSIZE/PAGESIZE)-1 if i2c.ReadPage(i2c#BootPin, i2c#EEPROM, offset+(i*PAGESIZE), @pgmbuff[i*PAGESIZE], PAGESIZE) abort -1 'error during read PRI DisplayBuffer (offset) | r, c, lc[16], w, adx 'display first 16KB w := 16 adx~ ndx~ ' repeat while ndx < MAXPGMSIZE ' repeat while ndx < (MAXPGMSIZE / 16) '<==== only show 1KB repeat while ndx < (MAXPGMSIZE / 64) '<==== only show 0.25KB ' printChar(spc) printString(str.integerToHexadecimal((adx + offset),4)) printString(string(":")) c := 0 repeat while c < w r := pgmbuff[ndx++] ' get next char printChar(" ") printString(str.integerToHexadecimal(r,2)) lc[c] := r c++ c := 0 printChar(" ") repeat while c < w r := lc[c] if r < $20 or r > $7E printChar(".") else printChar(r) c++ adx += w crlf dat {{ +------------------------------------------------------------------------------------------------------------------------------+ | TERMS OF USE: MIT License | +------------------------------------------------------------------------------------------------------------------------------+ |Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | |files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | |modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| |is furnished to do so, subject to the following conditions: | | | |The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| | | |THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | |WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | |COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | +------------------------------------------------------------------------------------------------------------------------------+ }}
Yes, the procedure is fairly straightforward now and MJB also has a TeraTerm script for loading the source files automatically. However this is the procedure I use for a new board.
1. Use Spin tool/BST to load the "Spin" kernel to bring the Prop to life.
2. Connect terminal at 230,400 baud and check coms
3. Load (paste or send) P8.SET to set the build required
4. Load EXTEND.FTH
5. Load EEWORDS.FTH (may be included in EXTEND later)
6. Load P8DEFS.FTH to define the P8 hardware (like a header file)
7. Load SDFS (combo of SDCARD and EASYFILE)
8. Run COMPACT
9. Load NET5500.FTH (combo of W5500 plus EASYNET)
10. Optional COMPACT which leaves around 7K free
Quickstart is even easier as there is no SD or Ethernet etc so really it only needs steps 1,2, and 4 and then QS.FTH optionally.
So the serial load could be reduced to P8EXTEND.FTH (combo of P8.SET + EXTEND + EEWORDS + P8DEFS) then SDFS then NET5500. In fact I load the networking source files straight from the SD card since SDFS is in place.
For production I only have to build once and then SAVEROM and use that 64K binary file from my programming Prop which directly loads the EEPROM of the target Prop, so each Prop only takes a couple of seconds to program.
Thanks Ray, I was sort of looking for a PC based loader that did it automatically over serial to make it easy for the user if I update a binary. I use a Prop configured as a programmer stick to clone all my boards quickly so the problem really is how does the end user load a new binary that is more than 32k? My kernel is incorporating a bootloader directly into the serial receive driver so that it transparently loads the EEPROM if it detects a valid hex file being loaded, regardless of what the O/S is doing. Of course certain checks need to be made to prevent corruption of the bootloader itself but that's a minor detail. I figure that if I buffer each line of hex and it's ok then I reprogram EEPROM directly then and there or maybe even accumulate a programming page's worth first. The thing is to prevent the startup code from being reprogrammed until the rest of the file has loaded correctly so that the bootloader never loses control. So this means that the user never has to use the Spin tool and then send a hex file through the terminal as well, just sending the file which can be done even from a smartphone is all that is needed.
If the target system is connected to the Ethernet at present I only have to FTP the binary to it and then execute LOADROM which just programs the whole 64k EEPROM from the FIRMWARE.ROM file. For these networked systems I may even make them automatically search for and apply firmware updates if this option is enabled by the user. It's quite a powerful system that's running, and I've still got 7K of RAM left and over four cogs free!
if anybody is interrested - here is the build script I have been using for TeraTerm.
If you set up propellent you can compile and load the spin kernel automatically as well
To confige TeraTerm you need to create a custom ini file with the correct linedelay and baud rate settings.
Here I have a lot of messageboxes active, which you can comment out, when it works for you.
The created log file shows exactly what has been done.
If you want even more diagnostics comment the [~ word in the fth files.
Current pause timings a very conservative.
btw. I save the Google docs documents locally with the google docs time stamp of last change in the name.
This way I can get reproducable builds and know exactly what is in there.
Very important with Peter's lightning speed of change ;-)
; save file with *.ttl extension (TeraTerm Language) ; Tachyon build file for TeraTerm ; ; Spinneret build file 2014-10-31 ; show 1 clearscreen 1 ; line delay setting is important, so we load custom ini file restoresetup 'SPINNERET.ini' getdir dir strconcat dir '\' messagebox dir 'DIR' getttdir ttdir messagebox ttdir 'TTdir' ; sendfile needs full path ; set build directory ; setdir 'D:\Tachyon\Spinneret 2014-10-23\' lf = dir gettime timestr "%Y-%m-%d--%H-%M-%S" strconcat lf 'build ' strconcat lf timestr strconcat lf '.log' logopen lf 0 0 0 1 1 ; assume a plain Tachyon base image ; sendln 'COLD' ; pause 20 ; or load kernel via propellent dispstr 'loading Kernel' disconnect 0 pause 1 execstr = 'D:\Propeller\Propellent\Propellent.exe /eeprom ' strconcat execstr #$22 strconcat execstr dir strconcat execstr 'TACHYON V24 2014-12-17 05-58.spin'#$22 messagebox execstr 'Load Tachyon' exec execstr pause 50 ; connect to COM5 connect '/C=5' dispstr 'done loading Kernel' messagebox 'done loading Kernel' 'done load' pause 1 sendbreak pause 10 fn = dir strconcat fn 'EXT_LOAD 2014-10-27 07-28.fth' messagebox fn 'loading' sendfile fn 1 pause 20 fn = dir strconcat fn 'EXTEND 2014-12-17 15-54.fth' messagebox fn 'loading' sendfile fn 1 pause 20 ; for debug we want to see all ; sendln 'pub [~ ; ' fn = dir ; ;strconcat fn 'EPRINT 2014-07-03 18-13.fth' ;messagebox fn 'loading' ;sendfile fn 1 ;pause 10 fn = dir strconcat fn 'SPINNERET 2013-12-04 12-00.fth' messagebox fn 'loading' sendfile fn 1 pause 10 sendln '?BACKUP' pause 20 fn = dir strconcat fn 'SDCARD 2014-12-09 03-44.fth' messagebox fn 'loading' sendfile fn 1 pause 20 fn = dir strconcat fn 'EASYFILE 2014-12-11 01-54.fth' messagebox fn 'loading' sendfile fn 1 pause 20 fn = dir strconcat fn 'SDWORDS 2014-12-10 06-55.fth' messagebox fn 'loading' sendfile fn 1 pause 30 sendln '?BACKUP' pause 30 sendln 'COMPACT' pause 50 sendln '?BACKUP' pause 30 sendln 'SDWORDS ' ; end pause 30 fn = dir strconcat fn 'W5100 2014-11-25 00-52.fth' messagebox fn 'loading' sendfile fn 1 pause 20 sendln '?BACKUP' pause 30 fn = dir yesnobox 'load EASYNET' 'EASYNET' if result then strconcat fn 'EASYNET 2014-12-16 02-13.fth' else yesnobox 'load MJBHTTP' 'MJBHTTP' if result then strconcat fn 'MJBHTTP 14.fth' else end endif endif messagebox fn 'loading' sendfile fn 1 pause 20 sendln 'COMPACT' pause 30 sendln '?BACKUP' pause 30 sendbreak pause 10 sendln 'SDWORDS ' pause 30 logclose
' That's all, but to sweep in 500Hz spacings from 37kHz to 42kHz every 50 ms perhaps try this: 15 APIN BEGIN 37,000 5,000 ADO I HZ 50 ms 500 +LOOP AGAIN ' To lock that into the system so it does it on startup is straightforward: pub JAMMER 15 APIN BEGIN 37000 5000 ADO I HZ 50 ms 500 +LOOP AGAIN ; AUTORUN JAMMER
But shouldn't it be this?
#15 APIN BEGIN #42,000 #37,000 ADO I HZ #50 ms #500 +LOOP AGAIN ' To lock that into the system so it does it on startup is straightforward: pub JAMMER #15 APIN BEGIN #42,000 #37000 ADO I HZ #50 ms #500 +LOOP AGAIN ; AUTORUN JAMMER
#s added just for clarification is system is not set to decimal but the ADO bounds
from Tachyon.spin
' ADO ( from cnt -- ) ... ' DO ( to from -- ) ...
and number base default is decimal now, but good to prefix anyhow.you are correct, should have check the source!
but from 32500 for 5000 times incrementing by 500 each time we end up with 2,500,000 + 32500 = 2,825,000?
so wouldn't you loop 140 times to increment 32500 to 42500 by increments of 500?
? You are confusing me David!
I left the # prefix off just to simplify it as I didn't want to clutter the simple straightforward thing that we know it is but for some reason people are afraid of
So 37,000 5,000 ADO will work the same as 42,000 37,000 DO and if we just used LOOP it would step 1 Hz each time for 5,000 times. Using 500 +LOOP means it jumps 500 at a time so the index would be 37,000 then 37,500 then 38,000 right up to 42,000 when +LOOP detects that boundary of 42,000 has been reached or crossed so it terminates the loop.
ADO grew out a distatse for those traditional Forth DO LOOP parameters and the use of BOUNDS at times to convert to that format. It was more efficient and looked cleaner when I combined the BOUNDS DO into a simple clean operation. I didn't know what to name it at the time and didn't want to make much "ado" about such a little thing so it was named ADO and it stuck!
15 APIN BEGIN 37,000 5,000 ADO I HZ 50 ms 500 +LOOP AGAIN
the loop is taken only 10 times
start is 37000
end is start + 5000
step is 500
.... didn't see your post Peter .....
woah how does the syntax below know it crossed 42,000?
pub JAMMER 15 APIN BEGIN 37000 5000 ADO I HZ 50 ms 500 +LOOP AGAIN ;
completely understand DOwith Tachyon reading the code helps in such cases ... ;-)
' ADO = BOUNDS DO - just a quick and direct way as BOUNDS is most often never used elsewhere ' ADO ( from cnt -- ) ADO mov X,tos+1 add tos+1,tos mov tos,X ' DO ( to from -- ) DO call #_PUSHLP ' PUSH index onto loop stack
the params are simply converted and then DO is usedForth <> syntax
Have a look at LOOP an +LOOP in the kernel source, it detects it crossing each time it executes a loop. That's also why you can manipulate the loop stack parameters with words such as LEAVE which will simply set the index to the value of the limit, when LOOP comes around it checks and says "I'm done for the day" and exits the loop.
' (+loop) ( n1 -- ) adds n1 to the loop index and branches back if not equal to the loop limit PLOOP jmpret POPX_ret,pDELTA wc ' DELTA calls POPX (code cramming) ' The comparison above is between the call insn (wr) at DELTA and the jump insn (nr) at POPX_ret, ' this will alwaye be carry set. The call itself is indirect. ' 400ns execution time including bytecode read and execute LOOP if_nc mov X,#1 ' default loop increment of 1 add loopstk+1,X ' increment index cmps loopstk,loopstk+1 wz,wc BRANCH if_a mov IP,branchstk ' Branch to the address that is saved in branch if_a jmp unext jmpret LPOPX_ret,forNEXT+1 wc ' discard top of loop index stack ' then next loop and its branch address
Got it, thanks for cheer leading me over the learning hump.
To make this a little easier to load the full 64k image I have created a spinneret.binary image which has the SD filesystem but does not have the networking so that it fits in 32K which can be loaded onto the Spinneret with your favorite Prop loader tool.
Look in the Dropbox files under binaries and then Spinneret. The Dropbox link is in my sig.
(make sure you copy the FIRMWARE.ROM file to your Spinneret's microSD)
Once you fire up the Spinneret you can connect your serial terminal at 230,400 and talk to the Forth shell and ask it to load the full 64k networking image into EEPROM by typing LOADROM, then reboot (either REBOOT or ^C or <break>). Once rebooted the Spinneret will automatically launch the network servers for WEB, FTP, and Telnet while still providing an interactive shell over the serial console. You can easily change the IP addresses and even the MAC which BTW is a random 32-bit number on a cold start (new and blank) with a fixed OUI of $02.FF. Here is the response to an ifconfig command (Linux equivalent of ipconfig):
[B]ifconfig[/B] ************ NETWORK STATUS ************ HARDWARE: SPINNERET using WIZnet W5100 (indirect) SRC IP 192.168.016.150. MASK 255.255.255.000. GATEWAY 192.168.016.001. MAC 02.FF.42.C5.F3.F6. SKT HH:MM:SS MODE PORT DEST TXRD TXWR RXRD RXWR RXSZ IR STATUS IP ADDR #0 15:30:23 TCP 21 54923 . . . . . 00 14 LISTEN #1 15:30:23 TCP 80 28777 . . . . . 00 14 LISTEN #2 15:30:23 TCP 10001 . . . . . 00 14 LISTEN #3 15:30:23 IPRW 511 43024 . .2800. . . A8 10 ok
You can change the IP address via the terminal by typing the IP address in using a & prefix to force the number to "decimal bytes", that is, each group of decimal digits represent one byte.
&192.168.0.14 SIP
To change the gateway:
&192.168.0.254 GATEWAY
To change the port number of the socket which btw is locked in software to a server, so socket 2 is locked to Telnet which actually connects to the Forth shell:
2 SOCKET 23 PORT!
This changes the Telnet port to the standard port 23
All these changes are automatically backed up in the topmost part of the 64k EEPROM and reloaded at network boot.
The Spinneret is online at the moment at tachyonforth.com but you can play with it a bit more using FTP and Chrome at ftp://tachyonforth.com or Telnet to port 10001
(EDIT: looks like my socket reporting is off a bit for some reason on the latest W5100 driver but it everything seems to work, I will fix it up shortly) - FIXED - updated Dropbox
No. Time Source Destination Protocol Length Info 21 34.225855000 192.168.16.2 192.168.16.150 FTP 59 Request: PWD 22 34.225875000 192.168.16.2 192.168.16.150 FTP 62 Request: TYPE I 23 34.238073000 192.168.16.150 192.168.16.2 FTP 88 Response: 257 "/" is your current location 24 34.238266000 192.168.16.2 192.168.16.150 FTP 60 Request: PASV 25 34.249351000 192.168.16.150 192.168.16.2 FTP 73 Response: 200 TYPE is now I 26 34.271760000 192.168.16.150 192.168.16.2 FTP 114 Response: 227 Entering Passive Mode with port (192,168,16,150,176,5) 27 34.271854000 192.168.16.2 192.168.16.150 TCP 54 49121 > ftp [RST, ACK] Seq=74 Ack=302 Win=29200 Len=0
So for some reason FF is sending two requests together (PWD and TYPE I) and when it receives a response for the first request it shoots off a request for PASV while the second response is still on it's way. So when PASV looks for a response it gets the previous response that it hadn't read.
I've tried this with a local NAS and FF doesn't try to send two requests together as perhaps the FEAT response cause it to take a different path. It seems like a FF bug to me but I can't see any mention of it anywhere and although it should be possible for me to process all receive packets and combine the responses before sending it just seems like a kludge to me when all other clients behave.
Any ideas anyone?
I just tried to connect using Firefox and got a popup window with the same error.
I've tested this on Windows, Android, and Linux, same thing. Yet I can connect to a local NAS server and it doesn't try to send TYPE I before it receives the response for PWD:
No. Time Source Destination Protocol Length Info 22 14.091912000 192.168.16.2 192.168.16.19 FTP 71 Request: PWD 23 14.092189000 192.168.16.19 192.168.16.2 FTP 100 Response: 257 "/" is your current location 24 14.092415000 192.168.16.2 192.168.16.19 FTP 74 Request: TYPE I 25 14.092667000 192.168.16.19 192.168.16.2 FTP 96 Response: 200 TYPE is now 8-bit binary 26 14.092810000 192.168.16.2 192.168.16.19 FTP 72 Request: PASV 27 14.093258000 192.168.16.19 192.168.16.2 FTP 116 Response: 227 Entering Passive Mode (192,168,16,19,62,227)
pub FEAT IMMEDIATE ON LANLED autosend C~ PRINT" 211-Features supported" CR PRINT" UTF8" CR --- note* indentation required PRINT" 211 End" autosend C~~ CR ;
after the first 211 there MUST be a "-" MINUS character if there are features reported.Without features there MUST be a SPACE
with this change Firefox works again.
I think it worked with firefox before you added the UTF8" feature.
see https://tools.ietf.org/html/rfc2389#section-2.1 Chapter 3.2. FEAT Command Responses
the handling of the FEAT OPTS command seems not implemented yet.
so maybe better go with the minimum
211 no Features supported
reply.
fixed in EASYNET.fth
quick fix: just paste the above code into your terminal window. The next FTP request will automatically use the new code.
No rebuild required. then do a BACKUP if you want it permanently in the image.
better even use the following code for now
pub FEAT IMMEDIATE ON LANLED autosend C~ PRINT" 211 no Features supported" CR autosend C~~ CR ;
Thanks for tracking that one down MJB, it's so sweet not having to sweat over it and still having the problem solved
So there is still a bug with FF as Chrome and other FTP clients work anyway but I will look at the FEAT response in more detail later.
BTW, the code for FEAT can be even simpler, and yes, we only need to paste this code through the console for it to work although I did reload EASYNET as that only took several seconds anyway.
pub FEAT ON LANLED PRINT" 211 no Features supported" CR ;
Thanks
Sorry, didn't notice the new post, done.
Renaming these to P8SET.FTH so that extensions are recognized by various clients.
BTW, decided that the HELP: word really needs to be in the form {HELP ............. } as I can insert this into the kernel document to keep the Spin compiler happy, even though I'm not using Spin of course. So this looks like this:
{HELP UM* ( u1 u2 -- u1*u2L u1*u2H ) DESC: unsigned 32bit * 32bit multiply -- 64bit result TIME: 1..11.8us } UMMUL mov R0,tos+1 min R0,tos ' max(tos, tos+1) mov R2,tos+1 max R2,tos ' min(tos, tos+1) mov R1,#0 mov tos,#0 ' zero result mov tos+1,#0 UMMULLP shr R2,#1 wz,wc ' test next bit of u1 if_nc jmp #UMMUL1 ' skip if no bit here add tos+1,R0 wc ' add in shifted u2 addx tos,R1 ' carry into upper long UMMUL1 add R0,R0 wc ' shift u2 left addx R1,R1 ' carry into 64-bits if_nz jmp #UMMULLP ' exhausted u1? jmp unext
Which means we can type HELP UM* for the kernel as well as the .FTH files.So when a new word is created and TF has run out of spare vectors in the 2K vector table it will compile a header with an attribute that indicates the 2 bytecodes in its header are actually the 16-bit direct address and that to reference this it needs to compile a CALL16 followed by these two bytes. This doesn't make a lot of difference to the code memory consumed because by this time all the important stuff has been compiled and is very compact and any references to words with a CALL16 attribute will automatically compile the correct bytecodes. Of course, all references to opcodes and vectored bytecodes will still compile one or two bytes.
So here is a system with a full EXTEND.fth with all the trimmings along with SDFS and networking, amounting to 1,223 words including 144 opcodes which means there are 1,024 vectored words plus 55 CALL16s. Notice that it has 0 vectors free which is in fact what it had before the EASYNET.fth network server module was loaded. To further test this out I then loaded an application on top of this and it all fits and works.
Do you have to do anything different? NO! You don't even need to force a SMALL EXTEND.fth or use the include filter sets such as P8SET.FTH etc.
VER: Propeller .:.:--TACHYON--:.:. Forth V24150105.2330 FREQ: 80,000,000 NAMES: $70E0...74B6 for 982 bytes (4,294,965,961) CODE: $0924...63B6 for 23,186 bytes (+3,301) CALLS: 0 vectors free RAM: 3,370 bytes free ok .EEMOD MODULES LOADED: 42DF: EASYFILE.fth FAT32 Virtual Memory Access File System Layer V1.1 141211-1100 4E42: W5500.fth WIZNET W5500 driver 141122.1200 3CF8: SDCARD.fth SD CARD Toolkit - 141202.0000 39ED: CE1372.fth CE1372 WIDGET HARDWARE DEFINITIONS 140918.2200 1A00: EXTEND.fth Primary extensions to TACHYON kernel - 141217-0000 56D1: EASYNET.fth WIZNET NETWORK SERVERS 150101.0800 36D8: EEWORDS.fth TACHYON DICTIONARY WORDS in EEPROM 141218.1930 ok EEWORDS SECT: WORDS 8000: sDIP .SKT HTTP FEAT WKEY TRUE LONG HIGH DIRA (op) EERD WRITEHEX 8000: +HEX +NFA &TE1 =dtk sdwr FILE SDWR file DIR! (ls) 8200: @mac contimer (.") ANDN DIRB BOLD @SCK FIND year WATCHDOG days &TE2 8200: RS232LED 8400: @gateway SKT@ sDISCON? type TYPE MDTM cwd$ HEAD FREE [PWM32!] mod2load BITS 8400: @SCL ATN? COLD NFA>SECT sdhc EASYFILE.fth CLUSTER@ 8600: autosend QUIT SYST RNTO TASK LEN$ .HEX ATN@ timerstk @CMS dir$ 8800: myGW WR_WCTRL sPRO .PTR FlushSkt GET$ ?LED HERE here BYTE TASKREGS ATN! 8800: ENQ@ boot dict root udir 8A00: txwr ifconfig .NET PORT (CREATE) >PFA unum @PAD [PLAYER] MYOP DROP CNT@ 8A00: @CNT ENQ! LIKE KEEP .PIN PWM! SDERRLED ACMD .ATR 8C00: &CON skt$ STOP [PRIVATE VCFG SPR! DUMP ESC[ matchstr PINLOAD? DUTY TIMEOUT? 8C00: !PCB FGET 8E00: mySN GETFNAME PASS HOLD FILL PIN@ LONGFILL (CLKSET) .MODULES _!SD @ATR 9000: .IP1 nettimer RNFR STOR ?EASYNET UNSMUDGE ?DUP PRIVATE] PIN! VSCL VCLS (VA) 9000: ADC@ (FORGET) APIN term leds LEDS .ASMONTH SPLITDEC 9200: ?FTP ELSE COG@ C@++ KEY@ OUTA PRINTDEC HOME !ADC HELP CTR@ BPIN 9200: DAC! PWM% @rtc PCB$ SD2@ sect/fat .FAT @RCD 9400: LREADSKT .SOCKETS PASV SENDFILE ?CONTENT KOLD .DEC COG! EXIT LOOP AVAR CONSTANT 9400: KEY! ESC? OUTB CTRA FRQA SQRT CTR! REVECTOR SDBSYLED READYLED RES@ FREM 9600: !WIZ .IPD SIZE base .VER SET? 2DUP (OPCODE) SWAP [CON CTRB FRQB 9600: ansi COMPARE$ #adc MUTE .LAP RS485LED SD4@ @FAT FRUN 9800: @sip sCLOSED? CDUP LIST TERMINAL GRAB NFA' >VEC word SWITCH>< CASE JUMP 9800: CALL MASK OVER NOOP WORD PHSA .MAP I2CSTART timerjob TIMERJOB .AUTORUN .DAY 9A00: &TIMEOUT sCONNECT .@SKTBUF #CONNECT RETR NOTFOUND CON] PHSB PRINTNUM &TR1 sdrd SDRD 9A00: .DIR 9C00: sSENDMAC .BYTEDEC REST IDLE ukey .NUM SARX MID$ I2C@ date &TR2 DAY@ 9C00: fats DIR? FCREATE$ FCRC 9E00: myIP oui2 WAITSEND .IPX dataport USER BELL EMIT [WS2812] THEN NEXT ECHO 9E00: <CR> I2C! time HEX: ERRORLED DAY! XADR rsvd >F83 fkey FPUT A000: ?SENDPOLL ERASE AGAIN @ 0 Published CALL$ ECOPY PWM.START hexch &SDDO TIME! A000: @FILE &sdto !SDIO XADR! fat32 FILE@ (DIR) A200: sINTS sCLOSING? [COMPILE] BCOMP ! 1 NORMALIZE SERIN SI2C@ eeadr A TIMER A200: hours CountDown &WNCS sdres SDCLK FPUTB A400: vread sDHAR sSENDKEEP ledon DISCONNECTED? .BYTE [SSD] " SPIRD 2 TIMES EMITS A400: .DECX DUMPL TASK? STRIP SI2C! B RI232 WRRTC sddst FLUSH byte/sect fread A400: fstat A600: IPRAW sRECV user$ # RESET 3 HELP: LONGS ttint &SDCS FILE# mount A600: MOUNT A800: PPPoE LANCONKEY names uemit U/MOD 4 (NULLOUT) HYPOT PLAIN ESAVE TIMERTASK cache A800: FI2C@ &IOCS SDBUF @ROOT @BOOT file$ FILE$ lscnt AA00: RETRYTIME sOPEN @txwr fsave BREAK BEGIN DEPTH SPIWR +LOOP CTYPE (rnd) % AA00: lpace ELOAD FI2C! &SFCS AC00: &RECV PORT! !TXWR LSEND KEEPALIVE ufind tasks ENDIF COGID FLOAT .SPRS blksz AC00: month RCDSZ FLOAD AE00: +CALL ' DEBUG 2DROP BYTES DUMPA eebuf .diff @FEXT B000: LREAD sMODE sCMD! sPORT QUIET contd ( 3DROP 8 TABLE radix RADIX B000: CONIO navar BDUMP @MOSI @MISO .ATRS .PINS (end) dboot (COMPACT) &WNDI =SPIO B000: FOPEN ?AUTOLOAD B200: WCOLD ?SEND ALLOCATED ?EXIT WHILE I (WAITPNE) modloaded (SEP) .ADDR +CHAR uboot B200: &WNCK !LEDS card? CARD? s (cat) B400: UPORT ERROR AUTO! .WORD (KEY) : * DELTA CMOVE 0EXIT ALIAS PINS@ B400: J ANSI? >CSTR &SDDI ?SPIO parts fboot .LIST B600: sendtimer pass$ lines delim { ; + FALSE LEMIT K LOCAL ALIGN B600: ERSCN MASK? &SDCK sdcmd SDCMD +DIR! ROMSZ B800: wctrl WCTRL wMODE RNFR$ ALLOT >CHAR SPACE < , | \ UNTIL B800: (WAITPEQ) CLOCK LBIT! UPPER (ESC) EFILL .DATE STAT@ _SDRD READFAT32 BA00: sSEND COMMA getsz flags } = - PRINT LEAVE SWAPB DUMPW MATCH BA00: ENDRD ALARM .TIME BC00: INTS@ codes . .LONG HDUMP IFDEF > UNPRIVATE ~ ^ (BDW) (COGINIT) BC00: (RECLAIM) I2C!? &WNDO DATE@ FILE> >FILE .FILE BE00: sSTAT ?HTTP SCRUB @HATR IMMEDIATE MASKS / NULL$ COPY$ LEFT$ .NAME WORDS BE00: (MAP) IDUMP RDRTC TIME@ DATE! ucard sdsrc PROCESS_TOKEN _SDWR C000: CREATEWORD ms ." (EMIT) R> >R >B STREND RETURN P@ QWORDS VirtualRTC C000: SETPWM FIXBIN RTS232 DSR232 LANLED sector scanch SECTOR serial C200: vwrite SUBNET sSSIZE WBUFSZ FTPMSG PRINT$ #> .S U< REPEAT 2/ OR C200: P! IX C~ XY $= SI2C!? (EESEARCH) DTR232 CTS232 SDCARD.fth sdpins SDPINS C200: SDDAT! fatptr @CDATE @FSIZE FSIZE@ fwrite .FILES C400: CONNECTED? prompt switch SWITCH LSTACK RIGHT$ SEROUT HZ hexbuf DCD232 WPWRDN sdsize C400: @WRFLG ?MOUNT @CTIME @FREAD .FDATE .UTIME C600: !WIZIO NETMAN FTPDAT un BUFSIZ U. WITHIN [SPIO] TO INPUTS C@ DO C600: PINSET U> RCFAST (+COMPACT) sdinfo FPRINT .FTIME C800: !WIZIP LANKEY CREATE [NFA'] create digits SHRINP OUTSET NEGATE U/ C! @NAMES C800: GETRND dwidth .TASKS ERASE$ timers @FDATE CA00: sINACTIVE? CR BINARY [SDRD] RUNMOD SHROUT >W W~ QHYPOT U@ $! ADCBUF CA00: E@ .BOOTS (DICT) CE1372.fth RXD232 wrflgs SDCMD: @FTIME FSECT@ FDATE! .FYEAR .FNAME CC00: RD RXREAD GO <CMOVE #S SEARCH >RADIX RADIX> ++ U! .INDEX VP CC00: CLKSET MY WWORDS E! ESAVEB BACKUP pwmtbl rtcbuf diradr FINPUT FTIME! CE00: LWRITE txsize ?CTRLS [PLOT] XCALLS COGREG SPIWRB W@ 16 IN DS /ROUND CE00: STRING FORGET TXD232 SD @FNAME QV D000: @ports TXREAD UpdateTXWR disreq [SDWR] || W! INVERT EXTEND.fth us PINCLR @X D000: << |< VOLTS@ QW EEPROM .EEMOD blklen _CARD? WRSECT X@ CLUST>SECT APPEND D000: RENAME D200: WR @wcold RETRYS socket SOCKET sCLOSE (STOR) NUMBER STACKS CMPSTR OUTCLR [~ D200: WORDS: X1 <= VC .BLOCK PULSEWIDTH X! sect/clust RW D400: CLOSED LANCONEMIT ledcnt DISCONNECT >UPPER LOOKUP <> SPIRDX L> >L OK ok D400: -- consav X2 == %% >| OPCODE RCSLOW EE WRESET sdbusy sdtask D400: SDBUSY D600: MACRAW txtime LANCON [WAVE] REBOOT BOUNDS ]~ DOUBLE X3 => PLLDIV hexptr D600: fname$ FOPEN# FSTAMP D800: L@ sDPORT sRXMEM .SKTHD TELNET 0< IFNDEF +! >N 2* 1+ SETMOD D800: ~~ X4 >> second MATCH? +TIMER hexadr dirbuf @FCLST FCLOSE FOPEN$ DA00: L! LANSKT errors 2+ SPIWRX 0= ON UNLOOP m@ M@ .STATS dictwr DA00: .DTFMT C: ?SDTIMEOUT DC00: sTXMEM (RETR) [WS2812CL] '' 1- BL -1 // PININP locals @. CURSOR DC00: hexflg extbuf (SDRD) (.DIR) LOGSZ? DE00: sktbuf <# >DIGIT C, IF 2- PUBLIC PRINT" SPACES (.NUM) ERLINE BLKSIZ DE00: SDERR? @ADATE APPEND.BLK ls E000: LC! UNKNOWN BYE blkpoll GET keypoll LOADMOD 4TH CON MODULE: MOD DPL E000: mc@ MC@ RAM (WORDS) NCO pwmmask cid ?SDCARD >|RCDSZ (SLIST) E200: @subnet MAC sESTAB? SetPORT #ftpmin baudcnt [PWM32] CLR -NEGATE NOT L>W W>L E200: W-- RELEASE U.N tid MARKER? @FWRITE E400: GATEWAY SKT sLISTEN CLS SWITCH@ LOW DS+ (.MODS) SCL .TIMERS pwmfreq SDCARD.TASK E400: oemname volname E600: LW@ sDISCON #ftpmax BLKSEND netflgs CONSOLE EXECUTE !RP ?NEGATE W+! ROR AND E600: NULLOUT W~~ PAR (STRIP) SETPWMS BCD>DEC DEC>BCD sectors rootdir -FERASE E800: wizpins LW! SP! !SP OUTPUTS ADO \\\ MIN RND mw@ MW@ I2CSTOP E800: runtime DUMPROM nfasect LEDREG! ocr filesel CMD @FCLSTH EA00: RXSIZE@ RXWRITE sCONNECTED? LANSEND RESTART HEX ROT SPR CNT COS RUN LISTKEY EA00: ?BACKUP minutes HEXLOAD LED PCB EC00: &DISCON TACHYON BCA ABS MAX SQR SPIPINS SETPINS SAR SERBAUD .I2CBUS .DT EC00: SDRDBLK EE00: INTMASK TXWRITE TCP .IP .SOCKET ECHOREQ .STACKS [SPIOD] pub SHL FOR NIP EE00: --- COGREG@ W>B B>W TAB atr TIMEOUT SETPWMW END COMPACT sectcrc SD@ EE00: scanpos FOUTPUT F000: KEEPTMR [ESPIO] CREATE$ OUT COGREG! WAITPNE GETLINE org ORG CLKFREQ INA @CE F000: any ANY SDA I2CPINS EC@ PLL .SW crc SD! sdtimer !SD cat F200: @COMMON @SOCKET UDP EASYNET.fth ?DISCONNECT EASYNET KEY READBUF 3RD XOR DUP C++ F200: INB EC! ctr CTR FRQ EEWORDS.fth EERDBLK EEWORDS F400: @RX &SENDOK LANEMIT WIZ FTP CONNECT DISCARD FINDSTR 0<> WAITCNT ... PFA>NFA F400: SIN MODPINS CLK @EE EVERIFY EXTEND.boot csd scancnt SDC FC! eof F600: LAN DISCREQ ?TELNET PWD CONTENT pri (:) OFF PRIVATE WAITPEQ .RETSTK dst F600: FRESHEN ACTIVE? XC@ (.LIST) F800: @TX SIP constat GETWORD SET SPIWR16 BRANCH> UM* B>L REVERSE APPEND$ LOCATE$ F800: EW@ PULSEWIDTHS CONBAUD EEWRBLK XC! fatname @DIRBUF RENAME$ SAVEIMG FA00: !TXBUFS GETPAGE BUFFERS LITERAL lastkey VER NFA>CFA LAP NOP REV SHR ROL FA00: W++ C-- bdw @SPISCK COGINIT ackI2C@ EW! KHZ RECLAIM clshift SAVEROM LOADIMG FC00: UIP TXFREE@ CWD aUTORUN autorun REG WAITKEY CTRMODE day COUNTUP PWMCOG.TASK AUTORUN FC00: LOADROM FE00: LC@ @SKTBUF ['] SPINNER COGDUMP DECIMAL SWITCH= C+! C~~ LSP seconds @EEWAIT FE00: MHZ wdt XW@ DIR WORD TOTAL = 1223 ok
Regarding the webserver, I think, that in most webserver applications there is no need for a full PWM32 and some of the other special modules in EXTEND.fth.
So for me it is absolutely fine to selectively load things from EXTEND and have enough space even without the CALL16.
But applications will grow - so good to be prepared.
My JSON writer for example needs 20 words / 278 bytes
I had some instability in my dynamic webserver Spinneret tests so hope to be able to clean this out soon.
Just so I'm clear on this how does COMPACT fit into this? Are the steps for a build different now that CALL16 is alive and well?
My little brain really likes the 1 2 3s as long as I don't run out of fingers I'm happy.
The build still works the same as before except that your code is no longer limited by the number of available vectors, although in practice this takes quite a bit and you may not have gotten anywhere now the limit. What happens is that if you have a fully loaded system with SDFS and NET that before there were only about 80 vectors left over, more than enough for most apps but tight if you perhaps had an assembler loaded which would use a vector for every instruction and mode etc. Now when the system runs out of vectors it will implement the CALL16 method transparently so there is no need to worry about it really. What you won't be able to do with these words is revector them since they don't have a vector, but that's minor.
You can do a full build like this:
F11 the Tachyon kernel
* Load EXTEND.fth (optional CREATE SMALL and/or load an include SET)
* Load EEWORDS.fth
* Load your hardware header such as P8DEFS.fth
* Load SDCARD.fth
* Load EASYNET.fth
At this point it hasn't yet been compacted and I like to save my system to SD with SAVEROM. This makes it easy later on if I want to reload modules as I can easily restore to this point with a LOADROM and reboot without having to start right from the beginning.
* Run COMPACT which will now convert the dictionary in RAM to an indexed list in upper EEPROM and release the RAM space.
* Load W5500.fth or other WIZnet driver
* Load EASYNET.fth after which the system will BACKUP
At this point then the dictionary for the network modules is still in RAM but the earlier stuff has been compacted into the EEPROM. If you don't need a lot more room you can leave it like this or else do an optional COMPACT again which will add the new words to the existing dictionary in EEPROM and release the memory it used in RAM.
* Optional COMPACT if desired.
So out of a total of 32K RAM the system does really well by making practically all of this available for code space with the remainder taken up with various buffers such as 2K for four file buffers etc. There's also no need to worry about reclaiming headers because they don't take up any RAM any more and neither is the dictionary searching speed impacted any appreciable amount.
I'm fixing up WORDS and some other functions now so that they work the same with the EEPROM dictionary as they do with RAM.
P.S. How are you going with the IOT modules?
Is the version really a year 2415 Jan 05?
Actually it's a combo of version,revision,year,month,day etc in the form VRYYMMDD,HHMM so that:
VER: Propeller .:.:--TACHYON--:.:. Forth V24150105.2330
is V2.4 YY=15 MM=01 DD=04. Putting it in this format is logical as a new revision/version number will always be a larger number than an old revision as is the YYMMDD which also avoids that American MMDDYY or English DDMMYY confusion thing, both of which are not in logical order especially when compared to HHMM.