ST7565.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. /**
  2. * @file ST7565.c
  3. *
  4. */
  5. /*********************
  6. * INCLUDES
  7. *********************/
  8. #include "ST7565.h"
  9. #if USE_ST7565
  10. #include <stdbool.h>
  11. #include <stddef.h>
  12. #include <string.h>
  13. #include "lvgl/lv_core/lv_vdb.h"
  14. #include LV_DRV_DISP_INCLUDE
  15. #include LV_DRV_DELAY_INCLUDE
  16. /*********************
  17. * DEFINES
  18. *********************/
  19. #define ST7565_BAUD 2000000 /*< 2,5 MHz (400 ns)*/
  20. #define ST7565_CMD_MODE 0
  21. #define ST7565_DATA_MODE 1
  22. #define ST7565_HOR_RES 128
  23. #define ST7565_VER_RES 64
  24. #define CMD_DISPLAY_OFF 0xAE
  25. #define CMD_DISPLAY_ON 0xAF
  26. #define CMD_SET_DISP_START_LINE 0x40
  27. #define CMD_SET_PAGE 0xB0
  28. #define CMD_SET_COLUMN_UPPER 0x10
  29. #define CMD_SET_COLUMN_LOWER 0x00
  30. #define CMD_SET_ADC_NORMAL 0xA0
  31. #define CMD_SET_ADC_REVERSE 0xA1
  32. #define CMD_SET_DISP_NORMAL 0xA6
  33. #define CMD_SET_DISP_REVERSE 0xA7
  34. #define CMD_SET_ALLPTS_NORMAL 0xA4
  35. #define CMD_SET_ALLPTS_ON 0xA5
  36. #define CMD_SET_BIAS_9 0xA2
  37. #define CMD_SET_BIAS_7 0xA3
  38. #define CMD_RMW 0xE0
  39. #define CMD_RMW_CLEAR 0xEE
  40. #define CMD_INTERNAL_RESET 0xE2
  41. #define CMD_SET_COM_NORMAL 0xC0
  42. #define CMD_SET_COM_REVERSE 0xC8
  43. #define CMD_SET_POWER_CONTROL 0x28
  44. #define CMD_SET_RESISTOR_RATIO 0x20
  45. #define CMD_SET_VOLUME_FIRST 0x81
  46. #define CMD_SET_VOLUME_SECOND 0x00
  47. #define CMD_SET_STATIC_OFF 0xAC
  48. #define CMD_SET_STATIC_ON 0xAD
  49. #define CMD_SET_STATIC_REG 0x00
  50. #define CMD_SET_BOOSTER_FIRST 0xF8
  51. #define CMD_SET_BOOSTER_234 0x00
  52. #define CMD_SET_BOOSTER_5 0x01
  53. #define CMD_SET_BOOSTER_6 0x03
  54. #define CMD_NOP 0xE3
  55. #define CMD_TEST 0xF0
  56. /**********************
  57. * TYPEDEFS
  58. **********************/
  59. /**********************
  60. * STATIC PROTOTYPES
  61. **********************/
  62. static void st7565_sync(int32_t x1, int32_t y1, int32_t x2, int32_t y2);
  63. static void st7565_command(uint8_t cmd);
  64. static void st7565_data(uint8_t data);
  65. /**********************
  66. * STATIC VARIABLES
  67. **********************/
  68. static uint8_t lcd_fb[ST7565_HOR_RES * ST7565_VER_RES / 8] = {0xAA, 0xAA};
  69. static uint8_t pagemap[] = { 7, 6, 5, 4, 3, 2, 1, 0 };
  70. /**********************
  71. * MACROS
  72. **********************/
  73. /**********************
  74. * GLOBAL FUNCTIONS
  75. **********************/
  76. /**
  77. * Initialize the ST7565
  78. */
  79. void st7565_init(void)
  80. {
  81. LV_DRV_DISP_RST(1);
  82. LV_DRV_DELAY_MS(10);
  83. LV_DRV_DISP_RST(0);
  84. LV_DRV_DELAY_MS(10);
  85. LV_DRV_DISP_RST(1);
  86. LV_DRV_DELAY_MS(10);
  87. LV_DRV_DISP_SPI_CS(0);
  88. st7565_command(CMD_SET_BIAS_7);
  89. st7565_command(CMD_SET_ADC_NORMAL);
  90. st7565_command(CMD_SET_COM_NORMAL);
  91. st7565_command(CMD_SET_DISP_START_LINE);
  92. st7565_command(CMD_SET_POWER_CONTROL | 0x4);
  93. LV_DRV_DELAY_MS(50);
  94. st7565_command(CMD_SET_POWER_CONTROL | 0x6);
  95. LV_DRV_DELAY_MS(50);
  96. st7565_command(CMD_SET_POWER_CONTROL | 0x7);
  97. LV_DRV_DELAY_MS(10);
  98. st7565_command(CMD_SET_RESISTOR_RATIO | 0x6);
  99. st7565_command(CMD_DISPLAY_ON);
  100. st7565_command(CMD_SET_ALLPTS_NORMAL);
  101. /*Set brightness*/
  102. st7565_command(CMD_SET_VOLUME_FIRST);
  103. st7565_command(CMD_SET_VOLUME_SECOND | (0x18 & 0x3f));
  104. LV_DRV_DISP_SPI_CS(1);
  105. memset(lcd_fb, 0x00, sizeof(lcd_fb));
  106. }
  107. void st7565_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t * color_p)
  108. {
  109. /*Return if the area is out the screen*/
  110. if(x2 < 0) return;
  111. if(y2 < 0) return;
  112. if(x1 > ST7565_HOR_RES - 1) return;
  113. if(y1 > ST7565_VER_RES - 1) return;
  114. /*Truncate the area to the screen*/
  115. int32_t act_x1 = x1 < 0 ? 0 : x1;
  116. int32_t act_y1 = y1 < 0 ? 0 : y1;
  117. int32_t act_x2 = x2 > ST7565_HOR_RES - 1 ? ST7565_HOR_RES - 1 : x2;
  118. int32_t act_y2 = y2 > ST7565_VER_RES - 1 ? ST7565_VER_RES - 1 : y2;
  119. int32_t x, y;
  120. /*Set the first row in */
  121. /*Refresh frame buffer*/
  122. for(y= act_y1; y <= act_y2; y++) {
  123. for(x = act_x1; x <= act_x2; x++) {
  124. if (lv_color_to1(*color_p) != 0) {
  125. lcd_fb[x+ (y/8)*ST7565_HOR_RES] &= ~( 1 << (7-(y%8)));
  126. } else {
  127. lcd_fb[x+ (y/8)*ST7565_HOR_RES] |= (1 << (7-(y%8)));
  128. }
  129. color_p ++;
  130. }
  131. color_p += x2 - act_x2; /*Next row*/
  132. }
  133. st7565_sync(act_x1, act_y1, act_x2, act_y2);
  134. lv_flush_ready();
  135. }
  136. void st7565_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t color)
  137. {
  138. /*Return if the area is out the screen*/
  139. if(x2 < 0) return;
  140. if(y2 < 0) return;
  141. if(x1 > ST7565_HOR_RES - 1) return;
  142. if(y1 > ST7565_VER_RES - 1) return;
  143. /*Truncate the area to the screen*/
  144. int32_t act_x1 = x1 < 0 ? 0 : x1;
  145. int32_t act_y1 = y1 < 0 ? 0 : y1;
  146. int32_t act_x2 = x2 > ST7565_HOR_RES - 1 ? ST7565_HOR_RES - 1 : x2;
  147. int32_t act_y2 = y2 > ST7565_VER_RES - 1 ? ST7565_VER_RES - 1 : y2;
  148. int32_t x, y;
  149. uint8_t white = lv_color_to1(color);
  150. /*Refresh frame buffer*/
  151. for(y= act_y1; y <= act_y2; y++) {
  152. for(x = act_x1; x <= act_x2; x++) {
  153. if (white != 0) {
  154. lcd_fb[x+ (y/8)*ST7565_HOR_RES] |= (1 << (7-(y%8)));
  155. } else {
  156. lcd_fb[x+ (y/8)*ST7565_HOR_RES] &= ~( 1 << (7-(y%8)));
  157. }
  158. }
  159. }
  160. st7565_sync(act_x1, act_y1, act_x2, act_y2);
  161. }
  162. void st7565_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t * color_p)
  163. {
  164. /*Return if the area is out the screen*/
  165. if(x2 < 0) return;
  166. if(y2 < 0) return;
  167. if(x1 > ST7565_HOR_RES - 1) return;
  168. if(y1 > ST7565_VER_RES - 1) return;
  169. /*Truncate the area to the screen*/
  170. int32_t act_x1 = x1 < 0 ? 0 : x1;
  171. int32_t act_y1 = y1 < 0 ? 0 : y1;
  172. int32_t act_x2 = x2 > ST7565_HOR_RES - 1 ? ST7565_HOR_RES - 1 : x2;
  173. int32_t act_y2 = y2 > ST7565_VER_RES - 1 ? ST7565_VER_RES - 1 : y2;
  174. int32_t x, y;
  175. /*Set the first row in */
  176. /*Refresh frame buffer*/
  177. for(y= act_y1; y <= act_y2; y++) {
  178. for(x = act_x1; x <= act_x2; x++) {
  179. if (lv_color_to1(*color_p) != 0) {
  180. lcd_fb[x+ (y/8)*ST7565_HOR_RES] &= ~( 1 << (7-(y%8)));
  181. } else {
  182. lcd_fb[x+ (y/8)*ST7565_HOR_RES] |= (1 << (7-(y%8)));
  183. }
  184. color_p ++;
  185. }
  186. color_p += x2 - act_x2; /*Next row*/
  187. }
  188. st7565_sync(act_x1, act_y1, act_x2, act_y2);
  189. }
  190. /**********************
  191. * STATIC FUNCTIONS
  192. **********************/
  193. /**
  194. * Flush a specific part of the buffer to the display
  195. * @param x1 left coordinate of the area to flush
  196. * @param y1 top coordinate of the area to flush
  197. * @param x2 right coordinate of the area to flush
  198. * @param y2 bottom coordinate of the area to flush
  199. */
  200. static void st7565_sync(int32_t x1, int32_t y1, int32_t x2, int32_t y2)
  201. {
  202. LV_DRV_DISP_SPI_CS(0);
  203. uint8_t c, p;
  204. for(p = y1 / 8; p <= y2 / 8; p++) {
  205. st7565_command(CMD_SET_PAGE | pagemap[p]);
  206. st7565_command(CMD_SET_COLUMN_LOWER | (x1 & 0xf));
  207. st7565_command(CMD_SET_COLUMN_UPPER | ((x1 >> 4) & 0xf));
  208. st7565_command(CMD_RMW);
  209. for(c = x1; c <= x2; c++) {
  210. st7565_data(lcd_fb[(ST7565_HOR_RES*p)+c]);
  211. }
  212. }
  213. LV_DRV_DISP_SPI_CS(1);
  214. }
  215. /**
  216. * Write a command to the ST7565
  217. * @param cmd the command
  218. */
  219. static void st7565_command(uint8_t cmd)
  220. {
  221. LV_DRV_DISP_CMD_DATA(ST7565_CMD_MODE);
  222. LV_DRV_DISP_SPI_WR_BYTE(data);
  223. }
  224. /**
  225. * Write data to the ST7565
  226. * @param data the data
  227. */
  228. static void st7565_data(uint8_t data)
  229. {
  230. LV_DRV_DISP_CMD_DATA(ST7565_DATA_MODE);
  231. LV_DRV_DISP_SPI_WR_BYTE(data);
  232. }
  233. #endif