TGB1718 Posted February 4 Share Posted February 4 8 minutes ago, Chri O. said: Question how accurate this PAL 3.546894MHz clock must be ? The clue is in the specification otherwise it would say something like 3.54MHz Quote Link to comment Share on other sites More sharing options...
Chri O. Posted February 4 Share Posted February 4 (edited) OK I'm trying to set the clock dividers on SAI1 Teensy 4.x MCU. This is what I'm getting right now 3.548679245283019... Edited February 4 by Chri O. Quote Link to comment Share on other sites More sharing options...
Chri O. Posted February 4 Share Posted February 4 How about this 3.54679802955665MHz 🙂 Quote Link to comment Share on other sites More sharing options...
Chri O. Posted February 4 Share Posted February 4 Here I can generate two different clocks on SAI1 & SAI2. SAI1 = 14.18757600719188 Mhz SAI2 = 3.546894001797969 Mhz (changing divider on SAI2) Unfortunately accessing SAI2 pin looks bit tricky on Teensy 4. Quote Link to comment Share on other sites More sharing options...
Overange Posted February 4 Author Share Posted February 4 21 minutes ago, Chri O. said: Here I can generate two different clocks on SAI1 & SAI2. SAI1 = 14.18757600719188 Mhz SAI2 = 3.546894001797969 Mhz (changing divider on SAI2) Unfortunately accessing SAI2 pin looks bit tricky on Teensy 4. Are you try to recreate the clock signals using the teensy or does it do more? This could be another alternative option- https://thepihut.com/products/adafruit-si5351a-clock-generator-with-stemma-qt-8khz-to-160mhz?variant=42293934981315 Quote Link to comment Share on other sites More sharing options...
Chri O. Posted February 4 Share Posted February 4 Good question I was thinking about using this Ted Fried's MicroCore Labs Project: MCL65+ Drop-in 6502 Emulator and Accelerator Github: https://github.com/MicroCoreLabs/Projects Quote Link to comment Share on other sites More sharing options...
dmsc Posted February 5 Share Posted February 5 Hi! 4 hours ago, Chri O. said: How about this 3.54679802955665MHz 🙂 A typical quartz oscillator has +/- 100ppm of precision, so you are good enough. Have Fun! Quote Link to comment Share on other sites More sharing options...
macsonny Posted February 5 Share Posted February 5 3 hours ago, Chri O. said: Here I can generate two different clocks on SAI1 & SAI2. SAI1 = 14.18757600719188 Mhz SAI2 = 3.546894001797969 Mhz (changing divider on SAI2) Unfortunately accessing SAI2 pin looks bit tricky on Teensy 4. Is there code you need to install on the Teensy? Quote Link to comment Share on other sites More sharing options...
macsonny Posted February 5 Share Posted February 5 3 hours ago, Overange said: Are you try to recreate the clock signals using the teensy or does it do more? This could be another alternative option- https://thepihut.com/products/adafruit-si5351a-clock-generator-with-stemma-qt-8khz-to-160mhz?variant=42293934981315 That's actually really cool and a 1/2 decent price too. A bit more expensive than a clock crystal, but far easier to find! Do you know how you can set the clock frequency output from the adafruit and how accurate it is? 1 Quote Link to comment Share on other sites More sharing options...
Chri O. Posted February 5 Share Posted February 5 3 hours ago, macsonny said: Is there code you need to install on the Teensy? Yes remains to be written I do however have a example which I borrow from my other project: (example only) CCM_ANALOG_PLL_VIDEO = CCM_ANALOG_PLL_VIDEO_BYPASS | CCM_ANALOG_PLL_VIDEO_ENABLE | CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(2) // 2: 1/4; 1: 1/2; 0: 1/1 | CCM_ANALOG_PLL_VIDEO_DIV_SELECT(c0); CCM_ANALOG_PLL_VIDEO_NUM = c1 & CCM_ANALOG_PLL_VIDEO_NUM_MASK; CCM_ANALOG_PLL_VIDEO_DENOM = c2 & CCM_ANALOG_PLL_VIDEO_DENOM_MASK; CCM_ANALOG_PLL_VIDEO &= ~CCM_ANALOG_PLL_VIDEO_POWERDOWN;//Switch on PLL while (!(CCM_ANALOG_PLL_VIDEO & CCM_ANALOG_PLL_VIDEO_LOCK)) {}; // Wait for pll-lock // -- PLL5 b10, Dec2, -- divide by 1 // -- PLL5 b01, Dec1, -- divide by 2 CCM_ANALOG_MISC2 = CCM_ANALOG_MISC2_VIDEO_DIV(1); // divide by 2 CCM_ANALOG_PLL_VIDEO &= ~CCM_ANALOG_PLL_VIDEO_BYPASS;// Disable Bypass Quote Link to comment Share on other sites More sharing options...
Overange Posted February 5 Author Share Posted February 5 5 hours ago, macsonny said: That's actually really cool and a 1/2 decent price too. A bit more expensive than a clock crystal, but far easier to find! Do you know how you can set the clock frequency output from the adafruit and how accurate it is? I have one here, as I was looking at using it on my 800XLi motherboard, but have not had chance to try or test it yet, it does look very easy to get going, you just need an Arduino Uno to program it.. As it has three outputs, the idea I had was to have it have 2 setups one for XLs and one for XEs along with the three outputs, 1 - NTSC Frequency 2 - PAL Frequency 3 - Colour Burst Frequency However, colour burst would be a little more complicated as it would need a redesign of the Colour burst circuit, unless this device could add the sub carrier wave internally via its programming?? here is a page explaining it. https://learn.adafruit.com/adafruit-si5351-clock-generator-breakout/wiring-and-test I am sure our Arduino Experienced guys would love to get their fingers in to this pie 2 Quote Link to comment Share on other sites More sharing options...
Simius Posted February 5 Share Posted February 5 12 hours ago, Chri O. said: Here I can generate two different clocks on SAI1 & SAI2. SAI1 = 14.18757600719188 Mhz SAI2 = 3.546894001797969 Mhz (changing divider on SAI2) There is no point in showing more than 6 digits. The best crystals have a stability of +/-5ppm. It means when you write 14.187576 then in fact the last 2 digit have nothing to do with reality. Quote Link to comment Share on other sites More sharing options...
Chri O. Posted February 5 Share Posted February 5 I see so I guess we can't copy and paste stuff anymore 🙂 Quote Link to comment Share on other sites More sharing options...
macsonny Posted February 10 Share Posted February 10 Hi All, I've been trying to follow the instructions here https://learn.adafruit.com/adafruit-si5351-clock-generator-breakout/wiring-and-test to create a PAL freq of 14.187576MHz. I've used the tool to generate the paramtters but still can't work out what need to be done to these lines of code for my UNO: /* INTEGER ONLY MODE --> most accurate output */ /* Setup PLLA to integer only mode @ 900MHz (must be 600..900MHz) */ /* Set Multisynth 0 to 112.5MHz using integer only mode (div by 4/6/8) */ /* 25MHz * 36 = 900 MHz, then 900 MHz / 8 = 112.5 MHz */ Serial.println("Set PLLA to 900MHz"); clockgen.setupPLLInt(SI5351_PLL_A, 36); Serial.println("Set Output #0 to 112.5MHz"); clockgen.setupMultisynthInt(0, SI5351_PLL_A, SI5351_MULTISYNTH_DIV_8); Can anyone please tell me what the above code needs to look like for the PAL freq output specified at the top of my post? Thanks macsonny 1 Quote Link to comment Share on other sites More sharing options...
macsonny Posted February 10 Share Posted February 10 (edited) Does this look right? #include <Adafruit_SI5351.h> Adafruit_SI5351 clockgen = Adafruit_SI5351(); /**************************************************************************/ /* Arduino setup function (automatically called at startup) */ /**************************************************************************/ void setup(void) { Serial.begin(9600); Serial.println("Si5351 Clockgen Test"); Serial.println(""); /* Initialise the sensor */ if (clockgen.begin() != ERROR_NONE) { /* There was a problem detecting the IC ... check your connections */ Serial.print("Ooops, no Si5351 detected ... Check your wiring or I2C ADDR!"); while(1); } Serial.println("OK!"); /* INTEGER ONLY MODE --> most accurate output */ Serial.println("Set PLLA to 709.3788MHz"); clockgen.setupPLL(SI5351_PLL_A, 28,23447,62500); Serial.println("Set Output #0 to 14.187576Hz"); clockgen.setupMultisynth(0, SI5351_PLL_A, 50,0,1); /* Enable the clocks */ clockgen.enableOutputs(true); } /**************************************************************************/ /* Arduino loop function, called once 'setup' is complete (your own code should go here) */ /**************************************************************************/ void loop(void) { } Edited February 10 by macsonny 1 Quote Link to comment Share on other sites More sharing options...
Overange Posted February 10 Author Share Posted February 10 @macsonny Just quickly looking, you have put it down as Hz should it need to be MHz also it mentions in the code, someone has create an APP to program it with out the need to work this code. http://www.adafruit.com/downloads/ClockBuilderDesktopSwInstallSi5351.zip maybe worth looking at this? funny enough I was going to fish out the one I purchased this weekend and try this but I had a troublesome 800XL to repair/upgrade, of which has taken longer to repair than expected, but that job is now done.... Any way, when you have done, let us know how this code goes, when I get a chance I can test it this end as well, as well as try the NTSC/XE Clock Speeds Well done so far Quote Link to comment Share on other sites More sharing options...
Overange Posted February 10 Author Share Posted February 10 The download does not work anymore https://web.archive.org/web/20220314070524/https://cdn-shop.adafruit.com/adafruit-download/ClockBuilderDesktopSwInstallSi5351.zip thank god for the waybackmachine Quote Link to comment Share on other sites More sharing options...
macsonny Posted February 10 Share Posted February 10 So I got it working - thanks for above advice. The board work out about $3-$6 USD each so fairly cheap. Now at least I know I can replace the clock crystals fairly easily 🙂 1 Quote Link to comment Share on other sites More sharing options...
Chri O. Posted February 10 Share Posted February 10 Not tested yet but just in case I'm posting this for teensy 4.x Ver.01 Teensy4.x SAI1 PAL 14.187576MHz MCLK OUTPUT on PIN 23 example code. /* V.01 Teensy4.x SAI1 PAL 14.187576MHz MCLK OUTPUT on PIN 23 example code. */ // heartbeat LED const int ledPin = LED_BUILTIN;// the number of the LED pin // int ledState = LOW; // ledState used to set the LED // unsigned long previousMillis = 0; // will store last time LED was updated // const long interval = 1000; // interval at which to blink (milliseconds) void setup() { pinMode(ledPin, OUTPUT); // heartbeat LED //Audio PLL (PLL4) //The audio PLL synthesize a low jitter clock from a 24 MHz reference clock. //The clock output frequency range for this PLL is from 650 MHz to 1.3 GHz. It has a Fractional-N synthesizer. //There are /1, /2, /4 post dividers for the Audio PLL. The output frequency can be set by //programming the fields in the CCM_ANALOG_PLL_AUDIO, and //CCM_ANALOG_MISC2 register sets according to the following equation. //PLL output frequency = Fref * (DIV_SELECT + (NUM/DENOM)) // !!! Set SAI1 MClock. !!! CCM_CCGR5 |= CCM_CCGR5_SAI1(CCM_CCGR_ON); CORE_PIN23_CONFIG = 3; //1:MCLK int DIV = 33; // divider value: 27~54, Fref24000000*(33+(155300/1488346)) int NUM = 155300; // 30 bit numerator of fractional loop divider int DENOM = 1488346; // 30 bit denominator of fractional loop divider. CCM_ANALOG_PLL_AUDIO = CCM_ANALOG_PLL_AUDIO_BYPASS | CCM_ANALOG_PLL_AUDIO_ENABLE | CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(1) // b01 = Divide/2, exp: b00 — Divide by 4, b10 — Divide by 1. | CCM_ANALOG_PLL_AUDIO_DIV_SELECT(DIV); CCM_ANALOG_PLL_AUDIO_NUM = NUM & CCM_ANALOG_PLL_AUDIO_NUM_MASK; CCM_ANALOG_PLL_AUDIO_DENOM = DENOM & CCM_ANALOG_PLL_AUDIO_DENOM_MASK; CCM_ANALOG_PLL_AUDIO &= ~CCM_ANALOG_PLL_AUDIO_POWERDOWN;//Switch on PLL while (!(CCM_ANALOG_PLL_AUDIO & CCM_ANALOG_PLL_AUDIO_LOCK)) {}; //Wait for pll-lock const int div_post_pll = 2; // 1 = Divide/2, other values: 2,4 CCM_ANALOG_MISC2 &= ~(CCM_ANALOG_MISC2_DIV_MSB | CCM_ANALOG_MISC2_DIV_LSB); if (div_post_pll > 1) CCM_ANALOG_MISC2 |= CCM_ANALOG_MISC2_DIV_LSB; if (div_post_pll > 3) CCM_ANALOG_MISC2 |= CCM_ANALOG_MISC2_DIV_MSB; CCM_ANALOG_PLL_AUDIO &= ~CCM_ANALOG_PLL_AUDIO_BYPASS;//Disable Bypass // clear SAI1_CLK register locations CCM_CSCMR1 = (CCM_CSCMR1 & ~(CCM_CSCMR1_SAI1_CLK_SEL_MASK)) | CCM_CSCMR1_SAI1_CLK_SEL(2); // (0,1,2): PLL3, PLL5, PLL4 CCM_CS1CDR = (CCM_CS1CDR & ~(CCM_CS1CDR_SAI1_CLK_PRED_MASK | CCM_CS1CDR_SAI1_CLK_PODF_MASK)) | CCM_CS1CDR_SAI1_CLK_PRED(7 - 1) // 110 divide by 7 | CCM_CS1CDR_SAI1_CLK_PODF(2 - 1); // 001 divide by 2 // IOMUXC_GPR, Select MCLK IOMUXC_GPR_GPR1 = (IOMUXC_GPR_GPR1 & ~(IOMUXC_GPR_GPR1_SAI1_MCLK1_SEL_MASK)) | (IOMUXC_GPR_GPR1_SAI1_MCLK_DIR | IOMUXC_GPR_GPR1_SAI1_MCLK1_SEL(0)); // todo MCLK2 } void loop() { // heartbeat LED unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interval) { // save the last time you blinked the LED previousMillis = currentMillis; if (ledState == LOW) { ledState = HIGH; } else { ledState = LOW; } digitalWriteFast(ledPin, ledState); } } Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.