1 | 1 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,113 @@ |
1 |
+// taken and adapted from |
|
2 |
+// Programming Sharp’s Memory LCDs |
|
3 |
+// by Ken Green |
|
4 |
+ |
|
5 |
+// LCD commands - Note: the bits are reversed per the memory LCD data |
|
6 |
+// sheets because of the order the bits are shifted out in the SPI |
|
7 |
+// port. |
|
8 |
+#define MLCD_WR 0x80 //MLCD write line command |
|
9 |
+#define MLCD_CM 0x20 //MLCD clear memory command |
|
10 |
+#define MLCD_NO 0x00 //MLCD NOP command (used to switch VCOM) |
|
11 |
+ |
|
12 |
+//LCD resolution |
|
13 |
+#define MLCD_XRES 96 //pixels per horizontal line |
|
14 |
+#define MLCD_YRES 96 //pixels per vertical line |
|
15 |
+#define MLCD_BYTES_LINE MLCD_XRES / 8 //number of bytes in a line |
|
16 |
+#define MLCD_BUF_SIZE MLCD_YRES * MLCD_BYTES_LINE |
|
17 |
+ |
|
18 |
+//defines the VCOM bit in the command word that goes to the LCD |
|
19 |
+#define VCOM_HI 0x40 |
|
20 |
+#define VCOM_LO 0x00 |
|
21 |
+ |
|
22 |
+static char *frmbufter; //current address of buffer to be displayed |
|
23 |
+static char locbuf[MLCD_BYTES_LINE + 3]; // local line buffer |
|
24 |
+static char linenum; // current line number being transmitted |
|
25 |
+ |
|
26 |
+//there are 3 stages in transmitting a buffer: |
|
27 |
+//stage 0: first line (has command in it) |
|
28 |
+//stage 1: 2nd through last line (no command) |
|
29 |
+//stage 2: null byte trailer |
|
30 |
+static int stage = 0; |
|
31 |
+ |
|
32 |
+//current state of vcom. This should alternate |
|
33 |
+//between VCOM _ HI and VCOM _ LO on a 1-30 second |
|
34 |
+//period. |
|
35 |
+extern char vcom; |
|
36 |
+ |
|
37 |
+//////////////////////////////////////////////////////////////// |
|
38 |
+// |
|
39 |
+// This routine transmits the contents of the pixel memory in |
|
40 |
+// a frame buffer to the memory LCD. It uses DMA to transfer |
|
41 |
+// each individual line. The address of the frame buffer to |
|
42 |
+// transfer is in the global variable show _ frm. |
|
43 |
+// |
|
44 |
+// |
|
45 |
+// NOTE: this routine also acts as the interrupt handler for SPI interrupts. |
|
46 |
+// |
|
47 |
+// |
|
48 |
+// INPUTS: |
|
49 |
+// The SPI and DMA units must have been previously initialized |
|
50 |
+// show _ frm: |
|
51 |
+// pointer to the buffer to be displayed |
|
52 |
+// |
|
53 |
+//////////////////////////////////////////////////////////////// |
|
54 |
+void show _ frame(char *show _ frm) { |
|
55 |
+int i; |
|
56 |
+unsigned long sts; |
|
57 |
+ |
|
58 |
+ switch(stage) { |
|
59 |
+ case 0: |
|
60 |
+ // stage 0: sending the first line. The command is |
|
61 |
+ // included in this line |
|
62 |
+ set_scs(HIGH); //set SCS high |
|
63 |
+ frmbufptr = show_frm; //init pointer to frame buffer |
|
64 |
+ linebuf = locbuf; //init pointer to line buffer |
|
65 |
+ linenum = 1; //init line address |
|
66 |
+ |
|
67 |
+ //first line of data is preceeded by a write command |
|
68 |
+ *linebuf++ = MLCD _ WR | vcom; //command (note: no need to swap) |
|
69 |
+ *linebuf++ = swap(linenum++); //line number (address) |
|
70 |
+ |
|
71 |
+ for (i=0; i<MLCD_BYTES_LINE; i++) |
|
72 |
+ *linebuf++ = swap(*frmbufptr++); //swap the order of the bits |
|
73 |
+ *linebuf++ = 0; //trailer |
|
74 |
+ |
|
75 |
+ //Setup the SPI DMA controller (starting addr, size) |
|
76 |
+ TransferSetup(locbuf, linebuf - locbuf); |
|
77 |
+ //Start the xfer |
|
78 |
+ TransferStart; |
|
79 |
+ stage = 1; //set to next stage |
|
80 |
+ break; |
|
81 |
+ |
|
82 |
+ case 1: //Sending a line (other than the first line). At this |
|
83 |
+ //point the DMA transfer for the previous line is done |
|
84 |
+ //and the channel disabled. |
|
85 |
+ linebuf = locbuf; //init pointer to line buffer |
|
86 |
+ *linebuf++ = swap(linenum++); //line number |
|
87 |
+ for (i=0; i<MLCD_BYTES_LINE; i++) |
|
88 |
+ *linebuf++ = swap(*frmbufptr++); //swap the order of the bits |
|
89 |
+ *linebuf++ = 0; //trailer |
|
90 |
+ //set up DMA control |
|
91 |
+ TransferSetup(locbuf, linebuf - locbuf); |
|
92 |
+ //Start the xfer |
|
93 |
+ TransferStart; |
|
94 |
+ if (linenum > MLCD_YRES) |
|
95 |
+ stage = 2; //all lines sent, go to next stage |
|
96 |
+ break; |
|
97 |
+ case 2: |
|
98 |
+ // All lines sent, send a fi nal null byte trailer. The DMA |
|
99 |
+ //transfer of the last line is fi nished and the channel |
|
100 |
+ //disabled. All that is left is to write a trailing null |
|
101 |
+ //byte. It’s not worth using DMA to transfer 1 byte, so |
|
102 |
+ //it’s done by directing writing to the SPI port. |
|
103 |
+ //Write the last (null) byte |
|
104 |
+ Write_to_SPI(0); |
|
105 |
+ //Since there is no interrupt on transmit buffer empty, loop |
|
106 |
+ //here until the byte is sent, then drop SCS. |
|
107 |
+ i = 0; |
|
108 |
+ while (SPI_BSY); //wait until done |
|
109 |
+ set_scs(LOW); |
|
110 |
+ stage = 0; //go back to stage 0 - sending out first line |
|
111 |
+ } |
|
112 |
+} |
|
113 |
+ |