pcd8544.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  1. // Copyright 2021 IOsetting <iosetting(at)outlook.com>
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "pcd8544.h"
  15. #include <string.h>
  16. /* PCD8544 data buffer */
  17. uint8_t PCD8544_currentX = 0;
  18. uint8_t PCD8544_currentY = 0;
  19. static __XDATA uint8_t PCD8544_Buffer[PCD8544_WIDTH * PCD8544_HEIGHT / 8];
  20. void PCD8544_WriteData(uint8_t dat)
  21. {
  22. PCD8544_CS = 0;
  23. SPI_TxRx(dat);
  24. PCD8544_CS = 1;
  25. }
  26. void PCD8544_WriteSameData(uint8_t dat, uint32_t size)
  27. {
  28. PCD8544_CS = 0;
  29. do
  30. {
  31. SPI_TxRx(dat);
  32. } while (--size);
  33. PCD8544_CS = 1;
  34. }
  35. void PCD8544_WriteCommand(uint8_t command)
  36. {
  37. PCD8544_DC = 0;
  38. PCD8544_WriteData(command);
  39. PCD8544_DC = 1;
  40. }
  41. static void PCD8544_Transmit(const uint8_t *pDat, uint32_t size)
  42. {
  43. PCD8544_CS = 0;
  44. do
  45. {
  46. SPI_TxRx(*pDat++);
  47. } while (--size);
  48. PCD8544_CS = 1;
  49. }
  50. void PCD8544_Reset(void)
  51. {
  52. PCD8544_RES = 0;
  53. SYS_Delay(5);
  54. PCD8544_RES = 1;
  55. }
  56. void PCD8544_SetPowerDownMode(HAL_State_t state)
  57. {
  58. if (state == HAL_State_ON)
  59. PCD8544_WriteCommand(PCD8544_FUNCTIONSET | PCD8544_POWERDOWN);
  60. else
  61. PCD8544_WriteCommand(PCD8544_FUNCTIONSET);
  62. }
  63. void PCD8544_clear(void)
  64. {
  65. PCD8544_WriteCommand(0x0c);
  66. PCD8544_WriteCommand(0x80);
  67. PCD8544_WriteSameData(0x00, PCD8544_WIDTH * PCD8544_HEIGHT);
  68. }
  69. void PCD8544_SetBias(uint8_t val)
  70. {
  71. val = val & 0x07;
  72. PCD8544_WriteCommand(PCD8544_FUNCTIONSET | PCD8544_EXT_INSTRUCTION);
  73. PCD8544_WriteCommand(PCD8544_SET_BIAS | val);
  74. PCD8544_WriteCommand(PCD8544_FUNCTIONSET);
  75. }
  76. void PCD8544_SetContrast(uint8_t bias, uint8_t val)
  77. {
  78. bias = bias & 0x07;
  79. val = val & 0x7F;
  80. // Extended instruction set
  81. PCD8544_WriteCommand(PCD8544_FUNCTIONSET | PCD8544_EXT_INSTRUCTION);
  82. // Set Bias System, value can be [0x03, 0x07]
  83. PCD8544_WriteCommand(PCD8544_SET_BIAS | bias);
  84. // Set Vop, value can be [0x01, 0x7F]
  85. PCD8544_WriteCommand(PCD8544_SET_VOP | val);
  86. // Change back to basic instruction set
  87. PCD8544_WriteCommand(PCD8544_FUNCTIONSET);
  88. }
  89. void PCD8544_SetTemperatureCoef(uint8_t val)
  90. {
  91. val = val & 0x03;
  92. PCD8544_WriteCommand(PCD8544_FUNCTIONSET | PCD8544_EXT_INSTRUCTION);
  93. PCD8544_WriteCommand(PCD8544_SET_TEMP | val);
  94. PCD8544_WriteCommand(PCD8544_FUNCTIONSET);
  95. }
  96. void PCD8544_SetDisplayAllOn(void)
  97. {
  98. PCD8544_WriteCommand(PCD8544_DISPLAY_CONTROL | PCD8544_DISPLAY_ALLON);
  99. }
  100. void PCD8544_SetDisplayInverted(void)
  101. {
  102. PCD8544_WriteCommand(PCD8544_DISPLAY_CONTROL | PCD8544_DISPLAY_INVERTED);
  103. }
  104. void PCD8544_SetDisplayBlank(void)
  105. {
  106. PCD8544_WriteCommand(PCD8544_DISPLAY_CONTROL | PCD8544_DISPLAY_BLANK);
  107. }
  108. void PCD8544_SetDisplayNormal(void)
  109. {
  110. PCD8544_WriteCommand(PCD8544_DISPLAY_CONTROL | PCD8544_DISPLAY_NORMAL);
  111. }
  112. void PCD8544_Init(void)
  113. {
  114. PCD8544_Reset();
  115. PCD8544_SetContrast(0x06, 0x20);
  116. PCD8544_SetDisplayNormal();
  117. }
  118. void PCD8544_SetBackLightState(HAL_State_t state)
  119. {
  120. PCD8544_BL = (state == HAL_State_ON)? SET : RESET;
  121. }
  122. void PCD8544_Fill(uint8_t color)
  123. {
  124. /* Set memory */
  125. memset((uint8_t *)PCD8544_Buffer, (color == 0x00) ? 0x00 : 0xFF, sizeof(PCD8544_Buffer));
  126. }
  127. void PCD8544_UpdateScreen(void)
  128. {
  129. uint8_t i = 0, *pt = PCD8544_Buffer;
  130. for (i = 0; i < PCD8544_PAGES; i++)
  131. {
  132. PCD8544_WriteCommand(PCD8544_SET_YADDR | i);
  133. PCD8544_WriteCommand(PCD8544_SET_XADDR);
  134. PCD8544_Transmit(pt + (PCD8544_WIDTH * i), PCD8544_WIDTH);
  135. }
  136. PCD8544_WriteCommand(PCD8544_SET_YADDR);
  137. }
  138. void PCD8544_DrawPixel(uint8_t x, uint8_t y, uint8_t color)
  139. {
  140. if (x >= PCD8544_WIDTH || y >= PCD8544_HEIGHT)
  141. {
  142. /* Error */
  143. return;
  144. }
  145. if (color == 0x01)
  146. {
  147. PCD8544_Buffer[x + (y / 8) * PCD8544_WIDTH] |= 1 << (y % 8);
  148. }
  149. else
  150. {
  151. PCD8544_Buffer[x + (y / 8) * PCD8544_WIDTH] &= ~(1 << (y % 8));
  152. }
  153. }
  154. void PCD8544_DrawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint8_t color)
  155. {
  156. int16_t dx, dy, sx, sy, err, e2, i, tmp;
  157. /* Check for overflow */
  158. if (x0 >= PCD8544_WIDTH)
  159. {
  160. x0 = PCD8544_WIDTH - 1;
  161. }
  162. if (x1 >= PCD8544_WIDTH)
  163. {
  164. x1 = PCD8544_WIDTH - 1;
  165. }
  166. if (y0 >= PCD8544_HEIGHT)
  167. {
  168. y0 = PCD8544_HEIGHT - 1;
  169. }
  170. if (y1 >= PCD8544_HEIGHT)
  171. {
  172. y1 = PCD8544_HEIGHT - 1;
  173. }
  174. dx = (x0 < x1) ? (x1 - x0) : (x0 - x1);
  175. dy = (y0 < y1) ? (y1 - y0) : (y0 - y1);
  176. sx = (x0 < x1) ? 1 : -1;
  177. sy = (y0 < y1) ? 1 : -1;
  178. err = ((dx > dy) ? dx : -dy) / 2;
  179. if (dx == 0)
  180. {
  181. if (y1 < y0)
  182. {
  183. tmp = y1;
  184. y1 = y0;
  185. y0 = tmp;
  186. }
  187. if (x1 < x0)
  188. {
  189. tmp = x1;
  190. x1 = x0;
  191. x0 = tmp;
  192. }
  193. /* Vertical line */
  194. for (i = y0; i <= y1; i++)
  195. {
  196. PCD8544_DrawPixel(x0, i, color);
  197. }
  198. return;
  199. }
  200. if (dy == 0)
  201. {
  202. if (y1 < y0)
  203. {
  204. tmp = y1;
  205. y1 = y0;
  206. y0 = tmp;
  207. }
  208. if (x1 < x0)
  209. {
  210. tmp = x1;
  211. x1 = x0;
  212. x0 = tmp;
  213. }
  214. /* Horizontal line */
  215. for (i = x0; i <= x1; i++)
  216. {
  217. PCD8544_DrawPixel(i, y0, color);
  218. }
  219. return;
  220. }
  221. while (1)
  222. {
  223. PCD8544_DrawPixel(x0, y0, color);
  224. if (x0 == x1 && y0 == y1)
  225. {
  226. break;
  227. }
  228. e2 = err;
  229. if (e2 > -dx)
  230. {
  231. err -= dy;
  232. x0 += sx;
  233. }
  234. if (e2 < dy)
  235. {
  236. err += dx;
  237. y0 += sy;
  238. }
  239. }
  240. }
  241. void PCD8544_GotoXY(uint8_t x, uint8_t y)
  242. {
  243. /* Set write pointers */
  244. PCD8544_currentX = x;
  245. PCD8544_currentY = y;
  246. }
  247. char PCD8544_Putc(char ch, FontDef_t* font, uint8_t color)
  248. {
  249. uint32_t i, b, j, k;
  250. for (i = 0; i < font->height; i++)
  251. {
  252. for (j = 0; j < font->bytes; j++)
  253. {
  254. b = font->dat[((ch - 32) * font->height + i) * font->bytes + j];
  255. if (font->order == 0)
  256. {
  257. for (k = 0; k < 8 && k < font->width - j * 8; k++)
  258. {
  259. if ((b << k) & 0x80)
  260. {
  261. PCD8544_DrawPixel(PCD8544_currentX + (j * 8) + k, (PCD8544_currentY + i), (uint8_t) color);
  262. }
  263. else
  264. {
  265. PCD8544_DrawPixel(PCD8544_currentX + (j * 8) + k, (PCD8544_currentY + i), (uint8_t) !color);
  266. }
  267. }
  268. }
  269. else
  270. {
  271. for (k = 0; k < 8 && k < font->width - j * 8; k++)
  272. {
  273. if (b & (0x0001 << k))
  274. {
  275. PCD8544_DrawPixel(PCD8544_currentX + (j * 8) + k, (PCD8544_currentY + i), (uint8_t) color);
  276. }
  277. else
  278. {
  279. PCD8544_DrawPixel(PCD8544_currentX + (j * 8) + k, (PCD8544_currentY + i), (uint8_t) !color);
  280. }
  281. }
  282. }
  283. }
  284. }
  285. /* Increase pointer */
  286. PCD8544_currentX += font->width + 1;
  287. /* Return character written */
  288. return ch;
  289. }
  290. char PCD8544_Puts(char* str, FontDef_t* Font, uint8_t color)
  291. {
  292. /* Write characters */
  293. while (*str)
  294. {
  295. /* Write character by character */
  296. if (PCD8544_Putc(*str, Font, color) != *str)
  297. {
  298. /* Return error */
  299. return *str;
  300. }
  301. /* Increase string pointer */
  302. str++;
  303. }
  304. /* Everything OK, zero should be returned */
  305. return *str;
  306. }
  307. static __CODE uint8_t Font3x5 [] = {
  308. 0x00, 0x00, 0x00, 0x00, 0x00, // SP
  309. 0x02, 0x02, 0x02, 0x00, 0x02, // !
  310. 0x05, 0x05, 0x00, 0x00, 0x00, // "
  311. 0x05, 0x07, 0x05, 0x07, 0x05, // #
  312. 0x06, 0x03, 0x06, 0x03, 0x02, // $
  313. 0x01, 0x04, 0x02, 0x01, 0x04, // %
  314. 0x03, 0x03, 0x07, 0x05, 0x06, // &
  315. 0x02, 0x02, 0x00, 0x00, 0x00, // '
  316. 0x04, 0x02, 0x02, 0x02, 0x04, // (
  317. 0x01, 0x02, 0x02, 0x02, 0x01, // )
  318. 0x05, 0x02, 0x05, 0x00, 0x00, // *
  319. 0x00, 0x02, 0x07, 0x02, 0x00, // +
  320. 0x00, 0x00, 0x00, 0x02, 0x01, // ,
  321. 0x00, 0x00, 0x07, 0x00, 0x00, // -
  322. 0x00, 0x00, 0x00, 0x00, 0x02, // .
  323. 0x00, 0x04, 0x02, 0x01, 0x00, // /
  324. 0x07, 0x05, 0x05, 0x05, 0x07, // 0
  325. 0x02, 0x03, 0x02, 0x02, 0x07, // 1
  326. 0x07, 0x04, 0x07, 0x01, 0x07, // 2
  327. 0x07, 0x04, 0x06, 0x04, 0x07, // 3
  328. 0x05, 0x05, 0x07, 0x04, 0x04, // 4
  329. 0x07, 0x01, 0x07, 0x04, 0x07, // 5
  330. 0x07, 0x01, 0x07, 0x05, 0x07, // 6
  331. 0x07, 0x04, 0x04, 0x04, 0x04, // 7
  332. 0x07, 0x05, 0x07, 0x05, 0x07, // 8
  333. 0x07, 0x05, 0x07, 0x04, 0x07, // 9
  334. 0x00, 0x02, 0x00, 0x02, 0x00, // :
  335. 0x00, 0x02, 0x00, 0x02, 0x01, // ;
  336. 0x04, 0x02, 0x01, 0x02, 0x04, // <
  337. 0x00, 0x07, 0x00, 0x07, 0x00, // =
  338. 0x01, 0x02, 0x04, 0x02, 0x01, // >
  339. 0x07, 0x04, 0x02, 0x00, 0x02, // ?
  340. 0x02, 0x05, 0x07, 0x01, 0x06, // @
  341. 0x02, 0x05, 0x07, 0x05, 0x05, // A
  342. 0x03, 0x05, 0x03, 0x05, 0x03, // B
  343. 0x06, 0x01, 0x01, 0x01, 0x06, // C
  344. 0x03, 0x05, 0x05, 0x05, 0x03, // D
  345. 0x07, 0x01, 0x07, 0x01, 0x07, // E
  346. 0x07, 0x01, 0x07, 0x01, 0x01, // F
  347. 0x06, 0x01, 0x07, 0x05, 0x06, // G
  348. 0x05, 0x05, 0x07, 0x05, 0x05, // H
  349. 0x07, 0x02, 0x02, 0x02, 0x07, // I
  350. 0x04, 0x04, 0x04, 0x05, 0x02, // J
  351. 0x05, 0x05, 0x03, 0x05, 0x05, // K
  352. 0x01, 0x01, 0x01, 0x01, 0x07, // L
  353. 0x05, 0x07, 0x07, 0x05, 0x05, // M
  354. 0x05, 0x07, 0x07, 0x07, 0x05, // N
  355. 0x02, 0x05, 0x05, 0x05, 0x02, // O
  356. 0x03, 0x05, 0x03, 0x01, 0x01, // P
  357. 0x02, 0x05, 0x05, 0x05, 0x06, // Q
  358. 0x03, 0x05, 0x07, 0x03, 0x05, // R
  359. 0x06, 0x01, 0x02, 0x04, 0x03, // S
  360. 0x07, 0x02, 0x02, 0x02, 0x02, // T
  361. 0x05, 0x05, 0x05, 0x05, 0x02, // U
  362. 0x05, 0x05, 0x05, 0x02, 0x02, // V
  363. 0x05, 0x05, 0x07, 0x07, 0x05, // W
  364. 0x05, 0x05, 0x02, 0x05, 0x05, // X
  365. 0x05, 0x05, 0x02, 0x02, 0x02, // Y
  366. 0x07, 0x04, 0x02, 0x01, 0x07, // Z
  367. 0x03, 0x01, 0x01, 0x01, 0x03, // [
  368. 0x00, 0x01, 0x02, 0x04, 0x00, /* \ */
  369. 0x06, 0x04, 0x04, 0x04, 0x06, // ]
  370. 0x02, 0x05, 0x00, 0x00, 0x00, // ^
  371. 0x00, 0x00, 0x00, 0x00, 0x07, // _
  372. 0x01, 0x02, 0x00, 0x00, 0x00, // `
  373. 0x00, 0x03, 0x06, 0x05, 0x07, // a
  374. 0x01, 0x03, 0x05, 0x05, 0x03, // b
  375. 0x00, 0x06, 0x01, 0x01, 0x06, // c
  376. 0x04, 0x06, 0x05, 0x05, 0x06, // d
  377. 0x00, 0x06, 0x05, 0x03, 0x06, // e
  378. 0x04, 0x02, 0x07, 0x02, 0x02, // f
  379. 0x06, 0x05, 0x07, 0x04, 0x02, // g
  380. 0x01, 0x03, 0x05, 0x05, 0x05, // h
  381. 0x02, 0x00, 0x02, 0x02, 0x02, // i
  382. 0x04, 0x00, 0x04, 0x04, 0x03, // j
  383. 0x01, 0x05, 0x03, 0x03, 0x05, // k
  384. 0x03, 0x02, 0x02, 0x02, 0x07, // l
  385. 0x00, 0x07, 0x07, 0x07, 0x05, // m
  386. 0x00, 0x03, 0x05, 0x05, 0x05, // n
  387. 0x00, 0x02, 0x05, 0x05, 0x02, // o
  388. 0x00, 0x03, 0x05, 0x03, 0x01, // p
  389. 0x00, 0x06, 0x05, 0x06, 0x04, // q
  390. 0x00, 0x06, 0x01, 0x01, 0x01, // r
  391. 0x00, 0x06, 0x03, 0x06, 0x03, // s
  392. 0x02, 0x07, 0x02, 0x02, 0x06, // t
  393. 0x00, 0x05, 0x05, 0x05, 0x06, // u
  394. 0x00, 0x05, 0x05, 0x05, 0x02, // v
  395. 0x00, 0x05, 0x07, 0x07, 0x07, // w
  396. 0x00, 0x05, 0x02, 0x02, 0x05, // x
  397. 0x00, 0x05, 0x06, 0x04, 0x06, // y
  398. 0x00, 0x07, 0x06, 0x03, 0x07, // z
  399. 0x06, 0x02, 0x01, 0x02, 0x06, // {
  400. 0x02, 0x02, 0x02, 0x02, 0x02, // |
  401. 0x03, 0x02, 0x04, 0x02, 0x03, // }
  402. 0x00, 0x06, 0x03, 0x00, 0x00, // ~
  403. 0x07, 0x07, 0x07, 0x07, 0x07, // DEL
  404. };
  405. static __CODE uint8_t Font5x7 [] = {
  406. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
  407. 0x04, 0x04, 0x04, 0x04, 0x00, 0x04, 0x00, // !
  408. 0x0a, 0x0a, 0x0a, 0x00, 0x00, 0x00, 0x00, // "
  409. 0x0a, 0x0a, 0x1f, 0x0a, 0x1f, 0x0a, 0x0a, // #
  410. 0x04, 0x1e, 0x05, 0x0e, 0x14, 0x0f, 0x04, // $
  411. 0x00, 0x19, 0x1a, 0x04, 0x0b, 0x13, 0x00, // %
  412. 0x06, 0x09, 0x05, 0x02, 0x15, 0x09, 0x16, // &
  413. 0x06, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, // '
  414. 0x08, 0x04, 0x02, 0x02, 0x02, 0x04, 0x08, // (
  415. 0x02, 0x04, 0x08, 0x08, 0x08, 0x04, 0x02, // )
  416. 0x00, 0x04, 0x15, 0x0e, 0x15, 0x04, 0x00, // *
  417. 0x00, 0x04, 0x04, 0x1f, 0x04, 0x04, 0x00, // +
  418. 0x00, 0x00, 0x00, 0x00, 0x0c, 0x08, 0x04, // ,
  419. 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, // -
  420. 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, // .
  421. 0x00, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, // /
  422. 0x0e, 0x11, 0x19, 0x15, 0x13, 0x11, 0x0e, // 0
  423. 0x04, 0x06, 0x04, 0x04, 0x04, 0x04, 0x0e, // 1
  424. 0x0e, 0x11, 0x10, 0x08, 0x04, 0x02, 0x1f, // 2
  425. 0x1f, 0x08, 0x04, 0x08, 0x10, 0x11, 0x0e, // 3
  426. 0x08, 0x0c, 0x0a, 0x09, 0x1f, 0x08, 0x08, // 4
  427. 0x1f, 0x01, 0x0f, 0x10, 0x10, 0x11, 0x0e, // 5
  428. 0x0c, 0x02, 0x01, 0x0f, 0x11, 0x11, 0x0e, // 6
  429. 0x1f, 0x10, 0x08, 0x04, 0x02, 0x02, 0x02, // 7
  430. 0x0e, 0x11, 0x11, 0x0e, 0x11, 0x11, 0x0e, // 8
  431. 0x0e, 0x11, 0x11, 0x1e, 0x10, 0x08, 0x06, // 9
  432. 0x00, 0x06, 0x06, 0x00, 0x06, 0x06, 0x00, // :
  433. 0x00, 0x06, 0x06, 0x00, 0x06, 0x04, 0x02, // ;
  434. 0x08, 0x04, 0x02, 0x01, 0x02, 0x04, 0x08, // <
  435. 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, // =
  436. 0x02, 0x04, 0x08, 0x10, 0x08, 0x04, 0x02, // >
  437. 0x0e, 0x11, 0x10, 0x08, 0x04, 0x00, 0x04, // ?
  438. 0x0e, 0x11, 0x10, 0x16, 0x1d, 0x11, 0x0e, // @
  439. 0x0e, 0x11, 0x11, 0x11, 0x1f, 0x11, 0x11, // A
  440. 0x0f, 0x11, 0x11, 0x0f, 0x11, 0x11, 0x0f, // B
  441. 0x0e, 0x11, 0x01, 0x01, 0x01, 0x11, 0x0e, // C
  442. 0x07, 0x09, 0x11, 0x11, 0x11, 0x09, 0x07, // D
  443. 0x1f, 0x01, 0x01, 0x0f, 0x01, 0x01, 0x1f, // E
  444. 0x1f, 0x01, 0x01, 0x0f, 0x01, 0x01, 0x01, // F
  445. 0x0e, 0x11, 0x01, 0x1d, 0x11, 0x11, 0x1e, // G
  446. 0x11, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11, // H
  447. 0x0e, 0x04, 0x04, 0x04, 0x04, 0x04, 0x0e, // I
  448. 0x1c, 0x08, 0x08, 0x08, 0x08, 0x09, 0x06, // J
  449. 0x11, 0x09, 0x05, 0x03, 0x05, 0x09, 0x11, // K
  450. 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1f, // L
  451. 0x11, 0x1b, 0x15, 0x15, 0x11, 0x11, 0x11, // M
  452. 0x11, 0x11, 0x13, 0x15, 0x19, 0x11, 0x11, // N
  453. 0x0e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e, // O
  454. 0x0f, 0x11, 0x11, 0x0f, 0x01, 0x01, 0x01, // P
  455. 0x0e, 0x11, 0x11, 0x11, 0x15, 0x09, 0x16, // Q
  456. 0x0f, 0x11, 0x11, 0x0f, 0x05, 0x09, 0x11, // R
  457. 0x1e, 0x01, 0x01, 0x0e, 0x10, 0x10, 0x0f, // S
  458. 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, // T
  459. 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e, // U
  460. 0x11, 0x11, 0x11, 0x11, 0x11, 0x0a, 0x04, // V
  461. 0x11, 0x11, 0x11, 0x15, 0x15, 0x15, 0x0a, // W
  462. 0x11, 0x11, 0x0a, 0x04, 0x0a, 0x11, 0x11, // X
  463. 0x11, 0x11, 0x11, 0x0a, 0x04, 0x04, 0x04, // Y
  464. 0x1f, 0x10, 0x08, 0x04, 0x02, 0x01, 0x1f, // Z
  465. 0x0e, 0x02, 0x02, 0x02, 0x02, 0x02, 0x0e, // [
  466. 0x15, 0x0a, 0x15, 0x0a, 0x15, 0x0a, 0x15, /* \ */
  467. 0x0e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0e, // ]
  468. 0x04, 0x0a, 0x11, 0x00, 0x00, 0x00, 0x00, // ^
  469. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, // _
  470. 0x02, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, // `
  471. 0x00, 0x00, 0x0e, 0x10, 0x1e, 0x11, 0x1e, // a
  472. 0x01, 0x01, 0x0d, 0x13, 0x11, 0x11, 0x0f, // b
  473. 0x00, 0x00, 0x0e, 0x01, 0x01, 0x11, 0x0e, // c
  474. 0x10, 0x10, 0x16, 0x19, 0x11, 0x11, 0x1e, // d
  475. 0x00, 0x00, 0x0e, 0x11, 0x1f, 0x01, 0x0e, // e
  476. 0x0c, 0x12, 0x02, 0x07, 0x02, 0x02, 0x02, // f
  477. 0x00, 0x1e, 0x11, 0x11, 0x1e, 0x10, 0x0e, // g
  478. 0x01, 0x01, 0x0d, 0x13, 0x11, 0x11, 0x11, // h
  479. 0x04, 0x00, 0x06, 0x04, 0x04, 0x04, 0x0e, // i
  480. 0x08, 0x00, 0x0c, 0x08, 0x08, 0x09, 0x06, // j
  481. 0x01, 0x01, 0x09, 0x05, 0x03, 0x05, 0x09, // k
  482. 0x06, 0x04, 0x04, 0x04, 0x04, 0x04, 0x0e, // l
  483. 0x00, 0x00, 0x0b, 0x15, 0x15, 0x11, 0x11, // m
  484. 0x00, 0x00, 0x0d, 0x13, 0x11, 0x11, 0x11, // n
  485. 0x00, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x0e, // o
  486. 0x00, 0x00, 0x0f, 0x11, 0x0f, 0x01, 0x01, // p
  487. 0x00, 0x00, 0x16, 0x19, 0x1e, 0x10, 0x10, // q
  488. 0x00, 0x00, 0x0d, 0x13, 0x01, 0x01, 0x01, // r
  489. 0x00, 0x00, 0x0e, 0x01, 0x0e, 0x10, 0x0f, // s
  490. 0x02, 0x02, 0x07, 0x02, 0x02, 0x12, 0x0c, // t
  491. 0x00, 0x00, 0x11, 0x11, 0x11, 0x19, 0x16, // u
  492. 0x00, 0x00, 0x11, 0x11, 0x11, 0x0a, 0x04, // v
  493. 0x00, 0x00, 0x11, 0x11, 0x15, 0x15, 0x0a, // w
  494. 0x00, 0x00, 0x11, 0x0a, 0x04, 0x0a, 0x11, // x
  495. 0x00, 0x00, 0x11, 0x11, 0x1e, 0x10, 0x0e, // y
  496. 0x00, 0x00, 0x1f, 0x08, 0x04, 0x02, 0x1f, // z
  497. 0x08, 0x04, 0x04, 0x02, 0x04, 0x04, 0x08, // {
  498. 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, // |
  499. 0x02, 0x04, 0x04, 0x08, 0x04, 0x04, 0x02, // }
  500. 0x00, 0x00, 0x02, 0x15, 0x08, 0x00, 0x00, // ~
  501. 0x00, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x00, //
  502. };
  503. __CODE FontDef_t Font_3x5 = {3, 5, 1, 1, Font3x5};
  504. __CODE FontDef_t Font_5x7 = {5, 7, 1, 1, Font5x7};