|Hacking the Baofeng UV5R|
|Opening The Radio|
|Hacking the Radio|
|Interfacing with the voice chip|
|interfacing with the RDA5802|
|Interfacing with the RDA1846|
|Removing the MCU|
IntroductionFor Christmas I got a Baofeng UV5R radio, which is a real cheep ($40) ham radio. Since I did not have a ham license, I started by simply programming it to be a police scanner. However, I soon got bored of just listening around and wanted to see what can be done with this radio. Since its a 4W radio, I thought it would be cool to try and send serial data over a few miles. After searching around a bit, I found that it can be programmed with an open source program called CHIRP. I was originally hoping that I could change the firmware, but after looking at the CHIRP code I realized that you can only program the channels in the radio, and a few settings. I even attempted to write a simple python script (derived from the chirp program), to see if other commands are available, but with no success. Since the schematics were available, I thought I could just try to interface with the cpu directly.
Opening the Radio
This was not too difficult. I found some information online from someone who needed to change the TX modulations.
Remove the battery and the belt clip. Remove the two screws on the back near the battery release switch (watch out for the spring) and remove the two screws on the back of the radio.
Pull the volume knob off, remove the nuts around the volume potentiometer and the antenna connector.
Pry up the back of the radio a bit, and pull that section back and away from the case (watch out for the speaker wire).
At this point you can desolder the speaker wire, but I left mine on because I am lazy.
Remove the screw down by the flashlight LED – this secures the battery connector.
Remove the battery connector
Remove the LCD display, and the screws holding the PCB together. Carefully remove the PCB by working around the antenna connector.
Hacking the radio
Before trying to change anything I posted on the baofeng_uv5r yahoo groups to see what I would need to insure that I will not radiate any RF energy. I found out that I could not just remove the antenna, and would need to place a dummy load. Per James Hall suggestion I ordered a dummy load from here qrpkits.
As soon as I got the radio, I signed up to take the license test. Unfortunately, the next one is on Jan 20. I can not wait to get licensed, so I can finally transmit and test this on the HAM frequencies. I also have not done anything with TX on this radio yet, which I am so attempted to try to see if that works.So for now I am just going to try to RX until I get my license.
Looking at the schematics, there are two main ICs on the radio. The first one is RDA1846 which does all the radio communications, and the other is an EM78P568 microcontroller which controls the RDA1846, LCD, keypad, etc.
I first tried to solder some wires directly onto the RDA1846 TX/RX pins and monitor them to see what the radio sends the chip.
First, I was hoping that the microcontroller will not communicate with the RDA1846 under various conditions (like switching to the RDA5802 FM radio) so I can also send commands to it. However, I monitored the SCLK and SDIO and it looks like its under constant communication. Since P93 and P92 are shared with the LCD (DB6, and DB7) as well as the keypad, the uv5r MCU is constantly setting/reading these pins. So their code probably has a loop setting the LCD, reading the keypad, and then transmitting serial commands to the RDA1846.
To resolved this I lifted P93 and P92 legs from the MCU (SCLK and SDIO) and solder two wires to it. I also soldered another line to P77 which is the SEN line. From the schematics, it looks like the MODE pin is tied to V+, which means it's communicating via SPI instead of I2C and the SEN line is used for ~EN.
I hooked up an arduino to the pins and tried to communicate over SPI, with no success. However, I should have not rushed into things, and noticed that the chip is 3.3V and not 5V (I was looking in their programming manual the whole time, and should have read the datasheet first).
Another small setback happened when I tried to remove the SEN pin, and the pcb trace lifted right up. So much for communicating with SPI, but luckily the chip can communicate over I2C, so I placed some solder on the RDA1946 chip to place it into I2C mode and remove the V+ tied to the MODE pin.
I also traced all the pins out of the cpu to insure that I know what each pin is doing. Here are the pins description:
Pin 1: PB5 keypad COL 1
Pin 2: PB6 keypad COL 2
Pin 3: PB7 keypad COL 3
Pin 4: P90 LCD DB4/keypad ROW 1/eeprom SDA
Pin 5: P91 LCD DB5/keypad ROW 2/
Pin 6: P92 LCD DB6/keypad ROW 3/RDA1846 SDIO
Pin 7: P93 LCD DB7/keypad ROW 4/RDA1846 SCLK
Pin 8: P94 RDA5802 DATA/keypad ROW 5
Pin 9: P95 LCD RS
Pin 10: P96 LCD CE
Pin 11: P97 Red LED on LCD
Pin 12: P57 The LED Flashlight
Pin 13: P56 VHF/UHF 1 UHF/ 0VHF
Pin 14: P55 Green LED on LCD
Pin 15: Analong VDD
Pin 16: No Connection
Pin 17: No Connection
Pin 18: No Connection
Pin 19: No Connection
Pin 20: TONE
Pin 21: PLCC
Pin 22: GND
Pin 23: P67 TX Power lever: 1.5V for LOW 1W and 2.67V for HIGH 4W
Pin 24: P66 TX power switch (low to activate TX)
Pin 25: P65 AURX Turn Speaker AMP on
Pin 26: P64 Low BAT input
Pin 27: P63 VOX from radio
Pin 28: P62 GPIO6 SQ on RDA1846
Pin 29: OSCI
Pin 30: OSCO
Pin 31: VSS
Pin 32: RESET
Pin 33: VDD
Pin 34: P77 SEN from RDA1846
Pin 35: P76 SDA for VOICE U5
Pin 36: P75 RX LED (square light on the radio)
Pin 37: P74 SCK for EEPROM U10
Pin 38: P73 SCL for VOICE U5
Pin 39: P72 TXD Serial input for programmer/ TX LED (square light on the radio)
Pin 41: P70 GPIO0 on RDA1846
Pin 40: P71 RDX serial input for programmer/ PPT on
Pin 42: PC0 CLK on RDA5802 U1
Pin 43: PC1 RX Power (PWM for save mode)
Pin 44: PC2 Keypad Col 4
I used the MSO19 to capture the data and see what the radio was doing. The nice thing about the MSO19, is that it has a pattern generator, so I was able to replay the commands back to the radio.
Interfacing with the voice chip
So here is how to interface with the voice chip.
Voice chip is SPI.
To send voice commands
CLK period is about 1ms
CLK Goes high for about 6 clock periods
8 bits of data are shifted with the clock (MSB first)
Each 8 bit number represet a voice stored in the chip
Some example speeches (I did not try all 256 locations, just a few).
Binery Hex Speech
10000101 85 Channel Mode
10000001 81 Tx Memory
10011001 99 Menu
01100000 60 0
01100001 61 1
01100010 62 2
01100011 63 3
00100000 20 Chinese ???
00100001 21 Chinese ???
00100011 22 Chinese ???
Here is a video of the MSO19 sending data into the voice chip (I removed the dummy load, since my TX is completely off).
Interfacing with the RDA5802I was also able to interface with the RDA5802 chip (the FM radio receiver).
The interface is I2C, and I was able to hook up an Arduino directly. Even though the chip is 3.3, you can hook it up with two 4.7K resistors tied to the 3.3 per I2CBi-directionalLevelShifter
However, the RDA5802 datasheet does not seem to have the registers that the radio is setting. I was able to capture the basic data that the uv5r is sending and play them back.
Here is the protocol (number are in hexadicimal).
When the radio boots up it sends: i2Start 0x10 w 0xD2 0x00 STOP i2cStart 0x10 w 0xD2 0x00 0x3D 0xD8 STOP
When the radio switches to radio FM mode is sends: i2Start 0x10 w 0x90 0x3 0x00 0x18 STOP i2cStart 0x10 w 0xD0 0x01 0x2A 0x18 STOP
Changing the channel the radio sends: i2cStart 0x10 w 0xD0 0x01 0x27 0x98 stop //for 91.8FM
So the channels seem to be
91.7FM is 0x2758
91.8FM is 0x2798
91.9FM is 0x27D8
However, when I tuned to some channel (I dont remember which freq it was) 0x28D4 a station comes in clear, when the freq is set to 0x28D5 all you hear is static, and the same for 0x28D6 and 0x28D7. However, when the freq is set to 0x28D8 the same station comes in clear. Stepping through the numbers the same channel will come in clear but the distance between the numbers grows larger and other channels are coming in between these numbers. So it looks like the stations are interleaved with one another. Any ideas why this is so? I think it might be harmonics.
I placed a youtube video showing the results.
Here is the arduino code I was using to step though the channels
Interfacing with the RDA1846I was able to captured some data for how the radio is setup when its first powers up. Here is the sequence that the radio is sending the RDA1846 at power on.
The first bit is for read/!write then address and lastly data
0 0110000(0x30) 0000000000000001 soft_reset
0 0110000(0x30) 0000000000000100 pdn_reg same as pdn
0 0000100(0x04) 0000111111010000 clk_mode 24~28MHZ
0 0001011(0x0B) 0001101000010000 Not in Manual
0 0101011(0x2B) 0011001011001000 xtal_freq (13000/1000)*2=26MHz
0 0101100(0x2C) 0001100101100100 Adc clk freq: (6500/1000)*4=26MHz
0 0110001(0x31) 0011111111000000 Not in Manual
0 0110010(0x32) 0110001001111110 Not in Manual
0 0110011(0x33) 0000101011110010 Not in Manual
0 1000111(0x47) 0011101111101100 Not in Manual
0 1001111(0x4F) 0001000001000000 Not in Manual
0 1001110(0x4E) 0010100100111010 Not in Manual
0 1010110(0x56) 0000011001010010 Not in Manual
0 1101110(0x6E) 0000011000101101 Not in Manual
0 1110000(0x70) 0001100000011011 Not in Manual
0 1110001(0x71) 0110110000011110 Not in Manual
0 1111111(0xFF) 0000000000000001 Not in Manual
0 0000101(0x05) 0000000000011111 Not in Manual
0 1111111(0xFF) 0000000000000000 Not in Manual
0 0111100(0x3C) 0000101001111000 Tx voice signal from MIC
0 0111101(0x3D) 0010000000001011 Not in Manual
0 0011111(0x1F) 0001000000000001 gpio6 sq out, gpio0 css out/in/cmp
0 0001010(0x0A) 0000001101000000 1.01V pabias voltage
0 0000010(0x02) 0000011010011000 Not in Manual
0 1010100(0x54) 0001110101000000 gpio6 is sq only
0 0101001 (0x29) 0000000000111000 Freq high value
0 0101010 (0x2A) 0111101111000100 Freq low value
1110000111101111000100 = 3701700 Dec
3701700/(8*1000) = 462.7125MHz
The radio was tuned to FRS ch 7
0 0001111 (0x0F) 0011110100100100 Band Select 400-520MHz
Finally I managed to interface with the RDA1846 over i2c (I changed the protocol from spi to i2c, since its simpler to interface with the arduino, and for the fact that I ripped up the PDN pad). For a while I was able to interface with the RDA1846, but I was only receiving static when the sq was open. It took me a while, but then I remembered that they are switching the RX signal on an off to save on battery, and since I have uv5r mcu disabled, it did not turn on the RX circuit. I tied pin PC1 (RX POW) to 3.3v and everything seemed to work. I tested the radio by tuning it to a FRS channel 7 and using one of my FRS radio, I sent DTMF codes. I know this is not completely legit, but I think I am not technically doing anything wrong (the FRS radio I bought at radio shack does not need a license, and I am only using the UV5r as a receiver. Please let me know if I am correct about this).
I also wrote an arduino code to configure registers via the serial terminal. It looks like the UV5R mcu monitors the sq pin and when it is on, it sends a RX on to the RDA1846. So for now I was basically just turning on the RX and turning it off. Here is a video of the radio receiving the DTMF tones on the FRS radio service.
Here is the configuration sequence I was using for the chip (the format is register value, register value, ....)
0x30 0x0004, 0x04 0x0FD0, 0x0B 0x1A10, 0x2B 0x32C8, 0x2C 0x1964, 0x31 0x3FC0, 0x32 0x627E, 0x33 0x0AF2, 0x47 0x3BEC, 0x4F 0x1040, 0x4E 0x293A, 0x56 0x0652, 0x6E 0x062D, 0x70 0x181B, 0x71 0x6C1E, 0xFF 0x0001, 0x05 0x001F, 0xFF 0x0000, 0x3C 0x0A78, 0x3D 0x200B, 0x1F 0x1001, 0x0A 0x0340, 0x02 0x0698, 0x54 0x1D40, 0x29 0x0038, 0x2A 0x7BC4, 0x0F 0x3D24
To turn on the TX
To turn off the TX
Here is the arduino code
To set the TX/RX circuitry, here is what is needed: I did not actually TX anything, just measured the voltage on the TX power circuit.
There are 3 pins that need to be controlled: PC1 for RX power (3.3 to RX), P66
for TX power (0 to TX), and P56 for UHF/VHF mode (0 for UHF and 3.3 for VHF).
Here is a video of the radio receiving the NOAA channel
There is a bit of static, but that is what I get with a new radio as well. I can
also set it to the police dispatch on UHF and it works as well.
Removing the CPU
I took the plunge, removed the main MCU and just soldered wires to the pads (I did not have a rework station, so I used my soldering iron. I just ordered a rework station from sparkfun). Everything seems to work ok and I am able to fully configure the RDA chip and set auto sq, freq, etc.
Here is what I am doing with the pins.
PC1 -> RX power, I am feeding 3.3V for this.
P56 -> U/V mode. I set it to 0 for VHF and 3.3V for UHF
P66 -> TX power. I am setting this to 3.3v since 0 is to activate
Here is the protocol message that I gathered which seems to work well (the first
arg is register the next one is value and then description)
0x30 0x0001 Reset all registers to default values
0x30 0x0004 same as pdn (dont sleep)
0x04 0x0FD0 24-28Mhz
0x09 0x032C high voltage of GPIO is 2.7V, 0x03AC high votlage of GPIO is more
then 3.0V, based on power voltage
0X2B 0x32C8 26Mhz xtal
0x2C 0x1964 adc clk for 26Mhz xtal
0x47 0x1AEA for 12.5KHz or 0x2C2F for 25kHz
0x54 0x1D40 for 12.5KHz or 0x1D4C for 25kHz
0x6E 0x062D for 25kHz no register for 12.5KHz
0x71 0x6C1E for 12.5Khz or 0x70 0x1029 for 25Khz
0x85 0x001F RFpower is 8dBm, ACP is -63dB in 12.5KHz and -65dB in 25KHz
0x0018 RFpower is 6dBm, ACP is -64dB in 12.5Khz and -66dB in 26KHz
0x0017 RFpower is -3dBM, ACP is -68dBc in 12.5KHz and -68dBc in 25KHz
0x30 0x0006 for 12.5KHz or 0x3006 for 25Khz
Delay a minimum of 100ms
0x30 0x0006 for 12.5KHz or 0x3006 for 25Khz
0x30 0x0026 for 12.5KHz or 0x3026 for 25Khz
To RX with auto Sq
0x48 and 0x49 setting Sq open and shut threshold
0x30 0x0006 for 12.5KHz or 0x3006 for 25Khz
0x30 0x002E for 12.5KHz or 0x302E for 25Khz
To RX with mute
0x30 0x0006 for 12.5KHz or 0x3006 for 25Khz
0x30 0x00A6 for 12.5KHz or 0x30A6 for 25Khz
I finally got my license a few weeks ago (KK6BWA) and after messing around a bit with just talking to people, I finally got back to the radio and tried to transmit. I also, tried to read some of the read only registers on the radio, which indicate RX level strength, DTMF decoded tones, etc.
The first thing I noticed was that I was able to tell the RDA1846 to send a sin wave of a given frequency. In fact, you can choose whether you want to send one sin wave or two at the same time (for DTMF). It also looks like you can change the sin wave relatively quickly while transmitting, so I can even send 1200 Baud FSK signals. I wrote a simple morse code function to send my call sign (KK6BWA) though the radio for testing.
Here is a video of the radio sending the morse code over 145.525MHz.
Since the chip itself can be configured to send data over the 220MHz band. I tried that as well. However, I only have another UV5R, so I have nothing to receive the signal on. Thankfully, Steve (WB8GRS) suggested to use harmonics and tune the other UV5R to the first harmonic. I configured the hacked radio to TX on 223.5MHz and the other UV5R to receive over (223.5*2) 447MHz. Since the RDA1846 has a special register that needs to be set to put it into the 220MHz band, I tried TXing with the register set to the other bands while on 220MHz. Unfortunately, by only setting the register to the 220MHz band, I was able to receive the signal, confirming the the stock UV5R will not be able to TX/RX on that band without setting this register. To my surprise I was able to receive the harmonics about 400 feet away before the signal started degrading.
Here is a video of the radio TXing on 223.5MHz and receiving over 447MHz.
The RDA1846 is also able to set the TX deviation, so I tried messing around with that register to see if I can get a better transmission over the harmonics. Here is the same test as above, but each time I set the deviation param to a different number:
Lastly, I tried to read the internal registers on the radio, which indicate the signal level strength, Voice signal strength, DTMF decoded output and some flags. Anyone knows why would the signal level strength change when different frequencies (DTMF) was going over the air? The signal level strength does seem to be working, since I was getting different values when I was tuning the radio to other far away stations.
Next step would be to design a PCB that I can place an atmega or an arm chip in the radio.
Here is the final code used for testing. It allows you to set registers by "Saa uu ll " where aa is the register address, uu is the upper byte to set and ll is the lower byte to set. "Raa" to read a register at address aa. "V" to display register values like signal strength, DTMF, etc. "T" to transmit my call sign in morse.
Using the arduino serial monitor its simple to just copy and paste settings. For example, to initialize the chip, copy the following into the arduino serial monitor (insure you are at 38400 baud rate).
Then to receive the NOAA channel on 162.550MHz send the following sequence
Here is the arduino code