dsPIC33CK MCC bugs? Can't configure clocks - Page 1
Forum section: electronics / general

author: uer166
author_rank: Super Contributor
timestamp: July 06, 2019, 03:36:46 am
content: I'm using a DSPIC33CK32MP102T-I/SS with analog inputs driven by opamps connected to AN0 and AN1 (RA0 and RB2). I've set up Fosc to be 100MHz and Fosc/2 50MHz (so 50 MIPS), as attached.Then trying to set up all 3 ADCs (2 dedicated and one shared) with Fosc/2 clock input. That would be 50MHz or 20ns. The spec calls for ADC clock to be >14.3ns.When putting all above in MCC setup for ADC, it barfs out a warning about the clock being too fast, even though it's a 20ns clock. Is this a bug in MCC or am I being dumb?

author: wilfred
author_rank: Super Contributor
timestamp: July 06, 2019, 04:15:21 am
content: I had a look at the datasheet and I don't see Fosc/2 as a valid clock source in ADCON3H. But it is the first time I have read it.Perhaps also show your control register settings. That might provide someone more clues.If you search on your problem and find no-one else has reported it then you've most likely configured the clock source wrong.

author: uer166
author_rank: Super Contributor
timestamp: July 06, 2019, 04:26:12 am
content: Quote from: wilfred on July 06, 2019, 04:15:21 amFosc/2 is also defined as Fp (peripheral clock), which is a valid source in ADCON3H. It's kind of annoying that they're interchangeable in datasheet and MCC and MPlab etc.Quote from: wilfred on July 06, 2019, 04:15:21 amI sure hope I'm the one doing something wrong! But so far can't find exactly what it is...Here's the auto-generated config bits in case it helps. I have a 10MHz external oscillator connected to OSCI. Then that gets PLL'd up to 50MHz which is to be used everywhere.Code:// Configuration bits: selected in the GUI// FSEC#pragma config BWRP = OFF //Boot Segment Write-Protect bit->Boot Segment may be written#pragma config BSS = DISABLED //Boot Segment Code-Protect Level bits->No Protection (other than BWRP)#pragma config BSEN = OFF //Boot Segment Control bit->No Boot Segment#pragma config GWRP = OFF //General Segment Write-Protect bit->General Segment may be written#pragma config GSS = DISABLED //General Segment Code-Protect Level bits->No Protection (other than GWRP)#pragma config CWRP = OFF //Configuration Segment Write-Protect bit->Configuration Segment may be written#pragma config CSS = DISABLED //Configuration Segment Code-Protect Level bits->No Protection (other than CWRP)#pragma config AIVTDIS = OFF //Alternate Interrupt Vector Table bit->Disabled AIVT// FBSLIM#pragma config BSLIM = 8191 //Boot Segment Flash Page Address Limit bits->8191// FOSCSEL#pragma config FNOSC = PRIPLL //Oscillator Source Selection->Primary Oscillator with PLL module (XT + PLL, HS + PLL, EC + PLL)#pragma config IESO = OFF //Two-speed Oscillator Start-up Enable bit->Start up with user-selected oscillator source// FOSC#pragma config POSCMD = EC //Primary Oscillator Mode Select bits->EC (External Clock) Mode#pragma config OSCIOFNC = OFF //OSC2 Pin Function bit->OSC2 is clock output#pragma config FCKSM = CSECMD //Clock Switching Mode bits->Clock switching is enabled,Fail-safe Clock Monitor is disabled#pragma config PLLKEN = ON //PLL Lock Enable->PLL clock output will be disabled if LOCK is lost#pragma config XTCFG = G3 //XT Config->24-32 MHz crystals#pragma config XTBST = ENABLE //XT Boost->Boost the kick-start// FWDT#pragma config RWDTPS = PS2147483648 //Run Mode Watchdog Timer Post Scaler select bits->1:2147483648#pragma config RCLKSEL = LPRC //Watchdog Timer Clock Select bits->Always use LPRC#pragma config WINDIS = OFF //Watchdog Timer Window Enable bit->Watchdog Timer in Window mode#pragma config WDTWIN = WIN25 //Watchdog Timer Window Select bits->WDT Window is 25% of WDT period#pragma config SWDTPS = PS2147483648 //Sleep Mode Watchdog Timer Post Scaler select bits->1:2147483648#pragma config FWDTEN = ON_SW //Watchdog Timer Enable bit->WDT controlled via SW, use WDTCON.ON bit// FPOR#pragma config BISTDIS = DISABLED //Memory BIST Feature Disable->mBIST on reset feature disabled// FICD#pragma config ICS = PGD3 //ICD Communication Channel Select bits->Communicate on PGC3 and PGD3#pragma config JTAGEN = OFF //JTAG Enable bit->JTAG is disabled// FDMTIVTL#pragma config DMTIVTL = 0 //Dead Man Timer Interval low word->0// FDMTIVTH#pragma config DMTIVTH = 0 //Dead Man Timer Interval high word->0// FDMTCNTL#pragma config DMTCNTL = 0 //Lower 16 bits of 32 bit DMT instruction count time-out value (0-0xFFFF)->0// FDMTCNTH#pragma config DMTCNTH = 0 //Upper 16 bits of 32 bit DMT instruction count time-out value (0-0xFFFF)->0// FDMT#pragma config DMTDIS = OFF //Dead Man Timer Disable bit->Dead Man Timer is Disabled and can be enabled by software// FDEVOPT#pragma config ALTI2C1 = OFF //Alternate I2C1 Pin bit->I2C1 mapped to SDA1/SCL1 pins#pragma config ALTI2C2 = OFF //Alternate I2C2 Pin bit->I2C2 mapped to SDA2/SCL2 pins#pragma config SMB3EN = SMBUS3 //SM Bus Enable->SMBus 3.0 input levels#pragma config SPI2PIN = PPS //SPI2 Pin Select bit->SPI2 uses I/O remap (PPS) pins// FALTREG#pragma config CTXT1 = OFF //Specifies Interrupt Priority Level (IPL) Associated to Alternate Working Register 1 bits->Not Assigned#pragma config CTXT2 = OFF //Specifies Interrupt Priority Level (IPL) Associated to Alternate Working Register 2 bits->Not Assigned#pragma config CTXT3 = OFF //Specifies Interrupt Priority Level (IPL) Associated to Alternate Working Register 3 bits->Not Assigned#pragma config CTXT4 = OFF //Specifies Interrupt Priority Level (IPL) Associated to Alternate Working Register 4 bits->Not AssignedEdit: I should add that I don't have the hardware and just trying to figure some things out beforehand, so can't just "test" it, even though for things like clock settings I don't like that concept since it still may be accidentally overclocked.

author: JPortici
author_rank: Super Contributor
timestamp: July 06, 2019, 11:18:03 am
content: I don't trust code generators.Also there were mentions of MCC having bugs and missing features for the dsPIC33C series (new oscillator block, new CAN FD peripehral.. such things)FYI you have to set the PLL output to 200 MHz to achieve 50 MIPS.. because the System clock source hasFPLL/2as an input.. so FPLL = 200 MHz => FOSC = 100 MHz => 50 MIPSI bet that MCC is setting the PLL frequency correctly, but it's reporting the incorrect frequency to the ADC module, hence the warning.Read the datasheet and the reference manual chapters (in your case "Oscillator Module with High-Speed PLL" and "12-Bit High-Speed, Multiple SARs A/D Converter (ADC)")in the FRM you'll have a ton of code examples for any peripheral, most if not all use cases.The oscillator is pretty straightforward to configure.. The ADC is a bit more convoluted but still rather easyOtherwise, i don't think i'll have time over the weekend (going away soon) but i may be able to post some code when i come back.. even though there's no need! the FRM has plenty. (i can however help you understand it)

author: ndan
author_rank: Newbie
timestamp: August 09, 2019, 06:29:30 pm
content: QuoteActually that is not right and the MCC outputs the correct warning.It is true that at FOSC/2 = 50MHz you have 20 ns. However, both shared and dedicated ADC cores divide this clock in half (the minimum setting) yielding a frequency of 100MHz for TCORESRC. As the reference manual (http://ww1.microchip.com/downloads/en/DeviceDoc/70005213f.pdf- page 37) says:"Each ADC core has its own clock divider that is configured with the ADCS<6:0> bits in the corresponding ADCOREnH register for the dedicated core, and with the SHRADCS<6:0> bits in the ADCON2L register for the shared ADC core."Hence, to use the ADC you have to lower the frequency a bit, i.e. FOSC = 70MHz => FOSC/2 = 35MHz which will yield > 14.3ns for the TADCOREI have tested this setting using dspic33CK256MP508 for both types of cores and it works just fine.As Dave usually goes:"Winner Winner Chicken Dinner"

author: NorthGuy
author_rank: Super Contributor
timestamp: August 09, 2019, 08:08:21 pm
content: Quote from: ndan on August 09, 2019, 06:29:30 pmSetting aside everything else, when you divide a clock the frequency becomes lower and the period becomes longer.

author: uer166
author_rank: Super Contributor
timestamp: August 11, 2019, 04:42:38 am
content: Yeah I still don't see it, how can a 50MHz clock become 100MHz after being divided? The ADCs have no PLLs on the inputs.

author: ndan
author_rank: Newbie
timestamp: August 11, 2019, 02:20:01 pm
content: Very true. However, the reference manual says:" each ADC core individually divides the TCORESRCclock to get a core-specific TADCOREclock"Hence its a frequency multiplier, as both TCORESRCand TADCOREare measured in seconds. You can try to play around with the settings in MCC and see the how the timing changes. Or perhaps you can try to measure how long it takes for a single conversion with an oscilloscope, i.e.:- use the ADC in software trigger mode/a single channel/interrupt based- set the LED on right before the trigger- set the LED off in the interrupt- do not forget to measure the interrupt latencyAfter this, you can calculate the ballpark estimate as: pulse_width - interrupt_latency, which will be close to your settings to distinguish the clocks: sampling time + convertion_timeDan.PS: There is no way around this if you want to use the ADC, even if you use an external oscillator.However, if I understood it wrong and you do manage to get the CPU at 100MHz with the ADC properly working, I would be more than happy to verify your settings on my setup.

author: NorthGuy
author_rank: Super Contributor
timestamp: August 11, 2019, 02:43:23 pm
content: Quote from: ndan on August 11, 2019, 02:20:01 pmAre you trying to say that two consecutive clock dividers are equivalent to a frequency multiplier?

author: ndan
author_rank: Newbie
timestamp: August 11, 2019, 03:24:10 pm
content: No, I'm just saying the core period is divided.

author: NorthGuy
author_rank: Super Contributor
timestamp: August 11, 2019, 03:41:38 pm
content: Quote from: ndan on August 11, 2019, 03:24:10 pmThe frequency is divided. The period (being 1/frequency) is multiplied.

author: ndan
author_rank: Newbie
timestamp: August 11, 2019, 04:05:48 pm
content: Well, maybe your right or maybe your not. And, yes, I do agree that having a period divider (no, not frequency divider which is the usual case) is extremely strange.Go test and post the results.

author: JPortici
author_rank: Super Contributor
timestamp: August 12, 2019, 05:50:46 am
content: Quote from: ndan on August 11, 2019, 02:20:01 pmyou need to read again, bolding added by me.divide theclock, multiply the period.

author: ndan
author_rank: Newbie
timestamp: August 12, 2019, 11:32:15 am
content: I admire your perseverance.Now, let me just say that I do understand what the datasheet / user reference manual says. Plus, I'm only a newbie on the forum and not much else. However, I have found several mistakes in both manuals regarding the ADC. Using the MCC was no help, because it gave the the reported clock warning. And computing T = 1 / f = 1 / 70MHz yielded approximately the 14.3ns specification which is the highest setting for which the MCC does not complain about. All of this made me to believe that they have included a clock (and I mean frequency) multiplier in the ADC.As of now, I have done the tests I have suggested earlier using the following setup:- MCU: dspic33ck256MP508- Compiler / IDE: XC16 v1.36B / MPLAB X v5.20- Clock: FRC+PLL @100MHz with prescaler = 1, feedback = 150, postscaler1 = 3, postscaler2 = 2- ADC: Clock Divisior (CLDIV) = 1, ADCS = 0 (which halves the clock) and sampling time of 6 TAD for the shared and core0- Toggling a LED marked the begging and end of the sampling+conversion, where the pulse width was measured with TBS1152 oscilloscopeAt this clock I assume its safe to test the ADC, since the datasheet reads:"Note 1: The ADC input clock frequency, selected by the CLKSEL[1:0] bits, must not exceed 560 MHz.2: The ADC clock frequency, after the divider selected by the CLKDIV[5:0] bits, must not exceed 280 MHz"Also I did two builds with the same clock and ADC settings:- first build: using a firmware I had at hand- second build: barebone project with Clock / ADC / UARTResults:- the interrupt latency is around 520ns +/- a few nano seconds for both builds (measured using two gpios).- on the first build the ADC gave me weird results for measured values. All conversions took way longer than those with the 70MHz clock. The average per sampling + conversion was at 4.5us . These, of course, are bogus and don't correspond to the expected 980ns by a huge margin. Other divisors yielded even weirder results, some of which took way longer and some of which took way shorter periods.- on the second build, the ADC gave me the correct results averaging 987ns per sampling + conversion. I also obtained good results for CLDIV = 2, ADCS = 0 or CLDIV = 1, ADCS = 2, both settings averaging around 1956ns per sampling + conversion. In this instance all the ADC measured values were as expected.@JPortici, @NorthGuy Hence, congrats you were right! Its a divisor as one usually expects.@uer166 However, I still don't recommend using the highest possible clock, especially with the ADC since its always impacted by temperature variations and clock drifts.

author: ndan
author_rank: Newbie
timestamp: August 12, 2019, 12:02:28 pm
content: @uer166 Find the attached clock (100MHz FRC+PLL ) and adc (50MHz) files below.