int2bcd ROM table, eliminates all divisions in clock applet displaying the time. #96

This commit is contained in:
Travis GOodspeed 2018-07-23 19:07:59 -04:00
parent 76f825295c
commit 6421f5c61b
5 changed files with 52 additions and 10 deletions

View File

@ -72,7 +72,7 @@ CC = msp430-gcc -mmcu=cc430f6137 -Wall -I. -Os $(addprefix -D, $(APPS_DEFINES))
BSL = ../bin/cc430-bsl.py -r 38400 -p $(PORT)
modules=rtcasm.o main.o lcd.o lcdtext.o rtc.o keypad.o apps.o applist.o adc.o ref.o \
modules=rtcasm.o main.o lcd.o lcdtext.o rtc.o keypad.o bcd.o apps.o applist.o adc.o ref.o \
sidebutton.o power.o uart.o monitor.o ucs.o buzz.o \
radio.o packet.o dmesg.o codeplug.o rng.o descriptor.o \
optim.o libs/assembler.o libs/morse.o

View File

@ -14,6 +14,7 @@
//GoodWatch modules.
#include "lcd.h"
#include "bcd.h"
#include "adc.h"
#include "ref.h"
#include "uart.h"

View File

@ -41,25 +41,38 @@ static void draw_time(int always){
changed, which lets us do nothing on three quarters of the
frames. Then we only draw the minutes and hours if the minutes
have changed, saving two thirds of the digit drawing on each
frame.
frame, and we only draw the tens digit if the ones digit is zero,
saving us half the LCD memory writes and trable lookups during
those frames.
This could be further improved by testing hours, but as that only
applies to one frame in 3600, it won't impact battery life very
much. When a button has been pressed or the mode changed, it is
set non-zero to force the whole frame to be drawn.
int2bcd() works by a ROM table lookup in bcd.o. The '6147 also
has a hardware BCD calculator, but as this isn't present in the
'6137 and only costs us 64 bytes of ROM, it isn't a very high
priority.
All the digits are drawn out of order for these fancy reasons.
Sorry about that.
*/
unsigned int hour=RTCHOUR;
static unsigned int min;
static unsigned int sec;//=RTCSEC;
static unsigned int sec;
unsigned int lsec; //Lower digit of the seconds.
//Only draw once a second, unless a button is pressed.
if(sec==RTCSEC && !always)
return;
sec=RTCSEC;
lcd_digit(1,sec/10);
lcd_digit(0,sec%10);
lcd_digit(0,lsec=int2bcd(sec)&0xf); //Lower digit.
if(lsec && !always) //Only need to draw tens digit if ones is zero.
return;
lcd_digit(1,int2bcd(sec)>>4);
//If the minute hasn't changed, don't bother drawing it or the hour.
if(min==RTCMIN && !always)
@ -68,12 +81,12 @@ static void draw_time(int always){
lcd_cleardigit(2); //Space between seconds and minutes.
lcd_digit(7,hour/10);
lcd_digit(6,hour%10);
lcd_digit(7,int2bcd(hour)>>4);
lcd_digit(6,int2bcd(hour)&0xf);
lcd_cleardigit(5); //Space between hours and minutes.
setcolon(1);
lcd_digit(4,min/10);
lcd_digit(3,min%10);
lcd_digit(4,int2bcd(min)>>4);
lcd_digit(3,int2bcd(min)&0xf);
setam(hour<12);
setpm(hour>=12);

19
firmware/bcd.c Normal file
View File

@ -0,0 +1,19 @@
/*! \file bcd.c
\brief Functions for converting decimal to BCD.
This uses a 60-byte ROM table to convert decimal to BCD. It is not
guaranteed outside that range, and it does not use the hardware BCD
engine of the CC430F6147.
*/
//! ROM table for conversion to BCD.
const char bcdtable[60]={
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59
};

9
firmware/bcd.h Normal file
View File

@ -0,0 +1,9 @@
/*! \file bcd.h
\brief Functions for converting decimal to BCD.
*/
//! ROM table for conversion to BCD.
extern const char bcdtable[];
//! Fetch from a ROM table for conversion to BCD.
#define int2bcd(i) bcdtable[i]