⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mca25.c

📁 ENC28J60 System HTTP
💻 C
📖 第 1 页 / 共 3 页
字号:
/*,-----------------------------------------------------------------------------------------.| io/mca25|-----------------------------------------------------------------------------------------| this file implements the communcation protocol used by sony ericcsons mca25 handy camera| - based on my mca25 code shipped with the rtl8019 webservercode| - enhanced by some ideas from jesper| - mca25 packetsize can be freely configured -> use full ethernet buffer -> faster|| BUGS:| - sometimes the camera hangs during mux7 etc -> but cam is then restartet| - retransfer if there was a lost packet is NOT TESTED !!|| Author   : {{removed according to contest rules}}|            -> circuitcellar.com avr design contest 2006|            -> Entry #AT2616||-----------------------------------------------------------------------------------------| License:| This program is free software; you can redistribute it and/or modify it under| the terms of the GNU General Public License as published by the Free Software| Foundation; either version 2 of the License, or (at your option) any later| version.| This program is distributed in the hope that it will be useful, but|| WITHOUT ANY WARRANTY;|| without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR| PURPOSE. See the GNU General Public License for more details.|| You should have received a copy of the GNU General Public License along with| this program; if not, write to the Free Software Foundation, Inc., 51| Franklin St, Fifth Floor, Boston, MA 02110, USA|| http://www.gnu.de/gpl-ger.html`-----------------------------------------------------------------------------------------*/#include "mca25.h"#include "led.h"//ACTIVATE DEBUG by editing this file:#include "debug.h"//start JPG magicPROGMEM char MCA25_START_JPG[] = {0xF9,0x81,0xEF,0x3F,0x83,0x00,0x82,0x71,0x00,0x58,0x3C,0x6D,0x6F,0x6E,0x69,0x74,0x6F,0x72,0x69,0x6E,0x67,0x2D,0x63,0x6F,0x6D,0x6D,0x61,0x6E,0x64,0x20,0x76,0x65,0x72,0x73,0x69,0x8C,0xF9,0xF9,0x81,0xEF,0x3F,0x6F,0x6E,0x3D,0x22,0x31,0x2E,0x30,0x22,0x20,0x74,0x61,0x6B,0x65,0x2D,0x70,0x69,0x63,0x3D,0x22,0x4E,0x4F,0x22,0x20,0x73,0x65,0x6E,0x64,0x2D,0x70,0x69,0x78,0x8C,0xF9,0xF9,0x81,0xEF,0x3F,0x65,0x6C,0x2D,0x73,0x69,0x7A,0x65,0x3D,0x22,0x36,0x34,0x30,0x2A,0x34,0x38,0x30,0x22,0x20,0x7A,0x6F,0x6F,0x6D,0x3D,0x22,0x31,0x30,0x22,0x2F,0x3E,0x42,0x00,0x8C,0xF9,0xF9,0x81,0xEF,0x3F,0x21,0x78,0x2D,0x62,0x74,0x2F,0x69,0x6D,0x61,0x67,0x69,0x6E,0x67,0x2D,0x6D,0x6F,0x6E,0x69,0x74,0x6F,0x72,0x69,0x6E,0x67,0x2D,0x69,0x6D,0x61,0x67,0x65,0x00,0x8C,0xF9,0xF9,0x81,0xEF,0x0D,0x4C,0x00,0x06,0x06,0x01,0x80,0x4B,0xF9};//start capturing magicPROGMEM char MCA25_START_CAPTURING[] = {//part 10xF9,0x81,0xEF,0x3F,0x83,0x00,0x69,0x71,0x00,0x3F,0x3C,0x6D,0x6F,0x6E,0x69,0x74,0x6F,0x72,0x69,0x6E,0x67,0x2D,0x63,0x6F,0x6D,0x6D,0x61,0x6E,0x64,0x20,0x76,0x65,0x72,0x73,0x69,0x8C,0xF9,//part 20xF9,0x81,0xEF,0x3F,0x6F,0x6E,0x3D,0x22,0x31,0x2E,0x30,0x22,0x20,0x74,0x61,0x6B,0x65,0x2D,0x70,0x69,0x63,0x3D,0x22,0x59,0x45,0x53,0x22,0x20,0x7A,0x6F,0x6F,0x6D,0x3D,0x22,0x31,0x8C,0xF9,0xF9,0x81,0xEF,0x3F,0x30,0x22,0x2F,0x3E,0x42,0x00,0x21,0x78,0x2D,0x62,0x74,0x2F,0x69,0x6D,0x61,0x67,0x69,0x6E,0x67,0x2D,0x6D,0x6F,0x6E,0x69,0x74,0x6F,0x72,0x69,0x6E,0x67,0x2D,0x8C,0xF9,//part 30xF9,0x81,0xEF,0x19,0x69,0x6D,0x61,0x67,0x65,0x00,0x4C,0x00,0x06,0x06,0x01,0x80,0x50,0xF9};//configure cam magicPROGMEM char MCA25_CONFIG_640x480[] = {0xF9,0x81,0xEF,0x3F,0x82,0x01,0x3B,0x01,0x00,0x03,0x49,0x01,0x35,0x3C,0x63,0x61,0x6D,0x65,0x72,0x61,0x2D,0x73,0x65,0x74,0x74,0x69,0x6E,0x67,0x73,0x20,0x76,0x65,0x72,0x73,0x69,0x8C,0xF9,0xF9,0x81,0xEF,0x3F,0x6F,0x6E,0x3D,0x22,0x31,0x2E,0x30,0x22,0x20,0x77,0x68,0x69,0x74,0x65,0x2D,0x62,0x61,0x6C,0x61,0x6E,0x63,0x65,0x3D,0x22,0x4F,0x46,0x46,0x22,0x20,0x63,0x6F,0x8C,0xF9,0xF9,0x81,0xEF,0x3F,0x6C,0x6F,0x72,0x2D,0x63,0x6F,0x6D,0x70,0x65,0x6E,0x73,0x61,0x74,0x69,0x6F,0x6E,0x3D,0x22,0x31,0x33,0x22,0x20,0x66,0x75,0x6E,0x2D,0x6C,0x61,0x79,0x65,0x72,0x8C,0xF9,0xF9,0x81,0xEF,0x3F,0x3D,0x22,0x30,0x22,0x3E,0x3C,0x6D,0x6F,0x6E,0x69,0x74,0x6F,0x72,0x69,0x6E,0x67,0x2D,0x66,0x6F,0x72,0x6D,0x61,0x74,0x20,0x65,0x6E,0x63,0x6F,0x64,0x69,0x6E,0x8C,0xF9,0xF9,0x81,0xEF,0x3F,0x67,0x3D,0x22,0x45,0x42,0x4D,0x50,0x22,0x20,0x70,0x69,0x78,0x65,0x6C,0x2D,0x73,0x69,0x7A,0x65,0x3D,0x22,0x38,0x30,0x2A,0x36,0x30,0x22,0x20,0x63,0x6F,0x6C,0x8C,0xF9,0xF9,0x81,0xEF,0x3F,0x6F,0x72,0x2D,0x64,0x65,0x70,0x74,0x68,0x3D,0x22,0x38,0x22,0x2F,0x3E,0x0D,0x0A,0x3C,0x74,0x68,0x75,0x6D,0x62,0x6E,0x61,0x69,0x6C,0x2D,0x66,0x6F,0x72,0x6D,0x8C,0xF9,0xF9,0x81,0xEF,0x3F,0x61,0x74,0x20,0x65,0x6E,0x63,0x6F,0x64,0x69,0x6E,0x67,0x3D,0x22,0x45,0x42,0x4D,0x50,0x22,0x20,0x70,0x69,0x78,0x65,0x6C,0x2D,0x73,0x69,0x7A,0x65,0x3D,0x22,0x8C,0xF9,0xF9,0x81,0xEF,0x3F,0x31,0x30,0x31,0x2A,0x38,0x30,0x22,0x20,0x63,0x6F,0x6C,0x6F,0x72,0x2D,0x64,0x65,0x70,0x74,0x68,0x3D,0x22,0x38,0x22,0x2F,0x3E,0x0D,0x0A,0x3C,0x6E,0x61,0x74,0x8C,0xF9,0xF9,0x81,0xEF,0x3F,0x69,0x76,0x65,0x2D,0x66,0x6F,0x72,0x6D,0x61,0x74,0x20,0x65,0x6E,0x63,0x6F,0x64,0x69,0x6E,0x67,0x3D,0x22,0x22,0x20,0x70,0x69,0x78,0x65,0x6C,0x2D,0x73,0x69,0x8C,0xF9,0xF9,0x81,0xEF,0x3F,0x7A,0x65,0x3D,0x22,0x36,0x34,0x30,0x2A,0x34,0x38,0x30,0x22,0x2F,0x3E,0x0D,0x0A,0x3C,0x2F,0x63,0x61,0x6D,0x65,0x72,0x61,0x2D,0x73,0x65,0x74,0x74,0x69,0x6E,0x8C,0xF9,0xF9,0x81,0xEF,0x0B,0x67,0x73,0x3E,0x0D,0x0A,0xAF,0xF9};//global varsunsigned char mca25_pic_state;unsigned char mca25_allocated_for_socket;unsigned char mca25_allocated_timeout;unsigned char mca25_buffer[MCA25_COMM_BUFFER_LEN];unsigned char mca25_ready;unsigned char mca25_mux_buffer[6];unsigned long mca25_datapos;unsigned char mca25_jpg_state;unsigned char mca25_is_rev017;#if 0unsigned char mca25_brightness;//estimate picture brightness, might be used to switch led light only if necessaryvoid mca25_estimate_brightness(unsigned char val){	//pixel is rgb332, we use rgb222 only!	unsigned char tmp = (((val&0xC0)>>6) + ((val&0x18)>>3) + (val&0x3));	mca25_brightness += tmp;}#endif//send data ackvoid mca25_send_data_ack(void){	mca25_puts_progmem("\xF9\x81\xEF\x07\x83\x00\x03\xA6\xF9");}//handle channel 0x23 datavoid mca25_handle_channel_x23(void){	if (mca25_mux_buffer[1] == 0xEF){		//UIH		if (string_compare_progmem_plen("AT*ECUR=", mca25_buffer)){			//ack current request packets:			// -> send mux "\r\nOK\r\n" packet:			mca25_puts_progmem("\xF9\x21\xEF\x0D\x0D\x0A\x4F\x4B\x0D\x0A\x48\xF9");		}else{			#if MCA25_DEBUG			softuart_putc('u');			#endif		}	}else if (mca25_mux_buffer[1] == 0x3F){		//SABM		mca25_puts_progmem("\xF9\x23\x73\x01\x02\xF9");	}}//handle channel 0x03 datavoid mca25_handle_channel_x03(void){	if (mca25_mux_buffer[1] == 0xEF){		//UIH		if (string_compare_progmem_plen("\xE1\x07\x23\x0C\x01", mca25_buffer)){			mca25_puts_progmem("\xF9\x01\xEF\x0B\xE3\x07\x23\x0C\x01\x79\xF9");		}else{			#if MCA25_DEBUG			softuart_putc('v');			#endif		}	}else if (mca25_mux_buffer[1] == 0x3F){		//SABM		mca25_puts_progmem("\xF9\x03\x73\x01\xD7\xF9");	}}//cleanup dead connection -> run this every second !void mca25_cleanup(void){	if (mca25_pic_state != MCA25_PIC_STATE_IDLE){		if (mca25_allocated_timeout == 0){			#if MCA25_DEBUG			softuart_puts_progmem("CAM : allocation to socket ");			softuart_put_uint8(mca25_allocated_for_socket);			softuart_puts_progmem(" removed");			softuart_putnewline();			#endif				mca25_pic_state = MCA25_PIC_STATE_IDLE;		}else{			mca25_allocated_timeout--;		}	}}//grab jpg data & store in bufferunsigned int mca25_grab_data(char *buffer, unsigned int datalen, unsigned long pos, unsigned char socketnum){	int skip_count=0;	unsigned char state=0;		mca25_allocated_timeout = 5; //5sec timeout	//cam is used by another user -> abort	if ((mca25_pic_state != MCA25_PIC_STATE_IDLE) && (mca25_allocated_for_socket != socketnum)){		return 0xFFFE;	}	//cam is no longer working -> reset !	if ((mca25_pic_state == MCA25_PIC_STATE_CAM_ERROR) || (mca25_ready == 0)){		//cam not initialised or missing!		#if MCA25_DEBUG		softuart_puts_progmem("CAM : grab -> cam error -> retry init!");		softuart_putnewline();		#endif		mca25_init_cam();		mca25_configure();		//return 0xFFFF; //-> abort this image !	}	//we need to do a preview image:	if (mca25_pic_state == MCA25_PIC_STATE_IDLE){		mca25_start_image_grab(socketnum);	}		#if 1	softuart_puts_progmem("CAM : req byte ");	softuart_put_uint16(pos);	softuart_puts_progmem(" cur pos is: ");	softuart_put_uint16(mca25_datapos);	softuart_putnewline();	//tcp stack requested data bytes we do no longer have...	//hack: dont touch ethernetbuffer & hope that data is still available.	//      if buffer was used during last transfer -> picture will have errors...	if (pos<mca25_datapos){		int adjust = (mca25_datapos-pos)-512;		if (adjust == 0){			//perfect			return 512;		}else if(adjust > 0){			//we must shift the data:			for(unsigned int a=0; a<512; a++){				if (a+adjust <= 512)					buffer[a] = buffer[a+adjust];			}			return adjust; //#adjusted bytes data		}else{			//>512 bytes of data seems to be lost -> no way to fix it...			//-> dont touch the buffer, maybe we can use the data later ...			return (adjust%512);		}	}else if(pos>mca25_datapos){		//?! how could that happen ?		//FIXME:		//1) ignore the missing data & continue		//2) skip camera data until we have the requestet data packet...		//-> use (1), change to 2 later ?!	}#endif	#if MCA25_DEBUG	/*softuart_puts_progmem("CAM : grab data starting at byte ");	softuart_put_uint16(pos>>16);	softuart_put_uint16(pos&0xFFFF);	softuart_puts_progmem(", current pos is ");	softuart_put_uint16(mca25_datapos>>16);	softuart_put_uint16(mca25_datapos&0xFFFF);	softuart_putnewline();*/	#endif	unsigned int dcnt=0;	unsigned int res=0;	unsigned int bufpos=0;	//we have received data -> send an ack !	if ((mca25_pic_state == MCA25_PIC_STATE_JPG_DATA) || (mca25_pic_state ==  MCA25_PIC_STATE_LAST_DATA)){		mca25_send_data_ack();	}	//do the statemachine	while (state != 100){		if (state == 0)			res = mca25_read_mux_packet(&buffer[bufpos],6);		else			res = mca25_read_mux_packet(&buffer[bufpos],0);		if (res == 0){			#if MCA25_DEBUG 			softuart_puts_progmem("TIMEOUT! (MUX J)");			softuart_putnewline();			softuart_puts_progmem("dcount=");			softuart_put_uint16(dcnt);			softuart_putnewline();			#endif			//cam error, disable !			mca25_ready = 0;			return 0xFFFF; //read failed -> exit!; 		}			if (bufpos>datalen){			#if MCA25_DEBUG 			softuart_puts_progmem("CAM : buf overflow! ");			softuart_put_uint16(skip_count);			softuart_put_uint16(bufpos);			softuart_putnewline();			#endif			return 0xFFFF;		}		//new version, thanks to jesper ;)		//softuart_put_uint8(mca25_buffer[1]);		if ((mca25_mux_buffer[0] == 0x83) && (mca25_mux_buffer[1] == 0xEF) ){ //data channel & UIH packet				dcnt++;								switch (state){					case 0: //check how many bytes cam want to send						skip_count = ((int)mca25_mux_buffer[4]<<8) + mca25_mux_buffer[5];						if (skip_count > datalen){							skip_count = datalen;						}												if (skip_count > 3){							//only handle data packets -> ignore packets smaller 3 bytes (=acks)							skip_count    -= ((mca25_mux_buffer[2])>>1);							bufpos        += (mca25_mux_buffer[2]>>1)-6;							//last data packet ?!							if (mca25_mux_buffer[3] == 0xA0){								mca25_pic_state = MCA25_PIC_STATE_LAST_DATA; //no more data							}else{								mca25_pic_state = MCA25_PIC_STATE_JPG_DATA; //middle of pic							}							state = 1;														if (skip_count <= 0){								//softuart_putc('.');								if (mca25_pic_state == MCA25_PIC_STATE_LAST_DATA){									mca25_send_data_ack();									//reconfigure mux channel (?!)									mca25_puts_progmem("\xF9\x01\xEF\x0B\xE3\x07\x23\x0C\x01\x79\xF9");									mca25_pic_state = MCA25_PIC_STATE_IDLE;									mca25_datapos += bufpos;									return bufpos;								}else{									mca25_datapos += bufpos;							    return 0;								}							}						}						break;					case 2:					case 1:						skip_count    -= ((mca25_mux_buffer[2])>>1);						bufpos        += (mca25_mux_buffer[2]>>1)-0;							if (skip_count <= 0){							//softuart_putc('.');							if (mca25_pic_state == MCA25_PIC_STATE_LAST_DATA){								mca25_send_data_ack();								//reconfigure mux channel (?!)								mca25_puts_progmem("\xF9\x01\xEF\x0B\xE3\x07\x23\x0C\x01\x79\xF9");								mca25_pic_state = MCA25_PIC_STATE_IDLE;								mca25_datapos += bufpos;								return bufpos; //last data packet !							}else{								mca25_datapos += bufpos;								return 0; //state = 100;							}						}						break;					default:						break;				} //case				//softuart_put_uint16(skip_count);			}else if (mca25_mux_buffer[0] == 0x23){				//channel 0x23				mca25_handle_channel_x23();			}else if (mca25_mux_buffer[0] == 0x03){ 				//channel 0x03				mca25_handle_channel_x03();			}else{				/*for(unsigned char f=0; f<40; f++){					softuart_put_uint8(f);					softuart_putc('>');					softuart_put_uint8(mca25_buffer[f]);					softuart_putnewline();				}softuart_putnewline();softuart_putnewline();*/			}		}			//softuart_puts_progmem("count=");		//softuart_put_uint16(dcnt);		//preview image #i has been grabbed.		#if MCA25_DEBUG		softuart_putc(' ');		#endif		return 0xFFFF;}//start image grab, grab preview pictures and send jpg requestunsigned char mca25_start_image_grab(unsigned char socketnum){	unsigned char state;	unsigned char datapos;	int skip_count=0;	//switch light on (slow fade in !)	//mpf10_fade(MPF10_FADE_IN);	//without soft fade in:	MPF10_ENABLE();	//reset global data byte counter		mca25_datapos = 0;	//allocate cam to current socket	mca25_allocated_for_socket = socketnum;	//reset state	mca25_pic_state = MCA25_PIC_STATE_IDLE; //not ready	if (mca25_ready == 0){		//cam not initialised or missing!		#if MCA25_DEBUG		softuart_puts_progmem("CAM : cam not initialised or missing -> abort.");		softuart_putnewline();		#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -