Mercurial > ~darius > hgwebdir.cgi > avr-lib
view cons.c @ 4:095216e8453d
Hide register name abstraction in a separate file.
author | darius@Inchoate |
---|---|
date | Thu, 12 Mar 2009 16:30:47 +1030 |
parents | 15d89caaf516 |
children | b46f0c742316 |
line wrap: on
line source
/* * Console code for AVR board * * Copyright (c) 2008-2009 * 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" #include "cons-reg.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) { _SETBAUD(38400); /* Enable receiver and transmitter. Turn on rx interrupts */ _INITREG(); 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(_RXVECT) { char c; while (_UCSRA & _BV(_RXC)) { c = _UDR; /* 255 means we're waiting for main to process the command, * just throw stuff away */ if (cmd.state == 255) continue; /* End of line? */ if (c == '\n' || c == '\r') { cmd.buf[cmd.state] = '\0'; printf_P(PSTR("\r\n")); cmd.len = cmd.state; cmd.state = 255; continue; } /* Backspace/delete */ if (c == 0x08 || c == 0x7f) { if (cmd.state > 0) { cmd.state--; printf_P(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)) { printf_P(PSTR("\r\nLine too long")); cmd.state = 0; continue; } } } /* Tx complete */ ISR(_TXVECT) { }