113 lines
3.8 KiB
C
113 lines
3.8 KiB
C
// taken and adapted from
|
||
// Programming Sharp’s Memory LCDs
|
||
// by Ken Green
|
||
|
||
// LCD commands - Note: the bits are reversed per the memory LCD data
|
||
// sheets because of the order the bits are shifted out in the SPI
|
||
// port.
|
||
#define MLCD_WR 0x80 //MLCD write line command
|
||
#define MLCD_CM 0x20 //MLCD clear memory command
|
||
#define MLCD_NO 0x00 //MLCD NOP command (used to switch VCOM)
|
||
|
||
//LCD resolution
|
||
#define MLCD_XRES 96 //pixels per horizontal line
|
||
#define MLCD_YRES 96 //pixels per vertical line
|
||
#define MLCD_BYTES_LINE MLCD_XRES / 8 //number of bytes in a line
|
||
#define MLCD_BUF_SIZE MLCD_YRES * MLCD_BYTES_LINE
|
||
|
||
//defines the VCOM bit in the command word that goes to the LCD
|
||
#define VCOM_HI 0x40
|
||
#define VCOM_LO 0x00
|
||
|
||
static char *frmbufter; //current address of buffer to be displayed
|
||
static char locbuf[MLCD_BYTES_LINE + 3]; // local line buffer
|
||
static char linenum; // current line number being transmitted
|
||
|
||
//there are 3 stages in transmitting a buffer:
|
||
//stage 0: first line (has command in it)
|
||
//stage 1: 2nd through last line (no command)
|
||
//stage 2: null byte trailer
|
||
static int stage = 0;
|
||
|
||
//current state of vcom. This should alternate
|
||
//between VCOM _ HI and VCOM _ LO on a 1-30 second
|
||
//period.
|
||
extern char vcom;
|
||
|
||
////////////////////////////////////////////////////////////////
|
||
//
|
||
// This routine transmits the contents of the pixel memory in
|
||
// a frame buffer to the memory LCD. It uses DMA to transfer
|
||
// each individual line. The address of the frame buffer to
|
||
// transfer is in the global variable show _ frm.
|
||
//
|
||
//
|
||
// NOTE: this routine also acts as the interrupt handler for SPI interrupts.
|
||
//
|
||
//
|
||
// INPUTS:
|
||
// The SPI and DMA units must have been previously initialized
|
||
// show _ frm:
|
||
// pointer to the buffer to be displayed
|
||
//
|
||
////////////////////////////////////////////////////////////////
|
||
void show _ frame(char *show _ frm) {
|
||
int i;
|
||
unsigned long sts;
|
||
|
||
switch(stage) {
|
||
case 0:
|
||
// stage 0: sending the first line. The command is
|
||
// included in this line
|
||
set_scs(HIGH); //set SCS high
|
||
frmbufptr = show_frm; //init pointer to frame buffer
|
||
linebuf = locbuf; //init pointer to line buffer
|
||
linenum = 1; //init line address
|
||
|
||
//first line of data is preceeded by a write command
|
||
*linebuf++ = MLCD _ WR | vcom; //command (note: no need to swap)
|
||
*linebuf++ = swap(linenum++); //line number (address)
|
||
|
||
for (i=0; i<MLCD_BYTES_LINE; i++)
|
||
*linebuf++ = swap(*frmbufptr++); //swap the order of the bits
|
||
*linebuf++ = 0; //trailer
|
||
|
||
//Setup the SPI DMA controller (starting addr, size)
|
||
TransferSetup(locbuf, linebuf - locbuf);
|
||
//Start the xfer
|
||
TransferStart;
|
||
stage = 1; //set to next stage
|
||
break;
|
||
|
||
case 1: //Sending a line (other than the first line). At this
|
||
//point the DMA transfer for the previous line is done
|
||
//and the channel disabled.
|
||
linebuf = locbuf; //init pointer to line buffer
|
||
*linebuf++ = swap(linenum++); //line number
|
||
for (i=0; i<MLCD_BYTES_LINE; i++)
|
||
*linebuf++ = swap(*frmbufptr++); //swap the order of the bits
|
||
*linebuf++ = 0; //trailer
|
||
//set up DMA control
|
||
TransferSetup(locbuf, linebuf - locbuf);
|
||
//Start the xfer
|
||
TransferStart;
|
||
if (linenum > MLCD_YRES)
|
||
stage = 2; //all lines sent, go to next stage
|
||
break;
|
||
case 2:
|
||
// All lines sent, send a fi nal null byte trailer. The DMA
|
||
//transfer of the last line is fi nished and the channel
|
||
//disabled. All that is left is to write a trailing null
|
||
//byte. It’s not worth using DMA to transfer 1 byte, so
|
||
//it’s done by directing writing to the SPI port.
|
||
//Write the last (null) byte
|
||
Write_to_SPI(0);
|
||
//Since there is no interrupt on transmit buffer empty, loop
|
||
//here until the byte is sent, then drop SCS.
|
||
i = 0;
|
||
while (SPI_BSY); //wait until done
|
||
set_scs(LOW);
|
||
stage = 0; //go back to stage 0 - sending out first line
|
||
}
|
||
}
|
||
|