etherkit / Si5351Arduino

Library for the Si5351 clock generator IC in the Arduino environment
GNU General Public License v3.0
229 stars 94 forks source link

detect if Si5351 is present at specified address #56

Closed ppisljar closed 6 years ago

ppisljar commented 6 years ago

Currently it seems library does not check if its actually talking to si5351 and would not show any error if you are talking to an invalid address. It would be nice if init function would actually check if si5351 is present at that address by reading some register by which it could identify it ?

i am using 10MSSOP si5351A (3 clock outputs) and i try to set the frequency of first clock output to 24MHz. after calling update_status SYS_INIT is 0, and both LOLs are 1 ... also REVID is 1 (which is suspicious as it should be 3 right ? ... chips were bought on digikey a week ago)

if i change the address to something random all the values above are 0

my full code:

    ESP_ERROR_CHECK( nvs_flash_init() );
    ESP_LOGI("main", "starting main app ...");
    vTaskDelay(1000 / portTICK_PERIOD_MS);

    ESP_LOGI("main", "starting I2C ...");
    Wire.begin(25,26);

    ESP_LOGI("main", "configuring si5351 ...");
    si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0);
    si5351.set_freq(2400000000ULL, SI5351_CLK0);
    si5351.set_freq(2457600000ULL, SI5351_CLK1);
    si5351.output_enable(SI5351_CLK0, 1);
    si5351.output_enable(SI5351_CLK1, 1);
    ESP_LOGI("main", "si5351 configuration complete ...");

    while(true) {
        si5351.update_status();
        vTaskDelay(5000 / portTICK_PERIOD_MS);
        ESP_LOGI("main", "SYS_INIT: %d", si5351.dev_status.SYS_INIT);
        ESP_LOGI("main", "  LOL_A: %d", si5351.dev_status.LOL_A);
        ESP_LOGI("main", "  LOL_B: %d", si5351.dev_status.LOL_B);
        ESP_LOGI("main", "  LOS: %d", si5351.dev_status.LOS);
        ESP_LOGI("main", "  REVID: %d", si5351.dev_status.REVID);
    }
ppisljar commented 6 years ago

so now i am really guessing that communication is not working as expected ... if i try to update_status before configuring si5351 it retuns all 0 (for REVID as well) ... after configuring it changes:

I (1236) main: starting I2C ...
I (7236) main: SYS_INIT: 0
I (7236) main:   LOL_A: 0
I (7236) main:   LOL_B: 0
I (7236) main:   LOS: 0
I (7236) main:   REVID: 0
I (7236) main: configuring si5351 ...
I (7246) main: si5351 configuration complete ...
I (12246) main: SYS_INIT: 0
I (12246) main:   LOL_A: 1
I (12246) main:   LOL_B: 1
I (12246) main:   LOS: 1
I (12246) main:   REVID: 1

i am guessing REVID should never change ?

NT7S commented 6 years ago

I've noticed some issues in the status register reporting as well, and I agree with your assessment of how the class should give some way of indicating that the IC isn't present on the address. I'll mull over how to handle this in the next update. Thank you for the feedback.

NT7S commented 6 years ago

@ppisljar I've added a bool return value to the init() method that returns true if a device is found on the bus (for now it just looks to see if something is there, not a specific check for an Si5351). Please install the v2.1.1 branch manually and see if that will meet your needs: https://github.com/etherkit/Si5351Arduino/tree/v2.1.1

I'm not sure of a good way of detecting specifically that a Si5351 is present on the bus at the specified address. The device doesn't have a register which returns a unique device ID or anything like that.

Also, regarding the status registers, I've done a bit of work investigating them, and from the best that I can determine, you have to do an initial read of the registers, then wait a bit (something on the order of 100 ms), and then you'll get the correct register values. Please see this in the example sketch. Try that out as well in your code and let me know if you get the desired behavior.

ppisljar commented 6 years ago

thank you, seems to work fine (init) i would suggest to read a register with known value (are reserved registers readable and do they have a constant value? ) or read register, write to register, read its value, reset to default value.

none of the above will be able to 100% identify Si5351, but should work better than just 'is present' test

in regards with my REVID register .... its still returning 1 ... and LOL and LOS are 1 now even before i start configuring the chip. (waiting for the registers to update seems to have done the trick)

seems something is wrong with my xtal ( i am using this one: https://www.digikey.si/products/en?keywords=535-13945-1-ND ). is there something i could check that you are aware of ?

thanks

la3pna commented 6 years ago

What microcontroller are you using? This may partly be a compiler issue.

2018-01-05 16:29 GMT+01:00 Peter Pisljar notifications@github.com:

thank you, seems to work fine (init) i would suggest to read a register with known value (are reserved registers readable and do they have a constant value? ) or read register, write to register, read its value, reset to default value.

none of the above will be able to 100% identify Si5351, but should work better than just 'is present' test

in regards with my REVID register .... its still returning 1 ... and LOL and LOS are 1 now even before i start configuring the chip. (waiting for the registers to update seems to have done the trick)

seems something is wrong with my xtal ( i am using this one: https://www.digikey.si/products/en?keywords=535-13945-1-ND ). is there something i could check that you are aware of ?

thanks

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/etherkit/Si5351Arduino/issues/56#issuecomment-355582439, or mute the thread https://github.com/notifications/unsubscribe-auth/AEOGvFHjOg_zasRAw2oMWCwjfMh_aYVZks5tHj_wgaJpZM4RNs2E .

-- With Best regards, Thomas S. Knutsen.

Please avoid sending me Word or PowerPoint attachments.

NT7S commented 6 years ago

I don't see anything obviously wrong with the xtal by looking at the specs. Can you probe the XA line to see if it is actually oscillating or not? It kind of sounds like just something electrically not working right. If it is oscillating, then perhaps @la3pna is correct.

ppisljar commented 6 years ago

i am using ESP32 microcontroller, seems XTAL is not oscillating, will try to replace it later this week.

NT7S commented 6 years ago

I think that there will be complaints about a choice of register to use to "validate" the presence of a proper SI5351, so I'd rather leave that up to the end user to implement if they really feel like they need that extra bit of assurance. I believe that a check that there's something on the bus at the desired address should do the trick in most cases, and if one wants to check some arbitrary registers to try to make the confirmation a bit more solid, it's done easily enough with a raw read command.

I've never tried using this library with the ESP32, so I'm curious to hear how it goes for you @ppisljar. I'm going to tentatively consider this issue resolved, but I won't close it until I hear back from you or a reasonable amount of time elapses. Please let us know what you find, thanks.

ppisljar commented 6 years ago

just to report back, yesterday i've played some more and got it to work. crystal was the problem, seems it was burned. replacing the crystal now makes it work (with ESP32).

i still get the LOS set to 1 ... but i can measure the output frequencies and they seem to be correct:

I (12246) main: SYS_INIT: 0 I (12246) main: LOL_A: 0 I (12246) main: LOL_B: 0 I (12246) main: LOS: 1 I (12246) main: REVID: 1

so i can confirm, this library seems to work ok with ESP32

NT7S commented 6 years ago

Glad to hear, thanks for the update. That still is strange about the registers. If I get my hands on an ESP32, I'll dig into it further.

jszamos commented 6 years ago

I currently work on the Si5351 identification, and this is the result of a register dump from an uninitialized Si5351 (deleted rows with all 0's for brevity):

0:  0x11  0xf8  0x03  0x00  0x00  0xff  0x00  0x00  0x00  0x00

10: 0x00 0x00 0x00 0x00 0x90 0x00 0x00 0x00 0x00 0x80 20: 0x80 0x80 0x80 0x80 0x00 0x00 0x00 0x00 0x00 0x00

170: 0x00 0x00 0x00 0x00 0x00 0x00 0xff 0x0c 0x00 0x00 180: 0x00 0x30 0x1e 0xd2 0x60 0x60 0xb8 0x02 0x00 0x00

200: 0x00 0x00 0x00 0x00 0x00 0x45 0x54 0x00 0x00 0x00 210: 0x00 0x80 0x00 0x00 0x00 0x00 0x00 0x00 0x1c 0x00 220: 0x00 0x00 0x00 0x40 0x00 0x00 0x38 0x00 0x00 0x00

Alas, many of the unique values are in reserved registers (ie: 0x45 & 0x54 in 205 and 206), but registers 0 and 1 are documented, and 0x11 and 0xf8 in them might just be enough.