?? mca25_pgm_buggy.c
字號:
/*********************************************************** driver for MCA-25 camera** Author : {{removed according to contest rules}}* -> circuitcellar.com avr design contest 2006* -> Entry #AT2616** 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 "main.h"volatile unsigned char mca25_uart_disabled;unsigned char mca25_cam_busy_for_socket = MCA25_NOT_BUSY;unsigned char mca25_cam_status = 0;volatile unsigned char mca25_cam_active;/* typical usage: 1) mca25_init(); -> trigger a hardware reset and activates mux transfer 2) mca25_configure(); -> set up image format etc. 3) mca25_start_image_grab(); -> activate image grabbing, take a preview image 4) mca25_grab_jpeg(); -> activate jpg transfer 5) mca25_grab_data(); -> get x byte data 6) while (){ mca25_send_data_ack(); mca25_grab_data(); ... } -> ack & grab loop => see mca25_copy_image_data_to_tcp_buffer() as an example ;) *//*======================================================================| copy the image data to the tcp data buffer, | buffer must be at least CAM_BUFFER_LEN byte long !`======================================================================*/unsigned char mca25_copy_image_data_to_tcp_buffer(char *buffer, int *bufferlen){ unsigned int result16; unsigned int len = 0; unsigned char frametype = 0; //set cam active flag: mca25_cam_active = 1; //Errechnet startpunkt der Daten im Tcp buffer //IP Headerl?ge + TCP Headerl?ge + Ethernetframe result16 = ((buffer[IP_VERS_LEN] & 0x0F) << 2) + ((buffer[TCP_HDRFLAGS] & 0xF0) >>2) + 14; //if we have had an error, we need to skip //the remaining picture. cam has no ABORT cmd ?!?! if (mca25_cam_status == MCA25_SKIP_PICTURE){ frametype = 0x48; //skip the current active picture... //dirty hack but seems like cam does //not have any abort commands :( while (frametype == 0x48){ mca25_uart_disabled = 0; mca25_send_data_ack(); mca25_uart_disabled = 1; mca25_grab_data((buffer+result16), &len, &frametype); //grabs 250 byte data } mca25_uart_disabled=0; printf_P(PSTR("\xF9\x01\xEF\x0B\xE3\x07\x23\x0C\x01\x79\xF9")); mca25_uart_disabled=1; mca25_cam_status = MCA25_FIRST_DATA; } #if USE_SERVO //this is the _only_ safe position to move the servo //a servo movement while cam is running freezes the cam ! //maybe a seperate power supply for servo can fix this (EM) if (servo_need_update){ servo_move(); //wait some time for (unsigned int z=0; z<60000; z++){ for (int y=0; y<20; y++){ nop();nop();nop();nop();nop();nop(); } } }#endif if (mca25_cam_status == MCA25_FIRST_DATA){ //start grab here, this takes a //long time... mca25_start_image_grab(); //initialise jpg dump mca25_grab_jpeg(); //first packet done mca25_cam_status = MCA25_NEXT_DATA; }else{ // if (mca25_cam_status == MCA25_NEXT_DATA){ mca25_uart_disabled = 0; mca25_send_data_ack(); mca25_uart_disabled = 1; } // we use the ethernet buffer for // storing the image data // --> make sure it is big enough ! (fixme) mca25_grab_data((buffer+result16), &len, &frametype); //sometimes the last packet seems to be empty //-> send this dummy data, it does not matter ... if (len == 0) len = CAM_BUFFER_LEN; //store data length result16 = result16 + len; //fixme, do something here ... /*if (result16 > (MTU_SIZE - 1)){ Buffer_Full = 1; printf_P(PSTR("WARN: buffer > MTU-1 !\n"); break; }*/ //Wait a short Time for(int a = 0;a<1000;a++){nop();}; TCP_New_Packtlen (buffer,bufferlen,result16); // last picture is XX SH SL CC 00 // CC = 0x48 -> more data (?) // = 0x49 -> last data if (frametype!=0x48){ // this is important ! after the image grad // we need to do this! without this the camera // sometimes hangs while grabbing another image ... strange // reconfig mux (?) mca25_uart_disabled=0; printf_P(PSTR("\xF9\x01\xEF\x0B\xE3\x07\x23\x0C\x01\x79\xF9")); mca25_uart_disabled=1; return 0; // this is a smaller packet -> it was the last }else return 1; // this is a full packet -> there should be more (fixme)}/*====================================================================== | this is called in the main loop. | it makes sure that the cam does not hang after a | user hits "abort" while loading the picture `======================================================================*/void mca25_check_for_closed_tcpconn(void){ //no transfer active: if (mca25_cam_busy_for_socket == MCA25_NOT_BUSY) return; //reset cam active flag: mca25_cam_active = 0; //if cam busy flag is not cleared within 5 seconds //we have a problem for (int i=0; i<5000; i++){ _delay_ms(1); } if (mca25_cam_active == 0){ //active flag was not set ! //-> maybe someone canceled the image transfer //-> set new status, httpd will cleanup later: mca25_cam_busy_for_socket = MCA25_BUSY_ABORTED; }}/*======================================================================| grab the next x byte data frame| (cam must bei in jpg capture mode!)`======================================================================*/void mca25_grab_data(char *buffer, unsigned int *datalen, char *frametype){ unsigned int j=0; unsigned char togo=31; unsigned char rx=0; unsigned char state=0; unsigned char firstframe = 1; //enable uart: mca25_uart_disabled=0; *datalen = 0; // we start with len=0, // we extract the packetlength // after the first packet and update len // // if we re in state12 -> continue, we do not have the full len yet while( *datalen==0 || (j<*datalen) || state>99 || state == 12 ){ MCA25_STATUS_LED_ON(); while (!(USR & (1<<RXC))){} rx = UDR; MCA25_STATUS_LED_OFF(); switch(state){ case 0: //no packet header rcv, wait for header: if (rx == 0xF9) state = 1; //else: do nothing break; case 1: //we got a F9 if (rx == 0x83) state = 2; //we have a data packet else if (rx == 0xF9){ state = 1; //this is the real start byte //MCA25_ERROR_LED_ON(); }else{ state = 0; // we missed something, try again. //MCA25_ERROR_LED_ON(); } break; case 2: //now we expect EF if (rx == 0xEF){ state = 3; // packet ok }else{ if (rx == 0xF9){ //??? happens sometimes state = 1; }else{ state = 0; // something went wrong -> retry //MCA25_ERROR_LED_ON(); } } break; case 3: //next byte is frame len: togo = (rx-1)/2; //rx/2 //printf_P(PSTR("len=%d\n",togo); //if (togo != 31 && togo != 13) printf_P(PSTR("len=%d\n",togo); if (firstframe==1) state = 10; //get frame info else state = 100; //grab data break; case 10: //90 01 00 48 00 xx //this is the first packet and we //have not sampled anything //-> this is 0x90 -> ignore togo--; state = 11; firstframe = 0; break; case 11: //this is the first packet and //this byte is hi(length) *datalen = (unsigned int)(rx<<8); togo--; state = 12; break; case 12: //this is the first packet and //this byte is lo(length) *datalen = (unsigned int)*datalen + (unsigned int)(rx) - 6; //substract the first //6byte frame info //make sure len is valid if (*datalen > CAM_BUFFER_LEN){ *datalen = CAM_BUFFER_LEN; } togo--; state = 13; break; case 13: //this is the first packet and //this byte is the frame type *frametype = rx; togo--; state = 14; break; case 14: //this is the first packet and //this byte is ??? -> ignore togo--; state = 15; break; case 15: //this is the first packet and //this byte is ??? -> ignore togo--; state = 100; //now sample data break; case 100: //now sample data: if (j<CAM_BUFFER_LEN) buffer[j] = rx; else MCA25_ERROR_LED_ON(); //printf_P(PSTR("ARGHHHHHHHHHHHHHHH\n"); //printf_P(PSTR("OUT[%03d] 0x%02x\n",j,rx); j++; togo--; if (togo == 0) state = 101; break; case 101: //data is there now we read checksum: //ignore CS... //printf_P(PSTR("CSUM=%02x\n",rx); state = 102; break; case 102: //we have frame end: if (rx != 0xF9){ //MCA25_ERROR_LED_ON(); //printf_P(PSTR("FRAME ERROR! @packet:%d: (0x%02x) len=%d\n"),j,rx,togo); } //printf_P(PSTR("EOF=%d\n\n",rx); state = 0; break; default: printf_P(PSTR("yeah stack problems. out of mem ? :-X\n")); } } //disable uart: mca25_uart_disabled=1;}/*======================================================================| start a jpg grab| (mca_25_start_image_grab() has to be called first)`======================================================================*/void mca25_grab_jpeg(){ //enable uart: mca25_uart_disabled=0; // send capture start cmd: mca25_pgm_send(MCA25_START_JPG); //send an ok for the power consumption message //printf_P(PSTR("\xF9\x21\xEF\x0D\x0D\x0A\x4F\x4B\x0D\x0A\x48\xF9")); //disable uart: mca25_uart_disabled=1;}/*======================================================================| initialise the image grabbing| it starts preview mode and "skips" a whole preview image`======================================================================*/void mca25_start_image_grab(){ unsigned char state; unsigned char datapos; unsigned char buf[MCA25_COMM_BUFFER_LEN]; //enable uart: mca25_uart_disabled=0; //grab 6 preview pictures: for (char i=0; i<6; i++){ /*while ( memcmp_P(buf,PSTR("\xF9\x83\xEF\x07\xA0\x00\x03",7) != 0) mca25_read_mux_packet(buf); */ // wait for go ?! fIXME // f9 83 f9 00 32 02 ??? mca25_read_mux_packet(buf); // send capture start cmd: mca25_pgm_send(MCA25_START_CAPTURING_1); // this delay is neccessary ! // without this we get a lot of // noise in the picture ! for (unsigned int z=0; z<10000; z++){ nop();nop();nop();nop();nop();nop(); } mca25_pgm_send(MCA25_START_CAPTURING_2); mca25_pgm_send(MCA25_START_CAPTURING_3); //send an ok for the power consumption message printf_P(PSTR("\xF9\x21\xEF\x0D\x0D\x0A\x4F\x4B\x0D\x0A\x48\xF9")); mca25_send_data_ack(); state = 0; datapos = 0; // grab actual image and tell cam to keep it in RAM // we acknowledge the _preview_ image and download // the full size image later... while (state != 100){ mca25_read_mux_packet(buf); //read MUX packet switch (state){ case 0: // wait for first packet, decode if is last data // [F9 83 EF 3F 90 01 00 xx xx FD * ] F9 ] // xx xx = C3 00 -> first 256 byte // xx xx = 48 01 -> middle // xx xx = 49 01 -> last data! #if CAM_BUFFER_LEN == 256 if (memcmp_P(buf,PSTR("\xF9\x83\xEF\x3F\x90"),5) == 0){#else // 512byte buf: // 90 02 00 C3 00 00 // 90 02 00 48 01 FD // A0 01 10 49 01 0D if (memcmp_P(buf,PSTR("\xF9\x83\xEF\x3F\x90\x02"),6) == 0){#endif if (buf[7] == 0xC3 && buf[8] == 0x00){ //first frame: datapos = 1; }else if(buf[7] == 0x48 && buf[8] == 0x01){ //middle datapos = 2; }else if(buf[7] == 0x49 && buf[8] == 0x01){ //end: datapos = 3; }else if(buf[7] == 0x48 && buf[8] == 0x00){ //end? datapos = 2; }else{ //printf_P(PSTR("buf7=%x, buf8=%x\n\n",buf[7],buf[8]); } state = 1; //last data -> send ack! mca25_send_data_ack(); }else if (memcmp_P(buf,PSTR("\xF9\x83\xEF\x3F\xA0"),5) == 0){ // F9 83 EF 3F A0 00 4C 49 00 49 00 if(buf[7] == 0x49 && buf[8] == 0x00){ //end when CAM_BUF_LEN = 256 datapos = 3; }else if(buf[7] == 0x49 && buf[8] == 0x01){ //end when CAM_BUF_LEN = 512 datapos = 3; }else{ //printf_P(PSTR("buf7=%x, buf8=%x\n\n",buf[7],buf[8]); } state = 1; //last data -> send ack! mca25_send_data_ack(); } break;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -