Skip to content

stm32/boards/OPENMVPT: Fix white illuminator default state and Lepton reset - #149

Open
kwagyeman wants to merge 2 commits into
openmv:openmv-1.29.0from
kwagyeman:kwabena/openmvpt_board_fixes
Open

kwagyeman wants to merge 2 commits into
openmv:openmv-1.29.0from
kwagyeman:kwabena/openmvpt_board_fixes

Conversation

@kwagyeman

Copy link
Copy Markdown
Member

Two independent OPENMVPT board fixes, both found while debugging an LTDC
issue on a bench board and both verified on hardware.

Stop turning the white illuminator on at boot

MICROPY_HW_LED4 mapped the white LED to PG3, but that pin is not wired
like the other three. Red, green and blue drive an HSMF-C116 whose common
pin ties to 3V3 through 220R, so they are active low, which is what the
board's MICROPY_HW_LED_ON()/OFF() macros assume. PG3 instead gates a
PMZ390UN N-channel MOSFET with a 100K pulldown on its gate, so the white
LED is active high.

So MICROPY_HW_LED_OFF() drove PG3 high and switched the MOSFET on:
led_init() lit the illuminator on every boot and left it on. It is not a
status LED, it is a CLP6B-WKW rated 3 x 50mA drawing 100mA through R120 off
the 5V rail.

The polarity macros are board-wide and correct for the RGB LED, and the
stm32 port has no per-LED polarity hook, so PG3 is left out of the LED
table. Nothing then configures the pin, it stays high impedance out of
reset, and R142 holds the gate low.

This also removes an inverted API: pyb.LED(4).on() turned the illuminator
off and .off() turned it on. No example uses LED(4) on this board.
Pin("LED_WHITE") remains available for deliberate control.

Verified on hardware: PG3 comes up mode=analog, ODR=0.

Actually reset the Lepton at boot

board_early_init() drove LEPTON_RSTN straight high and never pulsed it
low, and released it before starting MCLK. Both are wrong for this part: it
wants its master clock present when RESET_L is released, and it never
receives a reset at all.

A cold power-up POR hides this. Once the Lepton is confused it becomes
unrecoverable: it still ACKs its I2C address so the probe detects it, but
its status register never reads LEPTON_I2C_STATUS_BOOT, so
lepton_config() times out and omv_csi_init() returns
OMV_CSI_ERROR_CSI_INIT_FAILED. main() treats anything other than
OMV_CSI_ERROR_ISC_UNDETECTED as fatal, and this happens before USB is
brought up, so the board stops enumerating entirely - no CDC, no REPL, no
way in short of SWD - and every subsequent MCU reset runs this same code
and leaves the part exactly as it was.

Observed on a bench board that stayed in this state across MCU resets, an
nRST pin reset, toggling the shared CSI power/reset rail, and a physical
power cycle. Pulsing RSTN low by hand brought it straight back, which is
what led to the fix.

Hold RSTN low, release powerdown, start MCLK, spin past the 5000 clock
periods the part requires, then release RSTN. SystemClock_Config() has
not run this early, hence the spin rather than mp_hal_delay_ms().

Verified on hardware: Lepton enumerates at 160x120, thermal frames capture,
and the full thermal overlay demo path runs at 17.9fps.

MICROPY_HW_LED4 mapped the white LED to PG3, but that pin is not wired
like the other three. Red, green and blue drive an HSMF-C116 whose
common pin ties to 3V3 through 220R, so they are active low, which is
what the board's MICROPY_HW_LED_ON()/OFF() macros assume. PG3 instead
gates a PMZ390UN N-channel MOSFET with a 100K pulldown on its gate, so
the white LED is active high.

The result is that MICROPY_HW_LED_OFF() drives PG3 high and switches the
MOSFET on, so led_init() lights the illuminator on every boot and leaves
it on. It is not a status LED: it is a CLP6B-WKW rated 3 x 50mA, drawing
100mA through R120 off the 5V rail.

The polarity macros are board-wide and correct for the RGB LED, and the
stm32 port has no per-LED polarity hook, so the fix is to leave PG3 out
of the LED table. Nothing then configures the pin, it stays high
impedance out of reset, and R142 holds the gate low, which is off.

This also removes an inverted API: pyb.LED(4).on() turned the
illuminator off and .off() turned it on. No example uses LED(4) on this
board. Driving it deliberately is machine.Pin("G3", machine.Pin.OUT).
board_early_init() drove LEPTON_RSTN straight high and never pulsed it
low, and released it before starting MCLK. Both are wrong for this part:
it wants its master clock present when RESET_L is released, and it never
receives a reset at all.

On a cold power-up POR hides this. Once the Lepton is confused it is
unrecoverable: it still ACKs its I2C address, so the probe detects it,
but its status register never reads LEPTON_I2C_STATUS_BOOT, so
lepton_config() times out and omv_csi_init() returns
OMV_CSI_ERROR_CSI_INIT_FAILED. main() treats anything other than
OMV_CSI_ERROR_ISC_UNDETECTED as fatal, and this happens before USB is
brought up, so the board stops enumerating entirely - no CDC, no REPL,
no way in short of SWD - and every subsequent MCU reset runs this same
code and leaves the part exactly as it was.

Observed on a bench board that stayed in this state across MCU resets,
an nRST pin reset, toggling the shared CSI power/reset rail, and a
physical power cycle. Pulsing RSTN low by hand brought it straight back.

Hold RSTN low, release powerdown, start MCLK, spin past the 5000 clock
periods the part requires, then release RSTN. SystemClock_Config() has
not run this early, hence the spin rather than mp_hal_delay_ms().

Verified on hardware: Lepton enumerates at 160x120 and the full thermal
overlay demo path runs at 17.9fps.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant