diff --git a/Kconfig b/Kconfig index b1a8819..0db838a 100644 --- a/Kconfig +++ b/Kconfig @@ -28,12 +28,18 @@ config PMW3610_INVERT_X config PMW3610_INVERT_Y bool "Invert the Y axis of PMW3610 sensor" -config PMW3610_INIT_POWER_UP_EXTRA_DELAY_MS - int "Extra power up init delay (ms)" - default 0 +config PMW3610_INIT_RETRY_COUNT + int "Number of times to retry PMW3610 init" + default 50 help - Default minimum init power up delay is 10ms. - Use this config to postpone init power up sequence if needs longer bootup time. + How many times the driver should attempt to re-initialize + the PMW3610 sensor if initialization fails. + +config PMW3610_INIT_RETRY_DELAY_MS + int "Delay between retries (ms)" + default 100 + help + How long the driver waits between retry attempts in milliseconds. config PMW3610_REPORT_INTERVAL_MIN int "PMW3610's default minimum report rate" diff --git a/README.md b/README.md index a402f9c..74dcd90 100644 --- a/README.md +++ b/README.md @@ -116,9 +116,6 @@ CONFIG_PMW3610=y # CONFIG_PMW3610_INVERT_Y=y // <-- deprecated, use invert-y; instead # CONFIG_PMW3610_REPORT_INTERVAL_MIN=12 # CONFIG_PMW3610_LOG_LEVEL_DBG=y -# CONFIG_PMW3610_INIT_POWER_UP_EXTRA_DELAY_MS=300 // <--see Troubleshooting +# CONFIG_PMW3610_INIT_RETRY_COUNT=50 +# CONFIG_PMW3610_INIT_RETRY_DELAY_MS=100 ``` - -## Troubleshooting - -If you are getting `Incorrect product id 0xFF (expecting 0x3E)!` on `nice_nano_v2` board from the log, you'd want to apply `CONFIG_PMW3610_INIT_POWER_UP_EXTRA_DELAY_MS=1000` in your shield .conf/.overlay file. Due to this driver doesn't offer module dependancy setting, that would ensure external power (to enable VCC pin on board) is ready, the `CONFIG_PMW3610_INIT_POWER_UP_EXTRA_DELAY_MS` would use to add extra one second delay of power up. diff --git a/dts/bindings/pixart,pmw3610.yml b/dts/bindings/cyboard,pmw3610.yml similarity index 86% rename from dts/bindings/pixart,pmw3610.yml rename to dts/bindings/cyboard,pmw3610.yml index 2400a47..c515fd4 100644 --- a/dts/bindings/pixart,pmw3610.yml +++ b/dts/bindings/cyboard,pmw3610.yml @@ -1,7 +1,7 @@ description: | - Sensor driver for the pixart PMW3610 mouse sensor + Sensor driver for the pixart PMW3610 mouse sensor -compatible: "pixart,pmw3610" +compatible: "cyboard,pmw3610" include: spi-device.yaml diff --git a/src/pixart.h b/src/pixart.h index 70fccfd..77c7f4f 100644 --- a/src/pixart.h +++ b/src/pixart.h @@ -28,6 +28,7 @@ struct pixart_data { bool ready; // whether init is finished successfully int err; // error code during async init + int retries; // number of retries of the initialization sequence }; // device config data structure diff --git a/src/pmw3610.c b/src/pmw3610.c index 8df7c04..8242ade 100644 --- a/src/pmw3610.c +++ b/src/pmw3610.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: MIT */ -#define DT_DRV_COMPAT pixart_pmw3610 +#define DT_DRV_COMPAT cyboard_pmw3610 #include #include @@ -34,7 +34,7 @@ enum pmw3610_init_step { // - Since MCU is not involved in the sensor init process, i is allowed to do other tasks. // Thus, k_sleep or delayed schedule can be used. static const int32_t async_init_delay[ASYNC_INIT_STEP_COUNT] = { - [ASYNC_INIT_STEP_POWER_UP] = 10 + CONFIG_PMW3610_INIT_POWER_UP_EXTRA_DELAY_MS, // >10ms needed + [ASYNC_INIT_STEP_POWER_UP] = 10, // >10ms needed [ASYNC_INIT_STEP_CLEAR_OB1] = 200, // 150 us required, test shows too short, // also power-up reset is added in this step, thus using 50 ms [ASYNC_INIT_STEP_CHECK_OB1] = 50, // 10 ms required in spec, @@ -450,6 +450,23 @@ static void pmw3610_async_init(struct k_work *work) { data->err = async_init_fn[data->async_init_step](dev); if (data->err) { LOG_ERR("PMW3610 initialization failed in step %d", data->async_init_step); + + /* If we haven’t exceeded our retry budget, reset to step 0 and try again */ + if (data->retries < CONFIG_PMW3610_INIT_RETRY_COUNT) { + data->retries++; + data->async_init_step = 0; + LOG_WRN("Retrying PMW3610 init (attempt %d/%d) in %d ms...", + data->retries, + CONFIG_PMW3610_INIT_RETRY_COUNT, + CONFIG_PMW3610_INIT_RETRY_DELAY_MS); + + /* Schedule the next attempt after a delay */ + k_work_schedule(&data->init_work, + K_MSEC(CONFIG_PMW3610_INIT_RETRY_DELAY_MS)); + } else { + LOG_ERR("PMW3610 init failed after %d retries; giving up.", data->retries); + /* At this point, we do NOT re-schedule, so init stops. data->ready stays false */ + } } else { data->async_init_step++; @@ -729,7 +746,7 @@ DT_INST_FOREACH_STATUS_OKAY(PMW3610_DEFINE) #define GET_PMW3610_DEV(node_id) DEVICE_DT_GET(node_id), static const struct device *pmw3610_devs[] = { - DT_FOREACH_STATUS_OKAY(pixart_pmw3610, GET_PMW3610_DEV) + DT_FOREACH_STATUS_OKAY(cyboard_pmw3610, GET_PMW3610_DEV) }; static int on_activity_state(const zmk_event_t *eh) {