Thanks again, bartjenniskens
I will read again about the flags for sure as i have all the datasheet in pdf.
Correct me if i am wrong but i realise that you agree with this troubleshooting that the problem is within PIC and not the TSA5511?
Last question, if i manage to read the existing PIC memory can i come back to you for advice?
Thanks in advance for your help.
Brgds
Dimis
Indeed, I would be suspicious about the PIC than I would be about the TSA5511.
Sure, but assembly is not my strongest point.
Many thanks i will keep you posted
Brgds
Dimi
Hi again, here is my latest actions.
please be informed that programming is neither my strongest point, i have purchase PICkit 3 that i have connect and using the MPLAB software after few corrective attempts i manage to read the PIC16F628A. Within i am able to see all memory partitions like Program memory, Configuration bits, EE data memory, User ID memory and Device ID memory.
It seams all are there as i found my name that was entered during previous normal operation. After read I try a Verify action and it comes with the following message.
Readingā¦
The following memory area(s) will be read:
program memory: start address = 0x0, end address = 0x7ff
configuration memory
EEData memory
User Id Memory
Read complete
Verifyingā¦
The following memory areas(s) will be verified:
program memory: start address = 0x0, end address = 0x7ff
configuration memory
EEData memory
User Id Memory
Verification successful.
To my opinion it seams to be OK what do you believe?
I remain.
Dimis
Hi Dimis,
Iāve got a drfs06 exciter and it looks like the pic just died. Iāve got an empty pic laying around, but canāt find the firmware. Could you read out your pic and share the firmware?
I would really appreciate your help. Thank you!
Hi bartjenniskens,
Iāve got a pll fm transmitter in which the pic died. In case I canāt get the original firmware for the pic, could you share your .ino code so that I can build an alternative controller? I would really appreciate your help.
Thank you very much!
Off course, Iāll reply with the code to set the TSA5511
Hi bartjenniskens, I donāt want to look like Iām impatient, but are you still gonna share your code?
Hey @lavao; Apologies for the delayed response, here is the full code. This code includes a 16x2 LCD display and 3 buttons. On the LCD the frequency and PLL Lock of the TSA5511 is shown, the buttons are used to set the frequency.
// This #include statement was automatically added by the Particle IDE.
#include <clickButton.h>
// This #include statement was automatically added by the Particle IDE.
#include <LiquidCrystal_I2C_Spark.h>
// Display settings
LiquidCrystal_I2C *lcd;
// General definations
# define button_menu_up D2
# define button_menu_set D3
# define button_menu_down D4
const int button_menu_up_Pin2 = 2;
const int button_menu_set_Pin3 = 3;
const int button_menu_down_Pin4 = 4;
ClickButton menu_up(button_menu_up_Pin2, LOW, CLICKBTN_PULLUP);
ClickButton menu_set(button_menu_set_Pin3, LOW, CLICKBTN_PULLUP);
ClickButton menu_down(button_menu_down_Pin4, LOW, CLICKBTN_PULLUP);
int function_menu_up = 0; // Button results
int function_menu_set = 0; // Button results
int function_menu_down = 0; // Button results
// TSA5511 settings
# define tsa_addr_write 0x60 // normal 0xC0 but 0x60 because of 5 bits address (read wire lib why)
# define tsa_addr_read 0x60 // normal 0xC1 but 0x61 because of 5 bits address (read wire lib why)
bool readSensors = false; //Used in the loop to disable read-out when talking to the TSA5511
bool PLLWatchdog = false; //Action reading from I2C for LOCK flag at the TSA5511
uint32_t msLastMetric;
uint32_t msLastSample;
const uint32_t msSAMPLE_INTERVAL = 300; // 4 second interval
// EEPROM storage settings
int EEPROM_freq_addr = 10;
//Start freq when nothing is stored in the EEPROM
long freq = 87500000;
void setup() {
// Setup button
pinMode(button_menu_up, INPUT_PULLUP);
pinMode(button_menu_set, INPUT_PULLUP);
pinMode(button_menu_down, INPUT_PULLUP);
//Setup wire and serial
Wire.begin(); // join i2c bus (address optional for master)
Serial.begin(115200); // start serial for output
// Setup LCD
lcd = new LiquidCrystal_I2C(0x27, 16, 2);
lcd->init();
lcd->backlight();
lcd->clear();
display(0,0);
delay(1000);
// Initiate TSA5511
TSAinit();
}
void loop() {
//Read and actions on button clicks
menu_up.Update();
menu_set.Update();
menu_down.Update();
// Save click codes in LEDfunction, as click codes are reset at next Update()
if(menu_up.clicks != 0) function_menu_up = menu_up.clicks;
if(menu_set.clicks != 0) function_menu_set = menu_set.clicks;
if(menu_down.clicks != 0) function_menu_down = menu_down.clicks;
//UP - SINGLE click
if(function_menu_up == 1) {
menu2(1);
};
//DOWN - SINGLE click
if(function_menu_down == 1) {
menu2(2);
};
//SET - SINGLE click
if(function_menu_set == 1) {
menu2(0);
}
function_menu_up = 0;
function_menu_set = 0;
function_menu_down = 0;
//TSA5511 status loop
if (PLLWatchdog == true){
if (millis() - msLastSample >= msSAMPLE_INTERVAL){
bool PLLLock = readPLLLockOnly();
if (PLLLock == 1){
// 1: TSA5511 Output port CP LOW and rest low = 0xCE + 0x00
byte data[2];
data[0] = 0xCE;
data[1] = 0x24;
Wire.beginTransmission(tsa_addr_write);
Wire.write(data, 2);
Wire.endTransmission();
//Write frequency again.. or not
byte datafreq[2];
long Xtal = 3200000; //3.2Mhz crystal attached to TSA5511
long fRef = Xtal / 512; //Reference devider
long fDiv = freq / 8; // RF input devider
long divider = fDiv / fRef;
datafreq[0] = (divider & 0xFF00) >> 8;
datafreq[1] = divider & 0x00FF;
byte reg_addr = 0xCE;
//byte tsa_addr = 0x60; // normal 0xC0 but 0x60 because of 5 bits address
Wire.beginTransmission(tsa_addr_write);
Wire.write(datafreq, 2);
Wire.endTransmission();
PLLWatchdog = false;
}
}
}
}
void menu2(int menuMode){
switch(menuMode){
//MENU 1 - UP pushed
case 1:
freqSet(freq, 1);
//menuChange = 1;
break;
//MENU 1 - DOWN pushed
case 2:
freqSet(freq, 2);
//menuChange = 1;
break;
//MENU 1 - SET pushed
case 0:
freqSet(0,3);
//menuChange = 0;
break;
}
}
void TSAinit(){
Serial.println("## TSAinit ##");
//Get last stored frequency from EEPROM
uint16_t value;
EEPROM.get(EEPROM_freq_addr, value);
if(value == 0xFFFF) {
// EEPROM was empty -> initialize default freq value
freqStore(freq/100000);
Serial.print("No frequency stored, storing default: ");Serial.println(freq);
}
Serial.print("Initializing frequency is: ");Serial.println(value);
freq = value*100000;
// Initialise the TSA5511 chip
// 1: Set CP to HIGH and the rest to LOW
// 2: Write frequency
// 3: Start the PLL Watchdog
// 1: TSA5511 Output port CP HIGH and rest low = 0xCE + 0x00
byte data[2];
data[0] = 0xCE;
data[1] = 0x00;
Wire.beginTransmission(tsa_addr_write);
Wire.write(data, 2);
Wire.endTransmission();
// 2: Write frequency
byte datafreq[2];
long Xtal = 3200000; //3.2Mhz crystal attached to TSA5511
long fRef = Xtal / 512; //Reference devider
long fDiv = freq / 8; // RF input devider
long divider = fDiv / fRef;
datafreq[0] = (divider & 0xFF00) >> 8;
datafreq[1] = divider & 0x00FF;
Wire.beginTransmission(tsa_addr_write);
Wire.write(datafreq, 2);
Wire.endTransmission();
Serial.print("write address: "); Serial.println(tsa_addr_write,HEX);
Serial.print("data: "); Serial.print(data[0],HEX); Serial.print(" + "); Serial.println(data[1],HEX);
display(99,0);
delay(300);
PLLWatchdog = true;
readSensors = true;
}
void freqSet(long freqInput, int set){
switch(set){
//Counts frequency up or down by pressing buttons
case 0:
freq = freqInput;
freqWrite();
display(96,0);
break;
case 1:
freq = freqInput + 50000;
if (freq == 108050000){ freq = 87500000;}
display(97,freq);
display(98,0);
readSensors = false;
break;
case 2:
freq = freqInput - 50000;
if (freq == 87450000){ freq = 108000000;}
display(97,freq);
display(98,0);
readSensors = false;
break;
case 3:
freqWrite();
display(96,0);
delay(1000);
display(3,readPLLLock());
writeTSA5511P5down();
readSensors = true;
break;
}
}
void freqWrite(){
// 1: TSA5511 Output port CP HIGH and rest low = 0xCE + 0x00
byte data[2];
data[0] = 0xCE;
data[1] = 0x00;
Wire.beginTransmission(tsa_addr_write);
Wire.write(data, 2);
Wire.endTransmission();
// 2: Write frequency
byte datafreq[2];
long Xtal = 3200000; //3.2Mhz crystal attached to TSA5511
long fRef = Xtal / 512; //Reference devider
long fDiv = freq / 8; // RF input devider
long divider = fDiv / fRef;
datafreq[0] = (divider & 0xFF00) >> 8;
datafreq[1] = divider & 0x00FF;
Wire.beginTransmission(tsa_addr_write);
Wire.write(datafreq, 2);
Wire.endTransmission();
Serial.print("write address: "); Serial.println(tsa_addr_write,HEX);
Serial.print("data: "); Serial.print(data[0],HEX); Serial.print(" + "); Serial.println(data[1],HEX);
freqStore(freq/100000);
delay(100);
PLLWatchdog = true;
}
void chargePump(){
//Reset to 1100 1110
//Reset is used before writing frequency and waiting for lock
Serial.print("## chargepump ##");
byte data[2];
//TSA5511 Output port P5 high = 0xCE + 0x20
data[0] = 0xCE; //CP high
data[1] = 0x00; //P5 low
Wire.beginTransmission(tsa_addr_write);
Wire.write(data, 2);
Wire.endTransmission();
Serial.print("write address: "); Serial.println(tsa_addr_write,HEX);
Serial.print("data: "); Serial.print(data[0],HEX); Serial.print(" + "); Serial.println(data[1],HEX);
delay(100);
}
void writeTSA5511P5down(){
byte data[2];
//TSA5511 Output port P5 to low
data[0] = 0xCE; //CP high
data[1] = 0x00; //P5 low
Wire.beginTransmission(tsa_addr_write);
Wire.write(data, 2);
Wire.endTransmission();
}
void freqStore(uint16_t value){
//Store frequency to internal EEPROM
EEPROM.put(EEPROM_freq_addr, value);
}
int freqRead(){
uint16_t value;
EEPROM.get(EEPROM_freq_addr, value);
return value*100000;
}
int readPLLLock(){
int bitNumber = 6;
int readByte = 0;
int myBit = 0;
Wire.requestFrom(tsa_addr_read, 1); // request 1 byte from slave device
delayMicroseconds(6);
if (Wire.available()){ // wait for all data to arrive
readByte = Wire.read();
//Serial.printf("%02x ", readByte);
Serial.print(" ");
Serial.print(readByte, HEX);
Serial.print("-");
myBit = (readByte >> bitNumber) & 0x01;
Serial.println(myBit);
if (myBit == 1){
//Af ther LOCK
// - CP must be 1, T1 and T0, must be 0, OS must be 1 (HEX 0xCE)
// - P5 must be high and turns on the LOCK LED on the PCB (Pin 8 on the TSA5511) and P2 must get high (Pin 11 on TSA5511) (HEX 0x24)
byte data[2];
data[0] = 0xCE;
data[1] = 0x24;
Wire.beginTransmission(tsa_addr_write);
Wire.write(data, 2);
Wire.endTransmission();
//Write frequency again.. or not
byte datafreq[2];
long Xtal = 3200000; //3.2Mhz crystal attached to the TSA5511
long fRef = Xtal / 512; //Reference devider
long fDiv = freq / 8; // RF input devider
long divider = fDiv / fRef;
datafreq[0] = (divider & 0xFF00) >> 8;
datafreq[1] = divider & 0x00FF;
byte reg_addr = 0xCE;
//byte tsa_addr = 0x60; // normal 0xC0 but 0x60 because of 5 bits address
Wire.beginTransmission(tsa_addr_write);
Wire.write(datafreq, 2);
Wire.endTransmission();
} else {
chargePump();
}
} else {
//nothing
}
return myBit;
}
int readPLLLockOnly(){
int bitNumber = 6;
int readByte = 0;
int myBit = 0;
Wire.requestFrom(tsa_addr_read, 1); // request 1 byte from slave device
delayMicroseconds(6);
if (Wire.available()){ // wait for all data to arrive
readByte = Wire.read();
myBit = (readByte >> bitNumber) & 0x01;
display(3,myBit);
}
return myBit;
}
void display(int mode, int data) {
switch(mode){
//Startup TSA5511
case 1:
lcd->clear();
lcd->setCursor(0,0);
lcd->print("Initializing TSA5511");
break;
//frequency change
case 2:
freq = data;
freqStore(freq/100000);
//Display frequency
lcd->setCursor(0,1);
float displFreq;
displFreq = (float)freq / 1000000.00;
lcd->print(displFreq);
if (displFreq > 99.95){ lcd->setCursor(6,1); } else { lcd->setCursor(5,1); }
lcd->print("Mhz");
break;
//PLL lock
case 3:
lcd->setCursor(0,1);
lcd->print("PLL:");
lcd->setCursor(4,1);;
if (data == 1){
lcd->print("yes");
} else {
lcd->print("no ");
}
break;
case 4:
lcd->setCursor(14,1);
lcd->print(data);
break;
//Menu 1 - frequence set
case 11:
lcd->clear();
lcd->setCursor(6,0);
lcd->print("PARTICLE-FM");
lcd->setCursor(0,1);
lcd->print("Menu: 1 - set freq");
lcd->setCursor(0,1);
displFreq = (float)freq / 1000000.00;
lcd->print(displFreq);
if (displFreq > 99.95){ lcd->setCursor(6,1); } else { lcd->setCursor(5,1); }
lcd->print("Mhz ");
break;
//Menu 2 - Menu set
case 12:
lcd->clear();
lcd->setCursor(6,0);
lcd->print("PARTICLE-FM");
lcd->setCursor(0,1);
lcd->print("Menu: 2 - set");
break;
//removing changed note
case 96:
display(99,0);
break;
case 97:
lcd->clear();
//Line 1
lcd->setCursor(0,0);
lcd->print("Setting freq..");
//Line 2
//Display frequency
lcd->setCursor(0,1);
lcd->print("Freq: ");
lcd->setCursor(6,1);
displFreq = (float)freq / 1000000.00;
lcd->print(displFreq);
if (displFreq > 99.95){ lcd->setCursor(12,1); } else { lcd->setCursor(11,1); }
lcd->print("Mhz");
break;
//setting changed note
case 98:
lcd->setCursor(15,0);
lcd->print("*");
break;
//Home screen
case 99:
lcd->clear();
//Line 1
//Display frequency
lcd->setCursor(0,0);
lcd->print("Freq: ");
lcd->setCursor(6,0);
displFreq = (float)freq / 1000000.00;
lcd->print(displFreq);
if (displFreq > 99.95){ lcd->setCursor(12,0); } else { lcd->setCursor(11,0); }
lcd->print("Mhz");
//Line 2
lcd->setCursor(0,1);
lcd->print("PLL:");
lcd->setCursor(5,1);
lcd->print(readPLLLock());
break;
case 0:
//default (sets display after boot)
lcd->setCursor(0,0);
lcd->print("Starting...");
lcd->setCursor(3,1);
lcd->print("PARTICLE-FM");
break;
}
}```
hello with what program is compiled, is it for arduino?
No, it is for Particle products using their toolchains.