/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* 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: camera_task.c$
* $Version : 1.0$
* $Date    : April-29-2009$
*
* Comments:
*
*   This file is the main file for filesystem demo. Note that this example
*   is a multi tasking example and needs an operating system to run. This 
*   means that customers who are not using MQX should change the operating system
*   dependent code. An attempt has been made to comment out the code
*   however, a programmer must review all lines of code to ensure that
*   it correctly compiles with their libraries of operating system and
*   targetcompiler. This program has been compiled and tested for ARC AA3
*   processor with MQX real time operating system.
*
*END************************************************************************/


//#include "MFS_USB.h"


#include <string.h>
#include <usb.h>
#include <mqx_dll.h>
#include "defines.h"

#include <hostapi.h>
#include <mqx_arc.h>
#include <host_ch9.h>
#include <host_common.h>
#include <usb_desc.h>
#include <host_dev_list.h>
#include <usb_mass_bo.h>
#include <usb_hub_device.h>

#include "usb_task.h"
#include "usb_file.h"

void camera_task(uint_32 param);
void Camera_Init();
uint_8 snapShot();

extern MUTEX_STRUCT   cam_mutex;

FILE_PTR            uart1_ptr;



extern unsigned char data_mcf5225x_jpg[];
//extern unsigned char data_mcf5225x_jpg_temp[];

//pin connection
//Cable - Pin Number
//------------------
//Green  |   9
//Yellow |   11
//Black  |   37
//Red    |   40

/* Commands for Camera C328R */

const uint_8 SyncCmd[] = {0xAA, 0x0D, 0x00, 0x00, 0x00, 0x00};
const uint_8 SetResCmd[] = {0xAA, 0x01, 0x00, 0x05, 0x03, 0x07};
const uint_8 SetPckSizeCmd[] = {0xAA, 0x06, 0x08, 0x00, 0x02, 0x00};
const uint_8 GetPictureCmd[] = {0xAA, 0x04, 0x05, 0x00, 0x00, 0x00};
const uint_8 EndCmd[] = {0xAA, 0x0E, 0x00, 0x00, 0xF0, 0xF0};


const uint_8 ResetCmd[] = {0xAA,0x08,0x00,0x00,0x00,0xFF};

uint_8 AckCmd[] = {0xAA, 0x0E, 0x0D, 0x00, 0x00, 0x00};
uint_8 ACKIdCmd[] = {0xAA, 0x0E, 0x00, 0x00, 0x00, 0x00};

//const uint_8 SetBaudrateCmd[] = {0xAA, 0x07, 0x2F, 0x01, 0x00, 0x00};		//38400
//const uint_8 SetBaudrateCmd[] = {0xAA, 0x07, 0x1F, 0x01, 0x00, 0x00};		//57600
const uint_8 SetBaudrateCmd[] = {0xAA, 0x07, 0x0F, 0x01, 0x00, 0x00};		//115200

/********************************/

/* Global Variables */

uint_32 Baudrate;
boolean availableData = FALSE;
uint_16 RxCounter;
uint_16 ImageSize;
uint_16 FrameCounter;
uint_16 LastFrame;
uint_16 IDindex;
uint_16 JPGIndex;
uint_16 CopyIndex;
uint_8 *DestPtr;
uint_8 *OrigPtr;

//uint_8 data_mcf5225x_jpg[4600];
uint_8 recvBuffer[512];
uint_8 cmdBuffer[6];

/********************************/

void Camera_Init()
{
	uint_16 Delay = 0;
	uint_32 Tries = 0;
    
	// Open the the UART1 - ittyb: in interrupt mode.
	//uart1_ptr = fopen("ittya:", 0x00);
	//uart1_ptr = fopen("ittyb:", 0x00);
	uart1_ptr = fopen("ittyc:", 0x00);
	
	
	Baudrate = 14400;
	ioctl(uart1_ptr,IO_IOCTL_SERIAL_SET_BAUD,&Baudrate);
//	ioctl(uart1_ptr,IO_IOCTL_SERIAL_GET_BAUD,&Baudrate);
    
	availableData = FALSE;
	RxCounter = 0;

	recvBuffer[0] = 0;
	recvBuffer[1] = 0;
	recvBuffer[2] = 0;


	/////////////Synchronization process///////////////////
	while(1)
	{
		ioctl(uart1_ptr, IO_IOCTL_CHAR_AVAIL, &availableData);
		if(availableData == TRUE)
		{
			availableData = FALSE;
			RxCounter++;
		}

		if(!RxCounter)
		{
			_io_write(uart1_ptr, (pointer)&SyncCmd[0], sizeof(SyncCmd));

			while(--Delay)
			{
			}
			
			Tries = 200000;
		}
		else
		{
			if(RxCounter == 12)
			{
				_io_read(uart1_ptr, &recvBuffer[0], 12);
				
				if(recvBuffer[0] == 0xAA)
				{
					if((recvBuffer[1] == 0x0E) && (recvBuffer[2] == 0x0D))
					{
						break;
					}
				}
				else
				{
					recvBuffer[0] = 0;
					recvBuffer[1] = 0;
					recvBuffer[2] = 0;
		
					availableData = FALSE;
					RxCounter = 0;
					
					Baudrate = 115200;
					ioctl(uart1_ptr,IO_IOCTL_SERIAL_SET_BAUD,&Baudrate);
				}
			}
			
			if(!(--Tries))
			{
				_io_read(uart1_ptr, &recvBuffer[0], 2);
				
				if(recvBuffer[0] == 0xAA)
				{
					if(recvBuffer[1] == 0x0F)
					{
					 	_io_write(uart1_ptr, (pointer)&ResetCmd[0], sizeof(ResetCmd));

						while(--Delay)
						{
						}
						
						Baudrate = 14400;
						ioctl(uart1_ptr,IO_IOCTL_SERIAL_SET_BAUD,&Baudrate);
					}
				}
				recvBuffer[0] = 0;
				recvBuffer[1] = 0;
				recvBuffer[2] = 0;

				availableData = FALSE;
				RxCounter = 0;
			}
		}
	}

	AckCmd[3] = recvBuffer[3];
	_io_write(uart1_ptr, (pointer)&AckCmd[0], sizeof(AckCmd));
	//////////////////////////////////////////////////////


	availableData = FALSE;
	RxCounter = 0;
	_io_write(uart1_ptr, (pointer)&SetResCmd[0], sizeof(SetResCmd));
	_io_read(uart1_ptr, &recvBuffer[0], 6);

	availableData = FALSE;
	RxCounter = 0;
	_io_write(uart1_ptr, (pointer)&SetPckSizeCmd[0], sizeof(SetPckSizeCmd));
	_io_read(uart1_ptr, &recvBuffer[0], 6);


	availableData = FALSE;
	RxCounter = 0;
	_io_write(uart1_ptr, (pointer)&SetBaudrateCmd[0], sizeof(SetBaudrateCmd));
	_io_read(uart1_ptr, &recvBuffer[0], 6);
	
	availableData = FALSE;
	RxCounter = 0;	
	Baudrate = 115200;
	ioctl(uart1_ptr,IO_IOCTL_SERIAL_SET_BAUD,&Baudrate);
}

uint_8 snapShot()
{
	uint_16 Delay = 0;

	availableData = FALSE;
	RxCounter = 0;

	_io_write(uart1_ptr, (pointer)&GetPictureCmd[0], sizeof(GetPictureCmd));
	_io_read(uart1_ptr, &recvBuffer[0], 12);
	
	ImageSize = (uint_16)recvBuffer[9];
	ImageSize |= (uint_16)(recvBuffer[10] <<8);
	
	FrameCounter = ImageSize / 506;
	LastFrame = ImageSize % 506;
	JPGIndex = 0;
	
	printf("imageSize= %d, imagePackages= %d \n\r", ImageSize, FrameCounter);
	
//	if(ImageSize > sizeof((uint_8)data_mcf5225x_jpg))
	if(ImageSize > 10000)
	{
	 	_io_write(uart1_ptr, (pointer)&EndCmd[0], sizeof(EndCmd));
		return(1);
	}
	
	IDindex = 0;
	while(IDindex < FrameCounter)
	{
		availableData = FALSE;
		RxCounter = 0;
		
		ACKIdCmd[4] = (uint_8)IDindex;
		ACKIdCmd[5] = (uint_8)(IDindex >>8);

		_io_write(uart1_ptr, (pointer)&ACKIdCmd[0], sizeof(ACKIdCmd));
		_io_read(uart1_ptr, &recvBuffer[0], 512);
		
      	OrigPtr = (uint_8 *)&recvBuffer[4];
      	DestPtr = (uint_8 *)&data_mcf5225x_jpg[JPGIndex];
      	for(CopyIndex = 0;CopyIndex < 506;CopyIndex++)
      	{
      		*DestPtr++ = *OrigPtr++;
      	}
      	JPGIndex += 506;
      	IDindex++;
	}
	
	if(LastFrame)
	{
		availableData = FALSE;
		RxCounter = 0;

		ACKIdCmd[4] = (uint_8)IDindex;
		ACKIdCmd[5] = (uint_8)(IDindex >>8);
		
		_io_write(uart1_ptr, (pointer)&ACKIdCmd[0], sizeof(ACKIdCmd));
		_io_read(uart1_ptr, &recvBuffer[0], (LastFrame +6));

	 	OrigPtr = (uint_8 *)&recvBuffer[4];
	 	DestPtr = (uint_8 *)&data_mcf5225x_jpg[JPGIndex];
	 	for(CopyIndex = 0;CopyIndex < LastFrame;CopyIndex++)
	 	{
	 		*DestPtr++ = *OrigPtr++;
	 	}		
	}
	
 	_io_write(uart1_ptr, (pointer)&EndCmd[0], sizeof(EndCmd));
	
	printf("Finished\n\r");
	
	return(0);
}

/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : camera_task
* Returned Value : None
* Comments       :
*     
*END*--------------------------------------------------------------------*/


void camera_task(uint_32 param)
{
	_time_delay(2000);
	printf("Starting my camera task\n\r");

	Camera_Init();

	printf("Ready..\n\r");
	
	_time_delay(200);

	while (1)
	{
		if (_mutex_lock(&cam_mutex) != MQX_OK) 
		{
         	printf("Mutex lock failed in camera.\n");
      	}
		if(snapShot())
		{
			printf("Error\n\r");
			_time_delay(2000);
		}
	    _mutex_unlock(&cam_mutex);
	}
}

/* EOF */
	