59 changed files with 506 additions and 36 deletions
@ -1,3 +1,3 @@
@@ -1,3 +1,3 @@
|
||||
/across |
||||
/stellaris |
||||
/msp430/mecrisp |
||||
/msp430/src |
||||
|
@ -1,4 +1,4 @@
@@ -1,4 +1,4 @@
|
||||
\ generated from template: ./replace-constants.py rf69-rx.fs rf69-constants.fs |
||||
\ generated from template: ./replace-constants.py rf69-rx.template rf69-constants.fs |
||||
\ rf69 driver; RX part |
||||
\ needs spi |
||||
\ needs rf69-tx.fs |
@ -1,4 +1,4 @@
@@ -1,4 +1,4 @@
|
||||
\ generated from template: ./replace-constants.py rf69-tx.fs rf69-constants.fs |
||||
\ generated from template: ./replace-constants.py rf69-tx.template rf69-constants.fs |
||||
\ rf69 driver; TX part |
||||
\ needs spi |
||||
\ = 1092 bytes flash |
@ -0,0 +1,39 @@
@@ -0,0 +1,39 @@
|
||||
\ generated from template: ./templates/replace_constants.py templates/i2c-bb-base.fs fr2476/i2c-bb-base.tmplfill fr2476/port-regs.fs |
||||
\ bit-banged i2c driver, base words |
||||
\ There have to be 1..10 kΩ resistors on SDA and SCL to pull them up to idle state. |
||||
\ Master only. Supports clock stretching. |
||||
\ 270 bytes flash |
||||
|
||||
: 0>scl ( -- ) \ drive SCL low |
||||
%00000010 $0243 cbic! \ (%00000010:SCLPIN) \ (P6OUT:SCLOUT) \ ($0243:P6OUT) |
||||
; |
||||
|
||||
: 1>scl ( -- ) \ drive SCL high |
||||
%00000010 $0243 cbis! \ (%00000010:SCLPIN) \ (P6OUT:SCLOUT) \ ($0243:P6OUT) |
||||
; |
||||
|
||||
: 1>scl-s ( -- ) \ SCL high, stretching allowed |
||||
%00000010 $0245 cbic! \ SCL input \ (%00000010:SCLPIN) \ (P6DIR:SCLDIR) \ ($0245:P6DIR) |
||||
1>scl \ clear pulling down |
||||
begin %00000010 $0241 cbit@ until \ clock stretching to finish \ (%00000010:SCLPIN) \ (P6IN:SCLIN) \ ($0241:P6IN) |
||||
%00000010 $0245 cbis! \ SCL output \ (%00000010:SCLPIN) \ (P6DIR:SCLDIR) \ ($0245:P6DIR) |
||||
; |
||||
|
||||
: >sda ( f -- ) \ write f to SDA line |
||||
dup |
||||
%00000100 $0243 rot if cbis! else cbic! then \ (%00000100:SDAPIN) \ (P6OUT:SDAOUT) \ ($0243:P6OUT) |
||||
%00000100 $0245 rot if cbic! else cbis! then \ release to input when 1 \ (%00000100:SDAPIN) \ (P6DIR:SDADIR) \ ($0245:P6DIR) |
||||
; |
||||
|
||||
: sda> ( -- f ) \ read status of SDA line |
||||
%00000100 $0241 c@ and 0<> \ (%00000100:SDAPIN) \ (P6IN:SDAIN) \ ($0241:P6IN) |
||||
; |
||||
|
||||
: i2c-init ( -- ) \ initialise bit-banged I2C |
||||
%00000010 $0245 cbis! \ SCL output \ (%00000010:SCLPIN) \ (P6DIR:SCLDIR) \ ($0245:P6DIR) |
||||
1>scl |
||||
%00000100 $0245 cbic! \ SDA input \ (%00000100:SDAPIN) \ (P6DIR:SDADIR) \ ($0245:P6DIR) |
||||
; |
||||
|
||||
: i2c-half ( -- ) \ half-cycle timing delay for I2C |
||||
50 0 do loop ; \ ? inline |
@ -0,0 +1,15 @@
@@ -0,0 +1,15 @@
|
||||
\ i2c-bb-base.tmplfill: bitbanged i2c driver template filler for MSP430G2553 |
||||
\ chosen here: SCL:P6.1 SDA:P6.2 |
||||
\ compile into constant-free file with: |
||||
\ python templates/replace_constants.py templates/i2c-bb-base.fs fr2476/i2c-bb-base.tmplfill fr2476/port-regs.fs |
||||
|
||||
%00000010 constant SCLPIN |
||||
%00000100 constant SDAPIN |
||||
|
||||
P6OUT constant SCLOUT |
||||
P6DIR constant SCLDIR |
||||
P6IN constant SCLIN |
||||
|
||||
P6OUT constant SDAOUT |
||||
P6DIR constant SDADIR |
||||
P6IN constant SDAIN |
@ -1,4 +1,4 @@
@@ -1,4 +1,4 @@
|
||||
\ generated from template: templates/replace_constants.py templates/i2c-bb-base.fs g2553/i2c-bb-base.tmplfill g2553/port-regs.fs |
||||
\ generated from template: templates/replace_constants.py templates/i2c-bb-base.template g2553/i2c-bb-base.tmplfill g2553/port-regs.fs |
||||
\ bit-banged i2c driver, base words |
||||
\ There have to be 1..10 kΩ resistors on SDA and SCL to pull them up to idle state. |
||||
\ Master only. Supports clock stretching. |
@ -0,0 +1,7 @@
@@ -0,0 +1,7 @@
|
||||
|
||||
compiletoflash |
||||
|
||||
: cornerstone ( Name ) ( -- ) |
||||
<builds begin here $1FF and while 0 , repeat |
||||
does> begin dup $1FF and while 1+ repeat eraseflashfrom |
||||
; |
@ -0,0 +1,6 @@
@@ -0,0 +1,6 @@
|
||||
|
||||
compiletoflash |
||||
|
||||
: cornerstone ( Name ) ( -- ) |
||||
<builds does> eraseflashfrom |
||||
; |
@ -0,0 +1,45 @@
@@ -0,0 +1,45 @@
|
||||
|
||||
\ A convenient memory dump helper |
||||
|
||||
: u.4 ( u -- ) 0 <# # # # # #> type ; |
||||
: u.2 ( u -- ) 0 <# # # #> type ; |
||||
|
||||
: dump16 ( addr -- ) \ Print 16 bytes memory |
||||
base @ >r hex |
||||
$F bic |
||||
dup hex. ." : " |
||||
|
||||
dup 16 + over do |
||||
i c@ u.2 space \ Print data with 2 digits |
||||
i $F and 7 = if 2 spaces then |
||||
loop |
||||
|
||||
." | " |
||||
|
||||
dup 16 + swap do |
||||
i c@ 32 u>= i c@ 127 u< and if i c@ emit else [char] . emit then |
||||
i $F and 7 = if 2 spaces then |
||||
loop |
||||
|
||||
." |" cr |
||||
r> base ! |
||||
; |
||||
|
||||
: dump ( addr len -- ) \ Print a memory region |
||||
cr |
||||
over 15 and if 16 + then \ One more line if not aligned on 16 |
||||
begin |
||||
swap ( len addr ) |
||||
dup dump16 |
||||
16 + ( len addr+16 ) |
||||
swap 16 - ( addr+16 len-16 ) |
||||
dup 0< |
||||
until |
||||
2drop |
||||
; |
||||
|
||||
\ A small helper to find occurences of a special bit pattern |
||||
|
||||
: scanrange ( pattern end-addr start-addr -- ) |
||||
do dup i @ = if i 16 dump then 2 +loop drop |
||||
; |
@ -0,0 +1,39 @@
@@ -0,0 +1,39 @@
|
||||
|
||||
compiletoflash |
||||
|
||||
: u.4 ( u -- ) 0 <# # # # # #> type ; |
||||
: u.2 ( u -- ) 0 <# # # #> type ; |
||||
|
||||
: hexdump ( -- ) \ Dumps complete Flash |
||||
cr hex |
||||
|
||||
\ MSP430F2274: Complete: $FFFF $8000 |
||||
\ MSP430G2553: Complete: $FFFF $C000 |
||||
|
||||
$FFFF $C000 \ Complete image with Dictionary |
||||
do |
||||
\ Check if it would be $FFFF only: |
||||
0 \ Not worthy to print |
||||
i #16 + i do \ Scan data |
||||
i c@ $FF <> or \ Set flag if there is a non-$FF byte |
||||
loop |
||||
|
||||
if |
||||
." :10" i u.4 ." 00" \ Write record-intro with 4 digits. |
||||
$10 \ Begin checksum |
||||
i $FF and + \ Sum the address bytes |
||||
i >< $FF and + \ separately into the checksum |
||||
|
||||
i #16 + i do |
||||
i c@ u.2 \ Print data with 2 digits |
||||
i c@ + \ Sum it up for Checksum |
||||
loop |
||||
|
||||
negate u.2 \ Write Checksum |
||||
cr |
||||
then |
||||
|
||||
#16 +loop |
||||
." :00000001FF" cr |
||||
decimal |
||||
; |
@ -0,0 +1,273 @@
@@ -0,0 +1,273 @@
|
||||
|
||||
compiletoflash |
||||
|
||||
\ ------------------------------------------------ |
||||
\ A quick list of words - a wish of Paul Verbeke |
||||
\ ------------------------------------------------ |
||||
|
||||
\ Dictionary structure is: |
||||
\ (2-aligned) |
||||
\ 1 Byte Flags |
||||
\ 1 Byte Name length and name characters as counted string, maybe with filling zero to align |
||||
\ (2-aligned) |
||||
\ 2 Bytes Link |
||||
\ Code entry point |
||||
|
||||
: list ( -- ) |
||||
cr |
||||
dictionarystart |
||||
begin |
||||
dup 1+ ctype space |
||||
dictionarynext |
||||
until |
||||
drop |
||||
; |
||||
|
||||
\ ------------------------------------------------------------- |
||||
\ Which definitions are in use ? - An idea of Sandy Bumgarner |
||||
\ ------------------------------------------------------------- |
||||
|
||||
0 variable searchfor |
||||
|
||||
: searchcalls ( address-of-name -- ) |
||||
|
||||
\ As this searches for call opcodes until first ret, |
||||
\ it may fail on definitions using multiple exit points or inline strings. |
||||
\ Definitions in core include all sort of assembly tricks, direct jumps and others, so you cannot |
||||
\ rely on the output to determine what definitions in core are using Flamingo. |
||||
|
||||
dup skipstring |
||||
begin |
||||
2+ |
||||
dup @ $12B0 = if dup 2+ @ searchfor @ = if drop ctype space exit then then |
||||
dup @ $4130 = \ Ret opcode |
||||
until |
||||
2drop |
||||
; |
||||
|
||||
: uses ( -- ) \ "uses Flamingo" searches for definitions which contain calls to Flamingo. |
||||
cr ' searchfor ! \ Get code entry point |
||||
|
||||
dictionarystart |
||||
begin |
||||
dup c@ $FF <> if dup 1+ searchcalls then \ Skip invisible definitions |
||||
dictionarynext |
||||
until |
||||
drop |
||||
; |
||||
|
||||
\ ------------------------------------------------------------- |
||||
\ Disassembler |
||||
\ ------------------------------------------------------------- |
||||
|
||||
\ MSP430 Disassembler, Copyright (C) 2011 Matthias Koch |
||||
\ This is free software under GNU General Public License v3. |
||||
\ Knows MSP430 machine instructions, resolves call entry points and handles inline strings. |
||||
\ Usage: Specify your target address in disasm-$ and give disasm-step some calls. |
||||
|
||||
: name. ( Address -- ) \ Wenn die Adresse der Code-Anfang eines Dictionarywortes ist, wird es benannt. |
||||
>r \ If the address is Code-Start of a dictionary word, it gets named. |
||||
dictionarystart |
||||
begin |
||||
dup 1+ dup skipstring 2+ r@ = if ." --> " ctype else drop then |
||||
dictionarynext |
||||
until |
||||
r> 2drop |
||||
; |
||||
|
||||
0 variable disasm-$ \ Current position for disassembling |
||||
|
||||
: disasm-fetch \ ( -- Data ) Fetches opcodes and operands, increments disasm-$ |
||||
disasm-$ @ @ \ Holt Opcode oder Operand, incrementiert disasm-$ |
||||
2 disasm-$ +! ; |
||||
|
||||
: u.4 0 <# # # # # #> type ; |
||||
: u.ns 0 <# #s #> type ; |
||||
: u.h u.ns ." h"; |
||||
: register. ." r" decimal u.ns hex ; |
||||
: disasm-const ." #" u.h ; |
||||
|
||||
: disasm-jumps \ Bei Sprüngen ist bereits alle Information im Opcode enthalten. |
||||
dup $1C00 and \ Jumps have all information readily in their opcodes. |
||||
\ ( Opcode -- ) |
||||
case |
||||
$0000 of ." jnz " endof |
||||
$0400 of ." jz " endof |
||||
$0800 of ." jnc " endof |
||||
$0C00 of ." jc " endof |
||||
$1000 of ." jn " endof |
||||
$1400 of ." jge " endof |
||||
$1800 of ." jl " endof |
||||
$1C00 of ." jmp " endof |
||||
endcase |
||||
|
||||
\ Calculate Offset |
||||
$03FF and ( Offset ) |
||||
dup $0200 and if $FC00 or then |
||||
shl disasm-$ @ + u.4 |
||||
; |
||||
|
||||
: disasm-source \ Takes care of source operands |
||||
\ Kümmert sich um den Quelloperanden des Befehls ! |
||||
( Opcode Source-Reg -- Opcode ) |
||||
|
||||
over ( Opcode Source-Reg Opcode ) |
||||
dup $0040 and if ." .b " else ." .w " then |
||||
|
||||
$0030 and |
||||
case |
||||
$0000 of \ Register |
||||
case |
||||
3 of 0 disasm-const endof \ CG |
||||
dup register. |
||||
endcase |
||||
endof |
||||
|
||||
$0010 of \ Indexed |
||||
case |
||||
2 of ." &" disasm-fetch u.h endof \ SR |
||||
3 of 1 disasm-const endof \ CG |
||||
|
||||
dup disasm-fetch u.h ." (" register. ." )" |
||||
endcase |
||||
endof |
||||
|
||||
$0020 of \ Indirect |
||||
case |
||||
2 of 4 disasm-const endof \ SR |
||||
3 of 2 disasm-const endof \ CG |
||||
|
||||
dup ." @" register. |
||||
endcase |
||||
endof |
||||
|
||||
$0030 of \ Indirect Autoincrement |
||||
\ sr: 8 cg: -1 pc: Constant All others: @rx+ |
||||
case |
||||
2 of 8 disasm-const endof \ SR |
||||
3 of -1 disasm-const endof \ CG |
||||
0 of disasm-fetch disasm-const endof \ PC |
||||
|
||||
dup ." @" register. ." +" |
||||
endcase |
||||
endof |
||||
endcase |
||||
; |
||||
|
||||
: disasm-destination \ Takes care of destination operands in two-operand-instructions |
||||
." , " \ Kümmert sich um den Zieloperanden bei zwei-Operanden-Befehlen. |
||||
dup $0080 and \ ( Opcode -- ) |
||||
if \ Indexed Destination |
||||
|
||||
dup $000F and 2 = |
||||
if \ SR - Absolute addressing |
||||
drop disasm-fetch ." &" u.h |
||||
else \ Normal Indexed |
||||
disasm-fetch u.h ." (" $000F and register. ." )" |
||||
then |
||||
|
||||
else \ Register Destination |
||||
$000F and register. |
||||
then |
||||
; |
||||
|
||||
: disasm-string ( -- ) \ Takes care of an inline string |
||||
disasm-$ @ dup ctype skipstring disasm-$ ! |
||||
; |
||||
|
||||
: disasm-single ( Opcode -- ) |
||||
dup $0F80 and |
||||
case |
||||
$0000 of ." rrc" endof |
||||
$0080 of ." swpb" endof |
||||
$0100 of ." rra" endof |
||||
$0180 of ." sxt" endof |
||||
$0200 of ." push" endof |
||||
$0280 of ." call" endof |
||||
$0300 of ." reti" endof |
||||
|
||||
." Unknown Opcode " |
||||
endcase |
||||
|
||||
dup $000F and \ Mask Source Register |
||||
( Opcode Source-Reg ) |
||||
disasm-source |
||||
( Opcode ) |
||||
|
||||
\ Bei Call-Befehlen versuchen, den Einsprung zu benennen und Strings zu erkennen. |
||||
\ Try to give calls a name and detect inline strings. |
||||
$12B0 = if |
||||
disasm-$ @ 2- @ \ Fetch call target address |
||||
dup name. \ Try to give it a name |
||||
case |
||||
['] ." $1E + of ." .' " disasm-string ." '" endof \ It is ." runtime ? |
||||
['] s" $06 + of ." s' " disasm-string ." '" endof \ It is s" runtime ? |
||||
['] c" $06 + of ." c' " disasm-string ." '" endof \ It is c" runtime ? |
||||
endcase |
||||
then |
||||
; |
||||
|
||||
: disasm-double ( Opcode -- ) |
||||
dup $0F00 and 8 rshift \ Mask Source Register |
||||
( Opcode Source-Reg ) |
||||
disasm-source |
||||
( Opcode ) |
||||
disasm-destination |
||||
; |
||||
|
||||
: disasm ( -- ) \ Disassembles one machine instruction and advances disasm-$ |
||||
disasm-fetch \ Fetch Opcode and test instruction type. |
||||
\ Opcode holen und auf Befehlstyp hin prüfen. |
||||
|
||||
dup $F000 and ( Opcode Instruction-Mask ) |
||||
case |
||||
$1000 of disasm-single endof |
||||
$2000 of disasm-jumps endof |
||||
$3000 of disasm-jumps endof |
||||
$4000 of ." mov" disasm-double endof |
||||
$5000 of ." add" disasm-double endof |
||||
$6000 of ." addc" disasm-double endof |
||||
$7000 of ." subc" disasm-double endof |
||||
$8000 of ." sub" disasm-double endof |
||||
$9000 of ." cmp" disasm-double endof |
||||
$A000 of ." dadd" disasm-double endof |
||||
$B000 of ." bit" disasm-double endof |
||||
$C000 of ." bic" disasm-double endof |
||||
$D000 of ." bis" disasm-double endof |
||||
$E000 of ." xor" disasm-double endof |
||||
$F000 of ." and" disasm-double endof |
||||
|
||||
." Unknown Opcode " drop |
||||
endcase |
||||
; |
||||
|
||||
: memstamp \ ( Addr -- ) Shows a memory location nicely |
||||
dup u.4 ." : " @ u.4 ." " ; |
||||
|
||||
: disasm-step ( -- ) |
||||
disasm-$ @ \ Note current position |
||||
dup memstamp disasm cr \ Disassemble one instruction |
||||
|
||||
begin \ Write out all disassembled memory locations |
||||
2+ dup disasm-$ @ <> |
||||
while |
||||
dup memstamp cr |
||||
repeat |
||||
drop |
||||
; |
||||
|
||||
: seec ( -- ) \ Continues to see |
||||
base @ hex cr |
||||
|
||||
begin |
||||
disasm-$ @ @ $4130 = \ Flag: Loop terminates with ret |
||||
disasm-step |
||||
until |
||||
|
||||
base ! |
||||
; |
||||
|
||||
: see ( -- ) \ Takes name of definition and shows its contents from beginning to first ret |
||||
' disasm-$ ! |
||||
seec |
||||
; |
@ -0,0 +1 @@
@@ -0,0 +1 @@
|
||||
Files copied from mecrisp distribution tarball. |
@ -0,0 +1,37 @@
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env python3 |
||||
|
||||
import re |
||||
import argparse |
||||
import sys |
||||
|
||||
argparser = argparse.ArgumentParser(description='Replace constants in forth sources by values. No files changed, output will be send to stdout.') |
||||
argparser.add_argument('template', help='Base template on which replacements should be made') |
||||
argparser.add_argument('definitions', nargs='*', help='Where to read the constants from') |
||||
args = argparser.parse_args() |
||||
|
||||
get_const = re.compile("^(?:\s*|\\\\ @ +)(?P<value>[%$#]?\w+)\s+(?:constant|CONSTANT)\s+(?P<name>[^\s]+)(?:\Z|\s.*)") |
||||
# supports also inside comments with special syntax, '\ @ VALUE constant NAME' |
||||
replace_dict = {} |
||||
replace_re = {} |
||||
comments = re.compile(r"(^[^\\]*)(\\.*|$)") |
||||
|
||||
print("\ generated from template: %s" % (" ".join(sys.argv[:]))) |
||||
|
||||
# build replacement dictionary along with regexps that check for occurences |
||||
for filename in args.definitions + [args.template]: |
||||
with open(filename) as f: |
||||
for line in f: |
||||
m = get_const.match(line) |
||||
if m is not None: |
||||
replace_dict[m.group('name')] = m.group('value') |
||||
replace_re[m.group('name')] = re.compile(m.group('name')) |
||||
|
||||
with open(args.template) as f: |
||||
for line in f: |
||||
s = list(comments.match(line.rstrip()).groups()) |
||||
for nam in sorted(replace_re.keys(),reverse=True): # revsort to avoid sub-name clashes |
||||
upd, k = replace_re[nam].subn(replace_dict[nam], s[0]) |
||||
if k > 0: |
||||
s[0] = upd |
||||
s.append(" \\ ("+replace_dict[nam]+":"+nam+")") |
||||
print("".join(s)) |
@ -0,0 +1,19 @@
@@ -0,0 +1,19 @@
|
||||
\ on_top_of basis-fr2476.fs |
||||
|
||||
<<basis>> |
||||
|
||||
compiletoflash |
||||
|
||||
include ../flib/mecrisp/dump.txt |
||||
include ../flib/mecrisp/insight.txt |
||||
|
||||
cornerstone <<insight>> |
||||
|
||||
include launchpad.fs |
||||
|
||||
cornerstone <<launchpad>> |
||||
|
||||
include ../flib/fr2476/i2c-bb-base.fs |
||||
include ../flib/drivers/i2c-bb.fs |
||||
|
||||
compiletoram |
Loading…
Reference in new issue