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: UNABLE to read CLOCK_COUNT1 registers

Part Number: TDC7200
Other Parts Discussed in Thread: MSP430FR5969

Tool/software: Code Composer Studio

Good morning,

I'm using a TDC7200 to measure the ToF. Up until this moment, I've successfully configured all the registers and I'm able to see the interrupt on INTB pin. The TDC is configured to operate in Mode2 (16MHz external CLOCK), with a single STOP, 2 Calibration cycles at the end and with START, STOP and TRIGG at falling edge. The NEW MEASUREMENT and CLOCK_COUNTER_OVF Interrupts are enabled while the COARSE_COUNTER_OVF is disabled in INT_MASK. I've set the CLOCK_CNTR_OVF to several different values and the interrupt instant on INTB responds accordingly. For e.g., in the images below, I've set the overflow condition to 1us and 4us and one can see the INTB pin (Red signal) switching at the right time after the falling edge on START (yellow). I've also verified the INT_STATUS register after each interrupt and I obtain 0x1D (Clock overflow detected). The problem I'm facing is reading the CLOCK_COUNT1 registers. In principle, I should read the same value set on the CLOCK_CNTR_OVF. Whatsoever, I'm always reading 0.

Can someone please point me out the problem? The code I'm using is also shown below (MSP430FR5969 microcontroller).

Thank you very much,

Joaquim

P.S.- In the meantime, I've done some tests with an external STOP signal and the TDC seems to be unable to detect it and continues to interrupt at the time defined through CLOCK_CNTR_OVF.

#include <msp430fr5969.h>
#define nop __asm__ __volatile__("nop\n\t"); 

float f_p = 10, duty_cycle = 0.65;                      // Setup PWM parameters for periodic START signal 
uint8_t restart[2] = {0b01000000, 0b10111011};          // Set new measurement
int restart_len = sizeof(restart)/sizeof(restart[0]);
uint8_t RX_buffer[3] = {}, aux[3] = {}, aux_2[3] = {};  // Buffers where read values are stored

void setup_PWM(float , float);
void setup_TDC();
void SPI_send(uint8_t *, int);
void SPI_receive(uint8_t *, uint8_t);
void ToF_read();

void setup(){
  PM5CTL0 &= ~LOCKLPM5;

  Serial.begin(115200);    // Set UART to send to Serial Monitor

  P3DIR |= 0x20;           // Output SMCLK @ 16MHz
  P3OUT &= ~0x20;
 
  P2DIR &= ~0x10;          // Interrupt pin for TDC                   
  P2REN |= 0x10;                                                   
  P2IES |= 0x10;                                                    
  P2IFG &= ~0x10;                                                  
  P2IE |= 0x10; 
  
  P3DIR |= 0x10;                  
  P3SEL1 |= 0x10;

  setup_TDC();             // Configure TDCs
  delay(2);

  setup_PWM(f_p,duty_cycle);    // Setup PWM
}


void loop(){
  Serial.println(aux[0]);     // Print CONFIG1 after Interrupt (in decimal)
  Serial.println(RX_buffer[0]);   // Print 3 bytes read from CLOCK_COUNT1
  Serial.println(aux_2[0]);   // Print INT_STATUS after Interrupt (in decimal)
  Serial.println(RX_buffer[1]);
  Serial.println(RX_buffer[2]);
}

#pragma vector=PORT2_VECTOR
__interrupt void PORT2_ISR_HOOK(void){                                                                     
  ToF_read();                                                       // Read data
  P2IFG &= ~0x10;                                                   
  P2IE |= 0x10;                                                     // Re-enable Interrupt                                                   
}
          
void setup_PWM(float f_pwm, float dc_pwm) {                         
  P1DIR |= 0x04;                                                    // P1.2 as the PWM output (dedicated pin) 
  P1OUT &= ~0x04;                                                   
  P1SEL0 |= 0x04;                                                   
                                                                 
  TA1CTL |= TASSEL_2 | ID__1 | MC_1 | TACLR;                        
  TA1CCTL1 = OUTMOD_7;                                              
  int T_0 = int(16000 / f_pwm);                                     
  int T_1 = int(dc_pwm * T_0);                                      
  TA1CCR0 = T_0;                                                     
  TA1CCR1 = T_1;                                                                                                                      
}

void setup_TDC(){ 
  // SPI configuration                                                  
  P3DIR |= 0x01;    // CS pins (active-low)                                                  
  P3OUT |= 0x01;
  P1DIR |= 0x10;                                                    
  P1OUT |= 0x10; 
                                                       
  UCB0CTLW0 = UCSWRST | UCSSEL_2;                                   
  UCB0CTLW0 |= UCCKPH | UCMSB | UCSYNC | UCMST;                     
  UCB0CTLW0 &= ~UCCKPL;                                            
  P1DIR &= ~0b10000000;                                             
  P1DIR |= 0b01000000;                                              
  P1SEL1 |= 0b11000000;                                                                                        
  P1SEL0 &= ~0b11000000;
  P2DIR |= 0b00000100;                                              
  P2SEL1 |= 0b0000100;                                              
  P2SEL0 &= ~0b00000100;
  UCB0BR0 = 1;      // 16 MHz SPI CLK                                                                              
  UCB0BR1 = 0;
  UCB0CTLW0 &= ~UCSWRST;    

  // Configuration registers
  uint8_t CONFIG1[2] = {0b01000000, 0b10111011};      // Start New measurement | Mode 2 | START, STOP, TRIGG falling edge | Force CAL | No parity
  uint8_t CONFIG2[2] = {0b01000001, 0b00000000};      // Single stop | No averaging | 2 CAL cycles
  uint8_t INT_MASK[2] = {0b01000011, 0b00000101};     // Enable New measurement and Clock counter overflow enabled (Coarse counter overflow disabled)
  uint8_t CLOCK_CNTR_OVF_H[2] = {0b01000110, 0b00000000};   // Overflow set @ 1us for 16MHz external clock
  uint8_t CLOCK_CNTR_OVF_L[2] = {0b01000111, 0b00010000};   
  uint8_t CLOCK_CNTR_MASK_L[] = {0b00000000, 0b00000000};   // No STOP mask

  int config_len = sizeof(CONFIG1)/sizeof(CONFIG1[0]);      
                                                                
  SPI_send(CONFIG2,config_len);
  SPI_send(INT_MASK,config_len);      
  SPI_send(CLOCK_CNTR_OVF_H,config_len);
  SPI_send(CLOCK_CNTR_OVF_L,config_len);
  SPI_send(CLOCK_CNTR_MASK_L,config_len);
  SPI_send(CONFIG1,config_len);                   
}

void ToF_read(){                  // Read data from TDC whenever INTB interrupts
  SPI_receive(RX_buffer,0x11);    // Read CLOCK_COUNT1       
  SPI_receive(aux,0x00);          // Read CONFIG1 after measurement
  SPI_receive(aux_2,0x02);        // Read INT_STATUS

  SPI_send(restart,restart_len);  // Set New measurement bit in CONFIG1
}

void SPI_send(uint8_t *data, int len) {                                           
  P3OUT &= ~0x01;     // CS low
  while (len){                                                                    
    while(!(UCB0IFG & UCTXIFG));                                                  
    UCB0TXBUF = *(data++);                                                        
    while(!(UCB0IFG & UCTXIFG));                                   
    UCB0TXBUF = *(data++);  
    while (UCB0STAT & UCBUSY);                                                       
    len-=2;                                                                       
  }
  P3OUT |= 0x01;      // CS high      
}

void SPI_receive(uint8_t *buffer, uint8_t addr){      
  P3OUT &= ~0x01;                                                                                                               
  while(!(UCB0IFG & UCTXIFG));                                         
  UCB0TXBUF = addr;   // Address of register to read
                                                                                         
  while(!(UCB0IFG & UCTXIFG));
  UCB0TXBUF = 0x00;                                                    
  while (UCB0STAT & UCBUSY);                                          
  buffer[0] = UCB0RXBUF;
  
  while(!(UCB0IFG & UCTXIFG));
  UCB0TXBUF = 0x00;                                                    
  while (UCB0STAT & UCBUSY);                                          
  buffer[1] = UCB0RXBUF;
  
  while(!(UCB0IFG & UCTXIFG));
  UCB0TXBUF = 0x00;                                                    
  while (UCB0STAT & UCBUSY);                                          
  buffer[2] = UCB0RXBUF;   
                                                
  while (UCB0STAT & UCBUSY);                                                                   
  P3OUT |= 0x01;    
}