Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimization: i2c factorization #202

Merged
merged 2 commits into from
Jun 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions main/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
idf_component_register(
SRCS
"adc.c"
"i2c_master.c"
"DS4432U.c"
"EMC2101.c"
"fonts.c"
Expand Down
57 changes: 3 additions & 54 deletions main/DS4432U.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include <stdio.h>
#include <math.h>
#include "esp_log.h"
#include "driver/i2c.h"

#include "DS4432U.h"

Expand Down Expand Up @@ -50,62 +49,12 @@ static uint8_t voltage_to_reg(float vout)
return reg;
}

/**
* @brief i2c master initialization
*/
esp_err_t i2c_master_init(void)
{
int i2c_master_port = I2C_MASTER_NUM;

i2c_config_t conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = I2C_MASTER_SDA_IO,
.scl_io_num = I2C_MASTER_SCL_IO,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = I2C_MASTER_FREQ_HZ,
};

i2c_param_config(i2c_master_port, &conf);

return i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
}

/**
* @brief i2c master delete
*/
esp_err_t i2c_master_delete(void)
{
return i2c_driver_delete(I2C_MASTER_NUM);
}

/**
* @brief Read a sequence of I2C bytes
*/
static esp_err_t register_read(uint8_t reg_addr, uint8_t *data, size_t len)
{
return i2c_master_write_read_device(I2C_MASTER_NUM, DS4432U_SENSOR_ADDR, &reg_addr, 1, data, len, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
}

/**
* @brief Write a byte to a I2C register
*/
static esp_err_t register_write_byte(uint8_t reg_addr, uint8_t data)
{
int ret;
uint8_t write_buf[2] = {reg_addr, data};

ret = i2c_master_write_to_device(I2C_MASTER_NUM, DS4432U_SENSOR_ADDR, write_buf, sizeof(write_buf), I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);

return ret;
}

bool DS4432U_test(void)
{
uint8_t data[3];

/* Read the DS4432U+ WHO_AM_I register, on power up the register should have the value 0x00 */
esp_err_t register_result = register_read(DS4432U_OUT0_REG, data, 1);
esp_err_t register_result = register_read(DS4432U_SENSOR_ADDR, DS4432U_OUT0_REG, data, 1);
ESP_LOGI(TAG, "DS4432U+ OUT1 = 0x%02X", data[0]);
return register_result == ESP_OK;
}
Expand All @@ -115,14 +64,14 @@ void DS4432U_read(void)
uint8_t data[3];

/* Read the DS4432U+ WHO_AM_I register, on power up the register should have the value 0x00 */
ESP_ERROR_CHECK(register_read(DS4432U_OUT0_REG, data, 1));
ESP_ERROR_CHECK(register_read(DS4432U_SENSOR_ADDR, DS4432U_OUT0_REG, data, 1));
ESP_LOGI(TAG, "DS4432U+ OUT1 = 0x%02X", data[0]);
}

static void DS4432U_set(uint8_t val)
{
ESP_LOGI(TAG, "Writing 0x%02X", val);
ESP_ERROR_CHECK(register_write_byte(DS4432U_OUT0_REG, val));
ESP_ERROR_CHECK(register_write_byte(DS4432U_SENSOR_ADDR, DS4432U_OUT0_REG, val));
}

bool DS4432U_set_vcore(float core_voltage)
Expand Down
6 changes: 1 addition & 5 deletions main/DS4432U.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
#ifndef DS4432U_H_
#define DS4432U_H_

#include "driver/i2c.h"
#include "i2c_master.h"

#include "i2c_params.h"

esp_err_t i2c_master_init(void);
esp_err_t i2c_master_delete(void);
void DS4432U_read(void);
bool DS4432U_test(void);
bool DS4432U_set_vcore(float);
Expand Down
40 changes: 8 additions & 32 deletions main/EMC2101.c
Original file line number Diff line number Diff line change
@@ -1,43 +1,19 @@
#include "driver/i2c.h"
#include "esp_log.h"
#include <stdio.h>

#include "EMC2101.h"

// static const char *TAG = "EMC2101.c";

/**
* @brief Read a sequence of I2C bytes
*/
static esp_err_t register_read(uint8_t reg_addr, uint8_t * data, size_t len)
{
return i2c_master_write_read_device(I2C_MASTER_NUM, EMC2101_I2CADDR_DEFAULT, &reg_addr, 1, data, len,
I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
}

/**
* @brief Write a byte to a I2C register
*/
static esp_err_t register_write_byte(uint8_t reg_addr, uint8_t data)
{
int ret;
uint8_t write_buf[2] = {reg_addr, data};

ret = i2c_master_write_to_device(I2C_MASTER_NUM, EMC2101_I2CADDR_DEFAULT, write_buf, sizeof(write_buf),
I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);

return ret;
}

// run this first. sets up the config register
void EMC2101_init(bool invertPolarity)
{

// set the TACH input
ESP_ERROR_CHECK(register_write_byte(EMC2101_REG_CONFIG, 0x04));
ESP_ERROR_CHECK(register_write_byte(EMC2101_I2CADDR_DEFAULT, EMC2101_REG_CONFIG, 0x04));

if (invertPolarity) {
ESP_ERROR_CHECK(register_write_byte(EMC2101_FAN_CONFIG, 0b00100011));
ESP_ERROR_CHECK(register_write_byte(EMC2101_I2CADDR_DEFAULT, EMC2101_FAN_CONFIG, 0b00100011));
}
}

Expand All @@ -47,7 +23,7 @@ void EMC2101_set_fan_speed(float percent)
uint8_t speed;

speed = (uint8_t) (63.0 * percent);
ESP_ERROR_CHECK(register_write_byte(EMC2101_REG_FAN_SETTING, speed));
ESP_ERROR_CHECK(register_write_byte(EMC2101_I2CADDR_DEFAULT, EMC2101_REG_FAN_SETTING, speed));
}

// RPM = 5400000/reading
Expand All @@ -57,8 +33,8 @@ uint16_t EMC2101_get_fan_speed(void)
uint16_t reading;
uint16_t RPM;

ESP_ERROR_CHECK(register_read(EMC2101_TACH_LSB, &tach_lsb, 1));
ESP_ERROR_CHECK(register_read(EMC2101_TACH_MSB, &tach_msb, 1));
ESP_ERROR_CHECK(register_read(EMC2101_I2CADDR_DEFAULT, EMC2101_TACH_LSB, &tach_lsb, 1));
ESP_ERROR_CHECK(register_read(EMC2101_I2CADDR_DEFAULT, EMC2101_TACH_MSB, &tach_msb, 1));

// ESP_LOGI(TAG, "Raw Fan Speed = %02X %02X", tach_msb, tach_lsb);

Expand All @@ -77,8 +53,8 @@ float EMC2101_get_external_temp(void)
uint8_t temp_msb, temp_lsb;
uint16_t reading;

ESP_ERROR_CHECK(register_read(EMC2101_EXTERNAL_TEMP_MSB, &temp_msb, 1));
ESP_ERROR_CHECK(register_read(EMC2101_EXTERNAL_TEMP_LSB, &temp_lsb, 1));
ESP_ERROR_CHECK(register_read(EMC2101_I2CADDR_DEFAULT, EMC2101_EXTERNAL_TEMP_MSB, &temp_msb, 1));
ESP_ERROR_CHECK(register_read(EMC2101_I2CADDR_DEFAULT, EMC2101_EXTERNAL_TEMP_LSB, &temp_lsb, 1));

reading = temp_lsb | (temp_msb << 8);
reading >>= 5;
Expand All @@ -89,6 +65,6 @@ float EMC2101_get_external_temp(void)
uint8_t EMC2101_get_internal_temp(void)
{
uint8_t temp;
ESP_ERROR_CHECK(register_read(EMC2101_INTERNAL_TEMP, &temp, 1));
ESP_ERROR_CHECK(register_read(EMC2101_I2CADDR_DEFAULT, EMC2101_INTERNAL_TEMP, &temp, 1));
return temp;
}
2 changes: 1 addition & 1 deletion main/EMC2101.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef EMC2101_H_
#define EMC2101_H_

#include "i2c_params.h"
#include "i2c_master.h"

#define EMC2101_I2CADDR_DEFAULT 0x4C ///< EMC2101 default i2c address
#define EMC2101_CHIP_ID 0x16 ///< EMC2101 default device id from part id
Expand Down
28 changes: 4 additions & 24 deletions main/INA260.c
Original file line number Diff line number Diff line change
@@ -1,41 +1,21 @@
#include <stdio.h>
#include "esp_log.h"
#include "driver/i2c.h"

#include "INA260.h"

// static const char *TAG = "INA260.c";

/**
* @brief Read a sequence of I2C bytes
*/
static esp_err_t register_read(uint8_t reg_addr, uint8_t *data, size_t len)
{
return i2c_master_write_read_device(I2C_MASTER_NUM, INA260_I2CADDR_DEFAULT, &reg_addr, 1, data, len, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
}

/**
* @brief Write a byte to a I2C register
*/
// static esp_err_t register_write_byte(uint8_t reg_addr, uint8_t data) {
// int ret;
// uint8_t write_buf[2] = {reg_addr, data};

// ret = i2c_master_write_to_device(I2C_MASTER_NUM, INA260_I2CADDR_DEFAULT, write_buf, sizeof(write_buf), I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);

// return ret;
// }
bool INA260_installed(void)
{
uint8_t data[2];
return register_read(INA260_REG_BUSVOLTAGE, data, 2) == ESP_OK;
return register_read(INA260_I2CADDR_DEFAULT, INA260_REG_BUSVOLTAGE, data, 2) == ESP_OK;
}

float INA260_read_current(void)
{
uint8_t data[2];

ESP_ERROR_CHECK(register_read(INA260_REG_CURRENT, data, 2));
ESP_ERROR_CHECK(register_read(INA260_I2CADDR_DEFAULT, INA260_REG_CURRENT, data, 2));
// ESP_LOGI(TAG, "Raw Current = %02X %02X", data[1], data[0]);

return (uint16_t)(data[1] | (data[0] << 8)) * 1.25;
Expand All @@ -45,7 +25,7 @@ float INA260_read_voltage(void)
{
uint8_t data[2];

ESP_ERROR_CHECK(register_read(INA260_REG_BUSVOLTAGE, data, 2));
ESP_ERROR_CHECK(register_read(INA260_I2CADDR_DEFAULT, INA260_REG_BUSVOLTAGE, data, 2));
// ESP_LOGI(TAG, "Raw Voltage = %02X %02X", data[1], data[0]);

return (uint16_t)(data[1] | (data[0] << 8)) * 1.25;
Expand All @@ -55,7 +35,7 @@ float INA260_read_power(void)
{
uint8_t data[2];

ESP_ERROR_CHECK(register_read(INA260_REG_POWER, data, 2));
ESP_ERROR_CHECK(register_read(INA260_I2CADDR_DEFAULT, INA260_REG_POWER, data, 2));
// ESP_LOGI(TAG, "Raw Power = %02X %02X", data[1], data[0]);

return (data[1] | (data[0] << 8)) * 10;
Expand Down
2 changes: 1 addition & 1 deletion main/INA260.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef INA260_H_
#define INA260_H_

#include "i2c_params.h"
#include "i2c_master.h"

#define INA260_I2CADDR_DEFAULT 0x40 ///< INA260 default i2c address
#define INA260_REG_CONFIG 0x00 ///< Configuration register
Expand Down
59 changes: 59 additions & 0 deletions main/i2c_master.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#include "i2c_master.h"

#define I2C_MASTER_SCL_IO 48 /*!< GPIO number used for I2C master clock */
#define I2C_MASTER_SDA_IO 47 /*!< GPIO number used for I2C master data */
#define I2C_MASTER_FREQ_HZ 400000 /*!< I2C master clock frequency */
#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
#define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */

/**
* @brief i2c master initialization
*/
esp_err_t i2c_master_init(void)
{
int i2c_master_port = I2C_MASTER_NUM;

i2c_config_t conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = I2C_MASTER_SDA_IO,
.scl_io_num = I2C_MASTER_SCL_IO,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = I2C_MASTER_FREQ_HZ,
};

i2c_param_config(i2c_master_port, &conf);

return i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
}

/**
* @brief i2c master delete
*/
esp_err_t i2c_master_delete(void)
{
return i2c_driver_delete(I2C_MASTER_NUM);
}

/**
* @brief Read a sequence of I2C bytes
*/
esp_err_t register_read(uint8_t device_address, uint8_t reg_addr, uint8_t * data, size_t len)
{
return i2c_master_write_read_device(I2C_MASTER_NUM, device_address, &reg_addr, 1, data, len,
I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
}

/**
* @brief Write a byte to a I2C register
*/
esp_err_t register_write_byte(uint8_t device_address, uint8_t reg_addr, uint8_t data)
{
int ret;
uint8_t write_buf[2] = {reg_addr, data};

ret = i2c_master_write_to_device(I2C_MASTER_NUM, device_address, write_buf, sizeof(write_buf),
I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);

return ret;
}
14 changes: 14 additions & 0 deletions main/i2c_master.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifndef I2C_MASTER_H_
#define I2C_MASTER_H_

#include "driver/i2c.h"

#define I2C_MASTER_NUM 0 /*!< I2C master i2c port number, the number of i2c peripheral interfaces available will depend on the chip */
#define I2C_MASTER_TIMEOUT_MS 1000

esp_err_t i2c_master_init(void);
esp_err_t i2c_master_delete(void);
esp_err_t register_read(uint8_t device_address, uint8_t reg_addr, uint8_t * data, size_t len);
esp_err_t register_write_byte(uint8_t device_address, uint8_t reg_addr, uint8_t data);

#endif /* I2C_MASTER_H_ */
12 changes: 0 additions & 12 deletions main/i2c_params.h

This file was deleted.

9 changes: 2 additions & 7 deletions main/oled.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// A copy of the display memory is maintained by this code so that single pixel
// writes can occur without having to read from the display controller.

#include "driver/i2c.h"
#include "i2c_master.h"
#include "esp_err.h"
#include "esp_log.h"
#include "nvs_config.h"
Expand All @@ -25,11 +25,6 @@

#include "oled.h"

#define I2C_TIMEOUT 1000

/*!< I2C master i2c port number, the number of i2c peripheral interfaces available will depend on the chip */
#define I2C_MASTER_NUM 0

extern unsigned char ucSmallFont[];
static int iScreenOffset; // current write offset of screen data
static unsigned char ucScreen[1024]; // local copy of the image buffer
Expand Down Expand Up @@ -288,7 +283,7 @@ static esp_err_t write(uint8_t * data, uint8_t len)
{
int ret;

ret = i2c_master_write_to_device(I2C_MASTER_NUM, 0x3C, data, len, 1000 / portTICK_PERIOD_MS);
ret = i2c_master_write_to_device(I2C_MASTER_NUM, 0x3C, data, len, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);

return ret;
}
Loading
Loading