U8x8lib.cpp 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092
  1. /*
  2. U8x8lib.cpp
  3. Arduino specific low level functions
  4. Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
  5. Copyright (c) 2016, olikraus@gmail.com
  6. All rights reserved.
  7. Redistribution and use in source and binary forms, with or without modification,
  8. are permitted provided that the following conditions are met:
  9. * Redistributions of source code must retain the above copyright notice, this list
  10. of conditions and the following disclaimer.
  11. * Redistributions in binary form must reproduce the above copyright notice, this
  12. list of conditions and the following disclaimer in the documentation and/or other
  13. materials provided with the distribution.
  14. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  15. CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  16. INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  17. MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
  19. CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  20. SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  21. NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  23. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  24. STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  25. ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  26. ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. */
  28. #include "U8x8lib.h"
  29. #ifdef U8X8_HAVE_HW_SPI
  30. #include <SPI.h>
  31. #endif
  32. #ifdef U8X8_HAVE_HW_I2C
  33. #include <Wire.h>
  34. #endif
  35. /*=============================================*/
  36. size_t U8X8::write(uint8_t v)
  37. {
  38. if ( v == '\n' )
  39. {
  40. ty++;
  41. tx=0;
  42. }
  43. else
  44. {
  45. u8x8_DrawGlyph(&u8x8, tx, ty, v);
  46. tx++;
  47. }
  48. return 1;
  49. }
  50. /*=============================================*/
  51. /* callbacks */
  52. extern "C" uint8_t u8x8_gpio_and_delay_arduino(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, U8X8_UNUSED void *arg_ptr)
  53. {
  54. uint8_t i;
  55. switch(msg)
  56. {
  57. case U8X8_MSG_GPIO_AND_DELAY_INIT:
  58. for( i = 0; i < U8X8_PIN_CNT; i++ )
  59. if ( u8x8->pins[i] != U8X8_PIN_NONE )
  60. {
  61. if ( i < U8X8_PIN_OUTPUT_CNT )
  62. {
  63. pinMode(u8x8->pins[i], OUTPUT);
  64. }
  65. else
  66. {
  67. #ifdef INPUT_PULLUP
  68. pinMode(u8x8->pins[i], INPUT_PULLUP);
  69. #else
  70. pinMode(u8x8->pins[i], OUTPUT);
  71. digitalWrite(u8x8->pins[i], 1);
  72. #endif
  73. }
  74. }
  75. break;
  76. #ifndef __AVR__
  77. /* this case is not compiled for any AVR, because AVR uC are so slow */
  78. /* that this delay does not matter */
  79. case U8X8_MSG_DELAY_NANO:
  80. delayMicroseconds(arg_int==0?0:1);
  81. break;
  82. #endif
  83. case U8X8_MSG_DELAY_10MICRO:
  84. /* not used at the moment */
  85. break;
  86. case U8X8_MSG_DELAY_100NANO:
  87. /* not used at the moment */
  88. break;
  89. case U8X8_MSG_DELAY_MILLI:
  90. delay(arg_int);
  91. break;
  92. case U8X8_MSG_DELAY_I2C:
  93. /* arg_int is 1 or 4: 100KHz (5us) or 400KHz (1.25us) */
  94. delayMicroseconds(arg_int<=2?5:2);
  95. break;
  96. case U8X8_MSG_GPIO_I2C_CLOCK:
  97. case U8X8_MSG_GPIO_I2C_DATA:
  98. if ( arg_int == 0 )
  99. {
  100. pinMode(u8x8_GetPinValue(u8x8, msg), OUTPUT);
  101. digitalWrite(u8x8_GetPinValue(u8x8, msg), 0);
  102. }
  103. else
  104. {
  105. #ifdef INPUT_PULLUP
  106. pinMode(u8x8_GetPinValue(u8x8, msg), INPUT_PULLUP);
  107. #else
  108. pinMode(u8x8_GetPinValue(u8x8, msg), OUTPUT);
  109. digitalWrite(u8x8_GetPinValue(u8x8, msg), 1);
  110. #endif
  111. }
  112. break;
  113. default:
  114. if ( msg >= U8X8_MSG_GPIO(0) )
  115. {
  116. i = u8x8_GetPinValue(u8x8, msg);
  117. if ( i != U8X8_PIN_NONE )
  118. {
  119. if ( u8x8_GetPinIndex(u8x8, msg) < U8X8_PIN_OUTPUT_CNT )
  120. {
  121. digitalWrite(i, arg_int);
  122. }
  123. else
  124. {
  125. u8x8_SetGPIOResult(u8x8, digitalRead(i) == 0 ? 0 : 1);
  126. }
  127. }
  128. break;
  129. }
  130. return 0;
  131. }
  132. return 1;
  133. }
  134. /*=============================================*/
  135. /*
  136. replacement for a more faster u8x8_byte_4wire_sw_spi
  137. in general u8x8_byte_4wire_sw_spi could be a fallback:
  138. uint8_t u8x8_byte_arduino_4wire_sw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  139. {
  140. return u8x8_byte_4wire_sw_spi(u8x8, msg,arg_int, arg_ptr);
  141. }
  142. */
  143. #ifndef __AVR_ARCH__
  144. #define __AVR_ARCH__ 0
  145. #endif
  146. #if !defined(U8X8_USE_PINS)
  147. /* no pin information (very strange), so fallback */
  148. uint8_t u8x8_byte_arduino_4wire_sw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  149. {
  150. return u8x8_byte_4wire_sw_spi(u8x8, msg,arg_int, arg_ptr);
  151. }
  152. #elif __AVR_ARCH__ == 4 || __AVR_ARCH__ == 5 || __AVR_ARCH__ == 51 || __AVR_ARCH__ == 6
  153. /* this function completly replaces u8x8_byte_4wire_sw_spi*/
  154. extern "C" uint8_t u8x8_byte_arduino_4wire_sw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  155. {
  156. uint8_t i, b;
  157. uint8_t *data;
  158. uint8_t takeover_edge = u8x8_GetSPIClockPhase(u8x8);
  159. //uint8_t not_takeover_edge = 1 - takeover_edge;
  160. /* the following static vars are recalculated in U8X8_MSG_BYTE_START_TRANSFER */
  161. /* so, it should be possible to used multiple displays with different pins */
  162. static volatile uint8_t *arduino_clock_port;
  163. static uint8_t arduino_clock_mask;
  164. static uint8_t arduino_clock_n_mask;
  165. static volatile uint8_t *arduino_data_port;
  166. static uint8_t arduino_data_mask;
  167. static uint8_t arduino_data_n_mask;
  168. switch(msg)
  169. {
  170. case U8X8_MSG_BYTE_SEND:
  171. data = (uint8_t *)arg_ptr;
  172. if ( takeover_edge == 0 )
  173. {
  174. while( arg_int > 0 )
  175. {
  176. b = *data;
  177. data++;
  178. arg_int--;
  179. /* issue 156, check for speed */
  180. #if F_CPU <= 17000000
  181. if ( b == 0 )
  182. {
  183. *arduino_data_port &= arduino_data_n_mask;
  184. for( i = 0; i < 8; i++ )
  185. {
  186. *arduino_clock_port |= arduino_clock_mask;
  187. *arduino_clock_port &= arduino_clock_n_mask;
  188. }
  189. }
  190. else
  191. #endif
  192. {
  193. for( i = 0; i < 8; i++ )
  194. {
  195. if ( b & 128 )
  196. *arduino_data_port |= arduino_data_mask;
  197. else
  198. *arduino_data_port &= arduino_data_n_mask;
  199. *arduino_clock_port |= arduino_clock_mask;
  200. b <<= 1;
  201. *arduino_clock_port &= arduino_clock_n_mask;
  202. }
  203. }
  204. }
  205. }
  206. else
  207. {
  208. while( arg_int > 0 )
  209. {
  210. b = *data;
  211. data++;
  212. arg_int--;
  213. /* issue 156, check for speed */
  214. #if F_CPU <= 17000000
  215. if ( b == 0 )
  216. {
  217. *arduino_data_port &= arduino_data_n_mask;
  218. for( i = 0; i < 8; i++ )
  219. {
  220. *arduino_clock_port &= arduino_clock_n_mask;
  221. *arduino_clock_port |= arduino_clock_mask;
  222. }
  223. }
  224. else
  225. #endif
  226. {
  227. for( i = 0; i < 8; i++ )
  228. {
  229. if ( b & 128 )
  230. *arduino_data_port |= arduino_data_mask;
  231. else
  232. *arduino_data_port &= arduino_data_n_mask;
  233. *arduino_clock_port &= arduino_clock_n_mask;
  234. b <<= 1;
  235. *arduino_clock_port |= arduino_clock_mask;
  236. }
  237. }
  238. }
  239. }
  240. break;
  241. case U8X8_MSG_BYTE_INIT:
  242. /* disable chipselect */
  243. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
  244. /* no wait required here */
  245. /* for SPI: setup correct level of the clock signal */
  246. u8x8_gpio_SetSPIClock(u8x8, u8x8_GetSPIClockPhase(u8x8));
  247. break;
  248. case U8X8_MSG_BYTE_SET_DC:
  249. u8x8_gpio_SetDC(u8x8, arg_int);
  250. break;
  251. case U8X8_MSG_BYTE_START_TRANSFER:
  252. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);
  253. u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
  254. /* there is no consistency checking for u8x8->pins[U8X8_PIN_SPI_CLOCK] */
  255. arduino_clock_port = portOutputRegister(digitalPinToPort(u8x8->pins[U8X8_PIN_SPI_CLOCK]));
  256. arduino_clock_mask = digitalPinToBitMask(u8x8->pins[U8X8_PIN_SPI_CLOCK]);
  257. arduino_clock_n_mask = ~arduino_clock_mask;
  258. /* there is no consistency checking for u8x8->pins[U8X8_PIN_SPI_DATA] */
  259. arduino_data_port = portOutputRegister(digitalPinToPort(u8x8->pins[U8X8_PIN_SPI_DATA]));
  260. arduino_data_mask = digitalPinToBitMask(u8x8->pins[U8X8_PIN_SPI_DATA]);
  261. arduino_data_n_mask = ~arduino_data_mask;
  262. break;
  263. case U8X8_MSG_BYTE_END_TRANSFER:
  264. u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
  265. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
  266. break;
  267. default:
  268. return 0;
  269. }
  270. return 1;
  271. }
  272. #else
  273. /* fallback */
  274. uint8_t u8x8_byte_arduino_4wire_sw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  275. {
  276. return u8x8_byte_4wire_sw_spi(u8x8, msg,arg_int, arg_ptr);
  277. }
  278. #endif
  279. /*=============================================*/
  280. extern "C" uint8_t u8x8_byte_arduino_hw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  281. {
  282. #ifdef U8X8_HAVE_HW_SPI
  283. uint8_t *data;
  284. uint8_t internal_spi_mode;
  285. switch(msg)
  286. {
  287. case U8X8_MSG_BYTE_SEND:
  288. // 1.6.5 offers a block transfer, but the problem is, that the
  289. // buffer is overwritten with the incoming data
  290. // so it can not be used...
  291. // SPI.transfer((uint8_t *)arg_ptr, arg_int);
  292. data = (uint8_t *)arg_ptr;
  293. while( arg_int > 0 )
  294. {
  295. SPI.transfer((uint8_t)*data);
  296. data++;
  297. arg_int--;
  298. }
  299. break;
  300. case U8X8_MSG_BYTE_INIT:
  301. /* disable chipselect */
  302. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
  303. /* no wait required here */
  304. /* for SPI: setup correct level of the clock signal */
  305. // removed, use SPI.begin() instead: pinMode(11, OUTPUT);
  306. // removed, use SPI.begin() instead: pinMode(13, OUTPUT);
  307. // removed, use SPI.begin() instead: digitalWrite(13, u8x8_GetSPIClockPhase(u8x8));
  308. /* setup hardware with SPI.begin() instead of previous digitalWrite() and pinMode() calls */
  309. SPI.begin();
  310. break;
  311. case U8X8_MSG_BYTE_SET_DC:
  312. u8x8_gpio_SetDC(u8x8, arg_int);
  313. break;
  314. case U8X8_MSG_BYTE_START_TRANSFER:
  315. /* SPI mode has to be mapped to the mode of the current controller, at least Uno, Due, 101 have different SPI_MODEx values */
  316. internal_spi_mode = 0;
  317. switch(u8x8->display_info->spi_mode)
  318. {
  319. case 0: internal_spi_mode = SPI_MODE0; break;
  320. case 1: internal_spi_mode = SPI_MODE1; break;
  321. case 2: internal_spi_mode = SPI_MODE2; break;
  322. case 3: internal_spi_mode = SPI_MODE3; break;
  323. }
  324. #if ARDUINO >= 10600
  325. SPI.beginTransaction(SPISettings(u8x8->display_info->sck_clock_hz, MSBFIRST, internal_spi_mode));
  326. #else
  327. SPI.begin();
  328. if ( u8x8->display_info->sck_pulse_width_ns < 70 )
  329. SPI.setClockDivider( SPI_CLOCK_DIV2 );
  330. else if ( u8x8->display_info->sck_pulse_width_ns < 140 )
  331. SPI.setClockDivider( SPI_CLOCK_DIV4 );
  332. else
  333. SPI.setClockDivider( SPI_CLOCK_DIV8 );
  334. SPI.setDataMode(internal_spi_mode);
  335. SPI.setBitOrder(MSBFIRST);
  336. #endif
  337. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);
  338. u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
  339. break;
  340. case U8X8_MSG_BYTE_END_TRANSFER:
  341. u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
  342. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
  343. #if ARDUINO >= 10600
  344. SPI.endTransaction();
  345. #else
  346. SPI.end();
  347. #endif
  348. break;
  349. default:
  350. return 0;
  351. }
  352. #else
  353. #endif
  354. return 1;
  355. }
  356. /* issue #244 */
  357. extern "C" uint8_t u8x8_byte_arduino_2nd_hw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  358. {
  359. #ifdef U8X8_HAVE_2ND_HW_SPI
  360. uint8_t *data;
  361. uint8_t internal_spi_mode;
  362. switch(msg)
  363. {
  364. case U8X8_MSG_BYTE_SEND:
  365. // 1.6.5 offers a block transfer, but the problem is, that the
  366. // buffer is overwritten with the incoming data
  367. // so it can not be used...
  368. // SPI.transfer((uint8_t *)arg_ptr, arg_int);
  369. data = (uint8_t *)arg_ptr;
  370. while( arg_int > 0 )
  371. {
  372. SPI1.transfer((uint8_t)*data);
  373. data++;
  374. arg_int--;
  375. }
  376. break;
  377. case U8X8_MSG_BYTE_INIT:
  378. /* disable chipselect */
  379. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
  380. /* no wait required here */
  381. /* for SPI1: setup correct level of the clock signal */
  382. // removed, use SPI.begin() instead: pinMode(11, OUTPUT);
  383. // removed, use SPI.begin() instead: pinMode(13, OUTPUT);
  384. // removed, use SPI.begin() instead: digitalWrite(13, u8x8_GetSPIClockPhase(u8x8));
  385. /* setup hardware with SPI.begin() instead of previous digitalWrite() and pinMode() calls */
  386. SPI1.begin();
  387. break;
  388. case U8X8_MSG_BYTE_SET_DC:
  389. u8x8_gpio_SetDC(u8x8, arg_int);
  390. break;
  391. case U8X8_MSG_BYTE_START_TRANSFER:
  392. /* SPI1 mode has to be mapped to the mode of the current controller, at least Uno, Due, 101 have different SPI_MODEx values */
  393. internal_spi_mode = 0;
  394. switch(u8x8->display_info->spi_mode)
  395. {
  396. case 0: internal_spi_mode = SPI_MODE0; break;
  397. case 1: internal_spi_mode = SPI_MODE1; break;
  398. case 2: internal_spi_mode = SPI_MODE2; break;
  399. case 3: internal_spi_mode = SPI_MODE3; break;
  400. }
  401. #if ARDUINO >= 10600
  402. SPI1.beginTransaction(SPISettings(u8x8->display_info->sck_clock_hz, MSBFIRST, internal_spi_mode));
  403. #else
  404. SPI1.begin();
  405. if ( u8x8->display_info->sck_pulse_width_ns < 70 )
  406. SPI1.setClockDivider( SPI_CLOCK_DIV2 );
  407. else if ( u8x8->display_info->sck_pulse_width_ns < 140 )
  408. SPI1.setClockDivider( SPI_CLOCK_DIV4 );
  409. else
  410. SPI1.setClockDivider( SPI_CLOCK_DIV8 );
  411. SPI1.setDataMode(internal_spi_mode);
  412. SPI1.setBitOrder(MSBFIRST);
  413. #endif
  414. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);
  415. u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
  416. break;
  417. case U8X8_MSG_BYTE_END_TRANSFER:
  418. u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
  419. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
  420. #if ARDUINO >= 10600
  421. SPI1.endTransaction();
  422. #else
  423. SPI1.end();
  424. #endif
  425. break;
  426. default:
  427. return 0;
  428. }
  429. #else
  430. #endif
  431. return 1;
  432. }
  433. /*=============================================*/
  434. extern "C" uint8_t u8x8_byte_arduino_hw_i2c(U8X8_UNUSED u8x8_t *u8x8, U8X8_UNUSED uint8_t msg, U8X8_UNUSED uint8_t arg_int, U8X8_UNUSED void *arg_ptr)
  435. {
  436. #ifdef U8X8_HAVE_HW_I2C
  437. switch(msg)
  438. {
  439. case U8X8_MSG_BYTE_SEND:
  440. Wire.write((uint8_t *)arg_ptr, (int)arg_int);
  441. break;
  442. case U8X8_MSG_BYTE_INIT:
  443. #ifdef ESP8266
  444. /* for ESP8266, Wire.begin has two more arguments: clock and data */
  445. if ( u8x8->pins[U8X8_PIN_I2C_CLOCK] != U8X8_PIN_NONE && u8x8->pins[U8X8_PIN_I2C_DATA] != U8X8_PIN_NONE )
  446. {
  447. // second argument for the wire lib is the clock pin. In u8g2, the first argument of the clock pin in the clock/data pair
  448. Wire.begin(u8x8->pins[U8X8_PIN_I2C_DATA] , u8x8->pins[U8X8_PIN_I2C_CLOCK]);
  449. }
  450. else
  451. {
  452. Wire.begin();
  453. }
  454. #else
  455. Wire.begin();
  456. #endif
  457. break;
  458. case U8X8_MSG_BYTE_SET_DC:
  459. break;
  460. case U8X8_MSG_BYTE_START_TRANSFER:
  461. #if ARDUINO >= 10600
  462. /* not sure when the setClock function was introduced, but it is there since 1.6.0 */
  463. /* if there is any error with Wire.setClock() just remove this function call */
  464. if ( u8x8->display_info->i2c_bus_clock_100kHz >= 4 )
  465. {
  466. Wire.setClock(400000L);
  467. }
  468. #endif
  469. Wire.beginTransmission(u8x8_GetI2CAddress(u8x8)>>1);
  470. break;
  471. case U8X8_MSG_BYTE_END_TRANSFER:
  472. Wire.endTransmission();
  473. break;
  474. default:
  475. return 0;
  476. }
  477. #endif
  478. return 1;
  479. }
  480. extern "C" uint8_t u8x8_byte_arduino_2nd_hw_i2c(U8X8_UNUSED u8x8_t *u8x8, U8X8_UNUSED uint8_t msg, U8X8_UNUSED uint8_t arg_int, U8X8_UNUSED void *arg_ptr)
  481. {
  482. #ifdef U8X8_HAVE_2ND_HW_I2C
  483. switch(msg)
  484. {
  485. case U8X8_MSG_BYTE_SEND:
  486. Wire1.write((uint8_t *)arg_ptr, (int)arg_int);
  487. break;
  488. case U8X8_MSG_BYTE_INIT:
  489. Wire1.begin();
  490. break;
  491. case U8X8_MSG_BYTE_SET_DC:
  492. break;
  493. case U8X8_MSG_BYTE_START_TRANSFER:
  494. #if ARDUINO >= 10600
  495. /* not sure when the setClock function was introduced, but it is there since 1.6.0 */
  496. /* if there is any error with Wire.setClock() just remove this function call */
  497. if ( u8x8->display_info->i2c_bus_clock_100kHz >= 4 )
  498. {
  499. Wire1.setClock(400000L);
  500. }
  501. #endif
  502. Wire1.beginTransmission(u8x8_GetI2CAddress(u8x8)>>1);
  503. break;
  504. case U8X8_MSG_BYTE_END_TRANSFER:
  505. Wire1.endTransmission();
  506. break;
  507. default:
  508. return 0;
  509. }
  510. #endif
  511. return 1;
  512. }
  513. /*=============================================*/
  514. /*
  515. replacement for a more faster u8x8_byte_8bit_8080mode
  516. in general u8x8_byte_8bit_8080mode could be a fallback:
  517. uint8_t u8x8_byte_arduino_8bit_8080mode(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  518. {
  519. return u8x8_byte_8bit_8080mode(u8x8, msg,arg_int, arg_ptr);
  520. }
  521. */
  522. #ifndef __AVR_ARCH__
  523. #define __AVR_ARCH__ 0
  524. #endif
  525. #if !defined(U8X8_USE_PINS)
  526. /* no pin information (very strange), so fallback */
  527. extern "C" uint8_t u8x8_byte_arduino_8bit_8080mode(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  528. {
  529. return u8x8_byte_8bit_8080mode(u8x8, msg,arg_int, arg_ptr);
  530. }
  531. #elif __AVR_ARCH__ == 4 || __AVR_ARCH__ == 5 || __AVR_ARCH__ == 51 || __AVR_ARCH__ == 6
  532. /* this function completly replaces u8x8_byte_8bit_8080mode*/
  533. extern "C" uint8_t u8x8_byte_arduino_8bit_8080mode(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  534. {
  535. uint8_t i, b;
  536. uint8_t *data;
  537. /* the following static vars are recalculated in U8X8_MSG_BYTE_START_TRANSFER */
  538. /* so, it should be possible to use multiple displays with different pins */
  539. static volatile uint8_t *arduino_e_port;
  540. static volatile uint8_t arduino_e_mask;
  541. static volatile uint8_t arduino_e_n_mask;
  542. static volatile uint8_t *arduino_data_port[8];
  543. static volatile uint8_t arduino_data_mask[8];
  544. static volatile uint8_t arduino_data_n_mask[8];
  545. switch(msg)
  546. {
  547. case U8X8_MSG_BYTE_SEND:
  548. data = (uint8_t *)arg_ptr;
  549. while( arg_int > 0 )
  550. {
  551. b = *data;
  552. data++;
  553. arg_int--;
  554. for( i = 0; i < 8; i++ )
  555. {
  556. if ( b & 1 )
  557. *arduino_data_port[i] |= arduino_data_mask[i];
  558. else
  559. *arduino_data_port[i] &= arduino_data_n_mask[i];
  560. b >>= 1;
  561. }
  562. *arduino_e_port &= arduino_e_n_mask;
  563. /* AVR Architecture is very slow, extra call is not required */
  564. //u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->sda_setup_time_ns);
  565. u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->data_setup_time_ns);
  566. *arduino_e_port |= arduino_e_mask;
  567. /* AVR Architecture is very slow, extra call is not required */
  568. //u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->sck_pulse_width_ns);
  569. u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->write_pulse_width_ns);
  570. }
  571. break;
  572. case U8X8_MSG_BYTE_INIT:
  573. /* disable chipselect */
  574. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
  575. /* no wait required here */
  576. /* ensure that the enable signal is high */
  577. u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 1);
  578. break;
  579. case U8X8_MSG_BYTE_SET_DC:
  580. u8x8_gpio_SetDC(u8x8, arg_int);
  581. break;
  582. case U8X8_MSG_BYTE_START_TRANSFER:
  583. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);
  584. u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
  585. /* there is no consistency checking for u8x8->pins[U8X8_PIN_E] */
  586. arduino_e_port = portOutputRegister(digitalPinToPort(u8x8->pins[U8X8_PIN_E]));
  587. arduino_e_mask = digitalPinToBitMask(u8x8->pins[U8X8_PIN_E]);
  588. arduino_e_n_mask = ~arduino_e_mask;
  589. /* there is no consistency checking for u8x8->pins[U8X8_PIN_D0] */
  590. for( i = 0; i < 8; i++ )
  591. {
  592. arduino_data_port[i] = portOutputRegister(digitalPinToPort(u8x8->pins[U8X8_PIN_D0+i]));
  593. arduino_data_mask[i] = digitalPinToBitMask(u8x8->pins[U8X8_PIN_D0+i]);
  594. arduino_data_n_mask[i] = ~arduino_data_mask[i];
  595. }
  596. break;
  597. case U8X8_MSG_BYTE_END_TRANSFER:
  598. u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
  599. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
  600. break;
  601. default:
  602. return 0;
  603. }
  604. return 1;
  605. }
  606. #else
  607. /* fallback */
  608. extern "C" uint8_t u8x8_byte_arduino_8bit_8080mode(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  609. {
  610. return u8x8_byte_8bit_8080mode(u8x8, msg,arg_int, arg_ptr);
  611. }
  612. #endif
  613. /*=============================================*/
  614. /*
  615. replacement for a more faster u8x8_byte_ks0108
  616. in general u8x8_byte_ks0108 could be a fallback:
  617. uint8_t u8x8_byte_arduino_ks0108(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  618. {
  619. return u8x8_byte_ks0108(u8x8, msg,arg_int, arg_ptr);
  620. }
  621. */
  622. #ifndef __AVR_ARCH__
  623. #define __AVR_ARCH__ 0
  624. #endif
  625. #if !defined(U8X8_USE_PINS)
  626. /* no pin information (very strange), so fallback */
  627. extern "C" uint8_t u8x8_byte_arduino_ks0108(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  628. {
  629. return u8x8_byte_ks0108(u8x8, msg,arg_int, arg_ptr);
  630. }
  631. #elif __AVR_ARCH__ == 4 || __AVR_ARCH__ == 5 || __AVR_ARCH__ == 51 || __AVR_ARCH__ == 6
  632. /* this function completly replaces u8x8_byte_ks0108*/
  633. extern "C" uint8_t u8x8_byte_arduino_ks0108(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  634. {
  635. uint8_t i, b;
  636. uint8_t *data;
  637. /* the following static vars are recalculated in U8X8_MSG_BYTE_START_TRANSFER */
  638. /* so, it should be possible to use multiple displays with different pins */
  639. static volatile uint8_t *arduino_e_port;
  640. static volatile uint8_t arduino_e_mask;
  641. static volatile uint8_t arduino_e_n_mask;
  642. static volatile uint8_t *arduino_data_port[8];
  643. static volatile uint8_t arduino_data_mask[8];
  644. static volatile uint8_t arduino_data_n_mask[8];
  645. switch(msg)
  646. {
  647. case U8X8_MSG_BYTE_SEND:
  648. data = (uint8_t *)arg_ptr;
  649. while( arg_int > 0 )
  650. {
  651. b = *data;
  652. data++;
  653. arg_int--;
  654. for( i = 0; i < 8; i++ )
  655. {
  656. if ( b & 1 )
  657. *arduino_data_port[i] |= arduino_data_mask[i];
  658. else
  659. *arduino_data_port[i] &= arduino_data_n_mask[i];
  660. b >>= 1;
  661. }
  662. *arduino_e_port |= arduino_e_mask;
  663. /* AVR Architecture is very slow, extra call is not required */
  664. u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->data_setup_time_ns);
  665. *arduino_e_port &= arduino_e_n_mask;
  666. /* AVR Architecture is very slow, extra call is not required */
  667. u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->write_pulse_width_ns);
  668. }
  669. break;
  670. case U8X8_MSG_BYTE_INIT:
  671. /* disable chipselect */
  672. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
  673. /* no wait required here */
  674. /* ensure that the enable signal is low */
  675. u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 0);
  676. break;
  677. case U8X8_MSG_BYTE_SET_DC:
  678. u8x8_gpio_SetDC(u8x8, arg_int);
  679. break;
  680. case U8X8_MSG_BYTE_START_TRANSFER:
  681. u8x8_byte_set_ks0108_cs(u8x8, arg_int);
  682. u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
  683. /* there is no consistency checking for u8x8->pins[U8X8_PIN_E] */
  684. arduino_e_port = portOutputRegister(digitalPinToPort(u8x8->pins[U8X8_PIN_E]));
  685. arduino_e_mask = digitalPinToBitMask(u8x8->pins[U8X8_PIN_E]);
  686. arduino_e_n_mask = ~arduino_e_mask;
  687. /* there is no consistency checking for u8x8->pins[U8X8_PIN_D0] */
  688. for( i = 0; i < 8; i++ )
  689. {
  690. arduino_data_port[i] = portOutputRegister(digitalPinToPort(u8x8->pins[U8X8_PIN_D0+i]));
  691. arduino_data_mask[i] = digitalPinToBitMask(u8x8->pins[U8X8_PIN_D0+i]);
  692. arduino_data_n_mask[i] = ~arduino_data_mask[i];
  693. }
  694. break;
  695. case U8X8_MSG_BYTE_END_TRANSFER:
  696. u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
  697. u8x8_byte_set_ks0108_cs(u8x8, arg_int);
  698. break;
  699. default:
  700. return 0;
  701. }
  702. return 1;
  703. }
  704. #else
  705. /* fallback */
  706. extern "C" uint8_t u8x8_byte_arduino_ks0108(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  707. {
  708. return u8x8_byte_ks0108(u8x8, msg,arg_int, arg_ptr);
  709. }
  710. #endif
  711. /*
  712. use U8X8_PIN_NONE as value for "reset", if there is no reset line
  713. */
  714. void u8x8_SetPin_4Wire_SW_SPI(u8x8_t *u8x8, uint8_t clock, uint8_t data, uint8_t cs, uint8_t dc, uint8_t reset)
  715. {
  716. u8x8_SetPin(u8x8, U8X8_PIN_SPI_CLOCK, clock);
  717. u8x8_SetPin(u8x8, U8X8_PIN_SPI_DATA, data);
  718. u8x8_SetPin(u8x8, U8X8_PIN_CS, cs);
  719. u8x8_SetPin(u8x8, U8X8_PIN_DC, dc);
  720. u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
  721. }
  722. #ifdef _obsolete_com_specific_setup
  723. void u8x8_Setup_4Wire_SW_SPI(u8x8_t *u8x8, u8x8_msg_cb display_cb, uint8_t clock, uint8_t data, uint8_t cs, uint8_t dc, uint8_t reset)
  724. {
  725. u8x8_Setup(u8x8, display_cb, u8x8_cad_001, u8x8_byte_4wire_sw_spi, u8x8_gpio_and_delay_arduino);
  726. /* assign individual pin values (only for ARDUINO, if pin_list is available) */
  727. u8x8_SetPin(u8x8, U8X8_PIN_SPI_CLOCK, clock);
  728. u8x8_SetPin(u8x8, U8X8_PIN_SPI_DATA, data);
  729. u8x8_SetPin(u8x8, U8X8_PIN_CS, cs);
  730. u8x8_SetPin(u8x8, U8X8_PIN_DC, dc);
  731. u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
  732. }
  733. #endif /* obsolete com specific setup */
  734. void u8x8_SetPin_3Wire_SW_SPI(u8x8_t *u8x8, uint8_t clock, uint8_t data, uint8_t cs, uint8_t reset)
  735. {
  736. u8x8_SetPin(u8x8, U8X8_PIN_SPI_CLOCK, clock);
  737. u8x8_SetPin(u8x8, U8X8_PIN_SPI_DATA, data);
  738. u8x8_SetPin(u8x8, U8X8_PIN_CS, cs);
  739. u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
  740. }
  741. #ifdef _obsolete_com_specific_setup
  742. void u8x8_Setup_3Wire_SW_SPI(u8x8_t *u8x8, u8x8_msg_cb display_cb, uint8_t clock, uint8_t data, uint8_t cs, uint8_t reset)
  743. {
  744. u8x8_Setup(u8x8, display_cb, u8x8_cad_001, u8x8_byte_3wire_sw_spi, u8x8_gpio_and_delay_arduino);
  745. /* assign individual pin values (only for ARDUINO, if pin_list is available) */
  746. u8x8_SetPin(u8x8, U8X8_PIN_SPI_CLOCK, clock);
  747. u8x8_SetPin(u8x8, U8X8_PIN_SPI_DATA, data);
  748. u8x8_SetPin(u8x8, U8X8_PIN_CS, cs);
  749. u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
  750. }
  751. #endif /* obsolete com specific setup */
  752. /*
  753. use U8X8_PIN_NONE as value for "reset", if there is no reset line
  754. */
  755. void u8x8_SetPin_4Wire_HW_SPI(u8x8_t *u8x8, uint8_t cs, uint8_t dc, uint8_t reset)
  756. {
  757. u8x8_SetPin(u8x8, U8X8_PIN_CS, cs);
  758. u8x8_SetPin(u8x8, U8X8_PIN_DC, dc);
  759. u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
  760. }
  761. void u8x8_SetPin_ST7920_HW_SPI(u8x8_t *u8x8, uint8_t cs, uint8_t reset)
  762. {
  763. u8x8_SetPin(u8x8, U8X8_PIN_CS, cs);
  764. u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
  765. }
  766. #ifdef _obsolete_com_specific_setup
  767. void u8x8_Setup_4Wire_HW_SPI(u8x8_t *u8x8, u8x8_msg_cb display_cb, uint8_t cs, uint8_t dc, uint8_t reset)
  768. {
  769. u8x8_Setup(u8x8, display_cb, u8x8_cad_001, u8x8_byte_arduino_hw_spi, u8x8_gpio_and_delay_arduino);
  770. /* assign individual pin values (only for ARDUINO, if pin_list is available) */
  771. u8x8_SetPin(u8x8, U8X8_PIN_CS, cs);
  772. u8x8_SetPin(u8x8, U8X8_PIN_DC, dc);
  773. u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
  774. }
  775. #endif /* obsolete com specific setup */
  776. void u8x8_SetPin_SW_I2C(u8x8_t *u8x8, uint8_t clock, uint8_t data, uint8_t reset)
  777. {
  778. u8x8_SetPin(u8x8, U8X8_PIN_I2C_CLOCK, clock);
  779. u8x8_SetPin(u8x8, U8X8_PIN_I2C_DATA, data);
  780. u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
  781. }
  782. #ifdef _obsolete_com_specific_setup
  783. void u8x8_Setup_SSD13xx_SW_I2C(u8x8_t *u8x8, u8x8_msg_cb display_cb, uint8_t clock, uint8_t data, uint8_t reset)
  784. {
  785. u8x8_Setup(u8x8, display_cb, u8x8_cad_001, u8x8_byte_ssd13xx_sw_i2c, u8x8_gpio_and_delay_arduino);
  786. /* assign individual pin values (only for ARDUINO, if pin_list is available) */
  787. u8x8_SetPin(u8x8, U8X8_PIN_I2C_CLOCK, clock);
  788. u8x8_SetPin(u8x8, U8X8_PIN_I2C_DATA, data);
  789. u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
  790. }
  791. #endif /* obsolete com specific setup */
  792. void u8x8_SetPin_HW_I2C(u8x8_t *u8x8, uint8_t reset, uint8_t clock, uint8_t data)
  793. {
  794. u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
  795. u8x8_SetPin(u8x8, U8X8_PIN_I2C_CLOCK, clock);
  796. u8x8_SetPin(u8x8, U8X8_PIN_I2C_DATA, data);
  797. }
  798. void u8x8_SetPin_8Bit_6800(u8x8_t *u8x8, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, uint8_t enable, uint8_t cs, uint8_t dc, uint8_t reset)
  799. {
  800. u8x8_SetPin(u8x8, U8X8_PIN_D0, d0);
  801. u8x8_SetPin(u8x8, U8X8_PIN_D1, d1);
  802. u8x8_SetPin(u8x8, U8X8_PIN_D2, d2);
  803. u8x8_SetPin(u8x8, U8X8_PIN_D3, d3);
  804. u8x8_SetPin(u8x8, U8X8_PIN_D4, d4);
  805. u8x8_SetPin(u8x8, U8X8_PIN_D5, d5);
  806. u8x8_SetPin(u8x8, U8X8_PIN_D6, d6);
  807. u8x8_SetPin(u8x8, U8X8_PIN_D7, d7);
  808. u8x8_SetPin(u8x8, U8X8_PIN_E, enable);
  809. u8x8_SetPin(u8x8, U8X8_PIN_CS, cs);
  810. u8x8_SetPin(u8x8, U8X8_PIN_DC, dc);
  811. u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
  812. }
  813. #ifdef _obsolete_com_specific_setup
  814. void u8x8_Setup_8Bit_6800(u8x8_t *u8x8, u8x8_msg_cb display_cb, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, uint8_t enable, uint8_t cs, uint8_t dc, uint8_t reset)
  815. {
  816. u8x8_Setup(u8x8, display_cb, u8x8_cad_001, u8x8_byte_8bit_6800mode, u8x8_gpio_and_delay_arduino);
  817. /* assign individual pin values (only for ARDUINO, if pin_list is available) */
  818. u8x8_SetPin(u8x8, U8X8_PIN_D0, d0);
  819. u8x8_SetPin(u8x8, U8X8_PIN_D1, d1);
  820. u8x8_SetPin(u8x8, U8X8_PIN_D2, d2);
  821. u8x8_SetPin(u8x8, U8X8_PIN_D3, d3);
  822. u8x8_SetPin(u8x8, U8X8_PIN_D4, d4);
  823. u8x8_SetPin(u8x8, U8X8_PIN_D5, d5);
  824. u8x8_SetPin(u8x8, U8X8_PIN_D6, d6);
  825. u8x8_SetPin(u8x8, U8X8_PIN_D7, d7);
  826. u8x8_SetPin(u8x8, U8X8_PIN_E, enable);
  827. u8x8_SetPin(u8x8, U8X8_PIN_CS, cs);
  828. u8x8_SetPin(u8x8, U8X8_PIN_DC, dc);
  829. u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
  830. }
  831. #endif /* obsolete com specific setup */
  832. void u8x8_SetPin_8Bit_8080(u8x8_t *u8x8, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, uint8_t wr, uint8_t cs, uint8_t dc, uint8_t reset)
  833. {
  834. u8x8_SetPin(u8x8, U8X8_PIN_D0, d0);
  835. u8x8_SetPin(u8x8, U8X8_PIN_D1, d1);
  836. u8x8_SetPin(u8x8, U8X8_PIN_D2, d2);
  837. u8x8_SetPin(u8x8, U8X8_PIN_D3, d3);
  838. u8x8_SetPin(u8x8, U8X8_PIN_D4, d4);
  839. u8x8_SetPin(u8x8, U8X8_PIN_D5, d5);
  840. u8x8_SetPin(u8x8, U8X8_PIN_D6, d6);
  841. u8x8_SetPin(u8x8, U8X8_PIN_D7, d7);
  842. u8x8_SetPin(u8x8, U8X8_PIN_E, wr);
  843. u8x8_SetPin(u8x8, U8X8_PIN_CS, cs);
  844. u8x8_SetPin(u8x8, U8X8_PIN_DC, dc);
  845. u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
  846. }
  847. #ifdef _obsolete_com_specific_setup
  848. void u8x8_Setup_8Bit_8080(u8x8_t *u8x8, u8x8_msg_cb display_cb, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, uint8_t wr, uint8_t cs, uint8_t dc, uint8_t reset)
  849. {
  850. u8x8_Setup(u8x8, display_cb, u8x8_cad_001, u8x8_byte_8bit_8080mode, u8x8_gpio_and_delay_arduino);
  851. /* assign individual pin values (only for ARDUINO, if pin_list is available) */
  852. u8x8_SetPin(u8x8, U8X8_PIN_D0, d0);
  853. u8x8_SetPin(u8x8, U8X8_PIN_D1, d1);
  854. u8x8_SetPin(u8x8, U8X8_PIN_D2, d2);
  855. u8x8_SetPin(u8x8, U8X8_PIN_D3, d3);
  856. u8x8_SetPin(u8x8, U8X8_PIN_D4, d4);
  857. u8x8_SetPin(u8x8, U8X8_PIN_D5, d5);
  858. u8x8_SetPin(u8x8, U8X8_PIN_D6, d6);
  859. u8x8_SetPin(u8x8, U8X8_PIN_D7, d7);
  860. u8x8_SetPin(u8x8, U8X8_PIN_E, wr);
  861. u8x8_SetPin(u8x8, U8X8_PIN_CS, cs);
  862. u8x8_SetPin(u8x8, U8X8_PIN_DC, dc);
  863. u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
  864. }
  865. #endif /* obsolete com specific setup */
  866. void u8x8_SetPin_KS0108(u8x8_t *u8x8, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, uint8_t enable, uint8_t dc, uint8_t cs0, uint8_t cs1, uint8_t cs2, uint8_t reset)
  867. {
  868. u8x8_SetPin(u8x8, U8X8_PIN_D0, d0);
  869. u8x8_SetPin(u8x8, U8X8_PIN_D1, d1);
  870. u8x8_SetPin(u8x8, U8X8_PIN_D2, d2);
  871. u8x8_SetPin(u8x8, U8X8_PIN_D3, d3);
  872. u8x8_SetPin(u8x8, U8X8_PIN_D4, d4);
  873. u8x8_SetPin(u8x8, U8X8_PIN_D5, d5);
  874. u8x8_SetPin(u8x8, U8X8_PIN_D6, d6);
  875. u8x8_SetPin(u8x8, U8X8_PIN_D7, d7);
  876. u8x8_SetPin(u8x8, U8X8_PIN_E, enable);
  877. u8x8_SetPin(u8x8, U8X8_PIN_DC, dc);
  878. u8x8_SetPin(u8x8, U8X8_PIN_CS, cs0);
  879. u8x8_SetPin(u8x8, U8X8_PIN_CS1, cs1);
  880. u8x8_SetPin(u8x8, U8X8_PIN_CS2, cs2);
  881. u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
  882. }
  883. void u8x8_SetPin_SED1520(u8x8_t *u8x8, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, uint8_t dc, uint8_t e1, uint8_t e2, uint8_t reset)
  884. {
  885. u8x8_SetPin(u8x8, U8X8_PIN_D0, d0);
  886. u8x8_SetPin(u8x8, U8X8_PIN_D1, d1);
  887. u8x8_SetPin(u8x8, U8X8_PIN_D2, d2);
  888. u8x8_SetPin(u8x8, U8X8_PIN_D3, d3);
  889. u8x8_SetPin(u8x8, U8X8_PIN_D4, d4);
  890. u8x8_SetPin(u8x8, U8X8_PIN_D5, d5);
  891. u8x8_SetPin(u8x8, U8X8_PIN_D6, d6);
  892. u8x8_SetPin(u8x8, U8X8_PIN_D7, d7);
  893. u8x8_SetPin(u8x8, U8X8_PIN_E, e1);
  894. u8x8_SetPin(u8x8, U8X8_PIN_CS, e2);
  895. u8x8_SetPin(u8x8, U8X8_PIN_DC, dc);
  896. u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
  897. }