text.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /*
  2. * (c) 2004,2006 Richard Titmuss for SlimProtoLib
  3. * (c) Philippe G. 2019, philippe_44@outlook.com
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. *
  18. */
  19. #include <string.h>
  20. #include <ctype.h>
  21. #include <arpa/inet.h>
  22. #include "esp_log.h"
  23. #include "config.h"
  24. #include "ssd1306.h"
  25. #include "ssd1306_draw.h"
  26. #include "ssd1306_font.h"
  27. #include "ssd1306_default_if.h"
  28. #define LINELEN 40
  29. #define I2C_PORT 1
  30. #define I2C_ADDRESS 0x3C
  31. #define TAG "display"
  32. static struct SSD1306_Device I2CDisplay;
  33. static bool init, display;
  34. void display_init(void) {
  35. char *item = config_alloc_get(NVS_TYPE_STR, "display_config");
  36. if (!item || !*item) {
  37. ESP_LOGI(TAG, "no display");
  38. return;
  39. }
  40. if (strstr(item, "I2C")) {
  41. int scl = -1, sda = -1;
  42. int width = -1, height = -1;
  43. char *p;
  44. // done no matter what
  45. init = true;
  46. // no time for smart parsing - this is for tinkerers
  47. if ((p = strcasestr(item, "scl")) != NULL) scl = atoi(strchr(p, '=') + 1);
  48. if ((p = strcasestr(item, "sda")) != NULL) sda = atoi(strchr(p, '=') + 1);
  49. if ((p = strcasestr(item, "width")) != NULL) width = atoi(strchr(p, '=') + 1);
  50. if ((p = strcasestr(item, "height")) != NULL) height = atoi(strchr(p, '=') + 1);
  51. if (sda != -1 && scl != -1 && width != -1 && height != -1) {
  52. SSD1306_I2CMasterInitDefault( I2C_PORT, sda, scl );
  53. SSD1306_I2CMasterAttachDisplayDefault( &I2CDisplay, width, height, I2C_ADDRESS, -1);
  54. SSD1306_SetFont( &I2CDisplay, &Font_droid_sans_fallback_15x17 );
  55. ESP_LOGI(TAG, "initialized I2C display %dx%d (sda:%d, scl:%d)", width, height, sda, scl);
  56. display = true;
  57. } else {
  58. ESP_LOGI(TAG, "cannot initialized I2C display %s [%dx%d sda:%d, scl:%d]", item, width, height, sda, scl);
  59. }
  60. } else {
  61. // other types
  62. }
  63. }
  64. //Change special LCD chars to something more printable on screen
  65. unsigned char printable(unsigned char c) {
  66. switch (c) {
  67. case 11: /* block */
  68. return '#';
  69. break;;
  70. case 16: /* rightarrow */
  71. return '>';
  72. break;;
  73. case 22: /* circle */
  74. return '@';
  75. break;;
  76. case 145: /* note */
  77. return ' ';
  78. break;;
  79. case 152: /* bell */
  80. return 'o';
  81. break;
  82. default:
  83. return c;
  84. }
  85. }
  86. // Replace unprintable symbols in line
  87. void makeprintable(unsigned char * line) {
  88. for (int n = 0; n < LINELEN; n++) line[n] = printable(line[n]);
  89. }
  90. // Show the display
  91. void show_display_buffer(char *ddram) {
  92. char line1[LINELEN+1];
  93. char *line2;
  94. memset(line1, 0, LINELEN+1);
  95. strncpy(line1, ddram, LINELEN);
  96. line2 = &(ddram[LINELEN]);
  97. line2[LINELEN] = '\0';
  98. /* Convert special LCD chars */
  99. makeprintable((unsigned char *)line1);
  100. makeprintable((unsigned char *)line2);
  101. ESP_LOGI(TAG, "\n\t%.40s\n\t%.40s", line1, line2);
  102. if (display) {
  103. SSD1306_Clear( &I2CDisplay, SSD_COLOR_BLACK );
  104. SSD1306_FontDrawAnchoredString( &I2CDisplay, TextAnchor_NorthWest, line1, SSD_COLOR_WHITE );
  105. SSD1306_FontDrawAnchoredString( &I2CDisplay, TextAnchor_SouthWest, line2, SSD_COLOR_WHITE );
  106. SSD1306_Update( &I2CDisplay );
  107. }
  108. }
  109. // Check if char is printable, or a valid symbol
  110. bool charisok(unsigned char c) {
  111. switch (c) {
  112. case 11: /* block */
  113. case 16: /* rightarrow */
  114. case 22: /* circle */
  115. case 145: /* note */
  116. case 152: /* bell */
  117. return true;
  118. break;;
  119. default:
  120. return isprint(c);
  121. }
  122. }
  123. // Process display data
  124. void vfd_data( unsigned short *data, int bytes_read) {
  125. unsigned short *display_data;
  126. char ddram[LINELEN * 2];
  127. int n;
  128. int addr = 0; /* counter */
  129. if (!init) display_init();
  130. if (bytes_read % 2) bytes_read--; /* even number of bytes */
  131. // if we use Noritake VFD codes, display data starts at 12
  132. display_data = &(data[5]); /* display data starts at byte 10 */
  133. memset(ddram, ' ', LINELEN * 2);
  134. for (n = 0; n < (bytes_read/2); n++) {
  135. unsigned short d; /* data element */
  136. unsigned char t, c;
  137. d = ntohs(display_data[n]);
  138. t = (d & 0x00ff00) >> 8; /* type of display data */
  139. c = (d & 0x0000ff); /* character/command */
  140. switch (t) {
  141. case 0x03: /* character */
  142. if (!charisok(c)) c = ' ';
  143. if (addr <= LINELEN * 2) {
  144. ddram[addr++] = c;
  145. }
  146. break;
  147. case 0x02: /* command */
  148. switch (c) {
  149. case 0x06: /* display clear */
  150. memset(ddram, ' ', LINELEN * 2);
  151. break;
  152. case 0x02: /* cursor home */
  153. addr = 0;
  154. break;
  155. case 0xc0: /* cursor home2 */
  156. addr = LINELEN;
  157. break;
  158. }
  159. }
  160. }
  161. show_display_buffer(ddram);
  162. }