Shop OBEX P1 Docs P2 Docs Learn Events
Trying to increase the TX buffer of a four port serial object. — Parallax Forums

Trying to increase the TX buffer of a four port serial object.

Duane DegnDuane Degn Posts: 10,588
edited 2011-03-14 15:55 in Propeller 1
Lately I've been adapting Tim Moore's four port serial object to my needs. I have several versions with various RX sizes. See this thread:
http://forums.parallax.com/showthread.php?129714-Tim-Moore-s-pcFullDuplexSerial4FC-with-larger-(512-byte)-rx-buffer
If any of you use Tim's object, I'd suggest switching to the 128 byte buffer version. You get twice the RX buffer at the cost of a few extra longs in code size.

My latest attempt is to increase one of the TX buffers from 16 bytes to 512 bytes. I plan to use the increased TX buffer with a Emic text to speech module. I don't want the main program loop to have to wait for the Emic.

In my initial attempt I decided to hard code the port using the larger TX buffer. I chose port 3. I added this to the init method.
  emicPort := 3

I added emicBuffer after the cog image.
tx_buffer                                       'overlay tx variables over txbuffer
txdata                long      0               ' DWD transmit buffers moved but are
txbits                long      0               ' are still the same size
txcnt                 long      0
txdata1               long      0
 
tx_buffer1                                      'overlay tx variables over txbuffer
txbits1               long      0
txcnt1                long      0
txdata2               long      0
txbits2               long      0
 
tx_buffer2                                      'overlay tx variables over txbuffer
txcnt2                long      0
txdata3               long      0
txbits3               long      0
txcnt3                long      0
                                                'overlay tx variables over txbuffer
tx_buffer3            long      0
                      long      0
                      long      0
                      long      0
' DWD group bytes together.
rxchar                byte      0             ' DWD within cog and by rxcheck method
rxchar1               byte      0             
rxchar2               byte      0             
rxchar3               byte      0
'
        FIT
emicBuffer            long     128

The three other tx buffers remain in the same area of hub RAM as the cog image.

It can be hard to tell what variables are being used within the cog and which are used in the hub. I thought I had figured this out. tx_buffer, tx_buffer1, etc are used as hub locations. txdata is used within the cog.

These tx buffers don't need to be located within the cog image.

I changed the start method from
  txbuff_tail_ptr := txbuff_ptr  := @tx_buffer
  txbuff_tail_ptr1 := txbuff_ptr1 := @tx_buffer1
  txbuff_tail_ptr2 := txbuff_ptr2 := @tx_buffer2
  txbuff_tail_ptr3 := txbuff_ptr3 := @tx_buffer3
 
  tx_head_ptr  := @tx_head
  tx_head_ptr1 := @tx_head1
  tx_head_ptr2 := @tx_head2
  tx_head_ptr3 := @tx_head3
  tx_tail_ptr  := @tx_tail
  tx_tail_ptr1 := @tx_tail1
  tx_tail_ptr2 := @tx_tail2
  tx_tail_ptr3 := @tx_tail3
to
 
  txbuff_tail_ptr := txbuff_ptr  := @tx_buffer
  txbuff_tail_ptr1 := txbuff_ptr1 := @tx_buffer1
  txbuff_tail_ptr2 := txbuff_ptr2 := @tx_buffer2
  txbuff_tail_ptr3 := txbuff_ptr3 := @emicBuffer  ' ********* changed  ************
 
  tx_head_ptr  := @tx_head
  tx_head_ptr1 := @tx_head1
  tx_head_ptr2 := @tx_head2
  tx_head_ptr3 := @tx_head3
  tx_tail_ptr  := @tx_tail
  tx_tail_ptr1 := @tx_tail1
  tx_tail_ptr2 := @tx_tail2
  tx_tail_ptr3 := @tx_tail3

I''ve only included the tx variables in these code pieces.

I'm pretty sure I don't need to change anything else in the start method.

I've also changed the tx method from
PUB tx(port,txbyte)
'' Send byte (may wait for room in buffer)
  if port > 3
    abort
  repeat until (long[@tx_tail][port] <> (long[@tx_head][port] + 1) & $F)
  byte[@tx_buffer][(port<<4)+long[@tx_head][port]] := txbyte
  long[@tx_head][port] := (long[@tx_head][port] + 1) & $F
 
  if long[@rxtx_mode][port] & NOECHO
    rx(port)
 
to
PUB tx(port,txbyte)
'' Send byte (may wait for room in buffer)
  if port > 3
    abort
  if port == emicPort
    repeat until (long[@tx_tail][port] <> (long[@tx_head][port] + 1) & $1FF)
    byte[@emicBuffer][long[@tx_head][port]] := txbyte
    long[@tx_head][port] := (long[@tx_head][port] + 1) & $1FF
 
    if long[@rxtx_mode][port] & NOECHO
      rx(port)
  else
    repeat until (long[@tx_tail][port] <> (long[@tx_head][port] + 1) & $F)
    byte[@tx_buffer][(port<<4)+long[@tx_head][port]] := txbyte
    long[@tx_head][port] := (long[@tx_head][port] + 1) & $F
 
    if long[@rxtx_mode][port] & NOECHO
      rx(port)
 
I believe the (port<<4) is used to multiply the port by 16 in order to use the correct 16 byte tx buffer. Since the emicBuffer starts at the beginning, I don't need to shift the port number.

I also made changes in the PASM section. I'll use port 2 to show what the original code was.
transmit2               jmpret  txcode2,rxcode3       'run a chunk of receive code, then return
 
{282,84}txcts2          test    ctsmask2,ina    wc    'if flow-controlled don't send
                        rdlong  t1,tx_head_ptr2
                        cmp     t1,tx_tail2     wz
ctsi2   if_z            jmp     #transmit2            'may be patched to if_z_or_c or if_z_or_nc
                        rdbyte  txdata2,txbuff_tail_ptr2
                        add     tx_tail2,#1
                        and     tx_tail2,#$0F   wz
                        wrlong  tx_tail2,tx_tail_ptr2
        if_z            mov     txbuff_tail_ptr2,txbuff_ptr2 'reset tail_ptr if we wrapped
        if_nz           add     txbuff_tail_ptr2,#1   'otherwise add 1
{292,94}                jmpret  txcode2,rxcode3
                        shl     txdata2,#2
                        or      txdata2,txbitor       'ready byte to transmit
                        mov     txbits2,#11
                        mov     txcnt2,cnt
txbit2                  shr     txdata2,#1      wc
txout2                  muxc    outa,txmask2          'maybe patched to muxnc dira,txmask
                        add     txcnt2,bit_ticks2     'ready next cnt
:wait2                  jmpret  txcode2,rxcode3       'run a chunk of receive code, then return
                        mov     t1,txcnt2             'check if bit transmit period done
{302,104}               sub     t1,cnt
                        cmps    t1,#0           wc
        if_nc           jmp     #:wait2
                        djnz    txbits2,#txbit2       'another bit to transmit?
txjmp2                  jmp     ctsi2                 'byte done, transmit next byte
Here is port 3's code with my changes.
transmit3               jmpret  txcode3,rxcode        'run a chunk of receive code, then return
 
txcts3                  test    ctsmask3,ina    wc    'if flow-controlled dont send
                        rdlong  t1,tx_head_ptr3
                        cmp     t1,tx_tail3     wz
ctsi3   if_z            jmp     #transmit3            'may be patched to if_z_or_c or if_z_or_nc
{312,114}               rdbyte  txdata3,txbuff_tail_ptr3
                        add     tx_tail3,#1
                        and     tx_tail3,#$1FF   wz    ' ******* changed ***************
                        wrlong  tx_tail3,tx_tail_ptr3
        if_z            mov     txbuff_tail_ptr3,txbuff_ptr3 'reset tail_ptr if we wrapped
        if_nz           add     txbuff_tail_ptr3,#1   'otherwise add 1
                        jmpret  txcode3,rxcode
                        shl     txdata3,#2
                        or      txdata3,txbitor       'ready byte to transmit
                        mov     txbits3,#11
{322,124}               mov     txcnt3,cnt
txbit3                  shr     txdata3,#1      wc
txout3                  muxc    outa,txmask3          'maybe patched to muxnc dira,txmask
                        add     txcnt3,bit_ticks3     'ready next cnt
{128}local_wait3        jmpret  txcode3,rxcode        'run a chunk of receive code, then return
rx_buffer3              mov     t1,txcnt3             'check if bit transmit period done
                        sub     t1,cnt
                        cmps    t1,#0           wc
        if_nc           jmp     #local_wait3
                        djnz    txbits3,#txbit3       'another bit to transmit?
{332,6}txjmp3           jmp     ctsi3                 'byte done, transmit next byte
I just changed when txbuff_tail_ptr3 gets reset from $F (15) to $1FF (511).

Am I missing something? I'm attaching my test code. Sorry, but it's a mess. It had be used to test XBees so a lot of the Emic variables have XBee names.

I plan to use the Emic's Busy pin as a CTS pin. For now I have CTS disabled. I've been using this code with a Prop Plug connected where the Emic's "Sin" pin will be.

This is the output to the debug terminal
[code]
count[0] = 5876
count[1] = 3828
count[2] = 4340
count[3] = 4852
count[4] = 6024
count[5] = 2
count[6] = 0
count[7] = 7228
count[8] = 7236
count[9] = 7664
count[10] = 7670
count[11] = 0
count[12] = 0
count[13] = 2
c tx_head&tail = 0, 0
EmptyBuffer localBufferIndex = 0<$0D>
CheckBuffer rxFlag[0] = 0, oldRxFlag[0] = 0<$0D>
result = 0<$0D>
d tx_head&tail = 0, 0
c tx_head&tail = 0, 0
EmptyBuffer localBufferIndex = 3<$0D>
CheckBuffer rxFlag[3] = 0, oldRxFlag[3] = 0<$0D>
result = 0<$0D>
d tx_head&tail = 0, 0
1a tx_head&tail = 37, 2
EmptyBuffer localBufferIndex = 3<$0D>
CheckBuffer rxFlag[3] = 0, oldRxFlag[3] = 0<$0D>
result = 0<$0D>
1b tx_head&tail = 37, 8
2a tx_head&tail = 195, 13
EmptyBuffer localBufferIndex = 3<$0D>
CheckBuffer rxFlag[3] = 0, oldRxFlag[3] = 0<$0D>
result = 0<$0D>
2b tx_head&tail = 195, 18
EmptyBuffer localBufferIndex = 3<$0D>
CheckBuffer rxFlag[3] = 0, oldRxFlag[3] = 0<$0D>
result = 0<$0D>
EmptyBuffer localBufferIndex = 3<$0D>
CheckBuffer rxFlag[3] = 0, oldRxFlag[3] = 0<$0D>
result = 0<$0D>
6a tx_head&tail = 358, 32
EmptyBuffer localBufferIndex = 3<$0D>
CheckBuffer rxFlag[3] = 0, oldRxFlag[3] = 0<$0D>
result = 0<$0D>
EmptyBuffer localBufferIndex = 3<$0D>
CheckBuffer rxFlag[3] = 0, oldRxFlag[3] = 0<$0D>
result = 0<$0D>
9b t

Comments

  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-03-14 15:55
    I've found enough problems with the code I posted that the program didn't have a chance of working.

    I'm marking this thread "solved" for now. If I the code still doesn't work after I make some obvious changes I might switch it back to "unsolved."

    One of the problems is
      emicBuffer            long     128 
    

    should be
      emicBuffer            long     0[128] 
    

    I made the same mistake when I was working on the rx buffers.

    Sorry if I wasted anyone's time.

    Duane
Sign In or Register to comment.