st7567.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557
  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 "st7567.h"
  15. #include <string.h>
  16. /* Absolute value */
  17. #define ABS(x) ((x) > 0 ? (x) : -(x))
  18. /* ST7567 data buffer */
  19. __BIT ST7567_colorInverted = RESET;
  20. uint8_t ST7567_currentX = 0;
  21. uint8_t ST7567_currentY = 0;
  22. static __XDATA uint8_t ST7567_Buffer_all[ST7567_WIDTH * ST7567_PAGES];
  23. void ST7567_WriteData(uint8_t dat)
  24. {
  25. ST7567_CS = 0;
  26. SPI_TxRx(dat);
  27. ST7567_CS = 1;
  28. }
  29. void ST7567_WriteSameData(uint8_t dat, uint32_t size)
  30. {
  31. ST7567_CS = 0;
  32. do
  33. {
  34. SPI_TxRx(dat);
  35. } while (--size);
  36. ST7567_CS = 1;
  37. }
  38. void ST7567_WriteCommand(uint8_t command)
  39. {
  40. ST7567_DC = 0;
  41. ST7567_WriteData(command);
  42. ST7567_DC = 1;
  43. }
  44. static void ST7567_Transmit(const uint8_t *pDat, uint32_t size)
  45. {
  46. ST7567_CS = 0;
  47. do
  48. {
  49. SPI_TxRx(*pDat++);
  50. } while (--size);
  51. ST7567_CS = 1;
  52. }
  53. void ST7567_Reset(void)
  54. {
  55. ST7567_RES = 0;
  56. SYS_Delay(5);
  57. ST7567_RES = 1;
  58. }
  59. void ST7567_Init(void)
  60. {
  61. ST7567_Reset();
  62. ST7567_SetBackLightState(HAL_State_ON);
  63. ST7567_WriteCommand(ST7567_RESET);
  64. // adjust contrast
  65. ST7567_WriteCommand(ST7567_SET_EV);
  66. ST7567_WriteCommand(ST7567_SET_EV_MASK & 0x20);
  67. // adjust regular voltage. LCD may fail to display if it is set too low.
  68. ST7567_WriteCommand(ST7567_REGULATION_RATIO | ST7567_REGULATION_RATIO_5_0);
  69. ST7567_WriteCommand(ST7567_BIAS_1_9);
  70. ST7567_WriteCommand(ST7567_X_ORIENT);
  71. ST7567_WriteCommand(ST7567_Y_ORIENT);
  72. ST7567_WriteCommand(ST7567_INVERSE_DISPLAY_OFF);
  73. // Start from line 0
  74. ST7567_WriteCommand(ST7567_SET_START_LINE | (0x00 & ST7567_SET_START_LINE_MASK));
  75. // Start from page 0
  76. ST7567_WriteCommand(ST7567_SET_PAGE_ADDRESS | (0x00 & ST7567_SET_PAGE_ADDRESS_MASK));
  77. // Start from column 0
  78. ST7567_WriteCommand(ST7567_SET_COLUMN_ADDRESS_MSB | (0x00 & ST7567_SET_COLUMN_ADDRESS_MSB_MASK));
  79. ST7567_WriteCommand(ST7567_SET_COLUMN_ADDRESS_LSB | (0x00 & ST7567_SET_COLUMN_ADDRESS_LSB_MASK));
  80. // power control, LCD may fail to display if it is not properly set.
  81. // recommend to set them all
  82. ST7567_WriteCommand(ST7567_POWER_CONTROL
  83. |ST7567_POWER_CONTROL_VB
  84. |ST7567_POWER_CONTROL_VR
  85. |ST7567_POWER_CONTROL_VF);
  86. ST7567_WriteCommand(ST7567_DISPLAY_ON);
  87. ST7567_WriteCommand(ST7567_ALL_PIXEL_NORMAL);
  88. }
  89. void ST7567_SetPowerSaveMode(HAL_State_t state)
  90. {
  91. #if (ST7567_MODEL == ST7567_MODEL_ST7565)
  92. if (state == HAL_State_ON)
  93. ST7567_WriteCommand(ST7567_MODE_SLEEP);
  94. else
  95. ST7567_WriteCommand(ST7567_MODE_NORMAL);
  96. #else
  97. if (state == HAL_State_ON)
  98. {
  99. ST7567_WriteCommand(ST7567_DISPLAY_OFF);
  100. ST7567_WriteCommand(ST7567_ALL_PIXEL_ON);
  101. }
  102. else
  103. {
  104. ST7567_WriteCommand(ST7567_ALL_PIXEL_NORMAL);
  105. ST7567_WriteCommand(ST7567_DISPLAY_ON);
  106. }
  107. #endif
  108. }
  109. void ST7567_SetBackLightState(HAL_State_t state)
  110. {
  111. ST7567_BL = (state == HAL_State_ON)? SET : RESET;
  112. }
  113. void ST7567_SetContrast(uint8_t val)
  114. {
  115. ST7567_WriteCommand(ST7567_SET_EV);
  116. ST7567_WriteCommand(ST7567_SET_EV_MASK & val);
  117. }
  118. void ST7567_UpdateScreen(void)
  119. {
  120. uint8_t i = 0, *pt = ST7567_Buffer_all;
  121. for (i = 0; i < ST7567_PAGES; i++)
  122. {
  123. ST7567_WriteCommand(ST7567_SET_PAGE_ADDRESS|(i & ST7567_SET_PAGE_ADDRESS_MASK));
  124. ST7567_WriteCommand(ST7567_SET_COLUMN_ADDRESS_MSB|(0 >> 4));
  125. ST7567_WriteCommand(ST7567_SET_COLUMN_ADDRESS_LSB|(0 & 0x0F));
  126. ST7567_Transmit(pt + (ST7567_WIDTH * i), ST7567_WIDTH);
  127. }
  128. }
  129. void ST7567_ToggleInvert(void)
  130. {
  131. /* Toggle invert */
  132. ST7567_colorInverted = !ST7567_colorInverted;
  133. if (ST7567_colorInverted)
  134. {
  135. ST7567_WriteCommand(ST7567_INVERSE_DISPLAY_ON);
  136. }
  137. else
  138. {
  139. ST7567_WriteCommand(ST7567_INVERSE_DISPLAY_OFF);
  140. }
  141. }
  142. void ST7567_Fill(uint8_t color)
  143. {
  144. /* Set memory */
  145. memset((uint8_t *)ST7567_Buffer_all, (color == ST7567_COLOR_BACK) ? 0x00 : 0xFF, sizeof(ST7567_Buffer_all));
  146. }
  147. void ST7567_DrawPixel(uint8_t x, uint8_t y, uint8_t color)
  148. {
  149. uint8_t page, column;
  150. if (x >= ST7567_WIDTH || y >= ST7567_HEIGHT)
  151. {
  152. /* Error */
  153. return;
  154. }
  155. if (color == ST7567_COLOR_FRONT)
  156. {
  157. ST7567_Buffer_all[x + (y / 8) * ST7567_WIDTH] |= 1 << (y % 8);
  158. }
  159. else
  160. {
  161. ST7567_Buffer_all[x + (y / 8) * ST7567_WIDTH] &= ~(1 << (y % 8));
  162. }
  163. }
  164. void ST7567_GotoXY(uint16_t x, uint16_t y)
  165. {
  166. /* Set write pointers */
  167. ST7567_currentX = x;
  168. ST7567_currentY = y;
  169. }
  170. char ST7567_Putc(char ch, FontDef_t* font, uint8_t color)
  171. {
  172. uint32_t i, b, j, k;
  173. for (i = 0; i < font->height; i++)
  174. {
  175. for (j = 0; j < font->bytes; j++)
  176. {
  177. b = font->dat[((ch - 32) * font->height + i) * font->bytes + j];
  178. if (font->order == 0)
  179. {
  180. for (k = 0; k < 8 && k < font->width - j * 8; k++)
  181. {
  182. if ((b << k) & 0x80)
  183. {
  184. ST7567_DrawPixel(ST7567_currentX + (j * 8) + k, (ST7567_currentY + i), (uint8_t) color);
  185. }
  186. else
  187. {
  188. ST7567_DrawPixel(ST7567_currentX + (j * 8) + k, (ST7567_currentY + i), (uint8_t) !color);
  189. }
  190. }
  191. }
  192. else
  193. {
  194. for (k = 0; k < 8 && k < font->width - j * 8; k++)
  195. {
  196. if (b & (0x0001 << k))
  197. {
  198. ST7567_DrawPixel(ST7567_currentX + (j * 8) + k, (ST7567_currentY + i), (uint8_t) color);
  199. }
  200. else
  201. {
  202. ST7567_DrawPixel(ST7567_currentX + (j * 8) + k, (ST7567_currentY + i), (uint8_t) !color);
  203. }
  204. }
  205. }
  206. }
  207. }
  208. /* Increase pointer */
  209. ST7567_currentX += font->width + 1;
  210. /* Return character written */
  211. return ch;
  212. }
  213. char ST7567_Puts(char* str, FontDef_t* Font, uint8_t color)
  214. {
  215. /* Write characters */
  216. while (*str)
  217. {
  218. /* Write character by character */
  219. if (ST7567_Putc(*str, Font, color) != *str)
  220. {
  221. /* Return error */
  222. return *str;
  223. }
  224. /* Increase string pointer */
  225. str++;
  226. }
  227. /* Everything OK, zero should be returned */
  228. return *str;
  229. }
  230. void ST7567_DrawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint8_t c)
  231. {
  232. int16_t dx, dy, sx, sy, err, e2, i, tmp;
  233. /* Check for overflow */
  234. if (x0 >= ST7567_WIDTH)
  235. {
  236. x0 = ST7567_WIDTH - 1;
  237. }
  238. if (x1 >= ST7567_WIDTH)
  239. {
  240. x1 = ST7567_WIDTH - 1;
  241. }
  242. if (y0 >= ST7567_HEIGHT)
  243. {
  244. y0 = ST7567_HEIGHT - 1;
  245. }
  246. if (y1 >= ST7567_HEIGHT)
  247. {
  248. y1 = ST7567_HEIGHT - 1;
  249. }
  250. dx = (x0 < x1) ? (x1 - x0) : (x0 - x1);
  251. dy = (y0 < y1) ? (y1 - y0) : (y0 - y1);
  252. sx = (x0 < x1) ? 1 : -1;
  253. sy = (y0 < y1) ? 1 : -1;
  254. err = ((dx > dy) ? dx : -dy) / 2;
  255. if (dx == 0)
  256. {
  257. if (y1 < y0)
  258. {
  259. tmp = y1;
  260. y1 = y0;
  261. y0 = tmp;
  262. }
  263. if (x1 < x0)
  264. {
  265. tmp = x1;
  266. x1 = x0;
  267. x0 = tmp;
  268. }
  269. /* Vertical line */
  270. for (i = y0; i <= y1; i++)
  271. {
  272. ST7567_DrawPixel(x0, i, c);
  273. }
  274. /* Return from function */
  275. return;
  276. }
  277. if (dy == 0)
  278. {
  279. if (y1 < y0)
  280. {
  281. tmp = y1;
  282. y1 = y0;
  283. y0 = tmp;
  284. }
  285. if (x1 < x0)
  286. {
  287. tmp = x1;
  288. x1 = x0;
  289. x0 = tmp;
  290. }
  291. /* Horizontal line */
  292. for (i = x0; i <= x1; i++)
  293. {
  294. ST7567_DrawPixel(i, y0, c);
  295. }
  296. /* Return from function */
  297. return;
  298. }
  299. while (1)
  300. {
  301. ST7567_DrawPixel(x0, y0, c);
  302. if (x0 == x1 && y0 == y1)
  303. {
  304. break;
  305. }
  306. e2 = err;
  307. if (e2 > -dx)
  308. {
  309. err -= dy;
  310. x0 += sx;
  311. }
  312. if (e2 < dy)
  313. {
  314. err += dx;
  315. y0 += sy;
  316. }
  317. }
  318. }
  319. static __CODE uint8_t Font3x5 [] = {
  320. 0x00, 0x00, 0x00, 0x00, 0x00, // SP
  321. 0x02, 0x02, 0x02, 0x00, 0x02, // !
  322. 0x05, 0x05, 0x00, 0x00, 0x00, // "
  323. 0x05, 0x07, 0x05, 0x07, 0x05, // #
  324. 0x06, 0x03, 0x06, 0x03, 0x02, // $
  325. 0x01, 0x04, 0x02, 0x01, 0x04, // %
  326. 0x03, 0x03, 0x07, 0x05, 0x06, // &
  327. 0x02, 0x02, 0x00, 0x00, 0x00, // '
  328. 0x04, 0x02, 0x02, 0x02, 0x04, // (
  329. 0x01, 0x02, 0x02, 0x02, 0x01, // )
  330. 0x05, 0x02, 0x05, 0x00, 0x00, // *
  331. 0x00, 0x02, 0x07, 0x02, 0x00, // +
  332. 0x00, 0x00, 0x00, 0x02, 0x01, // ,
  333. 0x00, 0x00, 0x07, 0x00, 0x00, // -
  334. 0x00, 0x00, 0x00, 0x00, 0x02, // .
  335. 0x00, 0x04, 0x02, 0x01, 0x00, // /
  336. 0x07, 0x05, 0x05, 0x05, 0x07, // 0
  337. 0x02, 0x03, 0x02, 0x02, 0x07, // 1
  338. 0x07, 0x04, 0x07, 0x01, 0x07, // 2
  339. 0x07, 0x04, 0x06, 0x04, 0x07, // 3
  340. 0x05, 0x05, 0x07, 0x04, 0x04, // 4
  341. 0x07, 0x01, 0x07, 0x04, 0x07, // 5
  342. 0x07, 0x01, 0x07, 0x05, 0x07, // 6
  343. 0x07, 0x04, 0x04, 0x04, 0x04, // 7
  344. 0x07, 0x05, 0x07, 0x05, 0x07, // 8
  345. 0x07, 0x05, 0x07, 0x04, 0x07, // 9
  346. 0x00, 0x02, 0x00, 0x02, 0x00, // :
  347. 0x00, 0x02, 0x00, 0x02, 0x01, // ;
  348. 0x04, 0x02, 0x01, 0x02, 0x04, // <
  349. 0x00, 0x07, 0x00, 0x07, 0x00, // =
  350. 0x01, 0x02, 0x04, 0x02, 0x01, // >
  351. 0x07, 0x04, 0x02, 0x00, 0x02, // ?
  352. 0x02, 0x05, 0x07, 0x01, 0x06, // @
  353. 0x02, 0x05, 0x07, 0x05, 0x05, // A
  354. 0x03, 0x05, 0x03, 0x05, 0x03, // B
  355. 0x06, 0x01, 0x01, 0x01, 0x06, // C
  356. 0x03, 0x05, 0x05, 0x05, 0x03, // D
  357. 0x07, 0x01, 0x07, 0x01, 0x07, // E
  358. 0x07, 0x01, 0x07, 0x01, 0x01, // F
  359. 0x06, 0x01, 0x07, 0x05, 0x06, // G
  360. 0x05, 0x05, 0x07, 0x05, 0x05, // H
  361. 0x07, 0x02, 0x02, 0x02, 0x07, // I
  362. 0x04, 0x04, 0x04, 0x05, 0x02, // J
  363. 0x05, 0x05, 0x03, 0x05, 0x05, // K
  364. 0x01, 0x01, 0x01, 0x01, 0x07, // L
  365. 0x05, 0x07, 0x07, 0x05, 0x05, // M
  366. 0x05, 0x07, 0x07, 0x07, 0x05, // N
  367. 0x02, 0x05, 0x05, 0x05, 0x02, // O
  368. 0x03, 0x05, 0x03, 0x01, 0x01, // P
  369. 0x02, 0x05, 0x05, 0x05, 0x06, // Q
  370. 0x03, 0x05, 0x07, 0x03, 0x05, // R
  371. 0x06, 0x01, 0x02, 0x04, 0x03, // S
  372. 0x07, 0x02, 0x02, 0x02, 0x02, // T
  373. 0x05, 0x05, 0x05, 0x05, 0x02, // U
  374. 0x05, 0x05, 0x05, 0x02, 0x02, // V
  375. 0x05, 0x05, 0x07, 0x07, 0x05, // W
  376. 0x05, 0x05, 0x02, 0x05, 0x05, // X
  377. 0x05, 0x05, 0x02, 0x02, 0x02, // Y
  378. 0x07, 0x04, 0x02, 0x01, 0x07, // Z
  379. 0x03, 0x01, 0x01, 0x01, 0x03, // [
  380. 0x00, 0x01, 0x02, 0x04, 0x00, /* \ */
  381. 0x06, 0x04, 0x04, 0x04, 0x06, // ]
  382. 0x02, 0x05, 0x00, 0x00, 0x00, // ^
  383. 0x00, 0x00, 0x00, 0x00, 0x07, // _
  384. 0x01, 0x02, 0x00, 0x00, 0x00, // `
  385. 0x00, 0x03, 0x06, 0x05, 0x07, // a
  386. 0x01, 0x03, 0x05, 0x05, 0x03, // b
  387. 0x00, 0x06, 0x01, 0x01, 0x06, // c
  388. 0x04, 0x06, 0x05, 0x05, 0x06, // d
  389. 0x00, 0x06, 0x05, 0x03, 0x06, // e
  390. 0x04, 0x02, 0x07, 0x02, 0x02, // f
  391. 0x06, 0x05, 0x07, 0x04, 0x02, // g
  392. 0x01, 0x03, 0x05, 0x05, 0x05, // h
  393. 0x02, 0x00, 0x02, 0x02, 0x02, // i
  394. 0x04, 0x00, 0x04, 0x04, 0x03, // j
  395. 0x01, 0x05, 0x03, 0x03, 0x05, // k
  396. 0x03, 0x02, 0x02, 0x02, 0x07, // l
  397. 0x00, 0x07, 0x07, 0x07, 0x05, // m
  398. 0x00, 0x03, 0x05, 0x05, 0x05, // n
  399. 0x00, 0x02, 0x05, 0x05, 0x02, // o
  400. 0x00, 0x03, 0x05, 0x03, 0x01, // p
  401. 0x00, 0x06, 0x05, 0x06, 0x04, // q
  402. 0x00, 0x06, 0x01, 0x01, 0x01, // r
  403. 0x00, 0x06, 0x03, 0x06, 0x03, // s
  404. 0x02, 0x07, 0x02, 0x02, 0x06, // t
  405. 0x00, 0x05, 0x05, 0x05, 0x06, // u
  406. 0x00, 0x05, 0x05, 0x05, 0x02, // v
  407. 0x00, 0x05, 0x07, 0x07, 0x07, // w
  408. 0x00, 0x05, 0x02, 0x02, 0x05, // x
  409. 0x00, 0x05, 0x06, 0x04, 0x06, // y
  410. 0x00, 0x07, 0x06, 0x03, 0x07, // z
  411. 0x06, 0x02, 0x01, 0x02, 0x06, // {
  412. 0x02, 0x02, 0x02, 0x02, 0x02, // |
  413. 0x03, 0x02, 0x04, 0x02, 0x03, // }
  414. 0x00, 0x06, 0x03, 0x00, 0x00, // ~
  415. 0x07, 0x07, 0x07, 0x07, 0x07, // DEL
  416. };
  417. static __CODE uint8_t Font5x7 [] = {
  418. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
  419. 0x04, 0x04, 0x04, 0x04, 0x00, 0x04, 0x00, // !
  420. 0x0a, 0x0a, 0x0a, 0x00, 0x00, 0x00, 0x00, // "
  421. 0x0a, 0x0a, 0x1f, 0x0a, 0x1f, 0x0a, 0x0a, // #
  422. 0x04, 0x1e, 0x05, 0x0e, 0x14, 0x0f, 0x04, // $
  423. 0x00, 0x19, 0x1a, 0x04, 0x0b, 0x13, 0x00, // %
  424. 0x06, 0x09, 0x05, 0x02, 0x15, 0x09, 0x16, // &
  425. 0x06, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, // '
  426. 0x08, 0x04, 0x02, 0x02, 0x02, 0x04, 0x08, // (
  427. 0x02, 0x04, 0x08, 0x08, 0x08, 0x04, 0x02, // )
  428. 0x00, 0x04, 0x15, 0x0e, 0x15, 0x04, 0x00, // *
  429. 0x00, 0x04, 0x04, 0x1f, 0x04, 0x04, 0x00, // +
  430. 0x00, 0x00, 0x00, 0x00, 0x0c, 0x08, 0x04, // ,
  431. 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, // -
  432. 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, // .
  433. 0x00, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, // /
  434. 0x0e, 0x11, 0x19, 0x15, 0x13, 0x11, 0x0e, // 0
  435. 0x04, 0x06, 0x04, 0x04, 0x04, 0x04, 0x0e, // 1
  436. 0x0e, 0x11, 0x10, 0x08, 0x04, 0x02, 0x1f, // 2
  437. 0x1f, 0x08, 0x04, 0x08, 0x10, 0x11, 0x0e, // 3
  438. 0x08, 0x0c, 0x0a, 0x09, 0x1f, 0x08, 0x08, // 4
  439. 0x1f, 0x01, 0x0f, 0x10, 0x10, 0x11, 0x0e, // 5
  440. 0x0c, 0x02, 0x01, 0x0f, 0x11, 0x11, 0x0e, // 6
  441. 0x1f, 0x10, 0x08, 0x04, 0x02, 0x02, 0x02, // 7
  442. 0x0e, 0x11, 0x11, 0x0e, 0x11, 0x11, 0x0e, // 8
  443. 0x0e, 0x11, 0x11, 0x1e, 0x10, 0x08, 0x06, // 9
  444. 0x00, 0x06, 0x06, 0x00, 0x06, 0x06, 0x00, // :
  445. 0x00, 0x06, 0x06, 0x00, 0x06, 0x04, 0x02, // ;
  446. 0x08, 0x04, 0x02, 0x01, 0x02, 0x04, 0x08, // <
  447. 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, // =
  448. 0x02, 0x04, 0x08, 0x10, 0x08, 0x04, 0x02, // >
  449. 0x0e, 0x11, 0x10, 0x08, 0x04, 0x00, 0x04, // ?
  450. 0x0e, 0x11, 0x10, 0x16, 0x1d, 0x11, 0x0e, // @
  451. 0x0e, 0x11, 0x11, 0x11, 0x1f, 0x11, 0x11, // A
  452. 0x0f, 0x11, 0x11, 0x0f, 0x11, 0x11, 0x0f, // B
  453. 0x0e, 0x11, 0x01, 0x01, 0x01, 0x11, 0x0e, // C
  454. 0x07, 0x09, 0x11, 0x11, 0x11, 0x09, 0x07, // D
  455. 0x1f, 0x01, 0x01, 0x0f, 0x01, 0x01, 0x1f, // E
  456. 0x1f, 0x01, 0x01, 0x0f, 0x01, 0x01, 0x01, // F
  457. 0x0e, 0x11, 0x01, 0x1d, 0x11, 0x11, 0x1e, // G
  458. 0x11, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11, // H
  459. 0x0e, 0x04, 0x04, 0x04, 0x04, 0x04, 0x0e, // I
  460. 0x1c, 0x08, 0x08, 0x08, 0x08, 0x09, 0x06, // J
  461. 0x11, 0x09, 0x05, 0x03, 0x05, 0x09, 0x11, // K
  462. 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1f, // L
  463. 0x11, 0x1b, 0x15, 0x15, 0x11, 0x11, 0x11, // M
  464. 0x11, 0x11, 0x13, 0x15, 0x19, 0x11, 0x11, // N
  465. 0x0e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e, // O
  466. 0x0f, 0x11, 0x11, 0x0f, 0x01, 0x01, 0x01, // P
  467. 0x0e, 0x11, 0x11, 0x11, 0x15, 0x09, 0x16, // Q
  468. 0x0f, 0x11, 0x11, 0x0f, 0x05, 0x09, 0x11, // R
  469. 0x1e, 0x01, 0x01, 0x0e, 0x10, 0x10, 0x0f, // S
  470. 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, // T
  471. 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e, // U
  472. 0x11, 0x11, 0x11, 0x11, 0x11, 0x0a, 0x04, // V
  473. 0x11, 0x11, 0x11, 0x15, 0x15, 0x15, 0x0a, // W
  474. 0x11, 0x11, 0x0a, 0x04, 0x0a, 0x11, 0x11, // X
  475. 0x11, 0x11, 0x11, 0x0a, 0x04, 0x04, 0x04, // Y
  476. 0x1f, 0x10, 0x08, 0x04, 0x02, 0x01, 0x1f, // Z
  477. 0x0e, 0x02, 0x02, 0x02, 0x02, 0x02, 0x0e, // [
  478. 0x15, 0x0a, 0x15, 0x0a, 0x15, 0x0a, 0x15, /* \ */
  479. 0x0e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0e, // ]
  480. 0x04, 0x0a, 0x11, 0x00, 0x00, 0x00, 0x00, // ^
  481. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, // _
  482. 0x02, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, // `
  483. 0x00, 0x00, 0x0e, 0x10, 0x1e, 0x11, 0x1e, // a
  484. 0x01, 0x01, 0x0d, 0x13, 0x11, 0x11, 0x0f, // b
  485. 0x00, 0x00, 0x0e, 0x01, 0x01, 0x11, 0x0e, // c
  486. 0x10, 0x10, 0x16, 0x19, 0x11, 0x11, 0x1e, // d
  487. 0x00, 0x00, 0x0e, 0x11, 0x1f, 0x01, 0x0e, // e
  488. 0x0c, 0x12, 0x02, 0x07, 0x02, 0x02, 0x02, // f
  489. 0x00, 0x1e, 0x11, 0x11, 0x1e, 0x10, 0x0e, // g
  490. 0x01, 0x01, 0x0d, 0x13, 0x11, 0x11, 0x11, // h
  491. 0x04, 0x00, 0x06, 0x04, 0x04, 0x04, 0x0e, // i
  492. 0x08, 0x00, 0x0c, 0x08, 0x08, 0x09, 0x06, // j
  493. 0x01, 0x01, 0x09, 0x05, 0x03, 0x05, 0x09, // k
  494. 0x06, 0x04, 0x04, 0x04, 0x04, 0x04, 0x0e, // l
  495. 0x00, 0x00, 0x0b, 0x15, 0x15, 0x11, 0x11, // m
  496. 0x00, 0x00, 0x0d, 0x13, 0x11, 0x11, 0x11, // n
  497. 0x00, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x0e, // o
  498. 0x00, 0x00, 0x0f, 0x11, 0x0f, 0x01, 0x01, // p
  499. 0x00, 0x00, 0x16, 0x19, 0x1e, 0x10, 0x10, // q
  500. 0x00, 0x00, 0x0d, 0x13, 0x01, 0x01, 0x01, // r
  501. 0x00, 0x00, 0x0e, 0x01, 0x0e, 0x10, 0x0f, // s
  502. 0x02, 0x02, 0x07, 0x02, 0x02, 0x12, 0x0c, // t
  503. 0x00, 0x00, 0x11, 0x11, 0x11, 0x19, 0x16, // u
  504. 0x00, 0x00, 0x11, 0x11, 0x11, 0x0a, 0x04, // v
  505. 0x00, 0x00, 0x11, 0x11, 0x15, 0x15, 0x0a, // w
  506. 0x00, 0x00, 0x11, 0x0a, 0x04, 0x0a, 0x11, // x
  507. 0x00, 0x00, 0x11, 0x11, 0x1e, 0x10, 0x0e, // y
  508. 0x00, 0x00, 0x1f, 0x08, 0x04, 0x02, 0x1f, // z
  509. 0x08, 0x04, 0x04, 0x02, 0x04, 0x04, 0x08, // {
  510. 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, // |
  511. 0x02, 0x04, 0x04, 0x08, 0x04, 0x04, 0x02, // }
  512. 0x00, 0x00, 0x02, 0x15, 0x08, 0x00, 0x00, // ~
  513. 0x00, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x00, //
  514. };
  515. __CODE FontDef_t Font_3x5 = {3, 5, 1, 1, Font3x5};
  516. __CODE FontDef_t Font_5x7 = {5, 7, 1, 1, Font5x7};