Mercurial > ~darius > hgwebdir.cgi > avr
diff cons.c @ 41:5898fba6593c
Add temperature control.
- Split out console stuff to cons.[ch]. Set up stdio so we can use printf etc.
- Use \r\n as the line terminator consistently.
- Add OWGetTemp to get temperatures from a device.
- Load/save settings in EEPROM, defaults loaded from flash.
Nearly feature complete except you can't edit ROM IDs without a programming tool :)
(To be fixed)
Needs more testing.
author | darius@inchoate.localdomain |
---|---|
date | Sun, 06 Jul 2008 22:19:53 +0930 |
parents | |
children | 11c453539d31 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cons.c Sun Jul 06 22:19:53 2008 +0930 @@ -0,0 +1,180 @@ +/* + * Console code for AVR board + * + * Copyright (c) 2008 + * 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 <ctype.h> +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <avr/interrupt.h> +#include <avr/pgmspace.h> +#include "cons.h" + +#define UART_BAUD_SELECT(baudRate,xtalCpu) ((xtalCpu)/((baudRate)*16l)-1) + +/* Receive buffer storage */ +consbuf_t cmd; + +/* + * Stub to use with fdevopen + * + * We ignore f and always succeed + */ +static int _putc(char c, FILE *f) { + cons_putc(c); + return(0); +} + +/* + * Stub to use with fdevopen + * + * We ignore f and always succeed + */ +static int _getc(FILE *f) { + return(cons_getc()); +} + +void +cons_init(void) { + UBRRH = UART_BAUD_SELECT(38400, F_CPU) >> 8; + UBRRL = (uint8_t)UART_BAUD_SELECT(38400, F_CPU); + + /* Enable receiver and transmitter. Turn on rx interrupts */ + UCSRA = 0; + UCSRB = _BV(RXEN) | _BV(TXEN) | _BV(RXCIE); + UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); + + fdevopen(_putc, NULL); /* Open stdout */ + fdevopen(NULL, _getc); /* Open stdin */ +} + +int +cons_putc(char c) { + loop_until_bit_is_set(UCSRA, UDRE); + UDR = c; + + return(0); +} + +void +cons_putsP(const char *addr) { + char c; + + while ((c = pgm_read_byte_near(addr++))) + cons_putc(c); +} + +void +cons_puts(const char *addr) { + while (*addr) + cons_putc(*addr++); +} + +void +cons_puts_dec(uint8_t a, uint8_t l) { + char s[4]; + + if (l && a < 10) + cons_putsP(PSTR("0")); + cons_puts(utoa(a, s, 10)); +} + +void +cons_puts_hex(uint8_t a) { + char s[3]; + + if (a < 0x10) + cons_putc('0'); + + cons_puts(utoa(a, s, 16)); +} + +char +cons_getc(void) { + while (!(UCSRA & _BV(RXC))) + ; + + return (UDR); +} + +/* Rx complete */ +ISR(USART_RXC_vect) { + volatile char pit; + char c; + + while (UCSRA & _BV(RXC)) { + /* 255 means we're waiting for main to process the command, + just throw stuff away + */ + if (cmd.state == 255) { + pit = UDR; + continue; + } + c = UDR; + + /* End of line? */ + if (c == '\n' || c == '\r') { + cmd.buf[cmd.state + 1] = '\0'; + cons_putsP(PSTR("\r\n")); + cmd.len = cmd.state; + cmd.state = 255; + continue; + } + + /* Backspace/delete */ + if (c == 0x08 || c == 0x7f) { + if (cmd.state > 0) { + cmd.state--; + cons_putsP(PSTR("\010\040\010")); + } + continue; + } + + /* Anything unprintable just ignore it */ + if (!isprint(c)) + continue; + + cmd.buf[cmd.state] = tolower(c); + + /* Echo back to the user */ + cons_putc(cmd.buf[cmd.state]); + + cmd.state++; + /* Over flow? */ + if (cmd.state == ((sizeof(cmd.buf) / sizeof(cmd.buf[0])) - 1)) { + cons_putsP(PSTR("\r\nLine too long")); + cmd.state = 0; + continue; + } + } +} + +/* Tx complete */ +ISR(USART_TXC_vect) { + +} +