From 858d910d07784706618bab9b0f66db352302275b Mon Sep 17 00:00:00 2001 From: jflyper Date: Wed, 21 Jun 2017 17:53:18 +0900 Subject: [PATCH] Make I2C bus for OLED display configurable --- src/main/config/parameter_group_ids.h | 3 ++- src/main/drivers/bus_i2c.h | 7 +++++++ src/main/drivers/display_ug2864hsweg01.c | 25 +++++++++++++++++++----- src/main/drivers/display_ug2864hsweg01.h | 9 +++++++++ src/main/fc/settings.c | 5 +++++ 5 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/main/config/parameter_group_ids.h b/src/main/config/parameter_group_ids.h index e4b0bb3f5..e7949d38b 100644 --- a/src/main/config/parameter_group_ids.h +++ b/src/main/config/parameter_group_ids.h @@ -107,7 +107,8 @@ #define PG_SONAR_CONFIG 516 #define PG_ESC_SENSOR_CONFIG 517 #define PG_I2C_CONFIG 518 -#define PG_BETAFLIGHT_END 518 +#define PG_OLED_DISPLAY_CONFIG 519 +#define PG_BETAFLIGHT_END 519 // OSD configuration (subject to change) diff --git a/src/main/drivers/bus_i2c.h b/src/main/drivers/bus_i2c.h index bd2712599..d92a390b3 100644 --- a/src/main/drivers/bus_i2c.h +++ b/src/main/drivers/bus_i2c.h @@ -45,6 +45,13 @@ typedef enum I2CDevice { #define I2CDEV_COUNT 4 #endif +// Macro to convert CLI bus number to I2CDevice. +#define I2C_CFG_TO_DEV(x) ((x) - 1) + +// I2C device address range in 8-bit address mode +#define I2C_ADDR8_MIN 8 +#define I2C_ADDR8_MAX 119 + typedef struct i2cConfig_s { ioTag_t ioTagScl[I2CDEV_COUNT]; ioTag_t ioTagSda[I2CDEV_COUNT]; diff --git a/src/main/drivers/display_ug2864hsweg01.c b/src/main/drivers/display_ug2864hsweg01.c index b9ac8528e..fd0c617c4 100644 --- a/src/main/drivers/display_ug2864hsweg01.c +++ b/src/main/drivers/display_ug2864hsweg01.c @@ -24,16 +24,31 @@ #include "display_ug2864hsweg01.h" +#include "config/parameter_group.h" +#include "config/parameter_group_ids.h" + #ifdef USE_I2C_OLED_DISPLAY #if !defined(OLED_I2C_INSTANCE) #if defined(I2C_DEVICE) #define OLED_I2C_INSTANCE I2C_DEVICE #else -#define OLED_I2C_INSTANCE I2C_NONE +#define OLED_I2C_INSTANCE I2CINVALID #endif #endif +#define OLED_address 0x3C // OLED at address 0x3C in 7bit + +PG_REGISTER_WITH_RESET_TEMPLATE(oledDisplayConfig_t, oledDisplayConfig, PG_OLED_DISPLAY_CONFIG, 0); + +PG_RESET_TEMPLATE(oledDisplayConfig_t, oledDisplayConfig, + .bus = OLED_I2C_INSTANCE, + .address = OLED_address, +); + +static I2CDevice i2cBus = I2CINVALID; // XXX Protect against direct call to i2cWrite and i2cRead +static uint8_t i2cAddress; + #define INVERSE_CHAR_FORMAT 0x7f // 0b01111111 #define NORMAL_CHAR_FORMAT 0x00 // 0b00000000 @@ -176,16 +191,14 @@ static const uint8_t multiWiiFont[][5] = { // Refer to "Times New Roman" Font Da { 0x7A, 0x7E, 0x7E, 0x7E, 0x7A }, // (131) - 0x00C8 Vertical Bargraph - 6 (full) }; -#define OLED_address 0x3C // OLED at address 0x3C in 7bit - static bool i2c_OLED_send_cmd(uint8_t command) { - return i2cWrite(OLED_I2C_INSTANCE, OLED_address, 0x80, command); + return i2cWrite(i2cBus, i2cAddress, 0x80, command); } static bool i2c_OLED_send_byte(uint8_t val) { - return i2cWrite(OLED_I2C_INSTANCE, OLED_address, 0x40, val); + return i2cWrite(i2cBus, i2cAddress, 0x40, val); } void i2c_OLED_clear_display(void) @@ -257,6 +270,8 @@ void i2c_OLED_send_string(const char *string) */ bool ug2864hsweg01InitI2C(void) { + i2cBus = I2C_CFG_TO_DEV(oledDisplayConfig()->bus); + i2cAddress = oledDisplayConfig()->address; // Set display OFF if (!i2c_OLED_send_cmd(0xAE)) { diff --git a/src/main/drivers/display_ug2864hsweg01.h b/src/main/drivers/display_ug2864hsweg01.h index 3a51eab7a..5b5e0620c 100644 --- a/src/main/drivers/display_ug2864hsweg01.h +++ b/src/main/drivers/display_ug2864hsweg01.h @@ -17,6 +17,15 @@ #pragma once +#include "drivers/bus_i2c.h" + +typedef struct oledDisplayConfig_s { + I2CDevice bus; + uint8_t address; +} oledDisplayConfig_t; + +PG_DECLARE(oledDisplayConfig_t, oledDisplayConfig); + #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 diff --git a/src/main/fc/settings.c b/src/main/fc/settings.c index f316e5c92..5ef33138b 100644 --- a/src/main/fc/settings.c +++ b/src/main/fc/settings.c @@ -37,6 +37,7 @@ #include "config/parameter_group_ids.h" #include "drivers/light_led.h" +#include "drivers/display_ug2864hsweg01.h" #include "fc/config.h" #include "fc/controlrate_profile.h" @@ -719,6 +720,10 @@ const clivalue_t valueTable[] = { { "esc_sensor_halfduplex", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_ESC_SENSOR_CONFIG, offsetof(escSensorConfig_t, halfDuplex) }, #endif { "led_inversion", VAR_UINT8 | MASTER_VALUE, .config.minmax = { 0, ((1 << STATUS_LED_NUMBER) - 1) }, PG_STATUS_LED_CONFIG, offsetof(statusLedConfig_t, inversion) }, +#ifdef USE_I2C_OLED_DISPLAY + { "oled_display_i2c_bus", VAR_UINT8 | MASTER_VALUE, .config.minmax = { 0, I2CDEV_COUNT }, PG_OLED_DISPLAY_CONFIG, offsetof(oledDisplayConfig_t, bus) }, + { "oled_display_i2c_addr", VAR_UINT8 | MASTER_VALUE, .config.minmax = { I2C_ADDR8_MIN, I2C_ADDR8_MAX }, PG_OLED_DISPLAY_CONFIG, offsetof(oledDisplayConfig_t, bus) }, +#endif }; const uint16_t valueTableEntryCount = ARRAYLEN(valueTable);