Blame |
Last modification |
View Log
| RSS feed
/*****************************************************************************
Project : Video Overlay for RC Planes
Date : 1/14/2007
Author : Gunter Logemann (C) ALL RIGHTS RESERVED
Comments:
This project is optimized to work with the Mikrocopter (www.mikrokopter.de)
Many Thanks to Gary Dion who created the first basic implementation
Data communication decoder and encoder functions are taken from the
mikrokopter (www.mikrokopter.de) project.
Redistributions of this source code (with or without modifications) or parts
of this sourcode must retain the above copyright notice, this list of
conditions and the following disclaimer.
* Neither the name of the copyright holders nor the names of contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
* The use of this source code permittet for non-commercial use (directly
or indirectly) only.
* Commercial use Is only permitted with our written permission by
Gunter Logemann (gunter@pccon.de)
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
Chip type : ATmega88
Program type : Application
Clock frequency : 20,000000 MHz
*****************************************************************************/
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/io.h>
#include "Main.h"
#define CPUSPEED_20
//#define CPUSPEED_16
//#define CPUSPEED_11059
// Macros
#define WatchdogReset() asm("wdr")
#define Wait() while(!(SPSR & (1<<SPIF)))
// Define CPU speed dependant constants:
#ifdef CPUSPEED_20
#define LINESTART 200
#define COPYRIGHTSTART 0
#define HEADINGSTART 200
#endif
#ifdef CPUSPEED_16
#define LINESTART 150
#define COPYRIGHTSTART 0
#define HEADINGSTART 200
#endif
#ifdef CPUSPEED_11059
#define LINESTART 130
#define COPYRIGHTSTART 0
#endif
// Static functions and variables
unsigned int line; // current line to be drawed
unsigned char lowbat = 0;
unsigned char showmessage1 = 0;
unsigned char framecounter = 0;
unsigned char showgraphic = 1;
unsigned char showgraphicb = 1;
static unsigned char head[17] = {'C','@','G','U','N','T','E','R','@','L','O','G','E','M','A','N','N'};
static unsigned char Message_LowBat[15] = {'@','@','L','O','W','@','B','A','T','T','E','R','Y','@','@'};
unsigned char rxtx[ 9] = {'T','X','D',0x01,'@','R','X','D',0x01};
unsigned char heading[5] = { 0x02, '0', '0', '0',0x03};
unsigned char bat[8] = { 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08};
unsigned char ubat[8] = { 'U', ':', '@', '0', '0', '.', '0', 'V'};
unsigned char rx[8] = { 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08};
unsigned char urx[8] = { 'R', 'X', ':', '@', '1', '0', '0', '/'};
unsigned char altv[6] = { '+','0', '0', '0', '0', '0'};
unsigned char bar0 = 0x00;
unsigned char bar1 = 0xfe;
int old_alt;
unsigned int alt_delta = 0;
char alt_inc = 0;
char alt_dec = 0;
// define Graphic Area (56x40 pixel)
#define GR_MaxGraph 280
#define GR_BytePerLine 7
#define GR_Lines 40
unsigned char dmem[280] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x55,0x00,0xff,0x00,0xff,0x00,
0x00,0xff,0x00,0xff,0x00,0xff,0x00,
0x00,0xff,0x00,0xff,0x00,0xff,0x00,
0x00,0xff,0x00,0xff,0x00,0xff,0x00,
0x00,0xff,0x00,0xff,0x00,0xff,0x00,
0x00,0xff,0x00,0xff,0x00,0xff,0x00,
0x00,0xff,0x00,0xff,0x00,0xff,0x00,
0x00,0xff,0x00,0xff,0x00,0xff,0x00,
0x00,0xff,0x00,0xff,0x00,0xff,0x00,
0x00,0xff,0x00,0xff,0x00,0xff,0x00,
0x00,0xff,0x00,0xff,0x00,0xff,0x00,
0x00,0xff,0x00,0xff,0x00,0xff,0x00,
0xff,0x00,0xff,0x00,0xff,0x00,0xff,
0xff,0x00,0xff,0x00,0xff,0x00,0xff,
0xff,0x00,0xff,0x00,0xff,0x00,0xff,
0xff,0x00,0xff,0x00,0xff,0x00,0xff,
0xff,0x00,0xff,0x00,0xff,0x00,0xff,
0xff,0x00,0xff,0x00,0xff,0x00,0xff,
0xff,0x00,0xff,0x00,0xff,0x00,0xff,
0xff,0x00,0xff,0x00,0xff,0x00,0xff,
0xff,0x00,0xff,0x00,0xff,0x00,0xff,
0xff,0x00,0xff,0x00,0xff,0x00,0xff,
0xff,0x00,0xff,0x00,0xff,0x00,0xff,
0xff,0x00,0xff,0x00,0xff,0x00,0xff,
0xff,0x00,0xff,0x00,0xff,0x00,0xff,
0xff,0x00,0xff,0x00,0xff,0x00,0xff,
0xff,0x00,0xff,0x00,0xff,0x00,0xff,
0xff,0x00,0xff,0x00,0xff,0x00,0xff,
0xff,0x00,0xff,0x00,0xff,0x00,0xff,
0xff,0x00,0xff,0x00,0xff,0x00,0xff,
0xff,0x00,0xff,0x00,0xff,0x00,0xff,
0xff,0x00,0xff,0x00,0xff,0x00,0xff,
0xff,0x00,0xff,0x00,0xff,0x00,0x55,
0xff,0x00,0xff,0x00,0xff,0x00,0xAA,
0xff,0x00,0xff,0x00,0xff,0x00,0x55,
0xff,0x00,0xff,0x00,0xff,0x00,0xAA,
};
// ' ' A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
static unsigned char ltrs[189] = { 0, 24,124, 60,120,126,126, 60, 66,124,126, 66, 64,130,130, 60,124, 60,124, 60,124, 66, 66,130,130,130,254,
0, 36, 66, 66, 68, 64, 64, 66, 66, 16, 8, 68, 64,198,194, 66, 66, 66, 66, 66, 16, 66, 66,130, 68, 68, 4,
0, 66, 66, 64, 66, 64, 64, 64, 66, 16, 8, 72, 64,170,162, 66, 66, 66, 66, 64, 16, 66, 66,146, 40, 40, 8,
0, 66,124, 64, 66,124,124, 78,126, 16, 8,112, 64,146,146, 66,124, 66,124, 60, 16, 66, 36,146, 16, 16, 16,
0,126, 66, 64, 66, 64, 64, 66, 66, 16, 8, 72, 64,130,138, 66, 64, 76, 72, 2, 16, 66, 36,146, 40, 16, 32,
0, 66, 66, 66, 68, 64, 64, 66, 66, 16, 72, 68,126,130,134, 66, 64, 70, 68, 66, 16, 66, 36,108, 68, 16, 64,
0, 66,124, 60,120,126, 64, 60, 66,124, 48, 66,126,130,130, 60, 64, 50, 66, 60, 16, 60, 24,108,130, 16,254};
// + , - . / 0 1 2 3 4 5 6 7 8 9 :
static unsigned char nums[112] = { 0, 0, 0, 0, 48,124, 16,124,124, 28,254,124,254,124,124, 0,
16, 0, 0, 0, 68,130, 48,130,130, 36,128,128, 2,130,130, 16,
16, 0, 0, 0, 68,130, 16, 2, 2, 68,128,128, 4,130,130, 0,
124, 0,124, 0, 48,130, 16, 12, 28,132,124,252, 8,124,126, 0,
16, 24, 0, 0, 0,130, 16, 48, 2,254, 2,130, 16,130, 4, 0,
16, 24, 0, 24, 0,130, 16, 64,130, 4,130,130, 16,130, 8, 16,
0, 0, 0, 24, 0,124, 56,254,124, 4,124,124, 16,124, 48, 0};
static unsigned char infos[63] = { 0xfe,0xfe,0x18,0x30,0x00,0x80,0xa0,0xa8,0xaa,
0xfe,0x82,0x38,0x38,0x00,0x80,0xa0,0xa8,0xaa,
0xfe,0x82,0x78,0x3c,0x00,0x80,0xa0,0xa8,0xaa,
0xfe,0x82,0xfe,0xfe,0x00,0x80,0xa0,0xa8,0xaa,
0xfe,0x82,0x7e,0x3c,0x00,0x80,0xa0,0xa8,0xaa,
0xfe,0x82,0x38,0x38,0x00,0x80,0xa0,0xa8,0xaa,
0xfe,0xfe,0x18,0x30,0x00,0x80,0xa0,0xa8,0xaa};
unsigned char display_line1[10];
unsigned char templine[5];
unsigned char mode = 0;
#define MAX_RX_BUF 100
unsigned volatile char SioTmp = 0;
unsigned volatile char RxdBuffer[MAX_RX_BUF];
unsigned volatile char NeuerDatensatzEmpfangen = 0;
unsigned volatile char CntCrcError = 0;
unsigned volatile char AnzahlEmpfangsBytes = 0;
struct str_DebugOut DebugOut;
static unsigned char grlevel[21] = { 0x00,0x00,0x00,0x18,0x00,0x00,0x00,
0xff,0xff,0xff,0x24,0xff,0xff,0xff,
0x00,0x00,0x00,0x18,0x00,0x00,0x00};
static unsigned char grlevel0[7] = { 0xAA,0xAA,0xAA,0xFF,0x55,0x55,0x55};
//-----------------------------------------------------------------------------
// copy bitmap
//-----------------------------------------------------------------------------
extern void GR_Copy(unsigned char* source,int start,int max)
{
int i;
for(i=0;i<max;i++)
{
dmem[start+i]=*source;
source++;
}
}
//-----------------------------------------------------------------------------
// Clear Graphic Area
//-----------------------------------------------------------------------------
extern void GR_Clear()
{
int i;
for(i=0;i<GR_MaxGraph;i++)
{
dmem[i]=0;
}
}
//-----------------------------------------------------------------------------
// Show and Hide Graphic area and Background
//-----------------------------------------------------------------------------
#define SHOWGRAPHIC showgraphic=1
#define HIDEGRAPHIC showgraphic=0
#define SHOWGRAPHICBACK showgraphicb=1
#define HIDEGRAPHICBACK showgraphicb=0
//-----------------------------------------------------------------------------
// Decode64
//-----------------------------------------------------------------------------
extern void Decode64(unsigned char *ptrOut, unsigned char len, unsigned char ptrIn,unsigned char max)
{
unsigned char a,b,c,d;
unsigned char ptr = 0;
unsigned char x,y,z;
while(len)
{
a = RxdBuffer[ptrIn++] - '=';
b = RxdBuffer[ptrIn++] - '=';
c = RxdBuffer[ptrIn++] - '=';
d = RxdBuffer[ptrIn++] - '=';
if(ptrIn > max - 2) break;
x = (a << 2) | (b >> 4);
y = ((b & 0x0f) << 4) | (c >> 2);
z = ((c & 0x03) << 6) | d;
if(len--) ptrOut[ptr++] = x; else break;
if(len--) ptrOut[ptr++] = y; else break;
if(len--) ptrOut[ptr++] = z; else break;
}
}
//-----------------------------------------------------------------------------
// process RX Data
//-----------------------------------------------------------------------------
extern void process_rxdata(unsigned char c)
{
static unsigned int crc;
static unsigned char crc1,crc2,buf_ptr;
static unsigned char UartState = 0;
unsigned char CrcOkay = 0;
SioTmp=c;
if(buf_ptr >= MAX_RX_BUF)
UartState = 0;
if(SioTmp == '\r' && UartState == 2)
{
UartState = 0;
crc -= RxdBuffer[buf_ptr-2];
crc -= RxdBuffer[buf_ptr-1];
crc %= 4096;
crc1 = '=' + crc / 64;
crc2 = '=' + crc % 64;
CrcOkay = 0;
if((crc1 == RxdBuffer[buf_ptr-2]) && (crc2 == RxdBuffer[buf_ptr-1]))
{
CrcOkay = 1;
}
else
{
CrcOkay = 0;
CntCrcError++;
display_line1[1]='E';
}
if(!NeuerDatensatzEmpfangen && CrcOkay) // Datensatz schon verarbeitet
{
NeuerDatensatzEmpfangen = 1;
AnzahlEmpfangsBytes = buf_ptr;
RxdBuffer[buf_ptr] = '\r';
display_line1[1]='R';
}
}
else
switch(UartState)
{
case 0:
if(SioTmp == '#' && !NeuerDatensatzEmpfangen) UartState = 1; // Startzeichen und Daten schon verarbeitet
buf_ptr = 0;
RxdBuffer[buf_ptr++] = SioTmp;
crc = SioTmp;
display_line1[2]='A';
display_line1[1]='X';
break;
case 1: // Adresse auswerten
UartState++;
RxdBuffer[buf_ptr++] = SioTmp;
crc += SioTmp;
display_line1[2]='B';
break;
case 2: // Eingangsdaten sammeln
RxdBuffer[buf_ptr] = SioTmp;
if(buf_ptr < MAX_RX_BUF) buf_ptr++;
else UartState = 0;
crc += SioTmp;
display_line1[2]='C';
break;
default:
UartState = 0;
display_line1[2]='D';
break;
}
if(rxtx[8]==0x00)
rxtx[8]=0x01;
else
rxtx[8]=0x00;
}
//-----------------------------------------------------------------------------
// convert_uint16
//-----------------------------------------------------------------------------
extern void convert_uint16(unsigned char * c,int len, unsigned int value)
{
int tempvalue, i;
char c1[7];
if(len<1) return;
for(i=0;i<len;i++) {
c1[i]='0';
}
i=len-1;
while(value>0) {
tempvalue=value;
value=value/10;
c1[i]=(tempvalue-(value*10))+'0';
i--;
}
for(i=0;i<len;i++) {
*c=c1[i];
c++;
}
}
//-----------------------------------------------------------------------------
//main
//main execution loop
//-----------------------------------------------------------------------------
extern int main(void)
{
unsigned char c;
unsigned int i;
int i1;
HIDEGRAPHIC;
HIDEGRAPHICBACK;
CLKPR=0x80;
CLKPR=0x00;
// PORT D - unused right now
PORTD = 0x10;
DDRD = 0x00;
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud rate: 57600
UCSR0A=0x00;
UCSR0B=0x18;
UCSR0C=0x86;
#ifdef CPUSPEED_20 //20.000MHz
UBRR0H=0x00;
UBRR0L=0x15;
#endif
#ifdef CPUSPEED_16 //16.000MHz
UBRR0H=0x00;
UBRR0L=0x10;
#endif
#ifdef CPUSPEED_11059 //11.059MHz
UBRR0H=0x00;
UBRR0L=0x0B;
#endif
// Initialize the 8-bit Timer0 to clock at 20/8 MHz */
TCCR0A=0x00;
TCCR0B=0x01;
// Initialize the SPI Interface
PORTB = 0x00;
DDRB = 0x3E; //0x3E
//DDRB = 0x3A;
SPCR = (1<<SPE) | (1<<MSTR) | (1<<CPHA);
SPSR = 1;
// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Falling Edge
// INT1: On
// INT1 Mode: Falling Edge
// Interrupt on any change on pins PCINT0-7: Off
// Interrupt on any change on pins PCINT8-14: Off
// Interrupt on any change on pins PCINT16-23: Off
EICRA=0x0A;
EIMSK=0x03;
EIFR=0x03;
PCICR=0x00;
// Enable interrupts
sei();
// MAIN lOOP
display_line1[0]='X';
display_line1[1]='X';
display_line1[2]='X';
display_line1[3]='X';
display_line1[4]='X';
display_line1[5]='X';
NeuerDatensatzEmpfangen = 0;
framecounter = 0;
GR_Clear();
GR_Copy(&grlevel[0],(GR_Lines/2)*7,21);
SHOWGRAPHIC;
while (1)
{
if (UCSR0A & (1<<RXC0)) {
c=UDR0;
UDR0=c;
process_rxdata(c);
}
if (framecounter<25) showmessage1=1; else showmessage1=0;
if (framecounter>50) framecounter = 0;
if(NeuerDatensatzEmpfangen) {
switch(RxdBuffer[2])
{
case 'D':
//decode the Messagee
Decode64((unsigned char *)&DebugOut,sizeof(DebugOut),3,AnzahlEmpfangsBytes);
// Heading information
convert_uint16((unsigned char *)&heading[1],3,(unsigned int)DebugOut.Analog[8]);
// Altitute Information
if(DebugOut.Analog[5]>old_alt) {
alt_inc=1;
alt_dec=0;
alt_delta=DebugOut.Analog[5]-old_alt;
}
else {
if(DebugOut.Analog[5]<old_alt) {
alt_inc=0;
alt_dec=1;
alt_delta=old_alt-DebugOut.Analog[5];
}
else {
alt_inc=0;
alt_dec=0;
alt_delta=0;
}
}
if(alt_delta>60) alt_delta=60;
if(alt_delta<0) alt_delta=0;
old_alt=DebugOut.Analog[5];
if(DebugOut.Analog[5]<0) {
altv[0]='-';
DebugOut.Analog[5]=(0xffff-(unsigned int)DebugOut.Analog[5]);
}
else {
altv[0]='+';
}
convert_uint16((unsigned char *)&altv[1],5,(unsigned int)DebugOut.Analog[5]);
//Voltage value
convert_uint16((unsigned char *)&templine[0],5,(unsigned int)DebugOut.Analog[9]);
ubat[3]=templine[2];
ubat[4]=templine[3];
ubat[6]=templine[4];
if(DebugOut.Analog[9]>90) bat[0]=0x08; else bat[0]=0x04;
if(DebugOut.Analog[9]>95) bat[1]=0x08; else bat[1]=0x04;
if(DebugOut.Analog[9]>100) bat[2]=0x08; else bat[2]=0x04;
if(DebugOut.Analog[9]>105) bat[3]=0x08; else bat[3]=0x04;
if(DebugOut.Analog[9]>110) bat[4]=0x08; else bat[4]=0x04;
if(DebugOut.Analog[9]>115) bat[5]=0x08; else bat[5]=0x04;
if(DebugOut.Analog[9]>120) bat[6]=0x08; else bat[6]=0x04;
if(DebugOut.Analog[9]>125) bat[7]=0x08; else bat[7]=0x04;
if(DebugOut.Analog[9]<94) lowbat=1; else lowbat = 0;
//RX level
i=((unsigned int)DebugOut.Analog[10]*100)/255;
convert_uint16((unsigned char *)&templine[0],5,(unsigned int)i);
urx[4]=templine[2];
urx[5]=templine[3];
urx[6]=templine[4];
if(i>10) rx[0]=0x08; else rx[0]=0x04;
if(i>20) rx[1]=0x08; else rx[1]=0x04;
if(i>30) rx[2]=0x08; else rx[2]=0x04;
if(i>40) rx[3]=0x08; else rx[3]=0x04;
if(i>50) rx[4]=0x08; else rx[4]=0x04;
if(i>60) rx[5]=0x08; else rx[5]=0x04;
if(i>70) rx[6]=0x08; else rx[6]=0x04;
if(i>80) rx[7]=0x08; else rx[7]=0x04;
// nick
i1=DebugOut.Analog[0]/50;
i1=((GR_Lines/2)-i1);
if(i1<0) i1=0;
if(i1>37) i1=37;
GR_Clear();
GR_Copy(&grlevel[0],i1*7,21);
if(i1!=20) GR_Copy(&grlevel0[0],20*7,7);
break;
default:
break;
}
NeuerDatensatzEmpfangen=0;
}
}
return(1);
} /* main */
//-----------------------------------------------------------------------------
// draw line()
// will be executed in interrupt context and will display the overlay content
//-----------------------------------------------------------------------------*/
extern void draw_line()
{
unsigned char *ltr_p;
unsigned char *num_p;
unsigned char *info_p;
short ltemp;
short ntemp;
short itemp;
unsigned int i1;
unsigned char i=0;
unsigned char c1;
unsigned char c2;
unsigned char c3;
unsigned char c4;
unsigned char c5;
unsigned char c6;
unsigned char c7;
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Bat and Heading output
if ((line > 35) && (line < 43))
{
ltemp = (line - 36) * 27 - 64;
ntemp = (line - 36) * 16 - 43;
itemp = (line - 36) * 9;
ltr_p = ltrs+ltemp;
num_p = nums+ntemp;
info_p = infos+itemp;
// +++ Bat
while(TCNT0<LINESTART);
TCNT0=0;
SPSR=1;
DDRB|=1; //sink thru PB0
SPDR = info_p[bat[0]]; Wait();
SPDR = info_p[bat[1]]; Wait();
SPDR = info_p[bat[2]]; Wait();
SPDR = info_p[bat[3]]; Wait();
SPDR = info_p[bat[4]]; Wait();
SPDR = info_p[bat[5]]; Wait();
SPDR = info_p[bat[6]]; Wait();
SPDR = info_p[bat[7]]; Wait();
DDRB&=0xFE; //PB0 Hi-Z again, and load a blank so spacing is right
// +++ Heading
TCNT0=0;
while(TCNT0<80);
TCNT0=0;
SPSR=0;
DDRB|=1;
SPDR = info_p[heading[0]]; Wait();
SPDR = num_p[heading[1]]; Wait();
SPDR = num_p[heading[2]]; Wait();
SPDR = num_p[heading[3]]; Wait();
SPDR = info_p[heading[4]]; Wait();
DDRB&=0xFE; //PB0 Hi-Z again, and load a blank so spacing is right
// +++ RX Level
while(TCNT0<250);
TCNT0=0;
while(TCNT0<70);
SPSR=1;
DDRB|=1;
SPDR = info_p[rx[0]]; Wait();
SPDR = info_p[rx[1]]; Wait();
SPDR = info_p[rx[2]]; Wait();
SPDR = info_p[rx[3]]; Wait();
SPDR = info_p[rx[4]]; Wait();
SPDR = info_p[rx[5]]; Wait();
SPDR = info_p[rx[6]]; Wait();
SPDR = info_p[rx[7]]; Wait();
DDRB&=0xFE;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// UBat
if ((line > 44) && (line < 52))
{
ltemp = (line - 45) * 27 - 64;
ntemp = (line - 45) * 16 - 43;
itemp = (line - 45) * 9;
ltr_p = ltrs+ltemp;
num_p = nums+ntemp;
info_p = infos+itemp;
// +++ UBat
while(TCNT0<LINESTART);
TCNT0=0;
SPSR=1;
DDRB|=1;
SPDR = ltr_p[ubat[0]]; Wait();
SPDR = num_p[ubat[1]]; Wait();
SPDR = ltr_p[ubat[2]]; Wait();
SPDR = num_p[ubat[3]]; Wait();
SPDR = num_p[ubat[4]]; Wait();
SPDR = num_p[ubat[5]]; Wait();
SPDR = num_p[ubat[6]]; Wait();
SPDR = ltr_p[ubat[7]]; Wait();
DDRB&=0xFE;
TCNT0=0;
while(TCNT0<80);
TCNT0=0;
while(TCNT0<250);
TCNT0=0;
while(TCNT0<70);
TCNT0=0;
SPSR=1;
DDRB|=1;
SPDR = ltr_p[urx[0]]; Wait();
SPDR = ltr_p[urx[1]]; Wait();
SPDR = num_p[urx[2]]; Wait();
SPDR = ltr_p[urx[3]]; Wait();
SPDR = num_p[urx[4]]; Wait();
SPDR = num_p[urx[5]]; Wait();
SPDR = num_p[urx[6]]; Wait();
SPDR = num_p[urx[7]]; Wait();
DDRB&=0xFE;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Message
if ((line > 60) && (line < 68) && (showmessage1) && (lowbat))
{
ltemp = (line - 61) * 27 - 64;
ntemp = (line - 61) * 16 - 43;
itemp = (line - 61) * 9;
ltr_p = ltrs+ltemp;
num_p = nums+ntemp;
info_p = infos+itemp;
// +++ UBat
while(TCNT0<LINESTART);
TCNT0=0;
while(TCNT0<250);
SPSR=1;
SPDR = ltr_p[Message_LowBat[0]]; Wait();
SPDR = ltr_p[Message_LowBat[1]]; Wait();
SPDR = ltr_p[Message_LowBat[2]]; Wait();
SPDR = ltr_p[Message_LowBat[3]]; Wait();
SPDR = ltr_p[Message_LowBat[4]]; Wait();
SPDR = ltr_p[Message_LowBat[5]]; Wait();
SPDR = ltr_p[Message_LowBat[6]]; Wait();
SPDR = ltr_p[Message_LowBat[7]]; Wait();
SPDR = ltr_p[Message_LowBat[8]]; Wait();
SPDR = ltr_p[Message_LowBat[9]]; Wait();
SPDR = ltr_p[Message_LowBat[10]]; Wait();
SPDR = ltr_p[Message_LowBat[11]]; Wait();
SPDR = ltr_p[Message_LowBat[12]]; Wait();
SPDR = ltr_p[Message_LowBat[13]]; Wait();
SPDR = ltr_p[Message_LowBat[14]]; Wait();
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// alt value
if((line > 80) && (line <250))
{
while(TCNT0<LINESTART);
TCNT0=0;
}
if ((line > 170) && (line < 178))
{
ltemp = (line - 171) * 27 - 64;
ntemp = (line - 171) * 16 - 43;
itemp = (line - 171) * 9;
ltr_p = ltrs+ltemp;
num_p = nums+ntemp;
info_p = infos+itemp;
while(TCNT0<10);
SPSR=1;
DDRB|=1;
SPDR = num_p[altv[0]]; Wait();
SPDR = num_p[altv[1]]; Wait();
SPDR = num_p[altv[2]]; Wait();
SPDR = num_p[altv[3]]; Wait();
SPDR = num_p[altv[4]]; Wait();
SPDR = num_p[altv[5]]; Wait();
DDRB&=0xFE;
}
if ((line > 179) && (line < (179 + alt_delta)) && alt_dec)
{
while(TCNT0<50);
SPDR = bar1; Wait();
}
if ((line > (169 - alt_delta)) && (line < 169) && alt_inc)
{
while(TCNT0<50);
SPDR = bar1; Wait();
}
asm("nop");
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// grafic array
if ((line > 90) && (line < 250) && (showgraphic==1))
{
while(TCNT0<250);
TCNT0=0;
i1=7*((line-90)>>2);
i=0;
c1=dmem[i1++];
c2=dmem[i1++];
c3=dmem[i1++];
c4=dmem[i1++];
c5=dmem[i1++];
c6=dmem[i1++];
c7=dmem[i1++];
while(TCNT0<20);
if (showgraphicb) DDRB|=1;
do {
PORTB=((c1<<2)&0x04);
c1=c1>>1;
i++;
} while(i<8);
do {
PORTB=((c2<<2)&0x04);
c2=c2>>1;
i++;
} while(i<16);
do {
PORTB=((c3<<2)&0x04);
c3=c3>>1;
i++;
} while(i<24);
do {
PORTB=((c4<<2)&0x04);
c4=c4>>1;
i++;
} while(i<32);
do {
PORTB=((c5<<2)&0x04);
c5=c5>>1;
i++;
} while(i<40);
do {
PORTB=((c6<<2)&0x04);
c6=c6>>1;
i++;
} while(i<48);
do {
PORTB=((c7<<2)&0x04);
c7=c7>>1;
i++;
} while(i<56);
PORTB=0x00;
DDRB&=0xFE;
}
// Debug - remove for release
// if ((line > 270) && (line < 278))
// {
// SPSR=1;
// ltemp = (line - 271) * 27 - 64;
// ntemp = (line - 271) * 16 - 43;
// itemp = (line - 271) * 8;
// ltr_p = ltrs+ltemp;
// num_p = nums+ntemp;
// info_p = infos+itemp;
// while(TCNT0<LINESTART);
// DDRB|=1; //sink thru PB0
// SPDR = ltr_p[rxtx[0]]; Wait();
// SPDR = ltr_p[rxtx[1]]; Wait();
// SPDR = ltr_p[rxtx[2]]; Wait();
// SPDR = info_p[rxtx[3]]; Wait();
// SPDR = ltr_p[rxtx[4]]; Wait();
// SPDR = ltr_p[rxtx[5]]; Wait();
// SPDR = ltr_p[rxtx[6]]; Wait();
// SPDR = ltr_p[rxtx[7]]; Wait();
// SPDR = info_p[rxtx[8]]; Wait();
// TCNT0=0;
// while(TCNT0<3); // 3 wait a little bit before turning off dimmer so that the
// // length of black box on the right matches the one on the left
// DDRB&=0xFE; //PB0 Hi-Z again, and load a blank so spacing is right
// }
// if ((line > 280) && (line < 288))
// {
// SPSR=1;
// ltemp = (line - 281) * 27 - 64;
// ntemp = (line - 281) * 16 - 43;
// ltr_p = ltrs+ltemp; //by calculating this pointer you only have to
// num_p = nums+ntemp; //add ltemp/ntemp once per line, instead of for
//every char. This tightens up printing a bit
//saves about 3 assembly instructions per char
// SPDR = ltr_p['@']; Wait(); //goofy hack to make SPSR=0 work, write an empty char at SPSR=1 first
// SPSR=1;
// while(TCNT0<LINESTART);
// DDRB|=1; //sink thru PB0
// //;display_line1[0]='A';
// SPDR = ltr_p[display_line1[0]]; Wait();
// SPDR = ltr_p[display_line1[1]]; Wait();
// SPDR = ltr_p[display_line1[2]]; Wait();
// SPDR = ltr_p[display_line1[3]]; Wait();
// SPDR = ltr_p[display_line1[4]]; Wait();
// SPDR = ltr_p[display_line1[5]]; Wait();
// TCNT0=0;
// while(TCNT0<3); // 3 wait a little bit before turning off dimmer so that the
// // length of black box on the right matches the one on the left
// DDRB&=0xFE; //PB0 Hi-Z again, and load a blank so spacing is right
// }
if ((line > 300) && (line < 308))
{
SPSR=1;
ltemp = (line - 301) * 27 - 64;
ntemp = (line - 301) * 16 - 43;
ltr_p = ltrs+ltemp;
num_p = nums+ntemp;
while(TCNT0<LINESTART+COPYRIGHTSTART);
SPDR = ltr_p[head[0]]; Wait();
SPDR = ltr_p[head[1]]; Wait();
SPDR = ltr_p[head[2]]; Wait();
SPDR = ltr_p[head[3]]; Wait();
SPDR = ltr_p[head[4]]; Wait();
SPDR = ltr_p[head[5]]; Wait();
SPDR = ltr_p[head[6]]; Wait();
SPDR = ltr_p[head[7]]; Wait();
SPDR = ltr_p[head[8]]; Wait();
SPDR = ltr_p[head[9]]; Wait();
SPDR = ltr_p[head[10]]; Wait();
SPDR = ltr_p[head[11]]; Wait();
SPDR = ltr_p[head[12]]; Wait();
SPDR = ltr_p[head[13]]; Wait();
SPDR = ltr_p[head[14]]; Wait();
SPDR = ltr_p[head[15]]; Wait();
SPDR = ltr_p[head[16]]; Wait();
TCNT0=0;
while(TCNT0<2);
}
} // end draw_line()
//-----------------------------------------------------------------------------
// H-Sync Interrupt
//-----------------------------------------------------------------------------*/
SIGNAL(SIG_INTERRUPT0)
{
TCNT0=0; // reset timer
line++; // increment line counter
draw_line(); // output the line
}
//-----------------------------------------------------------------------------
// V-Sync Interrupt
//-----------------------------------------------------------------------------*/
SIGNAL(SIG_INTERRUPT1)
{
line = 0;
framecounter++;
}