My current project (to be shared soon when finished) is a PLL FM transmitter based on the RDVV NoTune design.
The transmitter uses a Philips TSA5511 I2C-bus controlled synthesizer. The synth is used to set the frequency in combination with the VCO.
Normally these circuits have a PIC integrated (e.g. pic16f628a) to interface with the tsa5511 over I2C and to provide input and outputs for selecting frequency and reading PLL lock state…
A PIC is way to oldschool for me, this thing must have a Photon included!
My challenge is to get the I2C interface working. I am not able to read the table describing what can be written and what can be read. The testing I did with interfacing over I2C with the tsa5511 resulted in gibberish.
My goals;
read the “In-Lock” bit (page 8 of the datasheet)
write the frequency (page 7 of the datasheet)
Any help is more than welcome!
Thanks!
INO code as inspiration: INO
tsa5511 datasheet: PDF
PS. I am not an FM design guru
Using the common I2C scanning script;
Scanning...
I2C device found at address 0x60 !
I2C device found at address 0x61 !
done
Reading i2c on address 0x60;
void loop() {
Wire.requestFrom(0x60, 4); // request 4 bytes from slave device #8
while (Wire.available()) { // slave may send less than requested
char c = Wire.read(); // receive a byte as character
Serial.print(c); // print the character
//Serial.print(Wire.read());
}
Serial.println("#");
delay(1000);
}
But since I prefer the more compact HEX representation of bytes anyway, you could also do this
Wire.requestFrom(0x60, 4);
while (Wire.available() < 4); // wait for all data to arrive
for (int i=0; i<4; i++) {
Serial.printf("%02x ", Wire.read());
}
Serial.println("#");
So there are only 8 byte to read? Or am I misreading the table here?
The goal is the be able to read the FL flag bit.
Code used:
Wire.requestFrom(0x60, 2);
while (Wire.available() < 2); // wait for all data to arrive
for (int i=0; i<4; i++) {
Serial.printf("%02x ", Wire.read());
}
Output:
Opening serial monitor for com port: "COM4"
10 10 10 10 #
For programming, there is one module address (7 bits) and the R/W bit for selecting READ or WRITE mode.
READ mode : R/W = 1
WRITE mode : R/W = 0
Based on the “Table 2” image above the device address = 1100010 or in HEX 0x62 Which is a 7 bit address missing the last R/W bit. The R/W low bit is added by the Wire library based on the Read or Write action in the library.
There is only 1 full byte to read.
The code for reading the status should then be:
Wire.requestFrom(0x62, 1);
while (Wire.available() < 1); // wait for all data to arrive
for (int i=0; i<1; i++) {
Serial.printf("%02x ", Wire.read());
}
Serial.println("#");
Where I struggle is to “address” the part I want to receive, which is FL status, the second position in the table.
Thanks @ScruffR, I think this seems to get working, thanks for the support so far!
Moving further to the writing part of the TSA5511.
The crystal used as a reference for the TSA5511 is a 3.2Mhz crystal. The manual describes it like this: The 7.8125 kHz reference frequency is obtained by dividing the output of the 4 MHz crystal oscillator by 512. Because the input of UHF/VHF signal is first divided by 8 the step size is 62.5 kHz. A 3.2 MHz crystal can offer step sizes of 50 kHz.
I am using a 3.2Mhz crystal, so it is correct because 3200000Hz / 512 = 6250Hz
What I know now is:
3200000Hz is the crystal
6250Hz is the reference frequency obtained by dividing the crystal with 512
92000000Hz is the desired FM frequency (92.00Mhz)
The input RF must be divide by 8 (92000000/8=11500000)
to be send to TSA5511: 11500000 / 6259 = 1840
The TSA5511 can also be partially programmed on the condition that the first data byte following the address is byte 2 or byte 4. The meaning of the bits in the data bytes is given in Table 1. The first bit of the first data byte transmitted indicates whether frequency data (first bit = 0) or charge pump and port information (first bit = 1) will follow. Until an I2C-bus STOP condition is sent by the controller, additional data bytes can be entered without the need to re-address the device. This allows a smooth frequency sweep for fine tuning or AFC purposes. At power-on the ports are set to the high impedance state.
The code you use does set the bytes correct already.
If you have a number in the range of 0~32767 (0b0000 0000 0000 0000 ~ 0b0111 1111 1111 1111) bit 15 will always be 0 already.
That's only required if you want to do a full setup, but you could also only send 3 bytes where the 2nd byte tells the device how to treat the next byte and if you end the transmission after the 3rd byte the device will still be happy with that.
Wire.beginTransmission(0x61);
Wire.write(data, 5); // if the device actually needs the address sent again (which I doubt)
// I'd rather think data[0] is exactly the same as your 0x61 << 1
Wire.endTransmission();
but as said in the comment, I'd rather think it should be this
Wire.beginTransmission(data[0] >> 1);
Wire.write(&data[1], 4); // only send the data bytes, since the address was already sent above
Wire.endTransmission();
BTW:
An integer division by a power of 2 is the same as a right shift (>>) by the power.
char data[5];
long Xtal = 3200000; // 3.2Mhz crystal
long fRef = Xtal >> 9; // x / 512 Reference devider = 6250Mhz
long fDiv = freq >> 3; // x / 8 RF input devider = 11500000
long div = fDiv / fRef; // 11500000 / 6250 = 1840
@bartjenniskens suggest that you get a logic analyser like this https://www.saleae.com/ that can analyse the I2C bus traffic. It is really handy for hardware debug.
Write frequency 92.00Mhz to TSA5511 with help of the formula. The two bytes are 0x70 and 0x30 when I run it through the formula and the image below proofs that it is correct:
Write frequency 92.05Mhz to TSA5511 with help of the formula. The two bytes are 0x07 and 0x31
Set charge pump and ports (called after frequency set/change):
The 2e byte, 0x20 = 0010 0000, in the image below sets the P5 port. When set to 1 the open-collector output is active. On my multimeter the voltage drops when set to 1, it turns on a LED on the board that indicates a “in-lock” state.
Now I have enough to fiddle with the code and to get it fully working. When the code is ready I will share it!
I was struggling with the same classic PLL last month.
I have working code for Arduino but I suppose it will work for you as well.
The program isn’t using “wire” but something custom make.
I was wondering…did you make it work?
Yes I did, it all works fine! Currently working on a custom PCB to control the FM board.
You could just use the Wire library for all i2c communications, no need for custom coding there.
ok, very good. Last weekend I made “Wire” working as well. Keep us informed when your PCB is finished. It’s always interresting to see how other people do similar jobs. My goal is to build some kind of universal PLL for RX/TX in UHF ham radio.
Dear bartjenniskens hello,
I was reading your article and found similar to a problem I want to solve, are you available to discuss that with me?
Thanks in advance
I remain
Dimis
Hi Bartjen and thanks for your prompt reply.
I was wondering if you can provide me with some help on a problem i face the last few months.
In brief, i have purchase as a kit and assemble an FM PLL transmitter the link is below.
That was working fine were suddenly one day didn’t lock to frequency, by a short troubleshooting i find out that the led shows lock comes on when i touch the line that connects RA0/AN0 from PIC16F628 to SCL at TSA5511.
Although the led shows lock there is no RF at any stage.
That after reading make me think that possibly the problem is with PIC17F628, to my attempt to contact with the seller there is no reply to order a new programmed so the new project ahead is how i can prepare a new PIC in order to perform the same functions as i believe that is the problem.
I am also attach the schematic diagram to you, furthermore i have download MPLAB IDE v 8.91, PICPgm programmer trying to be trained on how to do it if i find out an already prepared code, or to write the code,i was also ready to purchase a PIC KIT 3 but then i find your article and i thought would be better to ask from someone has done that successfully on the past.
Could you please advice me what to do?
Thanks in advance
Dimi Parts kit DRFS06 V2.1 FM transmitter 6 Watt
The PLL Lock LED that is turned on by the PIC is just a response to a read-out from the PIC on the I2C line between the PIC and the TSA5511. Most ideal would be if your can listen to the communication between the PIC and the TSA5511 by using a logic analyzer.
Once the TSA5511 has got a PLL Lock, there is a variable in the TSA5511 that goes from 0 to 1. The PIC runs a loop by reading this variable from the TSA5511 until it goes to 1, than the PIC turns on the LED. This loop normally starts after every frequency change and after first boot when the frequency is written to the TSA5511 by the PIC.
Also, the PIC should set the charge pump to get a PLL Lock quicker. Also this is a variable that needs to be set by the PIC after writing the frequency.
In the TSA5511 documentation you can find the binary codes for setting and reading the variables (flags).