u8x8_byte.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666
  1. /*
  2. u8x8_byte.c
  3. Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
  4. Copyright (c) 2016, olikraus@gmail.com
  5. All rights reserved.
  6. Redistribution and use in source and binary forms, with or without modification,
  7. are permitted provided that the following conditions are met:
  8. * Redistributions of source code must retain the above copyright notice, this list
  9. of conditions and the following disclaimer.
  10. * Redistributions in binary form must reproduce the above copyright notice, this
  11. list of conditions and the following disclaimer in the documentation and/or other
  12. materials provided with the distribution.
  13. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  14. CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  15. INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  16. MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  17. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
  18. CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  19. SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  20. NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  21. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  22. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  23. STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  24. ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  25. ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. #include "u8x8.h"
  28. uint8_t u8x8_byte_SetDC(u8x8_t *u8x8, uint8_t dc)
  29. {
  30. return u8x8->byte_cb(u8x8, U8X8_MSG_BYTE_SET_DC, dc, NULL);
  31. }
  32. uint8_t u8x8_byte_SendBytes(u8x8_t *u8x8, uint8_t cnt, uint8_t *data)
  33. {
  34. return u8x8->byte_cb(u8x8, U8X8_MSG_BYTE_SEND, cnt, (void *)data);
  35. }
  36. uint8_t u8x8_byte_SendByte(u8x8_t *u8x8, uint8_t byte)
  37. {
  38. return u8x8_byte_SendBytes(u8x8, 1, &byte);
  39. }
  40. uint8_t u8x8_byte_StartTransfer(u8x8_t *u8x8)
  41. {
  42. return u8x8->byte_cb(u8x8, U8X8_MSG_BYTE_START_TRANSFER, 0, NULL);
  43. }
  44. uint8_t u8x8_byte_EndTransfer(u8x8_t *u8x8)
  45. {
  46. return u8x8->byte_cb(u8x8, U8X8_MSG_BYTE_END_TRANSFER, 0, NULL);
  47. }
  48. /*=========================================*/
  49. uint8_t u8x8_byte_empty(U8X8_UNUSED u8x8_t *u8x8, uint8_t msg, U8X8_UNUSED uint8_t arg_int, U8X8_UNUSED void *arg_ptr)
  50. {
  51. switch(msg)
  52. {
  53. case U8X8_MSG_BYTE_SEND:
  54. case U8X8_MSG_BYTE_INIT:
  55. case U8X8_MSG_BYTE_SET_DC:
  56. case U8X8_MSG_BYTE_START_TRANSFER:
  57. case U8X8_MSG_BYTE_END_TRANSFER:
  58. break; /* do nothing */
  59. }
  60. return 1; /* always succeed */
  61. }
  62. /*=========================================*/
  63. /*
  64. Uses:
  65. u8x8->display_info->sda_setup_time_ns
  66. u8x8->display_info->sck_pulse_width_ns
  67. u8x8->display_info->spi_mode
  68. u8x8->display_info->chip_disable_level
  69. u8x8->display_info->chip_enable_level
  70. u8x8->display_info->post_chip_enable_wait_ns
  71. u8x8->display_info->pre_chip_disable_wait_ns
  72. Calls to GPIO and DELAY:
  73. U8X8_MSG_DELAY_NANO
  74. U8X8_MSG_GPIO_DC
  75. U8X8_MSG_GPIO_CS
  76. U8X8_MSG_GPIO_CLOCK
  77. U8X8_MSG_GPIO_DATA
  78. Handles:
  79. U8X8_MSG_BYTE_INIT
  80. U8X8_MSG_BYTE_SEND
  81. U8X8_MSG_BYTE_SET_DC
  82. U8X8_MSG_BYTE_START_TRANSFER
  83. U8X8_MSG_BYTE_END_TRANSFER
  84. */
  85. uint8_t u8x8_byte_4wire_sw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  86. {
  87. uint8_t i, b;
  88. uint8_t *data;
  89. uint8_t takeover_edge = u8x8_GetSPIClockPhase(u8x8);
  90. uint8_t not_takeover_edge = 1 - takeover_edge;
  91. switch(msg)
  92. {
  93. case U8X8_MSG_BYTE_SEND:
  94. data = (uint8_t *)arg_ptr;
  95. while( arg_int > 0 )
  96. {
  97. b = *data;
  98. data++;
  99. arg_int--;
  100. for( i = 0; i < 8; i++ )
  101. {
  102. if ( b & 128 )
  103. u8x8_gpio_SetSPIData(u8x8, 1);
  104. else
  105. u8x8_gpio_SetSPIData(u8x8, 0);
  106. b <<= 1;
  107. u8x8_gpio_SetSPIClock(u8x8, not_takeover_edge);
  108. u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->sda_setup_time_ns);
  109. u8x8_gpio_SetSPIClock(u8x8, takeover_edge);
  110. u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->sck_pulse_width_ns);
  111. }
  112. }
  113. break;
  114. case U8X8_MSG_BYTE_INIT:
  115. /* disable chipselect */
  116. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
  117. /* no wait required here */
  118. /* for SPI: setup correct level of the clock signal */
  119. u8x8_gpio_SetSPIClock(u8x8, u8x8_GetSPIClockPhase(u8x8));
  120. break;
  121. case U8X8_MSG_BYTE_SET_DC:
  122. u8x8_gpio_SetDC(u8x8, arg_int);
  123. break;
  124. case U8X8_MSG_BYTE_START_TRANSFER:
  125. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);
  126. u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
  127. break;
  128. case U8X8_MSG_BYTE_END_TRANSFER:
  129. u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
  130. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
  131. break;
  132. default:
  133. return 0;
  134. }
  135. return 1;
  136. }
  137. /*=========================================*/
  138. uint8_t u8x8_byte_8bit_6800mode(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  139. {
  140. uint8_t i, b;
  141. uint8_t *data;
  142. switch(msg)
  143. {
  144. case U8X8_MSG_BYTE_SEND:
  145. data = (uint8_t *)arg_ptr;
  146. while( arg_int > 0 )
  147. {
  148. b = *data;
  149. data++;
  150. arg_int--;
  151. for( i = U8X8_MSG_GPIO_D0; i <= U8X8_MSG_GPIO_D7; i++ )
  152. {
  153. u8x8_gpio_call(u8x8, i, b&1);
  154. b >>= 1;
  155. }
  156. u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->data_setup_time_ns);
  157. u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 1);
  158. u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->write_pulse_width_ns);
  159. u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 0);
  160. }
  161. break;
  162. case U8X8_MSG_BYTE_INIT:
  163. /* disable chipselect */
  164. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
  165. /* ensure that the enable signal is high */
  166. u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 0);
  167. break;
  168. case U8X8_MSG_BYTE_SET_DC:
  169. u8x8_gpio_SetDC(u8x8, arg_int);
  170. break;
  171. case U8X8_MSG_BYTE_START_TRANSFER:
  172. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);
  173. u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
  174. break;
  175. case U8X8_MSG_BYTE_END_TRANSFER:
  176. u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
  177. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
  178. break;
  179. default:
  180. return 0;
  181. }
  182. return 1;
  183. }
  184. uint8_t u8x8_byte_8bit_8080mode(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  185. {
  186. uint8_t i, b;
  187. uint8_t *data;
  188. switch(msg)
  189. {
  190. case U8X8_MSG_BYTE_SEND:
  191. data = (uint8_t *)arg_ptr;
  192. while( arg_int > 0 )
  193. {
  194. b = *data;
  195. data++;
  196. arg_int--;
  197. for( i = U8X8_MSG_GPIO_D0; i <= U8X8_MSG_GPIO_D7; i++ )
  198. {
  199. u8x8_gpio_call(u8x8, i, b&1);
  200. b >>= 1;
  201. }
  202. u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->data_setup_time_ns);
  203. u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 0);
  204. u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->write_pulse_width_ns);
  205. u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 1);
  206. }
  207. break;
  208. case U8X8_MSG_BYTE_INIT:
  209. /* disable chipselect */
  210. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
  211. /* ensure that the enable signal is high */
  212. u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 1);
  213. break;
  214. case U8X8_MSG_BYTE_SET_DC:
  215. u8x8_gpio_SetDC(u8x8, arg_int);
  216. break;
  217. case U8X8_MSG_BYTE_START_TRANSFER:
  218. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);
  219. u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
  220. break;
  221. case U8X8_MSG_BYTE_END_TRANSFER:
  222. u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
  223. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
  224. break;
  225. default:
  226. return 0;
  227. }
  228. return 1;
  229. }
  230. /*=========================================*/
  231. uint8_t u8x8_byte_3wire_sw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  232. {
  233. uint8_t i;
  234. uint8_t *data;
  235. uint8_t takeover_edge = u8x8_GetSPIClockPhase(u8x8);
  236. uint8_t not_takeover_edge = 1 - takeover_edge;
  237. uint16_t b;
  238. static uint8_t last_dc;
  239. switch(msg)
  240. {
  241. case U8X8_MSG_BYTE_SEND:
  242. data = (uint8_t *)arg_ptr;
  243. while( arg_int > 0 )
  244. {
  245. b = *data;
  246. if ( last_dc != 0 )
  247. b |= 256;
  248. data++;
  249. arg_int--;
  250. for( i = 0; i < 9; i++ )
  251. {
  252. if ( b & 256 )
  253. u8x8_gpio_SetSPIData(u8x8, 1);
  254. else
  255. u8x8_gpio_SetSPIData(u8x8, 0);
  256. b <<= 1;
  257. u8x8_gpio_SetSPIClock(u8x8, not_takeover_edge);
  258. u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->sda_setup_time_ns);
  259. u8x8_gpio_SetSPIClock(u8x8, takeover_edge);
  260. u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->sck_pulse_width_ns);
  261. }
  262. }
  263. break;
  264. case U8X8_MSG_BYTE_INIT:
  265. /* disable chipselect */
  266. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
  267. /* no wait required here */
  268. /* for SPI: setup correct level of the clock signal */
  269. u8x8_gpio_SetSPIClock(u8x8, u8x8_GetSPIClockPhase(u8x8));
  270. break;
  271. case U8X8_MSG_BYTE_SET_DC:
  272. last_dc = arg_int;
  273. break;
  274. case U8X8_MSG_BYTE_START_TRANSFER:
  275. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);
  276. u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
  277. break;
  278. case U8X8_MSG_BYTE_END_TRANSFER:
  279. u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
  280. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
  281. break;
  282. default:
  283. return 0;
  284. }
  285. return 1;
  286. }
  287. /*=========================================*/
  288. void u8x8_byte_set_ks0108_cs(u8x8_t *u8x8, uint8_t arg)
  289. {
  290. u8x8_gpio_SetCS(u8x8, arg&1);
  291. arg = arg >> 1;
  292. u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_CS1, arg&1);
  293. arg = arg >> 1;
  294. u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_CS2, arg&1);
  295. }
  296. /* 6800 mode */
  297. uint8_t u8x8_byte_ks0108(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  298. {
  299. uint8_t i, b;
  300. uint8_t *data;
  301. switch(msg)
  302. {
  303. case U8X8_MSG_BYTE_SEND:
  304. data = (uint8_t *)arg_ptr;
  305. while( arg_int > 0 )
  306. {
  307. b = *data;
  308. data++;
  309. arg_int--;
  310. for( i = U8X8_MSG_GPIO_D0; i <= U8X8_MSG_GPIO_D7; i++ )
  311. {
  312. u8x8_gpio_call(u8x8, i, b&1);
  313. b >>= 1;
  314. }
  315. u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->data_setup_time_ns);
  316. u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 1);
  317. u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->write_pulse_width_ns);
  318. u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 0);
  319. }
  320. break;
  321. case U8X8_MSG_BYTE_INIT:
  322. /* disable chipselect */
  323. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
  324. /* ensure that the enable signal is low */
  325. u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 0);
  326. break;
  327. case U8X8_MSG_BYTE_SET_DC:
  328. u8x8_gpio_SetDC(u8x8, arg_int);
  329. break;
  330. case U8X8_MSG_BYTE_START_TRANSFER:
  331. /* expects 3 bits in arg_int for the chip select lines */
  332. u8x8_byte_set_ks0108_cs(u8x8, arg_int);
  333. u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
  334. break;
  335. case U8X8_MSG_BYTE_END_TRANSFER:
  336. u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
  337. u8x8_byte_set_ks0108_cs(u8x8, arg_int);
  338. break;
  339. default:
  340. return 0;
  341. }
  342. return 1;
  343. }
  344. /* sed1520 or sbn1661
  345. U8X8_MSG_GPIO_E --> E1
  346. U8X8_MSG_GPIO_CS --> E2
  347. */
  348. uint8_t u8x8_byte_sed1520(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  349. {
  350. uint8_t i, b;
  351. uint8_t *data;
  352. static uint8_t enable_pin;
  353. switch(msg)
  354. {
  355. case U8X8_MSG_BYTE_SEND:
  356. data = (uint8_t *)arg_ptr;
  357. while( arg_int > 0 )
  358. {
  359. b = *data;
  360. data++;
  361. arg_int--;
  362. for( i = U8X8_MSG_GPIO_D0; i <= U8X8_MSG_GPIO_D7; i++ )
  363. {
  364. u8x8_gpio_call(u8x8, i, b&1);
  365. b >>= 1;
  366. }
  367. u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->data_setup_time_ns);
  368. u8x8_gpio_call(u8x8, enable_pin, 1);
  369. u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, 200); /* KS0108 requires 450 ns, use 200 here */
  370. u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->write_pulse_width_ns); /* expect 250 here */
  371. u8x8_gpio_call(u8x8, enable_pin, 0);
  372. }
  373. break;
  374. case U8X8_MSG_BYTE_INIT:
  375. /* disable chipselect */
  376. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
  377. /* ensure that the enable signals are low */
  378. u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 0);
  379. u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_CS, 0);
  380. enable_pin = U8X8_MSG_GPIO_E;
  381. break;
  382. case U8X8_MSG_BYTE_SET_DC:
  383. u8x8_gpio_SetDC(u8x8, arg_int);
  384. break;
  385. case U8X8_MSG_BYTE_START_TRANSFER:
  386. /* cs lines are not supported for the SED1520/SBN1661 */
  387. /* instead, this will select the E1 or E2 line */
  388. enable_pin = U8X8_MSG_GPIO_E;
  389. if ( arg_int != 0 )
  390. enable_pin = U8X8_MSG_GPIO_CS;
  391. break;
  392. case U8X8_MSG_BYTE_END_TRANSFER:
  393. break;
  394. default:
  395. return 0;
  396. }
  397. return 1;
  398. }
  399. /*=========================================*/
  400. /*
  401. software i2c,
  402. ignores ACK response (which is anyway not provided by some displays)
  403. also does not allow reading from the device
  404. */
  405. static void i2c_delay(u8x8_t *u8x8) U8X8_NOINLINE;
  406. static void i2c_delay(u8x8_t *u8x8)
  407. {
  408. //u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_10MICRO, u8x8->display_info->i2c_bus_clock_100kHz);
  409. u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_I2C, u8x8->display_info->i2c_bus_clock_100kHz);
  410. }
  411. static void i2c_init(u8x8_t *u8x8)
  412. {
  413. u8x8_gpio_SetI2CClock(u8x8, 1);
  414. u8x8_gpio_SetI2CData(u8x8, 1);
  415. i2c_delay(u8x8);
  416. }
  417. /* actually, the scl line is not observed, so this procedure does not return a value */
  418. static void i2c_read_scl_and_delay(u8x8_t *u8x8)
  419. {
  420. /* set as input (line will be high) */
  421. u8x8_gpio_SetI2CClock(u8x8, 1);
  422. i2c_delay(u8x8);
  423. }
  424. static void i2c_clear_scl(u8x8_t *u8x8)
  425. {
  426. u8x8_gpio_SetI2CClock(u8x8, 0);
  427. }
  428. static void i2c_read_sda(u8x8_t *u8x8)
  429. {
  430. /* set as input (line will be high) */
  431. u8x8_gpio_SetI2CData(u8x8, 1);
  432. }
  433. static void i2c_clear_sda(u8x8_t *u8x8)
  434. {
  435. /* set open collector and drive low */
  436. u8x8_gpio_SetI2CData(u8x8, 0);
  437. }
  438. static void i2c_start(u8x8_t *u8x8)
  439. {
  440. if ( u8x8->i2c_started != 0 )
  441. {
  442. /* if already started: do restart */
  443. i2c_read_sda(u8x8); /* SDA = 1 */
  444. i2c_delay(u8x8);
  445. i2c_read_scl_and_delay(u8x8);
  446. }
  447. i2c_read_sda(u8x8);
  448. /* send the start condition, both lines go from 1 to 0 */
  449. i2c_clear_sda(u8x8);
  450. i2c_delay(u8x8);
  451. i2c_clear_scl(u8x8);
  452. u8x8->i2c_started = 1;
  453. }
  454. static void i2c_stop(u8x8_t *u8x8)
  455. {
  456. /* set SDA to 0 */
  457. i2c_clear_sda(u8x8);
  458. i2c_delay(u8x8);
  459. /* now release all lines */
  460. i2c_read_scl_and_delay(u8x8);
  461. /* set SDA to 1 */
  462. i2c_read_sda(u8x8);
  463. i2c_delay(u8x8);
  464. u8x8->i2c_started = 0;
  465. }
  466. static void i2c_write_bit(u8x8_t *u8x8, uint8_t val)
  467. {
  468. if (val)
  469. i2c_read_sda(u8x8);
  470. else
  471. i2c_clear_sda(u8x8);
  472. i2c_delay(u8x8);
  473. i2c_read_scl_and_delay(u8x8);
  474. i2c_clear_scl(u8x8);
  475. }
  476. static void i2c_read_bit(u8x8_t *u8x8)
  477. {
  478. //uint8_t val;
  479. /* do not drive SDA */
  480. i2c_read_sda(u8x8);
  481. i2c_delay(u8x8);
  482. i2c_read_scl_and_delay(u8x8);
  483. i2c_read_sda(u8x8);
  484. i2c_delay(u8x8);
  485. i2c_clear_scl(u8x8);
  486. //return val;
  487. }
  488. static void i2c_write_byte(u8x8_t *u8x8, uint8_t b)
  489. {
  490. i2c_write_bit(u8x8, b & 128);
  491. i2c_write_bit(u8x8, b & 64);
  492. i2c_write_bit(u8x8, b & 32);
  493. i2c_write_bit(u8x8, b & 16);
  494. i2c_write_bit(u8x8, b & 8);
  495. i2c_write_bit(u8x8, b & 4);
  496. i2c_write_bit(u8x8, b & 2);
  497. i2c_write_bit(u8x8, b & 1);
  498. /* read ack from client */
  499. /* 0: ack was given by client */
  500. /* 1: nothing happend during ack cycle */
  501. i2c_read_bit(u8x8);
  502. }
  503. uint8_t u8x8_byte_sw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  504. {
  505. uint8_t *data;
  506. switch(msg)
  507. {
  508. case U8X8_MSG_BYTE_SEND:
  509. data = (uint8_t *)arg_ptr;
  510. while( arg_int > 0 )
  511. {
  512. i2c_write_byte(u8x8, *data);
  513. data++;
  514. arg_int--;
  515. }
  516. break;
  517. case U8X8_MSG_BYTE_INIT:
  518. i2c_init(u8x8);
  519. break;
  520. case U8X8_MSG_BYTE_SET_DC:
  521. break;
  522. case U8X8_MSG_BYTE_START_TRANSFER:
  523. i2c_start(u8x8);
  524. i2c_write_byte(u8x8, u8x8_GetI2CAddress(u8x8));
  525. //i2c_write_byte(u8x8, 0x078);
  526. break;
  527. case U8X8_MSG_BYTE_END_TRANSFER:
  528. i2c_stop(u8x8);
  529. break;
  530. default:
  531. return 0;
  532. }
  533. return 1;
  534. }
  535. /*=========================================*/
  536. /* alternative i2c byte procedure */
  537. #ifdef ALTERNATIVE_I2C_BYTE_PROCEDURE
  538. void i2c_transfer(u8x8_t *u8x8, uint8_t adr, uint8_t cnt, uint8_t *data)
  539. {
  540. uint8_t i;
  541. i2c_start(u8x8);
  542. i2c_write_byte(u8x8, adr);
  543. for( i = 0; i < cnt; i++ )
  544. i2c_write_byte(u8x8, data[i]);
  545. i2c_stop(u8x8);
  546. }
  547. uint8_t u8x8_byte_sw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  548. {
  549. static uint8_t buffer[32]; /* u8g2/u8x8 will never send more than 32 bytes */
  550. static uint8_t buf_idx;
  551. uint8_t *data;
  552. switch(msg)
  553. {
  554. case U8X8_MSG_BYTE_SEND:
  555. data = (uint8_t *)arg_ptr;
  556. while( arg_int > 0 )
  557. {
  558. buffer[buf_idx++] = *data;
  559. data++;
  560. arg_int--;
  561. }
  562. break;
  563. case U8X8_MSG_BYTE_INIT:
  564. i2c_init(u8x8); /* init i2c communication */
  565. break;
  566. case U8X8_MSG_BYTE_SET_DC:
  567. /* ignored for i2c */
  568. break;
  569. case U8X8_MSG_BYTE_START_TRANSFER:
  570. buf_idx = 0;
  571. break;
  572. case U8X8_MSG_BYTE_END_TRANSFER:
  573. i2c_transfer(u8x8, u8x8_GetI2CAddress(u8x8), buf_idx, buffer);
  574. break;
  575. default:
  576. return 0;
  577. }
  578. return 1;
  579. }
  580. #endif