SH1107: Support for alternate i2c address.

Add `i2c_address` option to MicroPython PicoGraphics.
patch-sh1107-i2c-addr
Phil Howard 2022-06-27 14:03:53 +01:00
rodzic 2721ad682f
commit b0cfb12b20
3 zmienionych plików z 45 dodań i 38 usunięć

Wyświetl plik

@ -31,14 +31,14 @@ namespace pimoroni {
uint8_t buf[page_size + 1];
for(int i = 0; i < 16; i++) {
i2c.reg_write_uint8(0x3c, 0, 0xb0 + i);
i2c.reg_write_uint8(0x3c, 0, 0x00);
i2c.reg_write_uint8(0x3c, 0, 0x10);
i2c.reg_write_uint8(i2c_address, 0, 0xb0 + i);
i2c.reg_write_uint8(i2c_address, 0, 0x00);
i2c.reg_write_uint8(i2c_address, 0, 0x10);
memcpy(buf + 1, ptemp, page_size);
buf[0] = 0x40;
i2c.write_blocking(0x3c, buf, page_size + 1, false);
i2c.write_blocking(i2c_address, buf, page_size + 1, false);
ptemp += page_size;
}

Wyświetl plik

@ -18,61 +18,64 @@ namespace pimoroni {
public:
bool round;
static const uint8_t DEFAULT_I2C_ADDRESS = 0x3c;
static const uint8_t ALTERNATE_I2C_ADDRESS = 0x3d;
//--------------------------------------------------
// Variables
//--------------------------------------------------
private:
uint8_t i2c_address = DEFAULT_I2C_ADDRESS;
public:
// Parallel init
SH1107(uint16_t width, uint16_t height, I2C &i2c) :
SH1107(uint16_t width, uint16_t height, I2C &i2c) : SH1107(width, height, i2c, DEFAULT_I2C_ADDRESS) {};
SH1107(uint16_t width, uint16_t height, I2C &i2c, uint8_t i2c_address) :
DisplayDriver(width, height, ROTATE_0),
i2c(i2c) {
i2c(i2c), i2c_address(i2c_address) {
i2c.reg_write_uint8(0x3c, 0, 0xae);
i2c.reg_write_uint8(i2c_address, 0, 0xae);
i2c.reg_write_uint8(0x3c, 0, 0x20); // set memory addressing mode
i2c.reg_write_uint8(0x3c, 0, 0x00);
i2c.reg_write_uint8(i2c_address, 0, 0x20); // set memory addressing mode
i2c.reg_write_uint8(i2c_address, 0, 0x00);
i2c.reg_write_uint8(0x3c, 0, 0xb0); // set page start address
i2c.reg_write_uint8(i2c_address, 0, 0xb0); // set page start address
i2c.reg_write_uint8(0x3c, 0, 0xc0); // mirror vertically (for australian market)
i2c.reg_write_uint8(i2c_address, 0, 0xc0); // mirror vertically (for australian market)
i2c.reg_write_uint8(0x3c, 0, 0x00);
i2c.reg_write_uint8(0x3c, 0, 0x10);
i2c.reg_write_uint8(i2c_address, 0, 0x00);
i2c.reg_write_uint8(i2c_address, 0, 0x10);
i2c.reg_write_uint8(0x3c, 0, 0x40);
i2c.reg_write_uint8(i2c_address, 0, 0x40);
i2c.reg_write_uint8(0x3c, 0, 0xa0); // mirror horizontally
i2c.reg_write_uint8(i2c_address, 0, 0xa0); // mirror horizontally
i2c.reg_write_uint8(0x3c, 0, 0xa6); // no inversion
i2c.reg_write_uint8(i2c_address, 0, 0xa6); // no inversion
i2c.reg_write_uint8(0x3c, 0, 0xff); // ??????!
i2c.reg_write_uint8(0x3c, 0, 0x3f); // confusion intensifies..
i2c.reg_write_uint8(i2c_address, 0, 0xff); // ??????!
i2c.reg_write_uint8(i2c_address, 0, 0x3f); // confusion intensifies..
i2c.reg_write_uint8(0x3c, 0, 0xa4);
i2c.reg_write_uint8(i2c_address, 0, 0xa4);
i2c.reg_write_uint8(0x3c, 0, 0xd3); // set display offset
i2c.reg_write_uint8(0x3c, 0, 0x00);
i2c.reg_write_uint8(i2c_address, 0, 0xd3); // set display offset
i2c.reg_write_uint8(i2c_address, 0, 0x00);
i2c.reg_write_uint8(0x3c, 0, 0xd5); // set display clock divide
i2c.reg_write_uint8(0x3c, 0, 0xf0);
i2c.reg_write_uint8(i2c_address, 0, 0xd5); // set display clock divide
i2c.reg_write_uint8(i2c_address, 0, 0xf0);
i2c.reg_write_uint8(0x3c, 0, 0xd9); // set precharge period
i2c.reg_write_uint8(0x3c, 0, 0x22);
i2c.reg_write_uint8(i2c_address, 0, 0xd9); // set precharge period
i2c.reg_write_uint8(i2c_address, 0, 0x22);
i2c.reg_write_uint8(0x3c, 0, 0xda); // set com pins hardware configuration
i2c.reg_write_uint8(0x3c, 0, 0x12);
i2c.reg_write_uint8(i2c_address, 0, 0xda); // set com pins hardware configuration
i2c.reg_write_uint8(i2c_address, 0, 0x12);
i2c.reg_write_uint8(0x3c, 0, 0xdb); // set vcomh
i2c.reg_write_uint8(0x3c, 0, 0x20);
i2c.reg_write_uint8(i2c_address, 0, 0xdb); // set vcomh
i2c.reg_write_uint8(i2c_address, 0, 0x20);
i2c.reg_write_uint8(0x3c, 0, 0x8d); // set dc-dc enable
i2c.reg_write_uint8(0x3c, 0, 0x14);
i2c.reg_write_uint8(i2c_address, 0, 0x8d); // set dc-dc enable
i2c.reg_write_uint8(i2c_address, 0, 0x14);
i2c.reg_write_uint8(0x3c, 0, 0xaf); // turn display on
i2c.reg_write_uint8(i2c_address, 0, 0xaf); // turn display on
}
void update(PicoGraphics *graphics) override;

Wyświetl plik

@ -115,7 +115,7 @@ size_t get_required_buffer_size(PicoGraphicsPenType pen_type, uint width, uint h
mp_obj_t ModPicoGraphics_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
ModPicoGraphics_obj_t *self = nullptr;
enum { ARG_display, ARG_rotate, ARG_bus, ARG_buffer, ARG_pen_type, ARG_extra_pins };
enum { ARG_display, ARG_rotate, ARG_bus, ARG_buffer, ARG_pen_type, ARG_extra_pins, ARG_i2c_address };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_display, MP_ARG_INT | MP_ARG_REQUIRED },
{ MP_QSTR_rotate, MP_ARG_INT, { .u_int = -1 } },
@ -123,6 +123,7 @@ mp_obj_t ModPicoGraphics_make_new(const mp_obj_type_t *type, size_t n_args, size
{ MP_QSTR_buffer, MP_ARG_OBJ, { .u_obj = mp_const_none } },
{ MP_QSTR_pen_type, MP_ARG_INT, { .u_int = -1 } },
{ MP_QSTR_extra_pins, MP_ARG_OBJ, { .u_obj = mp_const_none } },
{ MP_QSTR_i2c_address, MP_ARG_INT, { .u_int = -1 } },
};
// Parse args.
@ -174,11 +175,14 @@ mp_obj_t ModPicoGraphics_make_new(const mp_obj_type_t *type, size_t n_args, size
mp_raise_ValueError("SPIBus expected!");
}
} else if (display == DISPLAY_I2C_OLED_128X128) {
if (args[ARG_bus].u_obj == mp_const_none || mp_obj_is_type(args[ARG_bus].u_obj, &PimoroniI2C_type)) {
if (mp_obj_is_type(args[ARG_bus].u_obj, &PimoroniI2C_type)) {
_PimoroniI2C_obj_t *i2c = PimoroniI2C_from_machine_i2c_or_native(args[ARG_bus].u_obj);
self->display = m_new_class(SH1107, width, height, *(pimoroni::I2C *)(i2c->i2c));
int i2c_address = args[ARG_i2c_address].u_int;
if(i2c_address == -1) i2c_address = SH1107::DEFAULT_I2C_ADDRESS;
self->display = m_new_class(SH1107, width, height, *(pimoroni::I2C *)(i2c->i2c), (uint8_t)i2c_address);
} else {
mp_raise_ValueError("I2C bus expected!");
mp_raise_ValueError("I2C bus required!");
}
} else if (display == DISPLAY_INKY_PACK) {
if (args[ARG_bus].u_obj == mp_const_none) {