Mercurial > ~darius > hgwebdir.cgi > avr
view testavr.c @ 8:f9a085a0ba93
Change the 1 wire routines to mostly C with assembly delay routines
for ease of portability.
author | darius |
---|---|
date | Mon, 12 Jul 2004 17:50:42 +0930 |
parents | a940431af6f5 |
children | 7ed10c59ba06 |
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 <ctype.h> #include "1wire.h" #define UART_BAUD_SELECT(baudRate,xtalCpu) ((xtalCpu)/((baudRate)*16l)-1) #define XTAL_CPU 4000000 /* 4Mhz */ #define UART_BAUD_RATE 19200 void uart_putsP(const char *addr); void uart_puts(const char *addr); int uart_putc(char c); int uart_getc(void); int beginswith_P(const char *s1, const char *s2); #if 0 uint8_t PROGMEM ledvals[] = {0x01, 0x03, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0, 0xc0, 0x80}; static uint8_t dir = 0; static volatile uint8_t leds = 0; static uint8_t ledpos = 0; 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]); } #endif 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]; char cmdbuf[40]; int i; cli(); #if 0 outp(0xff, DDRA); /* Timer Clock divisor - CK/1024 */ outp(BV(CS00) | BV(CS02), TCCR0); #endif 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); uart_putsP(PSTR("\n\r\n\r===============\n\r" "Inited!\n\r\n\r")); while (1) { uart_putsP(PSTR("> ")); i = 0; while (1) { cmdbuf[i] = tolower(uart_getc()); if (cmdbuf[i] == '\n' || cmdbuf[i] == '\r') break; /* Backspace */ if (cmdbuf[i] == 010) { if (i > 0) { uart_putsP(PSTR("\010\040\010")); i--; } continue; } /* Anything unprintable just ignore it */ if (!isprint(cmdbuf[i])) continue; uart_putc(cmdbuf[i]); i++; if (i == sizeof(cmdbuf)) { uart_putsP(PSTR("\n\rLine too long\n\r")); i = 0; continue; } } cmdbuf[i + 1] = '\0'; uart_putsP(PSTR("\n\r")); if (i == 0) continue; if (cmdbuf[0] == '?') { uart_putsP(PSTR("rs Reset and check for presence\n\r" "sr Search the bus for ROMs\n\r" "re Read a bit\n\r" "rb Read a byte\n\r" "wr bit Write a bit\n\r" "wb byte Write a byte (hex)\n\r" "wc cmd [ROMID] Write command\n\r" "te ROMID Read the temperature from a DS1820\n\r")); continue; } if (i < 2) goto badcmd; if (cmdbuf[0] == 'r' && cmdbuf[1] == 's') { uart_putsP(PSTR("Resetting... ")); if (OWTouchReset() == 1) uart_putsP(PSTR("No presense\n\r")); else uart_putsP(PSTR("Presense\n\r")); } else if (cmdbuf[0] == 'r' && cmdbuf[1] == 'e') { if (OWReadBit()) uart_putsP(PSTR("Read a 1\n\r")); else uart_putsP(PSTR("Read a 0\n\r")); } else if (cmdbuf[0] == 'r' && cmdbuf[1] == 'b') { sprintf_P(cmdbuf, PSTR("Read a 0x%02x\n\r"), OWReadByte()); uart_puts(cmdbuf); } else if (cmdbuf[0] == 'w' && cmdbuf[1] == 'r') { int arg; if (sscanf_P(cmdbuf + 3, PSTR("%d"), &arg) != 1) { uart_putsP(PSTR("Unable to parse wr command\n\r")); continue; } OWWriteBit(arg); sprintf_P(cmdbuf, PSTR("Wrote a %d\n\r"), arg); uart_puts(cmdbuf); } else if (cmdbuf[0] == 'w' && cmdbuf[1] == 'b') { int arg; if (sscanf_P(cmdbuf + 3, PSTR("%2x"), &arg) != 1) { uart_putsP(PSTR("Unable to parse wb command\n\r")); continue; } OWWriteByte(arg); sprintf_P(cmdbuf, PSTR("Wrote a 0x%02x\n\r"), arg); uart_puts(cmdbuf); } else if (cmdbuf[0] == 'w' && cmdbuf[1] == 'c') { int arg; switch (sscanf_P(cmdbuf + 3, PSTR("%x %x:%x:%x:%x:%x:%x:%x:%x:%x"), &arg, &ROM[0], &ROM[1], &ROM[2], &ROM[3], &ROM[4], &ROM[5], &ROM[6], &ROM[7])) { break; case 1: OWSendCmd(NULL, arg); sprintf_P(cmdbuf, PSTR("Sent 0x%02x to all ROMS\n\r"), arg); uart_puts(cmdbuf); break; case 9: OWSendCmd(ROM, arg); sprintf_P(cmdbuf, PSTR("Sent 0x%02x to ROM %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n\r"), arg, ROM[0], ROM[1], ROM[2], ROM[3], ROM[4], ROM[5], ROM[6], ROM[7]); uart_puts(cmdbuf); break; case 0: default: uart_putsP(PSTR("Unable to parse wc command\n\r")); break; } OWWriteByte(arg); sprintf_P(cmdbuf, PSTR("Wrote a 0x%02x\n\r"), arg); uart_puts(cmdbuf); } else if (cmdbuf[0] == 't' && cmdbuf[1] == 'e') { uint8_t crc; uint16_t temp; uint8_t buf[9]; if (sscanf_P(cmdbuf + 3, PSTR("%x:%x:%x:%x:%x:%x:%x:%x:%x"), &ROM[0], &ROM[1], &ROM[2], &ROM[3], &ROM[4], &ROM[5], &ROM[6], &ROM[7]) != 8) { uart_putsP(PSTR("Unable to parse ROM ID\n\r")); continue; } if (ROM[0] != OW_FAMILY_TEMP) { uart_putsP(PSTR("ROM specified isn't a temperature sensor\n\r")); continue; } 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(cmdbuf, PSTR("Temp comversion took %d cycles\n\r"), i); uart_puts(cmdbuf); #endif OWSendCmd(ROM, OW_RD_SCR_CMD); crc = 0; for (i = 0; i < 9; i++) { buf[i] = OWReadByte(); if (i < 8) OWCRC(buf[i], &crc); } temp = buf[0]; temp |= (uint16_t)buf[1] << 8; temp <<= 3; if (crc != buf[8]) { sprintf_P(cmdbuf, PSTR("CRC mismatch got %d vs calcd %d\n\r"), buf[8], crc); uart_puts(cmdbuf); continue; } sprintf_P(cmdbuf, PSTR("temperature %d.%01d\n\r"), temp >> 4, (temp << 12) / 6553); uart_puts(cmdbuf); } else if (cmdbuf[0] == 's' && cmdbuf[1] == 'r') { memset(ROM, 0, 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 { sprintf_P(cmdbuf, PSTR("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n\r"), ROM[0], ROM[1], ROM[2], ROM[3], ROM[4], ROM[5], ROM[6], ROM[7]); uart_puts(cmdbuf); } while (OWNext(ROM, 1, 0)); #if 0 } else if (cmdbuf[0] == 'l' && cmdbuf[1] == 'e' && cmdbuf[2] == 'd') { 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")); } #endif } else { badcmd: uart_putsP(PSTR("Unknown command, ? for a list\n\r")); } } 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++); } int uart_getc(void) { while (!(inp(USR) & 0x80)) ; return (inp(UDR)); }