boop/boop/adc/adc.c
2017-07-01 22:09:52 +02:00

164 lines
3.6 KiB
C

/*
adc.c - adc readout for battery status
Copyright (C) 2007 Ch. Klippel <ck@mamalala.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "irq.h"
#include "timerfuncs.h"
#include "adc.h"
#include "adcirq.h"
#include "lcd.h"
#include "fonty.h"
#include "lpc2220.h"
extern volatile unsigned int bat_adc;
extern volatile unsigned int bmax, bmin;
extern unsigned int is_drawing;
static unsigned short bat_max, bat_min;
static unsigned short diffs[4];
static unsigned short diff;
volatile unsigned char bat_state;
void draw_b(unsigned char x, unsigned char y)
{
unsigned char w;
if(!(is_drawing))
{
if(bat_state & BAT_DEBUG)
{
draw_block(4,0,108,24,3,DRAW_ERASE);
draw_numU(4,0,bat_min>>2,0,3,DRAW_PUT);
draw_numU(32,0,bat_max>>2,0,3,DRAW_PUT);
draw_numU(4,8,(bat_max>>2)-(bat_min>>2),0,3,DRAW_PUT);
draw_numU(60,0,bat_min,0,3,DRAW_PUT);
draw_numU(88,0,bat_max,0,3,DRAW_PUT);
draw_numU(60,8,bat_max-bat_min,0,3,DRAW_PUT);
if((bat_state & BAT_NORMAL))
draw_string(4,16,"Bat.Operation",3,DRAW_PUT);
if((bat_state & BAT_CHARGE))
draw_string(4,16,"Charging",3,DRAW_PUT);
if((bat_state & BAT_CHARGE_DONE))
draw_string(4,16,"Done Charging",3,DRAW_PUT);
}
if (bat_min<0x320)
w = 0;
else if (bat_min>0x380)
w = 12;
else
w = (bat_min-0x320)/8;
draw_block(x+1,y+1,12,5,3,DRAW_ERASE);
draw_rect(x,y,14,7,1,3,DRAW_PUT);
draw_vline(x+14,y+2,3,3,DRAW_PUT);
if(w>0)
draw_block(x+1,y+1,w,5,2,DRAW_PUT);
if(w<12)
draw_block(x+1+w,y+1,12-w,5,0,DRAW_PUT);
}
}
void calcBat(unsigned int cb)
{
ADCR |= ((1<<21) | (1<<24));
// ADCR |= (1<<24); /* Start A/D Conversion (START:0=1) */
ADINTEN = 1<<5;
}
void showBat(unsigned int cb)
{
static int cnt;
unsigned char x;
bat_max = bmax;
bat_min = bmin;
cnt &= 0x03;
diffs[cnt++] = bat_max - bat_min;
diff = 0;
for(x=0;x<4;x++)
diff += diffs[x];
diff >>= 2;
if(bat_state & BAT_NORMAL)
{
if(diff > 15)
{
bat_state |= BAT_CHARGE;
bat_state &= ~BAT_NORMAL;
}
}
else if(bat_state & BAT_CHARGE)
{
if(bat_max >= 1020)
{
bat_state |= BAT_CHARGE_DONE;
bat_state &= ~BAT_CHARGE;
}
}
else if(bat_state & BAT_CHARGE_DONE)
{
if(bat_max < 1000)
{
bat_state |= BAT_CHARGE;
bat_state &= ~BAT_CHARGE_DONE;
}
}
if((diff < 7) && (bat_min < 1000))
{
bat_state |= BAT_NORMAL;
bat_state &= ~BAT_CHARGE;
bat_state &= ~BAT_CHARGE_DONE;
}
draw_b(113,0);
bmin = bat_max;
bmax = bat_min;
}
void startADC(void)
{
ADCR = ( 1<<5 | ((15-1)<<8) /*| (1UL<<16)*/ | (1UL<<21) );
ADCR |= (1UL<<24); /* Start A/D Conversion (START:0=1) */
while ((ADDR & (1UL<<31)) == 0); /* Wait for the conversion to complete (DONE=1)*/
bmin = ((ADDR >> 6) & 0x03FF); /* Extract the A/D result */
ADCR &=~(1UL<<21);
bmax = bmin;
bat_max = bmin;
bat_min = bmin;
bat_state = BAT_NORMAL;
diffs[0] = 0;
diffs[0] = 1;
diffs[0] = 2;
diffs[0] = 3;
VICVectAddr14 = (unsigned long)&(adcIRQ);
VICVectCntl14 = VIC_SLOT_EN | INT_SRC_ADC;
VICIntEnable = INT_ADC;
startCB(addTimerCB(calcBat, 6));
startCB(addTimerCB(showBat, 220));
}