This commit is contained in:
kraus 2020-01-26 22:15:46 +01:00
parent c3e91dc05f
commit a14bba7cae
2 changed files with 177 additions and 0 deletions

View File

@ -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
*/

View File

@ -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);