Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

When attempting the MCP23008 smoke test, the GPIOs are not toggled. By measuring the I2C wires with an oscilloscope, I noticed the clock signal was constantly 3.3 V. I eventually found that the pin on the mezzanine connector on the BMS carrier was not soldered to the PCB. I quickly checked the other pins on that side and found a few other pins that were not soldered to the PCB, including the current sense MOSI. After soldering these pins, the MCP23008 smoke test correctly toggles and reads the values of the GPIOs. The only issue is that after the GPIOs are initialized, values that are read for the first time after the values GPIOs are read, they initialized are wrong.

Expand
titleHere's the output showing the incorrect values being read.

Version: 298bdac-dirty
[0] projects/smoke_mcp23008/src/main.c:100: Testing GPIO initialization...
[0] projects/smoke_mcp23008/src/main.c:101: Initializing all pins out...
[0] projects/smoke_mcp23008/src/main.c:62: State for pin 0 set and read correctly
[0] projects/smoke_mcp23008/src/main.c:62: State for pin 1 set and read correctly
[0] projects/smoke_mcp23008/src/main.c:62: State for pin 2 set and read correctly
[0] projects/smoke_mcp23008/src/main.c:62: State for pin 3 set and read correctly
[0] projects/smoke_mcp23008/src/main.c:62: State for pin 4 set and read correctly
[0] projects/smoke_mcp23008/src/main.c:62: State for pin 5 set and read correctly
[0] projects/smoke_mcp23008/src/main.c:62: State for pin 6 set and read correctly
[0] projects/smoke_mcp23008/src/main.c:62: State for pin 7 set and read correctly
[0] projects/smoke_mcp23008/src/main.c:104: GPIO initialization complete. Now beginnin
[0] projects/smoke_mcp23008/src/main.c:83: State for pin 0 incorrectly
[0] projects/smoke_mcp23008/src/main.c:83: State for pin 1 incorrectly
[0] projects/smoke_mcp23008/src/main.c:83: State for pin 2 incorrectly
[0] projects/smoke_mcp23008/src/main.c:83: State for pin 3 incorrectly
[0] projects/smoke_mcp23008/src/main.c:83: State for pin 4 incorrectly
[0] projects/smoke_mcp23008/src/main.c:83: State for pin 5 incorrectly
[0] projects/smoke_mcp23008/src/main.c:83: State for pin 6 incorrectly
[0] projects/smoke_mcp23008/src/main.c:83: State for pin 7 incorrectly
[0] projects/smoke_mcp23008/src/main.c:87: GPIO state = low

By modifying the MCP23008 smoke test, I set the HSD diagnostic and select pins high, and activated the LV relay, then read the analog current value. Before activating the relay, the current is 0 and after, the current is about 1525. The current sense output was measured to be 1.17 V using a handheld DMM. I’m not sure how to convert the analog value to a voltage, but I think the value is about 1.23 V. I’ll double check these numbers later. The relay is supposed to draw about 18.3 mA when it’s closed, which based on the HSD current sense circuit, should result in a voltage of 1.21 V (18.3 mA * 5.3 kOhm / 80), which is close to the measured values. The kill switch monitor also correctly detects whether the relay is on or off.\

I initially thought that SPI communications were not working because the ADS1259 smoke test in master was not returning anything. I used an oscilloscope and watched the SPI signals after running the smoke test and the voltages did not change at all. I checked for shorts to adjacent pins and ground, and for continuity between the pins on the mezzanine connector and the LTC6820. Everything seemed fine. Later, I realized that the version on master was not the same as the version I used to validate current sense (specifically, there was no baudrate set so SPI initialization was failing and hence no signals).

Expand
titleThis is the output using the version I used for current sense validation.

Version: d5cb3e5-dirty
smoke test initializing ads1259
ads1259 post init register values:
reg 0: 0x25
reg 1: 0xc0
reg 2: 0x93
reg 3: 0x0
reg 4: 0x0
reg 5: 0x0
reg 6: 0x0
reg 7: 0x0
reg 8: 0x40
ads1259 driver init all ok
=========READING # 1========= vref mv: 2500
read: chksum: 0x53, lil endian: [bb fe ff]
raw reading as a float: 0xb8c80000
*1: 0, *10: 0, *100: 0, *1000: 0
=========READING # 2========= vref mv: 2500
read: chksum: 0x19, lil endian: [80 ff ff]
raw reading as a float: 0xb8200000
*1: 0, *10: 0, *100: 0, *1000: 0
=========READING # 3========= vref mv: 2500
read: chksum: 0x60, lil endian: [47 ff ff]
raw reading as a float: 0xb85c0000
*1: 0, *10: 0, *100: 0, *1000: 0
=========READING # 4========= vref mv: 2500
read: chksum: 0x7c, lil endian: [63 ff ff]
raw reading as a float: 0xb8340000
*1: 0, *10: 0, *100: 0, *1000: 0
=========READING # 5========= vref mv: 2500
read: chksum: 0x60, lil endian: [47 ff ff]
raw reading as a float: 0xb85c0000
*1: 0, *10: 0, *100: 0, *1000: 0
=========READING # 6========= vref mv: 2500
read: chksum: 0x15, lil endian: [fd fe ff]
raw reading as a float: 0xb8a00000
*1: 0, *10: 0, *100: 0, *1000: 0

When I ran the smoke test for the ADT7476A, and then measured the output PWM signal, the signal was a constant 3.3 V instead of the duty cycle increasing by 10 % every second. I confirmed that the correct commands were being transmitted using an oscilloscope on the SDA and SCL signals. I noticed that the commands being sent were in the form device address, register address, device address, value (more on this later). After looking at the code for a bit, I decided to use the I2C smoke test instead to validate the ADT7476A because it’s much simpler. For the first step, I tried writing to a register and reading it back. I initially used the PWM 1 duty cycle register, but it appears to be locked since the value wasn’t changing. I was able to successfully read the default value 0xFF. Instead, I tried writing to the configuration register because I happened to notice in the datasheet that it has a STRT bit that must be set to 1 to enable monitoring of the fan speeds. Otherwise, it sets the fans to 100% for safety reasons. I was able to write to this register and read the result after a few tries. I found out that even though registers are being written to, the i2c_write_reg command cannot be used and the regular i2c_write command must be used instead. This is because the device is expecting commands in the form device address, register address, data, but the i2c_write_reg command writes data using the form mentioned previously. I suspect this is caused by the fact that the device is designed to use SMBus, which is compatible with I2C, but not the same. Despite writing to this register, I was still unable to write to the PWM signal register. At this point, I looked back at the ADT7476A smoke test and was reminded that the PWM configuration register needs to be configured to allow for manual control of the fan, which it is not by default. So after writing the correct value to this register, I was able to write to the PWM duty cycle register. I then validated that the actual PWM output was consistent with the value written to the register by measuring it with an oscilloscope. Now that changing the PWM duty cycle is working, I decided to experiment with changing some values and checking the result to confirm which factors allow or prevent changing the PWM duty cycle.

Expand
titleHere’s a list of observations that may or may not be useful:
  1. If the STRT bit in the configuration register is set to 0, the PWM duty cycle register cannot be written to, however there appears to be a buffer register because after attempting to write to the PWM duty cycle register and then setting the STRT bit back to 1, the PWM duty cycle is automatically updated with the value.

  2. Setting the full speed bit of the configuration register doesn’t change the value in the PWM duty cycle register.

  3. Setting the mode to something other than manual mode does change the value in the PWM duty cycle register. The value is set back to the original value once the mode is set back to manual mode.

To read the tachometer registers after the device has been powered on, the STRT bit in the configuration register needs to be set to 1 and the upper byte must be read first because the device automatically reads the lower byte to lock the register. Once doing these two things, I was able to read the tachometer measurements from a digital waveform generator.

Expand
titleThis table summarizes the tachometer measurements.

Waveform Frequency

Imitated Fan Speed

Tachometer Value

Tachometer RPM

Error

100 Hz

3,000 RPM

0x0710

2,986.73 RPM

0.44 %

200 Hz

6,000 RPM

0x0388

5,973.45 RPM

0.44 %

100 kHz

3,000,000 RPM

0x0171

14,634.15 RPM

99.51 %

This is faster than the internal clock frequency (90 kHz), so it’s expected that the results are wrong.