Skip to content

Commit ce9eb7a

Browse files
nixwardcarlescufi
authored andcommitted
drivers: sensor: bmm150: improve initialisation
Update driver with low level power control and OpMode functions to better represent operations used in power mode transition diagram Figure 2 from the datasheet. This also prepares the driver for use of these functions for PM actions. Extend the soft reset at initialisation to a full POR. Add defines for maximum POR time and start up time. Signed-off-by: Nick Ward <[email protected]>
1 parent 49ff2a5 commit ce9eb7a

File tree

2 files changed

+74
-62
lines changed

2 files changed

+74
-62
lines changed

drivers/sensor/bmm150/bmm150.c

Lines changed: 66 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
/*
44
* Copyright (c) 2017 Intel Corporation
5+
* Copyright (c) 2023 FTP Technologies
56
*
67
* SPDX-License-Identifier: Apache-2.0
78
*/
@@ -80,41 +81,22 @@ int bmm150_reg_update_byte(const struct device *dev, uint8_t reg,
8081
return ret;
8182
}
8283

83-
static int bmm150_set_power_mode(const struct device *dev,
84-
enum bmm150_power_modes mode,
85-
int state)
84+
/* Power control = 'bit' */
85+
static int bmm150_power_control(const struct device *dev, uint8_t bit)
8686
{
87-
switch (mode) {
88-
case BMM150_POWER_MODE_SUSPEND:
89-
if (bmm150_reg_update_byte(dev,
90-
BMM150_REG_POWER,
91-
BMM150_MASK_POWER_CTL,
92-
!state) < 0) {
93-
return -EIO;
94-
}
95-
k_busy_wait(USEC_PER_MSEC * 5U);
96-
97-
return 0;
98-
case BMM150_POWER_MODE_SLEEP:
99-
return bmm150_reg_update_byte(dev,
100-
BMM150_REG_OPMODE_ODR,
101-
BMM150_MASK_OPMODE,
102-
BMM150_MODE_SLEEP <<
103-
BMM150_SHIFT_OPMODE);
104-
break;
105-
case BMM150_POWER_MODE_NORMAL:
106-
return bmm150_reg_update_byte(dev,
107-
BMM150_REG_OPMODE_ODR,
108-
BMM150_MASK_OPMODE,
109-
BMM150_MODE_NORMAL <<
110-
BMM150_SHIFT_OPMODE);
111-
break;
112-
}
113-
114-
return -ENOTSUP;
87+
return bmm150_reg_update_byte(dev, BMM150_REG_POWER,
88+
BMM150_MASK_POWER_CTL, bit);
89+
}
11590

91+
/* OpMode = 'mode' */
92+
static int bmm150_opmode(const struct device *dev, uint8_t mode)
93+
{
94+
return bmm150_reg_update_byte(dev, BMM150_REG_OPMODE_ODR,
95+
BMM150_MASK_OPMODE,
96+
mode << BMM150_SHIFT_OPMODE);
11697
}
11798

99+
118100
static int bmm150_set_odr(const struct device *dev, uint8_t val)
119101
{
120102
uint8_t i;
@@ -515,33 +497,63 @@ static const struct sensor_driver_api bmm150_api_funcs = {
515497
.channel_get = bmm150_channel_get,
516498
};
517499

518-
static int bmm150_init_chip(const struct device *dev)
500+
static int bmm150_full_por(const struct device *dev)
519501
{
520-
struct bmm150_data *data = dev->data;
521-
uint8_t chip_id;
522-
struct bmm150_preset preset;
502+
int ret;
523503

524-
/* Soft reset chip */
525-
if (bmm150_reg_update_byte(dev, BMM150_REG_POWER, BMM150_MASK_SOFT_RESET,
526-
BMM150_SOFT_RESET) < 0) {
527-
LOG_ERR("failed reset chip");
528-
goto err_poweroff;
504+
/* Ensure we are not in suspend mode so soft reset is not ignored */
505+
ret = bmm150_power_control(dev, 1);
506+
if (ret != 0) {
507+
LOG_ERR("failed to ensure not in suspend mode: %d", ret);
508+
return ret;
529509
}
530510

531-
/* Sleep for 1ms after software reset */
532-
k_sleep(K_MSEC(1));
511+
k_sleep(BMM150_START_UP_TIME);
533512

534-
/* Suspend mode to sleep mode */
535-
if (bmm150_set_power_mode(dev, BMM150_POWER_MODE_SUSPEND, 0)
536-
< 0) {
537-
LOG_ERR("failed to bring up device from suspend mode");
538-
return -EIO;
513+
/* Soft reset always brings the device into sleep mode */
514+
ret = bmm150_reg_update_byte(dev, BMM150_REG_POWER,
515+
BMM150_MASK_SOFT_RESET,
516+
BMM150_SOFT_RESET);
517+
if (ret != 0) {
518+
LOG_ERR("failed soft reset: %d", ret);
519+
return ret;
539520
}
540521

541-
/* Sleep for 3ms from suspend to sleep mode */
542-
k_sleep(K_MSEC(3));
522+
/*
523+
* To perform full POR (after soft reset), bring the device into suspend
524+
* mode then back into sleep mode, see datasheet section 5.6
525+
*/
526+
ret = bmm150_power_control(dev, 0);
527+
if (ret != 0) {
528+
LOG_ERR("failed to enter suspend mode: %d", ret);
529+
return ret;
530+
}
531+
532+
k_sleep(BMM150_POR_TIME);
533+
534+
/* Full POR - back into sleep mode */
535+
ret = bmm150_power_control(dev, 1);
536+
if (ret != 0) {
537+
LOG_ERR("failed to go back into sleep mode: %d", ret);
538+
return ret;
539+
}
540+
541+
k_sleep(BMM150_START_UP_TIME);
543542

544-
/* Read chip ID */
543+
return 0;
544+
}
545+
546+
static int bmm150_init_chip(const struct device *dev)
547+
{
548+
struct bmm150_data *data = dev->data;
549+
struct bmm150_preset preset;
550+
uint8_t chip_id;
551+
552+
if (bmm150_full_por(dev) != 0) {
553+
goto err_poweroff;
554+
}
555+
556+
/* Read chip ID (can only be read in sleep mode)*/
545557
if (bmm150_reg_read(dev, BMM150_REG_CHIP_ID, &chip_id, 1) < 0) {
546558
LOG_ERR("failed reading chip id");
547559
goto err_poweroff;
@@ -574,9 +586,8 @@ static int bmm150_init_chip(const struct device *dev)
574586
}
575587

576588
/* Set chip normal mode */
577-
if (bmm150_set_power_mode(dev, BMM150_POWER_MODE_NORMAL, 1)
578-
< 0) {
579-
LOG_ERR("failed to power on device");
589+
if (bmm150_opmode(dev, BMM150_MODE_NORMAL) < 0) {
590+
LOG_ERR("failed to enter normal mode");
580591
}
581592

582593
/* Reads the trim registers of the sensor */
@@ -603,8 +614,8 @@ static int bmm150_init_chip(const struct device *dev)
603614
return 0;
604615

605616
err_poweroff:
606-
bmm150_set_power_mode(dev, BMM150_POWER_MODE_NORMAL, 0);
607-
bmm150_set_power_mode(dev, BMM150_POWER_MODE_SUSPEND, 1);
617+
(void)bmm150_power_control(dev, 0); /* Suspend */
618+
608619
return -EIO;
609620
}
610621

drivers/sensor/bmm150/bmm150.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
/*
44
* Copyright (c) 2017 Intel Corporation
5+
* Copyright (c) 2023 FTP Technologies
56
*
67
* SPDX-License-Identifier: Apache-2.0
78
*/
@@ -116,7 +117,7 @@ extern const struct bmm150_bus_io bmm150_bus_io_i2c;
116117
#define BMM150_REG_INT_DRDY 0x4E
117118
#define BMM150_MASK_DRDY_EN BIT(7)
118119
#define BMM150_SHIFT_DRDY_EN 7
119-
#define BMM150_DRDY_INT3 BIT(6)
120+
#define BMM150_DRDY_INT3 BIT(6)
120121
#define BMM150_MASK_DRDY_Z_EN BIT(5)
121122
#define BMM150_MASK_DRDY_Y_EN BIT(4)
122123
#define BMM150_MASK_DRDY_X_EN BIT(3)
@@ -164,12 +165,6 @@ struct bmm150_data {
164165
int sample_x, sample_y, sample_z;
165166
};
166167

167-
enum bmm150_power_modes {
168-
BMM150_POWER_MODE_SUSPEND,
169-
BMM150_POWER_MODE_SLEEP,
170-
BMM150_POWER_MODE_NORMAL
171-
};
172-
173168
enum bmm150_axis {
174169
BMM150_AXIS_X,
175170
BMM150_AXIS_Y,
@@ -196,6 +191,12 @@ enum bmm150_presets {
196191
#define BMM150_DEFAULT_PRESET BMM150_HIGH_ACCURACY_PRESET
197192
#endif
198193

194+
/* Power On Reset time - from OFF to Suspend (Max) */
195+
#define BMM150_POR_TIME K_MSEC(1)
196+
197+
/* Start-Up Time - from suspend to sleep (Max) */
198+
#define BMM150_START_UP_TIME K_MSEC(3)
199+
199200
int bmm150_reg_update_byte(const struct device *dev, uint8_t reg,
200201
uint8_t mask, uint8_t value);
201202

0 commit comments

Comments
 (0)