Tachyon V4 "DAWN" - exploring new worlds

1212223242527»

Comments

  • 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 :smile:)
    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?)
    ..  $7400 100 DUMP 
    0000.7400:   00 00 00 00  B5 00 B5 00  08 08 08 08  08 08 08 08    ................
    0000.7410:   08 08 75 61  72 74 31 20  32 2D 20 43  46 41 3E 4E    ..uart1 2- CFA>N
    0000.7420:   46 41 20 43  52 20 50 52  49 4E 54 24  0D 4D 69 6E    FA CR PRINT$.Min
    0000.7430:   69 63 6F 6D  32 2E 37 08  08 08 08 08  08 08 08 08    icom2.7.........
    0000.7440:   08 08 72 78  62 75 66 66  65 72 73 20  38 0D 24 37    ..rxbuffers 8.$7
    0000.7450:   34 30 30 20  31 30 30 20  44 55 4D 50  0D 75 61 72    400 100 DUMP.uar ok
    .
    
    This seems that minicom appends something ("Minicom2.7) to my input?! Strange - bug or feature?
    Best regards,
    proplem
    I Am One With the Forth and the Forth Is With Me
  • Peter JakackiPeter Jakacki Posts: 6,613
    edited October 31 Vote Up0Vote Down
    @proplem - you are printing the count byte of 5 = ENQ which minicom responds to. Try CFA>NFA 1+ CR PRINT$.

    NFA Structure:
    CNT(1),<name>,ATR(1),wordcode(2)
    Tachyon Forth - compact, fast, forthwright and interactive
    useforthlogo-s.png
    Tachyon Forth News Blog
    TACHYON DEMONSTRATOR
    Brisbane, Australia
  • MJBMJB Posts: 966
    edited October 31 Vote Up0Vote Down
    proplem wrote: »
    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 :smile:)
    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?)
    ..  $7400 100 DUMP 
    0000.7400:   00 00 00 00  B5 00 B5 00  08 08 08 08  08 08 08 08    ................
    0000.7410:   08 08 75 61  72 74 31 20  32 2D 20 43  46 41 3E 4E    ..uart1 2- CFA>N
    0000.7420:   46 41 20 43  52 20 50 52  49 4E 54 24  0D 4D 69 6E    FA CR PRINT$.Min
    0000.7430:   69 63 6F 6D  32 2E 37 08  08 08 08 08  08 08 08 08    icom2.7.........
    0000.7440:   08 08 72 78  62 75 66 66  65 72 73 20  38 0D 24 37    ..rxbuffers 8.$7
    0000.7450:   34 30 30 20  31 30 30 20  44 55 4D 50  0D 75 61 72    400 100 DUMP.uar ok
    .
    
    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$
    

    http://www.smmu.info (german) Source-Measure-Multiplex-Unit = professional test system for electronic components, sensors, assemblies
    Tachyon code and documentation snippets from Tachyon thread
  • MJB wrote: »
    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$
    
    That's it MJB ! Thanks for clarifying. I hope I will be quiet now ...
    Thanks to you both.
    I Am One With the Forth and the Forth Is With Me
  • proplem wrote: »
    MJB wrote: »
    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$
    
    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 ... ;-)
    http://www.smmu.info (german) Source-Measure-Multiplex-Unit = professional test system for electronic components, sensors, assemblies
    Tachyon code and documentation snippets from Tachyon thread
  • @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 Am One With the Forth and the Forth Is With Me
  • proplem wrote: »
    @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.
    Tachyon Forth - compact, fast, forthwright and interactive
    useforthlogo-s.png
    Tachyon Forth News Blog
    TACHYON DEMONSTRATOR
    Brisbane, Australia
  • proplemproplem Posts: 219
    edited November 2 Vote Up0Vote Down
    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?
    I Am One With the Forth and the Forth Is With Me
  • Hi there,
    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?
    WORD myEMIT ' EMIT myEMIT W!
    WORD myKEY ' KEY myKEY W!
    
    2. Why does this console input
    ' KEY ukey W! ' EMIT uemit W!
    
    cause Tachyon to hang?
    I Am One With the Forth and the Forth Is With Me
  • @proplem -

    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.
    Tachyon Forth - compact, fast, forthwright and interactive
    useforthlogo-s.png
    Tachyon Forth News Blog
    TACHYON DEMONSTRATOR
    Brisbane, Australia
  • proplem wrote: »
    MJB wrote: »
    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$
    
    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 ... ;-)
    @proplem -

    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"
    
    http://www.smmu.info (german) Source-Measure-Multiplex-Unit = professional test system for electronic components, sensors, assemblies
    Tachyon code and documentation snippets from Tachyon thread
  • 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?
    I Am One With the Forth and the Forth Is With Me
  • proplem wrote: »
    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 
    
    

    @Peter_Jakacki +VECTOR is a great solution


    http://www.smmu.info (german) Source-Measure-Multiplex-Unit = professional test system for electronic components, sensors, assemblies
    Tachyon code and documentation snippets from Tachyon thread
  • 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.
  • Peter JakackiPeter Jakacki Posts: 6,613
    edited November 3 Vote Up0Vote Down
    Mike Green wrote: »
    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.
    Tachyon Forth - compact, fast, forthwright and interactive
    useforthlogo-s.png
    Tachyon Forth News Blog
    TACHYON DEMONSTRATOR
    Brisbane, Australia
  • Mike Green wrote: »
    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.

    --
    Reinhardt
  • rbehm wrote: »

    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 )
    http://www.smmu.info (german) Source-Measure-Multiplex-Unit = professional test system for electronic components, sensors, assemblies
    Tachyon code and documentation snippets from Tachyon thread
  • @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.
    Tachyon Forth - compact, fast, forthwright and interactive
    useforthlogo-s.png
    Tachyon Forth News Blog
    TACHYON DEMONSTRATOR
    Brisbane, Australia
  • proplemproplem Posts: 219
    edited November 4 Vote Up0Vote Down
    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
    I Am One With the Forth and the Forth Is With Me
  • MJBMJB Posts: 966
    edited November 5 Vote Up0Vote Down
    proplem wrote: »
    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
    http://www.smmu.info (german) Source-Measure-Multiplex-Unit = professional test system for electronic components, sensors, assemblies
    Tachyon code and documentation snippets from Tachyon thread
  • @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.
    --
    Reinhardt
  • rbehm wrote: »
    @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.

    Tachyon Forth - compact, fast, forthwright and interactive
    useforthlogo-s.png
    Tachyon Forth News Blog
    TACHYON DEMONSTRATOR
    Brisbane, Australia
  • @MJB,
    MJB wrote: »

    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
    I Am One With the Forth and the Forth Is With Me
Sign In or Register to comment.