| 151 | kaklik | 1 | /*
 | 
        
           |  |  | 2 |     Copyright (C) 2004    John Orlando
 | 
        
           |  |  | 3 |   | 
        
           |  |  | 4 |    AVRcam: a small real-time image processing engine.
 | 
        
           |  |  | 5 |   | 
        
           |  |  | 6 |     This program is free software; you can redistribute it and/or
 | 
        
           |  |  | 7 |     modify it under the terms of the GNU General Public
 | 
        
           |  |  | 8 |     License as published by the Free Software Foundation; either
 | 
        
           |  |  | 9 |     version 2 of the License, or (at your option) any later version.
 | 
        
           |  |  | 10 |   | 
        
           |  |  | 11 |     This program is distributed in the hope that it will be useful,
 | 
        
           |  |  | 12 |     but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
        
           |  |  | 13 |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
        
           |  |  | 14 |     General Public License for more details.
 | 
        
           |  |  | 15 |   | 
        
           |  |  | 16 |     You should have received a copy of the GNU General Public
 | 
        
           |  |  | 17 |     License along with this program; if not, write to the Free Software
 | 
        
           |  |  | 18 |     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
        
           |  |  | 19 |   | 
        
           |  |  | 20 |    For more information on the AVRcam, please contact:
 | 
        
           |  |  | 21 |   | 
        
           |  |  | 22 |    john@jrobot.net
 | 
        
           |  |  | 23 |   | 
        
           |  |  | 24 |    or go to www.jrobot.net for more details regarding the system.
 | 
        
           |  |  | 25 | */
 | 
        
           |  |  | 26 | /***********************************************************
 | 
        
           |  |  | 27 | 	Module Name: UIMgr.c
 | 
        
           |  |  | 28 | 	Module Date: 04/10/2004
 | 
        
           |  |  | 29 | 	Module Auth: John Orlando
 | 
        
           |  |  | 30 |   | 
        
           |  |  | 31 | 	Description: This module is responsible for providing
 | 
        
           |  |  | 32 | 	the processing to manage the user interface of the
 | 
        
           |  |  | 33 | 	system.  This user interface is provided via the UART.
 | 
        
           |  |  | 34 | 	This module handles the incoming serial commands, and
 | 
        
           |  |  | 35 | 	performs the needed functionality.  It is then
 | 
        
           |  |  | 36 | 	responsible for generating any needed response to
 | 
        
           |  |  | 37 | 	the external entity.
 | 
        
           |  |  | 38 |   | 
        
           |  |  | 39 |     Revision History:
 | 
        
           |  |  | 40 |     Date        Rel Ver.    Notes
 | 
        
           |  |  | 41 |     4/10/2004      0.1     Module created
 | 
        
           |  |  | 42 |     6/30/2004      1.0     Initial release for Circuit Cellar
 | 
        
           |  |  | 43 |                            contest.
 | 
        
           |  |  | 44 |     11/15/2004     1.2     Updated version string to 1.2.
 | 
        
           |  |  | 45 |     1/16/2005      1.4     Added code to write the colorMap
 | 
        
           |  |  | 46 |                            to EEPROM one byte at a time, 
 | 
        
           |  |  | 47 |                            ensuring that the EEPROM is only
 | 
        
           |  |  | 48 |                            written when the data is different
 | 
        
           |  |  | 49 |                            than the current value (thus saving
 | 
        
           |  |  | 50 |                            EEPROM writes).  Updated version
 | 
        
           |  |  | 51 |                            string to 1.4.
 | 
        
           |  |  | 52 | ***********************************************************/
 | 
        
           |  |  | 53 |   | 
        
           |  |  | 54 | /*	Includes */
 | 
        
           |  |  | 55 | #include <avr/io.h>
 | 
        
           |  |  | 56 | #include <stdlib.h>
 | 
        
           |  |  | 57 | #include <string.h>
 | 
        
           |  |  | 58 | #include <avr/eeprom.h>
 | 
        
           |  |  | 59 | #include "CommonDefs.h"
 | 
        
           |  |  | 60 | #include "UIMgr.h"
 | 
        
           |  |  | 61 | #include "UartInterface.h"
 | 
        
           |  |  | 62 | #include "CamConfig.h"
 | 
        
           |  |  | 63 | #include "Utility.h"
 | 
        
           |  |  | 64 | #include "Executive.h"
 | 
        
           |  |  | 65 | #include "CamInterface.h"
 | 
        
           |  |  | 66 |   | 
        
           |  |  | 67 | /* 	Local Structures and Typedefs */
 | 
        
           |  |  | 68 |   | 
        
           |  |  | 69 | typedef enum
 | 
        
           |  |  | 70 | {
 | 
        
           |  |  | 71 | 	getVersionCmd,
 | 
        
           |  |  | 72 | 	pingCmd,
 | 
        
           |  |  | 73 | 	setCameraRegsCmd,
 | 
        
           |  |  | 74 | 	dumpFrameCmd,
 | 
        
           |  |  | 75 | 	enableTrackingCmd,
 | 
        
           |  |  | 76 | 	disableTrackingCmd,
 | 
        
           |  |  | 77 | 	setColorMapCmd,
 | 
        
           |  |  | 78 | 	resetCameraCmd,
 | 
        
           |  |  | 79 | 	noCmd,
 | 
        
           |  |  | 80 | 	invalidCmd
 | 
        
           |  |  | 81 | } UIMgr_Cmd_t;
 | 
        
           |  |  | 82 |   | 
        
           |  |  | 83 | typedef enum
 | 
        
           |  |  | 84 | {
 | 
        
           |  |  | 85 | 	setRed,
 | 
        
           |  |  | 86 | 	setGreen,
 | 
        
           |  |  | 87 | 	setBlue
 | 
        
           |  |  | 88 | } setColorState_t;
 | 
        
           |  |  | 89 |   | 
        
           |  |  | 90 |   | 
        
           |  |  | 91 | /*  Local Variables */
 | 
        
           |  |  | 92 | static unsigned char charCount = 0; 
 | 
        
           |  |  | 93 | static unsigned char charIndex = 0;
 | 
        
           |  |  | 94 | static unsigned char asciiTokenBuffer[MAX_TOKEN_LENGTH+1]; /* +1 to ensure NULL at end */
 | 
        
           |  |  | 95 | static unsigned char tokenCount = 0;
 | 
        
           |  |  | 96 | static unsigned char tokenBuffer[MAX_TOKEN_COUNT];
 | 
        
           |  |  | 97 | static UIMgr_Cmd_t receivedCmd = noCmd;
 | 
        
           |  |  | 98 | static unsigned char AVRcamVersion[] = "AVRcam v1.4\r";
 | 
        
           |  |  | 99 |   | 
        
           |  |  | 100 | /*  Local Function Declaration */
 | 
        
           |  |  | 101 | static unsigned char UIMgr_readRxFifo(void);
 | 
        
           |  |  | 102 | static unsigned char UIMgr_readTxFifo(void);
 | 
        
           |  |  | 103 | static unsigned char UIMgr_readRxFifo(void);
 | 
        
           |  |  | 104 | static void UIMgr_sendNck(void);
 | 
        
           |  |  | 105 | static void UIMgr_sendAck(void);
 | 
        
           |  |  | 106 | static void UIMgr_convertTokenToCmd(void);
 | 
        
           |  |  | 107 | static void UIMgr_convertTokenToValue(void);
 | 
        
           |  |  | 108 | static void UIMgr_executeCmd(void);
 | 
        
           |  |  | 109 |   | 
        
           |  |  | 110 | /*  Extern Variables */
 | 
        
           |  |  | 111 | unsigned char UIMgr_rxFifo[UI_MGR_RX_FIFO_SIZE];
 | 
        
           |  |  | 112 | unsigned char UIMgr_rxFifoHead=0;
 | 
        
           |  |  | 113 | unsigned char UIMgr_rxFifoTail=0;
 | 
        
           |  |  | 114 |   | 
        
           |  |  | 115 | unsigned char UIMgr_txFifo[UI_MGR_TX_FIFO_SIZE];
 | 
        
           |  |  | 116 | unsigned char UIMgr_txFifoHead=0;
 | 
        
           |  |  | 117 | unsigned char UIMgr_txFifoTail=0;
 | 
        
           |  |  | 118 |   | 
        
           |  |  | 119 | /*  Definitions */
 | 
        
           |  |  | 120 | #define IS_DATA_IN_TX_FIFO() (!(UIMgr_txFifoHead == UIMgr_txFifoTail))
 | 
        
           |  |  | 121 | #define IS_DATA_IN_RX_FIFO() (!(UIMgr_rxFifoHead == UIMgr_rxFifoTail))
 | 
        
           |  |  | 122 |   | 
        
           |  |  | 123 | /* MAX_EEPROM_WRITE_ATTEMPTS limits the number of writes that can be
 | 
        
           |  |  | 124 | done to a particular EEPROM cell, so that it can't possible just 
 | 
        
           |  |  | 125 | write to the same cell over and over */
 | 
        
           |  |  | 126 | #define MAX_EEPROM_WRITE_ATTEMPTS 3
 | 
        
           |  |  | 127 |   | 
        
           |  |  | 128 | /***********************************************************
 | 
        
           |  |  | 129 | 	Function Name: UIMgr_init
 | 
        
           |  |  | 130 | 	Function Description: This function is responsible for
 | 
        
           |  |  | 131 | 	initializing the UIMgr module.  It sets up the fifo
 | 
        
           |  |  | 132 | 	used to hold incoming data, etc.
 | 
        
           |  |  | 133 | 	Inputs:  none 
 | 
        
           |  |  | 134 | 	Outputs: none
 | 
        
           |  |  | 135 | ***********************************************************/	
 | 
        
           |  |  | 136 | void UIMgr_init(void)
 | 
        
           |  |  | 137 | {
 | 
        
           |  |  | 138 | 	memset(asciiTokenBuffer,0x00,MAX_TOKEN_LENGTH+1);
 | 
        
           |  |  | 139 | 	memset(tokenBuffer,0x00,MAX_TOKEN_COUNT);
 | 
        
           |  |  | 140 | 	memset(UIMgr_txFifo,0x00,UI_MGR_TX_FIFO_SIZE);
 | 
        
           |  |  | 141 | 	memset(UIMgr_rxFifo,0x00,UI_MGR_RX_FIFO_SIZE);
 | 
        
           |  |  | 142 | }
 | 
        
           |  |  | 143 |   | 
        
           |  |  | 144 | /***********************************************************
 | 
        
           |  |  | 145 | 	Function Name: UIMgr_dispatchEvent
 | 
        
           |  |  | 146 | 	Function Description: This function is responsible for
 | 
        
           |  |  | 147 | 	processing events that pertain to the UIMgr.
 | 
        
           |  |  | 148 | 	Inputs:  event - the generated event
 | 
        
           |  |  | 149 | 	Outputs: none
 | 
        
           |  |  | 150 | ***********************************************************/	
 | 
        
           |  |  | 151 | void UIMgr_dispatchEvent(unsigned char event)
 | 
        
           |  |  | 152 | {
 | 
        
           |  |  | 153 | 	switch(event)
 | 
        
           |  |  | 154 | 	{
 | 
        
           |  |  | 155 | 		case EV_ACQUIRE_LINE_COMPLETE:
 | 
        
           |  |  | 156 | 			UIMgr_transmitPendingData();
 | 
        
           |  |  | 157 | 			break;
 | 
        
           |  |  | 158 |   | 
        
           |  |  | 159 | 		case EV_SERIAL_DATA_RECEIVED:		
 | 
        
           |  |  | 160 | 			UIMgr_processReceivedData();
 | 
        
           |  |  | 161 | 			break;
 | 
        
           |  |  | 162 |   | 
        
           |  |  | 163 | 		case EV_SERIAL_DATA_PENDING_TX:
 | 
        
           |  |  | 164 | 			UIMgr_flushTxBuffer();
 | 
        
           |  |  | 165 | 			break;
 | 
        
           |  |  | 166 | 	}
 | 
        
           |  |  | 167 | }
 | 
        
           |  |  | 168 | /***********************************************************
 | 
        
           |  |  | 169 | 	Function Name: UIMgr_transmitPendingData
 | 
        
           |  |  | 170 | 	Function Description: This function is responsible for
 | 
        
           |  |  | 171 | 	transmitting a single byte of data if data is waiting
 | 
        
           |  |  | 172 | 	to be sent.  Otherwise, if nothing is waiting, the
 | 
        
           |  |  | 173 | 	function just returns.
 | 
        
           |  |  | 174 | 	Inputs:  none 
 | 
        
           |  |  | 175 | 	Outputs: none
 | 
        
           |  |  | 176 | ***********************************************************/
 | 
        
           |  |  | 177 | void UIMgr_transmitPendingData(void)
 | 
        
           |  |  | 178 | {
 | 
        
           |  |  | 179 | 	if (IS_DATA_IN_TX_FIFO() == TRUE)
 | 
        
           |  |  | 180 | 	{
 | 
        
           |  |  | 181 | 		/* data is waiting...send a single byte */
 | 
        
           |  |  | 182 | 		UartInt_txByte( UIMgr_readTxFifo() );
 | 
        
           |  |  | 183 | 	}
 | 
        
           |  |  | 184 | }
 | 
        
           |  |  | 185 | /***********************************************************
 | 
        
           |  |  | 186 | 	Function Name: UIMgr_processReceivedData
 | 
        
           |  |  | 187 | 	Function Description: This function is responsible for
 | 
        
           |  |  | 188 | 	parsing any serial data waiting in the rx fifo
 | 
        
           |  |  | 189 | 	Inputs:  none 
 | 
        
           |  |  | 190 | 	Outputs: none
 | 
        
           |  |  | 191 | ***********************************************************/
 | 
        
           |  |  | 192 | void UIMgr_processReceivedData(void)
 | 
        
           |  |  | 193 | {
 | 
        
           |  |  | 194 | 	unsigned char tmpData = 0;
 | 
        
           |  |  | 195 |   | 
        
           |  |  | 196 | 	/* still need to add a mechanism to handle token counts 
 | 
        
           |  |  | 197 | 	that are excessive!!! FIX ME!!! */
 | 
        
           |  |  | 198 |   | 
        
           |  |  | 199 | 	while(IS_DATA_IN_RX_FIFO() == TRUE)
 | 
        
           |  |  | 200 | 	{
 | 
        
           |  |  | 201 | 		tmpData = UIMgr_readRxFifo();
 | 
        
           |  |  | 202 | 		if (tmpData == '\r') 
 | 
        
           |  |  | 203 | 		{
 | 
        
           |  |  | 204 | 			/* we have reached a token separator */
 | 
        
           |  |  | 205 | 			if (tokenCount == 0)
 | 
        
           |  |  | 206 | 			{
 | 
        
           |  |  | 207 | 				/* convert the command */
 | 
        
           |  |  | 208 | 				UIMgr_convertTokenToCmd();				
 | 
        
           |  |  | 209 | 			}
 | 
        
           |  |  | 210 | 			else
 | 
        
           |  |  | 211 | 			{
 | 
        
           |  |  | 212 | 				/* convert a value */
 | 
        
           |  |  | 213 | 				UIMgr_convertTokenToValue();
 | 
        
           |  |  | 214 | 				tokenCount++;
 | 
        
           |  |  | 215 | 			}
 | 
        
           |  |  | 216 | 			/* either way, it is time to try to process the received
 | 
        
           |  |  | 217 | 			token list since we have reached the end of the cmd. */
 | 
        
           |  |  | 218 | 			Utility_delay(100);
 | 
        
           |  |  | 219 | 			if (receivedCmd == invalidCmd ||
 | 
        
           |  |  | 220 | 			     receivedCmd == noCmd )
 | 
        
           |  |  | 221 | 			{
 | 
        
           |  |  | 222 | 				UIMgr_sendNck();
 | 
        
           |  |  | 223 | 				PUBLISH_EVENT(EV_SERIAL_DATA_PENDING_TX);
 | 
        
           |  |  | 224 | 			}
 | 
        
           |  |  | 225 | 			else
 | 
        
           |  |  | 226 | 			{
 | 
        
           |  |  | 227 | 				UIMgr_sendAck();
 | 
        
           |  |  | 228 | 				/* publish the serial data pending event, so it
 | 
        
           |  |  | 229 | 				will push the ACK out before we execute the cmd */
 | 
        
           |  |  | 230 | 				PUBLISH_EVENT(EV_SERIAL_DATA_PENDING_TX);
 | 
        
           |  |  | 231 | 				UIMgr_executeCmd();
 | 
        
           |  |  | 232 | 			}
 | 
        
           |  |  | 233 |   | 
        
           |  |  | 234 | 			/* reset any necessary data */
 | 
        
           |  |  | 235 | 			tokenCount = 0;
 | 
        
           |  |  | 236 | 			memset(tokenBuffer,0x00,MAX_TOKEN_COUNT);
 | 
        
           |  |  | 237 | 		}
 | 
        
           |  |  | 238 | 		else if (tmpData == ' ')  /* space char */
 | 
        
           |  |  | 239 | 		{
 | 
        
           |  |  | 240 | 			/* the end of a token has been reached */
 | 
        
           |  |  | 241 | 			if (tokenCount == 0)
 | 
        
           |  |  | 242 | 			{
 | 
        
           |  |  | 243 | 				UIMgr_convertTokenToCmd();
 | 
        
           |  |  | 244 | 				tokenCount++;   /* check this...why is this being incremented here??? This
 | 
        
           |  |  | 245 |                 means we have received a token, with tokenCount == 0, which means it is a
 | 
        
           |  |  | 246 |                 command...why is this contributing to tokenCount?
 | 
        
           |  |  | 247 |                 This might cause the set color map command to include too much data, since
 | 
        
           |  |  | 248 |                 it sets the color map based on tokenCount...CHECK*/
 | 
        
           |  |  | 249 | 			}
 | 
        
           |  |  | 250 | 			else
 | 
        
           |  |  | 251 | 			{
 | 
        
           |  |  | 252 | 				/* check to see if this token is going to push
 | 
        
           |  |  | 253 | 				us over the limit...if so, abort the transaction */
 | 
        
           |  |  | 254 | 				if (tokenCount+1 >= MAX_TOKEN_COUNT)
 | 
        
           |  |  | 255 | 				{
 | 
        
           |  |  | 256 | 					/* we received too many tokens, and 
 | 
        
           |  |  | 257 | 					need to NCK this request, since its too
 | 
        
           |  |  | 258 | 					large...reset everything...*/
 | 
        
           |  |  | 259 | 					charCount=0;
 | 
        
           |  |  | 260 | 					charIndex=0;
 | 
        
           |  |  | 261 | 					tokenCount=0;
 | 
        
           |  |  | 262 | 					receivedCmd = invalidCmd;
 | 
        
           |  |  | 263 | 				}
 | 
        
           |  |  | 264 | 				else
 | 
        
           |  |  | 265 | 				{
 | 
        
           |  |  | 266 | 					/* tokenCount is still in range...*/
 | 
        
           |  |  | 267 | 					UIMgr_convertTokenToValue();
 | 
        
           |  |  | 268 | 					tokenCount++;
 | 
        
           |  |  | 269 | 				}
 | 
        
           |  |  | 270 | 			}
 | 
        
           |  |  | 271 | 		}
 | 
        
           |  |  | 272 | 		else if ( (tmpData >= 'A' && tmpData <= 'Z') ||
 | 
        
           |  |  | 273 | 				   (tmpData >= '0' && tmpData <= '9') )
 | 
        
           |  |  | 274 | 		{
 | 
        
           |  |  | 275 | 			/* a valid range of token was received */
 | 
        
           |  |  | 276 | 			asciiTokenBuffer[charIndex] = tmpData;
 | 
        
           |  |  | 277 | 			charCount++;
 | 
        
           |  |  | 278 | 			charIndex++;
 | 
        
           |  |  | 279 | 			if (charCount > MAX_TOKEN_LENGTH)
 | 
        
           |  |  | 280 | 			{
 | 
        
           |  |  | 281 | 				/* we have received a token that cannot be handled...
 | 
        
           |  |  | 282 | 				set the received cmd to an invalid cmd, and wait
 | 
        
           |  |  | 283 | 				for the \r to process it */
 | 
        
           |  |  | 284 | 				receivedCmd = invalidCmd;
 | 
        
           |  |  | 285 | 				charIndex = 0;  /* ...so we won't overwrite memory */
 | 
        
           |  |  | 286 | 			}
 | 
        
           |  |  | 287 | 		}
 | 
        
           |  |  | 288 | 		else
 | 
        
           |  |  | 289 | 		{
 | 
        
           |  |  | 290 | 			/* an invalid character was received */
 | 
        
           |  |  | 291 | 			receivedCmd = invalidCmd;
 | 
        
           |  |  | 292 | 		}
 | 
        
           |  |  | 293 | 	}  /* end while */
 | 
        
           |  |  | 294 |   | 
        
           |  |  | 295 | 	asm volatile("clt"::);  /* clear out the T flag in case it wasn't
 | 
        
           |  |  | 296 | 								 cleared already */
 | 
        
           |  |  | 297 | }						
 | 
        
           |  |  | 298 |   | 
        
           |  |  | 299 | /***********************************************************
 | 
        
           |  |  | 300 | 	Function Name: UIMgr_executeCmd
 | 
        
           |  |  | 301 | 	Function Description: This function is responsible for
 | 
        
           |  |  | 302 | 	executing whatever cmd is stored in the receivedCmd
 | 
        
           |  |  | 303 | 	object.
 | 
        
           |  |  | 304 | 	Inputs:  none 
 | 
        
           |  |  | 305 | 	Outputs: none
 | 
        
           |  |  | 306 | ***********************************************************/
 | 
        
           |  |  | 307 | static void UIMgr_executeCmd(void)
 | 
        
           |  |  | 308 | {
 | 
        
           |  |  | 309 | 	unsigned char i,eepromData, num_writes=0;
 | 
        
           |  |  | 310 | 	unsigned char *pData;
 | 
        
           |  |  | 311 |     unsigned char eeprom_write_succeeded = FALSE;
 | 
        
           |  |  | 312 | #if	DEBUG_COLOR_MAP	
 | 
        
           |  |  | 313 | 	unsigned char asciiBuffer[5];
 | 
        
           |  |  | 314 | #endif
 | 
        
           |  |  | 315 |   | 
        
           |  |  | 316 | 	if (receivedCmd == pingCmd) 
 | 
        
           |  |  | 317 | 	{
 | 
        
           |  |  | 318 | 	}
 | 
        
           |  |  | 319 | 	else if (receivedCmd == getVersionCmd)
 | 
        
           |  |  | 320 | 	{
 | 
        
           |  |  | 321 | 		pData = AVRcamVersion;
 | 
        
           |  |  | 322 | 		while(*pData != 0)
 | 
        
           |  |  | 323 | 		{		
 | 
        
           |  |  | 324 | 			UIMgr_writeTxFifo(*pData++);
 | 
        
           |  |  | 325 | 		}
 | 
        
           |  |  | 326 | 	}		
 | 
        
           |  |  | 327 | 	else if (receivedCmd == resetCameraCmd)
 | 
        
           |  |  | 328 | 	{
 | 
        
           |  |  | 329 | 		CamInt_resetCam();
 | 
        
           |  |  | 330 | 	}
 | 
        
           |  |  | 331 | 	else if (receivedCmd == dumpFrameCmd)
 | 
        
           |  |  | 332 | 	{
 | 
        
           |  |  | 333 | 		/* publish the event that will indicate that
 | 
        
           |  |  | 334 | 		a request has come to dump a frame...this will
 | 
        
           |  |  | 335 | 		be received by the FrameMgr, which will begin
 | 
        
           |  |  | 336 | 		dumping the frame...a short delay is needed
 | 
        
           |  |  | 337 | 		here to keep the Java demo app happy (sometimes
 | 
        
           |  |  | 338 | 		it wouldn't be able to receive the serial data
 | 
        
           |  |  | 339 | 		as quickly as AVRcam can provide it). */
 | 
        
           |  |  | 340 | 		Utility_delay(100);
 | 
        
           |  |  | 341 | 		PUBLISH_EVENT(EV_DUMP_FRAME);
 | 
        
           |  |  | 342 | 	}
 | 
        
           |  |  | 343 | 	else if (receivedCmd == setCameraRegsCmd)
 | 
        
           |  |  | 344 | 	{
 | 
        
           |  |  | 345 | 		/* we need to gather the tokens and
 | 
        
           |  |  | 346 | 		build config cmds to be sent to the camera */
 | 
        
           |  |  | 347 | 		for (i=1; i<tokenCount; i+=2)  /* starts at 1 since first token
 | 
        
           |  |  | 348 | 											is the CR cmd */
 | 
        
           |  |  | 349 | 		{
 | 
        
           |  |  | 350 | 			CamConfig_setCamReg(tokenBuffer[i],tokenBuffer[i+1]);
 | 
        
           |  |  | 351 | 		}
 | 
        
           |  |  | 352 | 		CamConfig_sendFifoCmds();
 | 
        
           |  |  | 353 | 	}
 | 
        
           |  |  | 354 | 	else if (receivedCmd == enableTrackingCmd)
 | 
        
           |  |  | 355 | 	{
 | 
        
           |  |  | 356 | 		/* publish the event...again with a short delay */
 | 
        
           |  |  | 357 | 		Utility_delay(100);
 | 
        
           |  |  | 358 | 		PUBLISH_EVENT(EV_ENABLE_TRACKING);
 | 
        
           |  |  | 359 | 	}
 | 
        
           |  |  | 360 | 	else if (receivedCmd == disableTrackingCmd)
 | 
        
           |  |  | 361 | 	{
 | 
        
           |  |  | 362 | 		PUBLISH_EVENT(EV_DISABLE_TRACKING);
 | 
        
           |  |  | 363 | 	}
 | 
        
           |  |  | 364 | 	else if (receivedCmd == setColorMapCmd)
 | 
        
           |  |  | 365 | 	{
 | 
        
           |  |  | 366 | 		/* copy the received tokens into the color map */
 | 
        
           |  |  | 367 | 		for (i=0; i<tokenCount; i++)
 | 
        
           |  |  | 368 | 		{
 | 
        
           |  |  | 369 | 			colorMap[i] = tokenBuffer[i+1];
 | 
        
           |  |  | 370 |   | 
        
           |  |  | 371 |             /* write each colorMap byte to EEPROM, but only those
 | 
        
           |  |  | 372 |             that changed...this will help reduce wear on the EEPROM */
 | 
        
           |  |  | 373 |             eepromData = eeprom_read_byte( (unsigned char*)(i+1));
 | 
        
           |  |  | 374 |             if (eepromData != colorMap[i])
 | 
        
           |  |  | 375 |             {
 | 
        
           |  |  | 376 |                 /* need to actually perform the write because the
 | 
        
           |  |  | 377 |                 data in eeprom is different than the current colorMap */
 | 
        
           |  |  | 378 |                 eeprom_write_succeeded = FALSE;
 | 
        
           |  |  | 379 |                 while(eeprom_write_succeeded == FALSE && num_writes < MAX_EEPROM_WRITE_ATTEMPTS)
 | 
        
           |  |  | 380 |                 {
 | 
        
           |  |  | 381 |                     eeprom_write_byte((unsigned char*)(i+1),colorMap[i]);
 | 
        
           |  |  | 382 |                     num_writes++;
 | 
        
           |  |  | 383 |                     eepromData = eeprom_read_byte( (unsigned char*)(i+1));
 | 
        
           |  |  | 384 |                     if (eepromData == colorMap[i])
 | 
        
           |  |  | 385 |                     {
 | 
        
           |  |  | 386 |                         eeprom_write_succeeded = TRUE;
 | 
        
           |  |  | 387 |                     }
 | 
        
           |  |  | 388 |                 }
 | 
        
           |  |  | 389 |                 num_writes = 0;
 | 
        
           |  |  | 390 |             }
 | 
        
           |  |  | 391 | 		}
 | 
        
           |  |  | 392 |   | 
        
           |  |  | 393 | #if	DEBUG_COLOR_MAP			
 | 
        
           |  |  | 394 |             			/* for debugging...send out the entire color map */
 | 
        
           |  |  | 395 |         UIMgr_txBuffer("\r\n",2);
 | 
        
           |  |  | 396 | 		for (i=0; i<NUM_ELEMENTS_IN_COLOR_MAP; i++)
 | 
        
           |  |  | 397 | 		{
 | 
        
           |  |  | 398 | 			memset(asciiBuffer,0x00,5);
 | 
        
           |  |  | 399 | 			itoa(colorMap[i],asciiBuffer,10);
 | 
        
           |  |  | 400 | 			UIMgr_txBuffer(asciiBuffer,3);
 | 
        
           |  |  | 401 | 			UIMgr_txBuffer(" ",1);
 | 
        
           |  |  | 402 | 			if (i==15 || i == 31)
 | 
        
           |  |  | 403 | 			{
 | 
        
           |  |  | 404 | 				/* break up the output */
 | 
        
           |  |  | 405 | 				UIMgr_txBuffer("\r\n",2);
 | 
        
           |  |  | 406 | 			}
 | 
        
           |  |  | 407 | 		}
 | 
        
           |  |  | 408 | #endif			
 | 
        
           |  |  | 409 | 	}
 | 
        
           |  |  | 410 | }
 | 
        
           |  |  | 411 |   | 
        
           |  |  | 412 | /***********************************************************
 | 
        
           |  |  | 413 | 	Function Name: UIMgr_convertTokenToValue
 | 
        
           |  |  | 414 | 	Function Description: This function is responsible for
 | 
        
           |  |  | 415 | 	converting a received token to a hex value It will
 | 
        
           |  |  | 416 | 	access the asciiTokenBuffer directly, and store the
 | 
        
           |  |  | 417 | 	result in the appropriate token buffer.
 | 
        
           |  |  | 418 | 	Inputs:  none 
 | 
        
           |  |  | 419 | 	Outputs: none
 | 
        
           |  |  | 420 | ***********************************************************/	
 | 
        
           |  |  | 421 | static void UIMgr_convertTokenToValue(void)
 | 
        
           |  |  | 422 | {
 | 
        
           |  |  | 423 | 	unsigned int newValue;
 | 
        
           |  |  | 424 |   | 
        
           |  |  | 425 | 	newValue = atoi(asciiTokenBuffer);
 | 
        
           |  |  | 426 | 	if (newValue > 255)
 | 
        
           |  |  | 427 | 	{
 | 
        
           |  |  | 428 | 		/* the value is too large */
 | 
        
           |  |  | 429 | 		receivedCmd = invalidCmd;
 | 
        
           |  |  | 430 | 		tokenBuffer[tokenCount] = 0xFF;  /* to indicate an error */
 | 
        
           |  |  | 431 | 	}
 | 
        
           |  |  | 432 | 	else
 | 
        
           |  |  | 433 | 	{
 | 
        
           |  |  | 434 | 		/* copy the value into the tokenBuffer */
 | 
        
           |  |  | 435 | 		tokenBuffer[tokenCount] = newValue;
 | 
        
           |  |  | 436 | 	}
 | 
        
           |  |  | 437 | 	memset(asciiTokenBuffer,0x00,MAX_TOKEN_LENGTH);
 | 
        
           |  |  | 438 | 	charIndex = 0;
 | 
        
           |  |  | 439 | 	charCount = 0;
 | 
        
           |  |  | 440 | }
 | 
        
           |  |  | 441 | /***********************************************************
 | 
        
           |  |  | 442 | 	Function Name: UIMgr_convertTokenToCmd
 | 
        
           |  |  | 443 | 	Function Description: This function is responsible for
 | 
        
           |  |  | 444 | 	parsing a received 2-character command.  It will
 | 
        
           |  |  | 445 | 	access the asciiTokenBuffer directly.
 | 
        
           |  |  | 446 | 	Inputs:  none 
 | 
        
           |  |  | 447 | 	Outputs: none
 | 
        
           |  |  | 448 | ***********************************************************/	
 | 
        
           |  |  | 449 | static void UIMgr_convertTokenToCmd(void)
 | 
        
           |  |  | 450 | {
 | 
        
           |  |  | 451 | 	if ( (asciiTokenBuffer[0] == 'P') &&
 | 
        
           |  |  | 452 | 		 (asciiTokenBuffer[1] == 'G') )
 | 
        
           |  |  | 453 | 	{
 | 
        
           |  |  | 454 | 		/* we got a "ping" command...but we still need to see
 | 
        
           |  |  | 455 | 		if we are going to get the \r */
 | 
        
           |  |  | 456 | 		receivedCmd = pingCmd;
 | 
        
           |  |  | 457 | 	}
 | 
        
           |  |  | 458 | 	else if ( (asciiTokenBuffer[0] == 'G') &&
 | 
        
           |  |  | 459 | 			   (asciiTokenBuffer[1] == 'V') )
 | 
        
           |  |  | 460 | 	{
 | 
        
           |  |  | 461 | 		/* we got the "get version" command */
 | 
        
           |  |  | 462 | 		receivedCmd = getVersionCmd;
 | 
        
           |  |  | 463 | 	}
 | 
        
           |  |  | 464 | 	else if ( (asciiTokenBuffer[0] == 'D') &&
 | 
        
           |  |  | 465 | 			   (asciiTokenBuffer[1] == 'F') )
 | 
        
           |  |  | 466 | 	{
 | 
        
           |  |  | 467 | 		/* we should go into frame dump mode */
 | 
        
           |  |  | 468 | 		receivedCmd = dumpFrameCmd;	
 | 
        
           |  |  | 469 | 	}
 | 
        
           |  |  | 470 | 	else if ( (asciiTokenBuffer[0] == 'C') &&
 | 
        
           |  |  | 471 | 	           (asciiTokenBuffer[1] == 'R') )
 | 
        
           |  |  | 472 | 	{
 | 
        
           |  |  | 473 | 		/* the user wants to set registers in the OV6620 */
 | 
        
           |  |  | 474 | 		receivedCmd = setCameraRegsCmd;
 | 
        
           |  |  | 475 | 	}
 | 
        
           |  |  | 476 | 	else if ( (asciiTokenBuffer[0] == 'E') &&
 | 
        
           |  |  | 477 | 			   (asciiTokenBuffer[1] == 'T') )
 | 
        
           |  |  | 478 | 	{
 | 
        
           |  |  | 479 | 		/* the user wants to enable tracking */
 | 
        
           |  |  | 480 | 		receivedCmd = enableTrackingCmd;
 | 
        
           |  |  | 481 | 	}
 | 
        
           |  |  | 482 | 	else if ( (asciiTokenBuffer[0] == 'S') &&
 | 
        
           |  |  | 483 | 			   (asciiTokenBuffer[1] == 'M') )
 | 
        
           |  |  | 484 | 	{
 | 
        
           |  |  | 485 | 		/* the user wants to set the color map */
 | 
        
           |  |  | 486 | 		receivedCmd = setColorMapCmd;
 | 
        
           |  |  | 487 | 	}
 | 
        
           |  |  | 488 | 	else if ( (asciiTokenBuffer[0] == 'D') &&
 | 
        
           |  |  | 489 | 			   (asciiTokenBuffer[1] == 'T') )
 | 
        
           |  |  | 490 | 	{
 | 
        
           |  |  | 491 | 		receivedCmd = disableTrackingCmd;
 | 
        
           |  |  | 492 | 	}
 | 
        
           |  |  | 493 | 	else if ( (asciiTokenBuffer[0] == 'R') &&
 | 
        
           |  |  | 494 | 			   (asciiTokenBuffer[1] == 'S') )
 | 
        
           |  |  | 495 | 	{
 | 
        
           |  |  | 496 | 		receivedCmd = resetCameraCmd;
 | 
        
           |  |  | 497 | 	}
 | 
        
           |  |  | 498 | 	else
 | 
        
           |  |  | 499 | 	{
 | 
        
           |  |  | 500 | 		/* don't recognize the cmd */
 | 
        
           |  |  | 501 | 		receivedCmd = invalidCmd;
 | 
        
           |  |  | 502 | 	}
 | 
        
           |  |  | 503 | 	memset(asciiTokenBuffer,0x00,MAX_TOKEN_LENGTH);
 | 
        
           |  |  | 504 | 	charIndex = 0;
 | 
        
           |  |  | 505 | 	charCount = 0;
 | 
        
           |  |  | 506 | }
 | 
        
           |  |  | 507 | /***********************************************************
 | 
        
           |  |  | 508 | 	Function Name: UIMgr_sendAck
 | 
        
           |  |  | 509 | 	Function Description: This function is responsible for
 | 
        
           |  |  | 510 | 	queuing up an ACK to be sent to the user.
 | 
        
           |  |  | 511 | 	Inputs:  none 
 | 
        
           |  |  | 512 | 	Outputs: none
 | 
        
           |  |  | 513 | ***********************************************************/	
 | 
        
           |  |  | 514 | static void UIMgr_sendAck(void)
 | 
        
           |  |  | 515 | {
 | 
        
           |  |  | 516 | 	UIMgr_writeTxFifo('A');
 | 
        
           |  |  | 517 | 	UIMgr_writeTxFifo('C');
 | 
        
           |  |  | 518 | 	UIMgr_writeTxFifo('K');
 | 
        
           |  |  | 519 | 	UIMgr_writeTxFifo('\r');
 | 
        
           |  |  | 520 | }
 | 
        
           |  |  | 521 |   | 
        
           |  |  | 522 | /***********************************************************
 | 
        
           |  |  | 523 | 	Function Name: UIMgr_sendNck
 | 
        
           |  |  | 524 | 	Function Description: This function is responsible for
 | 
        
           |  |  | 525 | 	queueing up an NCK to be sent to the user.
 | 
        
           |  |  | 526 | 	Inputs:  none 
 | 
        
           |  |  | 527 | 	Outputs: none
 | 
        
           |  |  | 528 | ***********************************************************/	
 | 
        
           |  |  | 529 | static void UIMgr_sendNck(void)
 | 
        
           |  |  | 530 | {
 | 
        
           |  |  | 531 | 		UIMgr_writeTxFifo('N');
 | 
        
           |  |  | 532 | 		UIMgr_writeTxFifo('C');
 | 
        
           |  |  | 533 | 		UIMgr_writeTxFifo('K');
 | 
        
           |  |  | 534 | 		UIMgr_writeTxFifo('\r');
 | 
        
           |  |  | 535 | }
 | 
        
           |  |  | 536 |   | 
        
           |  |  | 537 |   | 
        
           |  |  | 538 | /***********************************************************
 | 
        
           |  |  | 539 | 	Function Name: UIMgr_writeBufferToTxFifo
 | 
        
           |  |  | 540 | 	Function Description: This function is responsible for
 | 
        
           |  |  | 541 | 	placing "length" bytes into the tx FIFO.
 | 
        
           |  |  | 542 | 	Inputs:  pData -  a pointer to the data to send
 | 
        
           |  |  | 543 | 	         length - the number of bytes to send
 | 
        
           |  |  | 544 | 	Outputs: none
 | 
        
           |  |  | 545 | ***********************************************************/	
 | 
        
           |  |  | 546 | void UIMgr_writeBufferToTxFifo(unsigned char *pData, unsigned char length)
 | 
        
           |  |  | 547 | {
 | 
        
           |  |  | 548 | 	unsigned char tmpHead;
 | 
        
           |  |  | 549 | 	if (length == 0)
 | 
        
           |  |  | 550 | 	{
 | 
        
           |  |  | 551 | 		return;
 | 
        
           |  |  | 552 | 	}
 | 
        
           |  |  | 553 |   | 
        
           |  |  | 554 | 	DISABLE_INTS();
 | 
        
           |  |  | 555 | 	while(length-- != 0)
 | 
        
           |  |  | 556 | 	{
 | 
        
           |  |  | 557 | 		UIMgr_txFifo[UIMgr_txFifoHead] = *pData++;
 | 
        
           |  |  | 558 |   | 
        
           |  |  | 559 | 		/* now move the head up */
 | 
        
           |  |  | 560 | 		tmpHead = (UIMgr_txFifoHead + 1) & (UI_MGR_TX_FIFO_MASK);
 | 
        
           |  |  | 561 | 		UIMgr_txFifoHead = tmpHead;
 | 
        
           |  |  | 562 | 	}
 | 
        
           |  |  | 563 | 	ENABLE_INTS();
 | 
        
           |  |  | 564 | }
 | 
        
           |  |  | 565 |   | 
        
           |  |  | 566 | /***********************************************************
 | 
        
           |  |  | 567 | 	Function Name: UIMgr_txBuffer
 | 
        
           |  |  | 568 | 	Function Description: This function is responsible for
 | 
        
           |  |  | 569 | 	sending 'length' bytes out using the UartInterface 
 | 
        
           |  |  | 570 | 	module.
 | 
        
           |  |  | 571 | 	Inputs:  pData -  a pointer to the data to send
 | 
        
           |  |  | 572 | 	         length - the number of bytes to send
 | 
        
           |  |  | 573 | 	Outputs: none
 | 
        
           |  |  | 574 | ***********************************************************/	
 | 
        
           |  |  | 575 | void UIMgr_txBuffer(unsigned char *pData, unsigned char length)
 | 
        
           |  |  | 576 | {
 | 
        
           |  |  | 577 | 	while(length-- != 0)
 | 
        
           |  |  | 578 | 	{
 | 
        
           |  |  | 579 | 		UartInt_txByte(*pData++); 
 | 
        
           |  |  | 580 | 	}
 | 
        
           |  |  | 581 | }
 | 
        
           |  |  | 582 |   | 
        
           |  |  | 583 | /***********************************************************
 | 
        
           |  |  | 584 | 	Function Name: UIMgr_flushTxBuffer
 | 
        
           |  |  | 585 | 	Function Description: This function is responsible for
 | 
        
           |  |  | 586 | 	sending all data currently in the serial tx buffer
 | 
        
           |  |  | 587 | 	to the user.
 | 
        
           |  |  | 588 | 	Inputs:  none
 | 
        
           |  |  | 589 | 	Outputs: none
 | 
        
           |  |  | 590 | ***********************************************************/	
 | 
        
           |  |  | 591 | void UIMgr_flushTxBuffer(void)
 | 
        
           |  |  | 592 | {
 | 
        
           |  |  | 593 | 	while(IS_DATA_IN_TX_FIFO() == TRUE)
 | 
        
           |  |  | 594 | 	{
 | 
        
           |  |  | 595 | 		UartInt_txByte(UIMgr_readTxFifo() );
 | 
        
           |  |  | 596 | 	}
 | 
        
           |  |  | 597 | }
 | 
        
           |  |  | 598 |   | 
        
           |  |  | 599 | /***********************************************************
 | 
        
           |  |  | 600 | 	Function Name: UIMgr_readRxFifo
 | 
        
           |  |  | 601 | 	Function Description: This function is responsible for
 | 
        
           |  |  | 602 | 	reading a single byte of data from the rx fifo, and
 | 
        
           |  |  | 603 | 	updating the appropriate pointers.
 | 
        
           |  |  | 604 | 	Inputs:  none 
 | 
        
           |  |  | 605 | 	Outputs: unsigned char-the data read
 | 
        
           |  |  | 606 | ***********************************************************/	
 | 
        
           |  |  | 607 | static unsigned char UIMgr_readRxFifo(void)
 | 
        
           |  |  | 608 | {
 | 
        
           |  |  | 609 | 	unsigned char dataByte, tmpTail;
 | 
        
           |  |  | 610 |   | 
        
           |  |  | 611 | 	/* just return the current tail from the rx fifo */
 | 
        
           |  |  | 612 | 	DISABLE_INTS();
 | 
        
           |  |  | 613 | 	dataByte = UIMgr_rxFifo[UIMgr_rxFifoTail];	
 | 
        
           |  |  | 614 | 	tmpTail = (UIMgr_rxFifoTail+1) & (UI_MGR_RX_FIFO_MASK);
 | 
        
           |  |  | 615 | 	UIMgr_rxFifoTail = tmpTail;
 | 
        
           |  |  | 616 | 	ENABLE_INTS();
 | 
        
           |  |  | 617 |   | 
        
           |  |  | 618 | 	return(dataByte);
 | 
        
           |  |  | 619 | }
 | 
        
           |  |  | 620 |   | 
        
           |  |  | 621 | /***********************************************************
 | 
        
           |  |  | 622 | 	Function Name: UIMgr_readTxFifo
 | 
        
           |  |  | 623 | 	Function Description: This function is responsible for
 | 
        
           |  |  | 624 | 	reading a single byte of data from the tx fifo, and
 | 
        
           |  |  | 625 | 	updating the appropriate pointers.
 | 
        
           |  |  | 626 | 	Inputs:  none 
 | 
        
           |  |  | 627 | 	Outputs: unsigned char-the data read
 | 
        
           |  |  | 628 | ***********************************************************/	
 | 
        
           |  |  | 629 | static unsigned char UIMgr_readTxFifo(void)
 | 
        
           |  |  | 630 | {
 | 
        
           |  |  | 631 | 	unsigned char dataByte, tmpTail;
 | 
        
           |  |  | 632 |   | 
        
           |  |  | 633 | 	/* just return the current tail from the tx fifo */
 | 
        
           |  |  | 634 | 	DISABLE_INTS();
 | 
        
           |  |  | 635 | 	dataByte = UIMgr_txFifo[UIMgr_txFifoTail];	
 | 
        
           |  |  | 636 | 	tmpTail = (UIMgr_txFifoTail+1) & (UI_MGR_TX_FIFO_MASK);
 | 
        
           |  |  | 637 | 	UIMgr_txFifoTail = tmpTail;
 | 
        
           |  |  | 638 | 	ENABLE_INTS();
 | 
        
           |  |  | 639 |   | 
        
           |  |  | 640 | 	return(dataByte);
 | 
        
           |  |  | 641 | }
 | 
        
           |  |  | 642 |   | 
        
           |  |  | 643 | /***********************************************************
 | 
        
           |  |  | 644 | 	Function Name: UIMgr_writeTxFifo
 | 
        
           |  |  | 645 | 	Function Description: This function is responsible for
 | 
        
           |  |  | 646 | 	writing a single byte to the TxFifo and
 | 
        
           |  |  | 647 | 	updating the appropriate pointers.
 | 
        
           |  |  | 648 | 	Inputs:  data - the byte to write to the Fifo 
 | 
        
           |  |  | 649 | 	Outputs: none
 | 
        
           |  |  | 650 | ***********************************************************/	
 | 
        
           |  |  | 651 | void UIMgr_writeTxFifo(unsigned char data)
 | 
        
           |  |  | 652 | {
 | 
        
           |  |  | 653 | 	unsigned char tmpHead;
 | 
        
           |  |  | 654 |   | 
        
           |  |  | 655 | 	DISABLE_INTS();
 | 
        
           |  |  | 656 | 	UIMgr_txFifo[UIMgr_txFifoHead] = data;
 | 
        
           |  |  | 657 |   | 
        
           |  |  | 658 |     /* now move the head up */
 | 
        
           |  |  | 659 |     tmpHead = (UIMgr_txFifoHead + 1) & (UI_MGR_TX_FIFO_MASK);
 | 
        
           |  |  | 660 |     UIMgr_txFifoHead = tmpHead;
 | 
        
           |  |  | 661 | 	ENABLE_INTS();
 | 
        
           |  |  | 662 |   | 
        
           |  |  | 663 | }
 | 
        
           |  |  | 664 |   |