123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749 |
- /*
-
- u8x8_cad.c
-
- "command arg data" interface to the graphics controller
- Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
- Copyright (c) 2016, 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:
- * 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
- materials provided with the distribution.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- The following sequence must be used for any data, which is set to the display:
-
-
- uint8_t u8x8_cad_StartTransfer(u8x8_t *u8x8)
- any of the following calls
- uint8_t u8x8_cad_SendCmd(u8x8_t *u8x8, uint8_t cmd)
- uint8_t u8x8_cad_SendArg(u8x8_t *u8x8, uint8_t arg)
- uint8_t u8x8_cad_SendData(u8x8_t *u8x8, uint8_t cnt, uint8_t *data)
-
- uint8_t u8x8_cad_EndTransfer(u8x8_t *u8x8)
- */
- /*
- uint8_t u8x8_cad_template(u8x8_t *u8x8, uint8_t msg, uint16_t arg_int, void *arg_ptr)
- {
- uint8_t i;
-
- switch(msg)
- {
- case U8X8_MSG_CAD_SEND_CMD:
- u8x8_mcd_byte_SetDC(mcd->next, 1);
- u8x8_mcd_byte_Send(mcd->next, arg_int);
- break;
- case U8X8_MSG_CAD_SEND_ARG:
- u8x8_mcd_byte_SetDC(mcd->next, 1);
- u8x8_mcd_byte_Send(mcd->next, arg_int);
- break;
- case U8X8_MSG_CAD_SEND_DATA:
- u8x8_mcd_byte_SetDC(mcd->next, 0);
- for( i = 0; i < 8; i++ )
- u8x8_mcd_byte_Send(mcd->next, ((uint8_t *)arg_ptr)[i]);
- break;
- case U8X8_MSG_CAD_RESET:
- return mcd->next->cb(mcd->next, msg, arg_int, arg_ptr);
- case U8X8_MSG_CAD_START_TRANSFER:
- return mcd->next->cb(mcd->next, msg, arg_int, arg_ptr);
- case U8X8_MSG_CAD_END_TRANSFER:
- return mcd->next->cb(mcd->next, msg, arg_int, arg_ptr);
- default:
- break;
- }
- return 1;
- }
- */
- #include "u8x8.h"
- uint8_t u8x8_cad_SendCmd(u8x8_t *u8x8, uint8_t cmd)
- {
- return u8x8->cad_cb(u8x8, U8X8_MSG_CAD_SEND_CMD, cmd, NULL);
- }
- uint8_t u8x8_cad_SendArg(u8x8_t *u8x8, uint8_t arg)
- {
- return u8x8->cad_cb(u8x8, U8X8_MSG_CAD_SEND_ARG, arg, NULL);
- }
- uint8_t u8x8_cad_SendMultipleArg(u8x8_t *u8x8, uint8_t cnt, uint8_t arg)
- {
- while( cnt > 0 )
- {
- u8x8->cad_cb(u8x8, U8X8_MSG_CAD_SEND_ARG, arg, NULL);
- cnt--;
- }
- return 1;
- }
- uint8_t u8x8_cad_SendData(u8x8_t *u8x8, uint8_t cnt, uint8_t *data)
- {
- return u8x8->cad_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, cnt, data);
- }
- uint8_t u8x8_cad_StartTransfer(u8x8_t *u8x8)
- {
- return u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 0, NULL);
- }
- uint8_t u8x8_cad_EndTransfer(u8x8_t *u8x8)
- {
- return u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 0, NULL);
- }
- void u8x8_cad_vsendf(u8x8_t * u8x8, const char *fmt, va_list va)
- {
- uint8_t d;
- u8x8_cad_StartTransfer(u8x8);
- while( *fmt != '\0' )
- {
- d = (uint8_t)va_arg(va, int);
- switch(*fmt)
- {
- case 'a': u8x8_cad_SendArg(u8x8, d); break;
- case 'c': u8x8_cad_SendCmd(u8x8, d); break;
- case 'd': u8x8_cad_SendData(u8x8, 1, &d); break;
- }
- fmt++;
- }
- u8x8_cad_EndTransfer(u8x8);
- }
- void u8x8_SendF(u8x8_t * u8x8, const char *fmt, ...)
- {
- va_list va;
- va_start(va, fmt);
- u8x8_cad_vsendf(u8x8, fmt, va);
- va_end(va);
- }
- /*
- 21 c send command c
- 22 a send arg a
- 23 d send data d
- 24 CS on
- 25 CS off
- 254 milli delay by milliseconds
- 255 end of sequence
- */
- void u8x8_cad_SendSequence(u8x8_t *u8x8, uint8_t const *data)
- {
- uint8_t cmd;
- uint8_t v;
- for(;;)
- {
- cmd = *data;
- data++;
- switch( cmd )
- {
- case U8X8_MSG_CAD_SEND_CMD:
- case U8X8_MSG_CAD_SEND_ARG:
- v = *data;
- u8x8->cad_cb(u8x8, cmd, v, NULL);
- data++;
- break;
- case U8X8_MSG_CAD_SEND_DATA:
- v = *data;
- u8x8_cad_SendData(u8x8, 1, &v);
- data++;
- break;
- case U8X8_MSG_CAD_START_TRANSFER:
- case U8X8_MSG_CAD_END_TRANSFER:
- u8x8->cad_cb(u8x8, cmd, 0, NULL);
- break;
- case 0x0fe:
- v = *data;
- u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_MILLI, v);
- data++;
- break;
- default:
- return;
- }
- }
- }
- uint8_t u8x8_cad_empty(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
- {
- switch(msg)
- {
- case U8X8_MSG_CAD_SEND_CMD:
- u8x8_byte_SendByte(u8x8, arg_int);
- break;
- case U8X8_MSG_CAD_SEND_ARG:
- u8x8_byte_SendByte(u8x8, arg_int);
- break;
- case U8X8_MSG_CAD_SEND_DATA:
- case U8X8_MSG_CAD_INIT:
- case U8X8_MSG_CAD_START_TRANSFER:
- case U8X8_MSG_CAD_END_TRANSFER:
- return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
- default:
- return 0;
- }
- return 1;
- }
- /*
- convert to bytes by using
- dc = 1 for commands and args and
- dc = 0 for data
- */
- uint8_t u8x8_cad_110(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
- {
- switch(msg)
- {
- case U8X8_MSG_CAD_SEND_CMD:
- u8x8_byte_SetDC(u8x8, 1);
- u8x8_byte_SendByte(u8x8, arg_int);
- break;
- case U8X8_MSG_CAD_SEND_ARG:
- u8x8_byte_SetDC(u8x8, 1);
- u8x8_byte_SendByte(u8x8, arg_int);
- break;
- case U8X8_MSG_CAD_SEND_DATA:
- u8x8_byte_SetDC(u8x8, 0);
- //u8x8_byte_SendBytes(u8x8, arg_int, arg_ptr);
- //break;
- /* fall through */
- case U8X8_MSG_CAD_INIT:
- case U8X8_MSG_CAD_START_TRANSFER:
- case U8X8_MSG_CAD_END_TRANSFER:
- return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
- default:
- return 0;
- }
- return 1;
- }
- /*
- convert to bytes by using
- dc = 1 for commands and args and
- dc = 0 for data
- t6963
- */
- uint8_t u8x8_cad_100(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
- {
- switch(msg)
- {
- case U8X8_MSG_CAD_SEND_CMD:
- u8x8_byte_SetDC(u8x8, 1);
- u8x8_byte_SendByte(u8x8, arg_int);
- break;
- case U8X8_MSG_CAD_SEND_ARG:
- u8x8_byte_SetDC(u8x8, 0);
- u8x8_byte_SendByte(u8x8, arg_int);
- break;
- case U8X8_MSG_CAD_SEND_DATA:
- u8x8_byte_SetDC(u8x8, 0);
- //u8x8_byte_SendBytes(u8x8, arg_int, arg_ptr);
- //break;
- /* fall through */
- case U8X8_MSG_CAD_INIT:
- case U8X8_MSG_CAD_START_TRANSFER:
- case U8X8_MSG_CAD_END_TRANSFER:
- return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
- default:
- return 0;
- }
- return 1;
- }
- /*
- convert to bytes by using
- dc = 0 for commands and args and
- dc = 1 for data
- */
- uint8_t u8x8_cad_001(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
- {
- switch(msg)
- {
- case U8X8_MSG_CAD_SEND_CMD:
- u8x8_byte_SetDC(u8x8, 0);
- u8x8_byte_SendByte(u8x8, arg_int);
- break;
- case U8X8_MSG_CAD_SEND_ARG:
- u8x8_byte_SetDC(u8x8, 0);
- u8x8_byte_SendByte(u8x8, arg_int);
- break;
- case U8X8_MSG_CAD_SEND_DATA:
- u8x8_byte_SetDC(u8x8, 1);
- //u8x8_byte_SendBytes(u8x8, arg_int, arg_ptr);
- //break;
- /* fall through */
- case U8X8_MSG_CAD_INIT:
- case U8X8_MSG_CAD_START_TRANSFER:
- case U8X8_MSG_CAD_END_TRANSFER:
- return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
- default:
- return 0;
- }
- return 1;
- }
- /*
- convert to bytes by using
- dc = 0 for commands
- dc = 1 for args and data
- */
- uint8_t u8x8_cad_011(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
- {
- switch(msg)
- {
- case U8X8_MSG_CAD_SEND_CMD:
- u8x8_byte_SetDC(u8x8, 0);
- u8x8_byte_SendByte(u8x8, arg_int);
- break;
- case U8X8_MSG_CAD_SEND_ARG:
- u8x8_byte_SetDC(u8x8, 1);
- u8x8_byte_SendByte(u8x8, arg_int);
- break;
- case U8X8_MSG_CAD_SEND_DATA:
- u8x8_byte_SetDC(u8x8, 1);
- //u8x8_byte_SendBytes(u8x8, arg_int, arg_ptr);
- //break;
- /* fall through */
- case U8X8_MSG_CAD_INIT:
- case U8X8_MSG_CAD_START_TRANSFER:
- case U8X8_MSG_CAD_END_TRANSFER:
- return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
- default:
- return 0;
- }
- return 1;
- }
- /* cad procedure for the ST7920 in SPI mode */
- /* u8x8_byte_SetDC is not used */
- uint8_t u8x8_cad_st7920_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
- {
- uint8_t *data;
- uint8_t b;
- uint8_t i;
- static uint8_t buf[16];
- uint8_t *ptr;
-
- switch(msg)
- {
- case U8X8_MSG_CAD_SEND_CMD:
- u8x8_byte_SendByte(u8x8, 0x0f8);
- u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, 1);
- u8x8_byte_SendByte(u8x8, arg_int & 0x0f0);
- u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, 1);
- u8x8_byte_SendByte(u8x8, arg_int << 4);
- u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, 1);
- break;
- case U8X8_MSG_CAD_SEND_ARG:
- u8x8_byte_SendByte(u8x8, 0x0f8);
- u8x8_byte_SendByte(u8x8, arg_int & 0x0f0);
- u8x8_byte_SendByte(u8x8, arg_int << 4);
- break;
- case U8X8_MSG_CAD_SEND_DATA:
-
- u8x8_byte_SendByte(u8x8, 0x0fa);
- u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, 1);
- /* this loop should be optimized: multiple bytes should be sent */
- /* u8x8_byte_SendBytes(u8x8, arg_int, arg_ptr); */
- data = (uint8_t *)arg_ptr;
-
- /* the following loop increases speed by 20% */
- while( arg_int >= 8 )
- {
- i = 8;
- ptr = buf;
- do
- {
- b = *data++;
- *ptr++= b & 0x0f0;
- b <<= 4;
- *ptr++= b;
- i--;
- } while( i > 0 );
- arg_int -= 8;
- u8x8_byte_SendBytes(u8x8, 16, buf);
- }
-
-
- while( arg_int > 0 )
- {
- b = *data;
- u8x8_byte_SendByte(u8x8, b & 0x0f0);
- u8x8_byte_SendByte(u8x8, b << 4);
- data++;
- arg_int--;
- }
- u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, 1);
- break;
- case U8X8_MSG_CAD_INIT:
- case U8X8_MSG_CAD_START_TRANSFER:
- case U8X8_MSG_CAD_END_TRANSFER:
- return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
- default:
- return 0;
- }
- return 1;
- }
- /* cad procedure for the SSD13xx family in I2C mode */
- /* this procedure is also used by the ST7588 */
- /* u8x8_byte_SetDC is not used */
- /* U8X8_MSG_BYTE_START_TRANSFER starts i2c transfer, U8X8_MSG_BYTE_END_TRANSFER stops transfer */
- /* After transfer start, a full byte indicates command or data mode */
- static void u8x8_i2c_data_transfer(u8x8_t *u8x8, uint8_t arg_int, void *arg_ptr) U8X8_NOINLINE;
- static void u8x8_i2c_data_transfer(u8x8_t *u8x8, uint8_t arg_int, void *arg_ptr)
- {
- u8x8_byte_StartTransfer(u8x8);
- u8x8_byte_SendByte(u8x8, 0x040);
- u8x8->byte_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, arg_int, arg_ptr);
- u8x8_byte_EndTransfer(u8x8);
- }
- /* classic version: will put a start/stop condition around each command and arg */
- uint8_t u8x8_cad_ssd13xx_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
- {
- uint8_t *p;
- switch(msg)
- {
- case U8X8_MSG_CAD_SEND_CMD:
- case U8X8_MSG_CAD_SEND_ARG:
- /* 7 Nov 2016: Can this be improved? */
- //u8x8_byte_SetDC(u8x8, 0);
- u8x8_byte_StartTransfer(u8x8);
- //u8x8_byte_SendByte(u8x8, u8x8_GetI2CAddress(u8x8));
- u8x8_byte_SendByte(u8x8, 0x000);
- u8x8_byte_SendByte(u8x8, arg_int);
- u8x8_byte_EndTransfer(u8x8);
- break;
- case U8X8_MSG_CAD_SEND_DATA:
- //u8x8_byte_SetDC(u8x8, 1);
-
- /* the FeatherWing OLED with the 32u4 transfer of long byte */
- /* streams was not possible. This is broken down to */
- /* smaller streams, 32 seems to be the limit... */
- /* I guess this is related to the size of the Wire buffers in Arduino */
- /* Unfortunately, this can not be handled in the byte level drivers, */
- /* so this is done here. Even further, only 24 bytes will be sent, */
- /* because there will be another byte (DC) required during the transfer */
- p = arg_ptr;
- while( arg_int > 24 )
- {
- u8x8_i2c_data_transfer(u8x8, 24, p);
- arg_int-=24;
- p+=24;
- }
- u8x8_i2c_data_transfer(u8x8, arg_int, p);
- break;
- case U8X8_MSG_CAD_INIT:
- /* apply default i2c adr if required so that the start transfer msg can use this */
- if ( u8x8->i2c_address == 255 )
- u8x8->i2c_address = 0x078;
- return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
- case U8X8_MSG_CAD_START_TRANSFER:
- case U8X8_MSG_CAD_END_TRANSFER:
- /* cad transfer commands are ignored */
- break;
- default:
- return 0;
- }
- return 1;
- }
- /* fast version with reduced data start/stops, issue 735 */
- uint8_t u8x8_cad_ssd13xx_fast_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
- {
- static uint8_t in_transfer = 0;
- uint8_t *p;
- switch(msg)
- {
- case U8X8_MSG_CAD_SEND_CMD:
- /* improved version, takeover from ld7032 */
- /* assumes, that the args of a command is not longer than 31 bytes */
- /* speed improvement is about 4% compared to the classic version */
- if ( in_transfer != 0 )
- u8x8_byte_EndTransfer(u8x8);
-
- u8x8_byte_StartTransfer(u8x8);
- u8x8_byte_SendByte(u8x8, 0x000); /* cmd byte for ssd13xx controller */
- u8x8_byte_SendByte(u8x8, arg_int);
- in_transfer = 1;
- /* lightning version: can replace the improved version from above */
- /* the drawback of the lightning version is this: The complete init sequence */
- /* must fit into the 32 byte Arduino Wire buffer, which might not always be the case */
- /* speed improvement is about 6% compared to the classic version */
- // if ( in_transfer == 0 )
- // {
- // u8x8_byte_StartTransfer(u8x8);
- // u8x8_byte_SendByte(u8x8, 0x000); /* cmd byte for ssd13xx controller */
- // in_transfer = 1;
- // }
- //u8x8_byte_SendByte(u8x8, arg_int);
- break;
- case U8X8_MSG_CAD_SEND_ARG:
- u8x8_byte_SendByte(u8x8, arg_int);
- break;
- case U8X8_MSG_CAD_SEND_DATA:
- if ( in_transfer != 0 )
- u8x8_byte_EndTransfer(u8x8);
-
-
- /* the FeatherWing OLED with the 32u4 transfer of long byte */
- /* streams was not possible. This is broken down to */
- /* smaller streams, 32 seems to be the limit... */
- /* I guess this is related to the size of the Wire buffers in Arduino */
- /* Unfortunately, this can not be handled in the byte level drivers, */
- /* so this is done here. Even further, only 24 bytes will be sent, */
- /* because there will be another byte (DC) required during the transfer */
- p = arg_ptr;
- while( arg_int > 24 )
- {
- u8x8_i2c_data_transfer(u8x8, 24, p);
- arg_int-=24;
- p+=24;
- }
- u8x8_i2c_data_transfer(u8x8, arg_int, p);
- in_transfer = 0;
- break;
- case U8X8_MSG_CAD_INIT:
- /* apply default i2c adr if required so that the start transfer msg can use this */
- if ( u8x8->i2c_address == 255 )
- u8x8->i2c_address = 0x078;
- return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
- case U8X8_MSG_CAD_START_TRANSFER:
- in_transfer = 0;
- break;
- case U8X8_MSG_CAD_END_TRANSFER:
- if ( in_transfer != 0 )
- u8x8_byte_EndTransfer(u8x8);
- in_transfer = 0;
- break;
- default:
- return 0;
- }
- return 1;
- }
- /* the st75256 i2c driver is a copy of the ssd13xx driver, but with arg=1 */
- /* modified from cad001 (ssd13xx) to cad011 */
- uint8_t u8x8_cad_st75256_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
- {
- uint8_t *p;
- switch(msg)
- {
- case U8X8_MSG_CAD_SEND_CMD:
- u8x8_byte_StartTransfer(u8x8);
- u8x8_byte_SendByte(u8x8, 0x000);
- u8x8_byte_SendByte(u8x8, arg_int);
- u8x8_byte_EndTransfer(u8x8);
- break;
- case U8X8_MSG_CAD_SEND_ARG:
- u8x8_byte_StartTransfer(u8x8);
- u8x8_byte_SendByte(u8x8, 0x040);
- u8x8_byte_SendByte(u8x8, arg_int);
- u8x8_byte_EndTransfer(u8x8);
- break;
- case U8X8_MSG_CAD_SEND_DATA:
- /* see ssd13xx driver */
- p = arg_ptr;
- while( arg_int > 24 )
- {
- u8x8_i2c_data_transfer(u8x8, 24, p);
- arg_int-=24;
- p+=24;
- }
- u8x8_i2c_data_transfer(u8x8, arg_int, p);
- break;
- case U8X8_MSG_CAD_INIT:
- /* apply default i2c adr if required so that the start transfer msg can use this */
- if ( u8x8->i2c_address == 255 )
- u8x8->i2c_address = 0x078; /* ST75256, often this is 0x07e */
- return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
- case U8X8_MSG_CAD_START_TRANSFER:
- case U8X8_MSG_CAD_END_TRANSFER:
- /* cad transfer commands are ignored */
- break;
- default:
- return 0;
- }
- return 1;
- }
- /* cad i2c procedure for the ld7032 controller */
- /* Issue https://github.com/olikraus/u8g2/issues/865 mentiones, that I2C does not work */
- /* Workaround is to remove the while loop (or increase the value in the condition) */
- uint8_t u8x8_cad_ld7032_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
- {
- static uint8_t in_transfer = 0;
- uint8_t *p;
- switch(msg)
- {
- case U8X8_MSG_CAD_SEND_CMD:
- if ( in_transfer != 0 )
- u8x8_byte_EndTransfer(u8x8);
- u8x8_byte_StartTransfer(u8x8);
- u8x8_byte_SendByte(u8x8, arg_int);
- in_transfer = 1;
- break;
- case U8X8_MSG_CAD_SEND_ARG:
- u8x8_byte_SendByte(u8x8, arg_int);
- break;
- case U8X8_MSG_CAD_SEND_DATA:
- //u8x8_byte_SetDC(u8x8, 1);
-
- /* the FeatherWing OLED with the 32u4 transfer of long byte */
- /* streams was not possible. This is broken down to */
- /* smaller streams, 32 seems to be the limit... */
- /* I guess this is related to the size of the Wire buffers in Arduino */
- /* Unfortunately, this can not be handled in the byte level drivers, */
- /* so this is done here. Even further, only 24 bytes will be sent, */
- /* because there will be another byte (DC) required during the transfer */
- p = arg_ptr;
- while( arg_int > 24 )
- {
- u8x8->byte_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, 24, p);
- arg_int-=24;
- p+=24;
- u8x8_byte_EndTransfer(u8x8);
- u8x8_byte_StartTransfer(u8x8);
- u8x8_byte_SendByte(u8x8, 0x08); /* data write for LD7032 */
- }
- u8x8->byte_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, arg_int, p);
- break;
- case U8X8_MSG_CAD_INIT:
- /* apply default i2c adr if required so that the start transfer msg can use this */
- if ( u8x8->i2c_address == 255 )
- u8x8->i2c_address = 0x060;
- return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
- case U8X8_MSG_CAD_START_TRANSFER:
- in_transfer = 0;
- break;
- case U8X8_MSG_CAD_END_TRANSFER:
- if ( in_transfer != 0 )
- u8x8_byte_EndTransfer(u8x8);
- break;
- default:
- return 0;
- }
- return 1;
- }
- /* cad procedure for the UC16xx family in I2C mode */
- /* u8x8_byte_SetDC is not used */
- /* DC bit is encoded into the adr byte */
- uint8_t u8x8_cad_uc16xx_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
- {
- static uint8_t in_transfer = 0;
- static uint8_t is_data = 0;
- uint8_t *p;
- switch(msg)
- {
- case U8X8_MSG_CAD_SEND_CMD:
- case U8X8_MSG_CAD_SEND_ARG:
- if ( in_transfer != 0 )
- {
- if ( is_data != 0 )
- {
- /* transfer mode is active, but data transfer */
- u8x8_byte_EndTransfer(u8x8);
- /* clear the lowest two bits of the adr */
- u8x8_SetI2CAddress( u8x8, u8x8_GetI2CAddress(u8x8)&0x0fc );
- u8x8_byte_StartTransfer(u8x8);
- }
- }
- else
- {
- /* clear the lowest two bits of the adr */
- u8x8_SetI2CAddress( u8x8, u8x8_GetI2CAddress(u8x8)&0x0fc );
- u8x8_byte_StartTransfer(u8x8);
- }
- u8x8_byte_SendByte(u8x8, arg_int);
- in_transfer = 1;
- break;
- case U8X8_MSG_CAD_SEND_DATA:
- if ( in_transfer != 0 )
- {
- if ( is_data == 0 )
- {
- /* transfer mode is active, but data transfer */
- u8x8_byte_EndTransfer(u8x8);
- /* clear the lowest two bits of the adr */
- u8x8_SetI2CAddress( u8x8, (u8x8_GetI2CAddress(u8x8)&0x0fc)|2 );
- u8x8_byte_StartTransfer(u8x8);
- }
- }
- else
- {
- /* clear the lowest two bits of the adr */
- u8x8_SetI2CAddress( u8x8, (u8x8_GetI2CAddress(u8x8)&0x0fc)|2 );
- u8x8_byte_StartTransfer(u8x8);
- }
- in_transfer = 1;
-
- p = arg_ptr;
- while( arg_int > 24 )
- {
- u8x8->byte_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, 24, p);
- arg_int-=24;
- p+=24;
- u8x8_byte_EndTransfer(u8x8);
- u8x8_byte_StartTransfer(u8x8);
- }
- u8x8->byte_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, arg_int, p);
-
- break;
- case U8X8_MSG_CAD_INIT:
- /* apply default i2c adr if required so that the start transfer msg can use this */
- if ( u8x8->i2c_address == 255 )
- u8x8->i2c_address = 0x070;
- return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
- case U8X8_MSG_CAD_START_TRANSFER:
- in_transfer = 0;
- /* actual start is delayed, because we do not whether this is data or cmd transfer */
- break;
- case U8X8_MSG_CAD_END_TRANSFER:
- if ( in_transfer != 0 )
- u8x8_byte_EndTransfer(u8x8);
- in_transfer = 0;
- break;
- default:
- return 0;
- }
- return 1;
- }
|