Skip to content
Permalink
Browse files

drivers: nrf: Add power management to nrf TWIM peripheral.

Add power management to nrf TWIM peripheral.

Signed-off-by: Mieszko Mierunski <mieszko.mierunski@nordicsemi.no>
  • Loading branch information...
Mierunski authored and carlescufi committed Jun 5, 2019
1 parent c9aaab7 commit 05cdd285cfbc844555c4f69b0af5dc9307ac0712
Showing with 66 additions and 24 deletions.
  1. +66 −24 drivers/i2c/i2c_nrfx_twim.c
@@ -18,10 +18,12 @@ struct i2c_nrfx_twim_data {
struct k_sem transfer_sync;
struct k_sem completion_sync;
volatile nrfx_err_t res;
uint32_t dev_config;
};

struct i2c_nrfx_twim_config {
nrfx_twim_t twim;
nrfx_twim_config_t config;
};

static inline struct i2c_nrfx_twim_data *get_dev_data(struct device *dev)
@@ -128,6 +130,7 @@ static int i2c_nrfx_twim_configure(struct device *dev, u32_t dev_config)
LOG_ERR("unsupported speed");
return -EINVAL;
}
get_dev_data(dev)->dev_config = dev_config;

return 0;
}
@@ -137,20 +140,58 @@ static const struct i2c_driver_api i2c_nrfx_twim_driver_api = {
.transfer = i2c_nrfx_twim_transfer,
};

static int init_twim(struct device *dev, const nrfx_twim_config_t *config)
static int init_twim(struct device *dev)
{

nrfx_err_t result = nrfx_twim_init(&get_dev_config(dev)->twim, config,
event_handler, dev);
nrfx_err_t result = nrfx_twim_init(&get_dev_config(dev)->twim,
&get_dev_config(dev)->config,
event_handler,
dev);
if (result != NRFX_SUCCESS) {
LOG_ERR("Failed to initialize device: %s",
dev->config->name);
dev->config->name);
return -EBUSY;
}


return 0;
}

#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
static int twim_nrfx_pm_control(struct device *dev, u32_t ctrl_command,
void *context, device_pm_cb cb, void *arg)
{
static u32_t current_state = DEVICE_PM_ACTIVE_STATE;

if (ctrl_command == DEVICE_PM_SET_POWER_STATE) {
u32_t new_state = *((const u32_t *)context);

if (new_state != current_state) {
switch (new_state) {
case DEVICE_PM_ACTIVE_STATE:
init_twim(dev);
i2c_nrfx_twim_configure(
dev, get_dev_data(dev)->dev_config);
break;

default:
nrfx_twim_uninit(&get_dev_config(dev)->twim);
break;
}
current_state = new_state;
}
} else {
assert(ctrl_command == DEVICE_PM_GET_POWER_STATE);
*((u32_t *)context) = current_state;
}

if (cb) {
cb(dev, 0, context, arg);
}

return 0;
}
#endif /* CONFIG_DEVICE_POWER_MANAGEMENT */

#define I2C_NRFX_TWIM_INVALID_FREQUENCY ((nrf_twim_frequency_t)-1)
#define I2C_NRFX_TWIM_FREQUENCY(bitrate) \
(bitrate == I2C_BITRATE_STANDARD ? NRF_TWIM_FREQ_100K \
@@ -169,31 +210,32 @@ static int init_twim(struct device *dev, const nrfx_twim_config_t *config)
IRQ_CONNECT(DT_NORDIC_NRF_I2C_I2C_##idx##_IRQ_0, \
DT_NORDIC_NRF_I2C_I2C_##idx##_IRQ_0_PRIORITY, \
nrfx_isr, nrfx_twim_##idx##_irq_handler, 0); \
const nrfx_twim_config_t config = { \
.scl = DT_NORDIC_NRF_I2C_I2C_##idx##_SCL_PIN, \
.sda = DT_NORDIC_NRF_I2C_I2C_##idx##_SDA_PIN, \
.frequency = I2C_NRFX_TWIM_FREQUENCY( \
DT_NORDIC_NRF_I2C_I2C_##idx##_CLOCK_FREQUENCY) \
}; \
return init_twim(dev, &config); \
return init_twim(dev); \
} \
static struct i2c_nrfx_twim_data twim_##idx##_data = { \
.transfer_sync = Z_SEM_INITIALIZER( \
.transfer_sync = Z_SEM_INITIALIZER( \
twim_##idx##_data.transfer_sync, 1, 1), \
.completion_sync = Z_SEM_INITIALIZER( \
.completion_sync = Z_SEM_INITIALIZER( \
twim_##idx##_data.completion_sync, 0, 1) \
}; \
static const struct i2c_nrfx_twim_config twim_##idx##z_config = { \
.twim = NRFX_TWIM_INSTANCE(idx) \
static const struct i2c_nrfx_twim_config twim_##idx##z_config = { \
.twim = NRFX_TWIM_INSTANCE(idx), \
.config = { \
.scl = DT_NORDIC_NRF_I2C_I2C_##idx##_SCL_PIN, \
.sda = DT_NORDIC_NRF_I2C_I2C_##idx##_SDA_PIN, \
.frequency = I2C_NRFX_TWIM_FREQUENCY( \
DT_NORDIC_NRF_I2C_I2C_##idx##_CLOCK_FREQUENCY) \
} \
}; \
DEVICE_AND_API_INIT(twim_##idx, \
DT_NORDIC_NRF_I2C_I2C_##idx##_LABEL, \
twim_##idx##_init, \
&twim_##idx##_data, \
&twim_##idx##z_config, \
POST_KERNEL, \
CONFIG_I2C_INIT_PRIORITY, \
&i2c_nrfx_twim_driver_api)
DEVICE_DEFINE(twim_##idx, \
DT_NORDIC_NRF_I2C_I2C_##idx##_LABEL, \
twim_##idx##_init, \
twim_nrfx_pm_control, \
&twim_##idx##_data, \
&twim_##idx##z_config, \
POST_KERNEL, \
CONFIG_I2C_INIT_PRIORITY, \
&i2c_nrfx_twim_driver_api)

#ifdef CONFIG_I2C_0_NRF_TWIM
I2C_NRFX_TWIM_DEVICE(0);

0 comments on commit 05cdd28

Please sign in to comment.
You can’t perform that action at this time.