pcd8544_lcd.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /*
  2. * pcd8544_lcd.c
  3. *
  4. * Copyright 2022 dh33ex <dh33ex@riseup.net>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  19. * MA 02110-1301, USA or see <http://www.gnu.org/licenses/>.
  20. *
  21. *
  22. */
  23. #ifndef __msp430_h_
  24. #include <msp430.h>
  25. #endif
  26. #include "pcd8544_lcd.h"
  27. /* parameters */
  28. /* H = 0 or 1 */
  29. #define PCD8544_FUNCTIONSET 0x20
  30. #define PCD8544_PD 0x04
  31. #define PCD8544_V 0x02
  32. #define PCD8544_H 0x01
  33. /* H = 0 */
  34. #define PCD8544_DISPLAYCONTROL 0x08
  35. #define PCD8544_E 0x01
  36. #define PCD8544_D 0x04
  37. #define PCD8544_Y_ADDR 0x40
  38. #define PCD8544_X_ADDR 0x80
  39. /* H = 1 */
  40. #define PCD8544_TEMPERATURECONTROL 0x4
  41. #define PCD8544_TC0 0x1
  42. #define PCD8544_TC1 0x2
  43. #define PCD8544_BIASSYSTEM 0x10
  44. #define PCD8544_BS0 0x1
  45. #define PCD8544_BS1 0x2
  46. #define PCD8544_BS2 0x4
  47. #define PCD8544_VOP 0x80
  48. /* D/C states */
  49. #define PCD8544_COMMAND 0
  50. #define PCD8544_DATA 1
  51. static const char font[][5] = {
  52. {0x00, 0x00, 0x00, 0x00, 0x00},
  53. {0x00, 0x00, 0x5f, 0x00, 0x00},
  54. {0x00, 0x07, 0x00, 0x07, 0x00},
  55. {0x14, 0x7f, 0x14, 0x7f, 0x14},
  56. {0x24, 0x2a, 0x7f, 0x2a, 0x12},
  57. {0x23, 0x13, 0x08, 0x64, 0x62},
  58. {0x36, 0x49, 0x55, 0x22, 0x50},
  59. {0x00, 0x05, 0x03, 0x00, 0x00},
  60. {0x00, 0x1c, 0x22, 0x41, 0x00},
  61. {0x00, 0x41, 0x22, 0x1c, 0x00},
  62. {0x14, 0x08, 0x3e, 0x08, 0x14},
  63. {0x08, 0x08, 0x3e, 0x08, 0x08},
  64. {0x00, 0x50, 0x30, 0x00, 0x00},
  65. {0x08, 0x08, 0x08, 0x08, 0x08},
  66. {0x00, 0x60, 0x60, 0x00, 0x00},
  67. {0x20, 0x10, 0x08, 0x04, 0x02},
  68. {0x3e, 0x51, 0x49, 0x45, 0x3e},
  69. {0x00, 0x42, 0x7f, 0x40, 0x00},
  70. {0x42, 0x61, 0x51, 0x49, 0x46},
  71. {0x21, 0x41, 0x45, 0x4b, 0x31},
  72. {0x18, 0x14, 0x12, 0x7f, 0x10},
  73. {0x27, 0x45, 0x45, 0x45, 0x39},
  74. {0x3c, 0x4a, 0x49, 0x49, 0x30},
  75. {0x01, 0x71, 0x09, 0x05, 0x03},
  76. {0x36, 0x49, 0x49, 0x49, 0x36},
  77. {0x06, 0x49, 0x49, 0x29, 0x1e},
  78. {0x00, 0x36, 0x36, 0x00, 0x00},
  79. {0x00, 0x56, 0x36, 0x00, 0x00},
  80. {0x08, 0x14, 0x22, 0x41, 0x00},
  81. {0x14, 0x14, 0x14, 0x14, 0x14},
  82. {0x00, 0x41, 0x22, 0x14, 0x08},
  83. {0x02, 0x01, 0x51, 0x09, 0x06},
  84. {0x32, 0x49, 0x79, 0x41, 0x3e},
  85. {0x7e, 0x11, 0x11, 0x11, 0x7e},
  86. {0x7f, 0x49, 0x49, 0x49, 0x36},
  87. {0x3e, 0x41, 0x41, 0x41, 0x22},
  88. {0x7f, 0x41, 0x41, 0x22, 0x1c},
  89. {0x7f, 0x49, 0x49, 0x49, 0x41},
  90. {0x7f, 0x09, 0x09, 0x09, 0x01},
  91. {0x3e, 0x41, 0x49, 0x49, 0x7a},
  92. {0x7f, 0x08, 0x08, 0x08, 0x7f},
  93. {0x00, 0x41, 0x7f, 0x41, 0x00},
  94. {0x20, 0x40, 0x41, 0x3f, 0x01},
  95. {0x7f, 0x08, 0x14, 0x22, 0x41},
  96. {0x7f, 0x40, 0x40, 0x40, 0x40},
  97. {0x7f, 0x02, 0x0c, 0x02, 0x7f},
  98. {0x7f, 0x04, 0x08, 0x10, 0x7f},
  99. {0x3e, 0x41, 0x41, 0x41, 0x3e},
  100. {0x7f, 0x09, 0x09, 0x09, 0x06},
  101. {0x3e, 0x41, 0x51, 0x21, 0x5e},
  102. {0x7f, 0x09, 0x19, 0x29, 0x46},
  103. {0x46, 0x49, 0x49, 0x49, 0x31},
  104. {0x01, 0x01, 0x7f, 0x01, 0x01},
  105. {0x3f, 0x40, 0x40, 0x40, 0x3f},
  106. {0x1f, 0x20, 0x40, 0x20, 0x1f},
  107. {0x3f, 0x40, 0x38, 0x40, 0x3f},
  108. {0x63, 0x14, 0x08, 0x14, 0x63},
  109. {0x07, 0x08, 0x70, 0x08, 0x07},
  110. {0x61, 0x51, 0x49, 0x45, 0x43},
  111. {0x00, 0x7f, 0x41, 0x41, 0x00},
  112. {0x02, 0x04, 0x08, 0x10, 0x20},
  113. {0x00, 0x41, 0x41, 0x7f, 0x00},
  114. {0x04, 0x02, 0x01, 0x02, 0x04},
  115. {0x40, 0x40, 0x40, 0x40, 0x40},
  116. {0x00, 0x01, 0x02, 0x04, 0x00},
  117. {0x20, 0x54, 0x54, 0x54, 0x78},
  118. {0x7f, 0x48, 0x44, 0x44, 0x38},
  119. {0x38, 0x44, 0x44, 0x44, 0x20},
  120. {0x38, 0x44, 0x44, 0x48, 0x7f},
  121. {0x38, 0x54, 0x54, 0x54, 0x18},
  122. {0x08, 0x7e, 0x09, 0x01, 0x02},
  123. {0x0c, 0x52, 0x52, 0x52, 0x3e},
  124. {0x7f, 0x08, 0x04, 0x04, 0x78},
  125. {0x00, 0x44, 0x7d, 0x40, 0x00},
  126. {0x20, 0x40, 0x44, 0x3d, 0x00},
  127. {0x7f, 0x10, 0x28, 0x44, 0x00},
  128. {0x00, 0x41, 0x7f, 0x40, 0x00},
  129. {0x7c, 0x04, 0x18, 0x04, 0x78},
  130. {0x7c, 0x08, 0x04, 0x04, 0x78},
  131. {0x38, 0x44, 0x44, 0x44, 0x38},
  132. {0x7c, 0x14, 0x14, 0x14, 0x08},
  133. {0x08, 0x14, 0x14, 0x18, 0x7c},
  134. {0x7c, 0x08, 0x04, 0x04, 0x08},
  135. {0x48, 0x54, 0x54, 0x54, 0x20},
  136. {0x04, 0x3f, 0x44, 0x40, 0x20},
  137. {0x3c, 0x40, 0x40, 0x20, 0x7c},
  138. {0x1c, 0x20, 0x40, 0x20, 0x1c},
  139. {0x3c, 0x40, 0x30, 0x40, 0x3c},
  140. {0x44, 0x28, 0x10, 0x28, 0x44},
  141. {0x0c, 0x50, 0x50, 0x50, 0x3c},
  142. {0x44, 0x64, 0x54, 0x4c, 0x44},
  143. {0x00, 0x08, 0x36, 0x41, 0x00},
  144. {0x00, 0x00, 0x7f, 0x00, 0x00},
  145. {0x00, 0x41, 0x36, 0x08, 0x00},
  146. {0x10, 0x08, 0x08, 0x10, 0x08}
  147. };
  148. void PCD8544_send(PCD8544 *disp, unsigned char type, unsigned char byte) {
  149. while(UCB0STAT&UCBUSY); /* wait until SPI is free */
  150. P2OUT &= ~disp->ss; /* clear SS */
  151. if (type) { /* set/clear D/C pin */
  152. P2OUT |= disp->dc;
  153. } else {
  154. P2OUT &= ~disp->dc;
  155. }
  156. while(UCB0STAT&UCBUSY);
  157. UCB0TXBUF = byte; /* send byte */
  158. while (UCB0STAT & UCBUSY); /* wait until SPI free */
  159. __delay_cycles(3); /* wait a little */
  160. P2OUT |= disp->ss; /* set SS */
  161. }
  162. void LCD_init(PCD8544 *disp) {
  163. /* setup SPI */
  164. UCB0CTL1 |= UCSWRST; /* put B0 into SW Reset */
  165. UCB0CTL1 |= UCSSEL_2; /* choose SMCLK */
  166. UCB0BR0 = 1; /* SMCLK=1M/1=1MHz */
  167. UCB0BR1 = 0;
  168. UCB0CTL0 |= UCSYNC /* put B0 into SPI mode */
  169. | UCMSB /* set MSB-first */
  170. | UCCKPH /* set falling edge */
  171. | UCCKPL /* set inactive state=HIGH */
  172. | UCMST; /* set master mode */
  173. /* configure the ports */
  174. P1SEL |= BIT5; /* P1.5 use CLK (11) */
  175. P1SEL2 |= BIT5;
  176. P1SEL |= BIT7; /* P1.7 use SIMO (11) */
  177. P1SEL2 |= BIT7;
  178. P2DIR |= disp->bl | disp->dc | disp->ss | disp->rst;/* set ports to outputs */
  179. P2OUT &= ~disp->bl; /* turn of backlight initially */
  180. P2OUT |= disp->dc | disp->ss | disp->rst;
  181. UCB0CTL1 &= ~UCSWRST;
  182. PCD8544_send(disp, PCD8544_COMMAND, PCD8544_FUNCTIONSET | PCD8544_H);
  183. PCD8544_send(disp, PCD8544_COMMAND, PCD8544_VOP | 0x3F);
  184. PCD8544_send(disp, PCD8544_COMMAND, PCD8544_TEMPERATURECONTROL | 0x02);
  185. PCD8544_send(disp, PCD8544_COMMAND, PCD8544_BIASSYSTEM | 0x03);
  186. PCD8544_send(disp, PCD8544_COMMAND, PCD8544_DISPLAYCONTROL | PCD8544_D);
  187. PCD8544_send(disp, PCD8544_COMMAND, PCD8544_FUNCTIONSET | PCD8544_V);
  188. LCD_clear(disp);
  189. }
  190. void LCD_write(PCD8544 *disp, char *string) {
  191. unsigned char i;
  192. PCD8544_send(disp, PCD8544_COMMAND, PCD8544_FUNCTIONSET);
  193. while (*string != '\0') {
  194. for(i = 0; i < 5; i++) {
  195. PCD8544_send(disp, PCD8544_DATA, font[*string - 0x20][i]);
  196. }
  197. string++;
  198. PCD8544_send(disp, PCD8544_DATA, 0);
  199. }
  200. }
  201. void LCD_backlight(PCD8544 *disp, unsigned char state) {
  202. if (state) {
  203. P2OUT |= disp->bl;
  204. } else {
  205. P2OUT &= ~disp->bl;
  206. }
  207. }
  208. void LCD_set_address(PCD8544 *disp, unsigned char x, unsigned char y) {
  209. PCD8544_send(disp, PCD8544_COMMAND, PCD8544_Y_ADDR | y);
  210. PCD8544_send(disp, PCD8544_COMMAND, PCD8544_X_ADDR | x);
  211. }
  212. void LCD_clear(PCD8544 *disp) {
  213. unsigned char j, i;
  214. for (i = 0; i < 84; i++) {
  215. for (j = 0; j < 6; j++) {
  216. PCD8544_send(disp, PCD8544_DATA, 0x0);
  217. }
  218. }
  219. }