diff --git a/app/drivers/sensor/pmw33xx/pmw33xx.c b/app/drivers/sensor/pmw33xx/pmw33xx.c index 1d07d2ef..af016781 100644 --- a/app/drivers/sensor/pmw33xx/pmw33xx.c +++ b/app/drivers/sensor/pmw33xx/pmw33xx.c @@ -1,5 +1,3 @@ - - #define DT_DRV_COMPAT pixart_pmw33xx #include @@ -22,344 +20,326 @@ LOG_MODULE_REGISTER(PMW33XX, CONFIG_SENSOR_LOG_LEVEL); #define PMW33XX_PID COND_CODE_1(CONFIG_PMW33XX_3389, (PMW33XX_3389_PID), (PMW33XX_3360_PID)) +#define PMW33XX_CPI_MAX \ + COND_CODE_1(CONFIG_PMW33XX_3389, (PMW33XX_3389_CPI_MAX), (PMW33XX_3360_CPI_MAX)) +#define PMW33XX_CPI_MIN \ + COND_CODE_1(CONFIG_PMW33XX_3389, (PMW33XX_3389_CPI_MIN), (PMW33XX_3360_CPI_MIN)) struct pmw33xx_motion_burst { - uint8_t motion; - uint8_t observation; - int16_t dx; - int16_t dy; + uint8_t motion; + uint8_t observation; + int16_t dx; + int16_t dy; } __attribute__((packed)); static inline int pmw33xx_cs_select(const struct pmw33xx_gpio_dt_spec *cs_gpio_cfg, - const uint8_t value) -{ - return gpio_pin_set(cs_gpio_cfg->port, cs_gpio_cfg->pin, value); + const uint8_t value) { + return gpio_pin_set(cs_gpio_cfg->port, cs_gpio_cfg->pin, value); } -static int pmw33xx_access(const struct device *dev, const uint8_t reg, uint8_t *value) -{ - struct pmw33xx_data *data = dev->data; - const struct pmw33xx_config *cfg = dev->config; - const struct spi_config *spi_cfg = &cfg->bus_cfg.spi_cfg->spi_conf; - const struct pmw33xx_gpio_dt_spec *cs_gpio_cfg = &cfg->bus_cfg.spi_cfg->cs_spec; +static int pmw33xx_access(const struct device *dev, const uint8_t reg, uint8_t *value) { + struct pmw33xx_data *data = dev->data; + const struct pmw33xx_config *cfg = dev->config; + const struct spi_config *spi_cfg = &cfg->bus_cfg.spi_cfg->spi_conf; + const struct pmw33xx_gpio_dt_spec *cs_gpio_cfg = &cfg->bus_cfg.spi_cfg->cs_spec; - uint8_t access[1] = { reg }; - struct spi_buf_set tx = { - .buffers = { &(struct spi_buf){ - .buf = access, - .len = 1, - } }, - .count = 1, - }; - uint8_t result[1] = { *value }; - struct spi_buf_set rx = { - .buffers = { &(struct spi_buf){ - .buf = result, - .len = 1, - } }, - .count = 1, - }; + uint8_t access[1] = {reg}; + struct spi_buf_set tx = { + .buffers = + &(struct spi_buf){ + .buf = access, + .len = 1, + }, + .count = 1, + }; + uint8_t result[1] = {*value}; + struct spi_buf_set rx = { + .buffers = + &(struct spi_buf){ + .buf = result, + .len = 1, + }, + .count = 1, + }; - pmw33xx_cs_select(cs_gpio_cfg, 0); + pmw33xx_cs_select(cs_gpio_cfg, 0); - int err = spi_write(data->bus, spi_cfg, &tx); - k_sleep(K_USEC(120)); //Tsrad - if (err) { - pmw33xx_cs_select(cs_gpio_cfg, 1); - return err; - } + int err = spi_write(data->bus, spi_cfg, &tx); + k_sleep(K_USEC(120)); // Tsrad + if (err) { + pmw33xx_cs_select(cs_gpio_cfg, 1); + return err; + } - if ((reg & PMW33XX_WR_MASK)) - err = spi_write(data->bus, spi_cfg, &rx); - else - err = spi_read(data->bus, spi_cfg, &rx); - pmw33xx_cs_select(cs_gpio_cfg, 1); - k_sleep(K_USEC(160)); - if ((reg & PMW33XX_WR_MASK) == 0) - *value = result[0]; - return err; + if ((reg & PMW33XX_WR_MASK)) + err = spi_write(data->bus, spi_cfg, &rx); + else + err = spi_read(data->bus, spi_cfg, &rx); + pmw33xx_cs_select(cs_gpio_cfg, 1); + k_sleep(K_USEC(160)); + if ((reg & PMW33XX_WR_MASK) == 0) + *value = result[0]; + return err; } -static int pmw33xx_read_reg(const struct device *dev, const uint8_t reg, uint8_t *value) -{ - return pmw33xx_access(dev, reg & PMW33XX_RD_MASK, value); +static int pmw33xx_read_reg(const struct device *dev, const uint8_t reg, uint8_t *value) { + return pmw33xx_access(dev, reg & PMW33XX_RD_MASK, value); } -static int pmw33xx_write_reg(const struct device *dev, const uint8_t reg, const uint8_t value) -{ - uint8_t v = value; - return pmw33xx_access(dev, reg | PMW33XX_WR_MASK, &v); +static int pmw33xx_write_reg(const struct device *dev, const uint8_t reg, const uint8_t value) { + uint8_t v = value; + return pmw33xx_access(dev, reg | PMW33XX_WR_MASK, &v); } -static int pmw33xx_write_srom(const struct device *dev) -{ - struct pmw33xx_data *data = dev->data; - const struct pmw33xx_config *cfg = dev->config; - const struct spi_config *spi_cfg = &cfg->bus_cfg.spi_cfg->spi_conf; - const struct pmw33xx_gpio_dt_spec *cs_gpio_cfg = &cfg->bus_cfg.spi_cfg->cs_spec; - uint8_t access[1] = { PMW33XX_REG_SROM_BURST | PMW33XX_WR_MASK }; - struct spi_buf_set tx = { - .buffers = { &(struct spi_buf){ - .buf = access, - .len = 1, - } }, - .count = 1, - }; +static int pmw33xx_write_srom(const struct device *dev) { + struct pmw33xx_data *data = dev->data; + const struct pmw33xx_config *cfg = dev->config; + const struct spi_config *spi_cfg = &cfg->bus_cfg.spi_cfg->spi_conf; + const struct pmw33xx_gpio_dt_spec *cs_gpio_cfg = &cfg->bus_cfg.spi_cfg->cs_spec; + uint8_t access[1] = {PMW33XX_REG_SROM_BURST | PMW33XX_WR_MASK}; + struct spi_buf_set tx = { + .buffers = + &(struct spi_buf){ + .buf = access, + .len = 1, + }, + .count = 1, + }; - pmw33xx_write_reg(dev, PMW33XX_REG_SROM_EN, PMW33XX_SROM_DWNLD_CMD); - k_sleep(K_USEC(15)); - pmw33xx_write_reg(dev, PMW33XX_REG_SROM_EN, PMW33XX_SROM_DWNLD_START_CMD); + pmw33xx_write_reg(dev, PMW33XX_REG_SROM_EN, PMW33XX_SROM_DWNLD_CMD); + k_sleep(K_USEC(15)); + pmw33xx_write_reg(dev, PMW33XX_REG_SROM_EN, PMW33XX_SROM_DWNLD_START_CMD); - pmw33xx_cs_select(cs_gpio_cfg, 0); + pmw33xx_cs_select(cs_gpio_cfg, 0); - int err = spi_write(data->bus, spi_cfg, &tx); + int err = spi_write(data->bus, spi_cfg, &tx); - k_sleep(K_USEC(15)); - if (err) { - pmw33xx_cs_select(cs_gpio_cfg, 1); - return err; - } + k_sleep(K_USEC(15)); + if (err) { + pmw33xx_cs_select(cs_gpio_cfg, 1); + return err; + } - for (uint16_t i = 0; i < sizeof(SROM); i++) { - access[0] = SROM[i]; - err = spi_write(data->bus, spi_cfg, &tx); - k_sleep(K_USEC(15)); - if (err) { - pmw33xx_cs_select(cs_gpio_cfg, 1); - return err; - } - } + for (uint16_t i = 0; i < sizeof(SROM); i++) { + access[0] = SROM[i]; + err = spi_write(data->bus, spi_cfg, &tx); + k_sleep(K_USEC(15)); + if (err) { + pmw33xx_cs_select(cs_gpio_cfg, 1); + return err; + } + } - pmw33xx_cs_select(cs_gpio_cfg, 1); - k_sleep(K_MSEC(2)); //Tbexit - return err; + pmw33xx_cs_select(cs_gpio_cfg, 1); + k_sleep(K_MSEC(2)); // Tbexit + return err; } -static int pmw33xx_read_motion_burst(const struct device *dev, struct pmw33xx_motion_burst *burst) -{ - struct pmw33xx_data *data = dev->data; - const struct pmw33xx_config *cfg = dev->config; - const struct spi_config *spi_cfg = &cfg->bus_cfg.spi_cfg->spi_conf; - const struct pmw33xx_gpio_dt_spec *cs_gpio_cfg = &cfg->bus_cfg.spi_cfg->cs_spec; +static int pmw33xx_read_motion_burst(const struct device *dev, struct pmw33xx_motion_burst *burst) { + struct pmw33xx_data *data = dev->data; + const struct pmw33xx_config *cfg = dev->config; + const struct spi_config *spi_cfg = &cfg->bus_cfg.spi_cfg->spi_conf; + const struct pmw33xx_gpio_dt_spec *cs_gpio_cfg = &cfg->bus_cfg.spi_cfg->cs_spec; - uint8_t access[1] = { PMW33XX_REG_BURST }; - struct spi_buf_set tx = { - .buffers = { &(struct spi_buf){ - .buf = access, - .len = 1, - } }, - .count = 1, - }; - struct spi_buf_set rx = { - .buffers = { &(struct spi_buf){ - .buf = (uint8_t *)burst, - .len = sizeof(struct pmw33xx_motion_burst), - } }, - .count = 1, - }; + uint8_t access[1] = {PMW33XX_REG_BURST}; + struct spi_buf_set tx = { + .buffers = + &(struct spi_buf){ + .buf = access, + .len = 1, + }, + .count = 1, + }; + struct spi_buf_set rx = { + .buffers = + &(struct spi_buf){ + .buf = (uint8_t *)burst, + .len = sizeof(struct pmw33xx_motion_burst), + }, + .count = 1, + }; - pmw33xx_cs_select(cs_gpio_cfg, 0); + pmw33xx_cs_select(cs_gpio_cfg, 0); - int err = spi_write(data->bus, spi_cfg, &tx); - k_sleep(K_USEC(35)); // tsrad motbr - if (err) { - pmw33xx_cs_select(cs_gpio_cfg, 1); - return err; - } - err = spi_read(data->bus, spi_cfg, &rx); - pmw33xx_cs_select(cs_gpio_cfg, 1); - return err; + int err = spi_write(data->bus, spi_cfg, &tx); + k_sleep(K_USEC(35)); // tsrad motbr + if (err) { + pmw33xx_cs_select(cs_gpio_cfg, 1); + return err; + } + err = spi_read(data->bus, spi_cfg, &rx); + pmw33xx_cs_select(cs_gpio_cfg, 1); + return err; } -// converts twos complement data to an int16 -static int16_t pmw33xx_raw_to_int16(const uint8_t src[2]) -{ - int16_t res = sys_get_be16(src); - if (res > BIT_MASK(15)) - res -= BIT(16); - return res; +int pmw33xx_spi_init(const struct device *dev) { + const struct pmw33xx_config *cfg = dev->config; + const struct pmw33xx_gpio_dt_spec *cs_gpio_cfg = &cfg->bus_cfg.spi_cfg->cs_spec; + + int err; + err = gpio_pin_configure(cs_gpio_cfg->port, cs_gpio_cfg->pin, GPIO_OUTPUT_ACTIVE); + if (err) { + LOG_ERR("could configure cs pin %d", err); + return -EIO; + } + return 0; } -static int pmw33xx_read_raw(const struct device *dev, const uint8_t reg_high, const uint8_t reg_low, - int16_t *value) -{ - uint8_t raw[2] = { 0x0, 0x0 }; - int err; - err = pmw33xx_read_reg(dev, reg_high, &raw[0]); - if (err) { - LOG_ERR("could not read high byte at %x", reg_high); - return err; - } - k_sleep(K_USEC(100)); - err = pmw33xx_read_reg(dev, reg_low, &raw[1]); - if (err) { - LOG_ERR("could not read low byte at %x", reg_low); - return err; - } - k_sleep(K_USEC(100)); - *value = pmw33xx_raw_to_int16(raw); - return 0; -} +static int pmw33xx_sample_fetch(const struct device *dev, enum sensor_channel chan) { + struct pmw33xx_data *data = dev->data; + struct pmw33xx_motion_burst burst; -int pmw33xx_spi_init(const struct device *dev) -{ - struct pmw33xx_data *data = dev->data; - const struct pmw33xx_config *cfg = dev->config; - const struct pmw33xx_spi_cfg *spi_cfg = cfg->bus_cfg.spi_cfg; - const struct pmw33xx_gpio_dt_spec *cs_gpio_cfg = &cfg->bus_cfg.spi_cfg->cs_spec; + if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_POS_DX && chan != SENSOR_CHAN_POS_DY) + return -ENOTSUP; - int err; - err = gpio_pin_configure(cs_gpio_cfg->port, cs_gpio_cfg->pin, GPIO_OUTPUT_ACTIVE); - if (err) { - LOG_ERR("could configure cs pin %d", err); - return -EIO; - } - return 0; -} - -static int pmw33xx_sample_fetch(const struct device *dev, enum sensor_channel chan) -{ - struct pmw33xx_data *data = dev->data; - const struct pmw33xx_config *cfg = dev->config; - struct pmw33xx_motion_burst burst; - - if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_POS_DX && chan != SENSOR_CHAN_POS_DY) - return -ENOTSUP; - - int err = pmw33xx_read_motion_burst(dev, &burst); - if (err) { - return err; - } - if (chan == SENSOR_CHAN_ALL || chan == SENSOR_CHAN_POS_DX) - data->dx = burst.dx; - if (chan == SENSOR_CHAN_ALL || chan == SENSOR_CHAN_POS_DY) - data->dy = burst.dy; - return 0; + int err = pmw33xx_read_motion_burst(dev, &burst); + if (err) { + return err; + } + if (chan == SENSOR_CHAN_ALL || chan == SENSOR_CHAN_POS_DX) + data->dx += burst.dx; + if (chan == SENSOR_CHAN_ALL || chan == SENSOR_CHAN_POS_DY) + data->dy += burst.dy; + return 0; } static int pmw33xx_channel_get(const struct device *dev, enum sensor_channel chan, - struct sensor_value *val) -{ - struct pmw33xx_data *data = dev->data; - const struct pmw33xx_config *cfg = dev->config; + struct sensor_value *val) { + struct pmw33xx_data *data = dev->data; - switch (chan) { - case SENSOR_CHAN_POS_DX: - val->val1 = data->dx; - data->dx = 0; - break; - case SENSOR_CHAN_POS_DY: - val->val1 = data->dy; - data->dy = 0; - break; - default: - return -ENOTSUP; - } + switch (chan) { + case SENSOR_CHAN_POS_DX: + val->val1 = data->dx; + data->dx = 0; + break; + case SENSOR_CHAN_POS_DY: + val->val1 = data->dy; + data->dy = 0; + break; + default: + return -ENOTSUP; + } - return 0; + return 0; } static const struct sensor_driver_api pmw33xx_driver_api = { #ifdef CONFIG_PMW33XX_TRIGGER - .trigger_set = pmw33xx_trigger_set, + .trigger_set = pmw33xx_trigger_set, #endif - // .attr_set = pmw33xx_attr_set, - .sample_fetch = pmw33xx_sample_fetch, - .channel_get = pmw33xx_channel_get, + // eventually implement this to allow setting cpi from the driver api maybe + // .attr_set = pmw33xx_attr_set, + .sample_fetch = pmw33xx_sample_fetch, + .channel_get = pmw33xx_channel_get, }; -static int pmw33xx_init_chip(const struct device *dev) -{ - struct pmw33xx_data *data = dev->data; - return 0; +static int pmw33xx_set_cpi(const struct device *dev, uint16_t cpi) { +#ifdef CONFIG_PMW33XX_3360 + if (cpi > PMW33XX_CPI_MIN && cpi < PMW33XX_CPI_MAX) + return pmw33xx_write_reg(dev, PMW33XX_3360_REG_CPI, + ((cpi / 100) - 1)); /* 100-12000, 100 cpi LSb */ +#elif CONFIG_PMW33XX_3389 + if (cpi > PMW33XX_CPI_MIN && cpi < PMW33XX_CPI_MAX) { + cpi /= 50; + int err = + pmw33xx_write_reg(dev, PMW33XX_3389_REG_CPI_L, cpi & 0xFF); /* 50-16000, 50 cpi LSb */ + if (err) { + return err; + } + return pmw33xx_write_reg(dev, PMW33XX_3389_REG_CPI_H, cpi >> 8); /* 50-16000, 50 cpi LSb */ + } +#endif + return -ENOTSUP; +} +static int pmw33xx_init_chip(const struct device *dev) { + const struct pmw33xx_config *const config = dev->config; + const struct pmw33xx_gpio_dt_spec *cs_gpio_cfg = &config->bus_cfg.spi_cfg->cs_spec; + pmw33xx_cs_select(cs_gpio_cfg, 1); + k_sleep(K_MSEC(1)); + + int err = pmw33xx_write_reg(dev, PMW33XX_REG_PWR_UP_RST, PMW33XX_RESET_CMD); + if (err) { + LOG_ERR("could not reset %d", err); + return -EIO; + } + uint8_t pid = 0x0; + err = pmw33xx_read_reg(dev, PMW33XX_REG_PID, &pid); + if (err) { + LOG_ERR("could not reset %d", err); + return -EIO; + } + if (pid != PMW33XX_PID) { + LOG_ERR("pid does not match expected: got (%x), expected(%x)", pid, PMW33XX_PID); + return -EIO; + } + pmw33xx_write_reg(dev, PMW33XX_REG_CONFIG2, 0x00); // clear rest enable + + err = pmw33xx_write_srom(dev); + if (err) { + LOG_ERR("could not upload srom %d", err); + return -EIO; + } + uint8_t srom_run = 0x0; + err = pmw33xx_read_reg(dev, PMW33XX_REG_OBSERVATION, &srom_run); + if (err) { + LOG_ERR("could not check srom status %d", err); + return -EIO; + } + if (!(srom_run & PMW33XX_SROM_RUN)) { + LOG_ERR("srom status invalid %d", srom_run); + return -EIO; + } + + uint8_t srom_id = 0x0; + err = pmw33xx_read_reg(dev, PMW33XX_REG_SROM_ID, &srom_id); + if (err) { + LOG_ERR("could not check srom id %d", err); + return -EIO; + } + if (!srom_id) { + LOG_ERR("srom id invalid %d", srom_id); + return -EIO; + } + + pmw33xx_write_reg(dev, PMW33XX_REG_CONFIG2, 0x00); // clear rest enable + pmw33xx_write_reg(dev, PMW33XX_REG_BURST, 0x01); // clear rest enable + struct pmw33xx_motion_burst val; + pmw33xx_read_motion_burst(dev, &val); // read and throwout initial motion data + + if (config->cpi > PMW33XX_CPI_MIN && config->cpi < PMW33XX_CPI_MAX) + return pmw33xx_set_cpi(dev, config->cpi); + return 0; } -static int pmw33xx_init(const struct device *dev) -{ - const struct pmw33xx_config *const config = dev->config; - struct pmw33xx_data *data = dev->data; +static int pmw33xx_init(const struct device *dev) { + const struct pmw33xx_config *const config = dev->config; + struct pmw33xx_data *data = dev->data; - data->bus = device_get_binding(config->bus_name); - if (!data->bus) { - LOG_DBG("master not found: %s", log_strdup(config->bus_name)); - return -EINVAL; - } + data->bus = device_get_binding(config->bus_name); + if (!data->bus) { + LOG_DBG("master not found: %s", log_strdup(config->bus_name)); + return -EINVAL; + } - config->bus_init(dev); + config->bus_init(dev); - if (pmw33xx_init_chip(dev) < 0) { - LOG_DBG("failed to initialize chip"); - return -EIO; - } - - const struct pmw33xx_gpio_dt_spec *cs_gpio_cfg = &config->bus_cfg.spi_cfg->cs_spec; + if (pmw33xx_init_chip(dev) < 0) { + LOG_DBG("failed to initialize chip"); + return -EIO; + } #ifdef CONFIG_PMW33XX_TRIGGER - if (pmw33xx_init_interrupt(dev) < 0) { - LOG_DBG("Failed to initialize interrupt!"); - return -EIO; - } + if (pmw33xx_init_interrupt(dev) < 0) { + LOG_DBG("Failed to initialize interrupt!"); + return -EIO; + } #endif - pmw33xx_cs_select(cs_gpio_cfg, 1); - k_sleep(K_MSEC(1)); - - int err = pmw33xx_write_reg(dev, PMW33XX_REG_PWR_UP_RST, PMW33XX_RESET_CMD); - if (err) { - LOG_ERR("could not reset %d", err); - return -EIO; - } - uint8_t pid = 0x0; - err = pmw33xx_read_reg(dev, PMW33XX_REG_PID, &pid); - if (err) { - LOG_ERR("could not reset %d", err); - return -EIO; - } - if (pid != PMW33XX_PID) { - LOG_ERR("pid does not match expected: got (%x), expected(%x)", pid, PMW33XX_PID); - return -EIO; - } - pmw33xx_write_reg(dev, PMW33XX_REG_CONFIG2, 0x00); // clear rest enable - - err = pmw33xx_write_srom(dev); - if (err) { - LOG_ERR("could not upload srom %d", err); - return -EIO; - } - uint8_t srom_run = 0x0; - err = pmw33xx_read_reg(dev, PMW33XX_REG_OBSERVATION, &srom_run); - if (err) { - LOG_ERR("could not check srom status %d", err); - return -EIO; - } - if (!(srom_run & PMW33XX_SROM_RUN)) { - LOG_ERR("srom status invalid %d", srom_run); - return -EIO; - } - - uint8_t srom_id = 0x0; - err = pmw33xx_read_reg(dev, PMW33XX_REG_SROM_ID, &srom_id); - if (err) { - LOG_ERR("could not check srom id %d", err); - return -EIO; - } - if (!srom_id) { - LOG_ERR("srom id invalid %d", srom_id); - return -EIO; - } - - pmw33xx_write_reg(dev, PMW33XX_REG_CONFIG2, 0x00); // clear rest enable - pmw33xx_write_reg(dev, PMW33XX_REG_BURST, 0x01); // clear rest enable - struct pmw33xx_motion_burst val; - pmw33xx_read_motion_burst(dev, &val); // read and throwout initial motion data - - return 0; + return 0; } #define PMW33XX_DATA_SPI(n) \ - { \ - .cs_ctrl = {}, \ - } + { .cs_ctrl = {}, } #define PMW33XX_SPI_CFG(n) \ - (&(struct pmw33xx_spi_cfg){ \ + (&(struct pmw33xx_spi_cfg){ \ .spi_conf = \ { \ .frequency = DT_INST_PROP(n, spi_max_frequency), \ @@ -367,30 +347,30 @@ static int pmw33xx_init(const struct device *dev) (SPI_WORD_SET(8) | SPI_OP_MODE_MASTER | SPI_MODE_CPOL | SPI_MODE_CPHA), \ .slave = DT_INST_REG_ADDR(n), \ }, \ - .cs_spec = PMW33XX_GPIO_DT_SPEC_GET_BY_IDX(DT_DRV_INST(n), cs_gpios, 0), \ + .cs_spec = PMW33XX_GPIO_DT_SPEC_GET_BY_IDX(DT_DRV_INST(n), cs_gpios, 0), \ }) #define PMW33XX_GPIO_DT_SPEC_GET_BY_IDX(node_id, prop, idx) \ - { \ - .port = DEVICE_DT_GET(DT_GPIO_CTLR_BY_IDX(node_id, prop, idx)), \ - .pin = DT_GPIO_PIN_BY_IDX(node_id, prop, idx), \ - .dt_flags = DT_GPIO_FLAGS_BY_IDX(node_id, prop, idx), \ - } + { \ + .port = DEVICE_DT_GET(DT_GPIO_CTLR_BY_IDX(node_id, prop, idx)), \ + .pin = DT_GPIO_PIN_BY_IDX(node_id, prop, idx), \ + .dt_flags = DT_GPIO_FLAGS_BY_IDX(node_id, prop, idx), \ + } #define PMW33XX_CONFIG_SPI(n) \ - { \ - .bus_name = DT_INST_BUS_LABEL(n), .bus_init = pmw33xx_spi_init, \ - .bus_cfg = { .spi_cfg = PMW33XX_SPI_CFG(n) }, \ - COND_CODE_1(CONFIG_MA730_TRIGGER, \ - (, PMW33XX_GPIO_DT_SPEC_GET_BY_IDX(DT_DRV_INST(n), motswk_gpios, 0)), \ - ()) \ - } + { \ + .bus_name = DT_INST_BUS_LABEL(n), .bus_init = pmw33xx_spi_init, \ + .bus_cfg = {.spi_cfg = PMW33XX_SPI_CFG(n)}, \ + COND_CODE_0(DT_INST_NODE_HAS_PROP(n, cpi), (0), (DT_INST_PROP(n, cpi))) \ + COND_CODE_1(CONFIG_PMW33XX_TRIGGER, \ + (PMW33XX_GPIO_DT_SPEC_GET_BY_IDX(DT_DRV_INST(n), motswk_gpios, 0)), ()) \ + } #define PMW33XX_INST(n) \ - static struct pmw33xx_data pmw33xx_data_##n = PMW33XX_DATA_SPI(n); \ - static const struct pmw33xx_config pmw33xx_cfg_##n = PMW33XX_CONFIG_SPI(n); \ - DEVICE_DT_INST_DEFINE(n, pmw33xx_init, device_pm_control_nop, &pmw33xx_data_##n, \ - &pmw33xx_cfg_##n, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \ - &pmw33xx_driver_api); + static struct pmw33xx_data pmw33xx_data_##n = PMW33XX_DATA_SPI(n); \ + static const struct pmw33xx_config pmw33xx_cfg_##n = PMW33XX_CONFIG_SPI(n); \ + DEVICE_DT_INST_DEFINE(n, pmw33xx_init, device_pm_control_nop, &pmw33xx_data_##n, \ + &pmw33xx_cfg_##n, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \ + &pmw33xx_driver_api); DT_INST_FOREACH_STATUS_OKAY(PMW33XX_INST) diff --git a/app/drivers/sensor/pmw33xx/pmw33xx.h b/app/drivers/sensor/pmw33xx/pmw33xx.h index 31b28944..6bab327d 100644 --- a/app/drivers/sensor/pmw33xx/pmw33xx.h +++ b/app/drivers/sensor/pmw33xx/pmw33xx.h @@ -65,6 +65,11 @@ /* power up reset cmd */ #define PMW33XX_RESET_CMD 0x5A +#define PMW33XX_3389_CPI_MIN 50 +#define PMW33XX_3389_CPI_MAX 16000 +#define PMW33XX_3360_CPI_MIN 100 +#define PMW33XX_3360_CPI_MAX 12000 + struct pmw33xx_gpio_dt_spec { const struct device *port; gpio_pin_t pin; @@ -84,7 +89,7 @@ struct pmw33xx_config { char *bus_name; int (*bus_init)(const struct device *dev); const union pmw33xx_bus_cfg bus_cfg; - int resolution; + int cpi; #if CONFIG_PMW33XX_TRIGGER struct pmw33xx_gpio_dt_spec motswk_spec; #endif // CONFIG_PMW33XX_TRIGGER diff --git a/app/drivers/sensor/pmw33xx/pmw33xx_trigger.c b/app/drivers/sensor/pmw33xx/pmw33xx_trigger.c index 9451a330..92c8a05e 100644 --- a/app/drivers/sensor/pmw33xx/pmw33xx_trigger.c +++ b/app/drivers/sensor/pmw33xx/pmw33xx_trigger.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: MIT */ -#define DT_DRV_COMPAT pixart_pmw3389 +#define DT_DRV_COMPAT pixart_pmw33xx #include #include @@ -12,119 +12,113 @@ #include #include -#include "pmw3389.h" +#include "pmw33xx.h" -// extern struct pmw3389_data pmw3389_driver; +// extern struct pmw33xx_data pmw33xx_driver; #include -LOG_MODULE_DECLARE(PMW3389, CONFIG_SENSOR_LOG_LEVEL); +LOG_MODULE_DECLARE(PMW33XX, CONFIG_SENSOR_LOG_LEVEL); -static inline void setup_int(const struct device *dev, bool enable) -{ - struct pmw3389_data *data = dev->data; - const struct pmw3389_config *cfg = dev->config; +static inline void setup_int(const struct device *dev, bool enable) { + struct pmw33xx_data *data = dev->data; + const struct pmw33xx_config *cfg = dev->config; - if (gpio_pin_interrupt_configure(cfg->motswk_spec.port, cfg->motswk_spec.pin, - enable ? GPIO_INT_EDGE_TO_ACTIVE : GPIO_INT_DISABLE)) { - LOG_WRN("Unable to set MOTSWK GPIO interrupt"); - } + if (gpio_pin_interrupt_configure(cfg->motswk_spec.port, cfg->motswk_spec.pin, + enable ? GPIO_INT_EDGE_TO_ACTIVE : GPIO_INT_DISABLE)) { + LOG_WRN("Unable to set MOTSWK GPIO interrupt"); + } } -static void pmw3389_motswk_gpio_callback(const struct device *dev, struct gpio_callback *cb, - uint32_t pins) -{ - struct pmw3389_data *drv_data = CONTAINER_OF(cb, struct pmw3389_data, motswk_gpio_cb); +static void pmw33xx_motswk_gpio_callback(const struct device *dev, struct gpio_callback *cb, + uint32_t pins) { + struct pmw33xx_data *drv_data = CONTAINER_OF(cb, struct pmw33xx_data, motswk_gpio_cb); - LOG_DBG(""); + LOG_DBG(""); - setup_int(drv_data->dev, false); + setup_int(drv_data->dev, false); -#if defined(CONFIG_PMW3389_TRIGGER_OWN_THREAD) - k_sem_give(&drv_data->gpio_sem); -#elif defined(CONFIG_PMW3389_TRIGGER_GLOBAL_THREAD) - k_work_submit(&drv_data->work); +#if defined(CONFIG_PMW33XX_TRIGGER_OWN_THREAD) + k_sem_give(&drv_data->gpio_sem); +#elif defined(CONFIG_PMW33XX_TRIGGER_GLOBAL_THREAD) + k_work_submit(&drv_data->work); #endif } -static void pmw3389_thread_cb(const struct device *dev) -{ - struct pmw3389_data *drv_data = dev->data; +static void pmw33xx_thread_cb(const struct device *dev) { + struct pmw33xx_data *drv_data = dev->data; - LOG_DBG("%p", drv_data->handler); - drv_data->handler(dev, drv_data->trigger); + LOG_DBG("%p", drv_data->handler); + drv_data->handler(dev, drv_data->trigger); - // Enable once the wall/spam of interrupts is solved - setup_int(dev, true); + // Enable once the wall/spam of interrupts is solved + setup_int(dev, true); } -#ifdef CONFIG_PMW3389_TRIGGER_OWN_THREAD -static void pmw3389_thread(int dev_ptr, int unused) -{ - const struct device *dev = INT_TO_POINTER(dev_ptr); - struct pmw3389_data *drv_data = dev->data; +#ifdef CONFIG_PMW33XX_TRIGGER_OWN_THREAD +static void pmw33xx_thread(int dev_ptr, int unused) { + const struct device *dev = INT_TO_POINTER(dev_ptr); + struct pmw33xx_data *drv_data = dev->data; - ARG_UNUSED(unused); + ARG_UNUSED(unused); - while (1) { - k_sem_take(&drv_data->gpio_sem, K_FOREVER); - pmw3389_thread_cb(dev); - } + while (1) { + k_sem_take(&drv_data->gpio_sem, K_FOREVER); + pmw33xx_thread_cb(dev); + } } #endif -#ifdef CONFIG_PMW3389_TRIGGER_GLOBAL_THREAD -static void pmw3389_work_cb(struct k_work *work) -{ - struct pmw3389_data *drv_data = CONTAINER_OF(work, struct pmw3389_data, work); +#ifdef CONFIG_PMW33XX_TRIGGER_GLOBAL_THREAD +static void pmw33xx_work_cb(struct k_work *work) { + struct pmw33xx_data *drv_data = CONTAINER_OF(work, struct pmw33xx_data, work); - LOG_DBG(""); + LOG_DBG(""); - pmw3389_thread_cb(drv_data->dev); + pmw33xx_thread_cb(drv_data->dev); } #endif -int pmw3389_trigger_set(const struct device *dev, const struct sensor_trigger *trig, - sensor_trigger_handler_t handler) -{ - struct pmw3389_data *drv_data = dev->data; +int pmw33xx_trigger_set(const struct device *dev, const struct sensor_trigger *trig, + sensor_trigger_handler_t handler) { + struct pmw33xx_data *drv_data = dev->data; - setup_int(dev, false); + setup_int(dev, false); - k_msleep(5); + k_msleep(5); - drv_data->trigger = trig; - drv_data->handler = handler; + drv_data->trigger = trig; + drv_data->handler = handler; - setup_int(dev, true); + setup_int(dev, true); - return 0; + return 0; } -int pmw3389_init_interrupt(const struct device *dev) -{ - struct pmw3389_data *drv_data = dev->data; - const struct pmw3389_config *drv_cfg = dev->config; +int pmw33xx_init_interrupt(const struct device *dev) { + struct pmw33xx_data *drv_data = dev->data; + const struct pmw33xx_config *drv_cfg = dev->config; - drv_data->dev = dev; - /* setup gpio interrupt */ + drv_data->dev = dev; + /* setup gpio interrupt */ - gpio_init_callback(&drv_data->motswk_gpio_cb, pmw3389_motswk_gpio_callback, - BIT(drv_cfg->motswk_spec.pin)); + gpio_init_callback(&drv_data->motswk_gpio_cb, pmw33xx_motswk_gpio_callback, + BIT(drv_cfg->motswk_spec.pin)); - if (gpio_add_callback(drv_cfg->motswk_spec.port, &drv_data->motswk_gpio_cb) < 0) { - LOG_DBG("Failed to set MOTSWK callback!"); - return -EIO; - } + int err = gpio_add_callback(drv_cfg->motswk_spec.port, &drv_data->motswk_gpio_cb); + if (err < 0) { + LOG_DBG("Failed to set MOTSWK callback!"); + return -EIO; + } -#if defined(CONFIG_PMW3389_TRIGGER_OWN_THREAD) - k_sem_init(&drv_data->gpio_sem, 0, UINT_MAX); +#if defined(CONFIG_PMW33XX_TRIGGER_OWN_THREAD) + k_sem_init(&drv_data->gpio_sem, 0, UINT_MAX); - k_thread_create(&drv_data->thread, drv_data->thread_stack, CONFIG_PMW3389_THREAD_STACK_SIZE, - (k_thread_entry_t)pmw3389_thread, dev, 0, NULL, - K_PRIO_COOP(CONFIG_PMW3389_THREAD_PRIORITY), 0, K_NO_WAIT); -#elif defined(CONFIG_PMW3389_TRIGGER_GLOBAL_THREAD) - k_work_init(&drv_data->work, pmw3389_work_cb); + k_thread_create(&drv_data->thread, drv_data->thread_stack, CONFIG_PMW33XX_THREAD_STACK_SIZE, + (k_thread_entry_t)pmw33xx_thread, dev, 0, NULL, + K_PRIO_COOP(CONFIG_PMW33XX_THREAD_PRIORITY), 0, K_NO_WAIT); +#elif defined(CONFIG_PMW33XX_TRIGGER_GLOBAL_THREAD) + k_work_init(&drv_data->work, pmw33xx_work_cb); #endif - return 0; + return 0; }