Dan,

[These thoughts were written to augment the existing page at https://chirp.danplanet.com/projects/chirp/wiki/DevelopersAdd_a_Radio.

They may be TMI for many of you experienced folks, but beginners might appreciate lessons-learned. And I’ve not written anything yet about how a Git noob can make your life miserable.

Declan Rieb, WD5EQY@arrl.net ]


Write get_memory(number: int | str)

This is called to get your driver to populate the CHIRP memory model with the data for one radio memory. On startup, it’s called once for each memory register you’ve delimited for your radio and once for each special memory. Later it will be called as needed.

- get_memory() returns a populated CHIRP memory object that the driver creates as a new instance of the chirp_common.Memory structure. You’ll want to become familiar with the fields in the Memory structure (presently specified in the source tree in the source file chirp/chirp_common.py).

  

- The number of memories is specified in chirp_common.RadioFeatures.memory_bounds, which is a pair of numbers (first memory register number, last memory register number.) get_memory will be called with an integer parameter for regular memory with a value up to the last memory register number.

- Special memories are radio-specific registers that can hold special meaning in the radio (such as scan limits, home registers, skip registers, etc.) They are specified in your driver as members of the list that you set at chirp_common.RadioFeatures.valid_special_chans. get_memory() will be called with a string containing the name of the special register, and you must set the Memory.number field of the resulting memory object to an index that is greater than the last memory register number and different than other special memories without holes in the sequence. Subsequent calls to get_memory() may receive either the index or the name.

Do read the example driver at chirp/chirp/drivers/template.py. There is a commented stub version of this routine in chirp/chirp.common.py. Your driver is expected to overload it.



Write set_memory(memory: chirp_common.Memory)

This is called whenever CHIRP wants your driver to set the radio’s memory according to the fields described in the specific chirp_common.Memory parameter. The driver will presumably need to determine the specific radio memory based upon the value of memory.number (e.g. integer less than or greater than last memory number.) The driver should not change the memory structure.

There is no special return to CHIRP required.

Do read the example driver at chirp/chirp/drivers/template.py. There is a commented stub version of this routine in chirp/chirp.common.py. Your driver is expected to overload it.



Radio memory settings that are not included in CHIRP chirp_common.Memory.

CHIRP can (optionally) manage and display other settings for each memory.  These are stored in a separate subject chirp_common.Memory.extra, and are handled during the get_memory and set_memory by calling _get_mem_extra(mem, _mem) and _set_mem_extra(mem, _mem), respectively. “mem” is the CHIRP memory structure, and “_mem” is the corresponding radio memory structure. You’ll get to write code to handle them similar to “RadioSettings.”


Run tests

Read the wiki page at https://chirp.danplanet.com/projects/chirp/wiki/DevelopersPython3Environment

Tox is a separate application used to run tests for CHIRP. (I got it by “pip install tox” and it installed into my Python instance.) It will check syntax and stylistic features of the python source. It will also run many logic tests on all drivers that have changed in your tree since the last time it was run. Use:

$ tox -e style

You may then wish to run the driver test only on your driver. It appears that you can do so by executing 

$ tox -e driver -- -k Vendor_Model
Or (to only test drivers with changes:)
$ tox -e fast-driver

When your new driver gets to the GitHub and a Pull request is made, the CHIRP folks will cause even more extensive tests to be run on it, so try to pass these tests first.


Things not said elsewhere:

Some of the following are hinted at in the example driver “chirp/chirp/drivers/template.py.”

CHIRP has a “directory” structure of all the radios it should know about. Your driver will have one or more “@directory.register” statement, wherein a class is defined for each radio you’re working on. They can inherit from each other (even other models and vendors) once the classes are read by CHIRP. The directory is sorted by text (vendor, model) pairs.

That class will have definitions (and some redefinitions) for your radio. It will also implement a function
get_features() -> chirp_common.RadioFeatures()
You get to return basic information about your radio in the structure that CHIRP defines in chirp/chirp_common.py and you instantiate. Any existing driver should have one for you to copy and modify. CHIRP calls it fairly often when starting, so it’s expected to be lightweight. You probably don’t want this function to be querying the radio each time it’s called.


Modes:
CHIRP has a predefined set of “modes” available for each memory entry. Whatever your radio defines as modes, they MUST map into the CHIRP model. If the radio’s modes don’t fit into CHIRP’s model, you’ll get to add some translation into your driver. The current list (as of 2023-07-28 from chirp/chirp_common.py) is:

MODES = ("WFM", "FM", "NFM", "AM", "NAM", "DV", "USB", "LSB", "CW", "RTTY",
         "DIG", "PKT", "NCW", "NCWR", "CWR", "P25", "Auto", "RTTYR",
         "FSK", "FSKR", "DMR", "DN")


Live drivers
A more-official description can be found at https://chirp.danplanet.com/projects/chirp/wiki/FAQ.
Most radios seem to have a mode for which memory can be read or written as a large block, and their drivers reflect that. A few radios can only be accessed on what is effectively memory-by-memory reads/writes. These radios will almost surely need to be written as “live”. An example driver is at chirp/chirp/drivers/kenwood_live.py. Several other Kenwood drivers inherit from that one (at least ts480.py, tmd710.py, ts2000.py.) These drivers do not use the same radio-memory model as most of the others, but can keep a kind of cache.


______
Declan Rieb WD5EQY
wd5eqy@arrl.net