As regular readers will know, Kai DG4KLU cracked the encryption on the Radioddity GD-77 DMR radio firmware back in March.
This has allowed the official firmware to be decrypted, modified and uploaded to the radio again, and also allows non-Radioddity firmware to be loaded onto the radio.
Initially after Kai cracked the firmware, my main focus was on attempting to understand how the official firmware functions, and to make changes and enhancements to the official firmware. This included removing the requirement that every DMR channel needs to have an Rx Group assigned to it, enhancing the DMR ID callsign / name lookup system, and more recently attempting to add direct TalkGroup numerical entry.
However, making more than minor modifications to the official firmware, proved to be an incredibly complex and time consuming process.
So when Kai told me, about 4 weeks ago, that he had some experimental open source firmware which was able to receive both FM and also DMR, I was keen to take a closer look….
Kai’s firmware is hosted on github in a sub folder of Kai’s other GD-77 related work, which includes his decryption and encryption tools
https://github.com/talentraspel/GD-77/tree/master/GD-77_new_firmware
Everything is open source, except that DMR audio codec, which is merged as a binary inclusion from the official Radioddity firmware.
Kai’s initial firmware, featured 4 VFO’s, and can be set to receive either DMR or FM (aka analog), and looked like this.
![]()
I was amazed at the progress Kai had made in only 2 months, because DMR decoding and reception is a very complex task.
His progress wasn’t helped by the fact that the main Digital Signal Processor chip in the GD-77, which both demodulates the 4FSK signal and converts to a DRM data stream, is a Chinese made IC that does not have any English language data sheets or other documentation.
The DSP is a HR-C6000, and the data sheet isn’t even publicly available; and we have Andrea Contini to thank for managing to obtain a copy of the Chinese language data sheet.
Kai’s firmware was able to receive DMR relatively well, with some occasional lockups, and strange noises from time to time.
In the following couple of weeks, Kai refined his DMR decoding software, which greatly improved the reliability and there are now hardly any lockups or unexpected noises.
At this point I realised that my time, effort and skills would be better employed helping Kai to write his Open Source firmware, than only continuing to modify the official firmware, especially considering that the official firmware was proving to be very difficult to modify, for numerous technical reasons which I won’t elaborate on at the moment.
Kai asked me to write the source code to communicate with the 64k EEPROM and also the 1Mb Flash memory, and also to write a better display driver for the 128×64 pixel back and white LCD screen.
Again, I won’t bore you with the technical details, but it took me about 2 weeks to write these 3 blocks of functionality, which Kai then merged into his main codebase.
I also suggested to Kai, that full blown menu system was needed for his firmware, and I’ve spent most of the last 2 weeks, building the menu system, and then implementing a number of new screens and new functionality, which Kai merged into his master code-base yesterday.
With the result being these screenshots, which are in this blog.
For those of you with more than one GD-77, or the very adventurous with only one GD-77, Kai has uploaded the firmware files to his git repository here
https://github.com/talentraspel/GD-77/tree/master/GD-77_new_firmware/firmware_binaries
With the latest version being downloadable from this link https://github.com/talentraspel/GD-77/raw/master/GD-77_new_firmware/firmware_binaries/firmware_V0_1.sgl
Please note.
This firmware should be viewed as experimental, and you use it at your own risk.
And currently it is Receive Only
After booting up, the software enters its VFO screen.
There are 4 VFO’s which can be accessed by cycling through using the left and right arrows.
The modulation mode is toggled between DMR and FM aka Analog, by pressing the star * key
![]()
![]()
The frequency can also be entered manually, like in the official Radioddity firmware.
![]()
![]()
Pressing the Red menu key, while on the VFO screen, toggles to the Channel display screen, and from the Channel screen the Red menu key takes you back to the VFO screen.
(Note. This functionality differs from the official firmware, which uses the Right arrow, because both the VFO and the Channel screen use the Right arrow key for their functionality
The Channel screen attempts to read the codeplug data that is already in the Flash memory of the radio.
I say attempts, because the official codeplug format in memory is a fragmented mess, and we have decided that there is ultimately no point in attempting to continue to use the official codeplug format within the radio.
The legacy codeplug support which I’ve written is primarily just so that, people can take a look at Kai’s firmware, before we write a new CPS.
The Channel screen differs from the official version, in that it displays the Channel name, in this case “Duplex HS” (for duplex hotspot), and also the TalkGroup to use on that channel ( frequency ).
The TalkGroup is derived from the Rx Group list which is assigned to the channel.
In my case, I made a copy of my existing codeplug, and removed all duplicate channels which were the same frequency, and only differed because they had a different TalkGroup assigned to them.
I also updated my Rx Groups, so that each group contained all the TG’s I want to use with a channel (frequency).
e.g.
I now have RxGroups for DMR MARC Australia, which contains TG’s 505, 3801 – 3810 and TG9, 113 and 123, which are the TG’s supported by the repeater network.
I also have another Rx Group for Brandmeister Australia, which includes TG 505, 5050, 5051, etc, which I use in conjunction with the channel for my hotspot.
Hence I now have need far less channels, and the term “channel” goes back to its more conventional meaning of “frequency”, rather than being a combination of frequency and other settings (mainly TalkGroup)
To change TG on the same Channel (frequency), I press either the Right or Left button, to cycle through the TG’s in the Rx Group.
![]()
For example, I change to TG 3801 by pressing the Right Arrow, since in my Rx Group list for DMR MARC Australia the second TG in the list is 3801.
![]()
Just a quick note about TimeSlots. Currently Kai’s firmware is receive only, and does not filter either by TG or even TimeSlot.
i.e It will receive any traffic on any TimeSlot on the chosen frequency.
Obviously in the future, when the firmware is able to transmit, the TimeSlot will have to be catered for.
BTW. I’ve renamed the Rx Group, as a TRx Group, since it will both set the Tx TG as well as the Rx TG.
In terms of the TimeSlot, I can think of at least 2 different ways that this can be handled.
1. Each TG is assigned a TimeSlot from within the Digital Contact screen in the CPS.
2. Or.. When a TG is assigned to TRx Group, the user will also select which TimeSlot to use for this entry in the TRx Group.
I don’t know if there are any situations where the same TG is used on both TimeSlots on the same repeater, but if this is used somewhere in the world, this could be catered for, either by adding the same TG into the TRx Group twice, once on TS1 and once on TS2, by allowing the user to toggle between TS’s on the Channel screen.
In fact, there will definitely be an option to toggle between TG on the channel screen, possibly using the star “*’ key
Looking at the menu system which is now in Kai’s firmware…
Pressing the Green menu key, access the menu system in the same way as it does in the official firmware, but as you can see in the photo below the menu options are not the same ![😉]()
And.. Rather than 2 menu items on the screen at a time, I’m displaying 3, with the centre menu option being the one which will be selected by pressing the Green key again.
![]()
Here I pressed the up arrow, to move the Zone to the middle of the screen, then selected it
![]()
Looking at the Zones screen, its very similar to the official Zone menu, except it displays 3 zones
![]()
Note. My codeplug reading code, seems to not be able to detect zones which have been deleted, so you will see the zones visible in the CPS but also old zones which have been removed from the CPS.
I’m sure I will be able to find out how the CPS stores which zones are active and which have been deleted, but at the moment, this is a known bug with the firmware.
Selecting a zone, transfers its frequency and mode into the Channel screen, even if you are in the VFO screen. This is the same functionality as the official firmware, but it strikes me that perhaps if you select a zone whilst in the VFO, then perhaps the radio should be switched into Channel mode.
Virtually all the rest of the menu options are for new functions, in Kai’s firmware.
The first new screen is the RSSI, (Received Signal Strength Indicator)
This screen is experimental, and works in both DMR and Analog mode, and displays the RF signal strength, and also a paramater, in the receiver chip (AT-1846S), called “Noise”.
The numerical values which are displayed, still need to be calibrated, and are the raw values from the receiver chip.
Noise appears to be the audio level of the demodulated FM signal.
Hence when there is little of no signal, the Noise value is at its highest of around 60.
![]()
When there is a DMR signal, e.g in this case from my hotspot, the RSSI increases to its maximum value, which seems to be approximately 70, and the noise decreases, because its the 4FSK of the digital transmission.
![]()
If I transmit using an FM transceiver on the same frequency, the noise is very low, because its a clean carrier with no audio. In my case as you can just about makeout, the value is changing between around 7 and 8.
And the RSSI is again 70, i.e the maximum.
In the fullness of time it should be possible to calibrate the RSSI e.g. 70 probably equates to 60dB over 9.
![]()
The next new screen is the battery voltage, which has some nice large text of the voltage, and also includes a bar graph representing the voltage of the battery, in this case 8.3V is 100% capacity
![]()
Next on the list are the display options.
I’ve added PWM (pulse width modulation) control to the LED backlight on the display, so that it can be dimmed, either for continuous operation while in the shack on a charger, or perhaps for night time operation.
I’ve also added a control for the LCD contrast, because I found that the contrast value used in the official firmware, which for the record is 15, is a bit lower than is optimal for my radio’s display, and I have set the default in Kai’s firmware to 17, but I normally adjust it to about 20, which makes the text even easier to see.
Its hard to see in photo’s since my camera compensates for the light level, but here is the display at bightness of 1
![]()
And here it is at 60%. Note that the radio and background of the photo are darker, because the camera is adjusting for the light produced by the display.
![]()
Reducing the contrast makes for a “washed out” display.
![]()
But increasing it too much, causes the background pixels to start to become visible, hence you have to strike the best balance for your own radio.
![]()
Another new feature is the “Last Heard” screen.
This operates like the PiStar dashboard, and keeps track of any DMR stations which are heard, and automatically adds new stations to the top of the list, or moves a station already in the list, to the top of the list when they transmit.
In this case I made a CQ call and Alex VK2PSF relied and was speaking when I took this photo.
![]()
After speaking to Alex, Peter VK4NBL called me, and I was speaking to him via another GD-77 when I took this photo.
![]()
Of course the Channel screen displays the current TG and callsign as in the official firmware.
![]()
I forgot to mention, that Kai’s firmware is currently setup to read the DMR ID database which I already loaded into the radio prior to installing Kai’s firmware, and uses virtually the same search method that the official firmware uses; except I found a more efficient algorithm on Wikipedia, hence the callsign lookup takes up less of the CPU’s time and resources.
Before I almost finish this blog post, I must thank Kai again, for his amazing work handling the complex low level part of the operation of the transceiver, which is extremely technically challenging, as well as building the overall software project including the use of a RealTime Operating system (FreeRTOS), and all the other complex technicalities of configuring a microprocessor to run at all.
And what’s next…
Well, my understanding is that Kai has now started work on DMR transmission, but I think this is likely to be an even more challenging task than DMR Rx, so I have no idea of how long this will take him.
I think Kai is better placed to write the Tx functionality, since he has written the Rx functionality, and my time is likely to be better spent doing other things, like writing a new CPS or perhaps implementing things like Text Message reception and Talker Alias reception etc.
The new CPS will definitely be able to read most of the data from the existing codeplug, one way or another, since I know people have invested a lot of time and effort into their existing codeplugs.
But some changes will be needed when moving to the new CPS paradigm, which will almost certainly need to be made manually.
The new CPS will probably be a Windows exe written using C#, so that I can re-use a lot of the screens etc from the community CPS, but I will make sure it runs under Wine on Linux, unlike the Community CPS which unfortunately has inherited some traits from the official CPS which means it won’t run using Wine.
I also have some other interesting ideas of enhancements for both Rx and Tx functionality, but I won’t post about these until I have made some progress with these.
One final thought…
If anyone else out there who has a GD-77, and can program in C is interested in helping, there is still loads of functionality that needs to be written, so please contact me, and I can send you details of the IDE and toolchain etc, (in addition to the information Kai has documented about this in his github repository)