DevelopersAdd a Radio » History » Version 3
Aaron P, 01/10/2017 03:38 PM
Fix link to template.py
1 | 1 | Tom Hayward | h1. Add a Radio |
---|---|---|---|
2 | |||
3 | You've got a radio that's not in Chirp, a little bit of software development experience, and you want to add that radio to Chirp. Here's what you'll need: |
||
4 | |||
5 | * a subscription to the "chirp_devel mailing list":http://intrepid.danplanet.com/mailman/listinfo/chirp_devel |
||
6 | * a Python + PyGTK development environment |
||
7 | * radio |
||
8 | * programming cable |
||
9 | |||
10 | h2. Setting up the development environment |
||
11 | |||
12 | Most Chirp contributors develop in Ubuntu Linux. Mainly, because we're lazy. Ubuntu comes with almost everything needed to develop for Chirp: Python, PyGTK, and a text editor. The one missing piece is Mercurial, for source code management. |
||
13 | |||
14 | To install Mercurial: |
||
15 | |||
16 | sudo apt-get install mercurial |
||
17 | |||
18 | If you've never used Mercurial before, please read [[DevelopersProcess]]. Actually, even if you have used Mercurial, that's a good document to read. It describes how to get the Chirp source code and generate a patch in the required format for inclusion in Chirp. |
||
19 | |||
20 | If you want to develop in another operating system, you're on your own. This guide isn't going to cover it. Here's a guide for Windows: [[DevelopersWin32Environment]]. |
||
21 | |||
22 | h2. Look over some existing code |
||
23 | |||
24 | 3 | Aaron P | Read source:chirp/drivers/template.py. The whole thing. |
25 | 1 | Tom Hayward | |
26 | h2. Write the download/upload routines |
||
27 | |||
28 | h3. Sniffing the protocol used by existing software |
||
29 | |||
30 | If you have other programming software for your radio, such as the software from the manufacturer, you can sniff the programming protocol with "Portmon":http://technet.microsoft.com/en-us/sysinternals/bb896644.aspx. Typically, radio programming software is writtne for Windows, and Portmon is a Windows utility. |
||
31 | |||
32 | Start with a read. |
||
33 | |||
34 | # Click Read in the official software |
||
35 | # Watch the output of Portmon after you click Read |
||
36 | # Look for a line that sets the BAUD RATE. Sometimes there are a few of them. |
||
37 | # Look for a WRITE line with a few data bytes. This is probably the command to tell the radio to start sending data. |
||
38 | # Look for READ lines with lots of data bytes after them. This is probably the memory contents of the radio being downloaded |
||
39 | # You're a smart developer. You should be able to figure out the protocol from here! |
||
40 | |||
41 | h3. Using existing Chirp code |
||
42 | |||
43 | If the radio you're developing for doesn't have existing programming software, you won't be able to use the above reverse engineering technique. Most radio manufacturers use a common protocol across most of their radios. Because Chirp supports so many manufacturers, there's a chance an existing radio driver has a download routine that will work with your new radio. This is especially true with Yaesu, which don't really even have a protocol. They just dump their memory. All you need to figure out is the baud rate and the memory size (and baud rate is usually 9600). |
||
44 | |||
45 | Choose a radio driver that you think might be similar. If you were going to add the VX9, you might start with the VX8 driver: |
||
46 | |||
47 | cd chirp.hg/chirp |
||
48 | sed s/VX8/VX9/g vx8.py > vx9.py |
||
49 | |||
50 | Increase the @_memsize@ variable significantly. The goal is to read more data than the radio sends. |
||
51 | |||
52 | Launch Chirp and start a download with your new radio driver. Did it work, sort of? Save the .img. |
||
53 | |||
54 | Now we're going to determine the @_memsize@. Open the .img in a hex editor: |
||
55 | |||
56 | hexdump -C VX9_oversize.img | less |
||
57 | |||
58 | Look towards the end of the file for the offset where the data becomes all zeros. This is your @_memsize@. The radio has stopped sending data, but Chirp was still "reading". Change @_memsize@ in your driver so that Chirp reads the same number of bytes the radio is sending. |
||
59 | |||
60 | h2. Map the memory blob |
||
61 | |||
62 | To map the memory layout, you're going to make a small change on the radio, do a download, then look for differences. Do this over and over until you have the whole memory layout mapped. |
||
63 | |||
64 | Here's a little helper script I use for the comparisons: |
||
65 | |||
66 | @hexdiff.sh:@ |
||
67 | <pre> |
||
68 | #!/bin/sh |
||
69 | |||
70 | A=`mktemp` |
||
71 | B=`mktemp` |
||
72 | |||
73 | hexdump -C $1 > $A |
||
74 | hexdump -C $2 > $B |
||
75 | diff $A $B | less |
||
76 | rm $A $B |
||
77 | </pre> |
||
78 | |||
79 | # Find the first channel |
||
80 | # Find the second channel |
||
81 | # The offset between the two is your memory channel struct size |
||
82 | # Find the last channel. Hopefully its offset is struct size * advertised number of channels away from the first channel! |
||
83 | |||
84 | You'll probably start off with something like this: |
||
85 | <pre> |
||
86 | MEM_FORMAT = """ |
||
87 | #seekto 0xb00; |
||
88 | struct { |
||
89 | u32 freq; |
||
90 | u8 unknown1; |
||
91 | u8 unknown2; |
||
92 | u8 unknown3; |
||
93 | char name[8]; |
||
94 | } memory[200]; |
||
95 | """ |
||
96 | </pre> |
||
97 | @0xb00@ is the location of the first memory channel. |
||
98 | @200@ is the number of channels the radio supports. |
||
99 | @unknown1@, @unknown2@, and @unknown3@ are for memory-specific settings (e.g., tone) that you haven't sussed out yet. |
||
100 | |||
101 | h2. Write @get_memory()@ |
||
102 | |||
103 | h2. Write @set_memory()@ |
||
104 | |||
105 | h2. Submit code to chirp_devel |
||
106 | |||
107 | Send a hg patch to the developer mailing list for review. We'll pick it apart and give you a list of things that can be improved before inclusion in Chirp. Don't take it personally! Our goal is to produce high quality software through peer review. |
||
108 | 2 | Brian Dickman | |
109 | h2. Pass testing |
||
110 | |||
111 | More detail on this in [[DevelopersProcess#Testing]]. In summary, create a test image in tests/images, make sure all tests pass, and attach the test image to your tracker issue for the new model. |