diff --git a/conf/modules/bebop_front_camera.xml b/conf/modules/bebop_front_camera.xml new file mode 100644 index 0000000000..2990f8343d --- /dev/null +++ b/conf/modules/bebop_front_camera.xml @@ -0,0 +1,61 @@ + + + + + + Video streaming for the Bebop front camera + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + BEBOP_FRONT_CAMERA_HOST ?= $(MODEM_HOST) + BEBOP_FRONT_CAMERA_PORT_OUT ?= 6000 + BEBOP_FRONT_CAMERA_BROADCAST ?= $(MODEM_BROADCAST) + + BEBOPVIEWVID_CFLAGS = -DBEBOP_FRONT_CAMERA_HOST=$(BEBOP_FRONT_CAMERA_HOST) -DBEBOP_FRONT_CAMERA_PORT_OUT=$(BEBOP_FRONT_CAMERA_PORT_OUT) + ifeq ($(BEBOP_FRONT_CAMERA_USE_NC),) + ap.CFLAGS += $(BEBOPVIEWVID_CFLAGS) -DBEBOP_FRONT_CAMERA_BROADCAST=$(BEBOP_FRONT_CAMERA_BROADCAST) + else + ap.CFLAGS += $(BEBOPVIEWVID_CFLAGS) -DBEBOP_FRONT_CAMERA_USE_NC + endif + + + + + + +
+ diff --git a/sw/airborne/boards/bebop/board.c b/sw/airborne/boards/bebop/board.c index 75320d3d3e..432a53ed2c 100644 --- a/sw/airborne/boards/bebop/board.c +++ b/sw/airborne/boards/bebop/board.c @@ -36,5 +36,5 @@ void board_init(void) // We also try to initialize the video CMOS chips here (Bottom and front) mt9v117_init(); - //mt9f002_init(); + mt9f002_init(); } diff --git a/sw/airborne/boards/bebop/mt9f002.h b/sw/airborne/boards/bebop/mt9f002.h new file mode 100644 index 0000000000..67fee7c926 --- /dev/null +++ b/sw/airborne/boards/bebop/mt9f002.h @@ -0,0 +1,374 @@ +#ifndef MT9F002_H +#define MT9F002_H + +#define MT9F002_NUM_OF_REGISTERS 367 + +#define MT9F002_MODEL_ID 0x0000 +#define MT9F002_REVISION_NUMBER 0x0002 +#define MT9F002_MANUFACTURER_ID 0x0003 +#define MT9F002_SMIA_VERSION 0x0004 +#define MT9F002_FRAME_COUNT 0x0005 +#define MT9F002_PIXEL_ORDER 0x0006 +#define MT9F002_DATA_PEDESTAL 0x0008 +#define MT9F002_FRAME_FORMAT_MODEL_TYPE 0x0040 +#define MT9F002_FRAME_FORMAT_MODEL_SUBTYPE 0x0041 +#define MT9F002_FRAME_FORMAT_DESCRIPTOR_0 0x0042 +#define MT9F002_FRAME_FORMAT_DESCRIPTOR_1 0x0044 +#define MT9F002_FRAME_FORMAT_DESCRIPTOR_2 0x0046 +#define MT9F002_FRAME_FORMAT_DESCRIPTOR_3 0x0048 +#define MT9F002_FRAME_FORMAT_DESCRIPTOR_4 0x004A +#define MT9F002_FRAME_FORMAT_DESCRIPTOR_5 0x004C +#define MT9F002_FRAME_FORMAT_DESCRIPTOR_6 0x004E +#define MT9F002_FRAME_FORMAT_DESCRIPTOR_7 0x0050 +#define MT9F002_FRAME_FORMAT_DESCRIPTOR_8 0x0052 +#define MT9F002_FRAME_FORMAT_DESCRIPTOR_9 0x0054 +#define MT9F002_FRAME_FORMAT_DESCRIPTOR_10 0x0056 +#define MT9F002_FRAME_FORMAT_DESCRIPTOR_11 0x0058 +#define MT9F002_FRAME_FORMAT_DESCRIPTOR_12 0x005A +#define MT9F002_FRAME_FORMAT_DESCRIPTOR_13 0x005C +#define MT9F002_FRAME_FORMAT_DESCRIPTOR_14 0x005E +#define MT9F002_ANALOG_GAIN_CAPABILITY 0x0080 +#define MT9F002_ANALOG_GAIN_CODE_MIN 0x0084 +#define MT9F002_ANALOG_GAIN_CODE_MAX 0x0086 +#define MT9F002_ANALOG_GAIN_CODE_STEP 0x0088 +#define MT9F002_ANALOG_GAIN_TYPE 0x008A +#define MT9F002_ANALOG_GAIN_M0 0x008C +#define MT9F002_ANALOG_GAIN_C0 0x008E +#define MT9F002_ANALOG_GAIN_M1 0x0090 +#define MT9F002_ANALOG_GAIN_C1 0x0092 +#define MT9F002_DATA_FORMAT_MODEL_TYPE 0x00C0 +#define MT9F002_DATA_FORMAT_MODEL_SUBTYPE 0x00C1 +#define MT9F002_DATA_FORMAT_DESCRIPTOR_0 0x00C2 +#define MT9F002_DATA_FORMAT_DESCRIPTOR_1 0x00C4 +#define MT9F002_DATA_FORMAT_DESCRIPTOR_2 0x00C6 +#define MT9F002_DATA_FORMAT_DESCRIPTOR_3 0x00C8 +#define MT9F002_DATA_FORMAT_DESCRIPTOR_4 0x00CA +#define MT9F002_DATA_FORMAT_DESCRIPTOR_5 0x00CC +#define MT9F002_DATA_FORMAT_DESCRIPTOR_6 0x00CE +#define MT9F002_MODE_SELECT 0x0100 +#define MT9F002_IMAGE_ORIENTATION 0x0101 +#define MT9F002_SOFTWARE_RESET 0x0103 +#define MT9F002_GROUPED_PARAMETER_HOLD 0x0104 +#define MT9F002_MASK_CORRUPTED_FRAMES 0x0105 +#define MT9F002_CPP_CHANNEL_IDENTIFIER 0x0110 +#define MT9F002_CPP2_SIGNALLING_MODE 0x0111 +#define MT9F002_CPP_DATA_FORMAT 0x0112 +#define MT9F002_GAIN_MODE 0x0120 +#define MT9F002_FINE_INTEGRATION_TIME 0x0200 +#define MT9F002_COARSE_INTEGRATION_TIME 0x0202 +#define MT9F002_ANALOG_GAIN_CODE_GLOBAL 0x0204 +#define MT9F002_ANALOG_GAIN_CODE_GREENR 0x0206 +#define MT9F002_ANALOG_GAIN_CODE_RED 0x0208 +#define MT9F002_ANALOG_GAIN_CODE_BLUE 0x020A +#define MT9F002_ANALOG_GAIN_CODE_GREENB 0x020C +#define MT9F002_DIGITAL_GAIN_GREENR 0x020E +#define MT9F002_DIGITAL_GAIN_RED 0x0210 +#define MT9F002_DIGITAL_GAIN_BLUE 0x0212 +#define MT9F002_DIGITAL_GAIN_GREENB 0x0214 +#define MT9F002_VT_PIX_CLK_DIV 0x0300 +#define MT9F002_VT_SYS_CLK_DIV 0x0302 +#define MT9F002_PRE_PLL_CLK_DIV 0x0304 +#define MT9F002_PLL_MULTIPLIER 0x0306 +#define MT9F002_OP_PIX_CLK_DIV 0x0308 +#define MT9F002_OP_SYS_CLK_DIV 0x030A +#define MT9F002_FRAME_LENGTH_LINES 0x0340 +#define MT9F002_LINE_LENGTH_PCK 0x0342 +#define MT9F002_X_ADDR_START 0x0344 +#define MT9F002_Y_ADDR_START 0x0346 +#define MT9F002_X_ADDR_END 0x0348 +#define MT9F002_Y_ADDR_END 0x034A +#define MT9F002_X_OUTPUT_SIZE 0x034C +#define MT9F002_Y_OUTPUT_SIZE 0x034E +#define MT9F002_X_EVEN_INC 0x0380 +#define MT9F002_X_ODD_INC 0x0382 +#define MT9F002_Y_EVEN_INC 0x0384 +#define MT9F002_Y_ODD_INC 0x0386 +#define MT9F002_SCALING_MODE 0x0400 +#define MT9F002_SPATIAL_SAMPLING 0x0402 +#define MT9F002_SCALE_M 0x0404 +#define MT9F002_SCALE_N 0x0406 +#define MT9F002_COMPRESSION_MODE 0x0500 +#define MT9F002_TEST_PATTERN_MODE 0x0600 +#define MT9F002_TEST_DATA_RED 0x0602 +#define MT9F002_TEST_DATA_GREENR 0x0604 +#define MT9F002_TEST_DATA_BLUE 0x0606 +#define MT9F002_TEST_DATA_GREENB 0x0608 +#define MT9F002_HORIZONTAL_CURSOR_WIDTH 0x060A +#define MT9F002_HORIZONTAL_CURSOR_POSITION 0x060C +#define MT9F002_VERTICAL_CURSOR_WIDTH 0x060E +#define MT9F002_VERTICAL_CURSOR_POSITION 0x0610 +#define MT9F002_INTEGRATION_TIME_CAPABILITY 0x1000 +#define MT9F002_COARSE_INTEGRATION_TIME_MIN 0x1004 +#define MT9F002_COARSE_INTEGRATION_TIME_MAX_MARGIN 0x1006 +#define MT9F002_FINE_INTEGRATION_TIME_MIN 0x1008 +#define MT9F002_FINE_INTEGRATION_TIME_MAX_MARGIN 0x100A +#define MT9F002_DIGITAL_GAIN_CAPABILITY 0x1080 +#define MT9F002_DIGITAL_GAIN_MIN 0x1084 +#define MT9F002_DIGITAL_GAIN_MAX 0x1086 +#define MT9F002_DIGITAL_GAIN_STEP_SIZE 0x1088 +#define MT9F002_MIN_EXT_CLK_FREQ_MHZ 0x1100 +#define MT9F002_MAX_EXT_CLK_FREQ_MHZ 0x1104 +#define MT9F002_MIN_PRE_PLL_CLK_DIV 0x1108 +#define MT9F002_MAX_PRE_PLL_CLK_DIV 0x110A +#define MT9F002_MIN_PLL_IP_FREQ_MHZ 0x110C +#define MT9F002_MAX_PLL_IP_FREQ_MHZ 0x1110 +#define MT9F002_MIN_PLL_MULTIPLIER 0x1114 +#define MT9F002_MAX_PLL_MULTIPLIER 0x1116 +#define MT9F002_MIN_PLL_OP_FREQ_MHZ 0x1118 +#define MT9F002_MAX_PLL_OP_FREQ_MHZ 0x111C +#define MT9F002_MIN_VT_SYS_CLK_DIV 0x1120 +#define MT9F002_MAX_VT_SYS_CLK_DIV 0x1122 +#define MT9F002_MIN_VT_SYS_CLK_FREQ_MHZ 0x1124 +#define MT9F002_MAX_VT_SYS_CLK_FREQ_MHZ 0x1128 +#define MT9F002_MIN_VT_PIX_CLK_FREQ_MHZ 0x112C +#define MT9F002_MAX_VT_PIX_CLK_FREQ_MHZ 0x1130 +#define MT9F002_MIN_VT_PIX_CLK_DIV 0x1134 +#define MT9F002_MAX_VT_PIX_CLK_DIV 0x1136 +#define MT9F002_MIN_FRAME_LENGTH_LINES 0x1140 +#define MT9F002_MAX_FRAME_LENGTH_LINES 0x1142 +#define MT9F002_MIN_LINE_LENGTH_PCK 0x1144 +#define MT9F002_MAX_LINE_LENGTH_PCK 0x1146 +#define MT9F002_MIN_LINE_BLANKING_PCK 0x1148 +#define MT9F002_MIN_FRAME_BLANKING_LINES 0x114A +#define MT9F002_MIN_OP_SYS_CLK_DIV 0x1160 +#define MT9F002_MAX_OP_SYS_CLK_DIV 0x1162 +#define MT9F002_MIN_OP_SYS_CLK_FREQ_MHZ 0x1164 +#define MT9F002_MAX_OP_SYS_CLK_FREQ_MHZ 0x1168 +#define MT9F002_MIN_OP_PIX_CLK_DIV 0x116C +#define MT9F002_MAX_OP_PIX_CLK_DIV 0x116E +#define MT9F002_MIN_OP_PIX_CLK_FREQ_MHZ 0x1170 +#define MT9F002_MAX_OP_PIX_CLK_FREQ_MHZ 0x1174 +#define MT9F002_X_ADDR_MIN 0x1180 +#define MT9F002_Y_ADDR_MIN 0x1182 +#define MT9F002_X_ADDR_MAX 0x1184 +#define MT9F002_Y_ADDR_MAX 0x1186 +#define MT9F002_MIN_EVEN_INC 0x11C0 +#define MT9F002_MAX_EVEN_INC 0x11C2 +#define MT9F002_MIN_ODD_INC 0x11C4 +#define MT9F002_MAX_ODD_INC 0x11C6 +#define MT9F002_SCALING_CAPABILITY 0x1200 +#define MT9F002_SCALER_M_MIN 0x1204 +#define MT9F002_SCALER_M_MAX 0x1206 +#define MT9F002_SCALER_N_MIN 0x1208 +#define MT9F002_SCALER_N_MAX 0x120A +#define MT9F002_COMPRESSION_CAPABILITY 0x1300 +#define MT9F002_MATRIX_ELEMENT_REDINRED 0x1400 +#define MT9F002_MATRIX_ELEMENT_GREENINRED 0x1402 +#define MT9F002_MATRIX_ELEMENT_BLUEINRED 0x1404 +#define MT9F002_MATRIX_ELEMENT_REDINGREEN 0x1406 +#define MT9F002_MATRIX_ELEMENT_GREENINGREEN 0x1408 +#define MT9F002_MATRIX_ELEMENT_BLUEINGREEN 0x140A +#define MT9F002_MATRIX_ELEMENT_REDINBLUE 0x140C +#define MT9F002_MATRIX_ELEMENT_GREENINBLUE 0x0140E +#define MT9F002_MATRIX_ELEMENT_BLUEINBLUE 0x1410 +#define MT9F002_MODEL_ID_ 0x3000 +#define MT9F002_Y_ADDR_START_ 0x3002 +#define MT9F002_X_ADDR_START_ 0x3004 +#define MT9F002_Y_ADDR_END_ 0x3006 +#define MT9F002_X_ADDR_END_ 0x3008 +#define MT9F002_FRAME_LENGTH_LINES_ 0x300A +#define MT9F002_LINE_LENGTH_PCK_ 0x300C +#define MT9F002_FINE_CORRECTION 0x3010 +#define MT9F002_COARSE_INTEGRATION_TIME_ 0x3012 +#define MT9F002_FINE_INTEGRATION_TIME_ 0x3014 +#define MT9F002_ROW_SPEED 0x3016 +#define MT9F002_EXTRA_DELAY 0x3018 +#define MT9F002_RESET_REGISTER 0x301A +#define MT9F002_MODE_SELECT_ 0x301C +#define MT9F002_IMAGE_ORIENTATION_ 0x301D +#define MT9F002_DATA_PEDESTAL_ 0x301E +#define MT9F002_SOFTWARE_RESET_ 0x3021 +#define MT9F002_GROUPED_PARAMETER_HOLD_ 0x3022 +#define MT9F002_MASK_CORRUPTED_FRAMES_ 0x3023 +#define MT9F002_PIXEL_ORDER_ 0x3024 +#define MT9F002_GPI_STATUS 0x3026 +#define MT9F002_ANALOG_GAIN_CODE_GLOBAL_ 0x3028 +#define MT9F002_ANALOG_GAIN_CODE_GREENR_ 0x302A +#define MT9F002_ANALOG_GAIN_CODE_RED_ 0x302C +#define MT9F002_ANALOG_GAIN_CODE_BLUE_ 0x302E +#define MT9F002_ANALOG_GAIN_CODE_GREENB_ 0x3030 +#define MT9F002_DIGITAL_GAIN_GREENR_ 0x3032 +#define MT9F002_DIGITAL_GAIN_RED_ 0x3036 +#define MT9F002_DIGITAL_GAIN_BLUE_ 0x3038 +#define MT9F002_DIGITAL_GAIN_GREENB_ 0x3038 +#define MT9F002_SMIA_VERSION_ 0x303A +#define MT9F002_FRAME_COUNT_ 0x303B +#define MT9F002_FRAME_STATUS 0x303C +#define MT9F002_READ_MODE 0x3040 +#define MT9F002_FLASH 0x3046 +#define MT9F002_FLASH_COUNT 0x3048 +#define MT9F002_GREEN1_GAIN 0x3056 +#define MT9F002_BLUE_GAIN 0x3058 +#define MT9F002_RED_GAIN 0x305A +#define MT9F002_GREEN2_GAIN 0x305C +#define MT9F002_GLOBAL_GAIN 0x305E +#define MT9F002_DATAPATH_STATUS 0x306A +#define MT9F002_DATAPATH_SELECT 0x306E +#define MT9F002_TEST_PATTERN_MODE_ 0x3070 +#define MT9F002_TEST_DATA_RED_ 0x3072 +#define MT9F002_TEST_DATA_GREENR_ 0x3074 +#define MT9F002_TEST_DATA_BLUE_ 0x3076 +#define MT9F002_TEST_DATA_GREENB_ 0x3078 +#define MT9F002_TEST_RAW_MODE 0x307A +#define MT9F002_X_EVEN_INC_ 0x30A0 +#define MT9F002_X_ODD_INC_ 0x30A2 +#define MT9F002_Y_EVEN_INC_ 0x30A4 +#define MT9F002_Y_ODD_INC_ 0x30A6 +#define MT9F002_CALIB_GREEN1_ASC1 0x30A8 +#define MT9F002_CALIB_BLUE_ASC1 0x30AA +#define MT9F002_CALIB_RED_ASC1 0x30AC +#define MT9F002_CALIB_GREEN2_ASC1 0x30AE +#define MT9F002_CALIB_GLOBAL 0x30BC +#define MT9F002_CALIB_CONTROL 0x30C0 +#define MT9F002_CALIB_GREEN1 0x30C2 +#define MT9F002_CALIB_BLUE 0x30C4 +#define MT9F002_CALIB_RED 0x30C6 +#define MT9F002_CALIB_GREEN2 0x30C8 +#define MT9F002_CTX_CONTROL_REG 0x30E8 +#define MT9F002_CTX_WR_DATA_REG 0x30EA +#define MT9F002_CTX_RD_DATA_REG 0x30EC +#define MT9F002_DARK_CONTROL3 0x30EE +#define MT9F002_OTPM_TCFG_READ_4B 0x3138 +#define MT9F002_OTPM_CFG 0x3140 +#define MT9F002_GLOBAL_FLASH_START 0x315A +#define MT9F002_GLOBAL_SEQ_TRIGGER 0x315E +#define MT9F002_GLOBAL_RST_END 0x3160 +#define MT9F002_GLOBAL_SHUTTER_START1 0x3162 +#define MT9F002_GLOBAL_SHUTTER_START2 0x3164 +#define MT9F002_GLOBAL_READ_START 0x3166 +#define MT9F002_GLOBAL_READ_START2 0x3168 +#define MT9F002_DAC_RSTLO 0x316A +#define MT9F002_ANALOG_CONTROL5 0x3178 +#define MT9F002_SERIAL_FORMAT_DESCRIPTOR_0 0x31A0 +#define MT9F002_SERIAL_FORMAT_DESCRIPTOR_1 0x31A2 +#define MT9F002_SERIAL_FORMAT_DESCRIPTOR_2 0x31A4 +#define MT9F002_SERIAL_FORMAT_DESCRIPTOR_3 0x31A6 +#define MT9F002_SERIAL_FORMAT_DESCRIPTOR_4 0x31A8 +#define MT9F002_SERIAL_FORMAT_DESCRIPTOR_5 0x31AA +#define MT9F002_SERIAL_FORMAT_DESCRIPTOR_6 0x31AC +#define MT9F002_SERIAL_FORMAT 0x31AE +#define MT9F002_FRAME_PREAMBLE 0x31B0 +#define MT9F002_LINE_PREAMBLE 0x31B2 +#define MT9F002_MIPI_TIMING_0 0x31B4 +#define MT9F002_MIPI_TIMING_1 0x31B6 +#define MT9F002_MIPI_TIMING_2 0x31B8 +#define MT9F002_MIPI_TIMING_3 0x31BA +#define MT9F002_MIPI_TIMING_4 0x31BC +#define MT9F002_HISPI_TIMING 0x31C0 +#define MT9F002_HISPI_CONTROL_STATUS 0x31C6 +#define MT9F002_HORIZONTAL_CURSOR_POSITION_ 0x31E8 +#define MT9F002_VERTICAL_CURSOR_POSITION_ 0x31EA +#define MT9F002_HORIZONTAL_CURSOR_WIDTH_ 0x31EC +#define MT9F002_VERTICAL_CURSOR_WIDTH_ 0x31EE +#define MT9F002_I2C_IDS_MIPI_DEFAULT 0x31F2 +#define MT9F002_I2C_IDS 0x31FC +#define MT9F002_P_GR_P0Q0 0x3600 +#define MT9F002_P_GR_P0Q1 0x3602 +#define MT9F002_P_GR_P0Q2 0x3604 +#define MT9F002_P_GR_P0Q3 0x3606 +#define MT9F002_P_GR_P0Q4 0x3608 +#define MT9F002_P_RD_P0Q0 0x360A +#define MT9F002_P_RD_P0Q1 0x360C +#define MT9F002_P_RD_P0Q2 0x360E +#define MT9F002_P_RD_P0Q3 0x3610 +#define MT9F002_P_RD_P0Q4 0x3612 +#define MT9F002_P_BL_P0Q0 0x3614 +#define MT9F002_P_BL_P0Q1 0x3616 +#define MT9F002_P_BL_P0Q2 0x3618 +#define MT9F002_P_BL_P0Q3 0x361A +#define MT9F002_P_BL_P0Q4 0x361C +#define MT9F002_P_GB_P0Q0 0x361E +#define MT9F002_P_GB_P0Q1 0x3620 +#define MT9F002_P_GB_P0Q2 0x3622 +#define MT9F002_P_GB_P0Q3 0x3624 +#define MT9F002_P_GB_P0Q4 0x3626 +#define MT9F002_P_GR_P1Q0 0x3640 +#define MT9F002_P_GR_P1Q1 0x3642 +#define MT9F002_P_GR_P1Q2 0x3644 +#define MT9F002_P_GR_P1Q3 0x3646 +#define MT9F002_P_GR_P1Q4 0x3648 +#define MT9F002_P_RD_P1Q0 0x364A +#define MT9F002_P_RD_P1Q1 0x364C +#define MT9F002_P_RD_P1Q2 0x364E +#define MT9F002_P_RD_P1Q3 0x3650 +#define MT9F002_P_RD_P1Q4 0x3652 +#define MT9F002_P_BL_P1Q0 0x3654 +#define MT9F002_P_BL_P1Q1 0x3656 +#define MT9F002_P_BL_P1Q2 0x3658 +#define MT9F002_P_BL_P1Q3 0x365A +#define MT9F002_P_BL_P1Q4 0x365C +#define MT9F002_P_GB_P1Q0 0x365E +#define MT9F002_P_GB_P1Q1 0x3660 +#define MT9F002_P_GB_P1Q2 0x3662 +#define MT9F002_P_GB_P1Q3 0x3664 +#define MT9F002_P_GB_P1Q4 0x3666 +#define MT9F002_P_GR_P2Q0 0x3680 +#define MT9F002_P_GR_P2Q1 0x3682 +#define MT9F002_P_GR_P2Q2 0x3684 +#define MT9F002_P_GR_P2Q3 0x3686 +#define MT9F002_P_GR_P2Q4 0x3688 +#define MT9F002_P_RD_P2Q0 0x368A +#define MT9F002_P_RD_P2Q1 0x368C +#define MT9F002_P_RD_P2Q2 0x368E +#define MT9F002_P_RD_P2Q3 0x3690 +#define MT9F002_P_RD_P2Q4 0x3692 +#define MT9F002_P_BL_P2Q0 0x3694 +#define MT9F002_P_BL_P2Q1 0x3696 +#define MT9F002_P_BL_P2Q2 0x3698 +#define MT9F002_P_BL_P2Q3 0x369A +#define MT9F002_P_BL_P2Q4 0x369C +#define MT9F002_P_GB_P2Q0 0x369E +#define MT9F002_P_GB_P2Q1 0x36A0 +#define MT9F002_P_GB_P2Q2 0x36A2 +#define MT9F002_P_GB_P2Q3 0x36A4 +#define MT9F002_P_GB_P2Q4 0x36A6 +#define MT9F002_P_GR_P3Q0 0x36C0 +#define MT9F002_P_GR_P3Q1 0x36C2 +#define MT9F002_P_GR_P3Q2 0x36C4 +#define MT9F002_P_GR_P3Q3 0x36C6 +#define MT9F002_P_GR_P3Q4 0x36C8 +#define MT9F002_P_RD_P3Q0 0x36CA +#define MT9F002_P_RD_P3Q1 0x36CC +#define MT9F002_P_RD_P3Q2 0x36CE +#define MT9F002_P_RD_P3Q3 0x36D0 +#define MT9F002_P_RD_P3Q4 0x36D2 +#define MT9F002_P_BL_P3Q0 0x36D4 +#define MT9F002_P_BL_P3Q1 0x36D6 +#define MT9F002_P_BL_P3Q2 0x36D8 +#define MT9F002_P_BL_P3Q3 0x36DA +#define MT9F002_P_BL_P3Q4 0x36DC +#define MT9F002_P_GB_P3Q0 0x36DE +#define MT9F002_P_GB_P3Q1 0x36E0 +#define MT9F002_P_GB_P3Q2 0x36E2 +#define MT9F002_P_GB_P3Q3 0x36E4 +#define MT9F002_P_GB_P3Q4 0x36E6 +#define MT9F002_P_GR_P4Q0 0x3700 +#define MT9F002_P_GR_P4Q1 0x3702 +#define MT9F002_P_GR_P4Q2 0x3704 +#define MT9F002_P_GR_P4Q3 0x3706 +#define MT9F002_P_GR_P4Q4 0x3708 +#define MT9F002_P_RD_P4Q0 0x370A +#define MT9F002_P_RD_P4Q1 0x370C +#define MT9F002_P_RD_P4Q2 0x370E +#define MT9F002_P_RD_P4Q3 0x3710 +#define MT9F002_P_RD_P4Q4 0x3712 +#define MT9F002_P_BL_P4Q0 0x3714 +#define MT9F002_P_BL_P4Q1 0x3716 +#define MT9F002_P_BL_P4Q2 0x3718 +#define MT9F002_P_BL_P4Q3 0x371A +#define MT9F002_P_BL_P4Q4 0x371C +#define MT9F002_P_GB_P4Q0 0x371E +#define MT9F002_P_GB_P4Q1 0x3720 +#define MT9F002_P_GB_P4Q2 0x3722 +#define MT9F002_P_GB_P4Q3 0x3724 +#define MT9F002_P_GB_P4Q4 0x3726 +#define MT9F002_POLY_SC_ENABLE 0x3780 +#define MT9F002_POLY_ORIGIN_C 0x3782 +#define MT9F002_POLY_ORIGIN_R 0x3784 +#define MT9F002_P_GR_Q5 0x37C0 +#define MT9F002_P_RD_Q5 0x37C2 +#define MT9F002_P_BL_Q5 0x37C4 +#define MT9F002_P_GB_Q5 0x37C6 +#define MT9F002_DAC_ID_FBIAS 0x3EF8 + +#endif /* MT9F002_H */ diff --git a/sw/airborne/boards/bebop/video.c b/sw/airborne/boards/bebop/video.c index 3e52c7778f..4863542011 100644 --- a/sw/airborne/boards/bebop/video.c +++ b/sw/airborne/boards/bebop/video.c @@ -26,12 +26,16 @@ #include "video.h" #include "std.h" +#include "mt9f002.h" #include #include #include #include #include +#include +#include +#include static bool_t write_reg(int fd, char *addr_val, uint8_t cnt) { @@ -122,18 +126,42 @@ void mt9v117_init(void) _write(fd_i2c, "\x09\x82\x00\x01", 4); _write(fd_i2c, "\x09\x8a\x70\x00", 4); - _write(fd_i2c, "\xf0\x00\x72\xcf\xff\x00\x3e\xd0\x92\x00\x71\xcf\xff\xff\xf2\x18\xb1\x10\x92\x05\xb1\x11\x92\x04\xb1\x12\x70\xcf\xff\x00\x30\xc0\x90\x00\x7f\xe0\xb1\x13\x70\xcf\xff\xff\xe7\x1c\x88\x36\x09\x0f\x00\xb3", 50); - _write(fd_i2c, "\xf0\x30\x69\x13\xe1\x80\xd8\x08\x20\xca\x03\x22\x71\xcf\xff\xff\xe5\x68\x91\x35\x22\x0a\x1f\x80\xff\xff\xf2\x18\x29\x05\x00\x3e\x12\x22\x11\x01\x21\x04\x0f\x81\x00\x00\xff\xf0\x21\x8c\xf0\x10\x1a\x22", 50); - _write(fd_i2c, "\xf0\x60\x10\x44\x12\x20\x11\x02\xf7\x87\x22\x4f\x03\x83\x1a\x20\x10\xc4\xf0\x09\xba\xae\x7b\x50\x1a\x20\x10\x84\x21\x45\x01\xc1\x1a\x22\x10\x44\x70\xcf\xff\x00\x3e\xd0\xb0\x60\xb0\x25\x7e\xe0\x78\xe0", 50); - _write(fd_i2c, "\xf0\x90\x71\xcf\xff\xff\xf2\x18\x91\x12\x72\xcf\xff\xff\xe7\x1c\x8a\x57\x20\x04\x0f\x80\x00\x00\xff\xf0\xe2\x80\x20\xc5\x01\x61\x20\xc5\x03\x22\xb1\x12\x71\xcf\xff\x00\x3e\xd0\xb1\x04\x7e\xe0\x78\xe0", 50); - _write(fd_i2c, "\xf0\xc0\x70\xcf\xff\xff\xe7\x1c\x88\x57\x71\xcf\xff\xff\xf2\x18\x91\x13\xea\x84\xb8\xa9\x78\x10\xf0\x03\xb8\x89\xb8\x8c\xb1\x13\x71\xcf\xff\x00\x30\xc0\xb1\x00\x7e\xe0\xc0\xf1\x09\x1e\x03\xc0\xc1\xa1", 50); - _write(fd_i2c, "\xf0\xf0\x75\x08\x76\x28\x77\x48\xc2\x40\xd8\x20\x71\xcf\x00\x03\x20\x67\xda\x02\x08\xae\x03\xa0\x73\xc9\x0e\x25\x13\xc0\x0b\x5e\x01\x60\xd8\x06\xff\xbc\x0c\xce\x01\x00\xd8\x00\xb8\x9e\x0e\x5a\x03\x20", 50); - _write(fd_i2c, "\xf1\x20\xd9\x01\xd8\x00\xb8\x9e\x0e\xb6\x03\x20\xd9\x01\x8d\x14\x08\x17\x01\x91\x8d\x16\xe8\x07\x0b\x36\x01\x60\xd8\x07\x0b\x52\x01\x60\xd8\x11\x8d\x14\xe0\x87\xd8\x00\x20\xca\x02\x62\x00\xc9\x03\xe0", 50); - _write(fd_i2c, "\xf1\x50\xc0\xa1\x78\xe0\xc0\xf1\x08\xb2\x03\xc0\x76\xcf\xff\xff\xe5\x40\x75\xcf\xff\xff\xe5\x68\x95\x17\x96\x40\x77\xcf\xff\xff\xe5\x42\x95\x38\x0a\x0d\x00\x01\x97\x40\x0a\x11\x00\x40\x0b\x0a\x01\x00", 50); - _write(fd_i2c, "\xf1\x80\x95\x17\xb6\x00\x95\x18\xb7\x00\x76\xcf\xff\xff\xe5\x44\x96\x20\x95\x15\x08\x13\x00\x40\x0e\x1e\x01\x20\xd9\x00\x95\x15\xb6\x00\xff\xa1\x75\xcf\xff\xff\xe7\x1c\x77\xcf\xff\xff\xe5\x46\x97\x40", 50); - _write(fd_i2c, "\xf1\xb0\x8d\x16\x76\xcf\xff\xff\xe5\x48\x8d\x37\x08\x0d\x00\x81\x96\x40\x09\x15\x00\x80\x0f\xd6\x01\x00\x8d\x16\xb7\x00\x8d\x17\xb6\x00\xff\xb0\xff\xbc\x00\x41\x03\xc0\xc0\xf1\x0d\x9e\x01\x00\xe8\x04", 50); - _write(fd_i2c, "\xf1\xe0\xff\x88\xf0\x0a\x0d\x6a\x01\x00\x0d\x8e\x01\x00\xe8\x7e\xff\x85\x0d\x72\x01\x00\xff\x8c\xff\xa7\xff\xb2\xd8\x00\x73\xcf\xff\xff\xf2\x40\x23\x15\x00\x01\x81\x41\xe0\x02\x81\x20\x08\xf7\x81\x34", 50); - _write(fd_i2c, "\xf2\x10\xa1\x40\xd8\x00\xc0\xd1\x7e\xe0\x53\x51\x30\x34\x20\x6f\x6e\x5f\x73\x74\x61\x72\x74\x5f\x73\x74\x72\x65\x61\x6d\x69\x6e\x67\x20\x25\x64\x20\x25\x64\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 50); + _write(fd_i2c, + "\xf0\x00\x72\xcf\xff\x00\x3e\xd0\x92\x00\x71\xcf\xff\xff\xf2\x18\xb1\x10\x92\x05\xb1\x11\x92\x04\xb1\x12\x70\xcf\xff\x00\x30\xc0\x90\x00\x7f\xe0\xb1\x13\x70\xcf\xff\xff\xe7\x1c\x88\x36\x09\x0f\x00\xb3", + 50); + _write(fd_i2c, + "\xf0\x30\x69\x13\xe1\x80\xd8\x08\x20\xca\x03\x22\x71\xcf\xff\xff\xe5\x68\x91\x35\x22\x0a\x1f\x80\xff\xff\xf2\x18\x29\x05\x00\x3e\x12\x22\x11\x01\x21\x04\x0f\x81\x00\x00\xff\xf0\x21\x8c\xf0\x10\x1a\x22", + 50); + _write(fd_i2c, + "\xf0\x60\x10\x44\x12\x20\x11\x02\xf7\x87\x22\x4f\x03\x83\x1a\x20\x10\xc4\xf0\x09\xba\xae\x7b\x50\x1a\x20\x10\x84\x21\x45\x01\xc1\x1a\x22\x10\x44\x70\xcf\xff\x00\x3e\xd0\xb0\x60\xb0\x25\x7e\xe0\x78\xe0", + 50); + _write(fd_i2c, + "\xf0\x90\x71\xcf\xff\xff\xf2\x18\x91\x12\x72\xcf\xff\xff\xe7\x1c\x8a\x57\x20\x04\x0f\x80\x00\x00\xff\xf0\xe2\x80\x20\xc5\x01\x61\x20\xc5\x03\x22\xb1\x12\x71\xcf\xff\x00\x3e\xd0\xb1\x04\x7e\xe0\x78\xe0", + 50); + _write(fd_i2c, + "\xf0\xc0\x70\xcf\xff\xff\xe7\x1c\x88\x57\x71\xcf\xff\xff\xf2\x18\x91\x13\xea\x84\xb8\xa9\x78\x10\xf0\x03\xb8\x89\xb8\x8c\xb1\x13\x71\xcf\xff\x00\x30\xc0\xb1\x00\x7e\xe0\xc0\xf1\x09\x1e\x03\xc0\xc1\xa1", + 50); + _write(fd_i2c, + "\xf0\xf0\x75\x08\x76\x28\x77\x48\xc2\x40\xd8\x20\x71\xcf\x00\x03\x20\x67\xda\x02\x08\xae\x03\xa0\x73\xc9\x0e\x25\x13\xc0\x0b\x5e\x01\x60\xd8\x06\xff\xbc\x0c\xce\x01\x00\xd8\x00\xb8\x9e\x0e\x5a\x03\x20", + 50); + _write(fd_i2c, + "\xf1\x20\xd9\x01\xd8\x00\xb8\x9e\x0e\xb6\x03\x20\xd9\x01\x8d\x14\x08\x17\x01\x91\x8d\x16\xe8\x07\x0b\x36\x01\x60\xd8\x07\x0b\x52\x01\x60\xd8\x11\x8d\x14\xe0\x87\xd8\x00\x20\xca\x02\x62\x00\xc9\x03\xe0", + 50); + _write(fd_i2c, + "\xf1\x50\xc0\xa1\x78\xe0\xc0\xf1\x08\xb2\x03\xc0\x76\xcf\xff\xff\xe5\x40\x75\xcf\xff\xff\xe5\x68\x95\x17\x96\x40\x77\xcf\xff\xff\xe5\x42\x95\x38\x0a\x0d\x00\x01\x97\x40\x0a\x11\x00\x40\x0b\x0a\x01\x00", + 50); + _write(fd_i2c, + "\xf1\x80\x95\x17\xb6\x00\x95\x18\xb7\x00\x76\xcf\xff\xff\xe5\x44\x96\x20\x95\x15\x08\x13\x00\x40\x0e\x1e\x01\x20\xd9\x00\x95\x15\xb6\x00\xff\xa1\x75\xcf\xff\xff\xe7\x1c\x77\xcf\xff\xff\xe5\x46\x97\x40", + 50); + _write(fd_i2c, + "\xf1\xb0\x8d\x16\x76\xcf\xff\xff\xe5\x48\x8d\x37\x08\x0d\x00\x81\x96\x40\x09\x15\x00\x80\x0f\xd6\x01\x00\x8d\x16\xb7\x00\x8d\x17\xb6\x00\xff\xb0\xff\xbc\x00\x41\x03\xc0\xc0\xf1\x0d\x9e\x01\x00\xe8\x04", + 50); + _write(fd_i2c, + "\xf1\xe0\xff\x88\xf0\x0a\x0d\x6a\x01\x00\x0d\x8e\x01\x00\xe8\x7e\xff\x85\x0d\x72\x01\x00\xff\x8c\xff\xa7\xff\xb2\xd8\x00\x73\xcf\xff\xff\xf2\x40\x23\x15\x00\x01\x81\x41\xe0\x02\x81\x20\x08\xf7\x81\x34", + 50); + _write(fd_i2c, + "\xf2\x10\xa1\x40\xd8\x00\xc0\xd1\x7e\xe0\x53\x51\x30\x34\x20\x6f\x6e\x5f\x73\x74\x61\x72\x74\x5f\x73\x74\x72\x65\x61\x6d\x69\x6e\x67\x20\x25\x64\x20\x25\x64\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + 50); _write(fd_i2c, "\xf2\x40\xff\xff\xe8\x28\xff\xff\xf0\xe8\xff\xff\xe8\x08\xff\xff\xf1\x54", 18); _write(fd_i2c, "\x09\x8e\x00\x00", 4); _write(fd_i2c, "\xe0\x00\x05\xd8", 4); @@ -219,222 +247,274 @@ void mt9v117_init(void) close(fd_i2c); } +int mt9f002_i2c_port; + +void mt9f002_open(void); +void mt9f002_close(void); +void mt9f002_set_address(uint8_t address); +void mt9f002_write_reg8(uint16_t reg, uint8_t value); +void mt9f002_write_reg16(uint16_t reg, uint16_t value); +uint8_t mt9f002_read_reg8(uint16_t reg); +uint16_t mt9f002_read_reg16(uint16_t reg); + +void mt9f002_open(void) +{ + mt9f002_i2c_port = open("/dev/i2c-0", O_RDWR); + if (mt9f002_i2c_port < 0) { + printf("mt9f002_open"); + // exit(1); + } +} + +void mt9f002_close(void) +{ + close(mt9f002_i2c_port); +} + +void mt9f002_set_address(uint8_t address) +{ + if (ioctl(mt9f002_i2c_port, I2C_SLAVE_FORCE, address) < 0) { + printf("mt9f002_set_address"); + // exit(1); + } +} + +void mt9f002_write_reg8(uint16_t reg, uint8_t value) +{ + mt9f002_open(); + mt9f002_set_address(0x10); + + uint8_t data[3]; + data[0] = (uint8_t)(reg >> 8) ; + data[1] = (uint8_t)reg & 0xFF; + data[2] = value; + // if(i2c_smbus_write_byte_data(mt9f002_i2c_port,reg,value) < 0) { + if (write(mt9f002_i2c_port, data, 3) < 0) { + printf("mt9f002_write_reg8"); + // exit(1); + } + + mt9f002_close(); + + usleep(100); +} + +void mt9f002_write_reg16(uint16_t reg, uint16_t value) +{ + mt9f002_open(); + mt9f002_set_address(0x10); + + uint8_t data[4]; + data[0] = (uint8_t)(reg >> 8); + data[1] = (uint8_t)reg & 0xFF; + data[2] = (uint8_t)(value >> 8); + data[3] = value & 0xFF; + if (write(mt9f002_i2c_port, data, 4) < 0) { + printf("mt9f002_write_reg16"); + // exit(1); + } + + mt9f002_close(); + + usleep(100); +} + +uint8_t mt9f002_read_reg8(uint16_t reg) +{ + mt9f002_open(); + mt9f002_set_address(0x10); + + uint8_t data[2]; + data[0] = (uint8_t)(reg >> 8); + data[1] = (uint8_t)reg & 0xFF; + write(mt9f002_i2c_port, data, 2); + usleep(10); + read(mt9f002_i2c_port, data, 1); + + mt9f002_close(); + + return data[0]; +} + + +uint16_t mt9f002_read_reg16(uint16_t reg) +{ + mt9f002_open(); + mt9f002_set_address(0x10); + + uint8_t data[2]; + data[0] = (uint8_t)(reg >> 8); + data[1] = (uint8_t)reg & 0xFF; + write(mt9f002_i2c_port, data, 2); + usleep(10); + read(mt9f002_i2c_port, data, 2); + + mt9f002_close(); + + return data[1] | (data[0] << 8); +} + /** * Initialisation of the Aptina MT9F002 CMOS sensor */ void mt9f002_init(void) { - /* We open the i2c-0 (because else I needed to convert the strace) */ - int fd_i2c = open("/dev/i2c-0", O_RDWR); - if (fd_i2c < 0) { - printf("[MT9F002] Could not open i2c-0\n"); - return; - } - if (ioctl(fd_i2c, 0x706, 0x10) < 0) { - printf("[MT9V117] Could not change the i2c address to 0x10\n"); - return; - } + /* Change to standby mode */ + mt9f002_write_reg8(MT9F002_MODE_SELECT, 0x00); - /* First reset the device */ - write(fd_i2c, "\1\3\1", 3); - //usleep(1); + /* Change registers */ + mt9f002_write_reg16(MT9F002_P_GR_P0Q0, 0); + mt9f002_write_reg16(MT9F002_P_GR_P0Q2, 0); + mt9f002_write_reg16(MT9F002_P_GR_P0Q3, 0); + mt9f002_write_reg16(MT9F002_P_GR_P0Q4, 0); + mt9f002_write_reg16(MT9F002_P_RD_P0Q0, 0); + mt9f002_write_reg16(MT9F002_P_RD_P0Q1, 0); + mt9f002_write_reg16(MT9F002_P_RD_P0Q2, 0); + mt9f002_write_reg16(MT9F002_P_RD_P0Q3, 0); + mt9f002_write_reg16(MT9F002_P_RD_P0Q4, 0); + mt9f002_write_reg16(MT9F002_P_BL_P0Q0, 0); + mt9f002_write_reg16(MT9F002_P_BL_P0Q1, 0); + mt9f002_write_reg16(MT9F002_P_BL_P0Q2, 0); + mt9f002_write_reg16(MT9F002_P_BL_P0Q3, 0); + mt9f002_write_reg16(MT9F002_P_BL_P0Q4, 0); + mt9f002_write_reg16(MT9F002_P_GB_P0Q0, 0); + mt9f002_write_reg16(MT9F002_P_GB_P0Q1, 0); + mt9f002_write_reg16(MT9F002_P_GB_P0Q2, 0); + mt9f002_write_reg16(MT9F002_P_GB_P0Q3, 0); + mt9f002_write_reg16(MT9F002_P_GB_P0Q4, 0); + mt9f002_write_reg16(MT9F002_P_GR_P1Q0, 0); + mt9f002_write_reg16(MT9F002_P_GR_P1Q1, 0); + mt9f002_write_reg16(MT9F002_P_GR_P1Q2, 0); + mt9f002_write_reg16(MT9F002_P_GR_P1Q3, 0); + mt9f002_write_reg16(MT9F002_P_GR_P1Q4, 0); + mt9f002_write_reg16(MT9F002_P_RD_P1Q0, 0); + mt9f002_write_reg16(MT9F002_P_RD_P1Q1, 0); + mt9f002_write_reg16(MT9F002_P_RD_P1Q2, 0); + mt9f002_write_reg16(MT9F002_P_RD_P1Q3, 0); + mt9f002_write_reg16(MT9F002_P_RD_P1Q4, 0); + mt9f002_write_reg16(MT9F002_P_BL_P1Q0, 0); + mt9f002_write_reg16(MT9F002_P_BL_P1Q1, 0); + mt9f002_write_reg16(MT9F002_P_BL_P1Q2, 0); + mt9f002_write_reg16(MT9F002_P_BL_P1Q3, 0); + mt9f002_write_reg16(MT9F002_P_BL_P1Q4, 0); + mt9f002_write_reg16(MT9F002_P_GB_P1Q0, 0); + mt9f002_write_reg16(MT9F002_P_GB_P1Q1, 0); + mt9f002_write_reg16(MT9F002_P_GB_P1Q2, 0); + mt9f002_write_reg16(MT9F002_P_GB_P1Q3, 0); + mt9f002_write_reg16(MT9F002_P_GB_P1Q4, 0); + mt9f002_write_reg16(MT9F002_P_GR_P2Q0, 0); + mt9f002_write_reg16(MT9F002_P_GR_P2Q1, 0); + mt9f002_write_reg16(MT9F002_P_GR_P2Q2, 0); + mt9f002_write_reg16(MT9F002_P_GR_P2Q3, 0); + mt9f002_write_reg16(MT9F002_P_GR_P2Q4, 0); + mt9f002_write_reg16(MT9F002_P_RD_P2Q0, 0); + mt9f002_write_reg16(MT9F002_P_RD_P2Q1, 0); + mt9f002_write_reg16(MT9F002_P_RD_P2Q2, 0); + mt9f002_write_reg16(MT9F002_P_RD_P2Q3, 0); + mt9f002_write_reg16(MT9F002_P_RD_P2Q4, 0); + mt9f002_write_reg16(MT9F002_P_BL_P2Q0, 0); + mt9f002_write_reg16(MT9F002_P_BL_P2Q1, 0); + mt9f002_write_reg16(MT9F002_P_BL_P2Q2, 0); + mt9f002_write_reg16(MT9F002_P_BL_P2Q3, 0); + mt9f002_write_reg16(MT9F002_P_BL_P2Q4, 0); + mt9f002_write_reg16(MT9F002_P_GB_P2Q0, 0); + mt9f002_write_reg16(MT9F002_P_GB_P2Q1, 0); + mt9f002_write_reg16(MT9F002_P_GB_P2Q2, 0); + mt9f002_write_reg16(MT9F002_P_GB_P2Q3, 0); + mt9f002_write_reg16(MT9F002_P_GB_P2Q4, 0); + mt9f002_write_reg16(MT9F002_P_GR_P3Q0, 0); + mt9f002_write_reg16(MT9F002_P_GR_P3Q1, 0); + mt9f002_write_reg16(MT9F002_P_GR_P3Q2, 0); + mt9f002_write_reg16(MT9F002_P_GR_P3Q3, 0); + mt9f002_write_reg16(MT9F002_P_GR_P3Q4, 0); + mt9f002_write_reg16(MT9F002_P_RD_P3Q0, 0); + mt9f002_write_reg16(MT9F002_P_RD_P3Q1, 0); + mt9f002_write_reg16(MT9F002_P_RD_P3Q2, 0); + mt9f002_write_reg16(MT9F002_P_RD_P3Q3, 0); + mt9f002_write_reg16(MT9F002_P_RD_P3Q4, 0); + mt9f002_write_reg16(MT9F002_P_BL_P3Q0, 0); + mt9f002_write_reg16(MT9F002_P_BL_P3Q1, 0); + mt9f002_write_reg16(MT9F002_P_BL_P3Q2, 0); + mt9f002_write_reg16(MT9F002_P_BL_P3Q3, 0); + mt9f002_write_reg16(MT9F002_P_BL_P3Q4, 0); + mt9f002_write_reg16(MT9F002_P_GB_P3Q0, 0); + mt9f002_write_reg16(MT9F002_P_GB_P3Q1, 0); + mt9f002_write_reg16(MT9F002_P_GB_P3Q2, 0); + mt9f002_write_reg16(MT9F002_P_GB_P3Q3, 0); + mt9f002_write_reg16(MT9F002_P_GB_P3Q4, 0); + mt9f002_write_reg16(MT9F002_P_GR_P4Q0, 0); + mt9f002_write_reg16(MT9F002_P_GR_P4Q1, 0); + mt9f002_write_reg16(MT9F002_P_GR_P4Q2, 0); + mt9f002_write_reg16(MT9F002_P_GR_P4Q3, 0); + mt9f002_write_reg16(MT9F002_P_GR_P4Q4, 0); + mt9f002_write_reg16(MT9F002_P_RD_P4Q0, 0); + mt9f002_write_reg16(MT9F002_P_RD_P4Q1, 0); + mt9f002_write_reg16(MT9F002_P_RD_P4Q2, 0); + mt9f002_write_reg16(MT9F002_P_RD_P4Q3, 0); + mt9f002_write_reg16(MT9F002_P_RD_P4Q4, 0); + mt9f002_write_reg16(MT9F002_P_BL_P4Q0, 0); + mt9f002_write_reg16(MT9F002_P_BL_P4Q1, 0); + mt9f002_write_reg16(MT9F002_P_BL_P4Q2, 0); + mt9f002_write_reg16(MT9F002_P_BL_P4Q3, 0); + mt9f002_write_reg16(MT9F002_P_BL_P4Q4, 0); + mt9f002_write_reg16(MT9F002_P_GB_P4Q0, 0); + mt9f002_write_reg16(MT9F002_P_GB_P4Q1, 0); + mt9f002_write_reg16(MT9F002_P_GB_P4Q2, 0); + mt9f002_write_reg16(MT9F002_P_GB_P4Q3, 0); + mt9f002_write_reg16(MT9F002_P_GB_P4Q4, 0); - write(fd_i2c, "0\32\0\20", 4); - write(fd_i2c, "0^\0240", 4); - write(fd_i2c, "0\32\0\20", 4); - write(fd_i2c, "0\32\0\20", 4); - write(fd_i2c, "0\32\0\20", 4); - write(fd_i2c, ">\332\345%", 4); - write(fd_i2c, "0\350\0\0", 4); - write(fd_i2c, "0\352\370s", 4); - write(fd_i2c, "0\352\10\252", 4); - write(fd_i2c, "0\3522\31", 4); - write(fd_i2c, "0\3522\31", 4); - write(fd_i2c, "0\3522\31", 4); - write(fd_i2c, "0\3522\0", 4); - write(fd_i2c, "0\3522\0", 4); - write(fd_i2c, "0\3522\0", 4); - write(fd_i2c, "0\3522\0", 4); - write(fd_i2c, "0\3522\0", 4); - write(fd_i2c, "0\352\27i", 4); - write(fd_i2c, "0\352\246\363", 4); - write(fd_i2c, "0\352\246\363", 4); - write(fd_i2c, "0\352\246\363", 4); - write(fd_i2c, "0\352\246\363", 4); - write(fd_i2c, "0\352\246\363", 4); - write(fd_i2c, "0\352\246\363", 4); - write(fd_i2c, "0\352\246\363", 4); - write(fd_i2c, "0\352\257\363", 4); - write(fd_i2c, "0\352\372d", 4); - write(fd_i2c, "0\352\372d", 4); - write(fd_i2c, "0\352\372d", 4); - write(fd_i2c, "0\352\361d", 4); - write(fd_i2c, "0\352\372d", 4); - write(fd_i2c, "0\352\372d", 4); - write(fd_i2c, "0\352\372d", 4); - write(fd_i2c, "0\352\361d", 4); - write(fd_i2c, "0\352'n", 4); - write(fd_i2c, "0\352\30\317", 4); - write(fd_i2c, "0\352\30\317", 4); - write(fd_i2c, "0\352\30\317", 4); - write(fd_i2c, "0\352(\317", 4); - write(fd_i2c, "0\352\30\317", 4); - write(fd_i2c, "0\352\30\317", 4); - write(fd_i2c, "0\352\30\317", 4); - write(fd_i2c, "0\352\30\317", 4); - write(fd_i2c, "0\352#c", 4); - write(fd_i2c, "0\352#c", 4); - write(fd_i2c, "0\352#R", 4); - write(fd_i2c, "0\352#c", 4); - write(fd_i2c, "0\352#c", 4); - write(fd_i2c, "0\352#c", 4); - write(fd_i2c, "0\352#R", 4); - write(fd_i2c, "0\352#R", 4); - write(fd_i2c, "0\352\243\224", 4); - write(fd_i2c, "0\352\243\224", 4); - write(fd_i2c, "0\352\217\217", 4); - write(fd_i2c, "0\352\243\324", 4); - write(fd_i2c, "0\352\243\224", 4); - write(fd_i2c, "0\352\243\224", 4); - write(fd_i2c, "0\352\217\217", 4); - write(fd_i2c, "0\352\217\317", 4); - write(fd_i2c, "0\352\334#", 4); - write(fd_i2c, "0\352\334c", 4); - write(fd_i2c, "0\352\334c", 4); - write(fd_i2c, "0\352\334#", 4); - write(fd_i2c, "0\352\334#", 4); - write(fd_i2c, "0\352\334c", 4); - write(fd_i2c, "0\352\334c", 4); - write(fd_i2c, "0\352\334#", 4); - write(fd_i2c, "0\352\17s", 4); - write(fd_i2c, "0\352\205\300", 4); - write(fd_i2c, "0\352\205\300", 4); - write(fd_i2c, "0\352\205\300", 4); - write(fd_i2c, "0\352\205\300", 4); - write(fd_i2c, "0\352\205\300", 4); - write(fd_i2c, "0\352\205\300", 4); - write(fd_i2c, "0\352\205\300", 4); - write(fd_i2c, "0\352\205\304", 4); - write(fd_i2c, "0\352\0\0", 4); - write(fd_i2c, "1v\200\0", 4); - write(fd_i2c, ">\332\345%", 4); - write(fd_i2c, "0\36\0\250", 4); - write(fd_i2c, "0\32\0\220", 4); - write(fd_i2c, "1\256\3\1", 4); - write(fd_i2c, "0\32\20\220", 4); - write(fd_i2c, "0d\10E", 4); - write(fd_i2c, "0\32\20\200", 4); - write(fd_i2c, "0n\330\200", 4); - write(fd_i2c, "0\32\220\200", 4); - write(fd_i2c, "0n\330\200", 4); - write(fd_i2c, "0\32\20\310", 4); - write(fd_i2c, "0n\330\200", 4); - write(fd_i2c, "\3\0\0\7", 4); - write(fd_i2c, "\3\2\0\1", 4); - write(fd_i2c, "\3\4\0\1", 4); - write(fd_i2c, "\3\6\0;", 4); - write(fd_i2c, "\3\10\0\10", 4); - write(fd_i2c, "\3\n\0\1", 4); + mt9f002_write_reg16(MT9F002_GREEN1_GAIN, 4176); + mt9f002_write_reg16(MT9F002_BLUE_GAIN, 4176); + mt9f002_write_reg16(MT9F002_RED_GAIN, 4176); + mt9f002_write_reg16(MT9F002_GREEN2_GAIN, 4176); + mt9f002_write_reg16(MT9F002_GLOBAL_GAIN, 4176); + mt9f002_write_reg16(MT9F002_ANALOG_GAIN_CODE_GLOBAL, 10); + mt9f002_write_reg16(MT9F002_ANALOG_GAIN_CODE_GREENR, 10); + mt9f002_write_reg16(MT9F002_ANALOG_GAIN_CODE_RED, 10); + mt9f002_write_reg16(MT9F002_ANALOG_GAIN_CODE_BLUE, 10); + mt9f002_write_reg16(MT9F002_ANALOG_GAIN_CODE_GREENB, 10); + mt9f002_write_reg16(MT9F002_CALIB_GREEN1_ASC1, 4224); + mt9f002_write_reg16(MT9F002_CALIB_BLUE_ASC1, 4224); + mt9f002_write_reg16(MT9F002_CALIB_RED_ASC1, 4224); + mt9f002_write_reg16(MT9F002_CALIB_GREEN2_ASC1, 4224); + mt9f002_write_reg16(MT9F002_CALIB_GREEN1, 4224); + mt9f002_write_reg16(MT9F002_CALIB_BLUE, 4224); + mt9f002_write_reg16(MT9F002_CALIB_RED, 4224); + mt9f002_write_reg16(MT9F002_CALIB_GREEN2, 4224); + mt9f002_write_reg16(MT9F002_POLY_ORIGIN_C, 0); + mt9f002_write_reg16(MT9F002_POLY_ORIGIN_R, 0); + mt9f002_write_reg16(MT9F002_P_GR_Q5, 0); + mt9f002_write_reg16(MT9F002_P_RD_Q5, 0); + mt9f002_write_reg16(MT9F002_P_BL_Q5, 0); + mt9f002_write_reg16(MT9F002_P_GB_Q5, 0); + mt9f002_write_reg16(MT9F002_DAC_ID_FBIAS, 57568); + + mt9f002_write_reg16(MT9F002_FRAME_LENGTH_LINES, 3434); + mt9f002_write_reg16(MT9F002_LINE_LENGTH_PCK, 2504); + mt9f002_write_reg16(MT9F002_ROW_SPEED, 273); + mt9f002_write_reg16(MT9F002_MIPI_TIMING_2, 61452); + mt9f002_write_reg16(MT9F002_HISPI_TIMING, 0); + + mt9f002_write_reg16(MT9F002_VT_PIX_CLK_DIV, 6); + mt9f002_write_reg16(MT9F002_PRE_PLL_CLK_DIV, 6); + mt9f002_write_reg16(MT9F002_PLL_MULTIPLIER, 165); + mt9f002_write_reg16(MT9F002_OP_PIX_CLK_DIV, 12); + + mt9f002_write_reg16(MT9F002_X_ADDR_START_, 500); + mt9f002_write_reg16(MT9F002_Y_ADDR_START_, 32); + mt9f002_write_reg16(MT9F002_X_ADDR_END_, 4527); // 4383 cols + mt9f002_write_reg16(MT9F002_Y_ADDR_END_, 3319); // 3287 rows + mt9f002_write_reg16(MT9F002_READ_MODE, 0x06E7); + mt9f002_write_reg16(MT9F002_X_ODD_INC, 3); + mt9f002_write_reg16(MT9F002_Y_ODD_INC, 3); // Sample 1, skip 7 -> /8 + + mt9f002_write_reg16(MT9F002_SCALING_MODE, 2); + mt9f002_write_reg16(MT9F002_SCALE_M, 48); - ioctl(fd_i2c, 0x707, 0xd0); - write(fd_i2c, "0d\10E", 4); + /* Stream mode */ + mt9f002_write_reg8(MT9F002_MODE_SELECT, 0x01); // Stream mode on - ioctl(fd_i2c, 0x707, 0xd0); - write(fd_i2c, "0\26\1!", 4); - write(fd_i2c, "1v\200\0", 4); - write(fd_i2c, "0@\0A", 4); - write(fd_i2c, "0@\4\303", 4); - write(fd_i2c, "0@\4\303", 4); - write(fd_i2c, "1x\0\0", 4); - write(fd_i2c, "1x\0\0", 4); - write(fd_i2c, "1x\0\0", 4); - write(fd_i2c, "1x\0\0", 4); - write(fd_i2c, ">\350\0G", 4); - write(fd_i2c, "0\324\260\200", 4); - write(fd_i2c, "0\324\261\0", 4); - write(fd_i2c, "0\356\0 ", 4); - write(fd_i2c, ">\344cI", 4); - write(fd_i2c, "1|\200\n", 4); - write(fd_i2c, "0\32\220\310", 4); - write(fd_i2c, "0\350\200\5", 4); - write(fd_i2c, "1|\200\n", 4); - write(fd_i2c, ">\350\0G", 4); - write(fd_i2c, ">\352\25\360", 4); - write(fd_i2c, ">\352\25\360", 4); - write(fd_i2c, ">\352\25\360", 4); - write(fd_i2c, ">\350\0G", 4); - write(fd_i2c, ">\350\0G", 4); - write(fd_i2c, "0\32\20\310", 4); - write(fd_i2c, "\2\2\10\303", 4); - write(fd_i2c, "0\260\0\0", 4); - write(fd_i2c, "0n\330\200", 4); - write(fd_i2c, "0@\0A", 4); - write(fd_i2c, "\1\5\1", 3); - write(fd_i2c, "\3L\2\200", 4); - write(fd_i2c, "\3N\1\340", 4); - write(fd_i2c, "\4\0\0\0", 4); - write(fd_i2c, "0@\0A", 4); - write(fd_i2c, "\3\202\0\1", 4); - write(fd_i2c, "\3\206\0\1", 4); - write(fd_i2c, "\3D\0\0", 4); - write(fd_i2c, "\3H\2\177", 4); - write(fd_i2c, "\3F\0\0", 4); - write(fd_i2c, "\3J\1\337", 4); - - write(fd_i2c, "\3B&\340", 4); - write(fd_i2c, "\3@\2\336", 4); - write(fd_i2c, "\2\2\2\224", 4); - write(fd_i2c, "0\24\27M", 4); - write(fd_i2c, "0V\24@", 4); - write(fd_i2c, "0X\24@", 4); - write(fd_i2c, "0Z\24@", 4); - write(fd_i2c, "0\\\24@", 4); - write(fd_i2c, "\1\4\1", 3); - write(fd_i2c, "\3L\2\200", 4); - write(fd_i2c, "\3N\1h", 4); - write(fd_i2c, "\4\0\0\0", 4); - write(fd_i2c, "0@\0A", 4); - write(fd_i2c, "\3\202\0\1", 4); - write(fd_i2c, "\3\206\0\1", 4); - write(fd_i2c, "\3D\0\0", 4); - write(fd_i2c, "\3H\2\177", 4); - write(fd_i2c, "\3F\0\0", 4); - write(fd_i2c, "\3J\1g", 4); - - write(fd_i2c, "\3B&\340", 4); - write(fd_i2c, "\3@\2\336", 4); - write(fd_i2c, "\2\2\2\224", 4); - write(fd_i2c, "0\24\27M", 4); - write(fd_i2c, "\1\4\0", 3); - - write(fd_i2c, "\1\4\1", 3); - write(fd_i2c, "\3B&\340", 4); - write(fd_i2c, "\3@\2\336", 4); - write(fd_i2c, "\2\2\2\224", 4); - write(fd_i2c, "0\24\27M", 4); - write(fd_i2c, "\1\4\0", 3); - write(fd_i2c, "\1\4\1", 3); - write(fd_i2c, "\2\2\0\334", 4); - write(fd_i2c, "0\24\7\304", 4); - write(fd_i2c, "\1\4\0", 3); - write(fd_i2c, "0VL@", 4); - write(fd_i2c, "0XL@", 4); - write(fd_i2c, "0ZL@", 4); - write(fd_i2c, "0\\L@", 4); - write(fd_i2c, "\3N\0\0", 4); - write(fd_i2c, "\1\0\1", 3); - write(fd_i2c, "\1\4\1", 3); - write(fd_i2c, "\3D\7\320", 4); - write(fd_i2c, "\3H\nO", 4); - write(fd_i2c, "\3F\5\310", 4); - write(fd_i2c, "\3J\7/", 4); - write(fd_i2c, "\1\4\0", 3); - - //usleep(1); - write(fd_i2c, "\3N\1h", 4); - write(fd_i2c, "\1\0\1", 3); - close(fd_i2c); } #pragma GCC diagnostic pop /* end disable -Wunused-result */ diff --git a/sw/airborne/modules/computer_vision/bebop_front_camera.c b/sw/airborne/modules/computer_vision/bebop_front_camera.c new file mode 100644 index 0000000000..e7e7cb6fe2 --- /dev/null +++ b/sw/airborne/modules/computer_vision/bebop_front_camera.c @@ -0,0 +1,239 @@ +/* + * Copyright (C) 2012-2014 The Paparazzi Community + * 2015 Freek van Tienen + * + * This file is part of Paparazzi. + * + * Paparazzi 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, or (at your option) + * any later version. + * + * Paparazzi 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 paparazzi; see the file COPYING. If not, see + * . + * + */ + +/** + * @file modules/computer_vision/bebop_front_camera.c + */ + +// Own header +#include "modules/computer_vision/bebop_front_camera.h" + +#include +#include +#include +#include +#include +#include + +// Video +#include "lib/v4l/v4l2.h" +#include "lib/vision/image.h" +#include "lib/vision/bayern.h" +#include "lib/encoding/jpeg.h" +#include "lib/encoding/rtp.h" +#include "udp_socket.h" + +// Threaded computer vision +#include + +#define MT9F002_WIDTH 1408 +#define MT9F002_HEIGHT 2112 +#define BEBOP_FRONT_CAMERA_WIDTH 272 +#define BEBOP_FRONT_CAMERA_HEIGHT 272 + +// The place where the shots are saved (without slash on the end) +#ifndef BEBOP_FRONT_CAMERA_SHOT_PATH +#define BEBOP_FRONT_CAMERA_SHOT_PATH /data/ftp/internal_000/images +#endif +PRINT_CONFIG_VAR(BEBOP_FRONT_CAMERA_SHOT_PATH) + +// Main thread +static void *bebop_front_camera_thread(void *data); +static void bebop_front_camera_save_shot(struct image_t *img_color, struct image_t *img_jpeg, struct image_t *raw_img); +void bebop_front_camera_periodic(void) { } + +// Initialize the bebop_front_camera structure with the defaults +struct viewvideo_t bebop_front_camera = { + .is_streaming = FALSE, + .take_shot = FALSE, + .shot_number = 0 +}; + +void bebop_front_camera_take_shot(bool_t take) +{ + bebop_front_camera.take_shot = TRUE; +} +/** + * Handles all the video streaming and saving of the image shots + * This is a sepereate thread, so it needs to be thread safe! + */ +static void *bebop_front_camera_thread(void *data __attribute__((unused))) +{ + struct UdpSocket video_sock; + udp_socket_create(&video_sock, STRINGIFY(BEBOP_FRONT_CAMERA_HOST), BEBOP_FRONT_CAMERA_PORT_OUT, -1, + BEBOP_FRONT_CAMERA_BROADCAST); + + // Create the JPEG encoded image + struct image_t img_jpeg; + image_create(&img_jpeg, BEBOP_FRONT_CAMERA_WIDTH, BEBOP_FRONT_CAMERA_HEIGHT, IMAGE_JPEG); + + // Create the Color image + struct image_t img_color; + image_create(&img_color, BEBOP_FRONT_CAMERA_WIDTH, BEBOP_FRONT_CAMERA_HEIGHT, IMAGE_YUV422); + + // Start the streaming of the V4L2 device + if (!v4l2_start_capture(bebop_front_camera.dev)) { + printf("[bebop_front_camera-thread] Could not start capture of %s.\n", bebop_front_camera.dev->name); + return 0; + } + + // Start streaming + bebop_front_camera.is_streaming = TRUE; + while (bebop_front_camera.is_streaming) { + // Wait for a new frame (blocking) + struct image_t img; + v4l2_image_get(bebop_front_camera.dev, &img); + + BayernToYUV(&img, &img_color, 0, 0); + + if (bebop_front_camera.take_shot) { + // Save the image + bebop_front_camera_save_shot(&img_color, &img_jpeg, &img); + bebop_front_camera.take_shot = FALSE; + } + + jpeg_encode_image(&img_color, &img_jpeg, 80, 0); + + // Send image with RTP + rtp_frame_send( + &video_sock, // UDP socket + &img_jpeg, + 0, // Format 422 + 80, // Jpeg-Quality + 0, // DRI Header + 0 // 90kHz time increment + ); + + + // Free the image + v4l2_image_free(bebop_front_camera.dev, &img); + } + + return 0; +} + +/** + * Initialize the view video + */ +void bebop_front_camera_init(void) +{ + // Initialize the V4L2 subdevice (TODO: fix hardcoded path, which and code) + if (!v4l2_init_subdev("/dev/v4l-subdev1", 0, 0, V4L2_MBUS_FMT_SGBRG10_1X10, MT9F002_WIDTH, MT9F002_HEIGHT)) { + printf("[bebop_front_camera] Could not initialize the v4l-subdev1 subdevice.\n"); + return; + } + + // Initialize the V4L2 device + bebop_front_camera.dev = v4l2_init("/dev/video1", MT9F002_WIDTH, MT9F002_HEIGHT, 10, V4L2_PIX_FMT_SGBRG10); + if (bebop_front_camera.dev == NULL) { + printf("[bebop_front_camera] Could not initialize the /dev/video1 V4L2 device.\n"); + return; + } + + // Create the shot directory + char save_name[128]; + sprintf(save_name, "mkdir -p %s", STRINGIFY(BEBOP_FRONT_CAMERA_SHOT_PATH)); + if (system(save_name) != 0) { + printf("[bebop_front_camera] Could not create shot directory %s.\n", STRINGIFY(BEBOP_FRONT_CAMERA_SHOT_PATH)); + return; + } +} + +/** + * Start with streaming + */ +void bebop_front_camera_start(void) +{ + // Check if we are already running + if (bebop_front_camera.is_streaming) { + return; + } + + // Start the streaming thread + pthread_t tid; + if (pthread_create(&tid, NULL, bebop_front_camera_thread, NULL) != 0) { + printf("[vievideo] Could not create streaming thread.\n"); + return; + } +} + +/** + * Stops the streaming + * This could take some time, because the thread is stopped asynchronous. + */ +void bebop_front_camera_stop(void) +{ + // Check if not already stopped streaming + if (!bebop_front_camera.is_streaming) { + return; + } + + // Stop the streaming thread + bebop_front_camera.is_streaming = FALSE; + + // Stop the capturing + if (!v4l2_stop_capture(bebop_front_camera.dev)) { + printf("[bebop_front_camera] Could not stop capture of %s.\n", bebop_front_camera.dev->name); + return; + } + + // TODO: wait for the thread to finish to be able to start the thread again! +} + +static void bebop_front_camera_save_shot(struct image_t *img, struct image_t *img_jpeg, struct image_t *raw_img) +{ + + // Search for a file where we can write to + char save_name[128]; + for (; bebop_front_camera.shot_number < 99999; bebop_front_camera.shot_number++) { + sprintf(save_name, "%s/img_%05d.pgm", STRINGIFY(BEBOP_FRONT_CAMERA_SHOT_PATH), bebop_front_camera.shot_number); + // Check if file exists or not + if (access(save_name, F_OK) == -1) { + FILE *fp = fopen(save_name, "w"); + if (fp == NULL) { + printf("[bebop_front_camera-thread] Could not write shot %s.\n", save_name); + } else { + // Save it to the file and close it + char pgm_header[] = "P5\n272 272\n255\n"; + fwrite(pgm_header, sizeof(char), 15, fp); + fwrite(img->buf, sizeof(uint8_t), img->buf_size, fp); + fclose(fp); + + // JPEG + jpeg_encode_image(img, img_jpeg, 99, 1); + sprintf(save_name, "%s/img_%05d.jpg", STRINGIFY(BEBOP_FRONT_CAMERA_SHOT_PATH), bebop_front_camera.shot_number); + fp = fopen(save_name, "w"); + fwrite(img_jpeg->buf, sizeof(uint8_t), img_jpeg->buf_size, fp); + fclose(fp); + + sprintf(save_name, "%s/img_%05d.raw", STRINGIFY(BEBOP_FRONT_CAMERA_SHOT_PATH), bebop_front_camera.shot_number); + fp = fopen(save_name, "w"); + fwrite(raw_img->buf, sizeof(uint8_t), raw_img->buf_size, fp); + fclose(fp); + + } + + // We don't need to seek for a next index anymore + break; + } + } +} diff --git a/sw/airborne/modules/computer_vision/bebop_front_camera.h b/sw/airborne/modules/computer_vision/bebop_front_camera.h new file mode 100644 index 0000000000..68d43d8b9e --- /dev/null +++ b/sw/airborne/modules/computer_vision/bebop_front_camera.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2012-2014 The Paparazzi Community + * 2015 Freek van Tienen + * + * This file is part of Paparazzi. + * + * Paparazzi 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, or (at your option) + * any later version. + * + * Paparazzi 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 paparazzi; see the file COPYING. If not, see + * . + * + */ + +/** + * @file modules/computer_vision/bebop_front_camera.h + * + * Get live images from a RTP/UDP stream + * and save pictures on internal memory + * + * Works on Bebop platforms + */ + +#ifndef BEBOP_FRONT_CAMERA_H +#define BEBOP_FRONT_CAMERA_H + +#include "std.h" +#include "viewvideo.h" + +extern struct viewvideo_t bebop_front_camera; + +// Module functions +extern void bebop_front_camera_init(void); +extern void bebop_front_camera_periodic(void); ///< A dummy for now +extern void bebop_front_camera_start(void); +extern void bebop_front_camera_stop(void); +extern void bebop_front_camera_take_shot(bool_t take); + +#endif /* BEBOP_FRONT_CAMERA_H */ + diff --git a/sw/airborne/modules/computer_vision/lib/encoding/jpeg.c b/sw/airborne/modules/computer_vision/lib/encoding/jpeg.c index 54ca23ef70..a957574fb9 100644 --- a/sw/airborne/modules/computer_vision/lib/encoding/jpeg.c +++ b/sw/airborne/modules/computer_vision/lib/encoding/jpeg.c @@ -432,6 +432,9 @@ void jpeg_encode_image(struct image_t *in, struct image_t *out, uint32_t quality if (in->type == IMAGE_YUV422) { image_format = FOUR_TWO_TWO; } + else if (in->type == IMAGE_GRAYSCALE) { + image_format = FOUR_ZERO_ZERO; + } JPEG_ENCODER_STRUCTURE JpegStruct; JPEG_ENCODER_STRUCTURE *jpeg_encoder_structure = &JpegStruct; diff --git a/sw/airborne/modules/computer_vision/lib/v4l/v4l2.c b/sw/airborne/modules/computer_vision/lib/v4l/v4l2.c index ecd6d498dd..1773d4f866 100644 --- a/sw/airborne/modules/computer_vision/lib/v4l/v4l2.c +++ b/sw/airborne/modules/computer_vision/lib/v4l/v4l2.c @@ -174,7 +174,9 @@ bool_t v4l2_init_subdev(char *subdev_name, uint8_t pad, uint8_t which, uint16_t * @param[in] buffer_cnt The amount of buffers used for mapping * @return The newly create V4L2 device */ -struct v4l2_device *v4l2_init(char *device_name, uint16_t width, uint16_t height, uint8_t buffers_cnt) { +struct v4l2_device *v4l2_init(char *device_name, uint16_t width, uint16_t height, uint8_t buffers_cnt, + uint32_t _pixelformat) +{ uint8_t i; struct v4l2_capability cap; struct v4l2_format fmt; @@ -198,12 +200,12 @@ struct v4l2_device *v4l2_init(char *device_name, uint16_t width, uint16_t height } // Check if the device is capable of capturing and streaming - if (!(cap.capabilities &V4L2_CAP_VIDEO_CAPTURE)) { + if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { printf("[v4l2] %s is no V4L2 video capturing device\n", device_name); close(fd); return NULL; } - if (!(cap.capabilities &V4L2_CAP_STREAMING)) { + if (!(cap.capabilities & V4L2_CAP_STREAMING)) { printf("[v4l2] %s isn't capable of streaming (TODO: support reading)\n", device_name); close(fd); return NULL; @@ -215,7 +217,7 @@ struct v4l2_device *v4l2_init(char *device_name, uint16_t width, uint16_t height fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmt.fmt.pix.width = width; fmt.fmt.pix.height = height; - fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY; + fmt.fmt.pix.pixelformat = _pixelformat; fmt.fmt.pix.field = V4L2_FIELD_NONE; if (ioctl(fd, VIDIOC_S_FMT, &fmt) < 0) { diff --git a/sw/airborne/modules/computer_vision/lib/v4l/v4l2.h b/sw/airborne/modules/computer_vision/lib/v4l/v4l2.h index a428ed9070..a42fb363e6 100644 --- a/sw/airborne/modules/computer_vision/lib/v4l/v4l2.h +++ b/sw/airborne/modules/computer_vision/lib/v4l/v4l2.h @@ -59,7 +59,8 @@ struct v4l2_device { /* External functions */ bool_t v4l2_init_subdev(char *subdev_name, uint8_t pad, uint8_t which, uint16_t code, uint16_t width, uint16_t height); -struct v4l2_device *v4l2_init(char *device_name, uint16_t width, uint16_t height, uint8_t buffers_cnt); +struct v4l2_device *v4l2_init(char *device_name, uint16_t width, uint16_t height, uint8_t buffers_cnt, + uint32_t _pixelformat); void v4l2_image_get(struct v4l2_device *dev, struct image_t *img); bool_t v4l2_image_get_nonblock(struct v4l2_device *dev, struct image_t *img); void v4l2_image_free(struct v4l2_device *dev, struct image_t *img); diff --git a/sw/airborne/modules/computer_vision/lib/vision/bayern.h b/sw/airborne/modules/computer_vision/lib/vision/bayern.h new file mode 100644 index 0000000000..0ee9cf03e3 --- /dev/null +++ b/sw/airborne/modules/computer_vision/lib/vision/bayern.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2012-2014 The Paparazzi Community + * 2015 Freek van Tienen + * + * This file is part of Paparazzi. + * + * Paparazzi 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, or (at your option) + * any later version. + * + * Paparazzi 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 paparazzi; see the file COPYING. If not, see + * . + * + */ + +/** + * @file modules/computer_vision/lib/vision/bayern.c + */ + +#ifndef BAYERN_H +#define BAYERN_H + +#include "lib/vision/image.h" + +static inline uint8_t clip(uint16_t x) +{ + if (x < 0) { + return 0; + } + if (x > 255) { + return 255; + } + return (uint8_t) x; +} + + +void BayernToYUV(struct image_t *Input, struct image_t *out, + int RedX, int RedY); + + +/** + * @brief Decode Bayern Pattern + * @param RedX, RedY the coordinates of the upper-rightmost green pixel + * which has a red pixel next to it and a blue underneath + * + */ + +void BayernToYUV(struct image_t *in, struct image_t *out, + int RedX, int RedY) +{ + uint16_t *ii = (uint8_t *) in->buf; + uint8_t *oi = (uint8_t *) out->buf; + int x, y; + + + for (y = 0; y < out->h; y++) { + for (x = 0; x < out->w; x += 2) { + /* RGB Bayern: + * RBRBRBRBRBRBRBRB + * GRGRGRGRGRGRGRGR + */ + int i = 2 * (out->h - y) + RedX; + int j = 2 * x + RedY; + if ((i < in->w) && (j < in->h)) { + uint16_t G1 = ii[i + j * in->w] / 2; + uint16_t R1 = ii[i + j * in->w + 1] / 2; + uint16_t B1 = ii[i + (j + 1) * in->w] / 2; + j += 2; + uint16_t G2 = ii[i + j * in->w] / 2; + uint16_t R2 = ii[i + j * in->w + 1] / 2; + uint16_t B2 = ii[i + (j + 1) * in->w] / 2; + + uint32_t u, y1, v, y2; + + y1 = (0.256788 * R1 + 0.504129 * G1 + 0.097906 * B1) / 128 + 16; + y2 = (0.256788 * R2 + 0.504129 * G2 + 0.097906 * B2) / 128 + 16; + u = (-0.148223 * (R1 + R2) - 0.290993 * (G1 + G2) + 0.439216 * (B1 + B2)) / 256 + 128; + v = (0.439216 * (R1 + R2) - 0.367788 * (G1 + G2) - 0.071427 * (B1 + B2)) / 256 + 128; + + + oi[(x + y * out->w) * 2] = clip(u); + oi[(x + y * out->w) * 2 + 1] = clip(y1); + oi[(x + y * out->w) * 2 + 2] = clip(v); + oi[(x + y * out->w) * 2 + 3] = clip(y2); + } else { + oi[(x + y * out->w) * 2] = 0; + oi[(x + y * out->w) * 2 + 1] = 0; + oi[(x + y * out->w) * 2 + 2] = 0; + oi[(x + y * out->w) * 2 + 3] = 0; + } + } + } +} + +#endif /* BAYERN_H */ diff --git a/sw/airborne/modules/computer_vision/opticflow_module.c b/sw/airborne/modules/computer_vision/opticflow_module.c index d2ebbf2b80..b82209304f 100644 --- a/sw/airborne/modules/computer_vision/opticflow_module.c +++ b/sw/airborne/modules/computer_vision/opticflow_module.c @@ -127,7 +127,7 @@ void opticflow_module_init(void) #endif /* Try to initialize the video device */ - opticflow_dev = v4l2_init(STRINGIFY(OPTICFLOW_DEVICE), OPTICFLOW_DEVICE_SIZE, OPTICFLOW_DEVICE_BUFFERS); + opticflow_dev = v4l2_init(STRINGIFY(OPTICFLOW_DEVICE), OPTICFLOW_DEVICE_SIZE, OPTICFLOW_DEVICE_BUFFERS,V4L2_PIX_FMT_UYVY); if (opticflow_dev == NULL) { printf("[opticflow_module] Could not initialize the video device\n"); } diff --git a/sw/airborne/modules/computer_vision/viewvideo.c b/sw/airborne/modules/computer_vision/viewvideo.c index 35d7ee0b53..d95fa1e93d 100644 --- a/sw/airborne/modules/computer_vision/viewvideo.c +++ b/sw/airborne/modules/computer_vision/viewvideo.c @@ -311,7 +311,7 @@ void viewvideo_init(void) #endif // Initialize the V4L2 device - viewvideo.dev = v4l2_init(STRINGIFY(VIEWVIDEO_DEVICE), VIEWVIDEO_DEVICE_SIZE, VIEWVIDEO_DEVICE_BUFFERS); + viewvideo.dev = v4l2_init(STRINGIFY(VIEWVIDEO_DEVICE), VIEWVIDEO_DEVICE_SIZE, VIEWVIDEO_DEVICE_BUFFERS, V4L2_PIX_FMT_UYVY); if (viewvideo.dev == NULL) { printf("[viewvideo] Could not initialize the %s V4L2 device.\n", STRINGIFY(VIEWVIDEO_DEVICE)); return;