alphawatch / alphawatch.c

/**
 * \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));
*/
	}
}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.