Shop OBEX P1 Docs P2 Docs Learn Events
Bell202 object, AX.25 and APRS — Parallax Forums

Bell202 object, AX.25 and APRS

ke4pjwke4pjw Posts: 1,172
edited 2011-12-02 10:28 in Propeller 1
I started playing with the Bell 202 object last night. I just used the test program and listened to the audio through speakers. My plan is to build a "PropTracker" for APRS. I have not dug into the object too much, but I just wanted to get some confirmation that I am traveling down the correct path.

It appears that I will have to construct the complete AX.25 UI frame, including flag fields. Is that correct?

BTW, the documentation and everything that goes with this object is great! Kudos to PhiPi!
«1

Comments

  • LukeHLukeH Posts: 22
    edited 2010-09-15 12:51
    I'm hoping to do something similar, specifically to make a full-up duplex AX.25 TNC which I can use for remote control and will be compatible with commercial TNCs. My understanding as well is that yes, you will need to construct the AX.25 frames yourself... something I need to learn how to do.

    -Luke AC0AV
  • ke4pjwke4pjw Posts: 1,172
    edited 2010-09-15 13:02
    I have done some more reading and I suspect that the "flag" fields are transmitted as a part of the bell202 layer. I could be wrong about that, but I will see. I know I will have to do all of my own bit stuffing and such. I found a good tutorial for constructing the UI frames as used by APRS that is for PICs. Looks like building a stand alone tracker is going to be pretty easy, as the Bell202 object does the heavy listing. (Famous last words) A TNC is going to be more challenging due to the nature of the book keeping for virtual connections and packet reconstruction.

    Maybe we can collaborate on our projects. :)
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2010-09-15 13:43
    The Bell202 object is just a straight 8-bit byte-by-byte data transceiver with no built-in protocol layers or special bit fields. Those will have to be added on top.

    -Phil
  • ke4pjwke4pjw Posts: 1,172
    edited 2010-09-15 20:14
    OK, this is going to be harder than at first blush. I figured I could do something like this
    PUB do_transmit | i
    
      i~  
      repeat
        mdm.transmit
        repeat 80
         mdm.outstr(string($7E))
        mdm.outstr(string($86, $A2,  $40,  $40,  $40,  $40,  $60,  $AE,  $64,  $8C,  $A6, $40,   $40,   $68, $A4, $8A,  $98,  $82,   $B2,  $40,   $61,  $03, $F0,   $54,   $65,  $73, $74))   
        mdm.outstr(string($7E))
    '    mdm.outstr(string($7e +"!Testing "))
    '    mdm.outstr(num.decf(i++, 4))
    '    mdm.outstr(string(" de KE4PJW", 13)) '─────── callsign here if using radio transmission.
        mdm.standby
        waitcnt(cnt + clkfreq * 2)
    

    The packet should be
    W2FS-4> CQ, RELAY: Test

    However it is not decoded by the remote TNC. (transmitting into a dummyload on UHF) I am using this specific packet because I have taken it from this document and did not want to deal with an unknown quantity. (Bad FCS field, etc)

    I hope someone can point out a huge oversight on my part.
  • ke4pjwke4pjw Posts: 1,172
    edited 2010-09-15 21:16
    Ah, I think it may be because there are start and stop bits added by the Bell202 object. My brain is starting to hurt :)


    EDIT: Ok, two big mistakes. FCS is missing from above. I have commented out the two ASM opcodes that create the start and stop bits and decremented the bit counter by 2. I feel like I am making progress.
  • RvnPhnxRvnPhnx Posts: 36
    edited 2010-09-19 07:48
    May I strongly suggest that you have a look at the work that others of us have posted on this subject (and save yourself a lot of headaches!)?

    http://forums.parallax.com/showpost.php?p=908872&postcount=64

    http://forums.parallax.com/showpost.php?p=919074&postcount=75
  • ke4pjwke4pjw Posts: 1,172
    edited 2010-09-19 10:04
    Hi Rvn,
    I have looked at your code, as well as that of others. (Though I haven't had any time this weekend to really dig into it). I like the modified CRC you have in your code and used it in mine. One question I have is in the modulator portion of your code, you have the instructions for the start and stop bits commented out, however the bit count to send is still #11. Why is that? That sort of has me confused.

    Thanks,
    Terry
    '=======[Modulator]============================================================
    
    transmitter   and       dira,xdira              'Configure pins for output.
                  mov       outa,xouta
                  mov       dira,xdira
    
    xmtlp         call      #getstat                'Are we still transmitting?
                  and       acc,#STSXMT wz
            if_z  jmp       #standingby             '  No: Go back to standby.
    
                  rdbyte    enq,xenqaddr            'Is enqueue index <> deque index?
                  rdbyte    deq,xdeqaddr
                  cmp       enq,deq wz
            if_nz jmp       #:dodeq                 '  Yes: There's data to send; go dequeue it.
                  mov       data,#$7e                 'No: Queue up some zeros
                  mov       bitcnt,#8              'Spit them out
                  jmp       #:sndtxdly              'As TXDelay
    
    :dodeq        mov       acc,xbufaddr            'Point to next byte to send.
                  add       acc,deq
                  rdbyte    data,acc                'Get it.
                  add       deq,#1                  'Increment dequeue index.
                  and       deq,#BUFMAX             'Point back to beginning if past end.
                  wrbyte    deq,xdeqaddr            'Write dequeue pointer back to xdeq.
    
    '              or        data,_0x0300              'OR in the stop bit.
    '              shl       data,#1                 'Shift left to create the start bit.
                  mov       bitcnt,#11              'Bit count to send is 10.
    :sndtxdly
    :bitloop      shr       data,#1 wc              'Shift next bit into carry.
                  call      #sendc
    :xnext        djnz      bitcnt,#:bitloop        'Go back for another bit.
    
                  jmp       #xmtlp
    
    
  • Toby SeckshundToby Seckshund Posts: 2,027
    edited 2010-09-20 00:31
    From what i can remember, from 30 years ago, the TNC I had used a Z80 set of chips and the serial was a SCC(?) instead of a commom UART. This may have been so that the stops, starts and parity bits didn't try to muscle into the packet.

    I will have to try this object too. It has always been the dificulty in getting the the modem chips that has put me off.

    I used to be G8LCU.
  • RvnPhnxRvnPhnx Posts: 36
    edited 2010-09-20 10:27
    ke4pjw wrote: »
    Hi Rvn,
    I have looked at your code, as well as that of others. (Though I haven't had any time this weekend to really dig into it). I like the modified CRC you have in your code and used it in mine. One question I have is in the modulator portion of your code, you have the instructions for the start and stop bits commented out, however the bit count to send is still #11. Why is that? That sort of has me confused.

    Thanks,
    Terry

    Terry,
    I started my work with the demodulator and I haven't completely mangled the modulator yet. The same lessons I learned with the demod will surely apply however, including the bit-stuffing and the NRZI code.
    AX.25 over Bell 202 utilizes bit-stuffing (pushing in an extra "0" state in the data stream) after five "1" states to keep the NRZI (Non-Return to Zero Inverted) stream that is passed to/from the raw modem from stagnating at one tone or the other (high or low). Stagnation would make re-synchronization and recovery of the bit rate of the raw stream very difficult (if not impossible under some circumstances). The other purpose of bit-stuffing is to keep a (begin/end) "flag" sequence of six ones in a row--0x7Eh--from showing up in the middle of a packet.
    My modifications to the demod code take both of these issues into account (NRZI and bit-stuffing) and can be implemented in inverse to make your transmit/modulate code work a bit more reliably.
    I strongly recommend looking at the AX.25 spec if you haven't yet to help you along (and in case I've bollocksed something above or in my additions to Phil's code) and it appears that you've already had a look at the APRS spec which will help a lot as well.
    Good Luck! I've set this thread to notify me on updates so you can post back here if you have more questions. Maybe I'll have some idea how to help, and maybe you'll inspire me to fix something else!
  • LA3QMALA3QMA Posts: 13
    edited 2010-09-20 23:28
    If you are doing any modifications or making a "aprs-api" for the Bell object please implement it so that you enter the string and the object is doing all the CRCs etc.

    i.e the possibility to transmit an valid APRS formated packet and let the code create the proper AX25 and transmit it.

    TX_AX25_KISS("LA3QMA-9 >VP2QW0,WIDE2-2:`{\Kl#P>/]"41}=")

    Same thing for RX. Let the code do all the tricky part and return it as "clear text" or "TNC2" format.

    I have some APRS projects and i want to use this Bell code but i think i have to learn more SPIN and finish my first project.
  • RvnPhnxRvnPhnx Posts: 36
    edited 2010-09-21 09:25
    LA3QMA wrote: »
    If you are doing any modifications or making a "aprs-api" for the Bell object please implement it so that you enter the string and the object is doing all the CRCs etc.

    i.e the possibility to transmit an valid APRS formated packet and let the code create the proper AX25 and transmit it.

    TX_AX25_KISS("LA3QMA-9 >VP2QW0,WIDE2-2:`{\Kl#P>/]"41}=")

    Same thing for RX. Let the code do all the tricky part and return it as "clear text" or "TNC2" format.

    I have some APRS projects and i want to use this Bell code but i think i have to learn more SPIN and finish my first project.

    My original intent was to implement a KISS TNC object and then use that to build an APRS digi. If Terry (or somebody else) gets there first that doesn't bother me--so long as I can understand their code!
  • LA3QMALA3QMA Posts: 13
    edited 2010-09-22 00:55
    KISS is ok i guess. Some application it's better to work a bit different.

    Anyhow i'm using the TNC-X with XDigi for doing digipeating.

    But doing "TNC2" mode is more useful for me. So this thread is going to be visited by me often :lol:
  • Brian CarpenterBrian Carpenter Posts: 728
    edited 2010-09-25 14:45
    Subscribing
  • leggsleggs Posts: 21
    edited 2011-06-09 15:39
    Hey guys. I know this thread is a bit old, but i am sure there is still interest in aprs with the propeller. Because no one seems to have gotten anywhere, i decided to tackle the problem myself. Let me know if anyone is still following this thread, and wants to help out with my (almost) working code
  • Toby SeckshundToby Seckshund Posts: 2,027
    edited 2011-06-10 01:44
    I still harbour some thoughts about getting back my call sign and packet would be one of the modes that i would be interested in. I often ponder on a non RF network for status checking of bits of kit 200 Metres away at work (big white round things).

    Doing it by ethernet would make it too easy, for the others :-)
  • ke4pjwke4pjw Posts: 1,172
    edited 2011-06-10 22:17
    leggs wrote: »
    Hey guys. I know this thread is a bit old, but i am sure there is still interest in aprs with the propeller. Because no one seems to have gotten anywhere, i decided to tackle the problem myself. Let me know if anyone is still following this thread, and wants to help out with my (almost) working code

    I am very interested. I felt as if I was close to being able to generate valid X.25 packets a few months ago, but had to give it a rest after my baby girl was born. I would love to look at your code!
  • RvnPhnxRvnPhnx Posts: 36
    edited 2011-06-11 05:20
    Let me know if anyone is still following this thread, and wants to help out with my (almost) working code

    I'm still around. Part of what's been taking up my time was getting involved with git.git--it's the one SCM that shows promise of being able to properly handle UTF-16 text (like that generated by Parallax's Propeller programming tool) as text. That's less of a problem for me, as BST handles UTF-8 just fine (and that's handled by most SCM software without pain).
  • leggsleggs Posts: 21
    edited 2011-06-14 07:37
    It works! Successfully transmitted AX.25 frames which were decoded by AGWPE. I am just going to clean up and comment the code, and then I will post it here. :thumb:
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-06-14 07:47
    Hey, that's great! 'Looking forward to seeing your code!

    -Phil
    AD7YF
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-06-14 07:58
    leggs wrote: »
    It works! Successfully transmitted AX.25 frames which were decoded by AGWPE. I am just going to clean up and comment the code, and then I will post it here. :thumb:
    leggs,

    Did you transmit RF packets or did you do a serial connection to your PC? I'm curious if your packets were picked up by a digi-peater and are visible on http://www.aprs.fi .

    Dave
    KE5LOL
  • leggsleggs Posts: 21
    edited 2011-06-14 08:23
    I connected the audio out jack on the propeller demo board directly to the mic jack on my laptop. All I managed to do so far is modify the bell202 object to do bitstuffing and NRZI encoding. The packet that AGWPE decoded was constructed out of bytes which I knew the FCS code for. Now I need to get an FCS algorithm working on the prop.
  • ke4pjwke4pjw Posts: 1,172
    edited 2011-06-14 08:45
    leggs wrote: »
    It works! Successfully transmitted AX.25 frames which were decoded by AGWPE. I am just going to clean up and comment the code, and then I will post it here. :thumb:

    Dude! Can't wait to see your code!
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-06-14 08:48
    OK, yes I should have realized is was an audio connection to the PC. From what I can tell, the FCS is the same one used in HDLC, and I think it is the same one used in the YMODEM protocol. I can post the FCS code I use in my YMODEM code if you're interested.

    EDIT: The CRC code I use in my YMODEM program is shown below.
    PUB AppendCRC(ptr, num) | crc
      crc := ComputeCRC(ptr, num)
      byte[ptr][num] := crc >> 8
      byte[ptr][num+1] := crc & $ff
    
    PUB ComputeCRC(ptr, num)
      repeat num
        result ^= (byte[ptr++] << 8)
        repeat 8
          result <<= 1
          if result & $10000
            result ^= $1021
      result &= $ffff
    
  • leggsleggs Posts: 21
    edited 2011-06-14 09:08
    By analyzing a correct AX.25 packet, I have this set of data and correct checksum:
    $90, $84, $72, $b4, $a4, $90,$60, $90, $84, $72, $a0, $aa, $9e, $e1, $f1 checksum $30 $26
    The checksum is sent most significant bit first, so I am not sure whether this checksum should be reversed or not. The algorithm is CRC-CCITT. Let me know if anyone can recreate this checksum from the given data.
  • leggsleggs Posts: 21
    edited 2011-06-14 09:35
    This modified version of Jason Wood's code was floating around the forums:
    PUB CRC_CCITT ( key, len ) : CRC | j, x
      CRC := $FFFF
    
      repeat len - 1
        
        x := word[key++]
        
        repeat 15
          j := 1 & (x ^ CRC)
          
          CRC := (CRC / 2) & $FFFF
    
          x := (x / 2) & $FFFF
    
          IF (j <> 0)
            CRC := CRC ^ $8408
    

    And there is this description from http://n1vg.net/packet/index.php

    Start with the 16-bit FCS set to 0xffff. For each data bit sent, shift the FCS value right one bit. If the bit that was shifted off (formerly bit 1) was not equal to the bit being sent, exclusive-OR the FCS value with 0x8408. After the last data bit, take the ones complement (inverse) of the FCS value and send it low-byte first.

    The code does not seem to give a valid checksum. Can anyone spot mistakes?
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-06-14 10:20
    This program generates the correct CRC. My original code assumed LSB first, so it was bit-reveresed with respect to the AX.25 code. It also started with $0000 instead of $ffff, and it didn't flip the bits at the end. The order of the checksum bytes was also reversed.
    con
      _clkmode = xtal1+pll16x
      _clkfreq = 80_000_000
      
    obj
      ser : "FullDuplexSerial"
    
    dat
      buffer byte $90, $84, $72, $b4, $a4, $90,$60, $90, $84, $72, $a0, $aa, $9e, $e1, $f1, 0, 0 'checksum $30 $26
    
    pub main
      ser.start(31, 30, 0, 115_200)
    
      AppendCRC(@buffer, 15)
    
      ser.str(string("checksum $"))
      ser.hex(buffer[15], 2)
      ser.str(string(" $"))
      ser.hex(buffer[16], 2)
      ser.tx(13)
    
    PUB AppendCRC(ptr, num) | crc
      crc := ComputeCRC(ptr, num)
      byte[ptr][num] := crc & $ff
      byte[ptr][num+1] := crc >> 8
    
    pub ComputeCRC(ptr, num)
      result := $ffff
      repeat num
        result ^= byte[ptr++]
        repeat 8
          if result & 1
            result := (result >> 1) ^ $8408
          else
            result >>= 1
      result ^= $ffff
    
  • leggsleggs Posts: 21
    edited 2011-06-14 11:09
    Great!, Thanks. Integrating...

    Ok, I am tired, but the hard work has been done. There seems to be a lot of interest, so here is my rough program. The bell202 modem object has been modified to do bit stuffing and NRZI encoding. The bell202demo simply transmits a valid AX.25 packet, by copying the contents from a received packet (and includes a working checksum algorithm). Hopefully someone can wrap it up into a nice send packet function, otherwise I will do it tomorrow.

    Edit: I am new to the propeller, so my code can most probably be improved!

    Have fun, guys
  • ke4pjwke4pjw Posts: 1,172
    edited 2011-06-14 12:02
    leggs wrote: »
    Great!, Thanks. Integrating...

    Ok, I am tired, but the hard work has been done. There seems to be a lot of interest, so here is my rough program. The bell202 modem object has been modified to do bit stuffing and NRZI encoding. The bell202demo simply transmits a valid AX.25 packet, by copying the contents from a received packet (and includes a working checksum algorithm). Hopefully someone can wrap it up into a nice send packet function, otherwise I will do it tomorrow.

    Have fun, guys

    I am desperately looking over your post for some linkage or source code :)

    UPDATE: Thanks for posting the code!!!
  • RvnPhnxRvnPhnx Posts: 36
    edited 2011-06-14 19:17
    leggs wrote: »
    This modified version of Jason Wood's code was floating around the forums:
    PUB CRC_CCITT ( key, len ) : CRC | j, x
      CRC := $FFFF
    
      repeat len - 1
        
        x := word[key++]
        
        repeat 15
          j := 1 & (x ^ CRC)
          
          CRC := (CRC / 2) & $FFFF
    
          x := (x / 2) & $FFFF
    
          IF (j <> 0)
            CRC := CRC ^ $8408
    

    And there is this description from http://n1vg.net/packet/index.php

    Start with the 16-bit FCS set to 0xffff. For each data bit sent, shift the FCS value right one bit. If the bit that was shifted off (formerly bit 1) was not equal to the bit being sent, exclusive-OR the FCS value with 0x8408. After the last data bit, take the ones complement (inverse) of the FCS value and send it low-byte first.

    The code does not seem to give a valid checksum. Can anyone spot mistakes?

    As the one who made the conversion from Jason's original, I'd like to know very much what is purported to be wrong with this. I will note that I have only tried DECODING packets with it, and that's not exactly the same process of encoding.
  • RvnPhnxRvnPhnx Posts: 36
    edited 2011-06-14 19:19
    leggs wrote: »
    Great!, Thanks. Integrating...

    Ok, I am tired, but the hard work has been done. There seems to be a lot of interest, so here is my rough program. The bell202 modem object has been modified to do bit stuffing and NRZI encoding. The bell202demo simply transmits a valid AX.25 packet, by copying the contents from a received packet (and includes a working checksum algorithm). Hopefully someone can wrap it up into a nice send packet function, otherwise I will do it tomorrow.

    Edit: I am new to the propeller, so my code can most probably be improved!

    Have fun, guys

    The assembly looks reasonable. I haven't tried it yet, but I don't anticipate problems. Perhaps you'll be able to take the work I've done patching the recieving side and make a whole tranciever from it.
Sign In or Register to comment.