mirror of
https://github.com/esp8266/Arduino.git
synced 2025-07-30 16:24:09 +03:00
Initial Arduino IDE based on Processing.
This commit is contained in:
381
build/shared/lib/avrlib/ks0108.c
Executable file
381
build/shared/lib/avrlib/ks0108.c
Executable file
@ -0,0 +1,381 @@
|
||||
/*! \file ks0108.c \brief Graphic LCD driver for HD61202/KS0108 displays. */
|
||||
//*****************************************************************************
|
||||
//
|
||||
// File Name : 'ks0108.c'
|
||||
// Title : Graphic LCD driver for HD61202/KS0108 displays
|
||||
// Author : Pascal Stang - Copyright (C) 2001-2003
|
||||
// Date : 10/19/2002
|
||||
// Revised : 5/5/2003
|
||||
// Version : 0.5
|
||||
// Target MCU : Atmel AVR
|
||||
// Editor Tabs : 4
|
||||
//
|
||||
// NOTE: This code is currently below version 1.0, and therefore is considered
|
||||
// to be lacking in some functionality or documentation, or may not be fully
|
||||
// tested. Nonetheless, you can expect most functions to work.
|
||||
//
|
||||
// This code is distributed under the GNU Public License
|
||||
// which can be found at http://www.gnu.org/licenses/gpl.txt
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef WIN32
|
||||
// AVR specific includes
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#endif
|
||||
|
||||
#include "global.h"
|
||||
#include "ks0108.h"
|
||||
|
||||
// global variables
|
||||
GrLcdStateType GrLcdState;
|
||||
|
||||
/*************************************************************/
|
||||
/********************** LOCAL FUNCTIONS **********************/
|
||||
/*************************************************************/
|
||||
|
||||
void glcdInitHW(void)
|
||||
{
|
||||
// initialize I/O ports
|
||||
// if I/O interface is in use
|
||||
#ifdef GLCD_PORT_INTERFACE
|
||||
|
||||
//TODO: make setup of chip select lines contingent on how
|
||||
// many controllers are actually in the display
|
||||
|
||||
// initialize LCD control lines levels
|
||||
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RS);
|
||||
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
|
||||
cbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
|
||||
cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS0);
|
||||
cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS1);
|
||||
cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS2);
|
||||
cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS3);
|
||||
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RESET);
|
||||
// initialize LCD control port to output
|
||||
sbi(GLCD_CTRL_DDR, GLCD_CTRL_RS);
|
||||
sbi(GLCD_CTRL_DDR, GLCD_CTRL_RW);
|
||||
sbi(GLCD_CTRL_DDR, GLCD_CTRL_E);
|
||||
sbi(GLCD_CTRL_DDR, GLCD_CTRL_CS0);
|
||||
sbi(GLCD_CTRL_DDR, GLCD_CTRL_CS1);
|
||||
sbi(GLCD_CTRL_DDR, GLCD_CTRL_CS2);
|
||||
sbi(GLCD_CTRL_DDR, GLCD_CTRL_CS3);
|
||||
sbi(GLCD_CTRL_DDR, GLCD_CTRL_RESET);
|
||||
// initialize LCD data
|
||||
outb(GLCD_DATA_PORT, 0x00);
|
||||
// initialize LCD data port to output
|
||||
outb(GLCD_DATA_DDR, 0xFF);
|
||||
#endif
|
||||
}
|
||||
|
||||
void glcdControllerSelect(u08 controller)
|
||||
{
|
||||
#ifdef GLCD_PORT_INTERFACE
|
||||
//TODO: make control of chip select lines contingent on how
|
||||
// many controllers are actually in the display
|
||||
|
||||
// unselect all controllers
|
||||
cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS0);
|
||||
cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS1);
|
||||
cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS2);
|
||||
cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS3);
|
||||
|
||||
// select requested controller
|
||||
switch(controller)
|
||||
{
|
||||
case 0: sbi(GLCD_CTRL_PORT, GLCD_CTRL_CS0); break;
|
||||
case 1: sbi(GLCD_CTRL_PORT, GLCD_CTRL_CS1); break;
|
||||
case 2: sbi(GLCD_CTRL_PORT, GLCD_CTRL_CS2); break;
|
||||
case 3: sbi(GLCD_CTRL_PORT, GLCD_CTRL_CS3); break;
|
||||
default: break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void glcdBusyWait(u08 controller)
|
||||
{
|
||||
#ifdef GLCD_PORT_INTERFACE
|
||||
cli();
|
||||
// wait until LCD busy bit goes to zero
|
||||
// select the controller chip
|
||||
glcdControllerSelect(controller);
|
||||
// do a read from control register
|
||||
outb(GLCD_DATA_PORT, 0xFF);
|
||||
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RS);
|
||||
outb(GLCD_DATA_DDR, 0x00);
|
||||
sbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
|
||||
sbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
|
||||
asm volatile ("nop"); asm volatile ("nop");
|
||||
while(inb(GLCD_DATA_PIN) & GLCD_STATUS_BUSY)
|
||||
{
|
||||
cbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
|
||||
asm volatile ("nop"); asm volatile ("nop");
|
||||
asm volatile ("nop"); asm volatile ("nop");
|
||||
sbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
|
||||
asm volatile ("nop"); asm volatile ("nop");
|
||||
asm volatile ("nop"); asm volatile ("nop");
|
||||
}
|
||||
cbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
|
||||
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
|
||||
outb(GLCD_DATA_DDR, 0xFF);
|
||||
sei();
|
||||
#else
|
||||
// sbi(MCUCR, SRW); // enable RAM waitstate
|
||||
// wait until LCD busy bit goes to zero
|
||||
while(*(volatile unsigned char *)
|
||||
(GLCD_CONTROLLER0_CTRL_ADDR + GLCD_CONTROLLER_ADDR_OFFSET*controller) & GLCD_STATUS_BUSY);
|
||||
// cbi(MCUCR, SRW); // disable RAM waitstate
|
||||
#endif
|
||||
}
|
||||
|
||||
void glcdControlWrite(u08 controller, u08 data)
|
||||
{
|
||||
#ifdef GLCD_PORT_INTERFACE
|
||||
cli();
|
||||
glcdBusyWait(controller); // wait until LCD not busy
|
||||
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RS);
|
||||
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
|
||||
sbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
|
||||
outb(GLCD_DATA_DDR, 0xFF);
|
||||
outb(GLCD_DATA_PORT, data);
|
||||
asm volatile ("nop"); asm volatile ("nop");
|
||||
asm volatile ("nop"); asm volatile ("nop");
|
||||
asm volatile ("nop"); asm volatile ("nop");
|
||||
asm volatile ("nop"); asm volatile ("nop");
|
||||
cbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
|
||||
sei();
|
||||
#else
|
||||
//sbi(MCUCR, SRW); // enable RAM waitstate
|
||||
glcdBusyWait(controller); // wait until LCD not busy
|
||||
*(volatile unsigned char *) (GLCD_CONTROLLER0_CTRL_ADDR + GLCD_CONTROLLER_ADDR_OFFSET*controller) = data;
|
||||
//cbi(MCUCR, SRW); // disable RAM waitstate
|
||||
#endif
|
||||
}
|
||||
|
||||
u08 glcdControlRead(u08 controller)
|
||||
{
|
||||
register u08 data;
|
||||
#ifdef GLCD_PORT_INTERFACE
|
||||
cli();
|
||||
glcdBusyWait(controller); // wait until LCD not busy
|
||||
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RS);
|
||||
outb(GLCD_DATA_DDR, 0x00);
|
||||
sbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
|
||||
sbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
|
||||
asm volatile ("nop"); asm volatile ("nop");
|
||||
asm volatile ("nop"); asm volatile ("nop");
|
||||
asm volatile ("nop"); asm volatile ("nop");
|
||||
asm volatile ("nop"); asm volatile ("nop");
|
||||
data = inb(GLCD_DATA_PIN);
|
||||
cbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
|
||||
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
|
||||
outb(GLCD_DATA_DDR, 0xFF);
|
||||
sei();
|
||||
#else
|
||||
//sbi(MCUCR, SRW); // enable RAM waitstate
|
||||
glcdBusyWait(controller); // wait until LCD not busy
|
||||
data = *(volatile unsigned char *) (GLCD_CONTROLLER0_CTRL_ADDR + GLCD_CONTROLLER_ADDR_OFFSET*controller);
|
||||
//cbi(MCUCR, SRW); // disable RAM waitstate
|
||||
#endif
|
||||
return data;
|
||||
}
|
||||
|
||||
void glcdDataWrite(u08 data)
|
||||
{
|
||||
register u08 controller = (GrLcdState.lcdXAddr/GLCD_CONTROLLER_XPIXELS);
|
||||
#ifdef GLCD_PORT_INTERFACE
|
||||
cli();
|
||||
glcdBusyWait(controller); // wait until LCD not busy
|
||||
sbi(GLCD_CTRL_PORT, GLCD_CTRL_RS);
|
||||
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
|
||||
sbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
|
||||
outb(GLCD_DATA_DDR, 0xFF);
|
||||
outb(GLCD_DATA_PORT, data);
|
||||
asm volatile ("nop"); asm volatile ("nop");
|
||||
asm volatile ("nop"); asm volatile ("nop");
|
||||
asm volatile ("nop"); asm volatile ("nop");
|
||||
asm volatile ("nop"); asm volatile ("nop");
|
||||
cbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
|
||||
sei();
|
||||
#else
|
||||
//sbi(MCUCR, SRW); // enable RAM waitstate
|
||||
glcdBusyWait(controller); // wait until LCD not busy
|
||||
*(volatile unsigned char *) (GLCD_CONTROLLER0_CTRL_ADDR + GLCD_CONTROLLER_ADDR_OFFSET*controller) = data;
|
||||
//cbi(MCUCR, SRW); // disable RAM waitstate
|
||||
#endif
|
||||
// increment our local address counter
|
||||
GrLcdState.ctrlr[controller].xAddr++;
|
||||
GrLcdState.lcdXAddr++;
|
||||
if(GrLcdState.lcdXAddr >= GLCD_XPIXELS)
|
||||
{
|
||||
GrLcdState.lcdYAddr++;
|
||||
glcdSetYAddress(GrLcdState.lcdYAddr);
|
||||
glcdSetXAddress(0);
|
||||
}
|
||||
}
|
||||
|
||||
u08 glcdDataRead(void)
|
||||
{
|
||||
register u08 data;
|
||||
register u08 controller = (GrLcdState.lcdXAddr/GLCD_CONTROLLER_XPIXELS);
|
||||
#ifdef GLCD_PORT_INTERFACE
|
||||
cli();
|
||||
glcdBusyWait(controller); // wait until LCD not busy
|
||||
sbi(GLCD_CTRL_PORT, GLCD_CTRL_RS);
|
||||
outb(GLCD_DATA_DDR, 0x00);
|
||||
sbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
|
||||
sbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
|
||||
asm volatile ("nop"); asm volatile ("nop");
|
||||
asm volatile ("nop"); asm volatile ("nop");
|
||||
asm volatile ("nop"); asm volatile ("nop");
|
||||
asm volatile ("nop"); asm volatile ("nop");
|
||||
data = inb(GLCD_DATA_PIN);
|
||||
cbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
|
||||
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
|
||||
sei();
|
||||
#else
|
||||
//sbi(MCUCR, SRW); // enable RAM waitstate
|
||||
glcdBusyWait(controller); // wait until LCD not busy
|
||||
data = *(volatile unsigned char *) (GLCD_CONTROLLER0_CTRL_ADDR + GLCD_CONTROLLER_ADDR_OFFSET*controller);
|
||||
//cbi(MCUCR, SRW); // disable RAM waitstate
|
||||
#endif
|
||||
// increment our local address counter
|
||||
GrLcdState.ctrlr[controller].xAddr++;
|
||||
GrLcdState.lcdXAddr++;
|
||||
if(GrLcdState.lcdXAddr >= GLCD_XPIXELS)
|
||||
{
|
||||
GrLcdState.lcdYAddr++;
|
||||
glcdSetYAddress(GrLcdState.lcdYAddr);
|
||||
glcdSetXAddress(0);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
void glcdReset(u08 resetState)
|
||||
{
|
||||
// reset lcd if argument is true
|
||||
// run lcd if argument is false
|
||||
#ifdef GLCD_PORT_INTERFACE
|
||||
if(resetState)
|
||||
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RESET);
|
||||
else
|
||||
sbi(GLCD_CTRL_PORT, GLCD_CTRL_RESET);
|
||||
#endif
|
||||
}
|
||||
|
||||
void glcdSetXAddress(u08 xAddr)
|
||||
{
|
||||
u08 i;
|
||||
// record address change locally
|
||||
GrLcdState.lcdXAddr = xAddr;
|
||||
|
||||
// clear y (col) address on all controllers
|
||||
for(i=0; i<GLCD_NUM_CONTROLLERS; i++)
|
||||
{
|
||||
glcdControlWrite(i, GLCD_SET_Y_ADDR | 0x00);
|
||||
GrLcdState.ctrlr[i].xAddr = 0;
|
||||
}
|
||||
|
||||
// set y (col) address on destination controller
|
||||
glcdControlWrite((GrLcdState.lcdXAddr/GLCD_CONTROLLER_XPIXELS),
|
||||
GLCD_SET_Y_ADDR | (GrLcdState.lcdXAddr & 0x3F));
|
||||
}
|
||||
|
||||
void glcdSetYAddress(u08 yAddr)
|
||||
{
|
||||
u08 i;
|
||||
// record address change locally
|
||||
GrLcdState.lcdYAddr = yAddr;
|
||||
// set page address for all controllers
|
||||
for(i=0; i<GLCD_NUM_CONTROLLERS; i++)
|
||||
{
|
||||
glcdControlWrite(i, GLCD_SET_PAGE | yAddr);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************/
|
||||
/********************* PUBLIC FUNCTIONS **********************/
|
||||
/*************************************************************/
|
||||
|
||||
void glcdInit()
|
||||
{
|
||||
u08 i;
|
||||
// initialize hardware
|
||||
glcdInitHW();
|
||||
// bring lcd out of reset
|
||||
glcdReset(FALSE);
|
||||
// Turn on LCD
|
||||
for(i=0; i<GLCD_NUM_CONTROLLERS; i++)
|
||||
{
|
||||
glcdControlWrite(i, GLCD_ON_CTRL | GLCD_ON_DISPLAY);
|
||||
}
|
||||
// clear lcd
|
||||
glcdClearScreen();
|
||||
// initialize positions
|
||||
glcdHome();
|
||||
}
|
||||
|
||||
void glcdHome(void)
|
||||
{
|
||||
u08 i;
|
||||
// initialize addresses/positions
|
||||
glcdStartLine(0);
|
||||
glcdSetAddress(0,0);
|
||||
// initialize local data structures
|
||||
for(i=0; i<GLCD_NUM_CONTROLLERS; i++)
|
||||
{
|
||||
GrLcdState.ctrlr[i].xAddr = 0;
|
||||
GrLcdState.ctrlr[i].yAddr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void glcdClearScreen(void)
|
||||
{
|
||||
u08 pageAddr;
|
||||
u08 xAddr;
|
||||
|
||||
// clear LCD
|
||||
// loop through all pages
|
||||
for(pageAddr=0; pageAddr<(GLCD_YPIXELS>>3); pageAddr++)
|
||||
{
|
||||
// set page address
|
||||
glcdSetAddress(0, pageAddr);
|
||||
// clear all lines of this page of display memory
|
||||
for(xAddr=0; xAddr<GLCD_XPIXELS; xAddr++)
|
||||
{
|
||||
glcdDataWrite(0x00);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void glcdStartLine(u08 start)
|
||||
{
|
||||
glcdControlWrite(0, GLCD_START_LINE | start);
|
||||
glcdControlWrite(1, GLCD_START_LINE | start);
|
||||
}
|
||||
|
||||
void glcdSetAddress(u08 x, u08 yLine)
|
||||
{
|
||||
// set addresses
|
||||
glcdSetYAddress(yLine);
|
||||
glcdSetXAddress(x);
|
||||
}
|
||||
|
||||
void glcdGotoChar(u08 line, u08 col)
|
||||
{
|
||||
glcdSetAddress(col*6, line);
|
||||
}
|
||||
|
||||
void glcdDelay(u16 p) // 1-8us ...2-13us ...5-31us
|
||||
{ // 10-60us ...50-290us
|
||||
unsigned int i; // 100-580us ...500-2,9ms
|
||||
unsigned char j; // 1000-5,8ms ...5000-29ms
|
||||
// 10000-56ms ...30000-170ms
|
||||
// 50000-295ms...60000-345ms
|
||||
// for (i = 0; i < p; i++) for (j = 0; j < 10; j++) asm volatile ("nop");
|
||||
for (i = 0; i < p; i++) for (j = 0; j < 10; j++);
|
||||
}
|
||||
|
||||
|
||||
// Higher level functionality has been moved to the API-layer glcd.c/glcd.h
|
Reference in New Issue
Block a user