sharp LM085YB01T01 kijelző vezérlése.
sharp LM085YB01T01 kijelző vezérlése.
Sziasztok!
Már itt ott kérdeztem, de most jutottam olyan adatok birtokába, hogy össze kellene szedni a tudásunkat hozzá, hátha érdemleges eszköz lesz belőle.
A problémám:
A fenti cimben megnevezett kijelző vezérlése hogyan oldhtó meg arduinoval, akár plusz elektronikával is.
Amit konkrétan tudok már róla egy dataset. Ami képként van elmente, és ide szertném beszúrni. Ezek alapján mit hogyan kell kötni programozni?
Már itt ott kérdeztem, de most jutottam olyan adatok birtokába, hogy össze kellene szedni a tudásunkat hozzá, hátha érdemleges eszköz lesz belőle.
A problémám:
A fenti cimben megnevezett kijelző vezérlése hogyan oldhtó meg arduinoval, akár plusz elektronikával is.
Amit konkrétan tudok már róla egy dataset. Ami képként van elmente, és ide szertném beszúrni. Ezek alapján mit hogyan kell kötni programozni?
Nincs meg a kellő jogosultságod a hozzászóláshoz csatolt állományok megtekintéséhez.
A microkontroler sok mindenre alkalmas. a Pc bármire amire meg tudod tanítani.
Re: sharp LM085YB01T01 kijelző vezérlése.
Nézd meg a SED1330/35 és T6963 LCD vezérlők pdf-jét. Az IC-nek lesznek ilyen lábai, oda kell kötni (tehát normális, 4-bites üzemmódban működik).
Lehet, hogy más vezérlőt kell majd választanod, amelyik tudja (főleg a vízszintes) megfelelő felbontást. Igazából, így belegondolva, amelyik uC (ARM) tudja a 4-bites SPI-t kezelni mondjuk DMA-val, azzal elég könnyen megoldható lenne programból is. AVR-el ne reménykedj, nincs rá ideje (vagy csak erre).
SED esetében ha már látsz futkosó vonalakat (bekapcsoláskor auto-refress módba áll), akkor már csak a kb 1000 oldalas doksit kell átbányászni a megfelelő beállításokhoz.
Lehet, hogy más vezérlőt kell majd választanod, amelyik tudja (főleg a vízszintes) megfelelő felbontást. Igazából, így belegondolva, amelyik uC (ARM) tudja a 4-bites SPI-t kezelni mondjuk DMA-val, azzal elég könnyen megoldható lenne programból is. AVR-el ne reménykedj, nincs rá ideje (vagy csak erre).
SED esetében ha már látsz futkosó vonalakat (bekapcsoláskor auto-refress módba áll), akkor már csak a kb 1000 oldalas doksit kell átbányászni a megfelelő beállításokhoz.
Re: sharp LM085YB01T01 kijelző vezérlése.
Nem hangzik valami bizalomgerjesztően elsőre. De hosszas munkával ezek szerint lehet még belőle display.
A tapi padját az életre tudtam kelteni, vagyis odáig eljutottam vele, hogy az uno kiirja a port monitorra az érintési poziciót.
Mostmár csak a nyomkodni való képet kellene alá varázsolnom.
A tapi padját az életre tudtam kelteni, vagyis odáig eljutottam vele, hogy az uno kiirja a port monitorra az érintési poziciót.
Mostmár csak a nyomkodni való képet kellene alá varázsolnom.
A microkontroler sok mindenre alkalmas. a Pc bármire amire meg tudod tanítani.
Re: sharp LM085YB01T01 kijelző vezérlése.
Nem olyan vészes, logikus a felépítése a vezérlőknek, a T6963 egyszerűbb, a SED kicsit macerásabb, mert tud layer-eket kezelni meg grafikus/karakteres dolgokat egyszerre. Viszont be kellene szerezned egy IC-s kispanelt (valaki gyártott SED1335-os kispaneleket, de nem találom) vagy törött kijelzőt, arról beköthető. Magában csak igen rövid ideig kapcsold be (és tapizd meg a csatlékokat, akkor beszalad valami adat), mert beég (-het), szóval pár másodperc. A vezérlőkhöz mindenképp kell külső SRAM (videoram), kivéve pl. SED13700. HE forumon valaki PICcel hajtott 512x64-es, ilyen buta kijelzőt, szerintem segít Neked. A touch-pad szerintem hétköznapi, azzal nem lesz gondod.
Re: sharp LM085YB01T01 kijelző vezérlése.
Mitől éghet be a kijelző?
Ez egy fénymáxolóban volt. Ott elég sokat ment bekapcsolt állapotban uhyanazzal a képpel. De béégve nincs.
Vagy ezeknél mit jelent a beégés?
Ez egy fénymáxolóban volt. Ott elég sokat ment bekapcsolt állapotban uhyanazzal a képpel. De béégve nincs.
Vagy ezeknél mit jelent a beégés?
A microkontroler sok mindenre alkalmas. a Pc bármire amire meg tudod tanítani.
Re: sharp LM085YB01T01 kijelző vezérlése.
Az LCD maga (azaz a folyadékkristály). Ezt nem 50-50% jellel hajtva a folyadékkristály bomlani kezd.
http://www.tavir.hu - a gazda
Re: sharp LM085YB01T01 kijelző vezérlése.
Keress rá a SED1180 pdf-re, kb 10 oldalon van egy általános kijelző felépítéséről rajz. Tehát van X meg Y meghajtó (blokkok), ezek végül is hosszú shiftregiszterek, ezek vezérlése megtalálható a leírásban. A rajzon van egy soktagú feszültségosztó, ennek feszültségeit kapcsolgatja a FRAME-jellel szinkronban magára a folyadékkristályra, tehát AC meghajtást igényel. A vezérlők ezért állnak be egy auto-refress módba mindenféle inicializálás nélkül, így egy aránylag lassú pásztázást lehet látni a kijelzőn, hogy ezek az AC görbék létrejöjjenek, ne károsodjon a DC-től az anyag. Szenvedések közben kb 10 másodperces DC (tehát egy csík beszalad és ott áll) kb 6 órán keresztül látszott még, szerencsére lassan helyrerázódik (ha szerencsénk van, ha nincs, akkor örökre ott marad). Alap dolog az LCD-nél, hogy a kristály meghajtása DC összetevőt nem tartalmazhat. (ami végül is téged nem annyira érdekel, mert a vezérlő majd megoldja, ha egyszer beindul) Sokaknak sikerült túlhajtott AVR-el meghajtani ilyen kijelzőket, keress rá "Driving controller-less graphical LCD" -re.
Re: sharp LM085YB01T01 kijelző vezérlése.
Gondolkodtam rajta, hogy magából a fénymásolóból kivarázsolom a meghajtását is.
Elképzelésem szerint, magát a gombok képeit alap és benyomott állapot is egy memóriában tárolhatja. Meg gondolom azon a meghajtó ic is rajta kell legyen.
De mikor kibontottam magát az elektronikát, hát van rajta ki meg bemenő kanóc rendesen. Meg pár ic is. Igy szerintem nehézkes lesz kiszűrni melyik lehet a vezérlő ic je.
Itt a kép róla: vagyis csak lett volna, mert igy túl nagy. Majd otthon gépről felteszem, mert ott le tudom venni a méretét.
Elképzelésem szerint, magát a gombok képeit alap és benyomott állapot is egy memóriában tárolhatja. Meg gondolom azon a meghajtó ic is rajta kell legyen.
De mikor kibontottam magát az elektronikát, hát van rajta ki meg bemenő kanóc rendesen. Meg pár ic is. Igy szerintem nehézkes lesz kiszűrni melyik lehet a vezérlő ic je.
Itt a kép róla: vagyis csak lett volna, mert igy túl nagy. Majd otthon gépről felteszem, mert ott le tudom venni a méretét.
A microkontroler sok mindenre alkalmas. a Pc bármire amire meg tudod tanítani.
Re: sharp LM085YB01T01 kijelző vezérlése.
Itt vannak a képek a vezérlőjéről.
Maga az lcd még nincs feltölthető formában.
Maga az lcd még nincs feltölthető formában.
Nincs meg a kellő jogosultságod a hozzászóláshoz csatolt állományok megtekintéséhez.
A microkontroler sok mindenre alkalmas. a Pc bármire amire meg tudod tanítani.
Re: sharp LM085YB01T01 kijelző vezérlése.
Maga a vezárlő panel egyszer 24v ot meg 5 v ot kap a fénymásolótol egy szalagkábelen, amin még jön rá pár érzékelő jele, de az most nálunk nem számit.
Tapija lejön külön. Próbáltam életre kelteni, de még az se nagyon sikerűlt. A 4 vezetéket valószinű rosszul kötöm be. Vagy passz.
Tapija lejön külön. Próbáltam életre kelteni, de még az se nagyon sikerűlt. A 4 vezetéket valószinű rosszul kötöm be. Vagy passz.
A microkontroler sok mindenre alkalmas. a Pc bármire amire meg tudod tanítani.
Re: sharp LM085YB01T01 kijelző vezérlése.
A vezérlő megtartása jó ötletnek tűnik.
Olyan képek kellenének, amin látunk is valamit, ez nagyon csillog!
Nem olvasható, a középen lévő nagyobb IC típus száma?
Ha ahhoz találsz adatlapot? Még boldogulhatsz vele.
Egy ehhez hasonló házilagos megépítésén ne is álmodozzál!
Olyan képek kellenének, amin látunk is valamit, ez nagyon csillog!
Nem olvasható, a középen lévő nagyobb IC típus száma?
Ha ahhoz találsz adatlapot? Még boldogulhatsz vele.
Egy ehhez hasonló házilagos megépítésén ne is álmodozzál!
Re: sharp LM085YB01T01 kijelző vezérlése.
NYÁK-ot úgy érdemes fotózni, hogy kikapcsolod a vakut, és leteszel mellé egy zseblámpát, ami oldalról világítja meg (súrlófény). Ha megtalálod a jó irányt, akkor az IC típusjelzése szinte kiugrik a képből.
Re: sharp LM085YB01T01 kijelző vezérlése.
Nos van már újabb fejlemény a sharp kijelzővel kapcsolatban.
Találtam egy oldalt, ahol a következők voltak leírva. Sajnos csak lengyelűl. (http://www.elektroda.pl/rtvforum/topic2686696.html)
Igy esetleg lehet vele valamit kezdeni?
Admin: a következő 4 oldalas kódbeszúrásért CODE gomb nélkül fenékbebillentés jár!
Találtam egy oldalt, ahol a következők voltak leírva. Sajnos csak lengyelűl. (http://www.elektroda.pl/rtvforum/topic2686696.html)
Kód: Egész kijelölése
Atmega1284p podłaczenie do LCD:
PB0..PB3: Data bits 0..3
PD2: YSCL
PD3: M (AC)
PD4: LCD Enable
PD5: HSYNC
PD6: VSYNC
PD7: DOTCLOCK
PC1: ECL
PINOUTY:
1 – DSP_OFF10 – VDD5
2 – VSYNC11 – VDD4
3 – HSYNC12 – VDD3
4 – SFIC_K13 – VDD2
5 – +5VS14 – VDD1
6 – GND15 – VDD0
7 – N.C16 – VEE
8 – VDD717 – VLCD
9 – VDD618 – N.C
Meg 3 program kód is van, melyet próbálok az időhiányos szabadidőmben megfejteni.
1.:
// 640 x 1 x 200
// 4-bit parallel data interface.
#include <avr/io.h>
#include <stdlib.h>
#include <string.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "./config.h"
#include "./clkisr.h"
#include "./util.h"
#define NIBBLEALIGN(px) if (1) {px = (px + 3) & 0xfffc;} //align on next 4 bit boundary
// Clock Image Data
#include "./SharpClock.inc"
extern prog_uint8_t Font8x8[][8];
// SplashScreen 320 x 240
extern prog_uint8_t SplashScreen[];
//
#define max(a,b) ((a > b) ? a : b)
#define min(a,b) ((a < b) ? a : b)
//
#define COLORON 0b00000001
#define COLOROFF 0b00000000
//
// a cluster is the lowest common denominator of
// pixels and memory units (bytes/nibbles)
//
#if BITSPERPIXEL == 1
#define nClustersPerLine (nHorPixels / DATABITS)
#elif BITSPERPIXEL == 3
#define nClustersPerLine (nHorPixels / 8)
#endif
#define nLinesPerBar 20
#define CLOCKOFFSET 20 // such that the 200 x 200 Clock and the 80 x 60 picture are centered in the right side window
uint8 FrameBuffer[PHYS_LINES*BYTES_PER_LINE];
uint8 pwrup_state;
uint8 RefreshLine;
uint8 PDATA;
uint8 BDATA;
uint8 Vx, Vy, Vb; //nibble address, row address, byte address
uint Vpix; //pixel address
uint8 ParseState, PrevParseCommand;
uint8 GlobalFault;
uint8 CommandTimeout;
uint NoActivityTimeout;
uint8 SecsCountdown;
volatile uint8 SecsToAdd;
uint8 TimeSecs, TimeMins, TimeHrs;
uint8 fShowClock, fStartClock, fAutoClock;
uint XStart, XEnd, XSize; //current window limits
uint8 YStart, YEnd, YSize;
uint MaxPictureBytes;
// for Line Command
uint8 SavedArgs[9];
uint8 SavedIdx;
unsigned int BMByteCount;
#if EXTDEBUG
uint8 *pSTData;
unsigned long InCnt;
#endif
void LCDDemo(uint8 val);
void Serial_In (uint8 data);
void DrawTable(prog_uint8_t *Table, uint8 erase);
extern void InitMem(void);
#if DEBUG
uint8 ReadNibble(uint8 x, uint8 y) __attribute__ ((noinline));
void WriteNibble(uint8 val, uint8 x, uint8 y) __attribute__ ((noinline));
#else
uint8 ReadNibble(uint8 x, uint8 y);
void WriteNibble(uint8 val, uint8 x, uint8 y);
#endif
void SetPixel(uint8 color, uint x, uint8 y);
void PutChar(uint8 ch);
#if DEBUG
void MemoryScanNonZero(uint8 y);
#endif
void Parse(uint8 inByte);
void __attribute__ ((naked, section (".init1"))) // called before .do_copy_data_start
SetMem_init (void)
{
InitMem();
}
// __heap_start is defined in the linker script
extern uint8_t __heap_start;
#if DEBUG
// Check for 0xcc (in DEBUG mode) as set by SetMem();
uint16_t
GetMemUnused (void)
{
uint16_t unused = 0;
// Get end of static allocated RAM space (.data, .bss, .noinit, ...)
uint8_t *p = &__heap_start;
do
{
// Value written in InitMem() still intact?
if (*p++ != 0xcc)
break;
unused++;
} while (p <= (uint8_t *) RAMEND);
return unused;
}
#endif
void foo(void)
{
do {
asm volatile (
"nop \n\t"
);
} while (1);
}
//
// Enable debug led
//
void InitDebug(void)
{
#if USE_LED
LED_OFF;
sbi(LED_DDR,LED_BIT); //output
#endif
LED2_OFF;
sbi(LED2_DDR,LED2_BIT); //output
}
const char DiagStr0[] PROGMEM = "DebugL0 ";
const char DiagStr1[] PROGMEM = "\n\rDebugL1: 0x";
const char DiagStr2[] PROGMEM = "DebugL2\n\r";
const char DiagStr3[] PROGMEM = "DebugL3\n\r";
const char DiagStr4[] PROGMEM = "DebugL4\n\r";
const char DiagStr5[] PROGMEM = "DebugL5\n\r";
void DebugL0(uint8 err) __attribute__ ((noinline));
void DebugL0(uint8 err)
{
UARTPrintfProgStr_I((prog_char*)DiagStr0);
Printfuint8(err);
PrintfEndOfLine();
FlashLed(5, 1);
}
void DebugL1(void)
{
UARTPrintfProgStr_I((prog_char*)DiagStr1);
#if 0
// Move this to ClkIsr.c
uint8 *ptr;
Printfu16((int)TailPtr);
UARTSendByte(' ', FALSE);
FlashLed(10, 1);
//
// now print last 32 bytes from input queue
//
for (int i = 32; i >= 1; --i) {
ptr = (uint8 *)(TailPtr - i);
if (ptr < &RxBuffer[0]) ptr += RXSIZE;
Printfuint8(*ptr);
UARTSendByte(' ', FALSE);
}
#endif
PrintfEndOfLine();
}
void DebugL2(void)
{
UARTPrintfProgStr_I((prog_char*)DiagStr2);
FlashLed(10, 2);
}
void DebugL3(void)
{
UARTPrintfProgStr_I((prog_char*)DiagStr3);
FlashLed(10, 3);
}
void DebugL4(void)
{
UARTPrintfProgStr_I((prog_char*)DiagStr4);
FlashLed(10, 4);
}
void DebugL5(void)
{
UARTPrintfProgStr_I((prog_char*)DiagStr5);
FlashLed(10, 5);
}
//
// TC0 is used to do the LCD Screen Refresh
//
// Initialize TC0
// Set prescaler to clkio/64. At 20 Mhz, this is 3.2 uSec
// Using a Timer0CountUp value of 52 yields an match every 166.4 uSec.
// resulting in a refresh rate of 60 (60 x 100 = 6,000 Hz -> 166.66 uSec)
// 60Hz refresh rate shows no visible flicker, a little flicker on video.
//
// Processing time per line: 89 uSec (1/3/2011),
// meaning the LCD refresh load is 53%. At this load, the AVR has no
// trouble processing a 115,200 bps serial stream (plus there is flow control)
//
// The refresh rate can be reduced to 50 Hz and there still is no visible flicker.
//
#if F_CPU==20000000UL
#define Timer0CountUp 52 //62 for 50 Hz.
#else
error: F_CPU undefined
#endif
void InitTC0(void)
{
TCCR0A = _BV(WGM01); // run timer in CTC mode
TCCR0B = (0<<CS02)|_BV(CS01)|_BV(CS00);
OCR0A = Timer0CountUp;
}
void EnableTC0(void)
{
TIFR0 = _BV(OCF0A); //clear pending match
TIMSK0 = _BV(OCIE0A); //Enable TC0.match
}
//
// Timer1 is setup in util.c but calls the application
// specific function "AppTimer1Stuff"
//
void AppTimer1Stuff(void)
{
if (--SecsCountdown == 0) {
SecsCountdown = 10;
++SecsToAdd;
}
if (CommandTimeout != 0) {
if (--CommandTimeout == 0) {
// Command Time out. Reset State Machine
ParseState = STANDBY;
}
}
if (NoActivityTimeout != 0) {
if (--NoActivityTimeout == 0) {
// No Activity Timeout. Start Clock
// Ought to save current image, then clrscreen first
fStartClock = TRUE;
fAutoClock = TRUE;
}
}
}
void InitDebug(void);
void InitCtrl(void)
{
//
// I/O PORTS INITIALIZATION
//
SRAMDATA_DDR = SRAMDATA_MASK; //data port defaults to output
cbi(LCD_YSCL, YSCL_BIT); //active High
cbi(LCD_ENABLE, ENABLE_BIT); //disable LCD
cbi(LCD_HSYNC, HSYNC_BIT); //active High
cbi(LCD_VSYNC, VSYNC_BIT); //active High
cbi(DOTCLK, DOTCLK_BIT); //active on falling edge
cbi(LCD_ECL, ECL_BIT); //active High
sbi(YSCL_DDR, YSCL_BIT);
sbi(LCDM_DDR, M_BIT);
sbi(ENABLE_DDR, ENABLE_BIT);
sbi(HSYNC_DDR, HSYNC_BIT);
sbi(VSYNC_DDR, VSYNC_BIT);
sbi(DOTCLK_DDR, DOTCLK_BIT);
sbi(ECL_DDR, ECL_BIT);
#if DEBUG
cbi(MCU_TEST, MCU_TEST_BIT);
sbi(MCU_TEST_DDR, MCU_TEST_BIT);
#endif
//
// Disable unused parts of the AVR to reduce power consumption
//
// unused TWI, ADC, TIM2, SPI
//
// Reserve TIM1 for inByte timeout
//
PRR0 = _BV(PRTWI) | _BV(PRADC) | _BV(PRTIM2) | _BV(PRSPI);
InitTC0(); //LCD refresh timer
InitTC1(); //Timeout/Led
InitDebug();
//
// VARIABLES INITIALIZATION
//
XStart = 0;
XEnd = nHorPixels - 1;
XSize = XEnd - XStart + 1;
YStart = 0;
YEnd = nLines - 1;
YSize = YEnd - YStart + 1;
MaxPictureBytes = (YSize * (XSize / 8));
RefreshLine = 0; //LCD Line being displayed
pwrup_state = 0;
ParseState = 0; //GrState = STANDBY
PrevParseCommand = 0; //nothing
PDATA = COLORON;
BDATA = COLOROFF;
Vpix = Vx = Vy = 0;
GlobalFault = 0;
SecsCountdown = 10;
SecsToAdd = 0;
CommandTimeout = 0;
NoActivityTimeout = NOACTIVITY;
#if EXTDEBUG
pSTData = FrameBuffer;
InCnt = 0;
#endif
}
//
// WriteNibble: write a nibble to SRam.
//
// IN: r24:nibble r22 x-address r20 y-address
//
void WriteNibble(uint8 nibble, uint8 x, uint8 y)
{
uint8 b, *p;
uint x0 = x;
ASSERT(x < LOG_NIBBLES_PER_LINE);
if (x >= LOG_NIBBLES_PER_LINE) {
x = LOG_NIBBLES_PER_LINE - 1;
}
ASSERT(y < LOG_MAX_LINES);
if (y >= LOG_MAX_LINES) {
y = LOG_MAX_LINES - 1;
}
if (y >= PHYS_LINES) {
y -= PHYS_LINES;
x0 += LOG_NIBBLES_PER_LINE;
}
p = &FrameBuffer[(y * BYTES_PER_LINE) + (x0 >> 1)];
b = *p;
if (x & 1) {
b = (nibble & 0x0f) | (b & 0xf0);
} else {
b = (nibble << 4) | (b & 0x0f);
}
*p = b;
}
//
// WriteByte: write a byte to SRam.
//
// IN: r24:byte r22 x-address (in bytes) r20 y-address
//
void WriteByte(uint8 b, uint8 x, uint8 y)
{
ASSERT(x < LOG_NIBBLES_PER_LINE / 2);
if (x >= (LOG_NIBBLES_PER_LINE /2)) {
x = (LOG_NIBBLES_PER_LINE / 2) - 1;
}
ASSERT(y < LOG_MAX_LINES);
if (y >= LOG_MAX_LINES) {
y = LOG_MAX_LINES - 1;
}
if (y >= PHYS_LINES) {
y -= PHYS_LINES;
x += (LOG_NIBBLES_PER_LINE / 2);
}
FrameBuffer[(y * BYTES_PER_LINE) + x] = b;
}
uint8 ReadNibble(uint8 x, uint8 y)
{
uint8 b;
uint x0 = x;
ASSERT(x < LOG_NIBBLES_PER_LINE);
if (x >= LOG_NIBBLES_PER_LINE) {
x = LOG_NIBBLES_PER_LINE - 1;
}
ASSERT(y < LOG_MAX_LINES);
if (y >= LOG_MAX_LINES) {
y = LOG_MAX_LINES - 1;
}
if (y >= PHYS_LINES) {
y -= PHYS_LINES;
x0 += LOG_NIBBLES_PER_LINE;
}
b = FrameBuffer[(y * BYTES_PER_LINE) + (x0 >> 1)];
if (x & 1) {
return (b & 0x0f);
} else {
return (b >> 4);
}
}
//
// Write a character at the current pixel location.
// May not wrap Vpix and Vy properly.
// SED
//
void PutChar(uint8 ch)
{
uint8 i,FontLine,px;
prog_uint8_t *pCode;
NIBBLEALIGN(Vpix);
if ((Vpix + 8) > nHorPixels) { // char won't fit on current line
Vpix = 0;
Vy += 8; // Line overflow check next
}
if ((Vy + 8) > nLines) { // char won't fit on screen
Vy = 0;
}
if (((uint8)Vpix & 0x07) != 0) { // not byte aligned
px = (Vpix >> 2); // Convert to nibble
//
// write One Line at a time
for (i = 0; i < 8; i++) {
pCode = &(Font8x8[ch][i]);
FontLine = __LPM(pCode);
WriteNibble(FontLine >> 4, px, Vy+i);
WriteNibble(FontLine & 0x0f, px+1, Vy+i);
}
} else { // Vpix is byte aligned
px = (Vpix >> 3); // Convert to byte
//
// write One Line at a time
for (i = 0; i < 8; i++) {
pCode = &(Font8x8[ch][i]);
FontLine = __LPM(pCode);
WriteByte(FontLine, px, Vy+i);
}
}
Vpix += 8;
}
byte MaskTbl[4] PROGMEM = {
8, 4, 2, 1
};
//
// Set Pixel at location x, y to color
// TODO use 4 byte table to compute bitmask
//
void SetPixel(uint8 color, uint x, uint8 y)
{
uint8 v, offset, bitmask, px;
x = min(x, nHorPixels - 1);
y = min(y, nLines - 1);
px = (x >> 2); //enclosing nibble
v = ReadNibble(px, y);
offset = x & 0x03;
bitmask = __LPM(&MaskTbl[offset]);
v &= ~bitmask; //clear pixel
if (color) {
v |= bitmask;
}
WriteNibble(v, px, y);
}
//
// Bresenham line drawing
//
void DrawLine(uint x0, uint y0, uint x1, uint y1)
{
uint steep, tmp;
u32 x, y;
s16 ystep;
int deltax, deltay, error;
#if DEBUG
if ((x0 >= nHorPixels) || (x1 >= nHorPixels) || (y0 >= nLines) || (y1 >= nLines)) return;
#endif
steep = (abs(y1 - y0) > abs (x1 - x0));
if (steep) {
tmp = x0; x0 = y0; y0 = tmp; // swap(x0, y0)
tmp = x1; x1 = y1; y1 = tmp; // swap(x1, y1)
}
if (x0 > x1) {
tmp = x0; x0 = x1; x1 = tmp; // swap(x0, x1)
tmp = y0; y0 = y1; y1 = tmp; // swap(y0, y1)
}
deltax = x1 - x0;
deltay = abs(y1 - y0);
error = 0;
y = y0;
if (y0 < y1) ystep = 1;
else ystep = -1;
for (x = x0; x <= x1; x++) {
if (steep) SetPixel(PDATA, y, x);
else SetPixel(PDATA, x, y);
error += deltay;
if ((error * 2) >= deltax) {
y += ystep;
error -= deltax;
}
}
}
//
// Bresenham circle drawing
//
void DrawCircle(unsigned int cx, unsigned int cy ,unsigned int radius)
{
int x, y, xchange, ychange, radiusError;
x = radius;
y = 0;
xchange = 1 - 2 * radius;
ychange = 1;
radiusError = 0;
while(x >= y) {
SetPixel(PDATA, cx+x, cy+y );
SetPixel(PDATA, cx-x, cy+y );
SetPixel(PDATA, cx-x, cy-y );
SetPixel(PDATA, cx+x, cy-y );
SetPixel(PDATA, cx+y, cy+x );
SetPixel(PDATA, cx-y, cy+x );
SetPixel(PDATA, cx-y, cy-x );
SetPixel(PDATA, cx+y, cy-x );
y++;
radiusError += ychange;
ychange += 2;
if ( 2*radiusError + xchange > 0 ) {
x--;
radiusError += xchange;
xchange += 2;
}
}
}
void DrawTable(prog_uint8_t *Table, uint8 erase)
{
prog_uint8_t *pCode = Table;
uint8 x0,y0,x1,y1;
uint8 SavedColor = PDATA;
if (erase) {
PDATA = BDATA;
}
do {
while ((x0 = __LPM(pCode)) == 0) { //skip leading 0 bytes
++pCode;
}
++pCode;
ASSERT (x0 != 0);
y0 = min(lastLine, __LPM(pCode));
y0 = lastLine-y0; //invert Y
++pCode;
do {
x1 = __LPM(pCode);
++pCode;
if (0 == x1) break; //move to next coordinate pair
if (0xff == x1) { //end of coordinate pairs
if (erase) {
BDATA = PDATA;
PDATA = SavedColor;
}
return;
}
y1 = min(lastLine, __LPM(pCode));
y1 = lastLine-y1; //invert Y
++pCode;
DrawLine(x0 + CLOCKOFFSET, y0, x1 + CLOCKOFFSET, y1);
x0 = x1;
y0 = y1;
} while (1);
} while (1);
if (erase) {
BDATA = PDATA;
PDATA = SavedColor;
}
}
void DrawSecsHand(uint8 sec, uint8 erase)
{
if (sec >= 60)
return;
DrawTable(&SecPtrData[sec * 5], erase);
}
void DrawMinsHand(uint8 min, uint8 erase)
{
if (min >= 60)
return;
DrawTable(&MinPtrData[min * 9], erase);
}
void DrawHrsHand(uint8 hr, uint8 erase)
{
if (hr >= 12)
return;
DrawTable(&HrPtrData[hr * 45], erase);
}
void UpdateTime(void)
{
while (SecsToAdd > 0) {
--SecsToAdd;
if (fShowClock) {
DrawSecsHand(TimeSecs, TRUE); //erase current seconds hand
}
++TimeSecs;
if (TimeSecs >= 60) {
if (fShowClock) {
DrawMinsHand(TimeMins, TRUE); //erase current minutes hand
}
TimeSecs = 0;
++TimeMins;
if (TimeMins >= 60) {
if (fShowClock) {
DrawHrsHand(TimeHrs, TRUE); //erase current hours hand
}
TimeMins = 0;
++TimeHrs;
if (TimeHrs >= 12) {
TimeHrs = 0;
}
}
}
if (fShowClock) {
DrawTable(DialDigits12, FALSE);
DrawSecsHand(TimeSecs, FALSE);
DrawMinsHand(TimeMins, FALSE);
DrawHrsHand(TimeHrs, FALSE);
}
}
}
void StartClock(void)
{
fStartClock = FALSE;
fShowClock = TRUE;
DrawTable(DialData, FALSE);
DrawTable(DialDigits12, FALSE);
DrawSecsHand(TimeSecs, FALSE);
DrawMinsHand(TimeMins, FALSE);
DrawHrsHand(TimeHrs, FALSE);
}
void StopClock(void)
{
DrawTable(DialData, TRUE);
DrawTable(DialDigits12, TRUE);
DrawSecsHand(TimeSecs, TRUE);
DrawMinsHand(TimeMins, TRUE);
DrawHrsHand(TimeHrs, TRUE);
fShowClock = FALSE;
fAutoClock = FALSE;
}
uint8 PrepareNibble(uint8 color)
{
#if DEBUG
color &= 0x01;
#endif
return (color) ? 0b00001111 : 0;
}
//
// set screen area to color. Set BDATA, Vx, Vy, Vpix
//
void SetScreenX(uint8 color, uint x0, uint8 y0, uint x1, uint8 y1)
{
uint8 nibble, x, y;
//
// convert pixel address X0 to nibble boundary
// align starting pixel to next nibble boundary
// align ending pixel to previous nibble boundary
//
NIBBLEALIGN(x0);
x1 = (x1 + 0) & 0xfffc;
nibble = PrepareNibble(color);
for (y = y0; y <= y1; ++y) { // Top to Bottom
for (x = (x0 >> 2) ; x <= (x1 >> 2); ++x) {
WriteNibble(nibble, x, y);
}
}
BDATA = color; //set color as background color
Vy = y0;
Vx = (x0 >> 2);
Vpix = (Vx << 2);
}
//
// set screen to color. Set BDATA, Vx, Vy, Vpix
//
// Optimization: could to a memset on the FrameBuffer!
//
void SetScreen(uint8 color)
{
uint8 v, x, y;
#if DEBUG
color &= 0x01;
#endif
v = (color) ? 0b11111111 : 0;
for (y = 0; y < nLines; ++y) { // Top to Bottom
for (x = 0 ; x < (LOG_NIBBLES_PER_LINE / 2); ++x) {
WriteByte(v, x, y);
}
}
BDATA = color; //set color as background color
Vy = Vx = Vpix = 0;
}
#if DEBUG
//
// Draw a line using argument color. Starting at current Vy
// Use WriteNibble()
//
void HorizontalLine(uint8 color)
{
uint8 x, nibble;
nibble = PrepareNibble(color);
for (x = 0; x < nColumnsPerLine; ++x) {
WriteNibble(nibble, x, Vy);
}
}
//
// Draw a line using argument color. Starting at current Vy.
// Use SetPixel
//
void HorizontalPixelLine(uint8 color)
{
PDATA = color;
uint px;
for (px = 0; px < (nHorPixels/16); ++px) {
SetPixel(color, px, Vy);
}
}
#endif
//
// Draw a bar using argument color. Starting at current Vy
//
void HorizontalBar(uint8 color)
{
uint8 i, x, nibble;
i = nLinesPerBar; //number of lines
nibble = PrepareNibble(color);
do {
for (x = 0; x < nColumnsPerLine; ++x) {
WriteNibble(nibble, x, Vy);
}
++Vy;
} while (--i);
Vx = 0;
}
//
// horizontal test bars.
//
void HorizontalTest(void)
{
uint8 i;
Vy = 0;
for (i = 0; i < (nLines/(2 * nLinesPerBar)); ++i) { //as many as will fit
HorizontalBar(COLORON);
HorizontalBar(COLOROFF);
}
#if DEBUG
if (Vy != nLines) {
DebugL0(LCDERROR0);
}
#endif
Vx = Vy = 0;
}
//
// compare data with PDATA
//
void VerifyNibble(uint8 data)
{
// bit 0: D0 .. bit 3: D0
if ((data & 0x01) != PDATA) DebugL0(LCDERROR0);
data >>= 1;
if ((data & 0x01) != PDATA) DebugL0(LCDERROR0);
data >>= 1;
if ((data & 0x01) != PDATA) DebugL0(LCDERROR0);
data >>= 1;
if ((data & 0x01) != PDATA) DebugL0(LCDERROR0);
}
void VerifyHorizontalLine(void)
{
uint8 nibble, i = nClustersPerLine;
Vx = 0;
do {
nibble = ReadNibble(Vx, Vy);
++Vx;
VerifyNibble(nibble); //compare with PDATA
} while (--i);
}
//
// argument: expected color
//
void VerifyHorizontalBar(uint8 color)
{
uint8 i = nLinesPerBar;
PDATA = color; //save
do {
VerifyHorizontalLine();
++Vy;
} while (--i);
}
void VerifyHorizontalTest()
{
Vy = 0;
for (uint8 i = 0; i < (nLines/(2 * nLinesPerBar)); ++i) { //as many as will fit
VerifyHorizontalBar(COLORON);
VerifyHorizontalBar(COLOROFF);
}
Vx = Vy = 0; //reset
Vpix = 0;
}
//
// VerticalTest: draw vertical bars
//
void VerticalTest()
{
uint8 color, i, nibble, x, y;
for (y = 0; y < nLines; ++y) {
x = 0;
color = COLOROFF; //color
for (i = 0; i < (nColumnsPerLine >> 1); ++i) {
if (++color > COLORON) { //next color
color = COLOROFF;
}
nibble = PrepareNibble(color); //set from PDATA
WriteNibble(nibble, x, y);
WriteNibble(nibble, x+1, y);
x += 2;
}
}
Vx = Vy = 0; //reset
Vpix = 0;
}
//
// HorVertTest: draw clusters
//
void HorVertTest()
{
uint8 i, j, color0, color, nibble, x, y;
color0 = COLOROFF; //start color
for (y = 0; y < nLines;) {
if (++color0 > COLORON) { //next color
color0 = COLOROFF;
}
color = color0;
for (j = 0; j < 8; ++j) { //nr of lines per block
x = 0;
for (i = 0; i < (nColumnsPerLine >> 1); ++i) {
nibble = PrepareNibble(color); //set from PDATA
WriteNibble(nibble, x, y);
WriteNibble(nibble, x+1, y);
x += 2;
if (++color > COLORON) { //next color
color = COLOROFF;
}
}
++y;
}
}
Vx = Vy = 0; //reset
Vpix = 0;
}
//
// Draw horizontal bars slowly.
//
void SlowHorizontalBars(void)
{
uint8 i;
Vy = 0;
for (i = 0; i < (nLines/(2 * nLinesPerBar)); ++i) { //as many as will fit
HorizontalBar(COLORON);
HorizontalBar(COLOROFF);
delayOneSecond();
}
Vx = 0;
Vy = 0;
}
//
// Select a demo. All delays done by sender
//
void LCDDemo(uint8 val)
{
if (val == 1) {
HorizontalTest();
VerifyHorizontalTest();
} else if (val == 2) {
VerticalTest();
} else if (val == 3) {
HorVertTest();
} else if (val == 4) {
SlowHorizontalBars(); //takes a while
}
}
void Parse(uint8 inByte)
{
uint8 v;
//
// Setting CommandTimeout to 50 gives us 5 second
// before the ParseState is set to STANDBY
// Timeout will never occur while inside Parse() - that's the intent
//
CommandTimeout = 50;
if (ParseState == STANDBY) {
//
//Decode inByte
//
if ((inByte & SINGLEBYTEMASK) != SINGLEBYTECMD) {
//
//MultiByteCommand
//
PrevParseCommand = inByte;
ParseState = inByte & MULTIBYTEMASK;
}
else {
//
// SingleByteCommand
//
if (LCD_DUMMY == inByte) {
} else if (CLEAR_SCR == inByte) {
SetScreen(COLOROFF); // sets BDATA
PDATA = COLORON;
} else if (CLOCK_ON == inByte) {
StartClock();
} else if (CLOCK_OFF == inByte) {
StopClock();
}
//
// done with unparameterized single byte commands.
// Must be <PSET>, <X++>, <Y++>, <X-->, <Y-->, <X++,PSET>, <Y++,PSET>, <X--,PSET> or, <Y--,PSET>
// Also UNSET (Clr pixel)
else if ((inByte & PSETINCDECMASK) == PSETINCDECCMD) { //Increment, Decrement, PSET
if ((inByte & PSETPIXMASK) == PSETPIXMASK) { // unused
} else if (inByte & PSETPIXON) {
SetPixel(PDATA, Vpix, Vy); // Set Pixel
} else if (inByte & PSETPIXOFF) {
SetPixel(BDATA, Vpix, Vy); //Clear Pixel
}
//
// Now check for X/Y increment or decrement
//
v = (inByte & PSETXYMASK); //X, Y or nothing
if (v == PSETXYMASK) { //unused
} else if (v == PSETX) {
if (inByte & PSETDEC) { //Decrement
if (--Vpix == 0xffff) Vpix = lastHorPixel;
} else { //Increment
if (++Vpix == nHorPixels) Vpix = 0;
}
} else if (v == PSETY) {
if (inByte & PSETDEC) { //Decrement
if (--Vy == 0xff) Vy = lastLine;
} else { //Increment
if (++Vy == nLines) Vy = 0;
}
} else { //No X or Y action.
}
} //PSETINCDECCMD
else { // UNKNOWN or UNIMPLEMENTED
//ignore since it's single byte
}
} // SingleByteCommand
} //ParseState == STANDBY
#if EXTDEBUG
else if (ParseState == SERIALTEST) {
if ((PrevParseCommand & MULTIBYTEMASK) == SERIALTEST) {
//First time through.
SavedIdx = 0;
PrevParseCommand &= ~MULTIBYTEMASK;
}
// 1 byte argument: #of test bytes
SavedArgs[SavedIdx++] = inByte;
if (SavedIdx >= 1) {
ParseState = SERIALTEST_DATA;
PrevParseCommand = SERIALTEST;
}
}
else if (ParseState == SERIALTEST_DATA) {
if (PrevParseCommand != SERIALTEST) {
// inconsistency
DebugL1();
}
*pSTData++ = inByte; //store test bytes
if (pSTData >= &FrameBuffer[PHYS_LINES*BYTES_PER_LINE]) {
pSTData = FrameBuffer;
}
if (--SavedArgs[0] == 0) {
ParseState = STANDBY;
}
}
#endif
else if (ParseState == PICTURE) {
//
// TODO. sb pixel argument for x. If x0 or x1 not aligned
// on nibble boundary, discard the data.
// first 4 byte arguments (x0, y0, x1, y1. Nibble addresses
// then data: (((x1 - x0 + 1) * (y1 - y0 + 1)) / 2) bytes
if ((PrevParseCommand & MULTIBYTEMASK) == PICTURE) {
//First time through.
SavedIdx = 0;
PrevParseCommand &= ~MULTIBYTEMASK;
}
// 4 bytes argument: X0,Y0,X1,Y1 (nibble addresses)
SavedArgs[SavedIdx++] = inByte;
if (SavedIdx >= 4) { // collected all args
BMByteCount = ((SavedArgs[2] - SavedArgs[0] + 1) * (SavedArgs[3] - SavedArgs[1] + 1) / 2);
if (BMByteCount > MaxPictureBytes) {
// TODO. Compute excess and ignore those bytes
DebugL1();
}
// TODO: expect Pixel Argument? Cluster Argument. Use X window limits
if (SavedArgs[0] >= nClustersPerLine) SavedArgs[0] = 0; //TODO
Vx = SavedArgs[0];
// if (SavedArgs[1] < YStart) SavedArgs[1] = YStart;
if (SavedArgs[3] > YEnd) SavedArgs[3] = YEnd;
Vy = SavedArgs[3];
ParseState = PICTURE_DATA;
#if DEBUG
PrevParseCommand = PICTURE;
#endif
}
} // PICTURE
else if (ParseState == PICTURE_DATA) {
ASSERT(PrevParseCommand == PICTURE);
// 2 nibbles packed per byte, packed Upper nibble, then Lower nibble
// works as long as "x1 - x0 + 1" is even
// Data come in bottom of area lines first
if (((uint8)Vx & 0x01) != 0) { // not byte aligned
WriteNibble((inByte >> 4), Vx, Vy);
WriteNibble((inByte & 0x0f), Vx+1, Vy);
} else {
WriteByte(inByte, Vx >> 1, Vy);
}
Vx += 2;
if ((Vx - 1) == SavedArgs[2]) {
Vx = SavedArgs[0];
Vpix = (Vx << 2);
if (--Vy == SavedArgs[1] - 1) {
Vy = SavedArgs[1];
}
}
if (--BMByteCount == 0) {
ParseState = STANDBY;
}
} //PICTURE_DATA
else if ((ParseState & MULTIBYTEMASK) == COLOR) {
PDATA = (PrevParseCommand & 0x07);
BDATA = PDATA ? 0 : 1;
// ignore current byte in inByte
ParseState = STANDBY;
}
else if (ParseState == SET) {
if ((PrevParseCommand & MULTIBYTEMASK) == SET) {
//First time through.
SavedIdx = 0;
PrevParseCommand &= ~MULTIBYTEMASK;
}
// 2 bytes argument: X or Y
SavedArgs[SavedIdx++] = inByte;
if (SavedIdx >= 2) { // collected all args
if (PrevParseCommand & SETX) Vpix = SavedArgs[0] | (SavedArgs[1] << 8);
else Vy = (uint8)(SavedArgs[0] | (SavedArgs[1] << 8));
if (PrevParseCommand & SETPIXON) {
SetPixel(PDATA, Vpix, Vy);
} else if (PrevParseCommand & SETPIXOFF) {
SetPixel(BDATA, Vpix, Vy);
}
ParseState = STANDBY;
}
}
else if (ParseState == PRINT_STRING) {
//
// Print String State. Check if NULL
//
if (inByte != 0) {
PutChar(inByte);
}
else {
ParseState = STANDBY; // End of String
}
}
else if (ParseState == PUT_CHAR) {
PutChar(inByte);
ParseState = STANDBY;
}
else if (ParseState == DRAW_LINE) {
if ((PrevParseCommand & MULTIBYTEMASK) == DRAW_LINE) {
//First time through.
SavedIdx = 0;
PrevParseCommand &= ~MULTIBYTEMASK;
}
// 8 bytes argument: X0,Y0,X1,Y1
// X0, X1, Y0 and Y1 are 2 bytes each (low, high)
SavedArgs[SavedIdx++] = inByte;
if (SavedIdx >= 8) { // collected all args
DrawLine(SavedArgs[0] | (SavedArgs[1] << 8),
SavedArgs[2] | (SavedArgs[3] << 8),
SavedArgs[4] | (SavedArgs[5] << 8),
SavedArgs[6] | (SavedArgs[7] << 8));
//
// Set current coordinate to last pixel drawn
//
Vpix = SavedArgs[4] | (SavedArgs[5] << 8);
Vy = SavedArgs[6] | (SavedArgs[7] << 8);
ParseState = STANDBY;
}
}
else if (ParseState == DRAW_CIRCLE) {
if ((PrevParseCommand & MULTIBYTEMASK) == DRAW_CIRCLE) {
//First time through.
SavedIdx = 0;
PrevParseCommand &= ~MULTIBYTEMASK;
}
// 6 bytes argument: X,Y,Radius
// X, Y and Radius are 2 bytes each (low, high)
SavedArgs[SavedIdx++] = inByte;
if (SavedIdx >= 6) { // collected all args
DrawCircle(SavedArgs[0] | (SavedArgs[1] << 8),
SavedArgs[2] | (SavedArgs[3] << 8),
SavedArgs[4] | (SavedArgs[5] << 8));
//
// Set current coordinate to center of circle
//
Vpix = SavedArgs[0] | (SavedArgs[1] << 8);
Vy = SavedArgs[2] | (SavedArgs[3] << 8);
ParseState = STANDBY;
}
}
else if (ParseState == SET_SCREEN) {
if ((PrevParseCommand & MULTIBYTEMASK) == SET_SCREEN) {
//First time through.
SavedIdx = 0;
PrevParseCommand &= ~MULTIBYTEMASK;
}
// 9 bytes argument: color, X0,Y0,X1,Y1
// color is 1 byte. X0, X1, Y0 and Y1 are 2 bytes each (low, high)
SavedArgs[SavedIdx++] = inByte;
if (SavedIdx >= 9) { // collected all args
SetScreenX( SavedArgs[0],
SavedArgs[1] | (SavedArgs[2] << 8), //x0
(uint8)(SavedArgs[3] | (SavedArgs[4] << 8)), //y0
SavedArgs[5] | (SavedArgs[6] << 8), //x1
(uint8)(SavedArgs[7] | (SavedArgs[8] << 8))); //y1
ParseState = STANDBY;
}
}
else if (ParseState == LCDDEMO) {
LCDDemo(inByte); //select Demo
ParseState = STANDBY;
}
else {
DebugL1();
ParseState = STANDBY;
}
#if 0&DEBUG
if (STANDBY == ParseState) {
UARTSendByte('.', FALSE);
}
#endif
}
const char StartStr1[] PROGMEM = "\r\nEpson P3000 LCD Controller V1.2\r\n";
//
// TODO: replace columnOffset with SetWindow()
void SetSplashScreen(uint8 columnOffset)
{
//
// should compress image before enabling this feature
//
// Bitmap is for QVGA (320 x 240) screen.
// Skip first and last 20 lines (6400 pixels, 800 bytes)
//
prog_uint8_t *pCode = SplashScreen;
uint8 x, v;
int y; //needed for for loop
pCode += 800;
for (y = YEnd; y >= YStart; --y) {
//OK to use WriteByte since horizontal offset X is always even.
for (x = 0; x < (nColumnsPerLine / 2); x += 2) {
v = __LPM(pCode++);
WriteByte(v, (x / 2) + (columnOffset / 2), y);
}
}
fStartClock = TRUE; //TEST TODO
}
void Preset(void)
{
Serial_In(CLEAR_SCR); //clear Screen
Serial_In(PRINT_STRING); //String
Serial_In('R');
Serial_In('e');
Serial_In('a');
Serial_In('d');
Serial_In('y');
Serial_In(0);
}
int main(void)
{
unsigned long i = 0;
uint8 inByte;
MCUSR = 0;
GPIOR0 = 0;
InitCtrl();
if (0 == UARTInit(BAUD_115200)) {
FlashLed(10, 100);
}
fShowClock = FALSE;
fStartClock = FALSE;
fAutoClock = FALSE;
TimeSecs = 0;
TimeMins = 0;
TimeHrs = 1;
SetScreen(COLOROFF); // sets BDATA
PDATA = COLORON;
#if SPLASHSCREEN
SetSplashScreen(0);
SetSplashScreen(80);
#else
Preset(); // text to lines 0..7 through SerialIn()
#endif
//
// Enable Timer0 & Timer1 in Interrupt Mask
//
EnableTC0();
EnableTC1();
sei(); //start interrupts -> screen refresh, serial in
BlinkFast();
UARTPrintfProgStr((prog_char*)StartStr1);
#if 0
SetScreen(COLOROFF); // sets BDATA
PDATA = COLORON;
DrawTable(DialData, FALSE);
DrawTable(DialDigits12, FALSE);
DrawSecsHand(TimeMins, FALSE);
DrawMinsHand(TimeSecs, FALSE);
DrawHrsHand(TimeHrs, FALSE);
#endif
do {
//
// process queued graphic commands from SerialIn
//
while (UARTRXAvailable()) {
inByte = UARTReceiveByte();
if (fAutoClock) {
StopClock();
}
Parse(inByte);
NoActivityTimeout = NOACTIVITY; // 1 minute
}
if (GlobalFault) {
DebugL0(GlobalFault);
}
//
// Signal when buffer is empty.
if (++i == 0x4ffff) {
FlashLed(1, 5);
i = 0;
ASSERT(GetMemUnused() > 25);
}
if (fStartClock &!fShowClock) {
SetScreen(COLOROFF); // sets BDATA
PDATA = COLORON;
SetSplashScreen(80);
StartClock();
}
fStartClock = FALSE;
if (SecsToAdd > 0) {
UpdateTime();
}
} while (TRUE);
}
2.:
byte DialData[] PROGMEM = {
0x64,0xc7,0x64,0xbe,0x00,0x6e,0xc7,0x6d,0xc2,0x00,0x78,0xc5,0x77,0xc0,0x00,0x82,0xc3,0x81,0xbe,0x00,
0x8c,0xbf,0x8a,0xba,0x00,0x95,0xba,0x92,0xb4,0x00,0x9e,0xb5,0x9b,0xb1,0x00,0xa6,0xae,0xa2,0xaa,0x00,
0xad,0xa7,0xa9,0xa3,0x00,0xb4,0x9f,0xb0,0x9c,0x00,0xb9,0x96,0xb3,0x92,0x00,0xbe,0x8d,0xb9,0x8b,0x00,
0xc2,0x83,0xbd,0x82,0x00,0xc4,0x79,0xbf,0x78,0x00,0xc6,0x6f,0xc1,0x6e,0x00,0xc6,0x64,0xbd,0x64,0x00,
0xc6,0x5a,0xc1,0x5b,0x00,0xc4,0x50,0xbf,0x51,0x00,0xc2,0x46,0xbd,0x47,0x00,0xbe,0x3c,0xb9,0x3e,0x00,
0xb9,0x33,0xb3,0x36,0x00,0xb4,0x2a,0xb0,0x2d,0x00,0xad,0x22,0xa9,0x26,0x00,0xa6,0x1b,0xa2,0x1f,0x00,
0x9e,0x14,0x9b,0x18,0x00,0x95,0x0f,0x92,0x15,0x00,0x8c,0x0a,0x8a,0x0f,0x00,0x82,0x06,0x81,0x0b,0x00,
0x78,0x04,0x77,0x09,0x00,0x6e,0x02,0x6d,0x07,0x00,0x63,0x02,0x63,0x0b,0x00,0x59,0x02,0x5a,0x07,0x00,
0x4f,0x04,0x50,0x09,0x00,0x45,0x06,0x46,0x0b,0x00,0x3b,0x0a,0x3d,0x0f,0x00,0x32,0x0f,0x36,0x15,0x00,
0x29,0x14,0x2c,0x18,0x00,0x21,0x1b,0x25,0x1f,0x00,0x1a,0x22,0x1e,0x26,0x00,0x13,0x2a,0x17,0x2d,0x00,
0x0e,0x33,0x14,0x37,0x00,0x09,0x3c,0x0e,0x3e,0x00,0x05,0x46,0x0a,0x47,0x00,0x03,0x50,0x08,0x51,0x00,
0x01,0x5a,0x06,0x5b,0x00,0x01,0x65,0x0a,0x65,0x00,0x01,0x6f,0x06,0x6e,0x00,0x03,0x79,0x08,0x78,0x00,
0x05,0x83,0x0a,0x82,0x00,0x09,0x8d,0x0e,0x8b,0x00,0x0e,0x96,0x14,0x92,0x00,0x13,0x9f,0x17,0x9c,0x00,
0x1a,0xa7,0x1e,0xa3,0x00,0x21,0xae,0x25,0xaa,0x00,0x29,0xb5,0x2c,0xb1,0x00,0x32,0xba,0x35,0xb4,0x00,
0x3b,0xbf,0x3d,0xba,0x00,0x45,0xc3,0x46,0xbe,0x00,0x4f,0xc5,0x50,0xc0,0x00,0x59,0xc7,0x5a,0xc2,0xff
};
byte DialDigits12[] PROGMEM = {
0x5c,0xb9,0x5d,0xba,0x60,0xbc,0x60,0xab,0x00,0x64,0xb8,0x64,0xb9,0x65,0xba,0x66,0xbb,0x67,0xbc,0x6b,0xbc,0x6c,0xbb,0x6d,0xba,0x6e,0xb9,0x6e,0xb7,0x6d,0xb5,0x6b,0xb3,0x63,0xab,0x6f,0xab,0x00,
0x88,0xae,0x89,0xaf,0x8c,0xb1,0x8c,0xa0,0x00,0x00,
0xa5,0x95,0xa5,0x96,0xa6,0x97,0xa7,0x98,0xa8,0x99,0xac,0x99,0xad,0x98,0xae,0x97,0xaf,0x96,0xaf,0x94,0xae,0x92,0xac,0x90,0xa4,0x88,0xb0,0x88,0x00,0x00,
0xb1,0x6e,0xba,0x6e,0xb5,0x67,0xb7,0x67,0xb9,0x67,0xba,0x66,0xbb,0x63,0xbb,0x62,0xba,0x5f,0xb8,0x5d,0xb6,0x5d,0xb3,0x5d,0xb1,0x5d,0xb0,0x5e,0xaf,0x60,0x00,0xac,0x46,0xa4,0x3a,0xb1,0x3a,0x00,0xac,0x46,0xac,0x35,0x00,0x00,
0x90,0x28,0x88,0x28,0x87,0x21,0x88,0x21,0x8a,0x22,0x8d,0x22,0x8f,0x21,0x91,0x20,0x92,0x1d,0x92,0x1c,0x91,0x19,0x8f,0x17,0x8d,0x17,0x8a,0x17,0x88,0x17,0x87,0x18,0x86,0x1a,0x00,0x00,
0x68,0x1d,0x67,0x1e,0x65,0x1f,0x63,0x1f,0x60,0x1e,0x5f,0x1c,0x5e,0x18,0x5e,0x13,0x5f,0x10,0x60,0x0e,0x63,0x0e,0x64,0x0e,0x66,0x0e,0x68,0x10,0x69,0x13,0x69,0x13,0x68,0x16,0x66,0x18,0x64,0x18,0x63,0x18,0x60,0x18,0x5f,0x16,0x5e,0x13,0x00,0x42,0x28,0x39,0x17,0x00,0x36,0x28,0x42,0x28,0x00,0x00,
0x1b,0x46,0x19,0x45,0x18,0x44,0x18,0x42,0x19,0x40,0x1a,0x3f,0x1e,0x3f,0x20,0x3e,0x22,0x3c,0x23,0x3a,0x23,0x38,0x22,0x36,0x21,0x35,0x1f,0x35,0x1b,0x35,0x19,0x35,0x18,0x36,0x17,0x38,0x17,0x3a,0x18,0x3c,0x1a,0x3e,0x1c,0x3f,0x1f,0x3f,0x21,0x40,0x22,0x42,0x22,0x44,0x21,0x45,0x1f,0x46,0x1b,0x46,0x00,0x00,
0x18,0x69,0x17,0x67,0x15,0x65,0x13,0x64,0x12,0x64,0x10,0x65,0x0e,0x67,0x0d,0x69,0x0d,0x6a,0x0e,0x6d,0x10,0x6e,0x12,0x6f,0x13,0x6f,0x15,0x6e,0x17,0x6d,0x18,0x69,0x18,0x65,0x17,0x61,0x15,0x5e,0x13,0x5e,0x11,0x5e,0x0f,0x5e,0x0e,0x60,0x00,0x00,
0x19,0x96,0x1a,0x97,0x1d,0x99,0x1d,0x88,0x00,0x00,
0x25,0x99,0x23,0x98,0x21,0x96,0x20,0x92,0x20,0x8f,0x21,0x8b,0x23,0x88,0x25,0x88,0x27,0x88,0x29,0x88,0x2b,0x8b,0x2c,0x8f,0x2c,0x92,0x2b,0x96,0x29,0x98,0x27,0x99,0x25,0x99,0x00,0x00,
0x34,0xae,0x35,0xaf,0x38,0xb1,0x38,0xa0,0x00,0x00,
0x3e,0xae,0x3f,0xaf,0x42,0xb1,0x42,0xa0,0xff,0x00
};
byte SecPtrData[] PROGMEM = {
0x64,0xbe,0x64,0x64,0xff,0x6d,0xbe,0x64,0x64,0xff,0x76,0xbd,0x64,0x64,0xff,0x7f,0xba,0x64,0x64,0xff,
0x88,0xb7,0x64,0x64,0xff,0x91,0xb2,0x64,0x64,0xff,0x98,0xad,0x64,0x64,0xff,0xa0,0xa7,0x64,0x64,0xff,
0xa6,0xa1,0x64,0x64,0xff,0xac,0x99,0x64,0x64,0xff,0xb1,0x91,0x64,0x64,0xff,0xb6,0x89,0x64,0x64,0xff,
0xb9,0x80,0x64,0x64,0xff,0xbc,0x77,0x64,0x64,0xff,0xbd,0x6e,0x64,0x64,0xff,0xbd,0x64,0x64,0x64,0xff,
0xbd,0x5b,0x64,0x64,0xff,0xbc,0x52,0x64,0x64,0xff,0xb9,0x49,0x64,0x64,0xff,0xb6,0x40,0x64,0x64,0xff,
0xb1,0x37,0x64,0x64,0xff,0xac,0x30,0x64,0x64,0xff,0xa6,0x28,0x64,0x64,0xff,0xa0,0x22,0x64,0x64,0xff,
0x98,0x1c,0x64,0x64,0xff,0x91,0x17,0x64,0x64,0xff,0x88,0x12,0x64,0x64,0xff,0x7f,0x0f,0x64,0x64,0xff,
0x76,0x0c,0x64,0x64,0xff,0x6d,0x0b,0x64,0x64,0xff,0x64,0x0b,0x64,0x64,0xff,0x5a,0x0b,0x64,0x64,0xff,
0x51,0x0c,0x64,0x64,0xff,0x48,0x0f,0x64,0x64,0xff,0x3f,0x12,0x64,0x64,0xff,0x37,0x17,0x64,0x64,0xff,
0x2f,0x1c,0x64,0x64,0xff,0x27,0x22,0x64,0x64,0xff,0x21,0x28,0x64,0x64,0xff,0x1b,0x30,0x64,0x64,0xff,
0x16,0x38,0x64,0x64,0xff,0x11,0x40,0x64,0x64,0xff,0x0e,0x49,0x64,0x64,0xff,0x0b,0x52,0x64,0x64,0xff,
0x0a,0x5b,0x64,0x64,0xff,0x0a,0x64,0x64,0x64,0xff,0x0a,0x6e,0x64,0x64,0xff,0x0b,0x77,0x64,0x64,0xff,
0x0e,0x80,0x64,0x64,0xff,0x11,0x89,0x64,0x64,0xff,0x16,0x91,0x64,0x64,0xff,0x1b,0x99,0x64,0x64,0xff,
0x21,0xa1,0x64,0x64,0xff,0x27,0xa7,0x64,0x64,0xff,0x2f,0xad,0x64,0x64,0xff,0x36,0xb2,0x64,0x64,0xff,
0x3f,0xb7,0x64,0x64,0xff,0x48,0xba,0x64,0x64,0xff,0x51,0xbd,0x64,0x64,0xff,0x5a,0xbe,0x64,0x64,0xff
};
byte MinPtrData[] PROGMEM = {
0x66,0x64,0x64,0xb4,0x62,0x64,0x66,0x64,0xff,0x65,0x64,0x6c,0xb4,0x62,0x65,0x65,0x64,0xff,
0x65,0x64,0x74,0xb3,0x62,0x65,0x65,0x64,0xff,0x65,0x64,0x7c,0xb1,0x62,0x65,0x65,0x64,0xff,
0x65,0x64,0x84,0xae,0x62,0x65,0x65,0x64,0xff,0x65,0x63,0x8c,0xaa,0x62,0x66,0x65,0x63,0xff,
0x65,0x63,0x93,0xa5,0x62,0x66,0x65,0x63,0xff,0x65,0x63,0x99,0xa0,0x62,0x66,0x65,0x63,0xff,
0x65,0x63,0x9f,0x9a,0x62,0x66,0x65,0x63,0xff,0x65,0x63,0xa4,0x94,0x62,0x66,0x65,0x63,0xff,
0x64,0x63,0xa9,0x8c,0x63,0x66,0x64,0x63,0xff,0x64,0x63,0xad,0x85,0x63,0x66,0x64,0x63,0xff,
0x64,0x63,0xb0,0x7d,0x63,0x66,0x64,0x63,0xff,0x64,0x63,0xb2,0x75,0x63,0x66,0x64,0x63,0xff,
0x64,0x63,0xb3,0x6d,0x63,0x66,0x64,0x63,0xff,0x63,0x62,0xb3,0x64,0x64,0x66,0x63,0x62,0xff,
0x63,0x63,0xb3,0x5c,0x64,0x66,0x63,0x63,0xff,0x63,0x63,0xb2,0x54,0x64,0x66,0x63,0x63,0xff,
0x63,0x63,0xb0,0x4c,0x64,0x66,0x63,0x63,0xff,0x63,0x63,0xad,0x44,0x64,0x66,0x63,0x63,0xff,
0x62,0x63,0xa9,0x3c,0x65,0x66,0x62,0x63,0xff,0x62,0x63,0xa4,0x35,0x65,0x66,0x62,0x63,0xff,
0x62,0x63,0x9f,0x2f,0x65,0x66,0x62,0x63,0xff,0x62,0x63,0x99,0x29,0x65,0x66,0x62,0x63,0xff,
0x62,0x63,0x93,0x24,0x65,0x66,0x62,0x63,0xff,0x62,0x63,0x8c,0x1f,0x65,0x66,0x62,0x63,0xff,
0x62,0x64,0x84,0x1b,0x65,0x65,0x62,0x64,0xff,0x62,0x64,0x7c,0x18,0x65,0x65,0x62,0x64,0xff,
0x62,0x64,0x74,0x16,0x65,0x65,0x62,0x64,0xff,0x62,0x64,0x6c,0x15,0x65,0x65,0x62,0x64,0xff,
0x62,0x65,0x63,0x15,0x65,0x64,0x62,0x65,0xff,0x62,0x65,0x5b,0x15,0x65,0x64,0x62,0x65,0xff,
0x62,0x65,0x53,0x16,0x65,0x64,0x62,0x65,0xff,0x62,0x65,0x4b,0x18,0x65,0x64,0x62,0x65,0xff,
0x62,0x65,0x43,0x1b,0x65,0x64,0x62,0x65,0xff,0x62,0x65,0x3c,0x1f,0x65,0x64,0x62,0x65,0xff,
0x62,0x66,0x34,0x24,0x65,0x63,0x62,0x66,0xff,0x62,0x66,0x2e,0x29,0x65,0x63,0x62,0x66,0xff,
0x62,0x66,0x28,0x2f,0x65,0x63,0x62,0x66,0xff,0x62,0x66,0x23,0x35,0x65,0x63,0x62,0x66,0xff,
0x63,0x66,0x1e,0x3d,0x64,0x63,0x63,0x66,0xff,0x63,0x66,0x1a,0x44,0x64,0x63,0x63,0x66,0xff,
0x63,0x66,0x17,0x4c,0x64,0x63,0x63,0x66,0xff,0x63,0x66,0x15,0x54,0x64,0x63,0x63,0x66,0xff,
0x63,0x66,0x14,0x5c,0x64,0x63,0x63,0x66,0xff,0x64,0x66,0x14,0x65,0x63,0x62,0x64,0x66,0xff,
0x64,0x66,0x14,0x6d,0x63,0x63,0x64,0x66,0xff,0x64,0x66,0x15,0x75,0x63,0x63,0x64,0x66,0xff,
0x64,0x66,0x17,0x7d,0x63,0x63,0x64,0x66,0xff,0x64,0x66,0x1a,0x85,0x63,0x63,0x64,0x66,0xff,
0x64,0x66,0x1e,0x8c,0x63,0x63,0x64,0x66,0xff,0x65,0x66,0x23,0x94,0x62,0x63,0x65,0x66,0xff,
0x65,0x66,0x28,0x9a,0x62,0x63,0x65,0x66,0xff,0x65,0x66,0x2e,0xa0,0x62,0x63,0x65,0x66,0xff,
0x65,0x66,0x34,0xa5,0x62,0x63,0x65,0x66,0xff,0x65,0x66,0x3b,0xaa,0x62,0x63,0x65,0x66,0xff,
0x65,0x65,0x43,0xae,0x62,0x64,0x65,0x65,0xff,0x65,0x65,0x4b,0xb1,0x62,0x64,0x65,0x65,0xff,
0x65,0x65,0x53,0xb3,0x62,0x64,0x65,0x65,0xff,0x65,0x65,0x5b,0xb4,0x62,0x64,0x65,0x65,0xff
};
byte HrPtrData[] PROGMEM = {
0x66,0x64,0x64,0x9b,0x62,0x64,0x66,0x64,0xff,0x65,0x64,0x69,0x9b,0x62,0x65,0x65,0x64,0xff,
0x65,0x64,0x6f,0x9a,0x62,0x65,0x65,0x64,0xff,0x65,0x64,0x74,0x99,0x62,0x65,0x65,0x64,0xff,
0x65,0x64,0x7a,0x97,0x62,0x65,0x65,0x64,0xff,0x65,0x63,0x7f,0x94,0x62,0x66,0x65,0x63,0xff,
0x65,0x63,0x84,0x91,0x62,0x66,0x65,0x63,0xff,0x65,0x63,0x88,0x8d,0x62,0x66,0x65,0x63,0xff,
0x65,0x63,0x8c,0x89,0x62,0x66,0x65,0x63,0xff,0x65,0x63,0x90,0x85,0x62,0x66,0x65,0x63,0xff,
0x64,0x63,0x93,0x80,0x63,0x66,0x64,0x63,0xff,0x64,0x63,0x96,0x7b,0x63,0x66,0x64,0x63,0xff,
0x64,0x63,0x98,0x75,0x63,0x66,0x64,0x63,0xff,0x64,0x63,0x99,0x70,0x63,0x66,0x64,0x63,0xff,
0x64,0x63,0x9a,0x6a,0x63,0x66,0x64,0x63,0xff,0x63,0x62,0x9a,0x64,0x64,0x66,0x63,0x62,0xff,
0x63,0x63,0x9a,0x5f,0x64,0x66,0x63,0x63,0xff,0x63,0x63,0x99,0x59,0x64,0x66,0x63,0x63,0xff,
0x63,0x63,0x98,0x54,0x64,0x66,0x63,0x63,0xff,0x63,0x63,0x96,0x4e,0x64,0x66,0x63,0x63,0xff,
0x62,0x63,0x93,0x49,0x65,0x66,0x62,0x63,0xff,0x62,0x63,0x90,0x44,0x65,0x66,0x62,0x63,0xff,
0x62,0x63,0x8c,0x40,0x65,0x66,0x62,0x63,0xff,0x62,0x63,0x88,0x3c,0x65,0x66,0x62,0x63,0xff,
0x62,0x63,0x84,0x38,0x65,0x66,0x62,0x63,0xff,0x62,0x63,0x7f,0x35,0x65,0x66,0x62,0x63,0xff,
0x62,0x64,0x7a,0x32,0x65,0x65,0x62,0x64,0xff,0x62,0x64,0x74,0x30,0x65,0x65,0x62,0x64,0xff,
0x62,0x64,0x6f,0x2f,0x65,0x65,0x62,0x64,0xff,0x62,0x64,0x69,0x2e,0x65,0x65,0x62,0x64,0xff,
0x62,0x65,0x63,0x2e,0x65,0x64,0x62,0x65,0xff,0x62,0x65,0x5e,0x2e,0x65,0x64,0x62,0x65,0xff,
0x62,0x65,0x58,0x2f,0x65,0x64,0x62,0x65,0xff,0x62,0x65,0x53,0x30,0x65,0x64,0x62,0x65,0xff,
0x62,0x65,0x4d,0x32,0x65,0x64,0x62,0x65,0xff,0x62,0x65,0x48,0x35,0x65,0x64,0x62,0x65,0xff,
0x62,0x66,0x43,0x38,0x65,0x63,0x62,0x66,0xff,0x62,0x66,0x3f,0x3c,0x65,0x63,0x62,0x66,0xff,
0x62,0x66,0x3b,0x40,0x65,0x63,0x62,0x66,0xff,0x62,0x66,0x37,0x44,0x65,0x63,0x62,0x66,0xff,
0x63,0x66,0x34,0x49,0x64,0x63,0x63,0x66,0xff,0x63,0x66,0x31,0x4e,0x64,0x63,0x63,0x66,0xff,
0x63,0x66,0x2f,0x54,0x64,0x63,0x63,0x66,0xff,0x63,0x66,0x2e,0x59,0x64,0x63,0x63,0x66,0xff,
0x63,0x66,0x2d,0x5f,0x64,0x63,0x63,0x66,0xff,0x64,0x66,0x2d,0x65,0x63,0x62,0x64,0x66,0xff,
0x64,0x66,0x2d,0x6a,0x63,0x63,0x64,0x66,0xff,0x64,0x66,0x2e,0x70,0x63,0x63,0x64,0x66,0xff,
0x64,0x66,0x2f,0x75,0x63,0x63,0x64,0x66,0xff,0x64,0x66,0x31,0x7b,0x63,0x63,0x64,0x66,0xff,
0x64,0x66,0x34,0x80,0x63,0x63,0x64,0x66,0xff,0x65,0x66,0x37,0x85,0x62,0x63,0x65,0x66,0xff,
0x65,0x66,0x3b,0x89,0x62,0x63,0x65,0x66,0xff,0x65,0x66,0x3f,0x8d,0x62,0x63,0x65,0x66,0xff,
0x65,0x66,0x43,0x91,0x62,0x63,0x65,0x66,0xff,0x65,0x66,0x48,0x94,0x62,0x63,0x65,0x66,0xff,
0x65,0x65,0x4d,0x97,0x62,0x64,0x65,0x65,0xff,0x65,0x65,0x53,0x99,0x62,0x64,0x65,0x65,0xff,
0x65,0x65,0x58,0x9a,0x62,0x64,0x65,0x65,0xff,0x65,0x65,0x5e,0x9b,0x62,0x64,0x65,0x65,0xff
};
3.:
#include "./avr.inc"
#include <avr/io.h>
#include <avr/portpins.h>
#include "Configuracja.h"
.extern TextPage
.extern Font8x8
//-- map the IO register back into the IO address space
#define PA_DDR (_SFR_IO_ADDR(PORTA) - 1)
#define PB_DDR (_SFR_IO_ADDR(PORTB) - 1)
#define PC_DDR (_SFR_IO_ADDR(PORTC) - 1)
#define PD_DDR (_SFR_IO_ADDR(PORTD) - 1)
#define PA_OUT _SFR_IO_ADDR(PORTA)
#define PB_OUT _SFR_IO_ADDR(PORTB)
#define PC_OUT _SFR_IO_ADDR(PORTC)
#define PD_OUT _SFR_IO_ADDR(PORTD)
#define PA_IN (_SFR_IO_ADDR(PORTA) - 2)
#define PB_IN (_SFR_IO_ADDR(PORTB) - 2)
#define PC_IN (_SFR_IO_ADDR(PORTC) - 2)
#define PD_IN (_SFR_IO_ADDR(PORTD) - 2)
//
// GENERAL DEFINITIONS
//
// Vx is a memory nibble address, not a pixel address
// Vy is line number (pixel and memory values are identical)
//
// PB0..PD3 connected to D0..D3 (nibble data)
//
#define SRAMDATAI PB_IN
#define SRAMDATAO PB_OUT
#define SRAMDATA_DDR PB_DDR
//
// PD2 connected to YSCL
//
#define LCD_YSCL PD_OUT,YSCL_BIT
#define YSCL_DDR PD_DDR,YSCL_BIT
//
// PD3 connected to M (AC) Line
//
#define M_DDR PD_DDR,3
#define LCD_MTOGGLE PD_IN,M_BIT
//
// PD4 connected to LCD Enable
//
#define LCD_ENABLE PD_OUT,ENABLE_BIT
#define ENABLE_DDR PD_DDR,ENABLE_BIT
//
// PD5 connected to LCD HSYNC (LP)
//
#define LCD_HSYNC PD_OUT,HSYNC_BIT
#define HSYNC_DDR PD_DDR,HSYNC_BIT
//
// PD6 connected to LCD VSYNC (SF)
//
#define LCD_VSYNC PD_OUT,VSYNC_BIT
#define VSYNC_DDR PD_DDR,VSYNC_BIT
//
// PD7 connected to software DOTCLOCK (XSCL)
//
#define DOTCLK PD_OUT,DOTCLK_BIT
#define DOTCLK_PORT PD_OUT
#define DOTCLK_DDR PD_DDR,DOTCLK_BIT
//
// PC0 connected to MCU_TEST bit
//
#define MCU_TEST PC_OUT,MCU_TEST_BIT
#define MCU_TEST_DDR DDRC,MCU_TEST_BIT
//
// PC1 connected to LCD ECL
//
#define LCD_ECL PC_OUT,ECL_BIT
#define ECLDDR PC_DDR,ECL_BIT
//
// PA0 connected to LED
//
#define LEDI PA_IN,0
#define LEDO PA_OUT,0
#define LED_DDR PA_DDR,0
//
// PA1 connected to LED2
//
#define LED2I PA_IN,1
#define LED2O PA_OUT,1
#define LED2_DDR PA_DDR,1
#define COLORWHITE 0b00000001
#define COLORBLACK 0b00000000
#define BITSPERPIXEL 1
#define DATABITS 4
.section .text
#define PORTDCLKOFF r21
#define PORTDCLKON r20
.global TIMER0_COMPA_vect
//
// Assume non-data pins in PORTB are input
//
.macro UpdateColumns
ld r16,Z+
swap r16 ;ldata >> 4
out DOTCLK_PORT,PORTDCLKON ; sbi DOTCLK
out SRAMDATAO,r16
out DOTCLK_PORT,PORTDCLKOFF ; cbi DOTCLK
swap r16 ;ldata << 4
out DOTCLK_PORT,PORTDCLKON ; sbi DOTCLK
out SRAMDATAO,r16
out DOTCLK_PORT,PORTDCLKOFF ; cbi DOTCLK
.endm
//
//
// Executed every 198.4 uSec (5,000 Hz).
//
// Refreshes one display line.
// 100 lines -> 50 Screen refreshes / second
//
TIMER0_COMPA_vect:
push r16
in r16, _SFR_IO_ADDR(SREG)
push r16
#if 0
Not needed when running in CTC mode
clr r16
sts TCNT0,r16
#endif
push ZL
push ZH
push r18
push r19
push PORTDCLKOFF
push PORTDCLKON
push r0
push r1
#if DEBUG
sbi MCU_TEST
#endif
//
// get the line we're refreshing. Compute data ptr.
// todo: times 160 => times 128 + times 32
//
lds r19,RefreshLine // Y
ldi r16,160 //160 bytes per line
mul r19,r16
movw ZL,r0
eor r1,r1
subi ZL,lo8(-(FrameBuffer))
sbci ZH,hi8(-(FrameBuffer))
//
// Allow interrupts again (process Serial In while doing refresh)
//
sei
//
ldi r18,20 //1180 count
#if 1
tst r19 //RefreshLine
brne 1f
sbi LCD_VSYNC //start VSYNC
1:
#endif
//
// preload the clock toggle registers
//
in PORTDCLKOFF,DOTCLK_PORT
mov PORTDCLKON,PORTDCLKOFF
sbr PORTDCLKON,_BV(DOTCLK_BIT) //DotClk On
SED1180Loop:
UpdateColumns
UpdateColumns
UpdateColumns
UpdateColumns
UpdateColumns
UpdateColumns
UpdateColumns
UpdateColumns
//
// Transfer the 1180 to the next 1180
//
sbi LCD_ECL
cbi LCD_ECL
//
// Loop until all 20 1180s had their turn
//
dec r18
breq 1f
rjmp SED1180Loop
1:
//
// Horizontal Sync.
//
sbi LCD_ECL //needed!!
sbi LCD_YSCL
sbi LCD_HSYNC
cbi LCD_ECL //PORTC!
#if 0
tst r19 //RefreshLine
brne 1f
sbi LCD_VSYNC //start VSYNC
1:
#endif
cbi LCD_YSCL //exact sequence is essential
cbi LCD_HSYNC
cbi LCD_VSYNC //stop VSYNC
//
// Update Line Address
//
inc r19
cpi r19,PHYS_LINES
; brsh DoLCD_LastLine
; rjmp RefreshExit //done
brlo RefreshExit
DoLCD_LastLine:
//
//toggle AC line
//
sbi LCD_MTOGGLE
//
// start new frame
//
clr r19
//
// Enable display after 3 frames
//
lds r16,pwrup_state
cpi r16,3
brsh Turn_On_LCDX
inc r16
sts pwrup_state,r16
rjmp RefreshExit
Turn_On_LCDX:
sbi LCD_ENABLE
RefreshExit:
sts RefreshLine,r19
#if DEBUG
cbi MCU_TEST
#endif
pop r1
pop r0
pop PORTDCLKON
pop PORTDCLKOFF
pop r19
pop r18
pop ZH
pop ZL
Tdone:
pop r16
out _SFR_IO_ADDR(SREG),r16
pop r16
reti
#undef PORTDCLKOFF
#undef PORTDCLKON
.global InitMem
#define RAMSTART 0x0100
InitMem:
push r18
push r20
push r21
push ZL
push ZH
in r20,_SFR_IO_ADDR(SPL) ;top
in r21,_SFR_IO_ADDR(SPH)
ldi r18,0xcc
; ldiw Z,RAMSTART ;Preset RAM
ldiw Z,__heap_start
1:
st Z+,r18
cp ZL,r20
cpc ZH,r21
brne 1b
pop ZH
pop ZL
pop r21
pop r20
pop r18
ret
//## ------------------- FONTS & BITMAPS
.global Font8x8
.global Font8x8End
#include ".\Font8x8.inc"
Font8x8End:
.align
#if 0
.global DialData
.global DialDigits
.global SecPtrData
.global MinPtrData
.global HrPtrData
#include "./EpsonClk.inc"
#endif
.align
#if SPLASHSCREEN
#include ".\RoseBM.inc"
.global SplashScreen
#endif
.align
Admin: a következő 4 oldalas kódbeszúrásért CODE gomb nélkül fenékbebillentés jár!
Nincs meg a kellő jogosultságod a hozzászóláshoz csatolt állományok megtekintéséhez.
A microkontroler sok mindenre alkalmas. a Pc bármire amire meg tudod tanítani.
Re: sharp LM085YB01T01 kijelző vezérlése.
Ha van üres 10....30 órád, nyugodtan.
- A kód ATMega1284re készült (Nem Arduino támogatott chip)
- C nyelven (Nem Arduino)
Amúgy a Nextion Touch kijelzője 800x480 (5") felbontás, touch támogatásal: ~60$ -> 18 eFt.
Ha a kijelződ tudna minimum ennyit, akkor a Nextion árat oszd le 30 órára: 600 Ft órabér. És van egy olyan kijelződ amibe minimum 100 órát még bele kellene tolnod és ha meghibásodik, nem pótolható.
Gazdaságilag NEM éri meg.
Én inkább tanulnék valami rentábilisabbat:) .
- A kód ATMega1284re készült (Nem Arduino támogatott chip)
- C nyelven (Nem Arduino)
Amúgy a Nextion Touch kijelzője 800x480 (5") felbontás, touch támogatásal: ~60$ -> 18 eFt.
Ha a kijelződ tudna minimum ennyit, akkor a Nextion árat oszd le 30 órára: 600 Ft órabér. És van egy olyan kijelződ amibe minimum 100 órát még bele kellene tolnod és ha meghibásodik, nem pótolható.
Gazdaságilag NEM éri meg.
Én inkább tanulnék valami rentábilisabbat:) .
http://www.tavir.hu - a gazda
Re: sharp LM085YB01T01 kijelző vezérlése.
Ezt a kijelzőt 10.000 ért vesztegetik újonnan, és a céljaimnak tökéletesen megfelel, főleg hogy a hozzá való tapi sem több 1500 Ft nál.
A microkontroler sok mindenre alkalmas. a Pc bármire amire meg tudod tanítani.