Hi there - I have an interesting tachyon/minicom phenomenon:
If I enter
uart1 2- CFA>NFA CR PRINT$
I get the following output intended (@MJB that's what I needed )
uart1 ok
plus this interesting unintended output:
.. Minicom2.7
The String "Minicom2.7" behaves as if I'd have had used the keyboard. With backspace I can delete just to the ".." prompt.
I checked the receive buffer at $7400 (right?)
Hi there - I have an interesting tachyon/minicom phenomenon:
If I enter
uart1 2- CFA>NFA CR PRINT$
I get the following output intended (@MJB that's what I needed )
uart1 ok
plus this interesting unintended output:
.. Minicom2.7
The String "Minicom2.7" behaves as if I'd have had used the keyboard. With backspace I can delete just to the ".." prompt.
I checked the receive buffer at $7400 (right?)
This seems that minicom appends something ("Minicom2.7) to my input?! Strange - bug or feature?
Best regards,
proplem
maybe let's note:
--- get the address of the name of the variable address on TOS
--- variable data lives in the variable space
pub VARNAME$ ( var-address .. strptr )
$8000 OR CFA>NFA 1+ ;
--- get the address of the name of the table address on TOS
--- table data lives in the word/code space
pub TABNAME$ ( table-address .. strptr )
2- CFA>NFA 1+ ;
TABLE mytab
mytab TABNAME$ PRINT$
WORD myword
myword VARNAME$ PRINT$
--- get the address of the name of the variable address on TOS
--- variable data lives in the variable space
pub VARNAME$ ( var-address .. strptr )
$8000 OR CFA>NFA 1+ ;
--- get the address of the name of the table address on TOS
--- table data lives in the word/code space
pub TABNAME$ ( table-address .. strptr )
2- CFA>NFA 1+ ;
TABLE mytab
mytab TABNAME$ PRINT$
WORD myword
myword VARNAME$ PRINT$
That's it MJB ! Thanks for clarifying. I hope I will be quiet now ...
Thanks to you both.
--- get the address of the name of the variable address on TOS
--- variable data lives in the variable space
pub VARNAME$ ( var-address .. strptr )
$8000 OR CFA>NFA 1+ ;
--- get the address of the name of the table address on TOS
--- table data lives in the word/code space
pub TABNAME$ ( table-address .. strptr )
2- CFA>NFA 1+ ;
TABLE mytab
mytab TABNAME$ PRINT$
WORD myword
myword VARNAME$ PRINT$
That's it MJB ! Thanks for clarifying. I hope I will be quiet now ...
Thanks to you both.
If you make some code that you do not need to keep secret,
let's see it ...
maybe we can learn from it, discuss it,
or at least praise it ;-)
I am still in so many other things that I hardly produce significant code.
But like the 'tricky' Tachyon internals ... ;-)
@Peter Jakacki- the following code is from the kernel source.
long ~c
--- switch I/O to console but save current device key&emit
pub [CON uemit @ ~c !
--- reset character I/O ( EMIT & KEY) back to default console
pub CON uemit ~ ;
--- retyrn from console and restore previous device
pub CON] ~c @ uemit ! ;
1. If I recall it correctly uemit is a word not a long?
2. Is there a reason why ~c is a long or is there a waste of 2 bytes :-)
3. Does uemit ~ delete 4 bytes then?
4. And uemit ! overwrites 4 bytes also?
Can you explain?
@Peter Jakacki- the following code is from the kernel source.
long ~c
--- switch I/O to console but save current device key&emit
pub [CON uemit @ ~c !
--- reset character I/O ( EMIT & KEY) back to default console
pub CON uemit ~ ;
--- retyrn from console and restore previous device
pub CON] ~c @ uemit ! ;
1. If I recall it correctly uemit is a word not a long?
2. Is there a reason why ~c is a long or is there a waste of 2 bytes :-)
3. Does uemit ~ delete 4 bytes then?
4. And uemit ! overwrites 4 bytes also?
Can you explain?
I don't use these ones much but uemit and ukey are part of one long so they can be cleared in one operation rather than individually.
Hi there - I've got some redirection hurdles to take.
pub OLD+UARTEMIT ( ch -- )
\ emit to currently set emit and mirror to RS232
DUP
oldEMIT W@ DUP 0 <> IF CALL ELSE DROP THEN
uemit W@ DUP 0 = IF DROP (EMIT) ELSE CALL THEN
EMIT1
;
pub BACKUPEMIT
uemit W@ oldEMIT W! \ remember old emit vector
;
pub RESTOREEMIT
oldEMIT W@ uemit W!
;
pub UART1> ( -- ) \ redirect output to COM port
BACKUPEMIT
' EMIT1 uemit W!
;
pub OLD+SER> ( -- ) \ mirror emit to SER
BACKUPEMIT
' OLD+UARTEMIT uemit W!
;
pub OLD> ( -- ) \ reset output vector
RESTOREEMIT
;
If I enter
'a' OLD+UARTEMIT
it is working fine the output is written to the UART and to console.
If I try to redirect with
OLD+UART1>
I get an immediate tachyon reboot.
What I intend is to output to console and to UART1
There is one constraint - the redirecting must work also via telnet !!
That means I want to output to UART and to LAN under telnet and to UART and CON on console.
Maybe I do something completely wrong but I don't see what.
Any help is appreciated.
Best regards,
proplem Edit: Maybe the problem is that I only wrote uemit and not ukey? Do they have to be written at the same time?
--- get the address of the name of the variable address on TOS
--- variable data lives in the variable space
pub VARNAME$ ( var-address .. strptr )
$8000 OR CFA>NFA 1+ ;
--- get the address of the name of the table address on TOS
--- table data lives in the word/code space
pub TABNAME$ ( table-address .. strptr )
2- CFA>NFA 1+ ;
TABLE mytab
mytab TABNAME$ PRINT$
WORD myword
myword VARNAME$ PRINT$
That's it MJB ! Thanks for clarifying. I hope I will be quiet now ...
Thanks to you both.
If you make some code that you do not need to keep secret,
let's see it ...
maybe we can learn from it, discuss it,
or at least praise it ;-)
I am still in so many other things that I hardly produce significant code.
But like the 'tricky' Tachyon internals ... ;-)
1. The address of the EMIT/KEY routie is not important but the setting of the uemit/ukey vector is.
2. KEY checks the ukey vector for an entry and if calls that if set. All you are doing is making it call itself until it crashes.
@Proplem
in other words ...
normally you do not have to preserve the previous value of ukey and uemit
you just assign the redirection to it.
And then you revert to having them cleared to 0 via CON.
Typically you just define your redirection word
pub MYSER ' myemit uemit W! ' mykey ukey W! ;
MYSER ." now it sends to my serial line " CON ." now normal again"
As far as I can see I shot myself into the knee with redirecting. After throwing everything away and beginning by zero I'm getting forward. Thanks for your help.
Now I've got a new issue: I need to insert a callback into EASYNET which is called when the connection is finished.
I thought BYE would be the right place but BYE is not called after a client break disconnect. I tried several places in EASYNET with console messages but there is redirection in process so no output is visible at the console.
@Peter could you give an advice where I can insert my connection close/interrupt callback?
As far as I can see I shot myself into the knee with redirecting. After throwing everything away and beginning by zero I'm getting forward. Thanks for your help.
Now I've got a new issue: I need to insert a callback into EASYNET which is called when the connection is finished.
I thought BYE would be the right place but BYE is not called after a client break disconnect. I tried several places in EASYNET with console messages but there is redirection in process so no output is visible at the console.
@Peter could you give an advice where I can insert my connection close/interrupt callback?
when I was debugging inside EASYNET I had a debug print routine which saved uemit, cleared it to 0 did the printing and restored the old uemit .
Actually just use:
[CON ." debug message" CON]
DISC?
checks if a disconnection has happened.
and uses BYE internally, so adding to BYE seems ok
I can not try it out,
but this might work.
pub MYBYE ." do what needs to be done" sDISCON ; --- sDISCON is needed since it is overwritten by placing a call to MYBYE at the first wordcode inside the old BYE
+VECTOR BYE MYBYE
I have a number of I/O drivers mostly written in assembly with small Spin interfaces and I would like to convert these to Tachyon. How do I go about packaging the assembly portions as part of Tachyon to load into a cog as needed? The actual interfaces are not big problems, mostly it's a matter of filling or emptying a buffer. I'm sure there are examples somewhere.
I have a number of I/O drivers mostly written in assembly with small Spin interfaces and I would like to convert these to Tachyon. How do I go about packaging the assembly portions as part of Tachyon to load into a cog as needed? The actual interfaces are not big problems, mostly it's a matter of filling or emptying a buffer. I'm sure there are examples somewhere.
Hi Mike, just by way of a quick reply for now probably the easiest way is to just insert those sections directly into the Tachyon kernel source in the "ROMS" section.
org
roms byte "ROMS"
long @romend-@roms
byte "ROMS" ' verification sig.
Add a header for each "ROM" .
org
byte ".ROM" ' ROM signature
word @F32end-@F32 ' size
byte "F32 " ' name
Then in your Forth code you can select and load a ROM during runtime or interactively.
f32cmd 3 " F32 " LOADCOG
I'm sure you could also compile your ROMs separately but I haven't tried that yet. The method I use takes care of getting from hub memory into upper EEPROM when EXTEND is first loaded and before that hub memory area is overwritten.
It's a pity that we don't have the ability to include source files but the other thing is that you may have to rename your symbols to avoid conflict.
I have a number of I/O drivers mostly written in assembly with small Spin interfaces and I would like to convert these to Tachyon. How do I go about packaging the assembly portions as part of Tachyon to load into a cog as needed? The actual interfaces are not big problems, mostly it's a matter of filling or emptying a buffer. I'm sure there are examples somewhere.
Hi Mike, just by way of a quick reply for now probably the easiest way is to just insert those sections directly into the Tachyon kernel source in the "ROMS" section.
org
roms byte "ROMS"
long @romend-@roms
byte "ROMS" ' verification sig.
Add a header for each "ROM" .
org
byte ".ROM" ' ROM signature
word @F32end-@F32 ' size
byte "F32 " ' name
Then in your Forth code you can select and load a ROM during runtime or interactively.
f32cmd 3 " F32 " LOADCOG
I'm sure you could also compile your ROMs separately but I haven't tried that yet. The method I use takes care of getting from hub memory into upper EEPROM when EXTEND is first loaded and before that hub memory area is overwritten.
It's a pity that we don't have the ability to include source files but the other thing is that you may have to rename your symbols to avoid conflict.
I am thinking about similar ideas to get some PASM drivers into Tachyon.
But I ran into space problems because the added "ROM" will make everything larger than 32k.
My question is, what can I kick out to make room. E.g. I do not need VGA. Will I get problems if I remove it?
And Now for Something Completely Different:
I use some SPI ADCs (TI ADS1018). The SPI outputs data while a new command is written.
As far as I have understood your SPI words can transmit or (xor) receive but not both. Am I correct or is there another solution?
Of course I can write this myself shift-out, shift in and clock in a loop.
And Now for Something Completely Different:
I use some SPI ADCs (TI ADS1018). The SPI outputs data while a new command is written.
As far as I have understood your SPI words can transmit or (xor) receive but not both. Am I correct or is there another solution?
Of course I can write this myself shift-out, shift in and clock in a loop.
have a look in Tachyon.spin
{HELP SPIO ( send -- receive ) ( A: miso mosi sck )
REGS: 0=sck 1=mosi 2=miso 3=cnt
*** SERIAL PERIPHERAL INPUT OUTPUT MODULE ***
Transfers 1 to 32 bits msb first
Transmit data must be left justified ready for transmission
Receive data is in correct format
Data is shifted in and out while the clock is low
The clock is left low between transfers
}
org _RUNMOD
' COGREGS: 0=sck 1=mosi 2=miso 3=cnt
' SPIO ( send -- receive ) ( A: miso mosi sck )
@rbehm - the ROMs themselves don't take up any hub RAM after they have been moved into upper EEPROM when EXTEND is loaded. Compiling them with the kernel is the easy way to get them into the system in the first place and in reality even when EXTEND may overwrite that area in hub RAM it doesn't matter as that image still exists in lower EEPROM. So before a BACKUP takes place SAVEROMS is run to copy the ROMs from lower EEPROM to upper EEPROM and after which the SAVEROMS routine is forgotten as it is no longer needed.
Also as MJB mentioned, there is the SPIO module that can be used for simultaneous SPI input/output whereas the SPIxx instructions are simple dedicated instructions optimized for fast read or write.
Hi there - feature request: UART ROM (used by UARTCOG.FTH) float pin after transmit
The problem is that after sending data the tx pin is hold as output which avoids reusing this pin for other cogs.
Would it be possible and if - could somebody add the lines to the assembler code to let the tx pin float after transmitting the buffer?
Here is the code (copied from tachyon):
'{
CON
fdwidth = $FF
fdbits = 8
DAT { *** UART - FULL-DUPLEX SERIAL TRANSMIT & RECEIVE *** }
org
byte ".ROM" ' ROM signature
word @UARTEnd-@UART ' size
byte "UART " ' name
' 1234567890
{
PAR STRUCTURE
byte rxpin
byte txpin
word mode
long bit_ticks
word rxbuf,rxsiz
word txbuf,txsz
word indices ' points to 4 words in memory
long [rxwr,rxrd] 'cog does not use rxrd
long [txwr,txrd]
}
'' mode bit 0 = invert rx
'' mode bit 1 = invert tx
'' mode bit 2 = open-drain/source tx
'' mode bit 3 = ignore tx echo on rx
org
'
' Entry
'
UART mov ut1,par 'get structure address
' rxpin
rdbyte ut2,ut1 'get rx_pin
mov fdrxmask,#1
shl fdrxmask,ut2 'rxmask
' txpin
add ut1,#1 '@tx_pin
rdbyte ut2,ut1 ' get tx pin
mov fdtxmask,#1 'txmask
shl fdtxmask,ut2
' mode
add ut1,#1 ' @mode
rdword fdmode,ut1 'get rxtx_mode
' baud rate ticks
add ut1,#2 'get bit_ticks
rdlong bitticks,ut1
mov fstticks,bitticks 'precalc optimum start bit timing
shr fstticks,#1
sub fstticks,#12 ' offset
'
add ut1,#4 ' @rxbuf,rxsiz
' rxbuf,rxsz
rdword rxbuff,ut1
add ut1,#2
rdword fdrxsz,ut1
sub fdrxsz,#1 ' rx size as mask
add ut1,#2
' txbuf,txsz
rdword txbuff,ut1
add ut1,#2
rdword fdtxsz,ut1
sub fdtxsz,#1 ' 256 -> $FF etc
' indice ptr --> rxwr,rxrd,txwr,txrd
add ut1,#2
rdword ut1,ut1 ' update ut1 - points to indices themselves
mov fdrxwrP,ut1 ' rxwr index = ut1
mov fdrxwr,#0 ' zero local rxwr
wrword fdrxwr,ut1 ' zero hub rxwr
add ut1,#2 ' @rxrd
wrword fdrxwr,ut1 ' zero hub rxrd (no local needed)
add ut1,#2 ' @txwr
mov fdtxwrP,ut1
mov fdtxwr,#0
wrword fdtxwr,ut1 ' zero hub txwr
add ut1,#2 ' @txrd
mov fdtxrdP,ut1
mov fdtxrd,#0
wrword fdtxrd,ut1 ' zero hub txrd
'
test fdmode,#%100 wz 'init tx pin according to mode
test fdmode,#%010 wc
if_z_ne_c or outa,fdtxmask
if_z or dira,fdtxmask
mov txcode,#fdtx 'initialize ping-pong multitasking
'
' Receive
'
fdrx mov rxbits,#fdbits+1 'ready to receive byte
mov fdcnt,fstticks
fdrxlp jmpret rxcode,txcode 'run a chunk of transmit code, then return
test fdmode,#%001 wz 'wait for start bit on rx pin
test fdrxmask,ina wc
if_z_eq_c jmp #fdrxlp
add fdcnt,cnt
:bit add fdcnt,bitticks 'ready next bit period
:wait jmpret rxcode,txcode 'run a chuck of transmit code, then return
mov ut1,fdcnt 'check if bit receive period done
sub ut1,cnt
cmps ut1,#0 wc
if_nc jmp #:wait
test fdrxmask,ina wc ' receive bit on rx pin
rcr rxdata,#1
djnz rxbits,#:bit
' CHARACTER RECEIVED
xor rxdata,invsp ' invert rxd stop bit (0=ok)
test fdmode,#%001 wz ' if rx inverted, invert byte
if_nz xor rxdata,alldata
shr rxdata,#32-fdbits-1 ' justify and trim received byte
mov ut2,fdrxwr ' get rx write index
add ut2,rxbuff ' offset into buffer
wrbyte rxdata,ut2 ' save byte (could be word if need be)
add fdrxwr,#1
and fdrxwr,fdrxsz ' wrap rx write index
wrword fdrxwr,fdrxwrP ' update rx write index in hub
jmp #fdrx 'byte done, receive next byte
'
'
' Transmit
'
fdtx jmpret txcode,rxcode ' run a chunk of receive code, then return
rdword fdtxwr,fdtxwrP ' read hub txwr to check for data
cmp fdtxwr,fdtxrd wz ' data available if wr<>rd?
if_z jmp #fdtx
mov ut3,fdtxrd ' get raw index
and ut3,fdtxsz ' wrap read index only when accessing data
add ut3,txbuff ' read data from txbuf
rdbyte txdata,ut3 ' get data
or txdata,fdstops ' ready byte to transmit
add fdtxrd,#1 ' update local tx read
wrword fdtxrd,fdtxrdP ' update hub txrd
shl txdata,#1 ' insert start bit
mov txbits,#fdbits+1+1 ' data+start+stops
test fdmode,#%110 wz ' any special modes?
if_nz jmp #fdtxm
mov txcnt,cnt
:bit shr txdata,#1 wc
muxc outa,fdtxmask
add txcnt,bitticks ' ready next cnt
:wait jmpret txcode,rxcode 'run a chunk of receive code, then return
mov ut1,txcnt 'check if bit transmit period done
sub ut1,cnt
cmps ut1,#0 wc
if_nc jmp #:wait
djnz txbits,#:bit 'another bit to transmit?
jmp #fdtx 'byte done, transmit next byte
fdtxm
mov txcnt,cnt
:bit ' bit loop
test fdmode,#%100 wz ' invert bit on tx pin according to mode
test fdmode,#%010 wc ' open-drain/source?
if_z_and_c xor txdata,#1
shr txdata,#1 wc
if_z muxc outa,fdtxmask ' output bit normally
if_nz muxnc dira,fdtxmask ' output bit open-drain
add txcnt,bitticks ' ready next cnt
:wait jmpret txcode,rxcode 'run a chunk of receive code, then return
mov ut1,txcnt 'check if bit transmit period done
sub ut1,cnt
cmps ut1,#0 wc
if_nc jmp #:wait
djnz txbits,#:bit 'another bit to transmit?
jmp #fdtx 'byte done, transmit next byte
invsp long $8000_0000 'inverts stop to use as a flag etc
alldata long $FFFF_FFFF
fdstops long $FFFF_FF00
uartend
'
'
' Uninitialized data
'
ut1 res 1
ut2 res 1
ut3 res 1
fdmode res 1
bitticks res 1
fstticks res 1
fdrxmask res 1
fdrxwr res 1 ' local copy of rx write
fdtxrd res 1 ' local copy
fdtxwr res 1
fdrxwrP res 1
fdrxrdP res 1
fdtxwrP res 1
fdtxrdP res 1
rxbuff res 1
rxdata res 1
rxbits res 1
fdcnt res 1
rxcode res 1
fdtxmask res 1
txbuff res 1
txdata res 1
txbits res 1
txcnt res 1
txcode res 1
fdrxsz res 1
fdtxsz res 1
'}
Hi there - feature request: UART ROM (used by UARTCOG.FTH) float pin after transmit
The problem is that after sending data the tx pin is hold as output which avoids reusing this pin for other cogs.
Would it be possible and if - could somebody add the lines to the assembler code to let the tx pin float after transmitting the buffer?
Here is the code (copied from tachyon):
'{
CON
fdwidth = $FF
fdbits = 8
DAT { *** UART - FULL-DUPLEX SERIAL TRANSMIT & RECEIVE *** }
org
byte ".ROM" ' ROM signature
word @UARTEnd-@UART ' size
byte "UART " ' name
' 1234567890
{
PAR STRUCTURE
byte rxpin
byte txpin
word mode
long bit_ticks
word rxbuf,rxsiz
word txbuf,txsz
word indices ' points to 4 words in memory
long [rxwr,rxrd] 'cog does not use rxrd
long [txwr,txrd]
}
'' mode bit 0 = invert rx
'' mode bit 1 = invert tx
'' mode bit 2 = open-drain/source tx
'' mode bit 3 = ignore tx echo on rx
org
'
' Entry
'
UART mov ut1,par 'get structure address
' rxpin
rdbyte ut2,ut1 'get rx_pin
mov fdrxmask,#1
shl fdrxmask,ut2 'rxmask
' txpin
add ut1,#1 '@tx_pin
rdbyte ut2,ut1 ' get tx pin
mov fdtxmask,#1 'txmask
shl fdtxmask,ut2
' mode
add ut1,#1 ' @mode
rdword fdmode,ut1 'get rxtx_mode
' baud rate ticks
add ut1,#2 'get bit_ticks
rdlong bitticks,ut1
mov fstticks,bitticks 'precalc optimum start bit timing
shr fstticks,#1
sub fstticks,#12 ' offset
'
add ut1,#4 ' @rxbuf,rxsiz
' rxbuf,rxsz
rdword rxbuff,ut1
add ut1,#2
rdword fdrxsz,ut1
sub fdrxsz,#1 ' rx size as mask
add ut1,#2
' txbuf,txsz
rdword txbuff,ut1
add ut1,#2
rdword fdtxsz,ut1
sub fdtxsz,#1 ' 256 -> $FF etc
' indice ptr --> rxwr,rxrd,txwr,txrd
add ut1,#2
rdword ut1,ut1 ' update ut1 - points to indices themselves
mov fdrxwrP,ut1 ' rxwr index = ut1
mov fdrxwr,#0 ' zero local rxwr
wrword fdrxwr,ut1 ' zero hub rxwr
add ut1,#2 ' @rxrd
wrword fdrxwr,ut1 ' zero hub rxrd (no local needed)
add ut1,#2 ' @txwr
mov fdtxwrP,ut1
mov fdtxwr,#0
wrword fdtxwr,ut1 ' zero hub txwr
add ut1,#2 ' @txrd
mov fdtxrdP,ut1
mov fdtxrd,#0
wrword fdtxrd,ut1 ' zero hub txrd
'
test fdmode,#%100 wz 'init tx pin according to mode
test fdmode,#%010 wc
if_z_ne_c or outa,fdtxmask
if_z or dira,fdtxmask
mov txcode,#fdtx 'initialize ping-pong multitasking
'
' Receive
'
fdrx mov rxbits,#fdbits+1 'ready to receive byte
mov fdcnt,fstticks
fdrxlp jmpret rxcode,txcode 'run a chunk of transmit code, then return
test fdmode,#%001 wz 'wait for start bit on rx pin
test fdrxmask,ina wc
if_z_eq_c jmp #fdrxlp
add fdcnt,cnt
:bit add fdcnt,bitticks 'ready next bit period
:wait jmpret rxcode,txcode 'run a chuck of transmit code, then return
mov ut1,fdcnt 'check if bit receive period done
sub ut1,cnt
cmps ut1,#0 wc
if_nc jmp #:wait
test fdrxmask,ina wc ' receive bit on rx pin
rcr rxdata,#1
djnz rxbits,#:bit
' CHARACTER RECEIVED
xor rxdata,invsp ' invert rxd stop bit (0=ok)
test fdmode,#%001 wz ' if rx inverted, invert byte
if_nz xor rxdata,alldata
shr rxdata,#32-fdbits-1 ' justify and trim received byte
mov ut2,fdrxwr ' get rx write index
add ut2,rxbuff ' offset into buffer
wrbyte rxdata,ut2 ' save byte (could be word if need be)
add fdrxwr,#1
and fdrxwr,fdrxsz ' wrap rx write index
wrword fdrxwr,fdrxwrP ' update rx write index in hub
jmp #fdrx 'byte done, receive next byte
'
'
' Transmit
'
fdtx jmpret txcode,rxcode ' run a chunk of receive code, then return
rdword fdtxwr,fdtxwrP ' read hub txwr to check for data
cmp fdtxwr,fdtxrd wz ' data available if wr<>rd?
if_z jmp #fdtx
mov ut3,fdtxrd ' get raw index
and ut3,fdtxsz ' wrap read index only when accessing data
add ut3,txbuff ' read data from txbuf
rdbyte txdata,ut3 ' get data
or txdata,fdstops ' ready byte to transmit
add fdtxrd,#1 ' update local tx read
wrword fdtxrd,fdtxrdP ' update hub txrd
shl txdata,#1 ' insert start bit
mov txbits,#fdbits+1+1 ' data+start+stops
test fdmode,#%110 wz ' any special modes?
if_nz jmp #fdtxm
mov txcnt,cnt
:bit shr txdata,#1 wc
muxc outa,fdtxmask
add txcnt,bitticks ' ready next cnt
:wait jmpret txcode,rxcode 'run a chunk of receive code, then return
mov ut1,txcnt 'check if bit transmit period done
sub ut1,cnt
cmps ut1,#0 wc
if_nc jmp #:wait
djnz txbits,#:bit 'another bit to transmit?
jmp #fdtx 'byte done, transmit next byte
fdtxm
mov txcnt,cnt
:bit ' bit loop
test fdmode,#%100 wz ' invert bit on tx pin according to mode
test fdmode,#%010 wc ' open-drain/source?
if_z_and_c xor txdata,#1
shr txdata,#1 wc
if_z muxc outa,fdtxmask ' output bit normally
if_nz muxnc dira,fdtxmask ' output bit open-drain
add txcnt,bitticks ' ready next cnt
:wait jmpret txcode,rxcode 'run a chunk of receive code, then return
mov ut1,txcnt 'check if bit transmit period done
sub ut1,cnt
cmps ut1,#0 wc
if_nc jmp #:wait
djnz txbits,#:bit 'another bit to transmit?
jmp #fdtx 'byte done, transmit next byte
invsp long $8000_0000 'inverts stop to use as a flag etc
alldata long $FFFF_FFFF
fdstops long $FFFF_FF00
uartend
'
'
' Uninitialized data
'
ut1 res 1
ut2 res 1
ut3 res 1
fdmode res 1
bitticks res 1
fstticks res 1
fdrxmask res 1
fdrxwr res 1 ' local copy of rx write
fdtxrd res 1 ' local copy
fdtxwr res 1
fdrxwrP res 1
fdrxrdP res 1
fdtxwrP res 1
fdtxrdP res 1
rxbuff res 1
rxdata res 1
rxbits res 1
fdcnt res 1
rxcode res 1
fdtxmask res 1
txbuff res 1
txdata res 1
txbits res 1
txcnt res 1
txcode res 1
fdrxsz res 1
fdtxsz res 1
'}
Best regards,
proplem
from reading the code I have the impression using
mode bit 2 = open-drain/source tx
should give you what you want if you set the open drain mode
@rbehm - the ROMs themselves don't take up any hub RAM after they have been moved into upper EEPROM when EXTEND is loaded. Compiling them with the kernel is the easy way to get them into the system in the first place and in reality even when EXTEND may overwrite that area in hub RAM it doesn't matter as that image still exists in lower EEPROM. So before a BACKUP takes place SAVEROMS is run to copy the ROMs from lower EEPROM to upper EEPROM and after which the SAVEROMS routine is forgotten as it is no longer needed.
Thanks for clarifying. But the the ROM code must fit into the originally compiled Tachyon code. If these do not fit I cannot put it there. How about a function to load precompiled code later?
Also as MJB mentioned, there is the SPIO module that can be used for simultaneous SPI input/output whereas the SPIxx instructions are simple dedicated instructions optimized for fast read or write.
Yes, I think I have to read the docs and extend my IDE to make this easier.
@rbehm - the ROMs themselves don't take up any hub RAM after they have been moved into upper EEPROM when EXTEND is loaded. Compiling them with the kernel is the easy way to get them into the system in the first place and in reality even when EXTEND may overwrite that area in hub RAM it doesn't matter as that image still exists in lower EEPROM. So before a BACKUP takes place SAVEROMS is run to copy the ROMs from lower EEPROM to upper EEPROM and after which the SAVEROMS routine is forgotten as it is no longer needed.
Thanks for clarifying. But the the ROM code must fit into the originally compiled Tachyon code. If these do not fit I cannot put it there. How about a function to load precompiled code later?
Also as MJB mentioned, there is the SPIO module that can be used for simultaneous SPI input/output whereas the SPIxx instructions are simple dedicated instructions optimized for fast read or write.
Yes, I think I have to read the docs and extend my IDE to make this easier.
There is plenty of room left in the hub memory map (16kB) to add PASM objects, none of which take up more than 496 longs, usually a lot less. After EXTEND is loaded the ROMS are removed from hub memory space into upper EEPROM. So it doesn't matter what may end up in hub memory later, as the ROMS have been relocated. 16kB is at least 8 more full ROMS but probably more like 20, so don't hold back, although I may have to make allowance for more room in the EEPROM. The 1Mbit EEPROMs are quite cheap, have a large page size, run at 1MHz etc, so if you can, use them.
from reading the code I have the impression using
mode bit 2 = open-drain/source tx
should give you what you want if you set the open drain mode
RTFM as you already taught me a few times :-)) but assembler is even more far away than spin. BTW I read the assembler code before posting and saw the mode bits but that's the difference between hearing and feeling.
After plugging the propplug 180 degrees reversed and using this "wonder bit" things are working well.
Thank you very very much! I heard of political disturbances - hope you are not affected.
Best regards,
proplem
Over on the P2 forum I demonstrated how easy it is to drive a string of LEDs connected in a daisy chain of shift registers. Here's the same thing for the P1 and even though there isn't a dedicated BUF>SPI function (the P2 version uses RDFAST) this version uses a tight FOR NEXT loop to write 64 LEDs serially in 35us.
.. &13.00.13.12 SPIPINS ok
.. pub LEDS ( buf -- ) FROM 0 8 FOR IC@ SPIWRB NEXT DROP ;
.. $2000 LAP LEDS LAP .LAP 3392 cycles at 96MHz = 35.333us ok
An unrolled version that just fetches 2 longs and writes 2 lots of 32-bit data only takes 22us.
EDIT: on that note I added a SPIWR32 instruction to the kernel that writes all 32-bits in one go. Now the code is simple and only takes 19us to execute.
While others celebrate success, we still fight with very basic problems: Tachyon (4.5) is started and easynet.
When we establish a telnet connection using PUTTY, Tachyon reboots.
Now we found, if we establish a raw connection, Tachyon answers "Welcome to the tachyon wiznet telnet session" and a normal tachyon console is present.
What went wrong with a "normal" Telnet connection?
While others celebrate success, we still fight with very basic problems: Tachyon (4.5) is started and easynet.
When we establish a telnet connection using PUTTY, Tachyon reboots.
Now we found, if we establish a raw connection, Tachyon answers "Welcome to the tachyon wiznet telnet session" and a normal tachyon console is present.
What went wrong with a "normal" Telnet connection?
Have a look at putty.log in your home directory. Perhaps it is sending a ^C and if it is then maybe you could disable that feature in Tachyon by overwriting the keytable.
Try:
keytable keytable 2+ 14 CMOVE
This will let all control characters from 01..07 pass through passively. Make a copy of the area if you want to restore it afterwards.
See if that quick fix helps but bear in mind that there are quite a few settings in putty such as "return key sends Telnet New Line instead of ^M" etc that may need to be changed.
Hello Peter, I'm now finally at the point where I have become acquainted with the 1000 miracles of Tachyon. While in principle the application is running, we see the following phenomenon:
A newly flashed Tachyon including Extended, Easyfile, then compact, EASYNET at boot shows all the boot up messages colorized. After a number of boots the colors vanish and in the end only the Tachyon Boot message appears.
In the meantime we found, that the sd-card was corrupted. I'm formatting the card and we will see :-)
The reason for the unstabilities is unknown.
There is a ANSI check on boot and if the terminal doesn't use it then it inhibits ANSI sequences. There may be something in your boot code too. I will check what I can check on this end to see if I can reproduce the problem.
OK, thanks, Peter. The ANSI check explains why we see different behavior, I had the expression that the system slowly degrades, but now it looks like a "normal" and intended behavior and we can try to find out, what else happens. Up and down is so close ;-)
Hello Peter, we are now back to work. There is one symptom: if we start putty with "raw", not telnet, a connection is established and we get a log file. Starting telnet, Tachyon reboots, and no connection is established.
One minor question: at boot, AUTORUN is followed by ?
Here is the boot message triggered by telnet connection
Update: a telnet connection under linux (using telnet) is working! And our original app also, so Putty seems to be the problem.
Next update: it turned out that the system started with a propplug installed, but stalled without propplug. We installed a pull up resistor to the rx of the propeller and Tachyon started properly.
Comments
If I enter I get the following output intended (@MJB that's what I needed
I checked the receive buffer at $7400 (right?) This seems that minicom appends something ("Minicom2.7) to my input?! Strange - bug or feature?
Best regards,
proplem
NFA Structure:
CNT(1),<name>,ATR(1),wordcode(2)
maybe let's note:
Thanks to you both.
If you make some code that you do not need to keep secret,
let's see it ...
maybe we can learn from it, discuss it,
or at least praise it ;-)
I am still in so many other things that I hardly produce significant code.
But like the 'tricky' Tachyon internals ... ;-)
2. Is there a reason why ~c is a long or is there a waste of 2 bytes :-)
3. Does uemit ~ delete 4 bytes then?
4. And uemit ! overwrites 4 bytes also?
Can you explain?
I don't use these ones much but uemit and ukey are part of one long so they can be cleared in one operation rather than individually.
If I try to redirect with I get an immediate tachyon reboot.
What I intend is to output to console and to UART1
There is one constraint - the redirecting must work also via telnet !!
That means I want to output to UART and to LAN under telnet and to UART and CON on console.
Maybe I do something completely wrong but I don't see what.
Any help is appreciated.
Best regards,
proplem
Edit: Maybe the problem is that I only wrote uemit and not ukey? Do they have to be written at the same time?
1. On console in un-redirected state uemit and ukey are not set ( equal 0 ). How can I get the current values then? Would this be correct? 2. Why does this console input cause Tachyon to hang?
1. The address of the EMIT/KEY routie is not important but the setting of the uemit/ukey vector is.
2. KEY checks the ukey vector for an entry and if calls that if set. All you are doing is making it call itself until it crashes.
If you make some code that you do not need to keep secret,
let's see it ...
maybe we can learn from it, discuss it,
or at least praise it ;-)
I am still in so many other things that I hardly produce significant code.
But like the 'tricky' Tachyon internals ... ;-)
@Proplem
in other words ...
normally you do not have to preserve the previous value of ukey and uemit
you just assign the redirection to it.
And then you revert to having them cleared to 0 via CON.
Typically you just define your redirection word
Now I've got a new issue: I need to insert a callback into EASYNET which is called when the connection is finished.
I thought BYE would be the right place but BYE is not called after a client break disconnect. I tried several places in EASYNET with console messages but there is redirection in process so no output is visible at the console.
@Peter could you give an advice where I can insert my connection close/interrupt callback?
when I was debugging inside EASYNET I had a debug print routine which saved uemit, cleared it to 0 did the printing and restored the old uemit .
Actually just use:
DISC?
checks if a disconnection has happened.
and uses BYE internally, so adding to BYE seems ok
I can not try it out,
but this might work.
@Peter_Jakacki +VECTOR is a great solution
Hi Mike, just by way of a quick reply for now probably the easiest way is to just insert those sections directly into the Tachyon kernel source in the "ROMS" section.
Add a header for each "ROM" .
Then in your Forth code you can select and load a ROM during runtime or interactively.
I'm sure you could also compile your ROMs separately but I haven't tried that yet. The method I use takes care of getting from hub memory into upper EEPROM when EXTEND is first loaded and before that hub memory area is overwritten.
It's a pity that we don't have the ability to include source files but the other thing is that you may have to rename your symbols to avoid conflict.
I am thinking about similar ideas to get some PASM drivers into Tachyon.
But I ran into space problems because the added "ROM" will make everything larger than 32k.
My question is, what can I kick out to make room. E.g. I do not need VGA. Will I get problems if I remove it?
And Now for Something Completely Different:
I use some SPI ADCs (TI ADS1018). The SPI outputs data while a new command is written.
As far as I have understood your SPI words can transmit or (xor) receive but not both. Am I correct or is there another solution?
Of course I can write this myself shift-out, shift in and clock in a loop.
have a look in Tachyon.spin
{HELP SPIO ( send -- receive ) ( A: miso mosi sck )
REGS: 0=sck 1=mosi 2=miso 3=cnt
*** SERIAL PERIPHERAL INPUT OUTPUT MODULE ***
Transfers 1 to 32 bits msb first
Transmit data must be left justified ready for transmission
Receive data is in correct format
Data is shifted in and out while the clock is low
The clock is left low between transfers
}
org _RUNMOD
' COGREGS: 0=sck 1=mosi 2=miso 3=cnt
' SPIO ( send -- receive ) ( A: miso mosi sck )
Also as MJB mentioned, there is the SPIO module that can be used for simultaneous SPI input/output whereas the SPIxx instructions are simple dedicated instructions optimized for fast read or write.
The problem is that after sending data the tx pin is hold as output which avoids reusing this pin for other cogs.
Would it be possible and if - could somebody add the lines to the assembler code to let the tx pin float after transmitting the buffer?
Here is the code (copied from tachyon): Best regards,
proplem
from reading the code I have the impression using
mode bit 2 = open-drain/source tx
should give you what you want if you set the open drain mode
Thanks for clarifying. But the the ROM code must fit into the originally compiled Tachyon code. If these do not fit I cannot put it there. How about a function to load precompiled code later?
Yes, I think I have to read the docs and extend my IDE to make this easier.
There is plenty of room left in the hub memory map (16kB) to add PASM objects, none of which take up more than 496 longs, usually a lot less. After EXTEND is loaded the ROMS are removed from hub memory space into upper EEPROM. So it doesn't matter what may end up in hub memory later, as the ROMS have been relocated. 16kB is at least 8 more full ROMS but probably more like 20, so don't hold back, although I may have to make allowance for more room in the EEPROM. The 1Mbit EEPROMs are quite cheap, have a large page size, run at 1MHz etc, so if you can, use them.
After plugging the propplug 180 degrees reversed and using this "wonder bit" things are working well.
Thank you very very much! I heard of political disturbances - hope you are not affected.
Best regards,
proplem
An unrolled version that just fetches 2 longs and writes 2 lots of 32-bit data only takes 22us.
EDIT: on that note I added a SPIWR32 instruction to the kernel that writes all 32-bits in one go. Now the code is simple and only takes 19us to execute.
When we establish a telnet connection using PUTTY, Tachyon reboots.
Now we found, if we establish a raw connection, Tachyon answers "Welcome to the tachyon wiznet telnet session" and a normal tachyon console is present.
What went wrong with a "normal" Telnet connection?
Try: This will let all control characters from 01..07 pass through passively. Make a copy of the area if you want to restore it afterwards.
See if that quick fix helps but bear in mind that there are quite a few settings in putty such as "return key sends Telnet New Line instead of ^M" etc that may need to be changed.
A newly flashed Tachyon including Extended, Easyfile, then compact, EASYNET at boot shows all the boot up messages colorized. After a number of boots the colors vanish and in the end only the Tachyon Boot message appears.
In the meantime we found, that the sd-card was corrupted. I'm formatting the card and we will see :-)
The reason for the unstabilities is unknown.
One minor question: at boot, AUTORUN is followed by ?
Here is the boot message triggered by telnet connection
Update: a telnet connection under linux (using telnet) is working! And our original app also, so Putty seems to be the problem.
Next update: it turned out that the system started with a propplug installed, but stalled without propplug. We installed a pull up resistor to the rx of the propeller and Tachyon started properly.