1 // taken and adapted from
2 // Programming Sharp’s Memory LCDs
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
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)
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
18 //defines the VCOM bit in the command word that goes to the LCD
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
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
32 //current state of vcom. This should alternate
33 //between VCOM _ HI and VCOM _ LO on a 1-30 second
37 ////////////////////////////////////////////////////////////////
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.
45 // NOTE: this routine also acts as the interrupt handler for SPI interrupts.
49 // The SPI and DMA units must have been previously initialized
51 // pointer to the buffer to be displayed
53 ////////////////////////////////////////////////////////////////
54 void show _ frame(char *show _ frm) {
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
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)
71 for (i=0; i<MLCD_BYTES_LINE; i++)
72 *linebuf++ = swap(*frmbufptr++); //swap the order of the bits
73 *linebuf++ = 0; //trailer
75 //Setup the SPI DMA controller (starting addr, size)
76 TransferSetup(locbuf, linebuf - locbuf);
79 stage = 1; //set to next stage
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
91 TransferSetup(locbuf, linebuf - locbuf);
94 if (linenum > MLCD_YRES)
95 stage = 2; //all lines sent, go to next stage
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
105 //Since there is no interrupt on transmit buffer empty, loop
106 //here until the byte is sent, then drop SCS.
108 while (SPI_BSY); //wait until done
110 stage = 0; //go back to stage 0 - sending out first line