AX.25 in the MMDVM


Jonathan Naylor
 

Hi Folks

I've just spent quite a number of days porting the mobilinkd AX.25 receive code to the MMDVM. This involved many things, simplification, and changing the sampling rate for the filters and the logic. I used the WA8LMF test audio, resampled to the appropriate sample rates for testing. It's not at the level of the direwolf for decoding, but it's within a couple of percent in terms of the numbers of decoded packets.

The code for the modem and the host is in the AX25 branch on GitHub and is based on master so it includes the basic FM controller functionality.

I would like it if people could test it out by firing 1200Bd AX.25 at it. It doesn't send data to aprs.fi or anything clever, merely dumping the raw packets to the log file, at debug level. If you get it to decode anything, could you post it on here. It should work with all packets, it doesn't filter on source, destination, or anything else, that will come later. It is a receive only implementation, so don't expect to be able to connect to it.

I am not sure how much processing power or memory space it requires. It is possible that it may need extra work to slim it down and maybe lose some performance along the way :-( Either way, testing will be appreciated. I would guess that only systems based on 180MHz ARM-M4s or better will work with it, just like the FM controller. Unlike the other modes, there is a lot of open source APRS code out there, and I hope to use some of that to make the rest of the development simpler.

Jonathan  G4KLX


SP2ONG Waldek
 

Hi Jonathan

Thanks, AX.25 this can give new possibilities of use, for example by sending local information via AX.25 1200 Bd information/messages (weather info, status system, alerts etc) use UI type frame in AX.25. There are a lot of descriptions of the construction of simple small TRX based on CC1101 + RPI or Arduino where you can easily build a cheap PAGER Packet Radio and it is an alternative to POCSAG for sending local information to local, where there is no development of cheap POCSAG receivers (for example based on Arduino + CC1101) only commercial PAGER is available for 90 EURO.

73 Waldek


pd1acf
 

Hi All (and Steve N4IRS),

Today I attempted to feed some AX25 packets to the receiver connected to our stm32_dvm_pihat.
I compiled the FM_AX25 branch for MMDVMHost, which seems to run OK (I can test FM and YSF, and d-star transmits OK).

However, nothing gets printed in the log file while sending AX25 packets. I do see the COS led going active during a AX25 packet, so the audio seems to reach the modem.

After some thinking, I wonder if the following statement from Jonathan indicates that I need another new firmware on the modem, which would include AX25:
''' The code for the modem and the host is in the AX25 branch on GitHub '''

@ Steve N4IRS , could you shed some light on this? 
I tried to understand what is required if the above is true, but the following does not make sense to me yet:

from : http://www.repeater-builder.com/products/stm32-dvm-faq.html in the section 'how do I update the firmware' :

https://github.com/N4IRS/MMDVM-Install/tree/master/STM32-DVM

05


Many thanks,

Ron


Phil M0VSE
 

Hi Ron,

 

Yes you definitely need an updated firmware, I don’t know if the FM_AX25 branch has been tested on the STM32-DVM from Repeater Builder yet though as it is still quite experimental.

 

73 Phil M0VSE

 

From: OpenDV@groups.io <OpenDV@groups.io> On Behalf Of ronnieponnie@...
Sent: 11 July 2020 22:23
To: OpenDV@groups.io
Subject: Re: [OpenDV] AX.25 in the MMDVM

 

Hi All (and Steve N4IRS),

Today I attempted to feed some AX25 packets to the receiver connected to our stm32_dvm_pihat.
I compiled the FM_AX25 branch for MMDVMHost, which seems to run OK (I can test FM and YSF, and d-star transmits OK).

However, nothing gets printed in the log file while sending AX25 packets. I do see the COS led going active during a AX25 packet, so the audio seems to reach the modem.

After some thinking, I wonder if the following statement from Jonathan indicates that I need another new firmware on the modem, which would include AX25:
''' The code for the modem and the host is in the AX25 branch on GitHub '''

@ Steve N4IRS , could you shed some light on this? 
I tried to understand what is required if the above is true, but the following does not make sense to me yet:

from : http://www.repeater-builder.com/products/stm32-dvm-faq.html in the section 'how do I update the firmware' :

https://github.com/N4IRS/MMDVM-Install/tree/master/STM32-DVM

05



Many thanks,

Ron


pd1acf
 

Hi Phil / Steve,

Today I followed the instruction on :
 https://github.com/N4IRS/MMDVM-Install/blob/master/STM32-DVM/README.txt
followed by :
 https://github.com/N4IRS/MMDVM-Install/tree/master/STM32-DVM/Version_3
and for both using the MMDVM branch FM_AX25

Above resulted in a mmdvm_f4.hex file, which I could program into the stm32_dvm_pihat.

The file new firmware version seems to be OK for the MMDVMHost version compiled for FM_AX25, as it detects the modem, and starts up.

-rw-r--r-- 1 root    root    816339 Jul 12 16:47 mmdvm_f4.hex

# sha256sum mmdvm_f4.hex
585be131a7bb58fc47645a57b02926907445d6d2793ce2240dd69e1435e51d1b  mmdvm_f4.hex


I will further investigate if this make reception of AX25 packets happening !


73'

Ron


pd1acf
 

Dear Phil / Steve / All,

While further experimenting with AX25 (still unsuccesfull yet...), I noticed the modem GIT version was still the same as with the FM only version. That was clearly not correct, so I further investigated. Apparently I made a mistake with the GIT checkout commands, resulting in a wrong version of the code used during build.

After a checkout of the correct firmware, and with a slightly modified instruction I could now build a firmware which includes AX25 :

root@mmdvmhost(ro):pi-star# pistar-findmodem
Detected MMDVM    (GPIO): /dev/ttyAMA0 (MMDVM 20200712 (D-Star/DMR/System Fusion/P25/NXDN/POCSAG/FM/AX.25) 12.0000 MHz GitID #5960fb9)


Steve's original 'instructions' perform a copy of two files: Config.h and IO.cpp
When copying Config.h, building still works correctly.
When copying IO.cpp, building fails:

root@mmdvmhost(rw):MMDVM# make dvm
arm-none-eabi-g++ -Os -fno-exceptions -ffunction-sections -fdata-sections -fno-builtin -fno-rtti -DCUSTOM_NEW -DNO_EXCEPTIONS -c -mcpu=cortex-m4 -mthumb -mlittle-endian -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb-interwork -I. -I./STM32F4XX_Lib/CMSIS/Include/ -I./STM32F4XX_Lib/Device/ -I./STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/ -DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F446xx -DSTM32F4_DVM -DHSE_VALUE=8000000 -DMADEBYMAKEFILE IO.cpp -o obj_f4/IO.o
IO.cpp: In member function 'void CIO::process()':
IO.cpp:276:40: error: no matching function for call to 'CRingBuffer<TSample>::get(uint16_t&, uint8_t&)'
       m_rxBuffer.get(sample, control[i]);
                                        ^
In file included from RingBuffer.h:75:0,
                 from SerialPort.h:24,
                 from Globals.h:77,
                 from IO.cpp:22:
RingBuffer.impl.h:83:36: note: candidate: bool CRingBuffer<TDATATYPE>::get(TDATATYPE&) volatile [with TDATATYPE = TSample]
 template <typename TDATATYPE> bool CRingBuffer<TDATATYPE>::get(TDATATYPE& item) volatile
                                    ^~~~~~~~~~~~~~~~~~~~~~
RingBuffer.impl.h:83:36: note:   candidate expects 1 argument, 2 provided
IO.cpp: In member function 'void CIO::write(MMDVM_STATE, q15_t*, uint16_t, const uint8_t*)':
IO.cpp:495:37: error: no matching function for call to 'CRingBuffer<TSample>::put(uint16_t&, const uint8_t&)'
       m_txBuffer.put(res3, MARK_NONE);
                                     ^
In file included from RingBuffer.h:75:0,
                 from SerialPort.h:24,
                 from Globals.h:77,
                 from IO.cpp:22:
RingBuffer.impl.h:59:36: note: candidate: bool CRingBuffer<TDATATYPE>::put(TDATATYPE) volatile [with TDATATYPE = TSample]
 template <typename TDATATYPE> bool CRingBuffer<TDATATYPE>::put(TDATATYPE item) volatile
                                    ^~~~~~~~~~~~~~~~~~~~~~
RingBuffer.impl.h:59:36: note:   candidate expects 1 argument, 2 provided
IO.cpp:497:38: error: no matching function for call to 'CRingBuffer<TSample>::put(uint16_t&, const uint8_t&)'
       m_txBuffer.put(res3, control[i]);
                                      ^
In file included from RingBuffer.h:75:0,
                 from SerialPort.h:24,
                 from Globals.h:77,
                 from IO.cpp:22:
RingBuffer.impl.h:59:36: note: candidate: bool CRingBuffer<TDATATYPE>::put(TDATATYPE) volatile [with TDATATYPE = TSample]
 template <typename TDATATYPE> bool CRingBuffer<TDATATYPE>::put(TDATATYPE item) volatile
                                    ^~~~~~~~~~~~~~~~~~~~~~
RingBuffer.impl.h:59:36: note:   candidate expects 1 argument, 2 provided
IO.cpp: At global scope:
IO.cpp:532:6: error: prototype for 'void CIO::setParameters(bool, bool, bool, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, int16_t, int16_t)' does not match any in class 'CIO'
 void CIO::setParameters(bool rxInvert, bool txInvert, bool pttInvert, uint8_t rxLevel, uint8_t cwIdTXLevel, uint8_t dstarTXLevel, uint8_t dmrTXLevel, uint8_t ysfTXLevel, uint8_t p25TXLevel, uint8_t nxdnTXLevel, uint8_t pocsagTXLevel, uint8_t fmTXLevel, int16_t txDCOffset, int16_t rxDCOffset)
      ^~~
In file included from Globals.h:104:0,
                 from IO.cpp:22:
IO.h:49:8: error: candidate is: void CIO::setParameters(bool, bool, bool, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, int16_t, int16_t)
   void setParameters(bool rxInvert, bool txInvert, bool pttInvert, uint8_t rxLevel, uint8_t cwIdTXLevel, uint8_t dstarTXLevel, uint8_t dmrTXLevel, uint8_t ysfTXLevel, uint8_t p25TXLevel, uint8_t nxdnTXLevel, uint8_t pocsagTXLevel, uint8_t fmTXLevel, uint8_t ax25TXLevel, int16_t txDCOffset, int16_t rxDCOffset);
        ^~~~~~~~~~~~~
make: *** [Makefile:278: obj_f4/IO.o] Error 1
root@mmdvmhost(rw):MMDVM#





With the current firmware (only Config.h replaced) the modem does load, but there are a load of errors in the log file :

E: 2020-07-12 18:43:44.290 **** Underflow in Modem RX FM ring buffer, 3 < 4
E: 2020-07-12 18:43:44.296 **** Underflow in Modem RX FM ring buffer, 2 < 33685506
E: 2020-07-12 18:43:44.296 **** Underflow in Modem RX FM ring buffer, 2 < 4
E: 2020-07-12 18:43:44.301 **** Underflow in Modem RX FM ring buffer, 2 < 4
E: 2020-07-12 18:43:44.301 **** Underflow in Modem RX FM ring buffer, 2 < 4
E: 2020-07-12 18:43:44.307 **** Underflow in Modem RX FM ring buffer, 2 < 4
E: 2020-07-12 18:43:44.307 **** Underflow in Modem RX FM ring buffer, 2 < 4
E: 2020-07-12 18:43:44.312 **** Underflow in Modem RX FM ring buffer, 2 < 4
E: 2020-07-12 18:43:44.312 **** Underflow in Modem RX FM ring buffer, 2 < 4
E: 2020-07-12 18:43:44.317 **** Underflow in Modem RX FM ring buffer, 2 < 4
E: 2020-07-12 18:43:44.317 **** Underflow in Modem RX FM ring buffer, 2 < 4
E: 2020-07-12 18:43:44.323 **** Underflow in Modem RX FM ring buffer, 2 < 4
E: 2020-07-12 18:43:44.323 **** Underflow in Modem RX FM ring buffer, 2 < 4
E: 2020-07-12 18:43:44.328 **** Underflow in Modem RX FM ring buffer, 2 < 4
E: 2020-07-12 18:43:44.328 **** Underflow in Modem RX FM ring buffer, 2 < 4
E: 2020-07-12 18:43:44.333 **** Underflow in Modem RX FM ring buffer, 2 < 4
E: 2020-07-12 18:43:44.333 **** Underflow in Modem RX FM ring buffer, 2 < 4



This needs some more time/investigations, any help is appreciated !

73'

Ron


Phil M0VSE
 

Hi Ron.

 

I’m not sure what modifications are in IO.cpp but a quick glance at the code shows me that the version from N4IRS is missing various code that is needed to run AX.25 so unless you are happy/able to compare the two and merge them yourself, you may be best to wait until AX.25 makes it into the master branch and Steve has made suitably modified files available?

 

73 Phil M0VSE

 

From: OpenDV@groups.io <OpenDV@groups.io> On Behalf Of ronnieponnie@...
Sent: 12 July 2020 20:16
To: OpenDV@groups.io
Subject: Re: [OpenDV] AX.25 in the MMDVM

 

Dear Phil / Steve / All,

While further experimenting with AX25 (still unsuccesfull yet...), I noticed the modem GIT version was still the same as with the FM only version. That was clearly not correct, so I further investigated. Apparently I made a mistake with the GIT checkout commands, resulting in a wrong version of the code used during build.

After a checkout of the correct firmware, and with a slightly modified instruction I could now build a firmware which includes AX25 :

root@mmdvmhost(ro):pi-star# pistar-findmodem

Detected MMDVM    (GPIO): /dev/ttyAMA0 (MMDVM 20200712 (D-Star/DMR/System Fusion/P25/NXDN/POCSAG/FM/AX.25) 12.0000 MHz GitID #5960fb9)



Steve's original 'instructions' perform a copy of two files: Config.h and IO.cpp
When copying Config.h, building still works correctly.
When copying IO.cpp, building fails:

root@mmdvmhost(rw):MMDVM# make dvm

arm-none-eabi-g++ -Os -fno-exceptions -ffunction-sections -fdata-sections -fno-builtin -fno-rtti -DCUSTOM_NEW -DNO_EXCEPTIONS -c -mcpu=cortex-m4 -mthumb -mlittle-endian -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb-interwork -I. -I./STM32F4XX_Lib/CMSIS/Include/ -I./STM32F4XX_Lib/Device/ -I./STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/ -DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F446xx -DSTM32F4_DVM -DHSE_VALUE=8000000 -DMADEBYMAKEFILE IO.cpp -o obj_f4/IO.o

IO.cpp: In member function 'void CIO::process()':

IO.cpp:276:40: error: no matching function for call to 'CRingBuffer<TSample>::get(uint16_t&, uint8_t&)'

       m_rxBuffer.get(sample, control[i]);

                                        ^

In file included from RingBuffer.h:75:0,

                 from SerialPort.h:24,

                 from Globals.h:77,

                 from IO.cpp:22:

RingBuffer.impl.h:83:36: note: candidate: bool CRingBuffer<TDATATYPE>::get(TDATATYPE&) volatile [with TDATATYPE = TSample]

 template <typename TDATATYPE> bool CRingBuffer<TDATATYPE>::get(TDATATYPE& item) volatile

                                    ^~~~~~~~~~~~~~~~~~~~~~

RingBuffer.impl.h:83:36: note:   candidate expects 1 argument, 2 provided

IO.cpp: In member function 'void CIO::write(MMDVM_STATE, q15_t*, uint16_t, const uint8_t*)':

IO.cpp:495:37: error: no matching function for call to 'CRingBuffer<TSample>::put(uint16_t&, const uint8_t&)'

       m_txBuffer.put(res3, MARK_NONE);

                                     ^

In file included from RingBuffer.h:75:0,

                 from SerialPort.h:24,

                 from Globals.h:77,

                 from IO.cpp:22:

RingBuffer.impl.h:59:36: note: candidate: bool CRingBuffer<TDATATYPE>::put(TDATATYPE) volatile [with TDATATYPE = TSample]

 template <typename TDATATYPE> bool CRingBuffer<TDATATYPE>::put(TDATATYPE item) volatile

                                    ^~~~~~~~~~~~~~~~~~~~~~

RingBuffer.impl.h:59:36: note:   candidate expects 1 argument, 2 provided

IO.cpp:497:38: error: no matching function for call to 'CRingBuffer<TSample>::put(uint16_t&, const uint8_t&)'

       m_txBuffer.put(res3, control[i]);

                                      ^

In file included from RingBuffer.h:75:0,

                 from SerialPort.h:24,

                 from Globals.h:77,

                 from IO.cpp:22:

RingBuffer.impl.h:59:36: note: candidate: bool CRingBuffer<TDATATYPE>::put(TDATATYPE) volatile [with TDATATYPE = TSample]

 template <typename TDATATYPE> bool CRingBuffer<TDATATYPE>::put(TDATATYPE item) volatile

                                    ^~~~~~~~~~~~~~~~~~~~~~

RingBuffer.impl.h:59:36: note:   candidate expects 1 argument, 2 provided

IO.cpp: At global scope:

IO.cpp:532:6: error: prototype for 'void CIO::setParameters(bool, bool, bool, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, int16_t, int16_t)' does not match any in class 'CIO'

 void CIO::setParameters(bool rxInvert, bool txInvert, bool pttInvert, uint8_t rxLevel, uint8_t cwIdTXLevel, uint8_t dstarTXLevel, uint8_t dmrTXLevel, uint8_t ysfTXLevel, uint8_t p25TXLevel, uint8_t nxdnTXLevel, uint8_t pocsagTXLevel, uint8_t fmTXLevel, int16_t txDCOffset, int16_t rxDCOffset)

      ^~~

In file included from Globals.h:104:0,

                 from IO.cpp:22:

IO.h:49:8: error: candidate is: void CIO::setParameters(bool, bool, bool, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, int16_t, int16_t)

   void setParameters(bool rxInvert, bool txInvert, bool pttInvert, uint8_t rxLevel, uint8_t cwIdTXLevel, uint8_t dstarTXLevel, uint8_t dmrTXLevel, uint8_t ysfTXLevel, uint8_t p25TXLevel, uint8_t nxdnTXLevel, uint8_t pocsagTXLevel, uint8_t fmTXLevel, uint8_t ax25TXLevel, int16_t txDCOffset, int16_t rxDCOffset);

        ^~~~~~~~~~~~~

make: *** [Makefile:278: obj_f4/IO.o] Error 1

root@mmdvmhost(rw):MMDVM#






With the current firmware (only Config.h replaced) the modem does load, but there are a load of errors in the log file :

E: 2020-07-12 18:43:44.290 **** Underflow in Modem RX FM ring buffer, 3 < 4

E: 2020-07-12 18:43:44.296 **** Underflow in Modem RX FM ring buffer, 2 < 33685506

E: 2020-07-12 18:43:44.296 **** Underflow in Modem RX FM ring buffer, 2 < 4

E: 2020-07-12 18:43:44.301 **** Underflow in Modem RX FM ring buffer, 2 < 4

E: 2020-07-12 18:43:44.301 **** Underflow in Modem RX FM ring buffer, 2 < 4

E: 2020-07-12 18:43:44.307 **** Underflow in Modem RX FM ring buffer, 2 < 4

E: 2020-07-12 18:43:44.307 **** Underflow in Modem RX FM ring buffer, 2 < 4

E: 2020-07-12 18:43:44.312 **** Underflow in Modem RX FM ring buffer, 2 < 4

E: 2020-07-12 18:43:44.312 **** Underflow in Modem RX FM ring buffer, 2 < 4

E: 2020-07-12 18:43:44.317 **** Underflow in Modem RX FM ring buffer, 2 < 4

E: 2020-07-12 18:43:44.317 **** Underflow in Modem RX FM ring buffer, 2 < 4

E: 2020-07-12 18:43:44.323 **** Underflow in Modem RX FM ring buffer, 2 < 4

E: 2020-07-12 18:43:44.323 **** Underflow in Modem RX FM ring buffer, 2 < 4

E: 2020-07-12 18:43:44.328 **** Underflow in Modem RX FM ring buffer, 2 < 4

E: 2020-07-12 18:43:44.328 **** Underflow in Modem RX FM ring buffer, 2 < 4

E: 2020-07-12 18:43:44.333 **** Underflow in Modem RX FM ring buffer, 2 < 4

E: 2020-07-12 18:43:44.333 **** Underflow in Modem RX FM ring buffer, 2 < 4




This needs some more time/investigations, any help is appreciated !

73'

Ron


pd1acf
 

@Steven N4IRS,

Dear Steve, would you have some time to build a firmware for the MMDVM V3 boards from the AX25_FM branch?
I seem to be unable to build it myself.

Many thanks in advance.

73'

ron


Gaston LU5AGQ
 

If you find it useful, here are the binaries I've compiled based on the 2509ab5 commit (which as today is the latest) from master for my V3 board (the blue one).

https://filebin.net/yo5344dfp59u80ei/bin.zip

73


pd1acf
 

Hi Gaston,

Many thanks, however I am not looking for the 'master' compiled version (this builds OK on my side also).

For experimenting with AX25 we need this branch https://github.com/g4klx/MMDVM/tree/AX25_FM in combination with https://github.com/g4klx/MMDVMHost/tree/AX25_FM

Then (if I am correct reading from previous hints for compiling for the V3 PiHat board), we need some additional steps on top of this branch : https://github.com/N4IRS/MMDVM-Install/tree/master/STM32-DVM/Version_3 

This last step is where I struggle to make a correct compilation.

Please let me know your thoughts...

Ron