Shop OBEX P1 Docs P2 Docs Learn Events
Tachyon V4 "DAWN" - exploring new worlds - Page 27 — Parallax Forums

Tachyon V4 "DAWN" - exploring new worlds

12425272930

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
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2017-10-31 09:27
    @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)
  • MJBMJB Posts: 1,235
    edited 2017-10-31 10:50
    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$
    

  • 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.
  • MJBMJB Posts: 1,235
    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 ... ;-)
  • @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?
  • 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.
  • proplemproplem Posts: 233
    edited 2017-11-02 07:25
    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?
  • 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?
  • @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.
  • MJBMJB Posts: 1,235
    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"
    
  • 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?
  • MJBMJB Posts: 1,235
    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


  • 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: 10,193
    edited 2017-11-03 07:23
    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.
  • 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.

  • MJBMJB Posts: 1,235
    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 )
  • @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.
  • proplemproplem Posts: 233
    edited 2017-11-04 17:57
    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
  • MJBMJB Posts: 1,235
    edited 2017-11-05 00:55
    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
  • @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 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.

  • @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
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2017-12-06 08:21
    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.
    pub LEDS4		DUP @ SPIWR32 DROP 4+ @ SPIWR32 DROP ;
    

    BARLED_SPI_2017-12-06_00.30.41.png
  • ErNaErNa Posts: 1,738
    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?
  • ErNa wrote: »
    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.

  • ErNaErNa Posts: 1,738
    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.
  • ErNaErNa Posts: 1,738
    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 ;-)
  • ErNaErNa Posts: 1,738
    edited 2017-12-19 15:05
    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
    SnSh19.12.2017-15.22.GIF

    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.
    709 x 732 - 130K
Sign In or Register to comment.