Subversion Repositories svnkaklik

Rev

Rev 409 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log

Rev 409 Rev 410
1
/*
1
/*
2
    Copyright (C) 2004    John Orlando
2
    Copyright (C) 2004    John Orlando
3
    
3
    
4
   AVRcam: a small real-time image processing engine.
4
   AVRcam: a small real-time image processing engine.
5
 
5
 
6
    This program is free software; you can redistribute it and/or
6
    This program is free software; you can redistribute it and/or
7
    modify it under the terms of the GNU General Public
7
    modify it under the terms of the GNU General Public
8
    License as published by the Free Software Foundation; either
8
    License as published by the Free Software Foundation; either
9
    version 2 of the License, or (at your option) any later version.
9
    version 2 of the License, or (at your option) any later version.
10
 
10
 
11
    This program is distributed in the hope that it will be useful,
11
    This program is distributed in the hope that it will be useful,
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
    General Public License for more details.
14
    General Public License for more details.
15
 
15
 
16
    You should have received a copy of the GNU General Public
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
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
18
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 
19
 
20
   For more information on the AVRcam, please contact:
20
   For more information on the AVRcam, please contact:
21
 
21
 
22
   john@jrobot.net
22
   john@jrobot.net
23
 
23
 
24
   or go to www.jrobot.net for more details regarding the system.
24
   or go to www.jrobot.net for more details regarding the system.
25
*/
25
*/
26
/*********************************************************
26
/*********************************************************
27
	Module Name: FrameMgr.c
27
	Module Name: FrameMgr.c
28
	Module Date: 04/10/2004
28
	Module Date: 04/10/2004
29
	Module Auth: John Orlando
29
	Module Auth: John Orlando
30
	
30
	
31
	Description: This modules is responsible for performing
31
	Description: This modules is responsible for performing
32
	both medium and high level processing on image data.
32
	both medium and high level processing on image data.
33
	This is performed at both the line level as well as
33
	This is performed at both the line level as well as
34
	the frame level.  It controls the main flow of the
34
	the frame level.  It controls the main flow of the
35
	system, adhering to all the critical timing 
35
	system, adhering to all the critical timing 
36
	requirements (such as when serial data can be transferred,
36
	requirements (such as when serial data can be transferred,
37
	etc).
37
	etc).
38
    
38
    
39
    Revision History:
39
    Revision History:
40
    Date        Rel Ver.    Notes
40
    Date        Rel Ver.    Notes
41
    4/10/2004      0.1     Module created
41
    4/10/2004      0.1     Module created
42
    6/30/2004      1.0     Initial release for Circuit Cellar
42
    6/30/2004      1.0     Initial release for Circuit Cellar
43
                           contest.
43
                           contest.
44
    11/15/2004     1.2     Updated processLine() function so 
44
    11/15/2004     1.2     Updated processLine() function so 
45
                           it will remove objects less than
45
                           it will remove objects less than
46
                           a specified length/width (reduces
46
                           a specified length/width (reduces
47
                           shot noise)
47
                           shot noise)
48
*********************************************************/
48
*********************************************************/
49
 
49
 
50
/*	Includes */
50
/*	Includes */
51
#include <stdlib.h>
51
#include <stdlib.h>
52
#include <string.h>
52
#include <string.h>
53
#include <avr/io.h>
53
#include <avr/io.h>
54
#include "Executive.h"
54
#include "Executive.h"
55
#include "UIMgr.h"
55
#include "UIMgr.h"
56
#include "FrameMgr.h"
56
#include "FrameMgr.h"
57
#include "CamInterface.h"
57
#include "CamInterface.h"
58
#include "UartInterface.h"
58
#include "UartInterface.h"
59
#include "Utility.h"
59
#include "Utility.h"
60
#include "I2CInterface.h"
60
#include "I2CInterface.h"
61
#include "CamConfig.h"
61
#include "CamConfig.h"
62
#include "CommonDefs.h"
62
#include "CommonDefs.h"
63
 
63
 
64
/* 	Local Structures and Typedefs */
64
/* 	Local Structures and Typedefs */
65
enum
65
enum
66
{
66
{
67
	ST_FrameMgr_idle,
67
	ST_FrameMgr_idle,
68
	ST_FrameMgr_TrackingFrame,
68
	ST_FrameMgr_TrackingFrame,
69
	ST_FrameMgr_DumpingFrame
69
	ST_FrameMgr_DumpingFrame
70
};
70
};
71
 
71
 
72
typedef unsigned char FrameMgr_State_t;
72
typedef unsigned char FrameMgr_State_t;
73
 
73
 
74
/*  Definitions */
74
/*  Definitions */
75
/* The most objects that can be tracked at any one time is 8.  
75
/* The most objects that can be tracked at any one time is 8.  
76
This number is determined by the number of bytes that can be
76
This number is determined by the number of bytes that can be
77
sent out during a frame (one byte per line, 144 lines per frame) 
77
sent out during a frame (one byte per line, 144 lines per frame) 
78
with the number of bytes in a tracked object (7) + some wiggle
78
with the number of bytes in a tracked object (7) + some wiggle
79
room :-) ... I guess this could be increased to around 20 if
79
room :-) ... I guess this could be increased to around 20 if
80
we had enough room and cycles to process objects between lines */
80
we had enough room and cycles to process objects between lines */
81
#define MAX_TRACKED_OBJECTS	8
81
#define MAX_TRACKED_OBJECTS	8
82
 
82
 
83
/* This defines the number of bytes that make up a trackedObject_t
83
/* This defines the number of bytes that make up a trackedObject_t
84
structure... */
84
structure... */
85
#define SIZE_OF_TRACKED_OBJECT 8
85
#define SIZE_OF_TRACKED_OBJECT 8
86
 
86
 
87
/* This define is used to turn off the timer overflow interrupt
87
/* This define is used to turn off the timer overflow interrupt
88
that is generated when the PCLK overflows TIMER1 */
88
that is generated when the PCLK overflows TIMER1 */
89
#define DISABLE_PCLK_TIMER1_OVERFLOW_BITMASK 0xFB
89
#define DISABLE_PCLK_TIMER1_OVERFLOW_BITMASK 0xFB
90
 
90
 
91
/* This define is used to determine if a run length is too small
91
/* This define is used to determine if a run length is too small
92
to be concerned with.  This helps to reduce the number of false
92
to be concerned with.  This helps to reduce the number of false
93
positives. */
93
positives. */
94
#define MIN_OBJECT_TRACKING_WIDTH 3
94
#define MIN_OBJECT_TRACKING_WIDTH 3
95
 
95
 
96
/* This define is used to determine if an object has enough
96
/* This define is used to determine if an object has enough
97
height to be considered worth tracking...it is used to reduce
97
height to be considered worth tracking...it is used to reduce
98
shot noise */
98
shot noise */
99
#define MIN_OBJECT_TRACKING_HEIGHT 3
99
#define MIN_OBJECT_TRACKING_HEIGHT 3
100
 
100
 
101
/* This define is used to indicate how often the filter routine
101
/* This define is used to indicate how often the filter routine
102
that removes objects less than MIN_OBJECT_TRACKING_HEIGHT should
102
that removes objects less than MIN_OBJECT_TRACKING_HEIGHT should
103
be executed.  It is measured in a number of lines (7 nominally). */
103
be executed.  It is measured in a number of lines (7 nominally). */
104
#define RUN_OBJECT_FILTER_MASK 0x07
104
#define RUN_OBJECT_FILTER_MASK 0x07
105
 
105
 
106
/* This enum describes the possible colors that can
106
/* This enum describes the possible colors that can
107
be tracked by the system.  This can't be represented as
107
be tracked by the system.  This can't be represented as
108
simple color names (red, brown, etc) due to the fact that
108
simple color names (red, brown, etc) due to the fact that
109
the user sets which colors will be associated with which
109
the user sets which colors will be associated with which
110
bits.  Remember...after the AND operation of the indexed
110
bits.  Remember...after the AND operation of the indexed
111
color map values executes, either a single bit indicating
111
color map values executes, either a single bit indicating
112
the color should be set, or no bits indicating that the
112
the color should be set, or no bits indicating that the
113
color isn't represented in the color map (notTracked). */
113
color isn't represented in the color map (notTracked). */
114
enum
114
enum
115
{
115
{
116
	notTracked,
116
	notTracked,
117
	color1,		/* bit 1 color */
117
	color1,		/* bit 1 color */
118
	color2,		/* bit 2 color */
118
	color2,		/* bit 2 color */
119
	color3,		/* bit 3 color */
119
	color3,		/* bit 3 color */
120
	color4,		/* bit 4 color */
120
	color4,		/* bit 4 color */
121
	color5,		/* bit 5 color */
121
	color5,		/* bit 5 color */
122
	color6,		/* bit 6 color */
122
	color6,		/* bit 6 color */
123
	color7,		/* bit 7 color */
123
	color7,		/* bit 7 color */
124
	color8		/* bit 8 color */
124
	color8		/* bit 8 color */
125
};
125
};
126
 
126
 
127
typedef unsigned char trackedColor_t;
127
typedef unsigned char trackedColor_t;
128
 
128
 
129
/* This structure defines the info that needs to be
129
/* This structure defines the info that needs to be
130
maintained for each trackedObject in the trackingTable */
130
maintained for each trackedObject in the trackingTable */
131
typedef struct
131
typedef struct
132
{
132
{
133
	trackedColor_t  color;
133
	trackedColor_t  color;
134
	unsigned char lastLineXStart;
134
	unsigned char lastLineXStart;
135
	unsigned char lastLineXFinish;
135
	unsigned char lastLineXFinish;
136
	unsigned char x_upperLeft;
136
	unsigned char x_upperLeft;
137
	unsigned char y_upperLeft;
137
	unsigned char y_upperLeft;
138
	unsigned char x_lowerRight;
138
	unsigned char x_lowerRight;
139
	unsigned char y_lowerRight;
139
	unsigned char y_lowerRight;
140
	unsigned char objectValid;  /* used to be a fill byte...now it is
140
	unsigned char objectValid;  /* used to be a fill byte...now it is
141
                                     used to determine if the object is valid
141
                                     used to determine if the object is valid
142
                                     or not...it gets invalidated if it is
142
                                     or not...it gets invalidated if it is
143
                                     determined that it is too small, or
143
                                     determined that it is too small, or
144
                                     that the object is within another object */
144
                                     that the object is within another object */
145
} trackedObject_t;
145
} trackedObject_t;
146
 
146
 
147
/* These defines are used to index into each individual element in the
147
/* These defines are used to index into each individual element in the
148
trackedObject_t structure.  This seems to be MUCH more efficient than
148
trackedObject_t structure.  This seems to be MUCH more efficient than
149
accessing the elements in GCC. */
149
accessing the elements in GCC. */
150
#define COLOR_OFFSET                0
150
#define COLOR_OFFSET                0
151
#define LAST_LINE_X_START_OFFSET    1
151
#define LAST_LINE_X_START_OFFSET    1
152
#define LAST_LINE_X_FINISH_OFFSET   2
152
#define LAST_LINE_X_FINISH_OFFSET   2
153
#define X_UPPER_LEFT_OFFSET         3
153
#define X_UPPER_LEFT_OFFSET         3
154
#define Y_UPPER_LEFT_OFFSET         4
154
#define Y_UPPER_LEFT_OFFSET         4
155
#define X_LOWER_RIGHT_OFFSET        5
155
#define X_LOWER_RIGHT_OFFSET        5
156
#define Y_LOWER_RIGHT_OFFSET        6
156
#define Y_LOWER_RIGHT_OFFSET        6
157
#define VALID_OBJECT_OFFSET         7
157
#define VALID_OBJECT_OFFSET         7
158
 
158
 
159
/*  Local Variables */
159
/*  Local Variables */
160
/* The trackedObjectTable is used to hold up to eight tracked objects
160
/* The trackedObjectTable is used to hold up to eight tracked objects
161
while they are being acquired. */
161
while they are being acquired. */
162
static trackedObject_t trackedObjectTable[MAX_TRACKED_OBJECTS];
162
static trackedObject_t trackedObjectTable[MAX_TRACKED_OBJECTS];
163
static trackedObject_t *pCurrentTrackedObjectTable = trackedObjectTable;
163
static trackedObject_t *pCurrentTrackedObjectTable = trackedObjectTable;
164
static unsigned char lineCount = 0;
164
static unsigned char lineCount = 0;
165
static FrameMgr_State_t currentState = ST_FrameMgr_idle;
165
static FrameMgr_State_t currentState = ST_FrameMgr_idle;
166
static unsigned char numCurrTrackedObjects = 0;
166
static unsigned char numCurrTrackedObjects = 0;
167
static unsigned char numPrevTrackedObjects = 0;
167
static unsigned char numPrevTrackedObjects = 0;
168
static unsigned char trackedLineCount = 0;
168
static unsigned char trackedLineCount = 0;
169
 
169
 
170
/*  Local Functions  */
170
/*  Local Functions  */
171
static void FrameMgr_findConnectedness(void);
171
static void FrameMgr_findConnectedness(void);
172
 
172
 
173
/*  Extern Functions */
173
/*  Extern Functions */
174
/* These functions are located in assembly files, and thus
174
/* These functions are located in assembly files, and thus
175
must be externed here so they can be referenced in the source below. */
175
must be externed here so they can be referenced in the source below. */
176
extern void CamIntAsm_waitForNewTrackingFrame(unsigned char *pBuffer, unsigned char *pMemLookup);
176
extern void CamIntAsm_waitForNewTrackingFrame(unsigned char *pBuffer, unsigned char *pMemLookup);
177
extern void CamIntAsm_waitForNewDumpFrame(unsigned char *pCurrBuffer, unsigned char *pPrevBuffer);
177
extern void CamIntAsm_waitForNewDumpFrame(unsigned char *pCurrBuffer, unsigned char *pPrevBuffer);
178
extern void CamIntAsm_acquireTrackingLine(unsigned char *pBuffer, unsigned char *pMemLookup);
178
extern void CamIntAsm_acquireTrackingLine(unsigned char *pBuffer, unsigned char *pMemLookup);
179
extern void CamIntAsm_acquireDumpLine(unsigned char *pCurrBuffer, unsigned char *pPrevBuffer);
179
extern void CamIntAsm_acquireDumpLine(unsigned char *pCurrBuffer, unsigned char *pPrevBuffer);
180
 
180
 
181
/***********************************************************
181
/***********************************************************
182
	Function Name: FrameMgr_init
182
	Function Name: FrameMgr_init
183
	Function Description: This function is responsible
183
	Function Description: This function is responsible
184
	for initializing the FrameMgr.  This includes 
184
	for initializing the FrameMgr.  This includes 
185
	setting up the various buffers and data needed to 
185
	setting up the various buffers and data needed to 
186
	process each frame of image data.
186
	process each frame of image data.
187
	Inputs:  none
187
	Inputs:  none
188
	Outputs: none
188
	Outputs: none
189
***********************************************************/	
189
***********************************************************/	
190
void FrameMgr_init(void)
190
void FrameMgr_init(void)
191
{
191
{
192
	memset(trackedObjectTable,0x00,sizeof(trackedObjectTable));
192
	memset(trackedObjectTable,0x00,sizeof(trackedObjectTable));
193
}
193
}
194
 
194
 
195
 
195
 
196
/***********************************************************
196
/***********************************************************
197
	Function Name: FrameMgr_dispatchEvent
197
	Function Name: FrameMgr_dispatchEvent
198
	Function Description: This function is responsible for
198
	Function Description: This function is responsible for
199
	taking an incoming event and performing the needed
199
	taking an incoming event and performing the needed
200
	actions with it as pertains to the FrameMgr.
200
	actions with it as pertains to the FrameMgr.
201
	Inputs:  event - the generated event
201
	Inputs:  event - the generated event
202
	Outputs: none
202
	Outputs: none
203
***********************************************************/	
203
***********************************************************/	
204
void FrameMgr_dispatchEvent(unsigned char event)
204
void FrameMgr_dispatchEvent(unsigned char event)
205
{	
205
{	
206
	switch(event)
206
	switch(event)
207
	{
207
	{
208
		case EV_DUMP_FRAME:
208
		case EV_DUMP_FRAME:
209
            /* try re-initializing the camera before we start dumping */
209
            /* try re-initializing the camera before we start dumping */
210
            
210
            
211
			CamConfig_setCamReg(0x11,0x01);  /* reduce the frame rate for dumping*/
211
			CamConfig_setCamReg(0x11,0x01);  /* reduce the frame rate for dumping*/
212
			CamConfig_sendFifoCmds();
212
			CamConfig_sendFifoCmds();
213
			Utility_delay(1000);		/* allow the new frame rate to settle */
213
			Utility_delay(1000);		/* allow the new frame rate to settle */
214
			lineCount = 0;
214
			lineCount = 0;
215
			currentState = ST_FrameMgr_DumpingFrame;
215
			currentState = ST_FrameMgr_DumpingFrame;
216
			//CamIntAsm_waitForNewDumpFrame(currentLineBuffer,previousLineBuffer);
216
			//CamIntAsm_waitForNewDumpFrame(currentLineBuffer,previousLineBuffer);
217
            FrameMgr_acquireLine();
217
            FrameMgr_acquireLine();
218
			break;
218
			break;
219
		
219
		
220
		case EV_ENABLE_TRACKING:
220
		case EV_ENABLE_TRACKING:
221
			currentState = ST_FrameMgr_TrackingFrame;					
221
			currentState = ST_FrameMgr_TrackingFrame;					
222
			FrameMgr_acquireFrame();
222
			FrameMgr_acquireFrame();
223
			break;
223
			break;
224
			
224
			
225
		case EV_ACQUIRE_FRAME_COMPLETE:
225
		case EV_ACQUIRE_FRAME_COMPLETE:
226
			FrameMgr_processFrame();
226
			FrameMgr_processFrame();
227
			break;
227
			break;
228
		
228
		
229
		case EV_PROCESS_FRAME_COMPLETE:
229
		case EV_PROCESS_FRAME_COMPLETE:
230
			FrameMgr_acquireFrame();
230
			FrameMgr_acquireFrame();
231
			break;
231
			break;
232
 
232
 
233
		case EV_SERIAL_DATA_RECEIVED:
233
		case EV_SERIAL_DATA_RECEIVED:
234
			if (currentState != ST_FrameMgr_idle)
234
			if (currentState != ST_FrameMgr_idle)
235
			{
235
			{
236
				/* we need to go back to processing line data, since
236
				/* we need to go back to processing line data, since
237
				serial data reception interrupted us....just trash the
237
				serial data reception interrupted us....just trash the
238
				frame and act like the frame has been processed, which
238
				frame and act like the frame has been processed, which
239
				will kick off the system to wait for the next line */
239
				will kick off the system to wait for the next line */
240
				PUBLISH_EVENT(EV_PROCESS_FRAME_COMPLETE);
240
				PUBLISH_EVENT(EV_PROCESS_FRAME_COMPLETE);
241
			}
241
			}
242
			break;
242
			break;
243
			
243
			
244
		case EV_DISABLE_TRACKING:
244
		case EV_DISABLE_TRACKING:
245
			/* tracking needs to be turned off */
245
			/* tracking needs to be turned off */
246
			currentState = ST_FrameMgr_idle;
246
			currentState = ST_FrameMgr_idle;
247
			break;
247
			break;
248
	}
248
	}
249
}
249
}
250
 
250
 
251
/***********************************************************
251
/***********************************************************
252
	Function Name: FrameMgr_acquireFrame
252
	Function Name: FrameMgr_acquireFrame
253
	Function Description: This function is responsible for
253
	Function Description: This function is responsible for
254
	beginning of the acquisition of a new frame of data
254
	beginning of the acquisition of a new frame of data
255
	from the camera interface. The acquisition of this line 
255
	from the camera interface. The acquisition of this line 
256
	depends on the current state of the FrameMgr.
256
	depends on the current state of the FrameMgr.
257
	Inputs:  none
257
	Inputs:  none
258
	Outputs: none
258
	Outputs: none
259
***********************************************************/	
259
***********************************************************/	
260
void FrameMgr_acquireFrame(void)
260
void FrameMgr_acquireFrame(void)
261
{
261
{
262
	if (currentState == ST_FrameMgr_TrackingFrame)
262
	if (currentState == ST_FrameMgr_TrackingFrame)
263
	{
263
	{
264
		trackedLineCount = 0;
264
		trackedLineCount = 0;
265
		numPrevTrackedObjects = numCurrTrackedObjects;
265
		numPrevTrackedObjects = numCurrTrackedObjects;
266
		numCurrTrackedObjects = 0;
266
		numCurrTrackedObjects = 0;
267
		
267
		
268
		/* clear out the tracking table, and wait for the new frame
268
		/* clear out the tracking table, and wait for the new frame
269
		to start */
269
		to start */
270
		memset(trackedObjectTable,0x00,sizeof(trackedObjectTable));
270
		memset(trackedObjectTable,0x00,sizeof(trackedObjectTable));
271
		//CamIntAsm_waitForNewTrackingFrame(currentLineBuffer,colorMap);
271
		//CamIntAsm_waitForNewTrackingFrame(currentLineBuffer,colorMap);
272
        WAIT_FOR_VSYNC_HIGH();
272
        WAIT_FOR_VSYNC_HIGH();
273
        CamIntAsm_acquireTrackingLine(currentLineBuffer,colorMap);
273
        CamIntAsm_acquireTrackingLine(currentLineBuffer,colorMap);
274
	}
274
	}
275
}
275
}
276
 
276
 
277
/***********************************************************
277
/***********************************************************
278
	Function Name: FrameMgr_acquireLine
278
	Function Name: FrameMgr_acquireLine
279
	Function Description: This function is responsible for
279
	Function Description: This function is responsible for
280
	acquiring a line of data from the camera interface.
280
	acquiring a line of data from the camera interface.
281
	The acquisition of this line depends on the current
281
	The acquisition of this line depends on the current
282
	state of the FrameMgr.
282
	state of the FrameMgr.
283
	Inputs:  none
283
	Inputs:  none
284
	Outputs: none
284
	Outputs: none
285
***********************************************************/	
285
***********************************************************/	
286
void FrameMgr_acquireLine(void)
286
void FrameMgr_acquireLine(void)
287
{
287
{
288
	unsigned char tmpLineCount;
288
	unsigned char tmpLineCount;
289
	
289
	
290
	/* clearing out the buffers takes too long...we should
290
	/* clearing out the buffers takes too long...we should
291
	just overwrite the data here without a problem when
291
	just overwrite the data here without a problem when
292
	we start acquiring...at no point do we check for 
292
	we start acquiring...at no point do we check for 
293
	a 0x00 value in the current or previous lineBuffers,
293
	a 0x00 value in the current or previous lineBuffers,
294
	so it was a bit excessive :-)  */
294
	so it was a bit excessive :-)  */
295
	
295
	
296
	/* check which state we are in and proceed as needed */
296
	/* check which state we are in and proceed as needed */
297
	if (currentState == ST_FrameMgr_DumpingFrame)
297
	if (currentState == ST_FrameMgr_DumpingFrame)
298
	{
298
	{
299
		tmpLineCount = lineCount*2;
299
		tmpLineCount = lineCount*2;
300
        
300
        
301
        /* clearing out the line data in dump mode is ok, and actually
301
        /* clearing out the line data in dump mode is ok, and actually
302
        is needed, since it is possible for the first dump line in
302
        is needed, since it is possible for the first dump line in
303
        a frame to come back with the last line captured of the
303
        a frame to come back with the last line captured of the
304
        last capture session...*/
304
        last capture session...*/
305
        memset(currentLineBuffer,0x00,LENGTH_OF_LINE_BUFFER);
305
        memset(currentLineBuffer,0x00,LENGTH_OF_LINE_BUFFER);
306
        memset(previousLineBuffer,0x00,LENGTH_OF_LINE_BUFFER);
306
        memset(previousLineBuffer,0x00,LENGTH_OF_LINE_BUFFER);
307
		/* wait for another VSYNC so we know which frame to use 
307
		/* wait for another VSYNC so we know which frame to use 
308
		to start looking for a line to receive */
308
		to start looking for a line to receive */
309
		WAIT_FOR_VSYNC_HIGH();  
309
		WAIT_FOR_VSYNC_HIGH();  
310
		WAIT_FOR_VSYNC_LOW();
310
		WAIT_FOR_VSYNC_LOW();
311
		
311
		
312
		/* look at lineCount to determine how many HREFs we should
312
		/* look at lineCount to determine how many HREFs we should
313
		wait before we start sampling */
313
		wait before we start sampling */
314
		while(tmpLineCount != 0)
314
		while(tmpLineCount != 0)
315
		{
315
		{
316
			WAIT_FOR_HREF_HIGH(); 
316
			WAIT_FOR_HREF_HIGH(); 
317
			tmpLineCount--;
317
			tmpLineCount--;
318
			WAIT_FOR_HREF_LOW(); 
318
			WAIT_FOR_HREF_LOW(); 
319
		}
319
		}
320
		
320
		
321
		/*  we should now be ready to sample our line...*/
321
		/*  we should now be ready to sample our line...*/
322
		CamIntAsm_acquireDumpLine(currentLineBuffer,previousLineBuffer);
322
		CamIntAsm_acquireDumpLine(currentLineBuffer,previousLineBuffer);
323
	}		
323
	}		
324
	else if (currentState == ST_FrameMgr_TrackingFrame)
324
	else if (currentState == ST_FrameMgr_TrackingFrame)
325
	{
325
	{
326
		WAIT_FOR_HREF_LOW();
326
		WAIT_FOR_HREF_LOW();
327
		CamIntAsm_acquireTrackingLine(currentLineBuffer,colorMap);
327
		CamIntAsm_acquireTrackingLine(currentLineBuffer,colorMap);
328
	}
328
	}
329
}
329
}
330
 
330
 
331
/***********************************************************
331
/***********************************************************
332
	Function Name: FrameMgr_processLine
332
	Function Name: FrameMgr_processLine
333
	Function Description: This function is responsible for
333
	Function Description: This function is responsible for
334
	parsing the received image line and performing either
334
	parsing the received image line and performing either
335
	connected region mapping (if in the Tracking state) or
335
	connected region mapping (if in the Tracking state) or
336
	sending out the raw sampled data (if in the Dumping
336
	sending out the raw sampled data (if in the Dumping
337
	state).
337
	state).
338
	Inputs:  none
338
	Inputs:  none
339
	Outputs: none
339
	Outputs: none
340
***********************************************************/	
340
***********************************************************/	
341
void FrameMgr_processLine(void)
341
void FrameMgr_processLine(void)
342
{
342
{
343
	unsigned char i;
343
	unsigned char i;
344
	volatile unsigned char dataToSend;
344
	volatile unsigned char dataToSend;
345
	unsigned char *pTrackedObjectData = (unsigned char *)pCurrentTrackedObjectTable;
345
	unsigned char *pTrackedObjectData = (unsigned char *)pCurrentTrackedObjectTable;
346
#ifdef DEBUG_TRACKED_LINE    
346
#ifdef DEBUG_TRACKED_LINE    
347
	unsigned char *pSendData;
347
	unsigned char *pSendData;
348
    unsigned char asciiBuffer[5];
348
    unsigned char asciiBuffer[5];
349
    unsigned char pixelCount = 0;
349
    unsigned char pixelCount = 0;
350
#endif    
350
#endif    
351
	
351
	
352
	if (currentState == ST_FrameMgr_DumpingFrame)
352
	if (currentState == ST_FrameMgr_DumpingFrame)
353
	{
353
	{
354
		/* we want to sit in a tight loop and send the acquired data
354
		/* we want to sit in a tight loop and send the acquired data
355
		sitting in current and previous line buffers out the serial
355
		sitting in current and previous line buffers out the serial
356
		port...it is sent out the serial port immediately instead
356
		port...it is sent out the serial port immediately instead
357
		of going into the UIMgr tx fifo because we can't do anything
357
		of going into the UIMgr tx fifo because we can't do anything
358
		until its sent out anyway...may as well just get it out now	*/
358
		until its sent out anyway...may as well just get it out now	*/
359
		
359
		
360
		/* currentLineBuffer is getting "g" previousLineBuffer is getting "b-r" */
360
		/* currentLineBuffer is getting "g" previousLineBuffer is getting "b-r" */
361
		UartInt_txByte(0x0B);			/* send the header byte */
361
		UartInt_txByte(0x0B);			/* send the header byte */
362
		UartInt_txByte(lineCount);		/* send the line count */
362
		UartInt_txByte(lineCount);		/* send the line count */
363
		for (i=0; i<NUM_PIXELS_IN_A_DUMP_LINE; i+=2)
363
		for (i=0; i<NUM_PIXELS_IN_A_DUMP_LINE; i+=2)
364
		{
364
		{
365
			/* when a dump line is sampled, the upper byte can potentially
365
			/* when a dump line is sampled, the upper byte can potentially
366
			have garbage in it...we don't have time to mask it off as we're
366
			have garbage in it...we don't have time to mask it off as we're
367
			sampling, so it is done here before we send it out...we also
367
			sampling, so it is done here before we send it out...we also
368
			combine the samples together so we really are sending up a
368
			combine the samples together so we really are sending up a
369
			sample for line N as well as line N+1 */
369
			sample for line N as well as line N+1 */
370
			dataToSend = currentLineBuffer[i];
370
			dataToSend = currentLineBuffer[i];
371
			dataToSend &= 0x0F;
371
			dataToSend &= 0x0F;
372
			dataToSend <<= 4;
372
			dataToSend <<= 4;
373
			dataToSend |= (previousLineBuffer[i] & 0x0F);
373
			dataToSend |= (previousLineBuffer[i] & 0x0F);
374
			
374
			
375
			/* dataToSend should be packed now */
375
			/* dataToSend should be packed now */
376
			UartInt_txByte(dataToSend);
376
			UartInt_txByte(dataToSend);
377
			
377
			
378
			/* flip the colors around since we are doing all G on Y and BR on UV */
378
			/* flip the colors around since we are doing all G on Y and BR on UV */
379
			dataToSend = previousLineBuffer[i+1];
379
			dataToSend = previousLineBuffer[i+1];
380
			dataToSend &= 0x0F;
380
			dataToSend &= 0x0F;
381
			dataToSend <<= 4;
381
			dataToSend <<= 4;
382
			dataToSend |= (currentLineBuffer[i+1] & 0x0F);
382
			dataToSend |= (currentLineBuffer[i+1] & 0x0F);
383
			
383
			
384
			/* dataToSend should be packed now */
384
			/* dataToSend should be packed now */
385
			UartInt_txByte(dataToSend);
385
			UartInt_txByte(dataToSend);
386
		}
386
		}
387
		UartInt_txByte(0x0F);  /* send line end */
387
		UartInt_txByte(0x0F);  /* send line end */
388
		/* once all the data is sent, increment out line count by 2 since
388
		/* once all the data is sent, increment out line count by 2 since
389
		we really get 2 lines worth of pixels on each pass */
389
		we really get 2 lines worth of pixels on each pass */
390
		/* Update...increment only by 1, but only send 72 double-lines */
390
		/* Update...increment only by 1, but only send 72 double-lines */
391
		lineCount++;
391
		lineCount++;
392
		
392
		
393
		/* check to see if we have retrieved all of the needed lines */
393
		/* check to see if we have retrieved all of the needed lines */
394
		if (lineCount >= 72)  /* half 144, since we send two lines at a time */
394
		if (lineCount >= 72)  /* half 144, since we send two lines at a time */
395
		{
395
		{
396
			/* we're done, so send the dump complete?...nope, just change
396
			/* we're done, so send the dump complete?...nope, just change
397
			states and we should be fine */
397
			states and we should be fine */
398
			lineCount = 0;
398
			lineCount = 0;
399
			currentState = ST_FrameMgr_idle;
399
			currentState = ST_FrameMgr_idle;
400
			
400
			
401
			/* disable the PCLK counting overflow interrupt */
401
			/* disable the PCLK counting overflow interrupt */
402
			TIMSK &= DISABLE_PCLK_TIMER1_OVERFLOW_BITMASK;
402
			TIMSK &= DISABLE_PCLK_TIMER1_OVERFLOW_BITMASK;
403
			
403
			
404
			CamConfig_setCamReg(0x11,0x00);  /* reset the frame rate to normal*/
404
			CamConfig_setCamReg(0x11,0x00);  /* reset the frame rate to normal*/
405
			CamConfig_sendFifoCmds();
405
			CamConfig_sendFifoCmds();
406
		}
406
		}
407
		else
407
		else
408
		{
408
		{
409
			/* we have more lines to acquire in this frame, so keep on truckin...*/
409
			/* we have more lines to acquire in this frame, so keep on truckin...*/
410
			PUBLISH_FAST_EVENT(FEV_PROCESS_LINE_COMPLETE);
410
			PUBLISH_FAST_EVENT(FEV_PROCESS_LINE_COMPLETE);
411
		}
411
		}
412
	}
412
	}
413
	else if (currentState == ST_FrameMgr_TrackingFrame)
413
	else if (currentState == ST_FrameMgr_TrackingFrame)
414
	{
414
	{
415
#ifdef DEBUG_TRACKED_LINE	
415
#ifdef DEBUG_TRACKED_LINE	
416
		/* send the received line over serial...this should only send
416
		/* send the received line over serial...this should only send
417
		until a pixelCount == 176 */
417
		until a pixelCount == 176 */
418
		pSendData = currentLineBuffer;
418
		pSendData = currentLineBuffer;
419
		itoa(trackedLineCount,asciiBuffer,10);
419
		itoa(trackedLineCount,asciiBuffer,10);
420
		UIMgr_txBuffer(asciiBuffer,3);
420
		UIMgr_txBuffer(asciiBuffer,3);
421
		UIMgr_txBuffer(" ",1);
421
		UIMgr_txBuffer(" ",1);
422
		while(pixelCount < ACTUAL_NUM_PIXELS_IN_A_LINE)  
422
		while(pixelCount < ACTUAL_NUM_PIXELS_IN_A_LINE)  
423
		{
423
		{
424
			memset(asciiBuffer,0x00,5);
424
			memset(asciiBuffer,0x00,5);
425
			itoa(*pSendData++,asciiBuffer,10);	/* color is first byte */
425
			itoa(*pSendData++,asciiBuffer,10);	/* color is first byte */
426
			UIMgr_txBuffer(asciiBuffer,3); /* 3 ascii bytes for data */
426
			UIMgr_txBuffer(asciiBuffer,3); /* 3 ascii bytes for data */
427
			UIMgr_txBuffer(" ",1);
427
			UIMgr_txBuffer(" ",1);
428
 
428
 
429
			pixelCount += *pSendData;	/* run-length is second byte */
429
			pixelCount += *pSendData;	/* run-length is second byte */
430
			memset(asciiBuffer,0x00,5);
430
			memset(asciiBuffer,0x00,5);
431
			itoa(*pSendData++,asciiBuffer,10);
431
			itoa(*pSendData++,asciiBuffer,10);
432
			UIMgr_txBuffer(asciiBuffer,3);
432
			UIMgr_txBuffer(asciiBuffer,3);
433
			UIMgr_txBuffer(" ",1);
433
			UIMgr_txBuffer(" ",1);
434
		}
434
		}
435
		UIMgr_txBuffer("\n\r",2);
435
		UIMgr_txBuffer("\n\r",2);
436
 
436
 
437
		trackedLineCount++;
437
		trackedLineCount++;
438
		if (trackedLineCount == 144)
438
		if (trackedLineCount == 144)
439
		{
439
		{
440
			UIMgr_txBuffer("  FC  \n\r",8);
440
			UIMgr_txBuffer("  FC  \n\r",8);
441
			trackedLineCount = 0;
441
			trackedLineCount = 0;
442
			PUBLISH_EVENT(EV_PROCESS_FRAME_COMPLETE);
442
			PUBLISH_EVENT(EV_PROCESS_FRAME_COMPLETE);
443
		}
443
		}
444
		else
444
		else
445
		{
445
		{
446
			PUBLISH_EVENT(EV_PROCESS_LINE_COMPLETE);
446
			PUBLISH_EVENT(EV_PROCESS_LINE_COMPLETE);
447
		}	
447
		}	
448
#else
448
#else
449
        /* determine if any of the RLE blocks overlap */
449
        /* determine if any of the RLE blocks overlap */
450
		FrameMgr_findConnectedness();
450
		FrameMgr_findConnectedness();
451
        
451
        
452
        /* we also want to remove any objects that are less than
452
        /* we also want to remove any objects that are less than
453
        a minimum height...we already removed portions of the 
453
        a minimum height...we already removed portions of the 
454
        run-length that are less than MIN_PIXEL_WIDTH in the
454
        run-length that are less than MIN_PIXEL_WIDTH in the
455
        findConnectedness() routine...doing it here instead of 
455
        findConnectedness() routine...doing it here instead of 
456
        a function to speed things up...this may end up slowing down the
456
        a function to speed things up...this may end up slowing down the
457
        frame rate slightly, and can be removed if this isn't needed */
457
        frame rate slightly, and can be removed if this isn't needed */
458
  
458
  
459
        /* run this routine once every 8 lines */       
459
        /* run this routine once every 8 lines */       
460
        if ( (trackedLineCount & RUN_OBJECT_FILTER_MASK) == RUN_OBJECT_FILTER_MASK)
460
        if ( (trackedLineCount & RUN_OBJECT_FILTER_MASK) == RUN_OBJECT_FILTER_MASK)
461
        {
461
        {
462
            for (i=0; i<MAX_TRACKED_OBJECTS; i++)
462
            for (i=0; i<MAX_TRACKED_OBJECTS; i++)
463
            {
463
            {
464
                if ( *(pTrackedObjectData + VALID_OBJECT_OFFSET) == TRUE)
464
                if ( *(pTrackedObjectData + VALID_OBJECT_OFFSET) == TRUE)
465
                {
465
                {
466
                    /* check to see if the object is already in
466
                    /* check to see if the object is already in
467
                    our past...i.e., its last */
467
                    our past...i.e., its last */
468
                    if ( (*(pTrackedObjectData + Y_LOWER_RIGHT_OFFSET) - 
468
                    if ( (*(pTrackedObjectData + Y_LOWER_RIGHT_OFFSET) - 
469
                          *(pTrackedObjectData + Y_UPPER_LEFT_OFFSET)) < MIN_OBJECT_TRACKING_HEIGHT)
469
                          *(pTrackedObjectData + Y_UPPER_LEFT_OFFSET)) < MIN_OBJECT_TRACKING_HEIGHT)
470
                    {
470
                    {
471
                        /* the object is less than the minimum height...see if it is adjacent
471
                        /* the object is less than the minimum height...see if it is adjacent
472
                        to the current line we just processed...if so, leave it here...otherwise,
472
                        to the current line we just processed...if so, leave it here...otherwise,
473
                        it needs to be invalidated since its too small */
473
                        it needs to be invalidated since its too small */
474
                        if ( trackedLineCount - *(pTrackedObjectData + Y_LOWER_RIGHT_OFFSET) > 2)
474
                        if ( trackedLineCount - *(pTrackedObjectData + Y_LOWER_RIGHT_OFFSET) > 2)
475
                        {
475
                        {
476
                            /* invalidate the object */
476
                            /* invalidate the object */
477
                            *(pTrackedObjectData + VALID_OBJECT_OFFSET) = FALSE;
477
                            *(pTrackedObjectData + VALID_OBJECT_OFFSET) = FALSE;
478
                            numCurrTrackedObjects--;
478
                            numCurrTrackedObjects--;
479
                        }
479
                        }
480
                    }
480
                    }
481
                }
481
                }
482
                pTrackedObjectData += SIZE_OF_TRACKED_OBJECT;
482
                pTrackedObjectData += SIZE_OF_TRACKED_OBJECT;
483
            }
483
            }
484
        }     
484
        }     
485
 
485
 
486
		trackedLineCount++;
486
		trackedLineCount++;
487
		if (trackedLineCount == ACTUAL_NUM_LINES_IN_A_FRAME)
487
		if (trackedLineCount == ACTUAL_NUM_LINES_IN_A_FRAME)
488
		{
488
		{
489
			/* an entire frame of tracking data has been acquired, so
489
			/* an entire frame of tracking data has been acquired, so
490
			publish an event letting the system know this fact */
490
			publish an event letting the system know this fact */
491
			PUBLISH_EVENT(EV_ACQUIRE_FRAME_COMPLETE);
491
			PUBLISH_EVENT(EV_ACQUIRE_FRAME_COMPLETE);
492
			/* disable the PCLK counting overflow interrupt */
492
			/* disable the PCLK counting overflow interrupt */
493
			TIMSK &= DISABLE_PCLK_TIMER1_OVERFLOW_BITMASK;
493
			TIMSK &= DISABLE_PCLK_TIMER1_OVERFLOW_BITMASK;
494
			trackedLineCount = 0;
494
			trackedLineCount = 0;
495
		}
495
		}
496
		else
496
		else
497
		{
497
		{
498
			PUBLISH_FAST_EVENT(FEV_PROCESS_LINE_COMPLETE);
498
			PUBLISH_FAST_EVENT(FEV_PROCESS_LINE_COMPLETE);
499
		}
499
		}
500
#endif		
500
#endif		
501
	}
501
	}
502
	else
502
	else
503
	{
503
	{
504
		/* ...and here? */
504
		/* ...and here? */
505
	}
505
	}
506
}
506
}
507
 
507
 
508
/***********************************************************
508
/***********************************************************
509
	Function Name: FrameMgr_processFrame
509
	Function Name: FrameMgr_processFrame
510
	Function Description: This function is responsible for
510
	Function Description: This function is responsible for
511
	parsing the completed frame and performing all actions
511
	parsing the completed frame and performing all actions
512
	needed at this level.
512
	needed at this level.
513
	Inputs:  none
513
	Inputs:  none
514
	Outputs: none
514
	Outputs: none
515
***********************************************************/	
515
***********************************************************/	
516
void FrameMgr_processFrame(void)
516
void FrameMgr_processFrame(void)
517
{
517
{
518
	unsigned char i,k,color;
518
	unsigned char i,k,color;
519
#if DEBUG_FRAME_DATA    
519
#if DEBUG_FRAME_DATA    
520
	unsigned char asciiBuffer[5];
520
	unsigned char asciiBuffer[5];
521
    unsigned char j;
521
    unsigned char j;
522
#endif    
522
#endif    
523
	unsigned char *pTableData = (unsigned char *)pCurrentTrackedObjectTable;
523
	unsigned char *pTableData = (unsigned char *)pCurrentTrackedObjectTable;
524
	unsigned char tmpUpperLeftX,tmpUpperLeftY,tmpLowerRightX,tmpLowerRightY;
524
	unsigned char tmpUpperLeftX,tmpUpperLeftY,tmpLowerRightX,tmpLowerRightY;
525
	
525
	
526
#if DEBUG_FRAME_DATA	
526
#if DEBUG_FRAME_DATA	
527
	/* we want to send all of the currently tracked table out
527
	/* we want to send all of the currently tracked table out
528
	the serial port for debugging */
528
	the serial port for debugging */
529
	for (i=0; i<numCurrTrackedObjects; i++)
529
	for (i=0; i<numCurrTrackedObjects; i++)
530
	{
530
	{
531
		UIMgr_txBuffer("----------\r\n",12);
531
		UIMgr_txBuffer("----------\r\n",12);
532
		for (j=0; j<SIZE_OF_TRACKED_OBJECT; j++)
532
		for (j=0; j<SIZE_OF_TRACKED_OBJECT; j++)
533
		{
533
		{
534
			memset(asciiBuffer,0x00,5);
534
			memset(asciiBuffer,0x00,5);
535
			itoa(*pTableData++,asciiBuffer,10);
535
			itoa(*pTableData++,asciiBuffer,10);
536
			UIMgr_txBuffer(asciiBuffer,3); /* 3 ascii bytes for data
536
			UIMgr_txBuffer(asciiBuffer,3); /* 3 ascii bytes for data
537
														+ 1 space */
537
														+ 1 space */
538
			UIMgr_txBuffer("\r\n",2);
538
			UIMgr_txBuffer("\r\n",2);
539
		}
539
		}
540
	}
540
	}
541
	
541
	
542
	/* finally, send a new line */
542
	/* finally, send a new line */
543
	UIMgr_txBuffer("\r\n",2);
543
	UIMgr_txBuffer("\r\n",2);
544
	
544
	
545
	memset(asciiBuffer,0x00,5);
545
	memset(asciiBuffer,0x00,5);
546
	itoa(numCurrTrackedObjects,asciiBuffer,10);
546
	itoa(numCurrTrackedObjects,asciiBuffer,10);
547
	UIMgr_txBuffer(asciiBuffer,3);
547
	UIMgr_txBuffer(asciiBuffer,3);
548
	UIMgr_txBuffer(" PFC\r\n",5);
548
	UIMgr_txBuffer(" PFC\r\n",5);
549
 
549
 
550
#else	
550
#else	
551
	/* we only send tracking packets if there are tracked objects */	        
551
	/* we only send tracking packets if there are tracked objects */	        
552
    
552
    
553
	if (numCurrTrackedObjects > 0)
553
	if (numCurrTrackedObjects > 0)
554
	{		
554
	{		
555
		UIMgr_writeTxFifo(0x0A);					/* header byte for a tracking packet */
555
		UIMgr_writeTxFifo(0x0A);					/* header byte for a tracking packet */
556
        /* reset the pointer */
556
        /* reset the pointer */
557
        pTableData = (unsigned char *)pCurrentTrackedObjectTable;
557
        pTableData = (unsigned char *)pCurrentTrackedObjectTable;
558
        
558
        
559
		UIMgr_writeTxFifo(numCurrTrackedObjects);	/* num of objects tracked */
559
		UIMgr_writeTxFifo(numCurrTrackedObjects);	/* num of objects tracked */
560
		for (i=0; i<MAX_TRACKED_OBJECTS; i++)
560
		for (i=0; i<MAX_TRACKED_OBJECTS; i++)
561
		{
561
		{
562
            /* we only want to process objects that have their objectValid flag
562
            /* we only want to process objects that have their objectValid flag
563
            set to TRUE */
563
            set to TRUE */
564
            if ( *(pTableData + VALID_OBJECT_OFFSET) == TRUE)
564
            if ( *(pTableData + VALID_OBJECT_OFFSET) == TRUE)
565
            {
565
            {
566
                /* the object is valid...convert the color from bit position to value...remember, 
566
                /* the object is valid...convert the color from bit position to value...remember, 
567
                each bit in the "color" byte corresponds to a color */
567
                each bit in the "color" byte corresponds to a color */
568
                k=0;
568
                k=0;
569
                color = *(pTableData + COLOR_OFFSET);
569
                color = *(pTableData + COLOR_OFFSET);
570
                if (color == 128) k=0;
570
                if (color == 128) k=0;
571
                else if (color == 64) k=1;
571
                else if (color == 64) k=1;
572
                else if (color == 32) k=2;
572
                else if (color == 32) k=2;
573
                else if (color == 16) k=3;
573
                else if (color == 16) k=3;
574
                else if (color == 8)  k=4;
574
                else if (color == 8)  k=4;
575
                else if (color == 4)  k=5;
575
                else if (color == 4)  k=5;
576
                else if (color == 2)  k=6;
576
                else if (color == 2)  k=6;
577
                else if (color == 1)  k=7;
577
                else if (color == 1)  k=7;
578
                
578
                
579
                tmpUpperLeftX = *(pTableData + X_UPPER_LEFT_OFFSET);	    /* get the upper left X */
579
                tmpUpperLeftX = *(pTableData + X_UPPER_LEFT_OFFSET);	    /* get the upper left X */
580
                tmpUpperLeftY = *(pTableData + Y_UPPER_LEFT_OFFSET);		/* get the upper left Y */		
580
                tmpUpperLeftY = *(pTableData + Y_UPPER_LEFT_OFFSET);		/* get the upper left Y */		
581
                tmpLowerRightX = *(pTableData + X_LOWER_RIGHT_OFFSET);		/* get the lower right X */
581
                tmpLowerRightX = *(pTableData + X_LOWER_RIGHT_OFFSET);		/* get the lower right X */
582
                tmpLowerRightY = *(pTableData + Y_LOWER_RIGHT_OFFSET);		/* get the lower right Y */	                
582
                tmpLowerRightY = *(pTableData + Y_LOWER_RIGHT_OFFSET);		/* get the lower right Y */	                
583
                
583
                
584
                UIMgr_writeTxFifo(k);				  	/* send the color first */
584
                UIMgr_writeTxFifo(k);				  	/* send the color first */
585
                UIMgr_writeTxFifo(tmpUpperLeftX);
585
                UIMgr_writeTxFifo(tmpUpperLeftX);
586
                UIMgr_writeTxFifo(tmpUpperLeftY);
586
                UIMgr_writeTxFifo(tmpUpperLeftY);
587
                UIMgr_writeTxFifo(tmpLowerRightX);
587
                UIMgr_writeTxFifo(tmpLowerRightX);
588
                UIMgr_writeTxFifo(tmpLowerRightY);			
588
                UIMgr_writeTxFifo(tmpLowerRightY);			
589
            }
589
            }
590
 
590
 
591
            /* move our pointer up to the beginning of the next object */
591
            /* move our pointer up to the beginning of the next object */
592
            pTableData += SIZE_OF_TRACKED_OBJECT;
592
            pTableData += SIZE_OF_TRACKED_OBJECT;
593
        }
593
        }
594
		
594
		
595
		/* all done...send the end of tracking packets char */
595
		/* all done...send the end of tracking packets char */
596
		UIMgr_writeTxFifo(0xFF);
596
		UIMgr_writeTxFifo(0xFF);
597
	}	
597
	}	
598
#endif	
598
#endif	
599
 
599
 
600
    /* the tracked object table will be cleared out right before we start
600
    /* the tracked object table will be cleared out right before we start
601
    to wait for VSYNC to indicate a new frame...so it doesn't need to be
601
    to wait for VSYNC to indicate a new frame...so it doesn't need to be
602
    done now */
602
    done now */
603
    
603
    
604
	/* schedule the next action to acquire a new frame */	
604
	/* schedule the next action to acquire a new frame */	
605
	PUBLISH_EVENT(EV_PROCESS_FRAME_COMPLETE);
605
	PUBLISH_EVENT(EV_PROCESS_FRAME_COMPLETE);
606
}
606
}
607
 
607
 
608
/***********************************************************
608
/***********************************************************
609
	Function Name: FrameMgr_findConnectedness
609
	Function Name: FrameMgr_findConnectedness
610
	Function Description: This function is responsible for
610
	Function Description: This function is responsible for
611
	finding the connectedness between two particular run-
611
	finding the connectedness between two particular run-
612
	length encoded lines of pixel data.  It updates the
612
	length encoded lines of pixel data.  It updates the
613
	trackingTable as needed.
613
	trackingTable as needed.
614
	Inputs:  none
614
	Inputs:  none
615
	Outputs: none
615
	Outputs: none
616
***********************************************************/	
616
***********************************************************/	
617
static void FrameMgr_findConnectedness(void)
617
static void FrameMgr_findConnectedness(void)
618
{
618
{
619
	trackedColor_t currColor;
619
	trackedColor_t currColor;
620
	unsigned char *pCurrLineColorInfo = currentLineBuffer;
620
	unsigned char *pCurrLineColorInfo = currentLineBuffer;
621
	unsigned char *pTrackedObjectData;
621
	unsigned char *pTrackedObjectData;
622
	register unsigned char currPixelRunStart=0;
622
	register unsigned char currPixelRunStart=0;
623
	register unsigned char currPixelRunFinish=0; 
623
	register unsigned char currPixelRunFinish=0; 
624
	register unsigned char lastLineXStart=0;
624
	register unsigned char lastLineXStart=0;
625
	register unsigned char lastLineXFinish=0;  
625
	register unsigned char lastLineXFinish=0;  
626
	register unsigned char runLength=1;
626
	register unsigned char runLength=1;
627
	unsigned char i;
627
	unsigned char i;
628
	bool_t colorConnected;	
628
	bool_t colorConnected;	
629
	
629
	
630
	do
630
	do
631
	{
631
	{
632
		/* grab both the current color and the number of pixels
632
		/* grab both the current color and the number of pixels
633
		in the run...remember, pixels start at 1, not 0! */
633
		in the run...remember, pixels start at 1, not 0! */
634
		colorConnected = FALSE;
634
		colorConnected = FALSE;
635
		currColor = *pCurrLineColorInfo++;
635
		currColor = *pCurrLineColorInfo++;
636
		currPixelRunStart += runLength;
636
		currPixelRunStart += runLength;
637
		runLength = *pCurrLineColorInfo++;
637
		runLength = *pCurrLineColorInfo++;
638
		currPixelRunFinish += runLength;
638
		currPixelRunFinish += runLength;
639
      
639
      
640
        /* make sure that the run-length is at least as wide as
640
        /* make sure that the run-length is at least as wide as
641
        the minimum horizontal tracking width, and we care about the color */ 
641
        the minimum horizontal tracking width, and we care about the color */ 
642
        
642
        
643
		if ( (currColor != notTracked) && (runLength > MIN_OBJECT_TRACKING_WIDTH) )
643
		if ( (currColor != notTracked) && (runLength > MIN_OBJECT_TRACKING_WIDTH) )
644
		{			
644
		{			
645
            /* this run contains a color we care about, so 
645
            /* this run contains a color we care about, so 
646
			either it will begin a new tracked object, or it
646
			either it will begin a new tracked object, or it
647
			is connected to a currently tracked object...
647
			is connected to a currently tracked object...
648
			compare it with each object in the tracking
648
			compare it with each object in the tracking
649
			table...we can't just look at the numTrackedObjects because
649
			table...we can't just look at the numTrackedObjects because
650
            it is entirely possible that the first couple of objects could
650
            it is entirely possible that the first couple of objects could
651
            be invalid...
651
            be invalid...
652
 
652
 
653
            NOTE: Instead of accessing each element in the trackedObjectTable
653
            NOTE: Instead of accessing each element in the trackedObjectTable
654
            through the 'i' index, and then accessing the fields in each structure,
654
            through the 'i' index, and then accessing the fields in each structure,
655
            a pointer to each entry is established each time through the loop, followed
655
            a pointer to each entry is established each time through the loop, followed
656
            by accessing the elements through specified offsets.  GCC seems to be
656
            by accessing the elements through specified offsets.  GCC seems to be
657
            able to optimize this code much better than simply accessing the elements
657
            able to optimize this code much better than simply accessing the elements
658
            of each structure in the array the more normal way...*/
658
            of each structure in the array the more normal way...*/
659
            
659
            
660
            pTrackedObjectData = (unsigned char *)pCurrentTrackedObjectTable;
660
            pTrackedObjectData = (unsigned char *)pCurrentTrackedObjectTable;
661
			for (i=0; i<MAX_TRACKED_OBJECTS; i++)
661
			for (i=0; i<MAX_TRACKED_OBJECTS; i++)
662
			{
662
			{
663
				if ( (currColor == *(pTrackedObjectData + COLOR_OFFSET)) && 
663
				if ( (currColor == *(pTrackedObjectData + COLOR_OFFSET)) && 
664
                     (*(pTrackedObjectData + VALID_OBJECT_OFFSET) == TRUE) &&
664
                     (*(pTrackedObjectData + VALID_OBJECT_OFFSET) == TRUE) &&
665
                     (*(pTrackedObjectData + Y_LOWER_RIGHT_OFFSET) == trackedLineCount - 1) )
665
                     (*(pTrackedObjectData + Y_LOWER_RIGHT_OFFSET) == trackedLineCount - 1) )
666
				{
666
				{
667
					/* found a color match and the object is valid...check to see if there is
667
					/* found a color match and the object is valid...check to see if there is
668
					connectedness */
668
					connectedness */
669
					lastLineXStart = *(pTrackedObjectData + LAST_LINE_X_START_OFFSET);
669
					lastLineXStart = *(pTrackedObjectData + LAST_LINE_X_START_OFFSET);
670
					lastLineXFinish = *(pTrackedObjectData + LAST_LINE_X_FINISH_OFFSET);
670
					lastLineXFinish = *(pTrackedObjectData + LAST_LINE_X_FINISH_OFFSET);
671
					
671
					
672
					/* Check for the 5 following types of line connectedness:
672
					/* Check for the 5 following types of line connectedness:
673
					---------------------
673
					---------------------
674
					|                   |
674
					|                   |
675
					---------------------
675
					---------------------
676
					         -------------------------
676
					         -------------------------
677
							 |                       |
677
							 |                       |
678
							 -------------------------  */
678
							 -------------------------  */
679
					if ( (	(currPixelRunStart >= lastLineXStart) &&
679
					if ( (	(currPixelRunStart >= lastLineXStart) &&
680
							(currPixelRunStart <= lastLineXFinish) )  ||
680
							(currPixelRunStart <= lastLineXFinish) )  ||
681
							
681
							
682
					/*               ---------------------
682
					/*               ---------------------
683
					                 |                   |
683
					                 |                   |
684
									 ---------------------
684
									 ---------------------
685
						-------------------
685
						-------------------
686
						|                 |
686
						|                 |
687
						-------------------  
687
						-------------------  
688
						                   OR
688
						                   OR
689
						     ------------------------------
689
						     ------------------------------
690
							 |                            |
690
							 |                            |
691
							 ------------------------------
691
							 ------------------------------
692
							              ---------
692
							              ---------
693
										  |       |
693
										  |       |
694
										  ---------  */
694
										  ---------  */
695
						 (	(currPixelRunFinish >= lastLineXStart) && 
695
						 (	(currPixelRunFinish >= lastLineXStart) && 
696
							(currPixelRunFinish <= lastLineXFinish) ) ||
696
							(currPixelRunFinish <= lastLineXFinish) ) ||
697
							
697
							
698
							
698
							
699
					/*     -------------------------------
699
					/*     -------------------------------
700
					       |                             |
700
					       |                             |
701
						   -------------------------------
701
						   -------------------------------
702
						   -------------------------------
702
						   -------------------------------
703
						   |                             |
703
						   |                             |
704
						   -------------------------------
704
						   -------------------------------
705
						                  OR
705
						                  OR
706
								     -------------
706
								     -------------
707
									 |           |
707
									 |           |
708
									 -------------
708
									 -------------
709
							-------------------------------
709
							-------------------------------
710
							|                             |
710
							|                             |
711
							-------------------------------   */
711
							-------------------------------   */
712
						 (  (currPixelRunStart <= lastLineXStart) &&
712
						 (  (currPixelRunStart <= lastLineXStart) &&
713
							(currPixelRunFinish >= lastLineXFinish) ) )
713
							(currPixelRunFinish >= lastLineXFinish) ) )
714
					{
714
					{
715
						/* THERE IS CONNECTEDNESS...update the lastLineXStart and lastLineXFinish
715
						/* THERE IS CONNECTEDNESS...update the lastLineXStart and lastLineXFinish
716
						data pointed to by pTrackedObjectData */
716
						data pointed to by pTrackedObjectData */
717
						*(pTrackedObjectData + LAST_LINE_X_START_OFFSET) = currPixelRunStart;
717
						*(pTrackedObjectData + LAST_LINE_X_START_OFFSET) = currPixelRunStart;
718
						*(pTrackedObjectData + LAST_LINE_X_FINISH_OFFSET) = currPixelRunFinish;
718
						*(pTrackedObjectData + LAST_LINE_X_FINISH_OFFSET) = currPixelRunFinish;
719
						
719
						
720
						/* check if the bounding box needs to be updated */
720
						/* check if the bounding box needs to be updated */
721
						if (*(pTrackedObjectData + X_UPPER_LEFT_OFFSET) > currPixelRunStart)
721
						if (*(pTrackedObjectData + X_UPPER_LEFT_OFFSET) > currPixelRunStart)
722
						{
722
						{
723
							/* need to update the bounding box for the upper left point to 
723
							/* need to update the bounding box for the upper left point to 
724
							enclose this new left-most point...we never have to update the
724
							enclose this new left-most point...we never have to update the
725
							upper left Y point, since each scan line we process moves from
725
							upper left Y point, since each scan line we process moves from
726
							top to bottom */
726
							top to bottom */
727
							*(pTrackedObjectData + X_UPPER_LEFT_OFFSET) = currPixelRunStart;
727
							*(pTrackedObjectData + X_UPPER_LEFT_OFFSET) = currPixelRunStart;
728
						}
728
						}
729
 
729
 
730
						if ( *(pTrackedObjectData + X_LOWER_RIGHT_OFFSET) < currPixelRunFinish)
730
						if ( *(pTrackedObjectData + X_LOWER_RIGHT_OFFSET) < currPixelRunFinish)
731
						{
731
						{
732
							/* need to update the bounding box for the lower right X point to
732
							/* need to update the bounding box for the lower right X point to
733
							enclose this new right-most point */
733
							enclose this new right-most point */
734
							*(pTrackedObjectData + X_LOWER_RIGHT_OFFSET) = currPixelRunFinish;
734
							*(pTrackedObjectData + X_LOWER_RIGHT_OFFSET) = currPixelRunFinish;
735
						}
735
						}
736
						
736
						
737
						/* the lower right 'y' point always gets updated when connectedness is found */
737
						/* the lower right 'y' point always gets updated when connectedness is found */
738
						*(pTrackedObjectData + Y_LOWER_RIGHT_OFFSET) = trackedLineCount;
738
						*(pTrackedObjectData + Y_LOWER_RIGHT_OFFSET) = trackedLineCount;
739
						
739
						
740
						/* set a flag indicating that that color run is part of another
740
						/* set a flag indicating that that color run is part of another
741
						object and thus doesn't need to be added as a new entry into the
741
						object and thus doesn't need to be added as a new entry into the
742
						tracking table */
742
						tracking table */
743
						colorConnected = TRUE;
743
						colorConnected = TRUE;
744
						break;
744
						break;
745
					}
745
					}
746
				}
746
				}
747
                
747
                
748
                /* go to the next object */
748
                /* go to the next object */
749
                pTrackedObjectData += SIZE_OF_TRACKED_OBJECT;
749
                pTrackedObjectData += SIZE_OF_TRACKED_OBJECT;
750
			}
750
			}
751
			
751
			
752
			if (colorConnected == FALSE)
752
			if (colorConnected == FALSE)
753
			{
753
			{
754
				/* a new entry needs to be made to the tracking table, since we have
754
				/* a new entry needs to be made to the tracking table, since we have
755
				a run-length with a color, and it isn't connected to anything...but we
755
				a run-length with a color, and it isn't connected to anything...but we
756
				can only do this if there is space left in the trackedObject table */
756
				can only do this if there is space left in the trackedObject table */
757
				if (numCurrTrackedObjects < MAX_TRACKED_OBJECTS)
757
				if (numCurrTrackedObjects < MAX_TRACKED_OBJECTS)
758
				{                
758
				{                
759
                    /* space is available...add the object...but first we need to find an
759
                    /* space is available...add the object...but first we need to find an
760
                    invalid object in the object tracking table */
760
                    invalid object in the object tracking table */
761
                    pTrackedObjectData = (unsigned char *)pCurrentTrackedObjectTable;
761
                    pTrackedObjectData = (unsigned char *)pCurrentTrackedObjectTable;
762
                    for (i=0; i<MAX_TRACKED_OBJECTS; i++)
762
                    for (i=0; i<MAX_TRACKED_OBJECTS; i++)
763
                    {
763
                    {
764
                        if ( *(pTrackedObjectData + VALID_OBJECT_OFFSET) == FALSE)  break;
764
                        if ( *(pTrackedObjectData + VALID_OBJECT_OFFSET) == FALSE)  break;
765
                        
765
                        
766
                        /* if we haven't broken above, then the object must have been valid...
766
                        /* if we haven't broken above, then the object must have been valid...
767
                        go ahead and move the pointer to the next object to check it */
767
                        go ahead and move the pointer to the next object to check it */
768
                        pTrackedObjectData += SIZE_OF_TRACKED_OBJECT;
768
                        pTrackedObjectData += SIZE_OF_TRACKED_OBJECT;
769
                    }
769
                    }
770
                    
770
                    
771
					
771
					
772
					/* now that we have a pointer to the tracked object to be updated, update all
772
					/* now that we have a pointer to the tracked object to be updated, update all
773
					the fields */
773
					the fields */
774
					*(pTrackedObjectData + COLOR_OFFSET)                = currColor;			/* color */
774
					*(pTrackedObjectData + COLOR_OFFSET)                = currColor;			/* color */
775
					*(pTrackedObjectData + LAST_LINE_X_START_OFFSET)    = currPixelRunStart; 	/* lastLineXStart */
775
					*(pTrackedObjectData + LAST_LINE_X_START_OFFSET)    = currPixelRunStart; 	/* lastLineXStart */
776
					*(pTrackedObjectData + LAST_LINE_X_FINISH_OFFSET)   = currPixelRunFinish;	/* lastLineXFinish */
776
					*(pTrackedObjectData + LAST_LINE_X_FINISH_OFFSET)   = currPixelRunFinish;	/* lastLineXFinish */
777
					*(pTrackedObjectData + X_UPPER_LEFT_OFFSET)         = currPixelRunStart;	/* x_upperLeft */
777
					*(pTrackedObjectData + X_UPPER_LEFT_OFFSET)         = currPixelRunStart;	/* x_upperLeft */
778
					*(pTrackedObjectData + Y_UPPER_LEFT_OFFSET)         = trackedLineCount;	/* y_upperLeft */
778
					*(pTrackedObjectData + Y_UPPER_LEFT_OFFSET)         = trackedLineCount;	/* y_upperLeft */
779
					*(pTrackedObjectData + X_LOWER_RIGHT_OFFSET)        = currPixelRunFinish;	/* x_lowerRight */
779
					*(pTrackedObjectData + X_LOWER_RIGHT_OFFSET)        = currPixelRunFinish;	/* x_lowerRight */
780
					*(pTrackedObjectData + Y_LOWER_RIGHT_OFFSET)        = trackedLineCount;	/* y_lowerRight */
780
					*(pTrackedObjectData + Y_LOWER_RIGHT_OFFSET)        = trackedLineCount;	/* y_lowerRight */
781
                    *(pTrackedObjectData + VALID_OBJECT_OFFSET)         = TRUE;                /* objectValid flag */
781
                    *(pTrackedObjectData + VALID_OBJECT_OFFSET)         = TRUE;                /* objectValid flag */
782
						
782
						
783
					numCurrTrackedObjects++;
783
					numCurrTrackedObjects++;
784
				}
784
				}
785
			}
785
			}
786
            
786
            
787
            /* move the pointer to the beginning of the next tracked object */
787
            /* move the pointer to the beginning of the next tracked object */
788
            pTrackedObjectData += SIZE_OF_TRACKED_OBJECT;
788
            pTrackedObjectData += SIZE_OF_TRACKED_OBJECT;
789
		}
789
		}
790
	} while(currPixelRunFinish < ACTUAL_NUM_PIXELS_IN_A_LINE);
790
	} while(currPixelRunFinish < ACTUAL_NUM_PIXELS_IN_A_LINE);
791
}
791
}
792
 
792