/*
 * web_cam.c
 *
 *  Created on: 31.3.2010
 *      Author: hudo
 */

#include "web_cam.h"

char ID_sync_cmd[] = { 0xaa, 0x0D, 0x00, 0x00, 0x00, 0x00, };
char ID_ack_cmd[] = { 0xAA, 0x0E, 0x0D, 0x00, 0x00, 0x00,

};

char picture_buff[3000];// buffer pre ulozenie obrazka, ktory je ulozeny v ramke

//RAM FAT
unsigned char pocet_sub = 0; //Pocet suborov v RAM fatke

RAM_FAT_STRUCT rfs[MAX_POCET_SUBOROV]; //Globalna premmena RAM Fat

char subor[] = "To to je test RAM suboroveho systemu";

void form_serial_function2(char *data) {

	if (pocet_sub > 0)
		free(rfs[0].file_pointer);
	pocet_sub = 1;
	strcpy(rfs[0].file_name, "text.txt");
	rfs[0].file_type = (unsigned long) 'text';
	rfs[0].file_size = strlen(data);

	rfs[0].file_pointer = (void *) malloc(rfs[0].file_size);
	strcpy(rfs[0].file_pointer, data);

	if (data[0] == 'u')
		rfs[0].locked = 0;
	else
		rfs[0].locked = 1;

	printf("%s", data);
}

//UART funkcie
void uart_SendBlock(char *data, int size) {
	while (size > 0) {
		size--;
		uart_putc(1, *data);
		(data)++;
	}

}

int _getch(void) {

	if (!uart_present(1))
		return -1;
	else
		return (uart_getc(1) & 0xFF);
}

//
//Funkcia, ktora pravidelne nacitava obrazok a uklada ho do ramky;
void web_kamera_task() {
	uint32 velkost_obr, temp_velkost;
	char CMD_buffer[6], buffer[6];
	int packet;
	for (;;) {

		pocet_sub = 1;
		strcpy(rfs[0].file_name, "obrazok.jpg");
		rfs[0].file_type = (unsigned long) 'jpeg';
		rfs[0].file_pointer = picture_buff;

		printf("\nTASK SLEEP");
		tk_sleep(1000);
		uart_close(0);
		uart_init(0);
		uart_close(1);
		uart_init(1);
		printf("\nTASK running");

		cam_sync();

		//Init
		CMD_buffer[1] = ID_init & 0xff;
		CMD_buffer[0] = ID_init >> 8;
		CMD_buffer[2] = 0x00;
		CMD_buffer[3] = jpeg;
		CMD_buffer[4] = _160na120;
		CMD_buffer[5] = _160na128;
		uart_SendBlock(CMD_buffer, 6);

		printf("\nInicializcia kamery");

		if (uart_RecvBlock(buffer, 6, 1000000)) {
			printf("\n Chyba citania UART - Init");
			continue;
			while (!uart_flush(CONSOLE_UART)) {
			};
		}

		if (test_cmd_ack(buffer, ID_ack_cmd, 3, CMD_buffer[1])) {
			printf("\nChyba: zla odpoved. Ocakvana odpoved ACK");
			printf("\n%#x %#x %#x %#x %#x %#x", buffer[0], buffer[1],
					buffer[2], buffer[3], buffer[4], buffer[5]);
			continue;
		}

		//Set Package size
		CMD_buffer[1] = ID_set_size & 0xff;
		CMD_buffer[0] = ID_set_size >> 8;
		CMD_buffer[2] = 0x08;
		CMD_buffer[3] = size_of_packet;
		CMD_buffer[4] = 0x00;
		CMD_buffer[5] = 0x00;
		uart_SendBlock(CMD_buffer, 6);

		printf("\nSet Package Size");

		if (uart_RecvBlock(buffer, 6, 1000000)) {
			printf("\n Chyba citania UART - Set Package size");
			continue;
		}

		if (test_cmd_ack(buffer, ID_ack_cmd, 3, CMD_buffer[1])) {
			printf("\nChyba: zla odpoved. Ocakvana odpoved ACK");
			printf("\n%#x %#x %#x %#x %#x %#x", buffer[0], buffer[1],
					buffer[2], buffer[3], buffer[4], buffer[5]);
			continue;
		}

		//Get picture
		CMD_buffer[1] = ID_get_pic & 0xff;
		CMD_buffer[0] = ID_get_pic >> 8;
		CMD_buffer[2] = JPEG_prev;
		CMD_buffer[3] = 0x00;
		CMD_buffer[4] = 0x00;
		CMD_buffer[5] = 0x00;
		uart_SendBlock(CMD_buffer, 6);

		printf("\nGet picture");

		if (uart_RecvBlock(buffer, 6, 1000000)) {
			printf("\n Chyba citania UART - Get picture");
			continue;
		}

		if (test_cmd_ack(buffer, ID_ack_cmd, 3, CMD_buffer[1])) {
			printf("\nChyba: zla odpoved. Ocakvana odpoved ACK");
			printf("\n%#x %#x %#x %#x %#x %#x", buffer[0], buffer[1],
					buffer[2], buffer[3], buffer[4], buffer[5]);
			continue;
		}
		tk_sleep(10);
		if (uart_RecvBlock(buffer, 6, 50000000)) {
			printf("\n Chyba citania UART - Get picture - DATA SIZE");
			continue;
		}

		temp_velkost = buffer[5];
		temp_velkost <<= 16;
		velkost_obr = temp_velkost;

		temp_velkost = buffer[4];
		temp_velkost <<= 8;
		velkost_obr += temp_velkost;

		velkost_obr += buffer[3];

		printf("\n Picture Size: %ld", velkost_obr);
		while (!uart_flush(CONSOLE_UART)) {
		};

		//Nacitanie dat:
		printf("\nData");

		temp_velkost = 0;
		ID_ack_cmd[2] = 0x00;
		packet = 0;
		while (temp_velkost < velkost_obr) {
			uart_close(1);
			uart_init(1);

			ID_ack_cmd[4] = packet & 0xff;
			ID_ack_cmd[5] = packet >> 8;
			printf("\nPacket c:%d", packet++);
			while (!uart_flush(CONSOLE_UART)) {
			};

			uart_SendBlock(ID_ack_cmd, 6);

			if (uart_RecvBlock(buffer, 4, 50000000)) {
				printf("\n Chyba citania UART - Data packet hlavicka");
				while (!uart_flush(CONSOLE_UART)) {
				};
				goto kon;
			}

			if (uart_RecvBlock(picture_buff + temp_velkost, buffer[2], 50000000)) {
				uart_close(0);
				uart_init(0);
				printf("\n Chyba citania UART - Data packet data");
				while (!uart_flush(CONSOLE_UART)) {
				};
				goto kon;
			}

			temp_velkost += buffer[2];
			rfs[0].file_size = temp_velkost;

			uart_close(0);
			uart_init(0);
			printf("\n %d / %d byte, PS:%d b", velkost_obr, temp_velkost,
					buffer[2]);
			while (!uart_flush(CONSOLE_UART)) {
			};

			if (uart_RecvBlock(buffer, 2, 50000000))

			{
				uart_close(0);
				uart_init(0);
				printf("\n Chyba citania UART - Data packet pata");
				while (!uart_flush(CONSOLE_UART)) {
				};
				goto kon;
			}

			tk_sleep(10);

		}
		kon:
		/*	uart_close(1);
		 uart_init(1);
		 uart_close(0);
		 uart_init(0);*/

		ID_ack_cmd[2] = 0x00;
		ID_ack_cmd[4] = 0xF0;
		ID_ack_cmd[5] = 0xF0;

		//	while( !uart_flush(1) ){};
		//	while( !uart_flush(0) ){};

		uart_SendBlock(ID_ack_cmd, 6);

		while (!uart_flush(1)) {
		};

		ID_ack_cmd[4] = 0x00;
		ID_ack_cmd[5] = 0x00;
		ID_ack_cmd[2] = 0x0D;

		uart_close(0);
		uart_init(0);

	}

}

// Inicializacia kamery:
void cam_init() {

}

//Nacitavanie poctu bytov s time outom
int uart_RecvBlock(char *dest, int pocet, uint32 time_out) {
	int c;
	uint16 i;
	uint32 start_time;

	for (i = 0; i < pocet; i++) {
		start_time = MCF_DTIM0_DTCN;
		while ((c = _getch()) == -1) {
			if ((MCF_DTIM0_DTCN - start_time) > time_out)
				return -1;
		};

		*dest = c;
		dest++;

	}
	return 0;
}

// Spravnost prikazov
int test_cmd(char *cmd1, char *cmd2, int pocet) {
	char i;
	for (i = 0; i < pocet; i++) {
		if (cmd1[i] != cmd2[i])
			return -1;
	}
	return 0;

}

// Spravnost prikazov
int test_cmd_ack(char *cmd1, char *cmd2, int pocet, char cmd) {
	char i;

	for (i = 0; i < pocet; i++) {
		if (i == 2) {
			if (cmd1[i] != cmd)
				return -1;
		} else if (cmd1[i] != cmd2[i])
			return -1;
	}
	return 0;

}

// synchronyzacia kamery:
void cam_sync() {
	char buffer[10];
	unsigned int i;
	uint32 start_time;

	for (i = 0; i < 60; i++) {
		uart_SendBlock(ID_sync_cmd, 6); //SYNC

		while (!uart_flush(1)) {
		};
		start_time = MCF_DTIM0_DTCN;
		while ((MCF_DTIM0_DTCN - start_time) < 1000000) {
		};

		if (uart_present(1) != 0)// Prisiel znak
		{
			if (uart_RecvBlock(buffer, 6, 1000000))
				printf("\n Chyba citania UART - Synchronizacia");
			else {
				if (test_cmd(buffer, ID_ack_cmd, 3)) {
					printf("\nChyba: zla odpoved. Ocakvana odpoved ACK");
					printf("\n%#x %#x %#x %#x %#x %#x", buffer[0], buffer[1],
							buffer[2], buffer[3], buffer[4], buffer[5]);
				} else {
					if (uart_RecvBlock(buffer, 6, 1000000))
						printf("\n Chyba citania UART - Synchronizacia");
					else {
						if (test_cmd(buffer, ID_sync_cmd, 3)) {
							printf(
									"\nChyba: zla odpoved. Ocakvana odpoved SYNC");
							printf("\n%#x %#x %#x %#x %#x %#x", buffer[0],
									buffer[1], buffer[2], buffer[3], buffer[4],
									buffer[5]);
						} else {
							uart_SendBlock(ID_ack_cmd, 6); //SYNC
							while (!uart_flush(1)) {
							};
							printf("\n KAMERA: Synchronizacia uspesna");
							return;
						}
					}

				}

			}

		};
	}
	printf("\n Chyba synchronizacie: 60 opakovani");

}

