LoIO.c

Go to the documentation of this file.
00001 /**
00002    \file  Robots/LoBot/irccm/LoIO.c
00003    \brief Serial I/O API for Robolocust control program running on iRobot
00004    Create Command Module.
00005 
00006    This file defines the functions for serial port I/O needed by the
00007    Robolocust iRobot Create Command Module control program.
00008 */
00009 
00010 /*
00011  ************************************************************************
00012  * The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005   *
00013  * by the University of Southern California (USC) and the iLab at USC.  *
00014  * See http://iLab.usc.edu for information about this project.          *
00015  *                                                                      *
00016  * Major portions of the iLab Neuromorphic Vision Toolkit are protected *
00017  * under the U.S. patent ``Computation of Intrinsic Perceptual Saliency *
00018  * in Visual Environments, and Applications'' by Christof Koch and      *
00019  * Laurent Itti, California Institute of Technology, 2001 (patent       *
00020  * pending; application number 09/912,225 filed July 23, 2001; see      *
00021  * http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     *
00022  ************************************************************************
00023  * This file is part of the iLab Neuromorphic Vision C++ Toolkit.       *
00024  *                                                                      *
00025  * The iLab Neuromorphic Vision C++ Toolkit is free software; you can   *
00026  * redistribute it and/or modify it under the terms of the GNU General  *
00027  * Public License as published by the Free Software Foundation; either  *
00028  * version 2 of the License, or (at your option) any later version.     *
00029  *                                                                      *
00030  * The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  *
00031  * that it will be useful, but WITHOUT ANY WARRANTY; without even the   *
00032  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      *
00033  * PURPOSE.  See the GNU General Public License for more details.       *
00034  *                                                                      *
00035  * You should have received a copy of the GNU General Public License    *
00036  * along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   *
00037  * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   *
00038  * Boston, MA 02111-1307 USA.                                           *
00039  ************************************************************************
00040 */
00041 
00042 /*
00043    Primary maintainer for this file: mviswana usc edu
00044    $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Robots/LoBot/irccm/LoIO.c $
00045    $Id: LoIO.c 13744 2010-08-02 02:55:15Z mviswana $
00046 */
00047 
00048 /*------------------------------ HEADERS ------------------------------*/
00049 
00050 // lobot headers
00051 #include "LoIO.h"
00052 #include "LoTimer.h"
00053 #include "LoOpenInterface.h"
00054 
00055 // AVR headers
00056 #include <avr/io.h>
00057 #include <avr/interrupt.h>
00058 
00059 /*------------------------------ GLOBALS ------------------------------*/
00060 
00061 // When I/O operations fail, we set a flag to let clients know
00062 static char g_io_error ;
00063 
00064 /*-------------------------- INITIALIZATION ---------------------------*/
00065 
00066 // Set up the serial port
00067 void lo_init_comm()
00068 {
00069    UBRR0  = LOBOT_OI_UBRR_57600 ;
00070    UCSR0B = (_BV(TXEN0)  | _BV(RXEN0))  ; // enable transmit & receive
00071    UCSR0C = (_BV(UCSZ00) | _BV(UCSZ01)) ; // 8-bit data
00072 }
00073 
00074 // Reset communication speed on both Create robot and Command Module
00075 void lo_reset_baud(int baud_rate)
00076 {
00077    if (baud_rate < LOBOT_OI_BAUD_300 || baud_rate > LOBOT_OI_BAUD_115200)
00078       return ;
00079 
00080    // Send baud command and new baud rate
00081    lo_tx(LOBOT_OI_CMD_BAUD) ;
00082    UCSR0A |= _BV(TXC0) ;
00083    lo_tx(baud_rate) ;
00084 
00085    // Busy wait until transmit is complete
00086    while (! (UCSR0A & _BV(TXC0)))
00087       ;
00088 
00089    // Inhibit interrupts while we update the baud rate register
00090    cli() ;
00091 
00092    // Update baud rate register
00093    switch (baud_rate)
00094    {
00095       case LOBOT_OI_BAUD_115200:
00096          UBRR0 = LOBOT_OI_UBRR_115200 ;
00097          break ;
00098       case LOBOT_OI_BAUD_57600:
00099          UBRR0 = LOBOT_OI_UBRR_57600 ;
00100          break ;
00101       case LOBOT_OI_BAUD_38400:
00102          UBRR0 = LOBOT_OI_UBRR_38400 ;
00103          break ;
00104       case LOBOT_OI_BAUD_28800:
00105          UBRR0 = LOBOT_OI_UBRR_28800 ;
00106          break ;
00107       case LOBOT_OI_BAUD_19200:
00108          UBRR0 = LOBOT_OI_UBRR_19200 ;
00109          break ;
00110       case LOBOT_OI_BAUD_14400:
00111          UBRR0 = LOBOT_OI_UBRR_14400 ;
00112          break ;
00113       case LOBOT_OI_BAUD_9600:
00114          UBRR0 = LOBOT_OI_UBRR_9600 ;
00115          break ;
00116       case LOBOT_OI_BAUD_4800:
00117          UBRR0 = LOBOT_OI_UBRR_4800 ;
00118          break ;
00119       case LOBOT_OI_BAUD_2400:
00120          UBRR0 = LOBOT_OI_UBRR_2400 ;
00121          break ;
00122       case LOBOT_OI_BAUD_1200:
00123          UBRR0 = LOBOT_OI_UBRR_1200 ;
00124          break ;
00125       case LOBOT_OI_BAUD_600:
00126          UBRR0 = LOBOT_OI_UBRR_600 ;
00127          break ;
00128       case LOBOT_OI_BAUD_300:
00129          UBRR0 = LOBOT_OI_UBRR_300 ;
00130          break ;
00131       default:
00132          UBRR0 = LOBOT_OI_UBRR_57600 ;
00133          break ;
00134    }
00135 
00136    // Okay to receive interrupts again
00137    sei();
00138 
00139    // Small delay to let things stabilize
00140    lo_wait(100) ;
00141 }
00142 
00143 // Clear TX and RX buffers
00144 void lo_clear_buffers(void)
00145 {
00146    // Wait for TX buffer to empty
00147    while (! (UCSR0A & _BV(UDRE0)))
00148       ;
00149 
00150    // Empty the RX buffer
00151    char c ;
00152    while (UCSR0A & 0x80)
00153       c = UDR0 ;
00154 }
00155 
00156 /*------------------------- SEND/RECEIVE API --------------------------*/
00157 
00158 // Transmit a byte over the serial port
00159 void lo_tx(char byte)
00160 {
00161    // Clear the communications error flag
00162    g_io_error = LOBOT_IO_OK ;
00163 
00164    // Busy wait for transmit buffer to become empty
00165    while (! (UCSR0A & _BV(UDRE0)))
00166       ;
00167 
00168    // Transmit buffer now empty ==> place byte in USART data register to send
00169    UDR0 = byte ;
00170 }
00171 
00172 // Receive the specified number of bytes over the serial port, waiting a
00173 // maximum number of milliseconds before giving up. If the timeout is
00174 // zero, wait forever for the data to come in.
00175 //
00176 // The function returns the number of bytes successfully read.
00177 //
00178 // Clients should setup a large enough buffer to accommodate the amount
00179 // of data they require and check the return value before using the data
00180 // in the buffer. If the number of bytes read is less than the number
00181 // requested, clients can query the I/O error to see what went wrong.
00182 unsigned char lo_rx(char* buf, unsigned char n, unsigned int timeout)
00183 {
00184    // Clear the communications error flag
00185    g_io_error = LOBOT_IO_OK ;
00186 
00187    unsigned char i = 0 ;
00188    if (timeout == 0) // wait forever
00189    {
00190       for (; i < n; ++i) {
00191          while (! (UCSR0A & 0x80)) // serial data not yet available
00192             ;
00193          buf[i] = UDR0 ;
00194       }
00195    }
00196    else // wait for specified amount of time and then give up
00197    {
00198       lo_setup_timer(timeout) ;
00199       while (lo_timer_is_running() && i < n)
00200          if (UCSR0A & 0x80) // serial byte is available
00201             buf[i++] = UDR0 ;
00202 
00203       if (i < n)
00204          g_io_error = LOBOT_IO_TIMEOUT ;
00205    }
00206    return i ;
00207 }
00208 
00209 // Receive a single byte over the serial port, waiting a maximum number
00210 // of milliseconds before giving up. If the timeout is zero, wait forever
00211 // for the data byte to come in.
00212 //
00213 // Clients should check the I/O error flag before using the byte returned
00214 // by this function.
00215 char lo_rx1(unsigned int timeout)
00216 {
00217    char c = 0 ;
00218    lo_rx(&c, 1, timeout) ;
00219    return c ;
00220 }
00221 
00222 /*------------------------- USART REDIRECTION -------------------------*/
00223 
00224 void lo_io_to_usb()
00225 {
00226    lo_wait(10) ; // just in case there are some pending bytes to/from Create
00227    PORTB |= 0x10 ;
00228    lo_wait(10) ; // need to wait at least 10 bit times after switching ports
00229 }
00230 
00231 void lo_io_to_create()
00232 {
00233    lo_wait(10) ; // just in case there are some pending bytes to/from USB
00234    PORTB &= ~0x10 ;
00235    lo_wait(10) ; // need to wait at least 10 bit times after switching ports
00236 }
00237 
00238 /*-------------------------- ERROR CHECKING ---------------------------*/
00239 
00240 // Retrieve current I/O status
00241 char lo_io_error()
00242 {
00243    return g_io_error ;
00244 }
Generated on Sun May 8 08:41:30 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3