issue #1041
This commit is contained in:
parent
c3e91dc05f
commit
a14bba7cae
|
@ -688,6 +688,172 @@ extern "C" uint8_t u8x8_byte_arduino_4wire_sw_spi(u8x8_t *u8x8, uint8_t msg, uin
|
|||
#endif
|
||||
|
||||
|
||||
/*=============================================*/
|
||||
/*=== 3 WIRE HARDWARE SPI with 8 bit HW SPI Subsystem ===*/
|
||||
/*
|
||||
references:
|
||||
https://github.com/olikraus/ucglib/blob/master/cppsrc/Ucglib.cpp#L581
|
||||
https://github.com/olikraus/u8g2/issues/1041
|
||||
*/
|
||||
|
||||
static uint8_t arduino_hw_spi_3w_buffer[9];
|
||||
static uint8_t arduino_hw_spi_3w_bytepos;
|
||||
static uint16_t arduino_hw_spi_3w_dc; // 0 = dc==0, 256 = dc==1
|
||||
|
||||
static void arduino_hw_spi_3w_init()
|
||||
{
|
||||
memset(arduino_hw_spi_3w_buffer, 0, 9);
|
||||
arduino_hw_spi_3w_bytepos = 0;
|
||||
}
|
||||
|
||||
static void arduino_hw_spi_3w_flush(void)
|
||||
{
|
||||
#ifdef U8X8_HAVE_HW_SPI
|
||||
uint8_t i;
|
||||
for(i = 0; i <= arduino_hw_spi_3w_bytepos; i++)
|
||||
{
|
||||
SPI.transfer(arduino_hw_spi_3w_buffer[i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void arduino_hw_spi_3w_sendbyte(uint8_t data)
|
||||
{
|
||||
static union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } data16; // well well, not legal ISO 9899 code
|
||||
|
||||
data16.val = (arduino_hw_spi_3w_dc + data) << (7 - arduino_hw_spi_3w_bytepos);
|
||||
#ifdef __BYTE_ORDER__
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
arduino_hw_spi_3w_buffer[arduino_hw_spi_3w_bytepos] |= data16.msb;
|
||||
++arduino_hw_spi_3w_bytepos;
|
||||
arduino_hw_spi_3w_buffer[arduino_hw_spi_3w_bytepos] |= data16.lsb;
|
||||
#else
|
||||
arduino_hw_spi_3w_buffer[arduino_hw_spi_3w_bytepos] |= data16.lsb;
|
||||
++arduino_hw_spi_3w_bytepos;
|
||||
arduino_hw_spi_3w_buffer[arduino_hw_spi_3w_bytepos] |= data16.msb;
|
||||
#endif
|
||||
#else // __BYTE_ORDER__ not defined (no gcc)
|
||||
// assume little endian
|
||||
arduino_hw_spi_3w_buffer[arduino_hw_spi_3w_bytepos] |= data16.msb;
|
||||
++arduino_hw_spi_3w_bytepos;
|
||||
arduino_hw_spi_3w_buffer[arduino_hw_spi_3w_bytepos] |= data16.lsb;
|
||||
#endif
|
||||
|
||||
if (arduino_hw_spi_3w_bytepos == 8)
|
||||
{
|
||||
arduino_hw_spi_3w_flush();
|
||||
arduino_hw_spi_3w_init();
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" uint8_t u8x8_byte_arduino_3wire_hw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
#ifdef U8X8_HAVE_HW_SPI
|
||||
|
||||
uint8_t *data;
|
||||
uint8_t internal_spi_mode;
|
||||
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_BYTE_SEND:
|
||||
data = (uint8_t *)arg_ptr;
|
||||
while(arg_int > 0) {
|
||||
arduino_hw_spi_3w_sendbyte((uint8_t)*data);
|
||||
data++;
|
||||
arg_int--;
|
||||
}
|
||||
break;
|
||||
|
||||
case U8X8_MSG_BYTE_INIT:
|
||||
if ( u8x8->bus_clock == 0 ) /* issue 769 */
|
||||
u8x8->bus_clock = u8x8->display_info->sck_clock_hz;
|
||||
/* disable chipselect */
|
||||
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
|
||||
|
||||
#if defined(ESP_PLATFORM) || defined(ARDUINO_ARCH_ESP32)
|
||||
/* ESP32 has the following begin: SPI.begin(int8_t sck=SCK, int8_t miso=MISO, int8_t mosi=MOSI, int8_t ss=-1); */
|
||||
/* not sure about ESP8266 */
|
||||
if ( u8x8->pins[U8X8_PIN_I2C_CLOCK] != U8X8_PIN_NONE && u8x8->pins[U8X8_PIN_I2C_DATA] != U8X8_PIN_NONE )
|
||||
{
|
||||
/* SPI.begin(int8_t sck=SCK, int8_t miso=MISO, int8_t mosi=MOSI, int8_t ss=-1); */
|
||||
/* actually MISO is not used, but what else could be used here??? */
|
||||
SPI.begin(u8x8->pins[U8X8_PIN_I2C_CLOCK], MISO, u8x8->pins[U8X8_PIN_I2C_DATA]);
|
||||
}
|
||||
else
|
||||
{
|
||||
SPI.begin();
|
||||
}
|
||||
#else
|
||||
SPI.begin();
|
||||
#endif
|
||||
break;
|
||||
|
||||
case U8X8_MSG_BYTE_SET_DC:
|
||||
arduino_hw_spi_3w_dc = arg_int ? 256 : 0;
|
||||
break;
|
||||
|
||||
case U8X8_MSG_BYTE_START_TRANSFER:
|
||||
/* SPI mode has to be mapped to the mode of the current controller;
|
||||
at least Uno, Due, 101 have different SPI_MODEx values */
|
||||
internal_spi_mode = 0;
|
||||
switch(u8x8->display_info->spi_mode) {
|
||||
case 0: internal_spi_mode = SPI_MODE0; break;
|
||||
case 1: internal_spi_mode = SPI_MODE1; break;
|
||||
case 2: internal_spi_mode = SPI_MODE2; break;
|
||||
case 3: internal_spi_mode = SPI_MODE3; break;
|
||||
}
|
||||
|
||||
#if ARDUINO >= 10600
|
||||
SPI.beginTransaction(
|
||||
SPISettings(u8x8->bus_clock, MSBFIRST, internal_spi_mode));
|
||||
#else
|
||||
SPI.begin();
|
||||
if (u8x8->display_info->sck_pulse_width_ns < 70)
|
||||
SPI.setClockDivider(SPI_CLOCK_DIV2);
|
||||
else if (u8x8->display_info->sck_pulse_width_ns < 140)
|
||||
SPI.setClockDivider(SPI_CLOCK_DIV4);
|
||||
else
|
||||
SPI.setClockDivider(SPI_CLOCK_DIV8);
|
||||
SPI.setDataMode(internal_spi_mode);
|
||||
SPI.setBitOrder(MSBFIRST);
|
||||
#endif
|
||||
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);
|
||||
u8x8->gpio_and_delay_cb(
|
||||
u8x8,
|
||||
U8X8_MSG_DELAY_NANO,
|
||||
u8x8->display_info->post_chip_enable_wait_ns,
|
||||
NULL);
|
||||
arduino_hw_spi_3w_init();
|
||||
break;
|
||||
|
||||
case U8X8_MSG_BYTE_END_TRANSFER:
|
||||
u8x8->gpio_and_delay_cb(
|
||||
u8x8,
|
||||
U8X8_MSG_DELAY_NANO,
|
||||
u8x8->display_info->pre_chip_disable_wait_ns,
|
||||
NULL);
|
||||
if (arduino_hw_spi_3w_bytepos)
|
||||
arduino_hw_spi_3w_flush();
|
||||
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
|
||||
|
||||
#if ARDUINO >= 10600
|
||||
SPI.endTransaction();
|
||||
#else
|
||||
SPI.end();
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // U8X8_HAVE_HW_SPI
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*=============================================*/
|
||||
/*=== 4 WIRE HARDWARE SPI ===*/
|
||||
|
||||
|
@ -1530,6 +1696,15 @@ void u8x8_Setup_3Wire_SW_SPI(u8x8_t *u8x8, u8x8_msg_cb display_cb, uint8_t clock
|
|||
}
|
||||
#endif /* obsolete com specific setup */
|
||||
|
||||
/*
|
||||
use U8X8_PIN_NONE as value for "reset", if there is no reset line
|
||||
*/
|
||||
void u8x8_SetPin_3Wire_HW_SPI(u8x8_t *u8x8, uint8_t cs, uint8_t reset)
|
||||
{
|
||||
u8x8_SetPin(u8x8, U8X8_PIN_CS, cs);
|
||||
u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
|
||||
}
|
||||
|
||||
/*
|
||||
use U8X8_PIN_NONE as value for "reset", if there is no reset line
|
||||
*/
|
||||
|
|
|
@ -133,6 +133,7 @@ extern "C" uint8_t u8x8_gpio_and_delay_arduino(u8x8_t *u8x8, uint8_t msg, uint8_
|
|||
extern "C" uint8_t u8x8_byte_arduino_8bit_8080mode(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
extern "C" uint8_t u8x8_byte_arduino_4wire_sw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
extern "C" uint8_t u8x8_byte_arduino_3wire_sw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
extern "C" uint8_t u8x8_byte_arduino_3wire_hw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
extern "C" uint8_t u8x8_byte_arduino_hw_spi(u8x8_t *u8g2, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
extern "C" uint8_t u8x8_byte_arduino_2nd_hw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); /* #244 */
|
||||
extern "C" uint8_t u8x8_byte_arduino_sw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
|
@ -143,6 +144,7 @@ extern "C" uint8_t u8x8_byte_arduino_ks0108(u8x8_t *u8x8, uint8_t msg, uint8_t a
|
|||
#ifdef U8X8_USE_PINS
|
||||
void u8x8_SetPin_4Wire_SW_SPI(u8x8_t *u8x8, uint8_t clock, uint8_t data, uint8_t cs, uint8_t dc, uint8_t reset);
|
||||
void u8x8_SetPin_3Wire_SW_SPI(u8x8_t *u8x8, uint8_t clock, uint8_t data, uint8_t cs, uint8_t reset);
|
||||
void u8x8_SetPin_3Wire_HW_SPI(u8x8_t *u8x8, uint8_t cs, uint8_t reset);
|
||||
void u8x8_SetPin_4Wire_HW_SPI(u8x8_t *u8x8, uint8_t cs, uint8_t dc, uint8_t reset);
|
||||
void u8x8_SetPin_ST7920_HW_SPI(u8x8_t *u8x8, uint8_t cs, uint8_t reset);
|
||||
void u8x8_SetPin_SW_I2C(u8x8_t *u8x8, uint8_t clock, uint8_t data, uint8_t reset);
|
||||
|
|
Loading…
Reference in New Issue