From 56d9bdd39ed36c36e9a61411b86c76d5228b2133 Mon Sep 17 00:00:00 2001 From: sicarius Date: Sun, 11 Feb 2007 18:32:03 +0000 Subject: Added lot's of code-files used during work --- source/ct-Bot/mcu/uart.c | 206 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 source/ct-Bot/mcu/uart.c (limited to 'source/ct-Bot/mcu/uart.c') diff --git a/source/ct-Bot/mcu/uart.c b/source/ct-Bot/mcu/uart.c new file mode 100644 index 0000000..c9c36c6 --- /dev/null +++ b/source/ct-Bot/mcu/uart.c @@ -0,0 +1,206 @@ +/* + * c't-Bot + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your + * option) any later version. + * This program is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307, USA. + * + */ + +/*! @file uart.c + * @brief Routinen zur seriellen Kommunikation + * @author Benjamin Benz (bbe@heise.de) + * @date 26.12.05 +*/ + +#ifdef MCU + +#include "ct-Bot.h" + +#include +#include +#ifndef NEW_AVR_LIB + #include +#endif +#include "ct-Bot.h" +#include "uart.h" +#include "command.h" +#include "log.h" + +#ifdef UART_AVAILABLE + +#define BAUDRATE 57600 + +#define UART_RX_BUFFER_SIZE 16 /*!< Größe des UART-Puffers */ + +#define UART_RX_BUFFER_MASK ( UART_RX_BUFFER_SIZE - 1 ) +#if ( UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK ) + #error RX buffer size is not a power of 2 +#endif + +//#define UART_TIMEOUT 20000 /*!< Timeout. Wartet UART_TIMEOUT CPU-Takte */ + +static uint8 UART_RxBuf[UART_RX_BUFFER_SIZE]; /*!< UART-Puffer */ +static volatile uint8 UART_RxHead; /*!< Zeiger für UART-Puffer */ +static volatile uint8 UART_RxTail; /*!< Zeiger für UART-Puffer */ + +//char uart_timeout; /*!< 0, wenn uart_read/uart_send erfolgreich 1, wenn timeout erreicht */ + +/*! + * Initialisiere UART + */ +void uart_init(void){ + #ifdef __AVR_ATmega644__ + /* Senden und Empfangen ermöglichen + RX Interrupt an */ + UCSR0B= (1<> 8); + #else + UBRRL = (uint8) (( ((uint32)F_CPU) / 16 / ((uint32)BAUDRATE) - 1) & 0xFF); + UBRRH = (uint8) (( ((uint32)F_CPU) / 16 / ((uint32)BAUDRATE) - 1) >> 8); + #endif + + /* Puffer leeren */ + UART_RxTail = 0; + UART_RxHead = 0; +} + +/*! + * Interrupt Handler fuer den Datenempfang per UART + */ +#ifdef __AVR_ATmega644__ + SIGNAL (USART0_RX_vect){ +#else + SIGNAL (SIG_UART_RECV){ +#endif + + /* Pufferindex berechnen */ + UART_RxHead++; /* erhoehen */ + UART_RxHead %= UART_RX_BUFFER_MASK; /* Und bei Bedarf umklappen, da Ringpuffer */ + + if (UART_RxHead == UART_RxTail){ + /* TODO Fehler behandeln !! + * ERROR! Receive buffer overflow */ + } + #ifdef __AVR_ATmega644__ + UART_RxBuf[UART_RxHead] = UDR0; /* Daten lesen und sichern*/ + #else + UART_RxBuf[UART_RxHead] = UDR; /* Daten lesen und sichern*/ + #endif +} + +/*! + * Prüft, ob daten verfügbar + * @return Anzahl der verfuegbaren Bytes + */ +uint8 uart_data_available(void){ + if (UART_RxHead == UART_RxTail) /* Puffer leer */ + return 0; + else if (UART_RxHead > UART_RxTail) /* Schreibzeiger vor Lesezeiger */ + return UART_RxHead - UART_RxTail; + else /* Schreibzeiger ist schon umgelaufen */ + return UART_RxHead - UART_RxTail + UART_RX_BUFFER_SIZE; +} + + +/*! + * Überträgt ein Zeichen per UART + * Achtung ist noch blockierend!!!! + * TODO: umstellen auf nicht blockierend und mehr als ein Zeichen + * @param data Das Zeichen + */ +void uart_send_byte(uint8 data){ // Achtung ist noch blockierend!!!! + #ifdef __AVR_ATmega644__ + while ((UCSR0A & _BV(UDRE0)) ==0){asm volatile("nop"); } // warten bis UART sendebereit + UDR0= data; + #else + while ((UCSRA & _BV(UDRE)) ==0){asm volatile("nop"); } // warten bis UART sendebereit + UDR= data; + #endif +} + +/*! + * Sende Kommando per UART im Little Endian + * @param cmd Zeiger auf das Kommando + * @return Anzahl der gesendete Bytes + */ +//#define uart_send_cmd(cmd) uart_write(cmd,sizeof(command_t)); + +/* +int uart_send_cmd(command_t *cmd){ + int i; + char * ptr = (char*) cmd; + for (i=0; i length) + count=length; + + for (i=0; i