Source

alphawatch / alphawatch.c

Full commit
Trammell Hudson 521c6b2 
Trammell Hudson 8f95de1 


Trammell Hudson 521c6b2 
















































Trammell Hudson 94a2e4c 




Trammell Hudson 521c6b2 
Trammell Hudson 94a2e4c 







Trammell Hudson 521c6b2 
Trammell Hudson 94a2e4c 




Trammell Hudson 521c6b2 
Trammell Hudson f3213a8 






























Trammell Hudson 521c6b2 


Trammell Hudson 8f95de1 



Trammell Hudson 521c6b2 
Trammell Hudson 8f95de1 















Trammell Hudson 94a2e4c 
Trammell Hudson 8f95de1 
Trammell Hudson 94a2e4c 
Trammell Hudson 521c6b2 

Trammell Hudson f3213a8 


Trammell Hudson 521c6b2 



















Trammell Hudson 8f95de1 














Trammell Hudson 94a2e4c 












Trammell Hudson 8f95de1 

Trammell Hudson 94a2e4c 
Trammell Hudson 8f95de1 

















Trammell Hudson 521c6b2 


































Trammell Hudson 8f95de1 

Trammell Hudson f3213a8 



Trammell Hudson 521c6b2 




Trammell Hudson 8f95de1 

Trammell Hudson 521c6b2 

Trammell Hudson 8f95de1 
Trammell Hudson 521c6b2 
Trammell Hudson 8f95de1 
Trammell Hudson f3213a8 




Trammell Hudson 8f95de1 
Trammell Hudson f3213a8 












Trammell Hudson 521c6b2 

Trammell Hudson f3213a8 
Trammell Hudson 521c6b2 
Trammell Hudson 8f95de1 







Trammell Hudson f3213a8 
Trammell Hudson 521c6b2 
/**
 * \file Alpha numeric watch
 *
 * Based on the HDSP-2110 display.
 *
 */

#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include <stdint.h>
#include <string.h>
#include <util/delay.h>
#include "usb_serial.h"
#include "bits.h"


#define LED			0xD6


void send_str(const char *s);
uint8_t recv_str(char *buf, uint8_t size);
void parse_and_execute_command(const char *buf, uint8_t num);

static uint8_t
hexdigit(
	uint8_t x
)
{
	x &= 0xF;
	if (x < 0xA)
		return x + '0' - 0x0;
	else
		return x + 'A' - 0xA;
}



// Send a string to the USB serial port.  The string must be in
// flash memory, using PSTR
//
void send_str(const char *s)
{
	char c;
	while (1) {
		c = pgm_read_byte(s++);
		if (!c) break;
		usb_serial_putchar(c);
	}
}


#define ADDR_0	0xF4
#define ADDR_1	0xF5
#define ADDR_2	0xF6
#define ADDR_3	0xF7
#define ADDR_4	0xD7

#define DATA_0	0xC6
#define DATA_1	0xD3
#define DATA_2	0xD0
#define DATA_3	0xB7
#define DATA_4	0xB3
#define DATA_5	0xB2
#define DATA_6	0xB1
#define DATA_7	0xB0

#define FLASH	0xF1
#define RESET	0xF0
#define WRCE	0xD5
#define RD	0xC7
#define CLKSEL	0xD6

static const char numbers[][16] = {
	"one",
	"two",
	"three",
	"four",
	"five",
	"six",
	"seven",
	"eight",
	"nine",
	"ten",
	"eleven",
	"twelve",
	"thirty",
	"fourteen",
	"fifteen",
	"sixteen",
	"seventeen",
	"eightteen",
	"nineteen",
	"twenty",
	"twenty one",
	"twenty two",
	"twenty three",
	"twenty four",
	"twenty five",
	"twenty six",
	"twenty seven",
	"twenty eight",
	"twenty nine",
};


static void
lcd_write(
	uint8_t addr,
	uint8_t data
)
{
	out(ADDR_0, addr & 1); addr >>= 1;
	out(ADDR_1, addr & 1); addr >>= 1;
	out(ADDR_2, addr & 1); addr >>= 1;
	out(ADDR_3, addr & 1); addr >>= 1;
	out(ADDR_4, addr & 1); addr >>= 1;

	out(DATA_0, data & 1); data >>= 1;
	out(DATA_1, data & 1); data >>= 1;
	out(DATA_2, data & 1); data >>= 1;
	out(DATA_3, data & 1); data >>= 1;
	out(DATA_4, data & 1); data >>= 1;
	out(DATA_5, data & 1); data >>= 1;
	out(DATA_6, data & 1); data >>= 1;
	out(DATA_7, data & 1); data >>= 1;

	//_delay_us(100);
	out(WRCE, 0);
	_delay_us(10);
	out(WRCE, 1);
}


static char output[64];

int
main(void)
{
	// set for 16 MHz clock
#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
	CPU_PRESCALE(0);

	// Disable the ADC
	ADMUX = 0;

	// initialize the USB, and then wait for the host
	// to set configuration.  If the Teensy is powered
	// without a PC connected to the USB port, this 
	// will wait forever.
	usb_init();

	// LED is an output; will be pulled down once connected
	ddr(LED, 1);
	out(LED, 1);

	ddr(DATA_0, 1);
	ddr(DATA_1, 1);
	ddr(DATA_2, 1);
	ddr(DATA_3, 1);
	ddr(DATA_4, 1);
	ddr(DATA_5, 1);
	ddr(DATA_6, 1);
	ddr(DATA_7, 1);

	ddr(ADDR_0, 1);
	ddr(ADDR_1, 1);
	ddr(ADDR_2, 1);
	ddr(ADDR_3, 1);
	ddr(ADDR_4, 1);

	// !FLASH should be high to select normal memory
	out(FLASH, 1);
	ddr(FLASH, 1);

	// CLS should be high to select internal clocks
	out(CLKSEL, 1);
	ddr(CLKSEL, 1);

	// WRCE ties together !WR and !CE
	out(WRCE, 1);
	ddr(WRCE, 1);

	out(RESET, 1);
	ddr(RESET, 1);

	// Reset the display
	_delay_ms(100);
	out(RESET, 0);
	_delay_ms(10);
	out(RESET, 1);

#define CHAR_RAM 0x18

	// We should be good to go
	lcd_write(0x20, 0x00); // normal operation

	lcd_write(CHAR_RAM | 0, 'A');
	lcd_write(CHAR_RAM | 1, 'B');
	lcd_write(CHAR_RAM | 2, 'C');
	lcd_write(CHAR_RAM | 3, 'D');
	lcd_write(CHAR_RAM | 4, 'E');
	lcd_write(CHAR_RAM | 5, 'F');
	lcd_write(CHAR_RAM | 6, 'G');
	lcd_write(CHAR_RAM | 7, 'H');

        // Timer 0 is used for a 64 Hz control loop timer.
        // Clk/1024 == 15.625 KHz, count up to 244
        // CTC mode resets the counter when it hits the top
        TCCR0A = 0
                | 1 << WGM01 // select CTC
                | 0 << WGM00
                ;

        TCCR0B = 0
                | 0 << WGM02
                | 1 << CS02 // select Clk/1024
                | 0 << CS01
                | 0 << CS00
                ;

        OCR0A = 244;
        sbi(TIFR0, OCF0A); // reset the overflow bit


	while (!usb_configured())
		;

	_delay_ms(1000);

	// wait for the user to run their terminal emulator program
	// which sets DTR to indicate it is ready to receive.
	while (!(usb_serial_get_control() & USB_SERIAL_DTR))
		;

	// discard anything that was received prior.  Sometimes the
	// operating system or other software will send a modem
	// "AT command", which can still be buffered.
	usb_serial_flush_input();

	send_str(PSTR("alphawatch\r\n"));
	uint32_t ticks = 0;

	strcpy(output, "      the quick brown fox jumps over the lazy dog      ");
	uint16_t offset = 0;

	while (1)
	{
		int c = usb_serial_getchar();
		if (c != -1)
		{
			lcd_write(CHAR_RAM | 5, c);
			usb_serial_putchar(c);
		}

		if (bit_is_set(TIFR0, OCF0A))
		{
			sbi(TIFR0, OCF0A); // reset the bit
			static uint8_t rate = 0;
			if ((rate++) < 40)
				continue;
			rate = 0;

			// do periodic stuff;
			for (int i = 0 ; i < 8 ; i++)
			{
				char c = output[offset + i];
				if (c == '\0')
				{
					offset = 0;
					c = ' ';
				}
			
				lcd_write(CHAR_RAM + i, c);
			}

			offset++;
		}

/*
		ticks++;
		lcd_write(CHAR_RAM | 7, hexdigit(ticks >> 0x00));
		lcd_write(CHAR_RAM | 6, hexdigit(ticks >> 0x04));
		lcd_write(CHAR_RAM | 5, hexdigit(ticks >> 0x08));
		lcd_write(CHAR_RAM | 4, hexdigit(ticks >> 0x0C));
		lcd_write(CHAR_RAM | 3, hexdigit(ticks >> 0x10));
		lcd_write(CHAR_RAM | 2, hexdigit(ticks >> 0x14));
		lcd_write(CHAR_RAM | 1, hexdigit(ticks >> 0x18));
		lcd_write(CHAR_RAM | 0, hexdigit(ticks >> 0x1C));
*/
	}
}