This is a sample program to check the camera image from the PC application.

Dependencies:   DisplayApp

このサンプルは 「GR-LYCHEE」ではじめる電子工作 で紹介しています。
出版時と内容が異ならないよう、各ライブラリはアップデートせずに使用してください。

このサンプルの最新バージョンは下記から入手できます。最新バージョンは本の内容と一部処理が異なります。
https://github.com/d-kato/GR-Boards_Camera_LCD_sample

Committer:
dkato
Date:
Fri Feb 02 05:59:59 2018 +0000
Revision:
1:0756c0a63a4b
Parent:
0:78f7f7683a42
Use mbed-os-lychee instead of mbed-os library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dkato 0:78f7f7683a42 1 #include "mbed.h"
dkato 0:78f7f7683a42 2 #include "EasyAttach_CameraAndLCD.h"
dkato 0:78f7f7683a42 3 #include "JPEG_Converter.h"
dkato 0:78f7f7683a42 4 #include "dcache-control.h"
dkato 0:78f7f7683a42 5 #include "DisplayApp.h"
dkato 0:78f7f7683a42 6
dkato 0:78f7f7683a42 7 /**** User Selection *********/
dkato 0:78f7f7683a42 8 /** JPEG out setting **/
dkato 0:78f7f7683a42 9 #define JPEG_ENCODE_QUALITY (75) /* JPEG encode quality (min:1, max:75 (Considering the size of JpegBuffer, about 75 is the upper limit.)) */
dkato 0:78f7f7683a42 10 #define VFIELD_INT_SKIP_CNT (0) /* A guide for GR-LYCHEE. 0:60fps, 1:30fps, 2:20fps, 3:15fps, 4:12fps, 5:10fps */
dkato 0:78f7f7683a42 11 /*****************************/
dkato 0:78f7f7683a42 12
dkato 0:78f7f7683a42 13 /*! Frame buffer stride: Frame buffer stride should be set to a multiple of 32 or 128
dkato 0:78f7f7683a42 14 in accordance with the frame buffer burst transfer mode. */
dkato 0:78f7f7683a42 15 #define VIDEO_PIXEL_HW (640u) /* VGA */
dkato 0:78f7f7683a42 16 #define VIDEO_PIXEL_VW (480u) /* VGA */
dkato 0:78f7f7683a42 17
dkato 0:78f7f7683a42 18 #define FRAME_BUFFER_STRIDE (((VIDEO_PIXEL_HW * 2) + 31u) & ~31u)
dkato 0:78f7f7683a42 19 #define FRAME_BUFFER_HEIGHT (VIDEO_PIXEL_VW)
dkato 0:78f7f7683a42 20
dkato 0:78f7f7683a42 21 DisplayBase Display;
dkato 0:78f7f7683a42 22
dkato 0:78f7f7683a42 23 #if defined(__ICCARM__)
dkato 0:78f7f7683a42 24 #pragma data_alignment=32
dkato 0:78f7f7683a42 25 static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * FRAME_BUFFER_HEIGHT]@ ".mirrorram";
dkato 0:78f7f7683a42 26 #pragma data_alignment=32
dkato 0:78f7f7683a42 27 static uint8_t JpegBuffer[2][1024 * 64];
dkato 0:78f7f7683a42 28 #else
dkato 0:78f7f7683a42 29 static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * FRAME_BUFFER_HEIGHT]__attribute((section("NC_BSS"),aligned(32)));
dkato 0:78f7f7683a42 30 static uint8_t JpegBuffer[2][1024 * 64]__attribute((aligned(32)));
dkato 0:78f7f7683a42 31 #endif
dkato 0:78f7f7683a42 32 static size_t jcu_encode_size[2];
dkato 0:78f7f7683a42 33 static JPEG_Converter Jcu;
dkato 0:78f7f7683a42 34 static int jcu_buf_index_write = 0;
dkato 0:78f7f7683a42 35 static int jcu_buf_index_write_done = 0;
dkato 0:78f7f7683a42 36 static int jcu_buf_index_read = 0;
dkato 0:78f7f7683a42 37 static volatile int jcu_encoding = 0;
dkato 0:78f7f7683a42 38 static volatile int image_change = 0;
dkato 0:78f7f7683a42 39 static DisplayApp display_app;
dkato 0:78f7f7683a42 40 static int Vfield_Int_Cnt = 0;
dkato 0:78f7f7683a42 41
dkato 0:78f7f7683a42 42 static void JcuEncodeCallBackFunc(JPEG_Converter::jpeg_conv_error_t err_code) {
dkato 0:78f7f7683a42 43 if (err_code == JPEG_Converter::JPEG_CONV_OK) {
dkato 0:78f7f7683a42 44 jcu_buf_index_write_done = jcu_buf_index_write;
dkato 0:78f7f7683a42 45 image_change = 1;
dkato 0:78f7f7683a42 46 }
dkato 0:78f7f7683a42 47 jcu_encoding = 0;
dkato 0:78f7f7683a42 48 }
dkato 0:78f7f7683a42 49
dkato 0:78f7f7683a42 50 static void snapshot(void) {
dkato 0:78f7f7683a42 51 while ((jcu_encoding == 1) || (image_change == 0)) {
dkato 0:78f7f7683a42 52 Thread::wait(1);
dkato 0:78f7f7683a42 53 }
dkato 0:78f7f7683a42 54 jcu_buf_index_read = jcu_buf_index_write_done;
dkato 0:78f7f7683a42 55 image_change = 0;
dkato 0:78f7f7683a42 56 display_app.SendJpeg(JpegBuffer[jcu_buf_index_read], (int)jcu_encode_size[jcu_buf_index_read]);
dkato 0:78f7f7683a42 57 }
dkato 0:78f7f7683a42 58
dkato 0:78f7f7683a42 59 static void IntCallbackFunc_Vfield(DisplayBase::int_type_t int_type) {
dkato 0:78f7f7683a42 60 if (Vfield_Int_Cnt < VFIELD_INT_SKIP_CNT) {
dkato 0:78f7f7683a42 61 Vfield_Int_Cnt++;
dkato 0:78f7f7683a42 62 return;
dkato 0:78f7f7683a42 63 }
dkato 0:78f7f7683a42 64 Vfield_Int_Cnt = 0;
dkato 0:78f7f7683a42 65
dkato 0:78f7f7683a42 66 //Interrupt callback function
dkato 0:78f7f7683a42 67 if (jcu_encoding == 0) {
dkato 0:78f7f7683a42 68 JPEG_Converter::bitmap_buff_info_t bitmap_buff_info;
dkato 0:78f7f7683a42 69 JPEG_Converter::encode_options_t encode_options;
dkato 0:78f7f7683a42 70
dkato 0:78f7f7683a42 71 bitmap_buff_info.width = VIDEO_PIXEL_HW;
dkato 0:78f7f7683a42 72 bitmap_buff_info.height = VIDEO_PIXEL_VW;
dkato 0:78f7f7683a42 73 bitmap_buff_info.format = JPEG_Converter::WR_RD_YCbCr422;
dkato 0:78f7f7683a42 74 bitmap_buff_info.buffer_address = (void *)user_frame_buffer0;
dkato 0:78f7f7683a42 75
dkato 0:78f7f7683a42 76 encode_options.encode_buff_size = sizeof(JpegBuffer[0]);
dkato 0:78f7f7683a42 77 encode_options.p_EncodeCallBackFunc = &JcuEncodeCallBackFunc;
dkato 0:78f7f7683a42 78 encode_options.input_swapsetting = JPEG_Converter::WR_RD_WRSWA_32_16_8BIT;
dkato 0:78f7f7683a42 79
dkato 0:78f7f7683a42 80 jcu_encoding = 1;
dkato 0:78f7f7683a42 81 if (jcu_buf_index_read == jcu_buf_index_write) {
dkato 0:78f7f7683a42 82 jcu_buf_index_write ^= 1; // toggle
dkato 0:78f7f7683a42 83 }
dkato 0:78f7f7683a42 84 jcu_encode_size[jcu_buf_index_write] = 0;
dkato 0:78f7f7683a42 85 dcache_invalid(JpegBuffer[jcu_buf_index_write], sizeof(JpegBuffer[0]));
dkato 0:78f7f7683a42 86 if (Jcu.encode(&bitmap_buff_info, JpegBuffer[jcu_buf_index_write],
dkato 0:78f7f7683a42 87 &jcu_encode_size[jcu_buf_index_write], &encode_options) != JPEG_Converter::JPEG_CONV_OK) {
dkato 0:78f7f7683a42 88 jcu_encode_size[jcu_buf_index_write] = 0;
dkato 0:78f7f7683a42 89 jcu_encoding = 0;
dkato 0:78f7f7683a42 90 }
dkato 0:78f7f7683a42 91 }
dkato 0:78f7f7683a42 92 }
dkato 0:78f7f7683a42 93
dkato 0:78f7f7683a42 94 static void Start_Video_Camera(void) {
dkato 0:78f7f7683a42 95 // Initialize the background to black
dkato 0:78f7f7683a42 96 for (uint32_t i = 0; i < sizeof(user_frame_buffer0); i += 2) {
dkato 0:78f7f7683a42 97 user_frame_buffer0[i + 0] = 0x10;
dkato 0:78f7f7683a42 98 user_frame_buffer0[i + 1] = 0x80;
dkato 0:78f7f7683a42 99 }
dkato 0:78f7f7683a42 100
dkato 0:78f7f7683a42 101 // Interrupt callback function setting (Field end signal for recording function in scaler 0)
dkato 0:78f7f7683a42 102 Display.Graphics_Irq_Handler_Set(DisplayBase::INT_TYPE_S0_VFIELD, 0, IntCallbackFunc_Vfield);
dkato 0:78f7f7683a42 103
dkato 0:78f7f7683a42 104 // Video capture setting (progressive form fixed)
dkato 0:78f7f7683a42 105 Display.Video_Write_Setting(
dkato 0:78f7f7683a42 106 DisplayBase::VIDEO_INPUT_CHANNEL_0,
dkato 0:78f7f7683a42 107 DisplayBase::COL_SYS_NTSC_358,
dkato 0:78f7f7683a42 108 (void *)user_frame_buffer0,
dkato 0:78f7f7683a42 109 FRAME_BUFFER_STRIDE,
dkato 0:78f7f7683a42 110 DisplayBase::VIDEO_FORMAT_YCBCR422,
dkato 0:78f7f7683a42 111 DisplayBase::WR_RD_WRSWA_32_16BIT,
dkato 0:78f7f7683a42 112 VIDEO_PIXEL_VW,
dkato 0:78f7f7683a42 113 VIDEO_PIXEL_HW
dkato 0:78f7f7683a42 114 );
dkato 0:78f7f7683a42 115 EasyAttach_CameraStart(Display, DisplayBase::VIDEO_INPUT_CHANNEL_0);
dkato 0:78f7f7683a42 116 }
dkato 0:78f7f7683a42 117
dkato 0:78f7f7683a42 118 int main(void) {
dkato 0:78f7f7683a42 119 Jcu.SetQuality(JPEG_ENCODE_QUALITY);
dkato 0:78f7f7683a42 120
dkato 0:78f7f7683a42 121 EasyAttach_Init(Display);
dkato 0:78f7f7683a42 122 Start_Video_Camera();
dkato 0:78f7f7683a42 123
dkato 0:78f7f7683a42 124 while (1) {
dkato 0:78f7f7683a42 125 snapshot();
dkato 0:78f7f7683a42 126 }
dkato 0:78f7f7683a42 127 }