Forum breadcrumbs - You are here:ForumEVC2: MiscellaneousPMD ADC Details
Please or Register to create posts and topics.

PMD ADC Details

Hello,

Thanks for making PMD, it is a well-engineered and useful product.

Since EVC2 doesn't exactly meet our needs, we are using a standard MCU board for logging current and voltage data from PMD over I2C. We hope to share details with the community once the project is completed.

One question is related to the PMD ADC sample rate at which you are updating internal current / voltage measurements. PMD documentation mentions a sample rate "up to 10 ksps". My guess is that you indicate the 10 ksps rate based on the maximum I2C bandwidth @ 400 kbps (1 byte request + 2 byte reply + overhead =~ 10 ksps @ 400 kbps), not necessarily the ADC sample rate (which is hopefully faster than 10 ksps?). Can you share the ADC sample rate? It will help us to quantify aliasing error.

Thanks,

Shawn

Quote from shawn on 2022-04-22, 04:47

Hello,

Thanks for making PMD, it is a well-engineered and useful product.

Since EVC2 doesn't exactly meet our needs, we are using a standard MCU board for logging current and voltage data from PMD over I2C. We hope to share details with the community once the project is completed.

One question is related to the PMD ADC sample rate at which you are updating internal current / voltage measurements. PMD documentation mentions a sample rate "up to 10 ksps". My guess is that you indicate the 10 ksps rate based on the maximum I2C bandwidth @ 400 kbps (1 byte request + 2 byte reply + overhead =~ 10 ksps @ 400 kbps), not necessarily the ADC sample rate (which is hopefully faster than 10 ksps?). Can you share the ADC sample rate? It will help us to quantify aliasing error.

Thanks,

Shawn

Hello Shawn,

I'm glad you like the product and happy to see extended use cases. You're correct in that the sample rate is limited by the I2C interface. There's a revision in progress with USB connectivity instead. The MCU ADC is configured for continuous sampling at 285.7 KHz (3.5 us sample time) with DMA transfer to SRAM, which is directly read over I2C. You also need to consider that the values are read through an analog mux (NCP45491) which has 8 channels (4x voltage + current), so the effective sample rate of each value is 35.7 KHz internally to the MCU.

Let me know if you have additional questions.

/Jon

Hi Jon (Elmor),

Thanks for the info.

We have been experimenting more with the I2C interface and it is working mostly well. But we have discovered some cases where the reported current has some unexplained error.

In our test setup, we are providing constant 12V from an external DC power supply to the PCIE1 input side of PMD, and we have a load generator pulling constant 1A from the PCIE1 output side of PMD. We are constantly reading back PCIE1 Current via I2C (tested 400 kbps and 100 kbps with similar results).

Nominally we are reading back a reported raw current of 013h +/- 2, which translates to 912 mA +/- 96 mA. That seems a bit low but we can adjust it with calibration / offset parameters, no problem.

But there are two very specific troublesome cases which rarely occur (estimated rate 1 per 100 samples, at irregular / seemly random intervals).

Case 1 - Under-measure: In this case, bit 4 of the reported raw current reads 0b (instead of expected 1b). So we see raw current values like 003h, 004h, 002h, etc, when we hit this case. It's interesting that we don't ever see values like 008h, 009h, 00ah, etc., which to me indicates this might be some kind of bit flip issue.

Case 2 - Over-measure: In this case, bits 3, 2, 1, and 0 of the reported raw current read 1111b / fh (instead of the expected 3h +/- 2). So we see raw current values of 01fh when we hit this case, and again it's interesting that we don't see values like 01eh or 01dh.. so again it doesn't merely look like a measurement error but rather bits inexplicably getting set high.

When I noticed this issue, my first action was to look at the I2C signals with a scope, and the problematic transactions do seem to match the description above for real. I can provide scope captures if they might be helpful.

Have you observed similar cases with the EVC2 I2C master?

If it's helpful, I can conduct additional experiments / data gathering. Just let me know.

Thanks,

Shawn

Quote from shawn on 2022-04-28, 05:45

Hi Jon (Elmor),

Thanks for the info.

We have been experimenting more with the I2C interface and it is working mostly well. But we have discovered some cases where the reported current has some unexplained error.

In our test setup, we are providing constant 12V from an external DC power supply to the PCIE1 input side of PMD, and we have a load generator pulling constant 1A from the PCIE1 output side of PMD. We are constantly reading back PCIE1 Current via I2C (tested 400 kbps and 100 kbps with similar results).

Nominally we are reading back a reported raw current of 013h +/- 2, which translates to 912 mA +/- 96 mA. That seems a bit low but we can adjust it with calibration / offset parameters, no problem.

But there are two very specific troublesome cases which rarely occur (estimated rate 1 per 100 samples, at irregular / seemly random intervals).

Case 1 - Under-measure: In this case, bit 4 of the reported raw current reads 0b (instead of expected 1b). So we see raw current values like 003h, 004h, 002h, etc, when we hit this case. It's interesting that we don't ever see values like 008h, 009h, 00ah, etc., which to me indicates this might be some kind of bit flip issue.

Case 2 - Over-measure: In this case, bits 3, 2, 1, and 0 of the reported raw current read 1111b / fh (instead of the expected 3h +/- 2). So we see raw current values of 01fh when we hit this case, and again it's interesting that we don't see values like 01eh or 01dh.. so again it doesn't merely look like a measurement error but rather bits inexplicably getting set high.

When I noticed this issue, my first action was to look at the I2C signals with a scope, and the problematic transactions do seem to match the description above for real. I can provide scope captures if they might be helpful.

Have you observed similar cases with the EVC2 I2C master?

If it's helpful, I can conduct additional experiments / data gathering. Just let me know.

Thanks,

Shawn

Hi Shawn,

ADC data being read back is 12-bit and left hand aligned, first byte reads [3:0] as bits [7:4] and second byte reads [11:4] as [7:0]. As this issue happens around this split, it seems suspicious to me. Possibly the ADC DMA transfer happening at the same time as I2C reading or similar? I have some example code here with EVC2 for your reference: https://github.com/eelmor/PMDLogger/blob/master/PMDLogger/Program.cs

There's additional registers available for reading the ADC data quickly that you can try to debug this, I just realized those are not documented in the current datasheet. These commands allows you to continuously read a single value without restart or re-writing the offset. If it works ok to read the single byte values that should verify the I2C connection is ok. If 2 byte values still cause issues, it may be related to when ADC DMA updates values or similar.

0x80-0x8F reads 2 bytes continuously and resets pointer after reading the second byte, ie: PCIE1 Voltage LSB, PCIE1 Voltage MSB, PCIE1 Voltage LSB ...

0x80 = PCIE1 Voltage LSB + MSB
0x82 = PCIE1 Current LSB + MSB
0x84 = PCIE2 Voltage LSB + MSB
...

0x90 - 0x97 reads 1 byte (ADC data [11:4]) continuously, ie: PCIE1 Voltage MSB, PCIE1 Voltage MSB ...

0x90 = PCIE1 Voltage MSB
0x91 = PCIE1 Current MSB
0x92 = PCIE2 Voltage MSB
...

/Jon

Hi Jon,

Thanks for the info. Those additional registers may come in useful.

I have done some additional testing and I think I have a reasonable explanation for the issue (similar to "ADC DMA transfer happening at the same time as I2C reading or similar", as you previously suggested).

For our test setup, we constructed a histogram and recorded the frequency of each raw 12-bit value read over I2C (which is stretched over 2 I2C byte reads, as you know). Here is some brief sample code to get the idea:

int hist[4096] = {0};
int count = 0;

...

while (1) {

  i2c_transfer(i2c_dev, ...);

  ...

  uint16_t val = (rd_data[1] << 4) + (rd_data[0] >> 4);

  hist[val]++;

  count++;

  ...

  // Print out histogram when count == 100000.

Here is our histogram for the fixed load setup I previously mentioned, with load = 600ma:

0006: 26
0007: 471
0008: 4882
0009: 20386
000a: 35442
000b: 27910
000c: 9386
000d: 1413
000e: 81
000f: 3

It is completely reasonable. Now here is 1200ma fixed load:

0012: 16
0013: 298
0014: 3235
0015: 14111
0016: 26986
0017: 29669
0018: 18954
0019: 5907
001a: 767
001b: 54
001c: 3

It is also fine. But here is 1000ma:

0000: 3
0001: 40
0002: 113
0003: 136
0004: 85
0005: 23
0006: 2
0007: 0
0008: 0
0009: 0
000a: 0
000b: 0
000c: 0
000d: 0
000e: 7
000f: 78
0010: 3494
0011: 15962
0012: 31540
0013: 29870
0014: 14904
0015: 3122
0016: 284
0017: 8
0018: 0
0019: 0
001a: 0
001b: 0
001c: 0
001d: 0
001e: 12
001f: 317

It is problematic. Maybe it can be explained by something similar to the following sequence:

t1: ADC conversion for PCIe1 Current completes, value = 00fh.

t2: I2C request for PCIe1 Current, so load the latest value LSB (00fh = fh = transmit as f0h) into the I2C Tx register.

t3: ADC conversion for PCIe1 Current completes again, value = 010h this time.

t4: I2C Tx of LSB completes.

t5: Another I2C read request for PCIe1 Current, so load the latest value MSB (010h = 01h = transmit as 01h) into the I2C Tx register.

t6: I2C Tx of MSB completes.

So from the I2C master point of view, it just received 01fh for the current, which is not correct. Basically the root cause is that the MSB and LSB received did not come from the same ADC conversion, they came from two different conversions.

What do you think?

Thanks,

Shawn

Quote from shawn on 2022-05-04, 01:59

Hi Jon,

Thanks for the info. Those additional registers may come in useful.

I have done some additional testing and I think I have a reasonable explanation for the issue (similar to "ADC DMA transfer happening at the same time as I2C reading or similar", as you previously suggested).

For our test setup, we constructed a histogram and recorded the frequency of each raw 12-bit value read over I2C (which is stretched over 2 I2C byte reads, as you know). Here is some brief sample code to get the idea:

int hist[4096] = {0};
int count = 0;

...

while (1) {

  i2c_transfer(i2c_dev, ...);

  ...

  uint16_t val = (rd_data[1] << 4) + (rd_data[0] >> 4);

  hist[val]++;

  count++;

  ...

  // Print out histogram when count == 100000.

Here is our histogram for the fixed load setup I previously mentioned, with load = 600ma:

0006: 26
0007: 471
0008: 4882
0009: 20386
000a: 35442
000b: 27910
000c: 9386
000d: 1413
000e: 81
000f: 3

It is completely reasonable. Now here is 1200ma fixed load:

0012: 16
0013: 298
0014: 3235
0015: 14111
0016: 26986
0017: 29669
0018: 18954
0019: 5907
001a: 767
001b: 54
001c: 3

It is also fine. But here is 1000ma:

0000: 3
0001: 40
0002: 113
0003: 136
0004: 85
0005: 23
0006: 2
0007: 0
0008: 0
0009: 0
000a: 0
000b: 0
000c: 0
000d: 0
000e: 7
000f: 78
0010: 3494
0011: 15962
0012: 31540
0013: 29870
0014: 14904
0015: 3122
0016: 284
0017: 8
0018: 0
0019: 0
001a: 0
001b: 0
001c: 0
001d: 0
001e: 12
001f: 317

It is problematic. Maybe it can be explained by something similar to the following sequence:

t1: ADC conversion for PCIe1 Current completes, value = 00fh.

t2: I2C request for PCIe1 Current, so load the latest value LSB (00fh = fh = transmit as f0h) into the I2C Tx register.

t3: ADC conversion for PCIe1 Current completes again, value = 010h this time.

t4: I2C Tx of LSB completes.

t5: Another I2C read request for PCIe1 Current, so load the latest value MSB (010h = 01h = transmit as 01h) into the I2C Tx register.

t6: I2C Tx of MSB completes.

So from the I2C master point of view, it just received 01fh for the current, which is not correct. Basically the root cause is that the MSB and LSB received did not come from the same ADC conversion, they came from two different conversions.

What do you think?

Thanks,

Shawn

Hi Shawn,

Yes that looks like what I was suspecting. As I see it, there are a couple of options to deal with this:

  • Read only the 8-bit ADC value (MSB) which results in lower resolution
  • Update the firmware of the device to deal with this issue. Would require a programmer such as J-Link, would you have access to that?
  • Wait for the upcoming version of PMD with USB interface that can solve this issue, it'll be available in about 4-6 weeks
shawn has reacted to this post.
shawn

Hi Jon,

Thanks for looking into it. We can definitely get a programmer to try new FW once it is available. Would one of these programmers be appropriate?

https://www.mouser.com/ProductDetail/Microchip-Technology/ATATMEL-ICE?qs=KLFHFgXTQiDAUrt43H15kQ%3D%3D&mgh=1&gclid=CjwKCAjw9-KTBhBcEiwAr19ig8UIQifNGlHxUFUigNz5CE71nYIeIn9w1gwMt0gdUbAL7VqfmOwlFhoCQBsQAvD_BwE

J-Link BASE Classic (8.08.00)

http://dangerousprototypes.com/docs/Bus_Blaster

Thanks,

Shawn

Checking closer, it seems this might be the preferred debugger / programmer for SAMD10:

J-32 Debug Probe - https://www.microchip.com/en-us/development-tool/DV164232. Is it similar to what you use on your side?

Thanks,

Shawn

Quote from shawn on 2022-05-10, 01:11

Checking closer, it seems this might be the preferred debugger / programmer for SAMD10:

J-32 Debug Probe - https://www.microchip.com/en-us/development-tool/DV164232. Is it similar to what you use on your side?

Thanks,

Shawn

Hello Shawn, anything capable of SWD access should work. I'd recommend a cheap CMSIS-DAP adapter if you just want to use it for programming the firmware (ex https://www.ebay.com/itm/294642898839?hash=item449a15d797:g:0-gAAOSwZ11g8TpA).

Otherwise I'd probably recommend the J-32 over Atmel ICE.

/Jon

Hi Jon,

Thanks for the recommendation, it is much cheaper than the ones I linked. I ordered one and I expect it will arrive in 1-2 weeks, at which time we will be able to flash and test the new PMD FW.

BTW here is what we have been working on w/ PMD: https://github.com/rivosinc/pcie-power-logger. Maybe it is useful to the community.

Thanks,

Shawn