|
@ -20,42 +20,38 @@ |
|
|
* |
|
|
* |
|
|
*/ |
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
/*
|
|
|
* Based on u8g_dev_ssd1306_128x64.c |
|
|
|
|
|
* |
|
|
u8g_dev_ssd1306_128x64.c |
|
|
* Universal 8bit Graphics Library |
|
|
|
|
|
* |
|
|
Universal 8bit Graphics Library |
|
|
* Copyright (c) 2015, olikraus@gmail.com |
|
|
|
|
|
* All rights reserved. |
|
|
Copyright (c) 2011, olikraus@gmail.com |
|
|
* |
|
|
All rights reserved. |
|
|
* Redistribution and use in source and binary forms, with or without modification, |
|
|
|
|
|
* are permitted provided that the following conditions are met: |
|
|
Redistribution and use in source and binary forms, with or without modification, |
|
|
* |
|
|
are permitted provided that the following conditions are met: |
|
|
* * Redistributions of source code must retain the above copyright notice, this list |
|
|
|
|
|
* of conditions and the following disclaimer. |
|
|
* Redistributions of source code must retain the above copyright notice, this list |
|
|
* |
|
|
of conditions and the following disclaimer. |
|
|
* * Redistributions in binary form must reproduce the above copyright notice, this |
|
|
|
|
|
* list of conditions and the following disclaimer in the documentation and/or other |
|
|
* Redistributions in binary form must reproduce the above copyright notice, this |
|
|
* materials provided with the distribution. |
|
|
list of conditions and the following disclaimer in the documentation and/or other |
|
|
* |
|
|
materials provided with the distribution. |
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
|
|
|
|
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
|
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
|
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
|
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
|
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
|
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR |
|
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR |
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
|
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
|
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
|
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
|
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
|
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
|
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
|
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
|
|
*/ |
|
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
/**
|
|
|
* These routines are meant for two wire I2C interfaces. |
|
|
* These routines are meant for two wire I2C interfaces. |
|
@ -85,43 +81,38 @@ uint8_t u8g_WriteEscSeqP_2_wire(u8g_t *u8g, u8g_dev_t *dev, const uint8_t *esc_s |
|
|
// The sh1106 is compatible to the ssd1306, but is 132x64. 128x64 display area is centered within
|
|
|
// The sh1106 is compatible to the ssd1306, but is 132x64. 128x64 display area is centered within
|
|
|
// the 132x64.
|
|
|
// the 132x64.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static const uint8_t u8g_dev_sh1106_128x64_data_start_2_wire[] PROGMEM = { |
|
|
static const uint8_t u8g_dev_sh1106_128x64_data_start_2_wire[] PROGMEM = { |
|
|
0x010, // set upper 4 bit of the col adr to 0
|
|
|
0x010, // set upper 4 bit of the col adr to 0
|
|
|
0x002, // set lower 4 bit of the col adr to 2 (centered display with ssd1306)
|
|
|
0x002, // set lower 4 bit of the col adr to 2 (centered display with ssd1306)
|
|
|
U8G_ESC_END // end of sequence
|
|
|
U8G_ESC_END // end of sequence
|
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static const uint8_t u8g_dev_sh1106_128x64_init_seq_2_wire[] PROGMEM = { |
|
|
static const uint8_t u8g_dev_sh1106_128x64_init_seq_2_wire[] PROGMEM = { |
|
|
U8G_ESC_ADR(0), // initiate command mode
|
|
|
U8G_ESC_ADR(0), // initiate command mode
|
|
|
0x0ae, /* display off, sleep mode */ |
|
|
0x0AE, // display off, sleep mode
|
|
|
0x0a8, 0x03f, /* mux ratio */ |
|
|
0x0A8, 0x03F, // mux ratio
|
|
|
0x0d3, 0x00, /* display offset */ |
|
|
0x0D3, 0x00, // display offset
|
|
|
0x040, /* start line */ |
|
|
0x040, // start line
|
|
|
0x0a1, /* segment remap a0/a1*/ |
|
|
0x0A1, // segment remap a0/a1
|
|
|
0x0c8, /* c0: scan dir normal, c8: reverse */ |
|
|
0x0C8, // c0: scan dir normal, c8: reverse
|
|
|
0x0da, 0x012, /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */ |
|
|
0x0DA, 0x012, // com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5)
|
|
|
0x081, 0x0cf, /* [2] set contrast control */ |
|
|
0x081, 0x0CF, // [2] set contrast control
|
|
|
0x020, 0x002, /* 2012-05-27: page addressing mode */ |
|
|
0x020, 0x002, // 2012-05-27: page addressing mode
|
|
|
0x21, 2, 0x81, // set column range from 0 through 131
|
|
|
0x21, 2, 0x81, // set column range from 0 through 131
|
|
|
0x22, 0, 7, // set page range from 0 through 7
|
|
|
0x22, 0, 7, // set page range from 0 through 7
|
|
|
0x0d9, 0x0f1, /* [2] pre-charge period 0x022/f1*/ |
|
|
0x0D9, 0x0F1, // [2] pre-charge period 0x022/f1
|
|
|
0x0db, 0x040, /* vcomh deselect level */ |
|
|
0x0DB, 0x040, // vcomh deselect level
|
|
|
0x0a4, /* output ram to display */ |
|
|
0x0A4, // output ram to display
|
|
|
0x0a6, /* none inverted normal display mode */ |
|
|
0x0A6, // none inverted normal display mode
|
|
|
0x0d5, 0x080, /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */ |
|
|
0x0D5, 0x080, // clock divide ratio (0x00=1) and oscillator frequency (0x8)
|
|
|
0x08d, 0x014, /* [2] charge pump setting (p62): 0x014 enable, 0x010 disable */ |
|
|
0x08D, 0x014, // [2] charge pump setting (p62): 0x014 enable, 0x010 disable
|
|
|
0x02e, /* 2012-05-27: Deactivate scroll */ |
|
|
0x02E, // 2012-05-27: Deactivate scroll
|
|
|
0x0af, /* display on */ |
|
|
0x0AF, // display on
|
|
|
U8G_ESC_END /* end of sequence */ |
|
|
U8G_ESC_END // end of sequence
|
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
uint8_t u8g_dev_sh1106_128x64_2x_2_wire_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) { |
|
|
uint8_t u8g_dev_sh1106_128x64_2x_2_wire_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) |
|
|
switch(msg) { |
|
|
{ |
|
|
|
|
|
switch(msg) |
|
|
|
|
|
{ |
|
|
|
|
|
case U8G_DEV_MSG_INIT: |
|
|
case U8G_DEV_MSG_INIT: |
|
|
u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_300NS); |
|
|
u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_300NS); |
|
|
u8g_WriteEscSeqP_2_wire(u8g, dev, u8g_dev_sh1106_128x64_init_seq_2_wire); |
|
|
u8g_WriteEscSeqP_2_wire(u8g, dev, u8g_dev_sh1106_128x64_init_seq_2_wire); |
|
@ -152,7 +143,6 @@ uint8_t u8g_dev_sh1106_128x64_2x_2_wire_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t m |
|
|
return u8g_dev_pb16v1_base_fn(u8g, dev, msg, arg); |
|
|
return u8g_dev_pb16v1_base_fn(u8g, dev, msg, arg); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t u8g_dev_sh1106_128x64_2x_i2c_2_wire_buf[WIDTH*2] U8G_NOCOMMON ; |
|
|
uint8_t u8g_dev_sh1106_128x64_2x_i2c_2_wire_buf[WIDTH*2] U8G_NOCOMMON ; |
|
|
u8g_pb_t u8g_dev_sh1106_128x64_2x_i2c_2_wire_pb = { {16, HEIGHT, 0, 0, 0}, WIDTH, u8g_dev_sh1106_128x64_2x_i2c_2_wire_buf}; |
|
|
u8g_pb_t u8g_dev_sh1106_128x64_2x_i2c_2_wire_pb = { {16, HEIGHT, 0, 0, 0}, WIDTH, u8g_dev_sh1106_128x64_2x_i2c_2_wire_buf}; |
|
|
u8g_dev_t u8g_dev_sh1106_128x64_2x_i2c_2_wire = { u8g_dev_sh1106_128x64_2x_2_wire_fn, &u8g_dev_sh1106_128x64_2x_i2c_2_wire_pb, U8G_COM_SSD_I2C_HAL }; |
|
|
u8g_dev_t u8g_dev_sh1106_128x64_2x_i2c_2_wire = { u8g_dev_sh1106_128x64_2x_2_wire_fn, &u8g_dev_sh1106_128x64_2x_i2c_2_wire_pb, U8G_COM_SSD_I2C_HAL }; |
|
@ -160,41 +150,37 @@ u8g_dev_t u8g_dev_sh1106_128x64_2x_i2c_2_wire = { u8g_dev_sh1106_128x64_2x_2_wir |
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
static const uint8_t u8g_dev_ssd1306_128x64_data_start_2_wire[] PROGMEM = { |
|
|
static const uint8_t u8g_dev_ssd1306_128x64_data_start_2_wire[] PROGMEM = { |
|
|
0x010, // set upper 4 bit of the col adr to 0
|
|
|
0x010, // set upper 4 bit of the col adr to 0
|
|
|
0x000, // set lower 4 bit of the col adr to 0
|
|
|
0x000, // set lower 4 bit of the col adr to 0
|
|
|
U8G_ESC_END // end of sequence
|
|
|
U8G_ESC_END // end of sequence
|
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static const uint8_t u8g_dev_ssd1306_128x64_init_seq_2_wire[] PROGMEM = { |
|
|
static const uint8_t u8g_dev_ssd1306_128x64_init_seq_2_wire[] PROGMEM = { |
|
|
U8G_ESC_ADR(0), // initiate command mode
|
|
|
U8G_ESC_ADR(0), // initiate command mode
|
|
|
0x0ae, /* display off, sleep mode */ |
|
|
0x0AE, // display off, sleep mode
|
|
|
0x0a8, 0x03f, /* mux ratio */ |
|
|
0x0A8, 0x03F, // mux ratio
|
|
|
0x0d3, 0x00, /* display offset */ |
|
|
0x0D3, 0x00, // display offset
|
|
|
0x040, /* start line */ |
|
|
0x040, // start line
|
|
|
0x0a1, /* segment remap a0/a1*/ |
|
|
0x0A1, // segment remap a0/a1
|
|
|
0x0c8, /* c0: scan dir normal, c8: reverse */ |
|
|
0x0C8, // c0: scan dir normal, c8: reverse
|
|
|
0x0da, 0x012, /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */ |
|
|
0x0DA, 0x012, // com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5)
|
|
|
0x081, 0x0cf, /* [2] set contrast control */ |
|
|
0x081, 0x0CF, // [2] set contrast control
|
|
|
0x020, 0x002, /* 2012-05-27: page addressing mode */ |
|
|
0x020, 0x002, // 2012-05-27: page addressing mode
|
|
|
0x21, 0, 0x7f, // set column range from 0 through 127
|
|
|
0x21, 0, 0x7F, // set column range from 0 through 127
|
|
|
0x22, 0, 7, // set page range from 0 through 7
|
|
|
0x22, 0, 7, // set page range from 0 through 7
|
|
|
0x0d9, 0x0f1, /* [2] pre-charge period 0x022/f1*/ |
|
|
0x0D9, 0x0F1, // [2] pre-charge period 0x022/f1
|
|
|
0x0db, 0x040, /* vcomh deselect level */ |
|
|
0x0DB, 0x040, // vcomh deselect level
|
|
|
0x0a4, /* output ram to display */ |
|
|
0x0A4, // output ram to display
|
|
|
0x0a6, /* none inverted normal display mode */ |
|
|
0x0A6, // none inverted normal display mode
|
|
|
0x0d5, 0x080, /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */ |
|
|
0x0D5, 0x080, // clock divide ratio (0x00=1) and oscillator frequency (0x8)
|
|
|
0x08d, 0x014, /* [2] charge pump setting (p62): 0x014 enable, 0x010 disable */ |
|
|
0x08D, 0x014, // [2] charge pump setting (p62): 0x014 enable, 0x010 disable
|
|
|
0x02e, /* 2012-05-27: Deactivate scroll */ |
|
|
0x02E, // 2012-05-27: Deactivate scroll
|
|
|
0x0af, /* display on */ |
|
|
0x0AF, // display on
|
|
|
U8G_ESC_END /* end of sequence */ |
|
|
U8G_ESC_END // end of sequence
|
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
uint8_t u8g_dev_ssd1306_128x64_2x_2_wire_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) { |
|
|
uint8_t u8g_dev_ssd1306_128x64_2x_2_wire_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) |
|
|
switch(msg) { |
|
|
{ |
|
|
|
|
|
switch(msg) |
|
|
|
|
|
{ |
|
|
|
|
|
case U8G_DEV_MSG_INIT: |
|
|
case U8G_DEV_MSG_INIT: |
|
|
u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_300NS); |
|
|
u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_300NS); |
|
|
u8g_WriteEscSeqP_2_wire(u8g, dev, u8g_dev_ssd1306_128x64_init_seq_2_wire); |
|
|
u8g_WriteEscSeqP_2_wire(u8g, dev, u8g_dev_ssd1306_128x64_init_seq_2_wire); |
|
@ -238,54 +224,42 @@ u8g_dev_t u8g_dev_ssd1306_128x64_2x_i2c_2_wire = { u8g_dev_ssd1306_128x64_2x_2_w |
|
|
|
|
|
|
|
|
#define I2C_CMD_MODE 0x080 |
|
|
#define I2C_CMD_MODE 0x080 |
|
|
|
|
|
|
|
|
uint8_t u8g_WriteEscSeqP_2_wire(u8g_t *u8g, u8g_dev_t *dev, const uint8_t *esc_seq) |
|
|
uint8_t u8g_WriteEscSeqP_2_wire(u8g_t *u8g, u8g_dev_t *dev, const uint8_t *esc_seq) { |
|
|
{ |
|
|
|
|
|
uint8_t is_escape = 0; |
|
|
uint8_t is_escape = 0; |
|
|
uint8_t value; |
|
|
uint8_t value; |
|
|
for(;;) |
|
|
for(;;) { |
|
|
{ |
|
|
|
|
|
value = u8g_pgm_read(esc_seq); |
|
|
value = u8g_pgm_read(esc_seq); |
|
|
if ( is_escape == 0 ) |
|
|
if (is_escape == 0) { |
|
|
{ |
|
|
if (value != 255) { |
|
|
if ( value != 255 ) |
|
|
if (u8g_WriteByte(u8g, dev, value) == 0 ) |
|
|
{ |
|
|
|
|
|
if ( u8g_WriteByte(u8g, dev, value) == 0 ) |
|
|
|
|
|
return 0; |
|
|
return 0; |
|
|
if ( u8g_WriteByte(u8g, dev, I2C_CMD_MODE) == 0 ) |
|
|
if (u8g_WriteByte(u8g, dev, I2C_CMD_MODE) == 0 ) |
|
|
return 0; |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
else |
|
|
else { |
|
|
{ |
|
|
|
|
|
is_escape = 1; |
|
|
is_escape = 1; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
else |
|
|
else { |
|
|
{ |
|
|
if (value == 255) { |
|
|
if ( value == 255 ) |
|
|
if (u8g_WriteByte(u8g, dev, value) == 0 ) |
|
|
{ |
|
|
|
|
|
if ( u8g_WriteByte(u8g, dev, value) == 0 ) |
|
|
|
|
|
return 0; |
|
|
return 0; |
|
|
if ( u8g_WriteByte(u8g, dev, I2C_CMD_MODE) == 0 ) |
|
|
if (u8g_WriteByte(u8g, dev, I2C_CMD_MODE) == 0 ) |
|
|
return 0; |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
else if ( value == 254 ) |
|
|
else if (value == 254) { |
|
|
{ |
|
|
|
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
else if ( value >= 0x0f0 ) |
|
|
else if (value >= 0x0f0) { |
|
|
{ |
|
|
|
|
|
/* not yet used, do nothing */ |
|
|
/* not yet used, do nothing */ |
|
|
} |
|
|
} |
|
|
else if ( value >= 0xe0 ) |
|
|
else if (value >= 0xe0 ) { |
|
|
{ |
|
|
|
|
|
u8g_SetAddress(u8g, dev, value & 0x0f); |
|
|
u8g_SetAddress(u8g, dev, value & 0x0f); |
|
|
} |
|
|
} |
|
|
else if ( value >= 0xd0 ) |
|
|
else if (value >= 0xd0) { |
|
|
{ |
|
|
|
|
|
u8g_SetChipSelect(u8g, dev, value & 0x0f); |
|
|
u8g_SetChipSelect(u8g, dev, value & 0x0f); |
|
|
} |
|
|
} |
|
|
else if ( value >= 0xc0 ) |
|
|
else if (value >= 0xc0) { |
|
|
{ |
|
|
|
|
|
u8g_SetResetLow(u8g, dev); |
|
|
u8g_SetResetLow(u8g, dev); |
|
|
value &= 0x0f; |
|
|
value &= 0x0f; |
|
|
value <<= 4; |
|
|
value <<= 4; |
|
@ -294,13 +268,10 @@ uint8_t u8g_WriteEscSeqP_2_wire(u8g_t *u8g, u8g_dev_t *dev, const uint8_t *esc_s |
|
|
u8g_SetResetHigh(u8g, dev); |
|
|
u8g_SetResetHigh(u8g, dev); |
|
|
u8g_Delay(value); |
|
|
u8g_Delay(value); |
|
|
} |
|
|
} |
|
|
else if ( value >= 0xbe ) |
|
|
else if (value >= 0xbe) { /* not yet implemented */ |
|
|
{ |
|
|
|
|
|
/* not yet implemented */ |
|
|
|
|
|
/* u8g_SetVCC(u8g, dev, value & 0x01); */ |
|
|
/* u8g_SetVCC(u8g, dev, value & 0x01); */ |
|
|
} |
|
|
} |
|
|
else if ( value <= 127 ) |
|
|
else if (value <= 127) { |
|
|
{ |
|
|
|
|
|
u8g_Delay(value); |
|
|
u8g_Delay(value); |
|
|
} |
|
|
} |
|
|
is_escape = 0; |
|
|
is_escape = 0; |
|
|