Proper getchar() routine, keypad arrangement. Close #2.

This commit is contained in:
Travis Goodspeed 2017-09-26 09:15:55 -04:00
parent 5010755477
commit ffbcb11212
7 changed files with 151 additions and 22 deletions

View File

@ -5,14 +5,14 @@ CC = msp430-gcc -mmcu=cc430f6137 -Wall
BSL = ../bin/cc430-bsl.py BSL = ../bin/cc430-bsl.py
modules=main.o lcd.o lcdtext.o rtc.o modules=main.o lcd.o lcdtext.o rtc.o keypad.o
all: goodwatch.hex all: goodwatch.hex
goodwatch: $(modules) goodwatch: $(modules)
$(CC) -o goodwatch $(modules) $(CC) -o goodwatch $(modules)
goodwatch.hex: goodwatch goodwatch.hex: goodwatch
msp430-objcopy -O ihex goodwatch goodwatch.hex msp430-objcopy -O ihex goodwatch goodwatch.hex
clean: clean:
rm -f *~ *.hex *.elf *.o goodwatch rm -f *~ *.hex *.elf *.o goodwatch

127
firmware/keypad.c Normal file
View File

@ -0,0 +1,127 @@
#include <msp430.h>
//Initializes the keypad pin directions.
void key_init(){
/* The keypad uses P1.7 and all of Port 2. Pins are bridged
together by rows and columns, which requires active scanning for
a read but can allow for an initial wakeup on an interrupt. */
P2SEL=0x00; //All of port 2 are IO.
P2DIR=0x00; //All are input.
P2REN|=0xFF; //All resistor.
P2OUT=0x00; //Pull all of them down.
P1SEL&=~0x80; //P1.7 is IO.
P1DIR&=~0x80; //P1.7 is input.
P1REN|=0x80;
P1OUT&=~0x80; //Output low.
}
//! Bitfields indicate pressed rows.
int key_row(){
int row;
P1DIR|=0x80; //P1.7 out.
P1OUT|=0x80; //P1.7 high.
P2DIR= 0x07; //P2.0, 2.1, 2.2 out.
P2OUT= 0x07; //P2.0, 2.1, 2.2 high.
//We'll return this result, but after cleaning up.
row=(P2IN>>3)&0x0F;
P1DIR&=~0x80; //All input.
P2DIR=0x00;
P1OUT&=~0x80; //All down.
P2OUT=0x00;
return row;
}
//! Bitfields indicate pressed columns.
int key_col(){
int col;
P1DIR&=~0x80; //Input
P1OUT&=~0x80; //Low
P2DIR= 0xF8; //P2.1.3, 2.4, 2.5, 2.6 out
P2OUT= 0xF8; //P2.1.3, 2.4, 2.5, 2.6 high
//We'll return this result, but after cleaning up.
col=((P2IN&0x7)<<1) | ((P2IN&0x80)>>7);
P1DIR&=~0x80; //All input.
P2DIR=0x00;
P1OUT&=~0x80; //All down.
P2OUT=0x00;
//Temporary workaround for what I think is hardware damage in my
//prototype.
if(col&~1)
return col&0xFE;
return col;
}
//! Returns the key code of the currently pressed button.
unsigned int key_scan(){
/* This is the key matrix. P2.7 isn't used, which would've been
nice to know earlier.
2.2 2.1 2.0 1.7
| | | |
2.3----+----+----+----+--10
| | | |
2.4----+----+----+----+--20
| | | |
2.5----+----+----+----+--40
| | | |
2.6----+----+----+----+--80
| | | |
08 04 02 01
*/
unsigned int scan=(key_row()<<4)|key_col();
if(scan&0xF0)
return scan;
else
return 0;
}
/* //! Map of presses to buttons. */
/* const int keymap[4][4]={ */
/* //Lowest row has highest bitmask, so it comes first. */
/* {0, '.', '=', '+'}, */
/* {1, 2, 3, '-'}, */
/* {4, 5, 6, '*'}, */
/* {7, 8, 9, '%'} */
/* }; */
//! Map of presses to buttons.
const unsigned int keymap[]={
/* Upper nybble is the scan code, lower nybble is the byte in ASCII.
*/
0x1837, 0x1438, 0x1239, 0x1100|'%',
0x2834, 0x2435, 0x2236, 0x2100|'*',
0x4831, 0x4432, 0x4233, 0x4100|'-',
0x8830, 0x8400|'.', 0x8200|'=', 0x8100|'+',
0x0000 //End on a null byte.
};
//! Returns a character of the current scan code.
unsigned int key_chr(code){
/* Row is the upper nybble, column is the lower nybble.*/
unsigned int i=0;
for(i=0;keymap[i];i++){
if(keymap[i]>>8==code)
return keymap[i]&0xFF;
}
//Return null for all unknown codes.
return 00;
}
//! Gets a character as ASCII.
char getchar(){
return key_chr(key_scan());
}

5
firmware/keypad.h Normal file
View File

@ -0,0 +1,5 @@
void key_init();
char getchar();

View File

@ -47,34 +47,27 @@ void lcd_init() {
lcd_zero(); lcd_zero();
for(i=0;i<13;i++) for(i=0;i<13;i++)
lcdbm[i]=0xFF; lcdbm[i]=0xFF;
//Seems unwired?
lcdm[2]^=0x40;
//Weird top-right thingys.
//lcdm[9]|=0x04;
//lcdm[0x0a]|=0x40;
//lcdm[0x0c]|=0x01;
//Beyond the range.
//lcdm[0x0c]|=0x10;
} }
//! Moved the LCD memory to the blink memory, then displays the backup. //! Moved the LCD memory to the blink memory, then displays the backup.
void lcd_predraw(){ void lcd_predraw(){
//Copy the LCD memory to the blink memory, then display blink memory. //Switch to the backup of the previous frame.
memcpy((char*) lcdbm,(char*) lcdm,13);
LCDBMEMCTL |= LCDDISP; // Enable blink memory LCDBMEMCTL |= LCDDISP; // Enable blink memory
} }
//! Reverts to the main display. //! Reverts to the main display.
void lcd_postdraw(){ void lcd_postdraw(){
//Now swap back the buffer. //Now swap back the buffer and copy it to blink memory for the next round.
LCDBMEMCTL &= ~LCDDISP; // Return to main display memory. LCDBMEMCTL &= ~LCDDISP; // Return to main display memory.
memcpy((char*) lcdbm,(char*) lcdm,13);
} }
//! LCD callback when the CPU wakes. //! LCD callback when the CPU wakes.
void lcd_wdt(){ void lcd_wdt(){
lcd_predraw(); lcd_predraw();
//lcd_zero();
draw_time(); draw_time();
lcd_postdraw(); lcd_postdraw();
} }

View File

@ -18,7 +18,7 @@
//This maps the segments of each digit. //This maps the segments of each digit.
// A, B, C, D, E, F, G, dp digit // A, B, C, D, E, F, G, dp digit
const int map[10][8]={ const int lcdmap[10][8]={
{0x0b04, 0x0b40, 0x0b20, 0x0b01, 0x0a10, 0x0a20, 0x0b02, 0x0b10}, //0 {0x0b04, 0x0b40, 0x0b20, 0x0b01, 0x0a10, 0x0a20, 0x0b02, 0x0b10}, //0
{0x0940, 0x0a04, 0x0a02, 0x0910, 0x0901, 0x0902, 0x0920, 0x0a01}, //1 {0x0940, 0x0a04, 0x0a02, 0x0910, 0x0901, 0x0902, 0x0920, 0x0a01}, //1
{0x0804, 0x0840, 0x0820, 0x0801, 0x0710, 0x0720, 0x0802, 0x0810}, //2 {0x0804, 0x0840, 0x0820, 0x0801, 0x0710, 0x0720, 0x0802, 0x0810}, //2
@ -29,7 +29,11 @@ const int map[10][8]={
{0x0040, 0x0104, 0x0102, 0x0010, 0x0001, 0x0002, 0x0020, 0x0201}, //7 {0x0040, 0x0104, 0x0102, 0x0010, 0x0001, 0x0002, 0x0020, 0x0201}, //7
}; };
enum mappos {A=1, B=2, C=4, D=8, E=0x10, F=0x20, G=0x40, DP=0x80}; //These are the fragments of the day of the week: 0x0904, 0x0a40, 0x0c01
//0x0c10 is beyond the screen.
//0x0240 seems not to be wired to any visible segment.
enum lcdmappos {A=1, B=2, C=4, D=8, E=0x10, F=0x20, G=0x40, DP=0x80};
const int numfont[]={ const int numfont[]={
A|B|C|D|E|F, //0 A|B|C|D|E|F, //0
B|C, //1 B|C, //1
@ -50,15 +54,13 @@ const int numfont[]={
}; };
#define DRAWPOINT(todraw) lcdm[todraw>>8]|=todraw&0xFF #define DRAWPOINT(todraw) lcdm[todraw>>8]|=todraw&0xFF
#define DRAWPOINTB(todraw) lcdbm[todraw>>8]|=todraw&0xFF
//! Draws one LCD digit. //! Draws one LCD digit.
void lcd_digit(int pos, int digit){ void lcd_digit(int pos, int digit){
int segments=numfont[digit]; int segments=numfont[digit];
int bit; int bit;
for(bit=0;bit<8;bit++){ for(bit=0;bit<8;bit++){
if(segments&(1<<bit)){ if(segments&(1<<bit)){
DRAWPOINT(map[pos][bit]); DRAWPOINT(lcdmap[pos][bit]);
//DRAWPOINTB(map[pos][bit]);
} }
} }
} }

View File

@ -8,6 +8,7 @@
#include "lcd.h" #include "lcd.h"
#include "rtc.h" #include "rtc.h"
#include "keypad.h"
//Initialize the XT1 crystal, and stabilize it. //Initialize the XT1 crystal, and stabilize it.
void xtal_init(){ void xtal_init(){
@ -34,6 +35,7 @@ int main(void) {
lcd_init(); lcd_init();
xtal_init(); xtal_init();
rtc_init(); rtc_init();
key_init();
// Setup and enable WDT 250ms, ACLK, interval timer // Setup and enable WDT 250ms, ACLK, interval timer
WDTCTL = WDT_ADLY_250; WDTCTL = WDT_ADLY_250;

View File

@ -64,9 +64,9 @@ void rtc_init(){
void __attribute__ ((interrupt(RTC_VECTOR))) RTC_ISR (void){ void __attribute__ ((interrupt(RTC_VECTOR))) RTC_ISR (void){
//Display the hex value if we ever drop here. //Display the hex value if we ever drop here.
lcd_hex(0xC1000000|RTCIV); //lcd_hex(0xC1000000|RTCIV);
//switch(__even_in_range(RTCIV,16)) //We don't really handly these, but might want to in the future.
switch(RTCIV&~1){ switch(RTCIV&~1){
case 0: break; // No interrupts case 0: break; // No interrupts
case 2: break; // RTCRDYIFG case 2: break; // RTCRDYIFG