Mercurial > ~darius > hgwebdir.cgi > avr
diff testavr.c @ 0:ffeab3c04e83
Initial revision
author | darius |
---|---|
date | Sun, 11 Jul 2004 00:45:50 +0930 |
parents | |
children | 81e2f85e02ce |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testavr.c Sun Jul 11 00:45:50 2004 +0930 @@ -0,0 +1,274 @@ +/* + * Copyright (c) 2004 + * Daniel O'Connor <darius@dons.net.au>. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <stdio.h> +#include <avr/io.h> +#include <avr/interrupt.h> +#include <avr/signal.h> +#include <avr/pgmspace.h> +#include <string.h> + +#include "1wire.h" + +#define UART_BAUD_SELECT(baudRate,xtalCpu) ((xtalCpu)/((baudRate)*16l)-1) +#define XTAL_CPU 4000000 /* 4Mhz */ +#define UART_BAUD_RATE 9600 /* 9600 baud */ + +static uint8_t dir = 0; +static volatile uint8_t leds = 0; +static uint8_t ledpos = 0; + +void uart_putsP(const char *addr); +void uart_puts(const char *addr); +int uart_putc(char c); +uint8_t uart_getc(void); + +uint8_t PROGMEM ledvals[] = {0x01, 0x03, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0, 0xc0, 0x80}; + +INTERRUPT(SIG_OVERFLOW0) { + if (!leds) + return; + + /* Going up */ + if (dir == 0) { + if (ledpos == 9) { + dir = 1; + TCNT0 = 0; + goto doleds; + } + + ledpos++; + } else { + if (ledpos == 0) { + dir = 0; + TCNT0 = 0; + goto doleds; + } + + ledpos--; + } + + doleds: + TCNT0 = 0; + + PORTA = pgm_read_byte(&ledvals[ledpos]); +} + +void +usleep(uint16_t usec) { + /* 4Mhz = 250ns per clock cycle */ + usec /= 2; + if (usec < 1) + return; + + while (usec--) + asm volatile ( + "" + ::); +} + +int +main(void) { + uint8_t ROM[8], count; + char foo[40]; + int i; + + cli(); + outp(0xff, DDRA); + outp(0xfe, DDRC); + outp(0x00, PORTC); + + /* Init UART */ + outp(UART_BAUD_SELECT(UART_BAUD_RATE,XTAL_CPU), UBRR); + + /* Enable receiver and transmitter. Turn on transmit interrupts */ + outp(BV(RXEN) | BV(TXEN), UCR); + + /* Timer Clock divisor - CK/1024 */ + outp(BV(CS00) | BV(CS02), TCCR0); + + uart_putsP(PSTR("\n\r\n\r===============\n\r")); + uart_putsP(PSTR("Inited!\n\r\n\r")); + uart_putsP(PSTR("Test message 1\n\r")); + + count = 0; + while (1) { + char cmd; + + cmd = uart_getc(); + switch (cmd) { + case 'r': + uart_putsP(PSTR("Resetting... ")); + + if (OWTouchReset() == 1) + uart_putsP(PSTR("No presense\n\r")); + else + uart_putsP(PSTR("Presense\n\r")); + break; + + case 'R': + if (OWReadBit()) + uart_putsP(PSTR("Read a 1\n\r")); + else + uart_putsP(PSTR("Read a 0\n\r")); + break; + + case 'w': + OWWriteBit(0); + uart_putsP(PSTR("Wote a 0\n\r")); + break; + + case 'W': + OWWriteBit(1); + uart_putsP(PSTR("Wote a 1\n\r")); + break; + + case 'd': + bzero(ROM, 8); + if (OWTouchReset()) { + uart_putsP(PSTR("No devices on bus\n\r")); + break; + } + if (OWFirst(ROM, 1, 0) == 0) { + uart_putsP(PSTR("No module found\n\r")); + break; + } + do { + uart_putsP(PSTR("Found a module ")); + sprintf_P(foo, PSTR("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x"), + ROM[0], + ROM[1], + ROM[2], + ROM[3], + ROM[4], + ROM[5], + ROM[6], + ROM[7]); + uart_puts(foo); + if (ROM[0] == OW_FAMILY_TEMP) { + uint8_t tempbuf[9]; + uint8_t crc; + uint16_t temp; + + uart_putsP(PSTR(" is a temp sensor\n\r")); + OWSendCmd(ROM, OW_CONVERTT_CMD); +#if OW_DEBUG + uart_putsP(PSTR("Command sent, waiting\n\r")); +#endif + i = 0; + while (OWReadBit() == 0) { + i++; + } +#if OW_DEBUG + sprintf_P(foo, PSTR("Temp comversion took %d cycles\n\r"), i); + uart_puts(foo); +#endif + OWSendCmd(ROM, OW_RD_SCR_CMD); + crc = 0; + for (i = 0; i < 9; i++) { + tempbuf[i] = OWReadByte(); + if (i < 8) + OWCRC(tempbuf[i], &crc); + } + + temp = tempbuf[0]; + temp |= (uint16_t)tempbuf[1] << 8; + temp <<= 3; + + if (crc != tempbuf[9]) { + sprintf_P(foo, PSTR("CRC mismatch got %d vs calcd %d\n\r"), tempbuf[9], crc); + uart_puts(foo); + } + + sprintf_P(foo, PSTR("temperature %d.%01d\n\r"), + temp >> 4, (temp << 12) / 6553); + uart_puts(foo); + } + + if (ROM[0] == OW_FAMILY_ROM) { + uart_putsP(PSTR(" is a ROM\n\r")); + } + } while (OWNext(ROM, 1, 0)); + break; + + case 'l': + if (leds == 0) { + leds = 1; + ledpos = 0; + outp(0, TCNT0); + sbi(TIMSK, TOIE0); + sei(); + uart_putsP(PSTR("Starting\n\r")); + } else { + leds = 0; + ledpos = 0; + PORTA = 0x00; + cbi(TIMSK, TOIE0); + cli(); + uart_putsP(PSTR("Stopping\n\r")); + } + + break; + + default: + uart_putsP(PSTR("Unknown command\n\r")); + break; + } + + } + + return(0); +} + +int +uart_putc(char c) { + loop_until_bit_is_set(USR, UDRE); + outp(c, UDR); + + return(0); +} + +void +uart_putsP(const char *addr) { + char c; + + while ((c = PRG_RDB((unsigned short)addr++))) + uart_putc(c); +} + +void +uart_puts(const char *addr) { + while (*addr) + uart_putc(*addr++); +} + +uint8_t +uart_getc(void) { + while (!(inp(USR) & 0x80)) + ; + + return (inp(UDR)); +}