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.

TDC7201-ZAX-EVM: What is necessary to do after one measurement before taking another?

Part Number: TDC7201-ZAX-EVM
Other Parts Discussed in Thread: TDC7201

I'm seeing some weird SPI behavior in my Raspberry Pi 3B + TDC7201-ZAX-EVM system.. Taking the first measurement seems to work perfectly; I get pulses or a timeout, calibration gets run (I have CONFIG1/FORCE_CAL turned on so I can test calibration), I can read all the registers, the numbers look reasonable, I can do TOF calculation. But when I try to run a second measurement using the exact same code, the SPI interface isn't working right. Trying to read CONFIG1 and CONFIG2 gets me the CONFIG1 value for both reads, trying to read INT_STATUS and INT_MASK gets me the CONFIG2 value for both reads, etc. It is behaving as if the address byte was shifted 1 bit to the right, so that addresses 0 and 1 both count as 0, addresses 2 and 3 both count as 1, etc..

There could be many possible causes for this. Something in the Raspberry Pi 3 hardware. Something in the kernel driver. Something in the spidev library. Something in my own code. Something in the tdc7201 or the EVM. But before I go diving down the rabbit hole into kernel space, could someone explain EXACTLY what steps are required to clean up the tdc7201 state after a measurement and before starting another measurement? The documentation is a little vague on this point. I tried writing 1s to the appropriate INT_STATUS bits to clear them, but it didn't work, probably due to the address-shift mangling.

Power cycling the whole system (including rebooting the RPi) fixes the problem enough to get one more measurement, but then it goes wonky again.

Changing the SPI clock speed has absolutely no effect. The same thing happens from 50 kHz to 16 MHz.

I'm not doing any SPI operations during the measurement. I'm just sitting and waiting for INTB1 to drop like a good boy.

Thanks,

    Howard

  • Hi Howard,

    There aren't really any steps to clean up the TDC7201 after finishing a measurement before starting a new one. Just setting the Start New Measurement bit takes care of everything.

    I think there is likely something weird going on elsewhere with the SPI communication. I'm curious if it will work properly if you try multi cycle averaging, though. Try doing 2 or more cycles and see if it will give you good values after the second set of measurements is complete.

    Is there any way for you to keep the TDC7201 powered while rebooting the RPi? If you can reboot the RPi between measurements and it works fine, that could help narrow things down.

    Regards,
  • I finally tracked down the problem, and boy was it a doozy. I had a line of code in my tdc7201.compute_TOFs() routine to check what measurement mode we were in:

    self.mode = (self.reg1[self.CONFIG1] & self._CF1_MEAS_MODE) >> 1

    which was supposed to take the (previously read and saved) value of the CONFIG1 register from side 1 of the chip, logical AND it with a mask 0x06 for the measurement mode bits (getting 2), and right shift it by one bit (getting 1, meaning measurement mode 2). How could this possibly affect the SPI interface at all, you might well ask? It doesn't even talk to SPI, so it shouldn't have been able to. In fact, nothing in compute_TOFs() talks to SPI, so I had a hard time believing that the problem could be inside it. However ...

    As near as I can tell, Python 2.7.9 interprets this >> operator not as a bit shift, but as a write to file, and so is attempting to write the integer 2 to device 1, whatever that is. This hoses the SPI interface. The same line of code, but without the shift at the end, does NOT hose the SPI interface.

    The Python 2 >> operator is overloaded, just like in C++, so that it can mean either shift or write, depending on context. Python 3 doesn't allow use of >> as a file write, so this bug couldn't happen in it. One more reason to prefer Python 3. Maybe I'll convert all my code over before something else like this bites me.

  • Never mind, it was even stupider than that. The SpiDev class has a variable named "mode" which controls the polarity and phase. I was stepping on it when I assigned to self.mode. The reason the behavior was so different was that assigning 2 to it inverted the polarity, which meant that when I wrote to a register all the bits were inverted, but when I read them back they got inverted again so looked OK (even though the value stored in the register was wrong). But when I wrote a 1 to it, that inverted the clock phase so everything broke.

    Changing "self.mode" to "self.meas_mode" fixed everything. I am now running multiple measurements in a row (looking for 2 STOP pulses) and seeing times between software-generated pulses of around 3.9 to 8.6 uS (using GPIO.output() to drive the STOP signal high-low-high-low). I'm surprised that there's that much spread, but it looks like I might be ready to try real signals soon.