-
I'd like to port an ssd1306 driver from elsewhere, for example from here https://github.com/nopnop2002/esp-idf-ssd1306, in my project that already uses i2cdev. Rewriting all the commands to be completely i2cdev-friendly is tedious. How should one use i2cdev with other i2c libs? I thought to wrap everything in typedef struct {
i2c_dev_t i2c_dev;
...
} SSD1306_t; // only once
i2c_dev_create_mutex(&dev->i2c_dev)
// function body
I2C_DEV_TAKE_MUTEX(&dev->i2c_dev);
SEMAPHORE_TAKE(dev->i2c_dev.port);
// custom i2c commands
SEMAPHORE_GIVE(dev->i2c_dev.port);
I2C_DEV_GIVE_MUTEX(&dev->i2c_dev); but |
Beta Was this translation helpful? Give feedback.
Replies: 5 comments 8 replies
-
Hi! |
Beta Was this translation helpful? Give feedback.
-
That's what I mean tedious to do. Just have a look at the original static bool I2CDefaultWriteBytes( int Address, bool IsCommand, const uint8_t* Data, size_t DataLength ) {
i2c_cmd_handle_t* CommandHandle = NULL;
static uint8_t ModeByte = 0;
NullCheck( Data, return false );
if ( ( CommandHandle = i2c_cmd_link_create( ) ) != NULL ) {
ModeByte = ( IsCommand == true ) ? SSD1306_I2C_COMMAND_MODE: SSD1306_I2C_DATA_MODE;
ESP_ERROR_CHECK_NONFATAL( i2c_master_start( CommandHandle ), return false );
ESP_ERROR_CHECK_NONFATAL( i2c_master_write_byte( CommandHandle, ( Address << 1 ) | I2C_MASTER_WRITE, true ), return false );
ESP_ERROR_CHECK_NONFATAL( i2c_master_write_byte( CommandHandle, ModeByte, true ), return false );
ESP_ERROR_CHECK_NONFATAL( i2c_master_write( CommandHandle, ( uint8_t* ) Data, DataLength, true ), return false );
ESP_ERROR_CHECK_NONFATAL( i2c_master_stop( CommandHandle ), return false );
ESP_ERROR_CHECK_NONFATAL( i2c_master_cmd_begin( I2CPortNumber, CommandHandle, pdMS_TO_TICKS( 1000 ) ), return false );
i2c_cmd_link_delete( CommandHandle );
}
return true;
} and i2cdev rewritten version static bool I2CDefaultWriteBytes(int Address, bool IsCommand,
const uint8_t *Data, size_t DataLength) {
NullCheck(Data, return false);
ESP_ERROR_CHECK_NONFATAL(i2c_dev_take_mutex(&dev), return false);
ESP_ERROR_CHECK_NONFATAL(
i2c_dev_write_reg(&dev,
(IsCommand == true) ? SSD1306_I2C_COMMAND_MODE
: SSD1306_I2C_DATA_MODE,
Data, DataLength),
do {
i2c_dev_give_mutex(&dev);
return false;
} while (0));
ESP_ERROR_CHECK_NONFATAL(i2c_dev_give_mutex(&dev), return false);
return true;
} Clearly, not an obvious substitution for an outsider who is not into i2cdev. Especially in the case of I2C calls flooding as it's in nopnop's repo. I had a look at https://github.com/UncleRus/esp-idf-lib/tree/ssd1306/components/ssd1306 and found no functions to draw text. Also, it's not clear in which state the code is - is it plug and play or proof of concept. |
Beta Was this translation helpful? Give feedback.
-
I suggest adding the example I shown above in FAQ. It's descriptive and shows how to do the porting. Still, it'd be nice to have a semaphore lock accessible as I suggested in the first comment. Wrapping everything in mutex and semahore lock will ensure that no change has been made to the original raw i2c calls. |
Beta Was this translation helpful? Give feedback.
-
I'm having trouble porting this lib https://github.com/nopnop2002/esp-idf-24c/blob/master/components/at24c/at24c.c to i2cdev. I think it's a good example to add in the PR too. The one-byte-address functions are rewritten in: static esp_err_t ReadReg8(EEPROM_t * dev, int chip_addr, uint8_t data_addr, uint8_t * data)
{
esp_err_t err = i2c_dev_take_mutex(&dev->i2c_dev);
if (err != ESP_OK) {
return err;
}
dev->i2c_dev.addr = chip_addr;
err = i2c_dev_read_reg(&dev->i2c_dev, data_addr, data, 1);
i2c_dev_give_mutex(&dev->i2c_dev);
if (err != ESP_OK) {
ESP_LOGW(TAG, "ReadReg8 %s", esp_err_to_name(err));
}
return err;
}
static esp_err_t WriteReg8(EEPROM_t * dev, int chip_addr, uint8_t data_addr, uint8_t data)
{
esp_err_t err = i2c_dev_take_mutex(&dev->i2c_dev);
if (err != ESP_OK) {
return err;
}
dev->i2c_dev.addr = chip_addr;
err = i2c_dev_write_reg(&dev->i2c_dev, data_addr, &data, 1);
i2c_dev_give_mutex(&dev->i2c_dev);
usleep(1000*2);
if (err != ESP_OK) {
ESP_LOGW(TAG, "WriteReg8 %s", esp_err_to_name(err));
}
return err;
} but I don't know how to rewrite ReadReg16 and WriteReg16 functions because they operate on the two-bytes address. |
Beta Was this translation helpful? Give feedback.
-
anyone ? TEXT + FONT example ? please help |
Beta Was this translation helpful? Give feedback.
Hi!
You don't need to call internal macros. Just use common interface of i2cdev,
i2c_dev_read...()
andi2c_dev_write...()
functions.The nopnop's driver is not the best choice for porting to i2cdev: it has too many low-level i2c calls. You can port other driver, such as suggested in #74 or use an already ported driver: https://github.com/UncleRus/esp-idf-lib/tree/ssd1306/components/ssd1306