added i2c_device_add/i2c_bus_add/spi_device_add function

This commit is contained in:
nopnop2002 2024-09-09 11:01:19 +09:00
parent 5a033a1c51
commit 2e6910b549
4 changed files with 146 additions and 54 deletions

View File

@ -4,6 +4,8 @@
#include "driver/spi_master.h"
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0))
#include "driver/i2c_master.h"
#else
#include "driver/i2c.h"
#endif
// Following definitions are bollowed from
@ -74,8 +76,6 @@ Usage:
#define I2C_ADDRESS 0x3C
#define SPI_ADDRESS 0xFF
#define I2C_DRIVER_NOT_INSTALL -1
typedef enum {
SCROLL_RIGHT = 1,
SCROLL_LEFT = 2,
@ -96,13 +96,14 @@ typedef struct {
int _height;
int _pages;
int _dc;
spi_device_handle_t _SPIHandle;
bool _scEnable;
int _scStart;
int _scEnd;
int _scDirection;
PAGE_t _page[8];
bool _flip;
i2c_port_t _i2c_num;
spi_device_handle_t _SPIHandle;
} SSD1306_t;
#ifdef __cplusplus
@ -141,17 +142,17 @@ void ssd1306_fadeout(SSD1306_t * dev);
void ssd1306_dump(SSD1306_t dev);
void ssd1306_dump_page(SSD1306_t * dev, int page, int seg);
#if CONFIG_SPI_INTERFACE
void spi_clock_speed(int speed);
#endif
void i2c_master_init(SSD1306_t * dev, int16_t sda, int16_t scl, int16_t reset);
void i2c_device_add(SSD1306_t * dev, i2c_master_bus_handle_t bus_handle, int16_t reset);
void i2c_device_add(SSD1306_t * dev, i2c_port_t i2c_num, int16_t reset);
void i2c_bus_add(SSD1306_t * dev, i2c_master_bus_handle_t bus_handle, i2c_port_t i2c_num, int16_t reset);
void i2c_init(SSD1306_t * dev, int width, int height);
void i2c_display_image(SSD1306_t * dev, int page, int seg, uint8_t * images, int width);
void i2c_contrast(SSD1306_t * dev, int contrast);
void i2c_hardware_scroll(SSD1306_t * dev, ssd1306_scroll_type_t scroll);
void spi_master_init(SSD1306_t * dev, int16_t GPIO_MOSI, int16_t GPIO_SCLK, int16_t GPIO_CS, int16_t GPIO_DC, int16_t GPIO_RESET);
void spi_clock_speed(int speed);
void spi_master_init(SSD1306_t * dev, int16_t mosi, int16_t sclk, int16_t cs, int16_t dc, int16_t reset);
void spi_device_add(SSD1306_t * dev, int16_t cs, int16_t dc, int16_t reset);
bool spi_master_write_byte(spi_device_handle_t SPIHandle, const uint8_t* Data, size_t DataLength );
bool spi_master_write_command(SSD1306_t * dev, uint8_t Command );
bool spi_master_write_data(SSD1306_t * dev, const uint8_t* Data, size_t DataLength );

View File

@ -19,25 +19,21 @@
#endif
#define I2C_MASTER_FREQ_HZ 400000 // I2C clock of SSD1306 can run at 400 kHz max.
#define I2C_TICKS_TO_WAIT 100 // Maximum ticks to wait before issuing a timeout.
#define I2C_TICKS_TO_WAIT 100 // Maximum ticks to wait before issuing a timeout.
void i2c_master_init(SSD1306_t * dev, int16_t sda, int16_t scl, int16_t reset)
{
ESP_LOGI(TAG, "Legacy i2c driver is used");
if (sda != I2C_DRIVER_NOT_INSTALL && scl != I2C_DRIVER_NOT_INSTALL) {
i2c_config_t i2c_config = {
.mode = I2C_MODE_MASTER,
.sda_io_num = sda,
.scl_io_num = scl,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = I2C_MASTER_FREQ_HZ
};
ESP_ERROR_CHECK(i2c_param_config(I2C_NUM, &i2c_config));
ESP_ERROR_CHECK(i2c_driver_install(I2C_NUM, I2C_MODE_MASTER, 0, 0, 0));
} else {
ESP_LOGW(TAG, "Will not install i2c master driver");
}
i2c_config_t i2c_config = {
.mode = I2C_MODE_MASTER,
.sda_io_num = sda,
.scl_io_num = scl,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = I2C_MASTER_FREQ_HZ
};
ESP_ERROR_CHECK(i2c_param_config(I2C_NUM, &i2c_config));
ESP_ERROR_CHECK(i2c_driver_install(I2C_NUM, I2C_MODE_MASTER, 0, 0, 0));
if (reset >= 0) {
//gpio_pad_select_gpio(reset);
@ -47,8 +43,41 @@ void i2c_master_init(SSD1306_t * dev, int16_t sda, int16_t scl, int16_t reset)
vTaskDelay(50 / portTICK_PERIOD_MS);
gpio_set_level(reset, 1);
}
dev->_address = I2C_ADDRESS;
dev->_flip = false;
dev->_i2c_num = I2C_NUM;
}
void i2c_device_add(SSD1306_t * dev, i2c_port_t i2c_num, int16_t reset)
{
ESP_LOGI(TAG, "Legacy i2c driver is used");
ESP_LOGW(TAG, "Will not install i2c master driver");
#if 0
i2c_config_t i2c_config = {
.mode = I2C_MODE_MASTER,
.sda_io_num = sda,
.scl_io_num = scl,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = I2C_MASTER_FREQ_HZ
};
ESP_ERROR_CHECK(i2c_param_config(I2C_NUM, &i2c_config));
ESP_ERROR_CHECK(i2c_driver_install(I2C_NUM, I2C_MODE_MASTER, 0, 0, 0));
#endif
if (reset >= 0) {
//gpio_pad_select_gpio(reset);
gpio_reset_pin(reset);
gpio_set_direction(reset, GPIO_MODE_OUTPUT);
gpio_set_level(reset, 0);
vTaskDelay(50 / portTICK_PERIOD_MS);
gpio_set_level(reset, 1);
}
dev->_address = I2C_ADDRESS;
dev->_flip = false;
dev->_i2c_num = i2c_num;
}
void i2c_init(SSD1306_t * dev, int width, int height) {
@ -62,11 +91,11 @@ void i2c_init(SSD1306_t * dev, int width, int height) {
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (dev->_address << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_STREAM, true);
i2c_master_write_byte(cmd, OLED_CMD_DISPLAY_OFF, true); // AE
i2c_master_write_byte(cmd, OLED_CMD_SET_MUX_RATIO, true); // A8
i2c_master_write_byte(cmd, OLED_CMD_DISPLAY_OFF, true); // AE
i2c_master_write_byte(cmd, OLED_CMD_SET_MUX_RATIO, true); // A8
if (dev->_height == 64) i2c_master_write_byte(cmd, 0x3F, true);
if (dev->_height == 32) i2c_master_write_byte(cmd, 0x1F, true);
i2c_master_write_byte(cmd, OLED_CMD_SET_DISPLAY_OFFSET, true); // D3
i2c_master_write_byte(cmd, OLED_CMD_SET_DISPLAY_OFFSET, true); // D3
i2c_master_write_byte(cmd, 0x00, true);
//i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_DATA_STREAM, true); // 40
i2c_master_write_byte(cmd, OLED_CMD_SET_DISPLAY_START_LINE, true); // 40
@ -102,7 +131,7 @@ void i2c_init(SSD1306_t * dev, int width, int height) {
i2c_master_stop(cmd);
esp_err_t res = i2c_master_cmd_begin(I2C_NUM, cmd, I2C_TICKS_TO_WAIT);
esp_err_t res = i2c_master_cmd_begin(dev->_i2c_num, cmd, I2C_TICKS_TO_WAIT);
if (res == ESP_OK) {
ESP_LOGI(TAG, "OLED configured successfully");
} else {
@ -138,7 +167,7 @@ void i2c_display_image(SSD1306_t * dev, int page, int seg, uint8_t * images, int
i2c_master_write_byte(cmd, 0xB0 | _page, true);
i2c_master_stop(cmd);
esp_err_t res = i2c_master_cmd_begin(I2C_NUM, cmd, I2C_TICKS_TO_WAIT);
esp_err_t res = i2c_master_cmd_begin(dev->_i2c_num, cmd, I2C_TICKS_TO_WAIT);
if (res != ESP_OK) {
ESP_LOGE(TAG, "Image command failed. code: 0x%.2X", res);
}
@ -151,7 +180,7 @@ void i2c_display_image(SSD1306_t * dev, int page, int seg, uint8_t * images, int
i2c_master_write(cmd, images, width, true);
i2c_master_stop(cmd);
res = i2c_master_cmd_begin(I2C_NUM, cmd, I2C_TICKS_TO_WAIT);
res = i2c_master_cmd_begin(dev->_i2c_num, cmd, I2C_TICKS_TO_WAIT);
if (res != ESP_OK) {
ESP_LOGE(TAG, "Image command failed. code: 0x%.2X", res);
}
@ -171,7 +200,7 @@ void i2c_contrast(SSD1306_t * dev, int contrast) {
i2c_master_write_byte(cmd, _contrast, true);
i2c_master_stop(cmd);
esp_err_t res = i2c_master_cmd_begin(I2C_NUM, cmd, I2C_TICKS_TO_WAIT);
esp_err_t res = i2c_master_cmd_begin(dev->_i2c_num, cmd, I2C_TICKS_TO_WAIT);
if (res != ESP_OK) {
ESP_LOGE(TAG, "Contrast command failed. code: 0x%.2X", res);
}
@ -252,7 +281,7 @@ void i2c_hardware_scroll(SSD1306_t * dev, ssd1306_scroll_type_t scroll) {
i2c_master_stop(cmd);
esp_err_t res = i2c_master_cmd_begin(I2C_NUM, cmd, I2C_TICKS_TO_WAIT);
esp_err_t res = i2c_master_cmd_begin(dev->_i2c_num, cmd, I2C_TICKS_TO_WAIT);
if (res != ESP_OK) {
ESP_LOGE(TAG, "Scroll command failed. code: 0x%.2X", res);
}

View File

@ -53,13 +53,16 @@ void i2c_master_init(SSD1306_t * dev, int16_t sda, int16_t scl, int16_t reset)
vTaskDelay(50 / portTICK_PERIOD_MS);
gpio_set_level(reset, 1);
}
dev->_address = I2C_ADDRESS;
dev->_flip = false;
dev->_i2c_num = I2C_NUM;
}
void i2c_device_add(SSD1306_t * dev, i2c_master_bus_handle_t bus_handle, int16_t reset)
void i2c_bus_add(SSD1306_t * dev, i2c_master_bus_handle_t bus_handle, i2c_port_t i2c_num, int16_t reset)
{
ESP_LOGI(TAG, "New i2c driver is used");
ESP_LOGW(TAG, "Will not install i2c master driver");
#if 0
i2c_master_bus_config_t i2c_mst_config = {
.clk_source = I2C_CLK_SRC_DEFAULT,
@ -89,8 +92,10 @@ void i2c_device_add(SSD1306_t * dev, i2c_master_bus_handle_t bus_handle, int16_t
vTaskDelay(50 / portTICK_PERIOD_MS);
gpio_set_level(reset, 1);
}
dev->_address = I2C_ADDRESS;
dev->_flip = false;
dev->_i2c_num = i2c_num;
}
void i2c_init(SSD1306_t * dev, int width, int height) {
@ -145,7 +150,7 @@ void i2c_init(SSD1306_t * dev, int width, int height) {
if (res == ESP_OK) {
ESP_LOGI(TAG, "OLED configured successfully");
} else {
ESP_LOGE(TAG, "Could not write to device [0x%02x at %d]: %d (%s)", dev->_address, I2C_NUM, res, esp_err_to_name(res));
ESP_LOGE(TAG, "Could not write to device [0x%02x at %d]: %d (%s)", dev->_address, dev->_i2c_num, res, esp_err_to_name(res));
}
}
@ -181,14 +186,14 @@ void i2c_display_image(SSD1306_t * dev, int page, int seg, uint8_t * images, int
esp_err_t res;
res = i2c_master_transmit(dev_handle, out_buf, out_index, I2C_TICKS_TO_WAIT);
if (res != ESP_OK)
ESP_LOGE(TAG, "Could not write to device [0x%02x at %d]: %d (%s)", dev->_address, I2C_NUM, res, esp_err_to_name(res));
ESP_LOGE(TAG, "Could not write to device [0x%02x at %d]: %d (%s)", dev->_address, dev->_i2c_num, res, esp_err_to_name(res));
out_buf[0] = OLED_CONTROL_BYTE_DATA_STREAM;
memcpy(&out_buf[1], images, width);
res = i2c_master_transmit(dev_handle, out_buf, width + 1, I2C_TICKS_TO_WAIT);
if (res != ESP_OK)
ESP_LOGE(TAG, "Could not write to device [0x%02x at %d]: %d (%s)", dev->_address, I2C_NUM, res, esp_err_to_name(res));
ESP_LOGE(TAG, "Could not write to device [0x%02x at %d]: %d (%s)", dev->_address, dev->_i2c_num, res, esp_err_to_name(res));
free(out_buf);
}
@ -205,7 +210,7 @@ void i2c_contrast(SSD1306_t * dev, int contrast) {
esp_err_t res = i2c_master_transmit(dev_handle, out_buf, 3, I2C_TICKS_TO_WAIT);
if (res != ESP_OK)
ESP_LOGE(TAG, "Could not write to device [0x%02x at %d]: %d (%s)", dev->_address, I2C_NUM, res, esp_err_to_name(res));
ESP_LOGE(TAG, "Could not write to device [0x%02x at %d]: %d (%s)", dev->_address, dev->_i2c_num, res, esp_err_to_name(res));
}
@ -280,6 +285,6 @@ void i2c_hardware_scroll(SSD1306_t * dev, ssd1306_scroll_type_t scroll) {
esp_err_t res = i2c_master_transmit(dev_handle, out_buf, 3, I2C_TICKS_TO_WAIT);
if (res != ESP_OK)
ESP_LOGE(TAG, "Could not write to device [0x%02x at %d]: %d (%s)", dev->_address, I2C_NUM, res, esp_err_to_name(res));
ESP_LOGE(TAG, "Could not write to device [0x%02x at %d]: %d (%s)", dev->_address, dev->_i2c_num, res, esp_err_to_name(res));
}

View File

@ -29,30 +29,30 @@ void spi_clock_speed(int speed) {
clock_speed_hz = speed;
}
void spi_master_init(SSD1306_t * dev, int16_t GPIO_MOSI, int16_t GPIO_SCLK, int16_t GPIO_CS, int16_t GPIO_DC, int16_t GPIO_RESET)
void spi_master_init(SSD1306_t * dev, int16_t mosi, int16_t sclk, int16_t cs, int16_t dc, int16_t reset)
{
esp_err_t ret;
gpio_reset_pin( GPIO_CS );
gpio_set_direction( GPIO_CS, GPIO_MODE_OUTPUT );
gpio_set_level( GPIO_CS, 0 );
gpio_reset_pin( cs );
gpio_set_direction( cs, GPIO_MODE_OUTPUT );
gpio_set_level( cs, 0 );
gpio_reset_pin( GPIO_DC );
gpio_set_direction( GPIO_DC, GPIO_MODE_OUTPUT );
gpio_set_level( GPIO_DC, 0 );
gpio_reset_pin( dc );
gpio_set_direction( dc, GPIO_MODE_OUTPUT );
gpio_set_level( dc, 0 );
if ( GPIO_RESET >= 0 ) {
gpio_reset_pin( GPIO_RESET );
gpio_set_direction( GPIO_RESET, GPIO_MODE_OUTPUT );
gpio_set_level( GPIO_RESET, 0 );
if ( reset >= 0 ) {
gpio_reset_pin( reset );
gpio_set_direction( reset, GPIO_MODE_OUTPUT );
gpio_set_level( reset, 0 );
vTaskDelay( pdMS_TO_TICKS( 100 ) );
gpio_set_level( GPIO_RESET, 1 );
gpio_set_level( reset, 1 );
}
spi_bus_config_t spi_bus_config = {
.mosi_io_num = GPIO_MOSI,
.mosi_io_num = mosi,
.miso_io_num = -1,
.sclk_io_num = GPIO_SCLK,
.sclk_io_num = sclk,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
.max_transfer_sz = 0,
@ -68,17 +68,74 @@ void spi_master_init(SSD1306_t * dev, int16_t GPIO_MOSI, int16_t GPIO_SCLK, int1
memset( &devcfg, 0, sizeof( spi_device_interface_config_t ) );
//devcfg.clock_speed_hz = SPI_DEFAULT_FREQUENCY;
devcfg.clock_speed_hz = clock_speed_hz;
devcfg.spics_io_num = GPIO_CS;
devcfg.spics_io_num = cs;
devcfg.queue_size = 1;
spi_device_handle_t handle;
ret = spi_bus_add_device( HOST_ID, &devcfg, &handle);
ESP_LOGI(TAG, "spi_bus_add_device=%d",ret);
assert(ret==ESP_OK);
dev->_dc = GPIO_DC;
dev->_SPIHandle = handle;
dev->_dc = dc;
dev->_address = SPI_ADDRESS;
dev->_flip = false;
dev->_SPIHandle = handle;
}
void spi_device_add(SSD1306_t * dev, int16_t cs, int16_t dc, int16_t reset)
{
ESP_LOGW(TAG, "Will not install spi master driver");
esp_err_t ret;
gpio_reset_pin( cs );
gpio_set_direction( cs, GPIO_MODE_OUTPUT );
gpio_set_level( cs, 0 );
gpio_reset_pin( dc );
gpio_set_direction( dc, GPIO_MODE_OUTPUT );
gpio_set_level( dc, 0 );
if ( reset >= 0 ) {
gpio_reset_pin( reset );
gpio_set_direction( reset, GPIO_MODE_OUTPUT );
gpio_set_level( reset, 0 );
vTaskDelay( pdMS_TO_TICKS( 100 ) );
gpio_set_level( reset, 1 );
}
#if 0
spi_bus_config_t spi_bus_config = {
.mosi_io_num = mosi,
.miso_io_num = -1,
.sclk_io_num = sclk,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
.max_transfer_sz = 0,
.flags = 0
};
ESP_LOGI(TAG, "SPI HOST_ID=%d", HOST_ID);
ret = spi_bus_initialize( HOST_ID, &spi_bus_config, SPI_DMA_CH_AUTO );
ESP_LOGI(TAG, "spi_bus_initialize=%d",ret);
assert(ret==ESP_OK);
#endif
spi_device_interface_config_t devcfg;
memset( &devcfg, 0, sizeof( spi_device_interface_config_t ) );
//devcfg.clock_speed_hz = SPI_DEFAULT_FREQUENCY;
devcfg.clock_speed_hz = clock_speed_hz;
devcfg.spics_io_num = cs;
devcfg.queue_size = 1;
spi_device_handle_t handle;
ret = spi_bus_add_device( HOST_ID, &devcfg, &handle);
ESP_LOGI(TAG, "spi_bus_add_device=%d",ret);
assert(ret==ESP_OK);
dev->_dc = dc;
dev->_address = SPI_ADDRESS;
dev->_flip = false;
dev->_SPIHandle = handle;
}