Tool/software:
Hi team,
My customer is having a crystal-related issue.
What they are trying to do
Hi Rick,
Thank you for sharing I am awaiting some inputs from the team. I
Please bear with me.
Best regards,
Hi,
Thank you for your patience.
First of all, I would like to make you aware that the LF good indicator in CC2340R2 is not a fully reliable indicator of the clocks being stable. This has been found under validation and the software shipped within the SDK implements the required workarounds.
The following is recommended: Before switching to the clock, the SW needs to ensure that the LF clock is stable. To make sure this is the case, it is recommended to wait for 1s after switching on LFXT, and 100ms after switching on LFOSC before switching them to the main clock
However this does not explain the behavior of the GOOD signal in your case, this will have to be considered when developing your software.
To go back to the LF good signal not working at all - This behavior has not been observed so far. For sanity, I believe we should check on the procedure you follow to switch on LFXT.
Could you please share such procedure with us so we can review?
Best regards,
Hi,
Thanks, this helps. It looks like from your reply that we cannot do what we were wanting to do. Just to be clear I will restate that what we want to do. We are trying to measure the crystal start up time of the external low frequency crystal. We are using DIO20 as a port pin to measure this amount of time. When we allow the crystal to start, we raise DIO20 and when the LFCLKGOOD signal is true we will lower DIO20. Also we are exporting the LF clock signal out on DIO12. This allows us to capture the scope plot above that show the LFCLKGOOD signal is occurring before the crystal actually starts. Below is source code that will allow you to see this occur. We just call it in main() after board_init() runs before app_main() and the scheduler starts.
// Turn off HFXT and LFXT crystals
HWREG(CKMD_BASE + CKMD_O_HFXTCTL) &= ~CKMD_HFXTCTL_EN_M;
HWREG(CKMD_BASE + CKMD_O_LFXTCTL) &= ~CKMD_LFXTCTL_EN;
/* Enable LFCLKGOOD Note the LFCLKGOOD block is not directly connected to LFXT.
* See the LFCLK link, 3 steps below */
HWREG(CKMD_BASE + CKMD_O_IMSET) = CKMD_IMASK_LFCLKGOOD;
// Clear the RIS LFCLKGOOD flag by setting the ICLR register for the GOOD bit.
HWREG(CKMD_BASE + CKMD_O_ICLR) |= CKMD_MIS_HFXTGOOD_M + CKMD_MIS_LFCLKGOOD_M;
// route LFXT to 32K bus
/* Set LFCLK */
HWREG(CKMD_BASE + CKMD_O_LFCLKSEL) = CKMD_LFCLKSEL_MAIN_LFXT;
// route 32K bus to Clock out pin
Crystal_OSC_Output();
// turn on LFXT
HWREG(CKMD_BASE + CKMD_O_LFXTCTL) = CKMD_LFXTCTL_EN;
// DIO20 High [ start of osc time ]
HWREG(GPIO_BASE + GPIO_O_DOUTSET31_0) = 1 << MY_STARTUP_TIME_OUTPUT;
while(1)
{
small_delay(); // delay a hundred or 2 microseconds
// If LFXT is Enabled, Test for the LFXT GOOD Flag
if (HWREG(CKMD_BASE + CKMD_O_RIS) & CKMD_MIS_LFCLKGOOD_M)
{
// iF the Good Flag is Set, Clear DIO20
HWREG(GPIO_BASE + GPIO_O_DOUTCLR31_0) = 1 << MY_STARTUP_TIME_OUTPUT;
break; //Break from Loop
}
}
// Done
void Crystal_OSC_Output(void)
{
uint8_t clockSrc = 0x0F; //for LF crystal clock
// drive output low first
GPIO_setConfig(12, GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW);
// Configure the IOC.IOC12.PORTCFG MMR to select DTB
HWREG(IOC_BASE + IOC_O_IOC12) &= ~IOC_IOC12_PORTCFG_M;
HWREG(IOC_BASE + IOC_O_IOC12) |= IOC_IOC12_PORTCFG_DTB;
// Make sure the DTB mux selects in IOC (and if required in
// source clock IP) are reset that zero is driven on DTB0.
// ULLSEL mux select (select CKMD)
HWREG(IOC_BASE + IOC_O_DTBCFG) &= ~IOC_DTBCFG_ULLSEL_M;
HWREG(IOC_BASE + IOC_O_DTBCFG) |= 0x1 << IOC_DTBCFG_ULLSEL_S; // 0x1 to route CKMD to DTB0
// Map DTB[2:0] to DTB[15:13]
HWREG(IOC_BASE + IOC_O_DTBCFG) &= ~IOC_DTBCFG_PADSEL_M;
HWREG(IOC_BASE + IOC_O_DTBCFG) |= IOC_DTBCFG_PADSEL_DTB2TO0;
// Enable IOC.DTBOE.EN0
HWREG(IOC_BASE + IOC_O_DTBOE) &= ~IOC_DTBOE_EN0_M;
HWREG(IOC_BASE + IOC_O_DTBOE) |= IOC_DTBOE_EN0_ENABLE;
// select which clock (CKMD) to output on DTB0 (DTB[0])
HWREG(CKMD_BASE + CKMD_O_DTBCTL) &= ~CKMD_DTBCTL_CLKSEL_M;
HWREG(CKMD_BASE + CKMD_O_DTBCTL) |= (clockSrc) << CKMD_DTBCTL_CLKSEL_S;
// enable DTB output
HWREG(CKMD_BASE + CKMD_O_DTBCTL) &= ~CKMD_DTBCTL_EN_M;
HWREG(CKMD_BASE + CKMD_O_DTBCTL) |= CKMD_DTBCTL_EN;
}
Hi Rick,
Hope you are doing well! I will be supporting you on resolving this as soon as possible. I have reached out to our R&D team with the latest information you have shared and I will let you know once I have heard back.
Best Regards,
Jan
Hi Rick,
Could you provide the source code of the small_delay()? The R&D team would like to see the exact procedure done by that function to achieve the delay.
Best Regards,
Jan
Hi Jan,
That part of the code was just pseudo code. Any kind of delay or no delay at all will probably work. So no I cannot provided code for that small delay.
The actual code just loops through a bigger part of the code and checks a port pin to ensure that we are still testing the low frequency crystal and then comes back. I was just guessing that the time to get back to test the pin would be a 100 or so microseconds.
Thanks,
Rick
Hi Rick,
Understood. I will let the R&D team know. Thank you for the quick response on this.
Best Regards,
Jan
Hi Rick,
Just got word back from R&D and they suggest the following:
Best Regards,
Jan
Thanks Jan,
I can't wait to try this! I will post if it works for us.
Thanks,
Rick
Hi Rick,
Sounds good! Let me us know how the test results look!
Best Regards,
Jan
Hi Rick,
Glad to hear! I will mark this thread as closed for now. If you have any further questions on this topic feel free to reply to this comment or create a new thread if a new topic comes up.
Best Regards,
Jan