トラ技 頒布カメラB(OV7670 FIFO AL422B)の動作確認
.
接続
接続には、3番ピン(SCL)にプルアップ抵抗が必要。10kΩで動作した。そのほかは、直結で問題なかった。
ピント合わせ
レンズ先端が回せるようになっているので、そちらでピントを合わせることができる。 ピントを合わせた後は、ドライバでねじを固定すれば、動かない。
FIFO関連
レジスタの設定
OV7670のVSYNCとAL422のWriteReset(Active Low)が接続されているので、AL422のWriteResetを行うためにVSYNCの信号をネガティブにする必要がある。
WriteReg(REG_COM10,0x02);
容量限界
FIFO(AL422B)は393,216Byteを搭載している。
RGB444/RGB555/RGB666フォーマットで出力した場合、1画素、2Byte使用するため、393,216 / 2 = 196,608画素まで、保存可能。
YUV422フォーマットで出力した場合、2画素、4Byte使用するため、393,216 / (4 / 2) = 196,608画素まで、保存可能(RGBフォーマットと同様の容量となる)。
VGA(640x480) = 307,200画素なので、メモリ内を読み込んでも崩れた画像が出力される。
RGB444/RGB555/RGB666/YUV422では、544x360 = 195,840画素で出力できることが確認できた。 544x360の設定は、下記の解像度の2byte 1pixelの場合のFIFOの容量限界近辺(544x360)を参照のこと。
Bayerフォーマットで出力した場合、1画素、1Byte(ただし、各画素RGBのどれか1色を保持)なので、VGA(640x480) = 307,200画素=Byte < FIFO(AL422B) 393,216Byteとなり、カメラの限界のVGA分の画素を保存できる。
データフォーマット
Linuxのov7670ドライバ及び、トラ技の2012年3月号の設定を元にしている。
定数を新たに設定/変更している部分があるので、参考のコードにそのまま追記してもコンパイルできない場合がある。
RGB444
WriteReg(REG_COM7, COM7_RGB); WriteReg(REG_RGB444, RGB444_ENABLE|RGB444_XBGR); WriteReg(REG_COM15, COM15_R01FE|COM15_RGB444); WriteReg(REG_COM1, 0x40); // Magic reserved bit WriteReg(REG_COM9, 0x38); // 16x gain ceiling; 0x8 is reserved bit WriteReg(0x4f, 0xb3); // "matrix coefficient 1" WriteReg(0x50, 0xb3); // "matrix coefficient 2" WriteReg(0x51, 0x00); // vb WriteReg(0x52, 0x3d); // "matrix coefficient 4" WriteReg(0x53, 0xa7); // "matrix coefficient 5" WriteReg(0x54, 0xe4); // "matrix coefficient 6" WriteReg(REG_COM13, COM13_GAMMA|COM13_UVSAT|0x2); // Magic rsvd bit WriteReg(REG_TSLB, 0x04);
取得したデータをRGB888に変換する場合。
d1 = camera.ReadOneByte(); d2 = camera.ReadOneByte(); // RGB444 to RGB888 b = (d1 & 0x0F) << 4; g = (d2 & 0xF0); r = (d2 & 0x0F) << 4;
RGB555
WriteReg(REG_COM7, COM7_RGB); WriteReg(REG_RGB444, RGB444_DISABLE); WriteReg(REG_COM15, COM15_RGB555|COM15_R00FF); WriteReg(REG_TSLB, 0x04); WriteReg(REG_COM1, 0x00); WriteReg(REG_COM9, 0x38); // 16x gain ceiling; 0x8 is reserved bit WriteReg(0x4f, 0xb3); // "matrix coefficient 1" WriteReg(0x50, 0xb3); // "matrix coefficient 2" WriteReg(0x51, 0x00); // vb WriteReg(0x52, 0x3d); // "matrix coefficient 4" WriteReg(0x53, 0xa7); // "matrix coefficient 5" WriteReg(0x54, 0xe4); // "matrix coefficient 6" WriteReg(REG_COM13, COM13_GAMMA|COM13_UVSAT);
取得したデータをRGB888に変換する場合。
d1 = camera.ReadOneByte(); d2 = camera.ReadOneByte(); // RGB555 to RGB888 b = (d1 & 0x1F) << 3; g = (((d1 & 0xE0) >> 2) | ((d2 & 0x03) << 6)); r = (d2 & 0x7c) << 1;
RGB565
WriteReg(REG_COM7, COM7_RGB); WriteReg(REG_RGB444, RGB444_DISABLE); WriteReg(REG_COM15, COM15_R00FF|COM15_RGB565); WriteReg(REG_TSLB, 0x04); WriteReg(REG_COM1, 0x00); WriteReg(REG_COM9, 0x38); // 16x gain ceiling; 0x8 is reserved bit WriteReg(0x4f, 0xb3); // "matrix coefficient 1" WriteReg(0x50, 0xb3); // "matrix coefficient 2" WriteReg(0x51, 0x00); // vb WriteReg(0x52, 0x3d); // "matrix coefficient 4" WriteReg(0x53, 0xa7); // "matrix coefficient 5" WriteReg(0x54, 0xe4); // "matrix coefficient 6" WriteReg(REG_COM13, COM13_GAMMA|COM13_UVSAT);
取得したデータをRGB888に変換する場合。
d1 = camera.ReadOneByte(); d2 = camera.ReadOneByte(); // RGB565 to RGB888 b = (d1 & 0x1F) << 3; g = (((d1 & 0xE0) >> 3) | ((d2 & 0x07) << 5)); r = (d2 & 0xF8);
YUV422
WriteReg(REG_COM7, COM7_YUV); WriteReg(REG_RGB444, RGB444_DISABLE); WriteReg(REG_COM15, COM15_R00FF); WriteReg(REG_TSLB, 0x04); // WriteReg(REG_TSLB, 0x14); //この部分を有効にすると、UVの値を0x00固定できるので、 // WriteReg(REG_MANU, 0x00); //グレースケールの画像が取得できる。 // WriteReg(REG_MANV, 0x00); WriteReg(REG_COM1, 0x00); WriteReg(REG_COM9, 0x18); // 4x gain ceiling; 0x8 is reserved bit WriteReg(0x4f, 0x80); // "matrix coefficient 1" WriteReg(0x50, 0x80); // "matrix coefficient 2" WriteReg(0x51, 0x00); // vb WriteReg(0x52, 0x22); // "matrix coefficient 4" WriteReg(0x53, 0x5e); // "matrix coefficient 5" WriteReg(0x54, 0x80); // "matrix coefficient 6" WriteReg(REG_COM13, COM13_GAMMA|COM13_UVSAT|COM13_UVSWAP);
取得したデータをRGB888に変換する場合。 データを確認したところ、Yのレンジは0-255までのようなので、下記の変換式を使ってRGB888に変換できた。
シフト演算と論理演算で効率化したいところだが、飽和計算のアルゴリズムが思い浮かばなかったので、非効率なままとしている。
U0 = camera.ReadOneByte(); Y0 = camera.ReadOneByte(); V0 = camera.ReadOneByte(); Y1 = camera.ReadOneByte(); b0 = Y0 + 1.77200 * (U0 - 128); g0 = Y0 - 0.34414 * (U0 - 128) - 0.71414 * (V0 - 128); r0 = Y0 + 1.40200 * (V0 - 128); b1 = Y1 + 1.77200 * (U0 - 128); g1 = Y1 - 0.34414 * (U0 - 128) - 0.71414 * (V0 - 128); r1 = Y1 + 1.40200 * (V0 - 128); b0 = min(max(b0, 0), 255); g0 = min(max(g0, 0), 255); r0 = min(max(r0, 0), 255); b1 = min(max(b1, 0), 255); g1 = min(max(g1, 0), 255); r1 = min(max(r1, 0), 255);
Bayer RGB
int reg_com7 = ReadReg(REG_COM7); WriteReg(REG_COM7, reg_com7|COM7_PBAYER); WriteReg(REG_RGB444, RGB444_DISABLE); WriteReg(REG_COM15, COM15_R00FF); WriteReg(REG_TSLB, 0x04); WriteReg(REG_COM13, 0x08); /* No gamma, magic rsvd bit */ WriteReg(REG_COM16, 0x3d); /* Edge enhancement, denoise */ WriteReg(REG_REG76, 0xe1); /* Pix correction, magic rsvd */
取得したデータをRGB888に変換する場合。 アド・サイエンス: ベイヤーパターンカメラとは? RGBカラー画像への変換方法というページを参考にして、変換を行った。
unsigned char *bayer_line[2]; //操作行列を入れ替えるためのポインタ unsigned char *bayer_line_data[2]; //画像1行分のRGB情報を格納する2行分 for(int i=0; i<2; i++) { if((bayer_line_data[i] = (unsigned char *)malloc(sizeof(unsigned char)*sizex)) == NULL){ fprintf(stderr, "Error: Allocation error.\n"); return 1; } } // 1行目の処理 for (int x=0; x<sizex; x++) { // odd line GBGB... even line RGRG... bayer_line_data[0][x] = (unsigned char)camera.ReadOneByte(); } bayer_line[1] = bayer_line_data[0]; // 2行目以降の処理 for (int y=1; y<sizey; y++) { int line = y%2; for (int x=0; x<sizex; x++) { // odd line GBGB... even line RGRG... bayer_line_data[line][x] = (unsigned char)camera.ReadOneByte(); } // 操作行列のindex入れ替え bayer_line[0] = bayer_line[1]; bayer_line[1] = bayer_line_data[line]; for (int x=0; x<sizex - 1; x++) { if(y%2==1) { if(x%2==0) { // GB // RG b = bayer_line[0][x+1]; g = ((int)bayer_line[0][x] + bayer_line[1][x+1])>>1; r = bayer_line[1][x]; } else { // BG // GR b = bayer_line[0][x]; g = ((int)bayer_line[0][x+1] + bayer_line[1][x])>>1; r = bayer_line[1][x+1]; } } else { if(x%2==0) { // RG // GB b = bayer_line[1][x+1]; g = ((int)bayer_line[0][x+1] + bayer_line[1][x])>>1; r = bayer_line[0][x]; } else { // GR // BG b = bayer_line[1][x]; g = ((int)bayer_line[0][x] + bayer_line[1][x+1])>>1; r = bayer_line[0][x+1]; } } } }
生成したbitmapファイルBayer VGAトラ技の表紙とワイヤーストリッパーを映してみた。
また、Bayerフォーマットの場合、QVGA、QQVGAの設定だと、正常に画像出力できなかった。
原因は不明。
解像度
Linuxのov7670ドライバ及び、トラ技の2012年3月号の設定を元にしている。
定数を新たに設定/変更している部分があるので、参考のコードにそのまま追記してもコンパイルできない場合がある。
トラ技の設定は、すべてREG_HREFでエッジオフセット設定されているが、設定しないことでTSLBで、ネガポジ反転しなくても良くなった。 QQVGAは、エッジオフセット設定を残したままにしている。
VGA(640x480)
※FIFOの容量の関係で、Bayerフォーマット指定時のみ、画像取得できる。
WriteReg(REG_COM7,COM7_VGA); WriteReg(REG_HSTART,HSTART_VGA); WriteReg(REG_HSTOP,HSTOP_VGA); WriteReg(REG_HREF,HREF_VGA); WriteReg(REG_VSTART,VSTART_VGA); WriteReg(REG_VSTOP,VSTOP_VGA); WriteReg(REG_VREF,VREF_VGA); WriteReg(REG_COM3, COM3_VGA); WriteReg(REG_COM14, COM14_VGA); WriteReg(REG_SCALING_XSC, SCALING_XSC_VGA); WriteReg(REG_SCALING_YSC, SCALING_YSC_VGA); WriteReg(REG_SCALING_DCWCTR, SCALING_DCWCTR_VGA); WriteReg(REG_SCALING_PCLK_DIV, SCALING_PCLK_DIV_VGA); WriteReg(REG_SCALING_PCLK_DELAY, SCALING_PCLK_DELAY_VGA);
2Byte 1pixelの場合のFIFOの容量限界近辺のサイズ(544x360)
WriteReg(REG_COM7,COM7_VGA); WriteReg(REG_HSTART,HSTART_VGA); WriteReg(REG_HSTOP,HSTOP_VGA); WriteReg(REG_HREF,HREF_VGA); WriteReg(REG_VSTART,VSTART_VGA); WriteReg(REG_VSTOP,VSTOP_VGA); WriteReg(REG_VREF,VREF_VGA); WriteReg(REG_COM3, COM3_VGA); WriteReg(REG_COM14, COM14_VGA); WriteReg(REG_SCALING_XSC, SCALING_XSC_VGA); WriteReg(REG_SCALING_YSC, SCALING_YSC_VGA); WriteReg(REG_SCALING_DCWCTR, SCALING_DCWCTR_VGA); WriteReg(REG_SCALING_PCLK_DIV, SCALING_PCLK_DIV_VGA); WriteReg(REG_SCALING_PCLK_DELAY, SCALING_PCLK_DELAY_VGA); WriteReg(REG_HSTART, 0x17); WriteReg(REG_HSTOP, 0x5b); WriteReg(REG_VSTART, 0x12); WriteReg(REG_VSTOP, 0x6c);
(HREF, VREFの設定も厳密にした方が良いかもしれない。)
VGAの4分の3サイズ(480x360)
WriteReg(REG_COM7,COM7_VGA); WriteReg(REG_HSTART,HSTART_VGA); WriteReg(REG_HSTOP,HSTOP_VGA); WriteReg(REG_HREF,HREF_VGA); WriteReg(REG_VSTART,VSTART_VGA); WriteReg(REG_VSTOP,VSTOP_VGA); WriteReg(REG_VREF,VREF_VGA); WriteReg(REG_COM3, COM3_VGA); WriteReg(REG_COM14, COM14_VGA); WriteReg(REG_SCALING_XSC, SCALING_XSC_VGA); WriteReg(REG_SCALING_YSC, SCALING_YSC_VGA); WriteReg(REG_SCALING_DCWCTR, SCALING_DCWCTR_VGA); WriteReg(REG_SCALING_PCLK_DIV, SCALING_PCLK_DIV_VGA); WriteReg(REG_SCALING_PCLK_DELAY, SCALING_PCLK_DELAY_VGA); WriteReg(REG_HSTART, 0x1b); WriteReg(REG_HSTOP, 0x57); WriteReg(REG_VSTART, 0x12); WriteReg(REG_VSTOP, 0x6c);
QVGA
WriteReg(REG_COM7,COM7_QVGA); WriteReg(REG_HSTART,HSTART_QVGA); WriteReg(REG_HSTOP,HSTOP_QVGA); WriteReg(REG_HREF,HREF_QVGA); WriteReg(REG_VSTART,VSTART_QVGA); WriteReg(REG_VSTOP,VSTOP_QVGA); WriteReg(REG_VREF,VREF_QVGA); WriteReg(REG_COM3, COM3_QVGA); WriteReg(REG_COM14, COM14_QVGA); WriteReg(REG_SCALING_XSC, SCALING_XSC_QVGA); WriteReg(REG_SCALING_YSC, SCALING_YSC_QVGA); WriteReg(REG_SCALING_DCWCTR, SCALING_DCWCTR_QVGA); WriteReg(REG_SCALING_PCLK_DIV, SCALING_PCLK_DIV_QVGA); WriteReg(REG_SCALING_PCLK_DELAY, SCALING_PCLK_DELAY_QVGA);
QQVGA
WriteReg(REG_COM7,COM7_QQVGA); WriteReg(REG_HSTART,HSTART_QQVGA); WriteReg(REG_HSTOP,HSTOP_QQVGA); WriteReg(REG_HREF,HREF_QQVGA); WriteReg(REG_VSTART,VSTART_QQVGA); WriteReg(REG_VSTOP,VSTOP_QQVGA); WriteReg(REG_VREF,VREF_QQVGA); WriteReg(REG_COM3, COM3_QQVGA); WriteReg(REG_COM14, COM14_QQVGA); WriteReg(REG_SCALING_XSC, SCALING_XSC_QQVGA); WriteReg(REG_SCALING_YSC, SCALING_YSC_QQVGA); WriteReg(REG_SCALING_DCWCTR, SCALING_DCWCTR_QQVGA); WriteReg(REG_SCALING_PCLK_DIV, SCALING_PCLK_DIV_QQVGA); WriteReg(REG_SCALING_PCLK_DELAY, SCALING_PCLK_DELAY_QQVGA);
デフォルト設定
Linuxドライバのデフォルト設定から、不都合なものを除外した設定。
// Gamma curve values WriteReg(0x7a, 0x20); WriteReg(0x7b, 0x10); WriteReg(0x7c, 0x1e); WriteReg(0x7d, 0x35); WriteReg(0x7e, 0x5a); WriteReg(0x7f, 0x69); WriteReg(0x80, 0x76); WriteReg(0x81, 0x80); WriteReg(0x82, 0x88); WriteReg(0x83, 0x8f); WriteReg(0x84, 0x96); WriteReg(0x85, 0xa3); WriteReg(0x86, 0xaf); WriteReg(0x87, 0xc4); WriteReg(0x88, 0xd7); WriteReg(0x89, 0xe8); // AGC and AEC parameters. Note we start by disabling those features, //then turn them only after tweaking the values. WriteReg(REG_COM8, COM8_FASTAEC | COM8_AECSTEP | COM8_BFILT); WriteReg(REG_GAIN, 0); WriteReg(REG_AECH, 0); WriteReg(REG_COM4, 0x40); // magic reserved bit WriteReg(REG_COM9, 0x18); // 4x gain + magic rsvd bit WriteReg(REG_BD50MAX, 0x05); WriteReg(REG_BD60MAX, 0x07); WriteReg(REG_AEW, 0x95); WriteReg(REG_AEB, 0x33); WriteReg(REG_VPT, 0xe3); WriteReg(REG_HAECC1, 0x78); WriteReg(REG_HAECC2, 0x68); WriteReg(0xa1, 0x03); // magic WriteReg(REG_HAECC3, 0xd8); WriteReg(REG_HAECC4, 0xd8); WriteReg(REG_HAECC5, 0xf0); WriteReg(REG_HAECC6, 0x90); WriteReg(REG_HAECC7, 0x94); WriteReg(REG_COM8, COM8_FASTAEC|COM8_AECSTEP|COM8_BFILT|COM8_AGC|COM8_AEC); // Almost all of these are magic "reserved" values. WriteReg(REG_COM5, 0x61); WriteReg(REG_COM6, 0x4b); WriteReg(0x16, 0x02); WriteReg(REG_MVFP, 0x07); WriteReg(0x21, 0x02); WriteReg(0x22, 0x91); WriteReg(0x29, 0x07); WriteReg(0x33, 0x0b); WriteReg(0x35, 0x0b); WriteReg(0x37, 0x1d); WriteReg(0x38, 0x71); WriteReg(0x39, 0x2a); WriteReg(REG_COM12, 0x78); WriteReg(0x4d, 0x40); WriteReg(0x4e, 0x20); WriteReg(REG_GFIX, 0); WriteReg(0x6b, 0x0a); WriteReg(0x74, 0x10); WriteReg(0x8d, 0x4f); WriteReg(0x8e, 0); WriteReg(0x8f, 0); WriteReg(0x90, 0); WriteReg(0x91, 0); WriteReg(0x96, 0); WriteReg(0x9a, 0); WriteReg(0xb0, 0x84); WriteReg(0xb1, 0x0c); WriteReg(0xb2, 0x0e); WriteReg(0xb3, 0x82); WriteReg(0xb8, 0x0a); // More reserved magic, some of which tweaks white balance WriteReg(0x43, 0x0a); WriteReg(0x44, 0xf0); WriteReg(0x45, 0x34); WriteReg(0x46, 0x58); WriteReg(0x47, 0x28); WriteReg(0x48, 0x3a); WriteReg(0x59, 0x88); WriteReg(0x5a, 0x88); WriteReg(0x5b, 0x44); WriteReg(0x5c, 0x67); WriteReg(0x5d, 0x49); WriteReg(0x5e, 0x0e); WriteReg(0x6c, 0x0a); WriteReg(0x6d, 0x55); WriteReg(0x6e, 0x11); WriteReg(0x6f, 0x9f); // "9e for advance AWB" WriteReg(0x6a, 0x40); WriteReg(REG_BLUE, 0x40); WriteReg(REG_RED, 0x60); WriteReg(REG_COM8, COM8_FASTAEC|COM8_AECSTEP|COM8_BFILT|COM8_AGC|COM8_AEC|COM8_AWB); // Matrix coefficients WriteReg(0x4f, 0x80); WriteReg(0x50, 0x80); WriteReg(0x51, 0); WriteReg(0x52, 0x22); WriteReg(0x53, 0x5e); WriteReg(0x54, 0x80); WriteReg(0x58, 0x9e); WriteReg(REG_COM16, COM16_AWBGAIN); WriteReg(REG_EDGE, 0); WriteReg(0x75, 0x05); WriteReg(0x76, 0xe1); WriteReg(0x4c, 0); WriteReg(0x77, 0x01); WriteReg(0x4b, 0x09); WriteReg(0xc9, 0x60); WriteReg(REG_COM16, 0x38); WriteReg(0x56, 0x40); WriteReg(0x34, 0x11); WriteReg(REG_COM11, COM11_EXP|COM11_HZAUTO_ON); WriteReg(0xa4, 0x88); WriteReg(0x96, 0); WriteReg(0x97, 0x30); WriteReg(0x98, 0x20); WriteReg(0x99, 0x30); WriteReg(0x9a, 0x84); WriteReg(0x9b, 0x29); WriteReg(0x9c, 0x03); WriteReg(0x9d, 0x4c); WriteReg(0x9e, 0x3f); WriteReg(0x78, 0x04); // Extra-weird stuff. Some sort of multiplexor register WriteReg(0x79, 0x01); WriteReg(0xc8, 0xf0); WriteReg(0x79, 0x0f); WriteReg(0xc8, 0x00); WriteReg(0x79, 0x10); WriteReg(0xc8, 0x7e); WriteReg(0x79, 0x0a); WriteReg(0xc8, 0x80); WriteReg(0x79, 0x0b); WriteReg(0xc8, 0x01); WriteReg(0x79, 0x0c); WriteReg(0xc8, 0x0f); WriteReg(0x79, 0x0d); WriteReg(0xc8, 0x20); WriteReg(0x79, 0x09); WriteReg(0xc8, 0x80); WriteReg(0x79, 0x02); WriteReg(0xc8, 0xc0); WriteReg(0x79, 0x03); WriteReg(0xc8, 0x40); WriteReg(0x79, 0x05); WriteReg(0xc8, 0x30); WriteReg(0x79, 0x26);
定数表
// size register #define REG_COM7 0x12 /* Control 7 */ #define REG_HSTART 0x17 /* Horiz start high bits */ #define REG_HSTOP 0x18 /* Horiz stop high bits */ #define REG_HREF 0x32 /* HREF pieces */ #define REG_VSTART 0x19 /* Vert start high bits */ #define REG_VSTOP 0x1a /* Vert stop high bits */ #define REG_VREF 0x03 /* Pieces of GAIN, VSTART, VSTOP */ #define REG_COM3 0x0c /* Control 3 */ #define REG_COM14 0x3e /* Control 14 */ #define REG_SCALING_XSC 0x70 #define REG_SCALING_YSC 0x71 #define REG_SCALING_DCWCTR 0x72 #define REG_SCALING_PCLK_DIV 0x73 #define REG_SCALING_PCLK_DELAY 0xa2 // VGA setting #define COM7_VGA 0x00 #define HSTART_VGA 0x13 #define HSTOP_VGA 0x01 #define HREF_VGA 0x36 #define VSTART_VGA 0x02 #define VSTOP_VGA 0x7a #define VREF_VGA 0x0a #define COM3_VGA 0x00 #define COM14_VGA 0x00 #define SCALING_XSC_VGA 0x3a #define SCALING_YSC_VGA 0x35 #define SCALING_DCWCTR_VGA 0x11 #define SCALING_PCLK_DIV_VGA 0xf0 #define SCALING_PCLK_DELAY_VGA 0x02 // QVGA setting #define COM7_QVGA 0x00 #define HSTART_QVGA 0x16 #define HSTOP_QVGA 0x04 #define HREF_QVGA 0x00 #define VSTART_QVGA 0x02 #define VSTOP_QVGA 0x7a #define VREF_QVGA 0x0a #define COM3_QVGA 0x04 #define COM14_QVGA 0x19 #define SCALING_XSC_QVGA 0x3a #define SCALING_YSC_QVGA 0x35 #define SCALING_DCWCTR_QVGA 0x11 #define SCALING_PCLK_DIV_QVGA 0xf1 #define SCALING_PCLK_DELAY_QVGA 0x02 // QQVGA setting #define COM7_QQVGA 0x00 #define HSTART_QQVGA 0x16 #define HSTOP_QQVGA 0x04 #define HREF_QQVGA 0xa4 //0x24? 0xa4? #define VSTART_QQVGA 0x02 #define VSTOP_QQVGA 0x7a #define VREF_QQVGA 0x0a #define COM3_QQVGA 0x04 #define COM14_QQVGA 0x1a #define SCALING_XSC_QQVGA 0x3a #define SCALING_YSC_QQVGA 0x35 #define SCALING_DCWCTR_QQVGA 0x22 #define SCALING_PCLK_DIV_QQVGA 0xf2 #define SCALING_PCLK_DELAY_QQVGA 0x02 // YUV #define REG_COM13 0x3d /* Control 13 */ #define REG_TSLB 0x3a /* lots of stuff */ #define COM7_YUV 0x00 /* YUV */ #define COM13_UV 0x00 /* U before V - w/TSLB */ #define COM13_UVSWAP 0x01 /* V before U - w/TSLB */ #define TSLB_VLAST 0x00 /* YUYV - see com13 */ #define TSLB_ULAST 0x00 /* YVYU - see com13 */ #define TSLB_YLAST 0x08 /* UYVY or VYUY - see com13 */ // RGB #define COM7_RGB 0x04 /* bits 0 and 2 - RGB format */ // RGB444 #define REG_RGB444 0x8c /* RGB 444 control */ #define REG_COM15 0x40 /* Control 15 */ #define RGB444_ENABLE 0x02 /* Turn on RGB444, overrides 5x5 */ #define RGB444_XBGR 0x00 #define RGB444_BGRX 0x01 /* Empty nibble at end */ #define COM15_RGB444 0x10 /* RGB444 output */ // RGB555 #define RGB444_DISABLE 0x00 /* Turn off RGB444, overrides 5x5 */ #define COM15_RGB555 0x30 /* RGB555 output */ // RGB565 #define COM15_RGB565 0x10 /* RGB565 output */ // Bayer RGB #define COM7_BAYER 0x01 /* Bayer format */ #define COM7_PBAYER 0x05 /* "Processed bayer" */ // data format #define COM15_R10F0 0x00 /* Data range 10 to F0 */ #define COM15_R01FE 0x80 /* 01 to FE */ #define COM15_R00FF 0xc0 /* 00 to FF */
bitmapファイル
実際にmbed内でbitmapファイル化した画像データ集
上記の設定の組み合わせて、トラ技の2012年3月号の表紙を保存してみた。
RGB444 2Byte 1pixelの場合のFIFOの容量限界近辺のサイズ(544x360)
RGB555 2Byte 1pixelの場合のFIFOの容量限界近辺のサイズ(544x360)
RGB565 2Byte 1pixelの場合のFIFOの容量限界近辺のサイズ(544x360)
YUV422 2Byte 1pixelの場合のFIFOの容量限界近辺のサイズ(544x360)
検証に使用したコードはこちら。
Import programOV7670_with_AL422B_Color_Size_test
OV7670_with_AL422B Color & Size Test Program
参考
Import programOV7670_with_AL422B_QQVGA_test
OV7670 with FIFO AL422B (TORAGI Camera TYPE B) test program
OV7670+FIFOカメラモジュール(SCCBインタフェース)
HR2_blog: mbedでトラ技3月号の頒布カメラBを使う
Robot No.8080のブログ: mbed + トラ技カメラBの実験。(その1)
2 comments on トラ技 頒布カメラB(OV7670 FIFO AL422B)の動作確認:
Please log in to post comments.
何のマイコンを利用している?