This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TDC7200 calibration

Other Parts Discussed in Thread: TDC7200

I am intending to use the TDC7200 as a time to digital converter in a time tagging frequency counter.  The device will be used in measurement mode 1, with a clock frequency of 12.375MHz, and a range of times between start and stop events  from 80ns to 160ns.  After lengthy study of the data sheet, I eventually concluded that a calibration cycle is performed automatically after every measurement cycle.  The maximum measurement rate that I want to use is 100k measurements per second. I will be using an SPI clock rate of 20MHz.  My questions are:

1/- Is it necessary to read and calculate new calibration constants every measurement? What degradation in accuracy will result if the calibration constants are recalculated at a slower rate, say, every 10 or 100 measurement cycles?  Is the drift in the uncalibrated measurement mainly temperature related?

2/- Considering that my maximum time measurement is 160ns, is there any advantage in setting the second calibration measurement to more than 2 clock cycles?

 3/- Could you please confirm that I can achieve a throughput of 100k measurements per second with the above parameters?

regards

Cosmo Little

  • 1. Internal time base varies due to temperature as well as due to different delays in START, STOP and CLOCK paths. Calibration is needed to achieve accuracy specified in Data Sheet. We don't have data on the actual accuracy degradation when calibration is not applied. Is achieving higher throughput the main reason for reading calibration results every 10 or 100 measurement cycles?
    2. Considering your throughput requirement as well, 2 clock cycles of calibration measurement should do.
    3. With 20MHz SPI and 12.375MHz clock, you can get 100k measurements per second. Please see this discussion
    e2e.ti.com/.../445361
    Thanks,
    Vishy
  • Dear Vishy

    Thank you for the reply.

    Reading the calibration constants every measurement cycle takes too much time. I have to apply the calibration every measurement to correct the time reading, however I use two intermediate calculated constants, one a reciprocal of the other, in order to replace a  division with a multiplication.

      It occurs to me that I could average the calibration constants using a simple digital filter. This will reduce the variance of the calibration constants, and should also reduce the variance of the corrected measurement. This would be valid providing the calibration constants do not change too quickly. I am thinking of a filter time constant of not more than 100ms. Has this approach been considered?

    regards Cosmo Little

  • If you have not already, please look at Data Sheet figures 6 and 7. Gives you an idea of the variation of resolution over temperature and VDD. 

    thanks,

    Vishy

  • Dear Vishy,

    It seems from the data sheet that measurement variation with temperature will be negligible over a period under 1 second. As the calibration is two measurements with presumably the same random variation as a time measurement, averaging of the calibration constants may reduce the variation in the corrected measurement.

    I will try it

    regard

    Cosmo Little

  • Dear Cosmo,

    Could you please tell me how to "use two intermediate calculated constants, one a reciprocal of the other, in order to replace a  division with a multiplication"?

    I am dealing with a similar problem in mode 1 now and I think a division with denominator = calibration2 - calibration1 is needed, but I don't know how to replace it with a multiplication. Thanks. 

    Regards,

    Eric

  • Please see the following two code fragments. The first uses the two calibration constants to correct the time value.

    The second calculates the two constants from the TDC cal registers. Please note this code has only been tested on the simulator so far.

    Cosmo Little

    ; /* read TDC7200 time to digital converter */
    ;
    BCLR LATA, #7 ;chip select TDC A

    MOV #0x1000, W0 ;SPI1BUF = 0x1000. read cycle to TDC reg TIME1
    MOV W0, SPI1BUF ;start SPI
    ;

    BCLR IFS0, #IC1IF ; clear input capture 1 interrupt flag

    ; Aevent_time.integerclockcycles = IC1BUF + IC2BUF * 2^16 ); get 32 bit clock counter value

    MOV IC1BUF, W0
    MOV IC2BUF, W1
    MOV #_Aevent_data+2, W2
    MOV.D W0, [W2] ;store 32 bit clock cycle count in Aevent_data.integerclockcycles
    ;
    ; wait for SPI

    BTSS SPI1STAT, #SPIRBF
    BRA $-2
    ;
    ; 2nd part of read cycle, first 16 bits dumped
    CLR W0
    MOV W0, SPI1BUF
    ; wait for SPI

    BTSS SPI1STAT, #SPIRBF
    BRA $-2
    ; get 16 bit uncalibrated TIME1 from TDC

    MOV SPI1BUF, W0

    ; Correct TIME1 value using TDC calibration constants ( calculated in a different routine)

    ; Aevent_time.fractionalclockcycles = (TIME1 - Acalconstant)) * Arecipcalconstant >> 8

    ; A 16x16 multiply is performed. The 32 bit product is shifted 8 bits right ( /256)
    ; and the ls word is taken as the fraction cycle value. This must be complemented before storing
    ; as the time increment is measured to the next clock cycle, not the previous. The complemented value
    ; is stored in the first member of the struct Aevent_time, ie Aevent_time.fractionalclockcycles

    MOV _Acalconstant, W1
    SUB W0, W1, W0
    BRA NN , $+4
    CLR W0 ;if subtraction result is negative, zero result
    MOV _Arecipcalconstant, W1
    MUL.UU W0, W1, W0 ;32 bit result in W0, W1

    ; shift w0,w1 8 bits right, keeping lower word in w0

    SL W1, #8, W2
    LSR W0, #8, W0
    IOR W0, W2, W0
    LSR W1, #8, W1

    BRA Z, $+4 ;test for multiplication overflow past 24 bits
    SETM W0 ;set w0 to maximum fraction of FFFF

    ; fractional cycle count equals complement of W0

    COM W0, W0

    ; store calibrated fractional clock cycles in Aevent_data.fractionalclockcycles

    MOV W0, _Aevent_data

    /* Function CALIBRATE_TDC */

    void CALIBRATE_TDC (void)

    {
    static unsigned long lastPaceClock ;
    unsigned long calibration1, calibration2;

    if (PaceClock < ( lastPaceClock + CalibrateRate))
    return ;

    lastPaceClock = PaceClock;

    if ( LATBbits.LATB5 == 1) /*channel A busy*/
    return;
    else
    {

    LATAbits.LATA7 = 0; /*chip select TDC A*/
    SPI1BUF = 0x9C00; /* start read cycle from CALIBRATION1 register in TDC, auto increment on*/
    /* do not use first 16 bit read ( 8 ms bits) */
    while ( SPI1STATbits.SPIRBF == 0) /*wait for SPI*/
    ;
    SPI1BUF = 0x0000; /* read ls 16 bits of CALIBRATION1 register */
    while ( SPI1STATbits.SPIRBF == 0) /*wait for SPI*/
    ;
    calibration1 = SPI1BUF;

    SPI1BUF = 0x0000; /*read ms 8 bits of CALIBRATION2 register, but do not use */
    while ( SPI1STATbits.SPIRBF == 0) /*wait for SPI*/
    ;
    SPI1BUF = 0x0000; /* read ls 16bits from CALIBRATION2 */
    while ( SPI1STATbits.SPIRBF == 0) /*wait for SPI*/
    ;
    calibration2 = SPI1BUF;

    LATAbits.LATA7 = 1; /*deselect TDC A*/

    /* calculated the two calibration constants, Acalconstant and Arecipcalconstant */

    Acalconstant = calibration2 - calibration1;
    Arecipcalconstant = 0x1000000ul / Acalconstant;

  • considering this item closed