James Stephanick
Published © MIT

Directional Motion-Detecting USB Web Cam Using a FRDM-K82F

Use simple image processing and an image sensor to detect whether a person enters or leaves a room.

AdvancedFull instructions provided20 hours3,665
Directional Motion-Detecting USB Web Cam Using a FRDM-K82F

Things used in this project

Hardware components

Kinetis Freedom Board with FlexIO
NXP Kinetis Freedom Board with FlexIO
×1
UV7670 Camera Module
×1

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Code

camera.c -- NXP example code hacked

C/C++
Taking NXP's SDK code, modifying it, and adding some image processing to do directional motion detection
/**HEADER********************************************************************
* 
* Copyright (c) 2004-2010, 2014-2015 Freescale Semiconductor;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: virtual_camera.c$
* $Version : 
* $Date    : 
*
* Comments:
*        The file contains Macro's and functions required for Virtual Camera
*        Loopback Application
*
*****************************************************************************/

/******************************************************************************
 * Includes
 *****************************************************************************/
#include "usb_device_config.h"
#include "usb.h"
#include "usb_device_stack_interface.h"

#include "usb_descriptor.h"
#include "camera.h"   /* Virtual camera Application Header File */
#include "usb_request.h"

#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_SDK)
#include "fsl_device_registers.h"
#include "fsl_clock_manager.h"
#include "board.h"
#include "fsl_debug_console.h"
#include "fsl_port_hal.h"

#include <stdio.h>
#include <stdlib.h>

#include "flexio_ov7670.h"
#endif

/*****************************************************************************
 * Constant and Macro's - None
 *****************************************************************************/
 #define MAIN_TASK       10
/*****************************************************************************
 * Global Functions Prototypes
 *****************************************************************************/
void APP_init(void);
void USB_Prepare_Data(void);
extern void Main_Task(uint32_t param);

/****************************************************************************
 * Global Variables
 ****************************************************************************/
extern usb_desc_request_notify_struct_t  desc_callback;
virtual_camera_struct_t                  virtual_camera;

#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_MQX)
extern void Main_Task(uint32_t param);
#define MAIN_TASK       10
TASK_TEMPLATE_STRUCT  MQX_template_list[] =
{
   { MAIN_TASK, Main_Task, 2*3000L, 7L, "Main", MQX_AUTO_START_TASK, 0, 0},
   { 0L, 0L, 0L, 0L, 0L, 0L, 0, 0}
};
#endif
/*****************************************************************************
 * Local Types - None
 *****************************************************************************/

/*****************************************************************************
 * Local Functions Prototypes
 *****************************************************************************/

/*****************************************************************************
 * Local Variables
 *****************************************************************************/

/*****************************************************************************
 * Local Functions
 *****************************************************************************/
 /******************************************************************************
 *
 *   @name        USB_Prepare_Data
 *
 *   @brief       This function prepares data to send
 *
 *   @param       None
 *
 *   @return      None
 *****************************************************************************
 * This function prepare data before sending
 *****************************************************************************/
volatile int buf_indicator=0;

void USB_Prepare_Data(void)
{
    uint32_t                             frame_interval = 0;
    uint32_t                             buffer_count = 0;
    uint32_t                             send_data = 0;
    video_mjpeg_payload_header_struct_t* video_mjpeg_header_ptr = NULL;
    uint16_t                             k;
    uint8_t                              j;
    uint8_t                              format_index = 0;
    
    if (virtual_camera.still_image_transmit > 0)
    {
        format_index = virtual_camera.still_commit_struct.bFormatIndex;
        frame_interval = virtual_camera.commit_struct.dwFrameInterval;
    }
    else
    {
        format_index = virtual_camera.commit_struct.bFormatIndex;
        frame_interval = virtual_camera.commit_struct.dwFrameInterval;
    }

    video_mjpeg_header_ptr = (video_mjpeg_payload_header_struct_t*)virtual_camera.image_header;
    virtual_camera.image_buffer = virtual_camera.image_header;

    if (VS_FORMAT_UNCOMPRESSED_DESC_INDEX == format_index)
    {
        if (virtual_camera.image_position[format_index-1] < OV7670_FRAME_BYTES)
        {
            virtual_camera.image_buffer = (uint8_t *)&u8CameraFrameBuffer[virtual_camera.full_buffer_index][virtual_camera.image_position[format_index-1] - HEADER_PACKET_SIZE + 32];
            video_mjpeg_header_ptr = (video_mjpeg_payload_header_struct_t*)virtual_camera.image_buffer;
        }
    }
    
    video_mjpeg_header_ptr->bHeaderLength = HEADER_PACKET_SIZE;
    for (j = 0;j < sizeof(video_mjpeg_header_ptr->bSourceClockReference);j++)
    {
        video_mjpeg_header_ptr->bSourceClockReference[j] = 0;
    }
    video_mjpeg_header_ptr->HeaderInfo.bmHeaderInfo = 0;
    video_mjpeg_header_ptr->dwPresentationTime = 0;
    video_mjpeg_header_ptr->HeaderInfo.bitMap.frame_id = virtual_camera.frame_id;
    video_mjpeg_header_ptr->HeaderInfo.bitMap.end_of_frame = 0;
    video_mjpeg_header_ptr->HeaderInfo.bitMap.still_image = virtual_camera.still_image_transmit;
    
    virtual_camera.frame_progress += 10000;
    if (virtual_camera.frame_sent > 0)
    {
        virtual_camera.frame_send_length = HEADER_PACKET_SIZE;
        if (virtual_camera.frame_progress < frame_interval)
        {
            return;
        }
        else
        {
            video_mjpeg_header_ptr->HeaderInfo.bitMap.end_of_frame = 1;
            virtual_camera.frame_id = 1 - virtual_camera.frame_id;
            virtual_camera.frame_sent = 0;
            virtual_camera.frame_progress = 0;
            
            virtual_camera.image_position[format_index-1] = 0;
            
            if(virtual_camera.still_image_transmit > 0)
            {
                virtual_camera.still_image_transmit = 0;
                virtual_camera.transmit_type = 0;
            }
            
            if ((virtual_camera.transmit_type > 0) && (virtual_camera.transmit_type < 3))
            {
                virtual_camera.still_image_transmit = 1;
            }
            return;
        }
    }
  
    if (VS_FORMAT_UNCOMPRESSED_DESC_INDEX == format_index)
    {
        if (virtual_camera.image_position[format_index-1] < OV7670_FRAME_BYTES)
        {
            send_data = OV7670_FRAME_BYTES - virtual_camera.image_position[format_index-1];
            if (send_data > MAX_PAYLOAD_DATA_SIZE)
            {
               send_data = MAX_PAYLOAD_DATA_SIZE;
            }
//            for (int i = 0;i < send_data;i++)
//            {                
//                virtual_camera.image_buffer[HEADER_PACKET_SIZE + i] = camera_frame_buffer[virtual_camera.image_position[format_index-1] + i];
//            }
            virtual_camera.image_position[format_index-1] += send_data;
            
            if (virtual_camera.image_position[format_index-1] >= OV7670_FRAME_BYTES)
            {
            	//modify_image( virtual_camera.full_buffer_index );
                flexio_ov7670_start_capture(virtual_camera.full_buffer_index+1);
                virtual_camera.full_buffer_index = 1 - virtual_camera.full_buffer_index;
            	//buf_indicator=virtual_camera.full_buffer_index+1;
                if (virtual_camera.frame_progress < frame_interval)
                {
                    virtual_camera.frame_sent = 1;
                }
                else
                {
                    video_mjpeg_header_ptr->HeaderInfo.bitMap.end_of_frame = 1;
                    virtual_camera.frame_id = 1 - virtual_camera.frame_id;
                    virtual_camera.frame_sent = 0;
                    virtual_camera.frame_progress = 0;

                    virtual_camera.image_position[format_index-1] = 0;

                    if(virtual_camera.still_image_transmit > 0)
                    {
                        virtual_camera.still_image_transmit = 0;
                        virtual_camera.transmit_type = 0;
                    }

                    if ((virtual_camera.transmit_type > 0) && (virtual_camera.transmit_type < 3))
                    {
                        virtual_camera.still_image_transmit = 1;
                    }
                }
            }
        }
    }
    virtual_camera.frame_send_length = HEADER_PACKET_SIZE + send_data;
}

/******************************************************************************
 * 
 *    @name        USB_App_Param_Callback
 *
 *    @brief       This function handles the callback for Get/Set report req  
 *                  
 *    @param       request  :  request type
 *    @param       value    :  give report type and id
 *    @param       data     :  pointer to the data 
 *    @param       size     :  size of the transfer
 *
 *    @return      status
 *                  USB_OK  :  if successful
 *                  else return error
 *
 *****************************************************************************/
 uint8_t USB_App_Param_Callback
 (
    uint8_t request, 
    uint16_t value, 
    uint8_t ** data, 
    uint32_t* size,
    void* arg
) 
{
    uint8_t error = USB_OK;

    if ((request == USB_DEV_EVENT_SEND_COMPLETE) && (value == USB_VIDEO_ISO_REQ_VAL_INVALID))
    {
        virtual_camera.is_sending = (uint8_t)FALSE;
        
        if (NULL != arg)
        {
            if (((uint8_t)TRUE == virtual_camera.attached) && ((uint8_t)TRUE == virtual_camera.start_send))
            {
                if ((uint8_t)FALSE == virtual_camera.is_sending)
                {
                    virtual_camera.is_sending = (uint8_t)TRUE;
                    USB_Prepare_Data();
                    (void)USB_Class_Video_Send_Data(virtual_camera.video_handle,VIDEO_ISO_ENDPOINT,virtual_camera.image_buffer,virtual_camera.frame_send_length);
                }
            }
        }
        return error;
    }

    error = USB_Class_Get_feature(virtual_camera.video_handle, value, data, size);
    if (error == USBERR_INVALID_REQ_TYPE)
    {
        error = USB_Class_Set_feature(virtual_camera.video_handle, value, data, size);
    }

    return error; 
}   

/******************************************************************************
 * 
 *    @name        USB_App_Callback
 *    
 *    @brief       This function handles the callback  
 *                  
 *    @param       handle : handle to Identify the controller
 *    @param       event_type : value of the event
 *    @param       val : gives the configuration value 
 * 
 *    @return      None
 *
 *****************************************************************************/
void USB_App_Callback(uint8_t event_type, void* val,void* arg) 
{
    uint16_t interface_setting;
    uint8_t interface_alternate;
    uint8_t interface_num;

    if ((event_type == USB_DEV_EVENT_BUS_RESET) || (event_type == USB_DEV_EVENT_CONFIG_CHANGED))
    {
        virtual_camera.attached=FALSE;
        if (USB_OK == USB_Class_Video_Get_Speed(virtual_camera.video_handle, &virtual_camera.app_speed))
        {
            USB_Desc_Set_Speed(virtual_camera.video_handle, virtual_camera.app_speed);
        }
    }
    else if (event_type == USB_DEV_EVENT_ENUM_COMPLETE) 
    {
        virtual_camera.attached=TRUE; 
        USB_PRINTF("USB camera is working ... \r\n");
    }
    else if (event_type == USB_DEV_EVENT_ERROR)
    {
        /* add user code for error handling */
    }
    else if (event_type == USB_DEV_EVENT_INTERFACE_CHANGED)
    {
        interface_setting = *((uint16_t*)val);
        interface_alternate = (uint8_t)(interface_setting&0x00FF);
        interface_num = (uint8_t)((interface_setting>>8)&0x00FF);
        
        if (VIDEO_STREAM_IF_INDEX == interface_num)
        {
            if (0 != interface_alternate)
            {
                virtual_camera.start_send = TRUE;
                if (((uint8_t)TRUE == virtual_camera.attached) && ((uint8_t)TRUE == virtual_camera.start_send))
                {
                    if ((uint8_t)FALSE == virtual_camera.is_sending)
                    {
                        virtual_camera.is_sending = (uint8_t)TRUE;
                        virtual_camera.frame_sent = 0;
                        virtual_camera.frame_progress = 0;
                        USB_Prepare_Data();
                        (void)USB_Class_Video_Send_Data(virtual_camera.video_handle,VIDEO_ISO_ENDPOINT,virtual_camera.image_buffer,virtual_camera.frame_send_length);
                    }
                }
            }
            else
            {
                virtual_camera.transmit_type = 0;
                virtual_camera.start_send = (uint8_t)FALSE;
                if ((uint8_t)TRUE == virtual_camera.is_sending)
                {
                    virtual_camera.is_sending = (uint8_t)FALSE;
                    (void)USB_Class_Video_Cancel(virtual_camera.video_handle,VIDEO_ISO_ENDPOINT,USB_SEND);
                }
            }
        }
    }
  
}



 /******************************************************************************
 *
 *   @name        APP_init
 *
 *   @brief       This function is the entry for the Virtual camera application
 *
 *   @param       None
 *
 *   @return      None
 *****************************************************************************
 * This function starts the virtual camera application
 *****************************************************************************/

void APP_init(void)
{
    video_config_struct_t video_config;
    video_config.video_application_callback.callback = USB_App_Callback;
    video_config.video_application_callback.arg = &virtual_camera.video_handle;
    video_config.class_specific_callback.callback = USB_App_Param_Callback;
    video_config.class_specific_callback.arg = &virtual_camera.video_handle;
    video_config.board_init_callback.callback = NULL;
    video_config.board_init_callback.arg = NULL;
    video_config.desc_callback_ptr = &desc_callback;

    OS_Mem_zero((uint8_t*)&virtual_camera.probe_struct, sizeof(virtual_camera.probe_struct));
    OS_Mem_zero((uint8_t*)&virtual_camera.commit_struct, sizeof(virtual_camera.commit_struct));
    OS_Mem_zero((uint8_t*)&virtual_camera.still_probe_struct, sizeof(virtual_camera.still_probe_struct));
    OS_Mem_zero((uint8_t*)&virtual_camera.still_commit_struct, sizeof(virtual_camera.still_commit_struct));
    
    virtual_camera.probe_struct.bFormatIndex = VS_FORMAT_UNCOMPRESSED_DESC_INDEX;
    virtual_camera.probe_struct.bFrameIndex = 1;
    virtual_camera.probe_struct.dwFrameInterval = 0x1E8480;
    virtual_camera.probe_struct.dwMaxPayloadTransferSize = VIDEO_ISO_ENDPOINT_PACKET_SIZE;
    virtual_camera.probe_struct.dwMaxVideoFrameSize = 0x025800;
    
    virtual_camera.commit_struct.bFormatIndex = VS_FORMAT_UNCOMPRESSED_DESC_INDEX;
    virtual_camera.commit_struct.bFrameIndex = 1;
    virtual_camera.commit_struct.dwFrameInterval = 0x1E8480;
    virtual_camera.commit_struct.dwMaxPayloadTransferSize = VIDEO_ISO_ENDPOINT_PACKET_SIZE;
    virtual_camera.commit_struct.dwMaxVideoFrameSize = 0x025800;
    
    virtual_camera.probe_length = 26;
    virtual_camera.commit_length = 26;
    virtual_camera.probe_info = 0x03;
    virtual_camera.commit_info = 0x03;
    virtual_camera.frame_progress = 0;
    
    virtual_camera.still_probe_struct.bFormatIndex = VS_FORMAT_UNCOMPRESSED_DESC_INDEX;
    virtual_camera.still_probe_struct.bFrameIndex = 1;
    virtual_camera.still_probe_struct.bCompressionIndex = 1;
    virtual_camera.still_probe_struct.dwMaxPayloadTransferSize = VIDEO_ISO_ENDPOINT_PACKET_SIZE;
    virtual_camera.still_probe_struct.dwMaxVideoFrameSize = 0x025800;
    
    virtual_camera.still_commit_struct.bFormatIndex = VS_FORMAT_UNCOMPRESSED_DESC_INDEX;
    virtual_camera.still_commit_struct.bFrameIndex = 1;
    virtual_camera.still_commit_struct.bCompressionIndex = 1;
    virtual_camera.still_commit_struct.dwMaxPayloadTransferSize = VIDEO_ISO_ENDPOINT_PACKET_SIZE;
    virtual_camera.still_commit_struct.dwMaxVideoFrameSize = 0x025800;

    virtual_camera.still_probe_length = 26;
    virtual_camera.still_commit_length = 26;
    virtual_camera.still_probe_info = 0x03;
    virtual_camera.still_commit_info = 0x03;
    virtual_camera.transmit_type = 0;
    virtual_camera.full_buffer_index = 1;

    extern void flexio_ov7670_init();
    /* Initialize the USB interface */
    USB_Class_Video_Init(CONTROLLER_ID, &video_config, &virtual_camera.video_handle);
    flexio_ov7670_init();
}

/******************************************************************************
 *
 *    @name        APP_task
 *
 *    @brief       This function use to send data
 *
 *    @param       None
 *
 *    @return      None
 *
 *****************************************************************************
 *
 *****************************************************************************/

/*
 * Array indexing ar[row][col] also known as ar[y][x]
 *
 */
#define add_color(a) ( ((a&0xf800)>>11) + ((a&0x03e0)>>5) + (a&0x1f) )
#define DPTH 6
#define SLC 4
#define HOLD_CNT 10;

uint32_t avg[DPTH][SLC];
int gap[SLC];
int pos_gap[SLC];
int show_decrease_cnt=0;
int show_increase_cnt=0;

void show_motion( volatile uint16_t ar[120][160], int dir_flag )
{
	int x,y;

	// draw a horizontal line without arrow head
	for ( x=40; x<120; x++)
		for ( y=55; y<65; y++)
			ar[y][x] = 0xffff;

	// draw arrow head based on direction flag
	if ( dir_flag )
	{
		for ( x=30; x<40; x++)
			for ( y=(90-x); y<(30+x); y++)
				ar[y][x] = 0xffff;
	}
	else
	{
		for ( x=115; x<125; x++)
			for ( y=(60-(125-x)); y<(60+(125-x)); y++)
				ar[y][x] = 0xffff;
	}
}

void motion_algorithm( volatile uint16_t ar[120][160] )
{
	uint32_t i,j,k,l,z;
	uint32_t dcnt,flag_increase=TRUE,flag_decrease=TRUE;
	int last_gap;
	static uint32_t prior_increase=FALSE, prior_decrease=FALSE;

	// age the last average
	for( i=(DPTH-1); i>0; i--)
	{
		for(j=0; j<SLC; j++)
		{
			avg[i][j]=avg[i-1][j];
		}
	}

	avg[0][0]=0;
	avg[0][1]=0;
	avg[0][2]=0;
	avg[0][3]=0;

	for( i=0,j=40,k=80,l=120; i<40; i++, j++, k++, l++ )
	{
		for(z=0; z<120; z++ )
		{
			avg[0][0] += add_color( ar[z][i] );
			avg[0][1] += add_color( ar[z][j] );
			avg[0][2] += add_color( ar[z][k] );
			avg[0][3] += add_color( ar[z][l] );
		}
	}

	for(i=0;i<SLC;i++)
	{
		avg[0][i] = avg[0][i]/4800;
	}

	// for each slice, find the biggest gap
	for(i=0;i<SLC;i++)
	{
		int av,gp;

		gap[i]=0;
		pos_gap[i]=-1;
		for(j=0,av=0;j<DPTH;j++) av+=avg[j][i];
		av = av/DPTH;
		for(j=0;j<DPTH;j++)
		{
			gp = av-avg[j][i];
			if (gp < 0 ) gp = -gp;
			if ( gp > 5 )
			{
				if (gp > gap[i]) { gap[i]=gp; pos_gap[i]=j; }
			}
		}
	}

	dcnt=0;
	flag_increase=TRUE;
	flag_decrease=TRUE;
	last_gap = -1;
	for(i=0;i<SLC;i++)
	{
		if ( pos_gap[i] != -1)
		{
			dcnt++;
			if ( last_gap == -1 )
			{
				last_gap = pos_gap[i];
			}
			else
			{
				if ( pos_gap[i] > last_gap )
				{
					last_gap = pos_gap[i];
					flag_decrease = FALSE;
				}
				else if ( pos_gap[i] < last_gap )
				{
					last_gap = pos_gap[i];
					flag_increase = FALSE;
				}
			}
		}
	}

	if ( dcnt > 1 )
	{
		// throw out the case that the moving object stopped
		if ( flag_decrease && flag_increase ) { flag_decrease=FALSE; flag_increase=FALSE; };

		if ( flag_decrease || flag_increase)
		{
			if ( prior_decrease && flag_decrease )
			{
				if ( show_decrease_cnt == 0 ) printf("\Left to Right movement\n");
				show_decrease_cnt = HOLD_CNT;
			}
			if ( prior_increase && flag_increase )
			{
				if ( show_increase_cnt == 0 ) printf("\nRight to Left movement\n");
				show_increase_cnt = HOLD_CNT;
			}

//			printf("----------------------\n");
//			printf("A: %d/%d/%d/%d\n",avg[0][0],avg[0][1],avg[0][2],avg[0][3]);
//			printf("B: %d/%d/%d/%d\n",avg[1][0],avg[1][1],avg[1][2],avg[1][3]);
//			printf("C: %d/%d/%d/%d\n",avg[2][0],avg[2][1],avg[2][2],avg[2][3]);
//			printf("D: %d/%d/%d/%d\n",avg[3][0],avg[3][1],avg[3][2],avg[3][3]);
//			printf("E: %d/%d/%d/%d\n",avg[4][0],avg[4][1],avg[4][2],avg[4][3]);
//			printf("F: %d/%d/%d/%d\n",avg[5][0],avg[5][1],avg[5][2],avg[5][3]);
//			printf("Pos %d/%d/%d/%d   Gap %d/%d/%d/%d\n",pos_gap[0],pos_gap[1],pos_gap[2],pos_gap[3],gap[0],gap[1],gap[2],gap[3]);
		}
	}

	prior_increase = flag_increase;
	prior_decrease = flag_decrease;

	if ( show_decrease_cnt > 0 ) { show_motion( (void *)ar, 0 ); show_decrease_cnt--; }
	if ( show_increase_cnt > 0 ) { show_motion( (void *)ar, 1 ); show_increase_cnt--; }
}


void APP_task(void)
{
	int buf;
	int i,j;
	int pending_request_flag = 0;
	int pending_request_buf = 0;

	while(1)
	{
		/*
		 * The 'portb_callback' function of the camera is where we think the camera indicates that an image
		 * capture has completed.  It let's us know this information through the global variable 'buf_indicator'.
		 * '1' indicates buffer 0 is ready, '2' indicates buffer 1 is ready, and '0' means nothing happening.
		 *
		 * When a PC's program is grabbing video (is_sending flag TRUE), the USB initiates image capture.
		 * If not (is_sending flag FALSE), we initiate image capture.
		 */
		if ( buf_indicator  )
		{
			// buf_indicator flips between 1 and 2.  Adjust value to line up with 0 referenced buffer
			buf=buf_indicator-1;

			// USB capture indicated by '.', capture initiated by our routine is ':'
			if ( pending_request_flag ) printf(":"); else printf(".");

			motion_algorithm( (void *)&(u8CameraFrameBuffer[buf][32]) );

			buf_indicator=0;
			pending_request_flag= 0;
		}
		else
		{
			if (!virtual_camera.is_sending && !pending_request_flag )
			{
				// since USB is not requesting image capture, let's do it ourselves
				pending_request_flag = 1;
				flexio_ov7670_start_capture( pending_request_buf+1 );
				pending_request_buf = 1-pending_request_buf;
			}
			else
			{
				OSA_TimeDelay(5); /* 5ms */
			}
		}
	}
}


#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_MQX)

/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : Main_Task
* Returned Value : None
* Comments       :
*     First function called.  Calls Test_App
*     callback functions.
* 
*END*--------------------------------------------------------------------*/
void Main_Task( uint32_t param )
{   
    UNUSED_ARGUMENT (param)
    APP_init();
}
#endif

#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_SDK)

#if defined(FSL_RTOS_MQX)
void Main_Task(uint32_t param);
TASK_TEMPLATE_STRUCT  MQX_template_list[] =
{
   { 1L,     Main_Task,      2500L,  MQX_MAIN_TASK_PRIORITY, "Main",      MQX_AUTO_START_TASK},
   { 0L,     0L,             0L,    0L, 0L,          0L }
};
#endif


#if (USE_RTOS)
static void Task_Start(void *arg)
{
    APP_init();
    for (;; )
    {
        APP_task();
    }
}
#endif

#if defined(FSL_RTOS_MQX)
void Main_Task(uint32_t param)
#else

#if defined(__CC_ARM) || defined(__GNUC__)
int main(void)
#else
void main(void)
#endif

#endif
{
    RCM_MR = 0x03;
    
    OSA_Init();
    hardware_init();
    dbg_uart_init();
    PRINTF("Camera Demo!\r\n\r\n");
    PRINTF("I think this works.\n");

#if !(USE_RTOS)
    APP_init();
#else
    OS_Task_create(Task_Start, NULL, 4L, 1000L, "task_start", NULL);
#endif

    OSA_Start();
#if (!defined(FSL_RTOS_MQX))&(defined(__CC_ARM) || defined(__GNUC__))
    return 1;
#endif
}
#endif

/* EOF */

Credits

James Stephanick

James Stephanick

4 projects • 33 followers

Comments