view testavr.c @ 0:ffeab3c04e83

Initial revision
author darius
date Sun, 11 Jul 2004 00:45:50 +0930
parents
children 81e2f85e02ce
line wrap: on
line source

/*
 * 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));
}