Severson-Group / AMDC-Firmware

Embedded system code (C and Verilog) which runs the AMDC Hardware
http://docs.amdc.dev/firmware
BSD 3-Clause "New" or "Revised" License
31 stars 5 forks source link

Rewrite Kaman eddy current sensor FPGA driver #302

Closed npetersen2 closed 1 year ago

npetersen2 commented 1 year ago

This issue is related to the FPGA IP block which interfaces to the Kaman eddy current sensor block: https://github.com/Severson-Group/AMDC-Firmware/tree/v1.0.x/ip_repo/amdc_eddy_current_sensor_1.0


We need to update the FPGA logic per a few requests:

1. Worst-case timing

The Kaman eddy current sensor uses a SAR-type ADC to sample the voltage-based displacement signal internally. The ADC used is the Analog Devices AD4011. We need to drive the SPI interface with the worst-case timing per the datasheet, given the schematic connections used by Kaman (i.e., turbo mode, 3 or 4 wires, etc).

2. Minimize metastability issues

The current driver does not double flop the incoming data signals from the Kaman device. This can cause metastability concerns due to crossing clock domains.

3. Synchronize ADC convert start to PWM carrier

The current driver uses a free-running sampling method. However, due to periodic noise (EMI) induced by the PWM switching edges, we need to sample the eddy current sensors at the peak/valley of the PWM triangle carrier.

4. Run the SPI clock fast

Since we will need to wait until the data is sampled to run our control algorithm, make sure to run the ADC's SPI interface as fast as possible, given the hardware constraints. I presume the bottleneck here will be the diff/single-ended traceivers, so somewhere around 10-20 MHz clock rate will probably be the limit. Please review the relevant datasheets to ensure the limit, and make the clock divider settings configurable from the user C code API.

5. Add a done signal

Add a new signal output from the FPGA IP block to the rest of the block design which indicates when the data has arrived and is valid. This should go LOW when the ADC convert-start occurs, stay low during data transmission back to the AMDC, and then go HIGH only when both X and Y channels have valid data.

codecubepi commented 1 year ago

@npetersen2

I have written a quick ModelSim testbench to test my latest version on the spi-master branch.

Here is the testbench, which simulates the AXI clock and PWM carriers at their current frequencies, as well as applies random stimulus to the miso_x and miso_y lines. You don't have to run it if you're busy, but there are some things to know:

Here is my wave output:

Please compare the timing of the cnv and sclk lines to those in the datasheet linked above (page 32).

image

Next Steps

I'm going to update the IP block in Vivado and try to test this on hardware tomorrow. If it looks good by you and on the hardware, I'll start a PR.

npetersen2 commented 1 year ago

@codecubepi at first pass, I think your waveforms are looking pretty good!

Interesting to see that, at the 10 MHz SPI CLK rate, it takes about 2.5 usec to transfer the data from the sensors. So, at this 100 kHz double update rate PWM, that is about 50% of the total cycle time! This means the max PWM frequency for double update rate is about 200 kHz before the sensors would start dropping samples and things break apart. I think that is fine, just need to make sure it is documented clearly as a limitation (due to the slow diff/single ICs).

npetersen2 commented 1 year ago

@codecubepi for easier review, can you convert all tabs to spaces in your verilog code so it renders nicely on github, thanks

codecubepi commented 1 year ago

@npetersen2 Ah yes I actually saw that last night in VSCode and forgot to fix it before commit. I can take care of that. Thanks!