📄 mca25.c
字号:
MPF10_DISABLE(); return 0; } #if MCA25_DEBUG softuart_puts_progmem("CAM : starting image grab..."); softuart_putnewline(); softuart_puts_progmem("CAM : grabbing preview "); #endif //grab 5 preview pictures: for (char i=0; i<5; i++){ #if MCA25_DEBUG softuart_put_uint8(i); #endif //softuart_put_uint8(mca25_brightness); //mca25_brightness = 0; if ((i==0) && (mca25_pic_state == MCA25_PIC_STATE_JPG_DATA)){ // do not send start cmd ! an jpg request is already running // -> use first "preview" to ack jpg data! }else{ if (mca25_pic_state == MCA25_PIC_STATE_LAST_DATA){ //last data -> send an ack ! mca25_send_data_ack(); } // send capture start cmd: mca25_puts_progmem2(MCA25_START_CAPTURING, sizeof(MCA25_START_CAPTURING)); } 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){ if( ! mca25_read_mux_packet(mca25_buffer,0)){ #if MCA25_DEBUG softuart_puts_progmem("TIMEOUT! (MUX4) / previewpic"); softuart_put_uint8(i); softuart_putnewline(); #endif //cam error, disable ! mca25_ready = 0; MPF10_DISABLE(); return 0; //read failed -> exit!; } //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 //softuart_put_uint16(skip_count); 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 > 3){ //only handle data packets -> ignore packets smaller 3 bytes (=acks) skip_count -= ((mca25_mux_buffer[2])>>1); //last data packet ?! if (mca25_buffer[0] == 0xA0) state = 2; else state = 1; //estimate picture brightness by grabbing some bmp preview pixels ///mca25_estimate_brightness(mca25_buffer[28]); if (skip_count <= 0){ //softuart_putc('.'); mca25_send_data_ack(); if (state == 2) state = 100; else state = 0; } } break; case 2: case 1: skip_count -= ((mca25_mux_buffer[2])>>1); //estimate picture brightness by grabbing some bmp preview pixels ///mca25_estimate_brightness(mca25_buffer[28]); if (skip_count <= 0){ softuart_putc('.'); mca25_send_data_ack(); if (state == 2) state = 100; else state = 0; } 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_putc('.'); /*softuart_put_uint8(mca25_buffer[1]); softuart_put_uint8(mca25_buffer[2]); softuart_put_uint8(mca25_buffer[3]); softuart_put_uint8(mca25_buffer[4]); softuart_putnewline();*/ } } //preview image #i has been grabbed. #if MCA25_DEBUG softuart_putc('-'); #endif } #if MCA25_DEBUG softuart_putnewline(); softuart_puts_progmem("CAM : preview images done!"); softuart_putnewline(); softuart_puts_progmem("CAM : sending JPG grab request... "); softuart_putnewline(); #endif // send capture start cmd: mca25_puts_progmem2(MCA25_START_JPG, sizeof(MCA25_START_JPG)); #if MCA25_DEBUG //softuart_puts_progmem("done!"); //softuart_putnewline(); #endif //switch light off: MPF10_DISABLE(); //cam has transferred no image byte yet -> 0 mca25_datapos=0; mca25_pic_state = MCA25_PIC_STATE_PREVIEW_DONE; //preview done! return 1;}//configure mca25unsigned char mca25_configure(void){ unsigned char state=0; //unsigned char res = 0; int skip_count=0; mca25_pic_state = MCA25_PIC_STATE_IDLE; 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 return 0; } #if MCA25_DEBUG softuart_puts_progmem("CAM : configure..."); #endif //config cam: mca25_puts_progmem2(MCA25_CONFIG_640x480, sizeof(MCA25_CONFIG_640x480)); while (state != 100){ if( ! mca25_read_mux_packet(mca25_buffer,0)){ #if MCA25_DEBUG softuart_puts_progmem("TIMEOUT! (MUX2)"); softuart_putnewline(); #endif //cam error, disable ! mca25_ready = 0; return 0; //read failed -> exit!; } if (mca25_mux_buffer[0] == 0x83){ if (mca25_mux_buffer[1] == 0xEF){//UIH packet switch (state){ case 0: case 1: // wait for cam ACK: // [F9 83 EF 07 A0 00 03 C7 F9 //if (string_compare_progmem_plen("\xF9\x83\xEF\x07\xA0\x00\x03\xC7\xF9", mca25_buffer)){ if (string_compare_progmem_plen("\xA0\x00\x03", mca25_buffer)){ // request camera info: // [F9 81 EF 2F 83 00 17 42 00 14 78 2D 62 74 2F 63 // 61 6D 65 72 61 2D 69 6E 66 6F 00 90 F9] mca25_puts_progmem("\xF9\x81\xEF\x2F\x83\x00\x17\x42\x00\x14\x78\x2D\x62\x74\x2F\x63\x61\x6D\x65\x72\x61\x2D\x69\x6E\x66\x6F\x00\x90\xF9"); state = 2; } break; case 2: // ignore camera info ... // new version: read how many config bytes cam wants to send // in order to decide when we can continue! // thanks to jesper for this idea ;) [now works with brand new, unused cams!] skip_count = ((int)mca25_mux_buffer[3]<<8) + mca25_mux_buffer[4]; skip_count -= (mca25_mux_buffer[2]>>1); state = 3; break; case 3: //now skip the necessary amount of bytes: skip_count -= (mca25_mux_buffer[2]>>1); //finished ! if (skip_count <= 0) state = 100; break; default: break; } } }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{ softuart_putc('i'); } } #if MCA25_DEBUG softuart_puts_progmem("done!"); softuart_putnewline(); #endif return 1;}//initialisevoid mca25_init(void){ //start with rev016 mca25_is_rev017 = 0; mca25_allocated_timeout = 0; mca25_pic_state = MCA25_PIC_STATE_IDLE; mca25_init_cam();}//initialise webcam, return 0 if failed!unsigned char mca25_init_cam(void){ unsigned char state=0; #if MCA25_DEBUG //unsigned char old_state=0xFF; #endif //mark cam as not ready: mca25_ready = 0; //make camreset pin output MCA25_RESET_PORT_DIR |= (1<<MCA25_RESET_PIN); PORTD |= (1<<1); //UART TX = output PORTD &= ~(1<<0); //UART RX = input MCA25_RESET_LO(); //init uart if (mca25_is_rev017) mca25_uart_init_19200(); else mca25_uart_init_9600(); //reset cam: MCA25_RESET_LO(); _delay_ms(50); MCA25_RESET_HI(); #if MCA25_DEBUG softuart_puts_progmem("CAM : reset"); softuart_putnewline(); #endif/* //WARNING: will block whole server if no cam connected !! -> DO NOT USE! //detect mca25 revision //KTY 105 016 sends always at 9600 baud //KTY 105 017 sends AT at 9600 and then switches to 19200 !!! unsigned int count; for (state = 0; state <4; state++){ count=0; while((PIND & (1<<0))){} while(!(PIND & (1<<0))){ count++; } softuart_put_uint16(count); softuart_putnewline(); } #if MCA25_DEBUG softuart_puts_progmem("CAM : detected rev"); if (count > 50) softuart_puts_progmem("016"); else softuart_puts_progmem("017"); softuart_putnewline(); #endif //revision 017 ! if (count < 50){ mca25_uart_init_19200(); //reset cam again: MCA25_RESET_LO(); _delay_ms(50); MCA25_RESET_HI(); }*/ #if MCA25_DEBUG softuart_puts_progmem("CAM : init (takes ~5sec) "); #endif while (state != 100){ //read cam data: if (state<10){ //read AT command if ( ! mca25_read_at_command(mca25_buffer)){ #if MCA25_DEBUG softuart_puts_progmem("TIMEOUT! (AT) "); #endif if (state == 0){ //maybe this is a bad/new (?) mca25 which wants to communicate at 19200 baud! //retry! mca25_uart_init_19200(); #if MCA25_DEBUG softuart_puts_progmem(" trying 19200 baud "); #endif if ( ! mca25_read_at_command(mca25_buffer)){ #if MCA25_DEBUG softuart_puts_progmem("TIMEOUT! (AT) "); softuart_putnewline(); #endif return 0; }else{ mca25_is_rev017 = 1; } }else{ //state != 0 -> always exit #if MCA25_DEBUG softuart_putnewline(); #endif return 0; //read failed -> exit! } } }else{ //read MUX packet if( ! mca25_read_mux_packet(mca25_buffer,0)){ #if MCA25_DEBUG softuart_puts_progmem("TIMEOUT! (MUX)"); softuart_putnewline(); #endif return 0; //read failed -> exit!; } } #if MCA25_DEBUG /*if (old_state != state){ softuart_put_uint8(state); softuart_putc('-'); old_state = state; }*/ #endif switch (state){ case 0: //we have to wait for AT&F: if (string_compare_progmem_plen("AT&F", mca25_buffer) || string_compare_progmem_plen("AT&F", &mca25_buffer[2])){ mca25_send_ok(); state = 1; } break; case 1: //wait for AT+IPR if (string_compare_progmem_plen("AT+IPR=?", mca25_buffer)){ mca25_puts_progmem("+IPR: (),(1200,2400,4800,9600,19200,38400,57600,460800)\r\n\r\nOK\r\n"); state = 2; } break; case 2: //wait for AT+IPR SET command if (string_compare_progmem_plen("AT+IPR=460800", mca25_buffer)){ mca25_puts_progmem("\r\nOK\r\n"); //bubug: here only 1 \r before OK! //set higher baudrate: mca25_uart_init_460800(); //wait ... state = 3; } break; case 3: //wait for mux info req if (string_compare_progmem_plen("AT+CMUX=?", mca25_buffer)){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -