cb9190469de5a0b83ade2c1dbe29a056c0a87f33
[hackover2013-badge-firmware.git] / lcd / display.c
1 #include "display.h"
2
3 #include <core/ssp/ssp.h>
4 #include <core/gpio/gpio.h>
5 #include <core/systick/systick.h>
6 #include <sysdefs.h>
7 #include <lpc134x.h>
8
9 #include <r0ketports.h>
10
11 #ifdef CFG_USBMSC
12 #include <core/usbhid-rom/usbmsc.h>
13
14 static uint32_t usbintstatus;
15 #endif
16
17 static void lcd_select() {
18 #ifdef CFG_USBMSC
19 if(usbMSCenabled) {
20 usbintstatus = USB_DEVINTEN;
21 USB_DEVINTEN = 0;
22 }
23 #endif
24
25 /* the LCD requires 9-Bit frames */
26 uint32_t configReg = ( SSP_SSP0CR0_DSS_9BIT // Data size = 9-bit
27 | SSP_SSP0CR0_FRF_SPI // Frame format = SPI
28 | SSP_SSP0CR0_SCR_8); // Serial clock rate = 8
29 SSP_SSP0CR0 = configReg;
30 gpioSetValue(RB_LCD_CS, 0);
31 }
32
33 static void lcd_deselect() {
34 gpioSetValue(RB_LCD_CS, 1);
35 /* reset the bus to 8-Bit frames that everyone else uses */
36 uint32_t configReg = ( SSP_SSP0CR0_DSS_8BIT // Data size = 8-bit
37 | SSP_SSP0CR0_FRF_SPI // Frame format = SPI
38 | SSP_SSP0CR0_SCR_8); // Serial clock rate = 8
39 SSP_SSP0CR0 = configReg;
40
41 #ifdef CFG_USBMSC
42 if(usbMSCenabled) {
43 USB_DEVINTEN = usbintstatus;
44 }
45 #endif
46 }
47
48 static inline void lcd_write(uint16_t frame) {
49 while ((SSP_SSP0SR & (SSP_SSP0SR_TNF_NOTFULL | SSP_SSP0SR_BSY_BUSY)) != SSP_SSP0SR_TNF_NOTFULL);
50 SSP_SSP0DR = frame;
51 while ((SSP_SSP0SR & (SSP_SSP0SR_BSY_BUSY|SSP_SSP0SR_RNE_NOTEMPTY)) != SSP_SSP0SR_RNE_NOTEMPTY);
52 /* clear the FIFO */
53 frame = SSP_SSP0DR;
54 }
55
56 static void lcd_write_command(uint8_t data) { lcd_write( data); }
57 static void lcd_write_data (uint8_t data) { lcd_write(0x0100 | data); }
58
59 void badge_display_init(void) {
60 sspInit(0, sspClockPolarity_Low, sspClockPhase_RisingEdge);
61
62 gpioSetValue(RB_LCD_CS , 1);
63 gpioSetValue(RB_LCD_RST, 1);
64
65 gpioSetDir (RB_LCD_CS , gpioDirection_Output);
66 gpioSetDir (RB_LCD_RST, gpioDirection_Output);
67
68 systickDelay(100);
69 gpioSetValue(RB_LCD_RST, 0);
70 systickDelay(100);
71 gpioSetValue(RB_LCD_RST, 1);
72 systickDelay(100);
73 /*
74 int id = lcdRead(220);
75
76 if(id == 14) {
77 gpioSetDir(1, 7, gpioDirection_Output);
78 gpioSetValue(1, 7, 1);
79 }
80 */
81
82 /* Small Nokia 1200 LCD docs:
83 * clear/ set
84 * on 0xae / 0xaf
85 * invert 0xa6 / 0xa7
86 * mirror-x 0xA0 / 0xA1
87 * mirror-y 0xc7 / 0xc8
88 *
89 * 0x20+x contrast (0=black - 0x2e)
90 * 0x40+x offset in rows from top (-0x7f)
91 * 0x80+x contrast? (0=black -0x9f?)
92 * 0xd0+x black lines from top? (-0xdf?)
93 *
94 */
95 lcd_select();
96
97 /* Decoded:
98 * E2: Internal reset
99 * AF: Display on/off: DON = 1
100 * A1: undefined?
101 * A4: all on/normal: DAL = 0
102 * 2F: charge pump on/off: PC = 1
103 * B0: set y address: Y[0-3] = 0
104 * 10: set x address (upper bits): X[6-4] = 0
105 */
106 static uint8_t const initseq[]= { 0xE2, 0xAF, // Display ON
107 // 0xA1, // Mirror-X
108 0xc8, // mirror-y
109 0xa7, // invert (1 = black)
110 0xA4, 0x2F,
111 0xB0, 0x10,
112 0x9f, 0x24 };
113 for(uint8_t i = 0; i < sizeof(initseq); ++i){
114 lcd_write_command(initseq[i]);
115 systickDelay(5);
116 }
117
118 lcd_deselect();
119 }
120
121 void badge_framebuffer_flush(badge_framebuffer const *fb) {
122 lcd_select();
123
124 lcd_write_command(0xb0);
125 lcd_write_command(0x10);
126 lcd_write_command(0x00);
127
128
129 for(int i = 0; i < 9 * 96; ++i) {
130 lcd_write_data(fb->data[0][i]);
131 }
132
133 lcd_deselect();
134 }
This page took 0.052608 seconds and 3 git commands to generate.