• AVR Freaks

33EP CTMU does not give sensible readings

Rick M
New Member
  • Total Posts : 2
  • Reward points : 0
  • Joined: 2019/07/16 11:32:57
  • Location: 0
  • Status: offline
2019/07/18 02:07:25 (permalink)

33EP CTMU does not give sensible readings

Can someone help me solve the following please:

I'm trying to measure the time between the rising edges on two equal frequency, slow (~2Hz), almost in phase square waves. They are within about 500nS but can go down to almost 0ns. One has a random jitter of +/-25ns, the other <<1ns and signal 1 normally leads signal 2 (I can adjust the phase difference for testing). A dsPIC with CTMU seems ideal and I'm using one in the circuit anyway: dsPIC33EP128MC202

I've been at it for two days, going around in circles, re-reading all the datasheets, trying all sorts of variations and repeating the tests. No matter what I try I can't seem to get a sensible response from the CTMU/ADC. It always does the same thing:

It seems to be basically working, but the readings just don't make sense. In particular, when I lower the pulse separation from 400ns to zero, the ADC readings don't really change accordingly although they do get lower.

With a 5.5uA current, and with the ADC (+stray) capacitance of ~5pf, I should get an ADC reading of ~0.44V = 136 counts (3.3V supply, 10 bits, V=T.I/C). I get around 350 counts.

With the current set at 0.55uA, which should give a tenth of that, I get readings around 270 for 400nS. Setting 55uA makes the ADC go full scale instantly. As I bring the pulse difference down to zero, the ADC reading gets to around 180 counts (regardless of the current) before the pulses reverse and the ADC goes full scale as expected.

Discharge time for the sampling capacitor makes no difference; I've tried adjusting that too.

Below is the reduced (and now somewhat messy looking) code I've done for testing, along with an output log from a constant ~400ns (with jitter) pulse separation, and a log where I slowly ramp Pulse_2 closer to Pulse_1, eventually swapping order. Note that I've written the code in CCS C, but I also rewrote it with xc16 last night and got the same results (although for some reason with xc16 the CTMU will not trigger the ADC to read (done flag is never set and a the ADCBUF is empty), despite setting the registers correctly and the CTMU functioning as expected otherwise. I had to work the ADC manually once in the CTMU interrupt handler by resetting SAMP).

The pulses were observed on a 200MHz oscilloscope throughout. The waves are nice and clean and I can't see anything in the signals to explain the above.

// Include file not shown but has nothing of relevance to the issue
// CTMUICON bits
#word CTMUICON = getenv("SFR:CTMUICON")

// CTMUCON1 bits
#word CTMUCON1 = getenv("SFR:CTMUCON1")
#bit CTMUEN = getenv("BIT:CTMUEN") // Enable CTMU
#bit CTMUSIDL = getenv("BIT:CTMUSIDL")
#bit TGEN = getenv("BIT:TGEN")
#bit EDGEN = getenv("BIT:EDGEN") // 0 = Software, 1 = Hardware edges
#bit EDGSEQEN = getenv("BIT:EDGSEQEN") // 1 = Edge 1 must occur before Edge 2
#bit IDISSEN = getenv("BIT:IDISSEN") // Enable current discharge
#bit CTTRIG = getenv("BIT:CTTRIG") // CTMU triggers ADC

// CTMUCON2 bits
#word CTMUCON2 = getenv("SFR:CTMUCON2")
#bit EDG1STAT = getenv("BIT:EDG1STAT")
#bit EDG2STAT = getenv("BIT:EDG2STAT")

// ADC Registers
#word AD1CON1 = getenv("SFR:AD1CON1")
#bit ADON = AD1CON1.15 // Enable ADC
#bit SAMP = AD1CON1.1 // 1=Sampling, 0=Holding
#bit DONE = AD1CON1.0 // 1=Conversion finished
#word AD1CON2 = getenv("SFR:AD1CON2")
#word AD1CON3 = getenv("SFR:AD1CON3")
#word AD1CHS0 = getenv("SFR:AD1CHS0")
#word ADCBUF = getenv("SFR:ADC1BUF0")

long int CTMUvalue;

// Initialise the CTMU
void initCTMU() {
 CTMUICON = 0b0000000100000000; // 0.55uA, no trim
 CTMUCON2 = 0b1100110011001100; // Rising Edges, CTED1=Pulse_1, CTED2=Pulse_2
 CTMUCON1 = 0b0000010100000000; // CTMU Off, EDGSEQEN, CTTRIG
 AD1CON1 = 0b0000000011000000; // 10-bit, CTMU triggers conversion
 AD1CON2 = 0; // Supplyr rail Vrefs, CH0
 AD1CON3 = 0b0000000000000101; // ADC uses system clock, (5+1)*Tcy=120ns
 AD1CHS0 = 0b0001111100011111; // ADC MUX to Open for CTMU
 ADON=1; // Enable ADC
 SAMP=1; // Set ADC to Sampling
 IDISSEN=1; // Ground the current source
 delay_us(100); // Time to discharge the sample capacitor
 IDISSEN=0; // Disable discharge
 CTMUEN=0; // Disable CMTU
 CTMUCON2=0b1100110011001100; // Reset EDGxSTAT
 EDGEN=1; // Enable hardware edges
 CTMUEN=1; // Enable CTMU

void CTMU_Interrupt(void) {
 if (EDG1STAT && EDG2STAT) {
  while (!DONE) {}
  DONE=0; // Clear ADC done flag
  CTMUvalue = ADCBUF;
  // Reset for next trigger
  CTMUEN=0; // Disable CTMU
  SAMP=1; // Set ADC to Sampling
  IDISSEN=1; // Ground the current source
  delay_us(100); // Time to discharge the sample capacitor
  IDISSEN=0; // Disable discharge
  CTMUCON2 = 0b1100110011001100; // Reset EDGxSTAT
  CTMUEN=1; // Enable CTMU

void main() {
 #use delay(clock=100000000)
 printf("\r\nI'm Alive\r\n");

 while (1) { }

0.55uA current. Pulse_2 lags Pulse_1 by about 400nS with 20nS jitter.

ADC Counts
... continues similar to above

0.55uA Current, bringing Pulse 2 gradually closer to Pulse 1 until they are in phase and then swap order.

ADC Lag, ns
counts (approx)
------ -----
242 400
256 300
201 200
214 100
165 0
... reverses order
the pulses reverse order and the readings go full scale every other pair


2 Replies Related Threads

    Aussie Susan
    Super Member
    • Total Posts : 3735
    • Reward points : 0
    • Joined: 2008/08/18 22:20:40
    • Location: Melbourne, Australia
    • Status: offline
    Re: 33EP CTMU does not give sensible readings 2019/07/18 19:27:54 (permalink)
    (Also see https://www.edaboard.com/showthread.php?385570-dsPIC-CTMU-does-not-give-sensible-readings. At the time of posting this, there were no answers there either.)
    You have probably gone through the 'Electrical Characteristics' tables etc. but my first thought is that trying to to do any sort of measurement in the nS range with Microchip MCUs is problematic. The ADC needs many nSec for each sample time and I've no idea of the resolution of the CTMU.
    Rick M
    New Member
    • Total Posts : 2
    • Reward points : 0
    • Joined: 2019/07/16 11:32:57
    • Location: 0
    • Status: offline
    Re: 33EP CTMU does not give sensible readings 2019/07/19 01:59:36 (permalink)
    Hi, I recognize your username from over there. After posting there I thought I might be better off here since it's such a specific problem. Yes, I've read all the docs, even the errata (and subsequently stopped trying to use 12-bit ADC mode).
    Supposedly the CTMU has a <1ns resolution, but I can't find any specifications on its minimum gate time. I think it's more a CTMU issue than an ADC one. Repeated testing shows that the readings seem to have a minimum of about 150 counts so it seems that the CTMU just can't turn on and off the current source quickly enough. Basically there is a large and unpredictable offset.
    The oddest thing is that I did get it to work more or less as expected, just once and short lived. Early on in my tests I had the idea of swapping the signals over on the CTED1/2 pins, and reversing the sequence order in the register accordingly. Suddenly it just worked, giving a linear response to changing the phase lag and reading down to zero when in phase. Then I just powered off and back on and it went back to the usual problems. I have not been able to repeat this working state.
    If it wasn't for that one time, I would have given this up as a bad job. It's as if there was some random event in the chip that just aligned the logic properly, just that once, perhaps based on the order I set the registers or something. That seems a bit random, but I can't help wondering. I've even tried a new chip just in case I had a faulty one but it made no difference.
    If I could get this working properly it would make all the difference for my project.
    post edited by Rick M - 2019/07/19 02:04:23
    Jump to:
    © 2020 APG vNext Commercial Version 4.5