Camera sample for GR-Boads
このサンプルは 「GR-LYCHEE」ではじめる電子工作 で紹介しています。
出版時と内容が異ならないよう、各ライブラリはアップデートせずに使用してください。
このサンプルの最新バージョンは下記から入手できます。最新バージョンは本の内容と一部処理が異なります。
https://github.com/d-kato/GR-Boards_Camera_sample
main.cpp@0:a1daffd30b6d, 2017-10-13 (annotated)
- Committer:
- dkato
- Date:
- Fri Oct 13 11:59:28 2017 +0000
- Revision:
- 0:a1daffd30b6d
- Child:
- 1:be0f952b4551
first commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
dkato | 0:a1daffd30b6d | 1 | #include "mbed.h" |
dkato | 0:a1daffd30b6d | 2 | #include "EasyAttach_CameraAndLCD.h" |
dkato | 0:a1daffd30b6d | 3 | #include "SdUsbConnect.h" |
dkato | 0:a1daffd30b6d | 4 | #include "JPEG_Converter.h" |
dkato | 0:a1daffd30b6d | 5 | #include "dcache-control.h" |
dkato | 0:a1daffd30b6d | 6 | |
dkato | 0:a1daffd30b6d | 7 | #define MOUNT_NAME "storage" |
dkato | 0:a1daffd30b6d | 8 | |
dkato | 0:a1daffd30b6d | 9 | /*! Frame buffer stride: Frame buffer stride should be set to a multiple of 32 or 128 |
dkato | 0:a1daffd30b6d | 10 | in accordance with the frame buffer burst transfer mode. */ |
dkato | 0:a1daffd30b6d | 11 | #define VIDEO_PIXEL_HW (640u) /* VGA */ |
dkato | 0:a1daffd30b6d | 12 | #define VIDEO_PIXEL_VW (480u) /* VGA */ |
dkato | 0:a1daffd30b6d | 13 | |
dkato | 0:a1daffd30b6d | 14 | #define FRAME_BUFFER_STRIDE (((VIDEO_PIXEL_HW * 2) + 31u) & ~31u) |
dkato | 0:a1daffd30b6d | 15 | #define FRAME_BUFFER_HEIGHT (VIDEO_PIXEL_VW) |
dkato | 0:a1daffd30b6d | 16 | |
dkato | 0:a1daffd30b6d | 17 | #if defined(__ICCARM__) |
dkato | 0:a1daffd30b6d | 18 | #pragma data_alignment=32 |
dkato | 0:a1daffd30b6d | 19 | static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * FRAME_BUFFER_HEIGHT]@ ".mirrorram"; |
dkato | 0:a1daffd30b6d | 20 | #else |
dkato | 0:a1daffd30b6d | 21 | static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * FRAME_BUFFER_HEIGHT]__attribute((section("NC_BSS"),aligned(32))); |
dkato | 0:a1daffd30b6d | 22 | #endif |
dkato | 0:a1daffd30b6d | 23 | static int file_name_index = 1; |
dkato | 0:a1daffd30b6d | 24 | static volatile int Vfield_Int_Cnt = 0; |
dkato | 0:a1daffd30b6d | 25 | /* jpeg convert */ |
dkato | 0:a1daffd30b6d | 26 | static JPEG_Converter Jcu; |
dkato | 0:a1daffd30b6d | 27 | #if defined(__ICCARM__) |
dkato | 0:a1daffd30b6d | 28 | #pragma data_alignment=32 |
dkato | 0:a1daffd30b6d | 29 | static uint8_t JpegBuffer[1024 * 63]; |
dkato | 0:a1daffd30b6d | 30 | #else |
dkato | 0:a1daffd30b6d | 31 | static uint8_t JpegBuffer[1024 * 63]__attribute((aligned(32))); |
dkato | 0:a1daffd30b6d | 32 | #endif |
dkato | 0:a1daffd30b6d | 33 | |
dkato | 0:a1daffd30b6d | 34 | DisplayBase Display; |
dkato | 0:a1daffd30b6d | 35 | DigitalIn button0(USER_BUTTON0); |
dkato | 0:a1daffd30b6d | 36 | DigitalOut led1(LED1); |
dkato | 0:a1daffd30b6d | 37 | |
dkato | 0:a1daffd30b6d | 38 | static void IntCallbackFunc_Vfield(DisplayBase::int_type_t int_type) { |
dkato | 0:a1daffd30b6d | 39 | if (Vfield_Int_Cnt > 0) { |
dkato | 0:a1daffd30b6d | 40 | Vfield_Int_Cnt--; |
dkato | 0:a1daffd30b6d | 41 | } |
dkato | 0:a1daffd30b6d | 42 | } |
dkato | 0:a1daffd30b6d | 43 | |
dkato | 0:a1daffd30b6d | 44 | static void wait_new_image(void) { |
dkato | 0:a1daffd30b6d | 45 | Vfield_Int_Cnt = 1; |
dkato | 0:a1daffd30b6d | 46 | while (Vfield_Int_Cnt > 0) { |
dkato | 0:a1daffd30b6d | 47 | Thread::wait(1); |
dkato | 0:a1daffd30b6d | 48 | } |
dkato | 0:a1daffd30b6d | 49 | } |
dkato | 0:a1daffd30b6d | 50 | |
dkato | 0:a1daffd30b6d | 51 | static void Start_Video_Camera(void) { |
dkato | 0:a1daffd30b6d | 52 | // Field end signal for recording function in scaler 0 |
dkato | 0:a1daffd30b6d | 53 | Display.Graphics_Irq_Handler_Set(DisplayBase::INT_TYPE_S0_VFIELD, 0, IntCallbackFunc_Vfield); |
dkato | 0:a1daffd30b6d | 54 | |
dkato | 0:a1daffd30b6d | 55 | // Video capture setting (progressive form fixed) |
dkato | 0:a1daffd30b6d | 56 | Display.Video_Write_Setting( |
dkato | 0:a1daffd30b6d | 57 | DisplayBase::VIDEO_INPUT_CHANNEL_0, |
dkato | 0:a1daffd30b6d | 58 | DisplayBase::COL_SYS_NTSC_358, |
dkato | 0:a1daffd30b6d | 59 | (void *)user_frame_buffer0, |
dkato | 0:a1daffd30b6d | 60 | FRAME_BUFFER_STRIDE, |
dkato | 0:a1daffd30b6d | 61 | DisplayBase::VIDEO_FORMAT_YCBCR422, |
dkato | 0:a1daffd30b6d | 62 | DisplayBase::WR_RD_WRSWA_32_16BIT, |
dkato | 0:a1daffd30b6d | 63 | VIDEO_PIXEL_VW, |
dkato | 0:a1daffd30b6d | 64 | VIDEO_PIXEL_HW |
dkato | 0:a1daffd30b6d | 65 | ); |
dkato | 0:a1daffd30b6d | 66 | EasyAttach_CameraStart(Display, DisplayBase::VIDEO_INPUT_CHANNEL_0); |
dkato | 0:a1daffd30b6d | 67 | } |
dkato | 0:a1daffd30b6d | 68 | |
dkato | 0:a1daffd30b6d | 69 | static void save_image_jpg(void) { |
dkato | 0:a1daffd30b6d | 70 | size_t jcu_encode_size; |
dkato | 0:a1daffd30b6d | 71 | JPEG_Converter::bitmap_buff_info_t bitmap_buff_info; |
dkato | 0:a1daffd30b6d | 72 | JPEG_Converter::encode_options_t encode_options; |
dkato | 0:a1daffd30b6d | 73 | |
dkato | 0:a1daffd30b6d | 74 | bitmap_buff_info.width = VIDEO_PIXEL_HW; |
dkato | 0:a1daffd30b6d | 75 | bitmap_buff_info.height = VIDEO_PIXEL_VW; |
dkato | 0:a1daffd30b6d | 76 | bitmap_buff_info.format = JPEG_Converter::WR_RD_YCbCr422; |
dkato | 0:a1daffd30b6d | 77 | bitmap_buff_info.buffer_address = (void *)user_frame_buffer0; |
dkato | 0:a1daffd30b6d | 78 | |
dkato | 0:a1daffd30b6d | 79 | encode_options.encode_buff_size = sizeof(JpegBuffer); |
dkato | 0:a1daffd30b6d | 80 | encode_options.p_EncodeCallBackFunc = NULL; |
dkato | 0:a1daffd30b6d | 81 | encode_options.input_swapsetting = JPEG_Converter::WR_RD_WRSWA_32_16_8BIT; |
dkato | 0:a1daffd30b6d | 82 | |
dkato | 0:a1daffd30b6d | 83 | jcu_encode_size = 0; |
dkato | 0:a1daffd30b6d | 84 | dcache_invalid(JpegBuffer, sizeof(JpegBuffer)); |
dkato | 0:a1daffd30b6d | 85 | if (Jcu.encode(&bitmap_buff_info, JpegBuffer, &jcu_encode_size, &encode_options) != JPEG_Converter::JPEG_CONV_OK) { |
dkato | 0:a1daffd30b6d | 86 | jcu_encode_size = 0; |
dkato | 0:a1daffd30b6d | 87 | } |
dkato | 0:a1daffd30b6d | 88 | |
dkato | 0:a1daffd30b6d | 89 | char file_name[32]; |
dkato | 0:a1daffd30b6d | 90 | sprintf(file_name, "/"MOUNT_NAME"/img_%d.jpg", file_name_index++); |
dkato | 0:a1daffd30b6d | 91 | FILE * fp = fopen(file_name, "w"); |
dkato | 0:a1daffd30b6d | 92 | fwrite(JpegBuffer, sizeof(char), (int)jcu_encode_size, fp); |
dkato | 0:a1daffd30b6d | 93 | fclose(fp); |
dkato | 0:a1daffd30b6d | 94 | printf("Saved file %s\r\n", file_name); |
dkato | 0:a1daffd30b6d | 95 | } |
dkato | 0:a1daffd30b6d | 96 | |
dkato | 0:a1daffd30b6d | 97 | int main() { |
dkato | 0:a1daffd30b6d | 98 | // Initialize the background to black |
dkato | 0:a1daffd30b6d | 99 | for (uint32_t i = 0; i < sizeof(user_frame_buffer0); i += 2) { |
dkato | 0:a1daffd30b6d | 100 | user_frame_buffer0[i + 0] = 0x10; |
dkato | 0:a1daffd30b6d | 101 | user_frame_buffer0[i + 1] = 0x80; |
dkato | 0:a1daffd30b6d | 102 | } |
dkato | 0:a1daffd30b6d | 103 | |
dkato | 0:a1daffd30b6d | 104 | // Camera |
dkato | 0:a1daffd30b6d | 105 | EasyAttach_Init(Display); |
dkato | 0:a1daffd30b6d | 106 | Start_Video_Camera(); |
dkato | 0:a1daffd30b6d | 107 | |
dkato | 0:a1daffd30b6d | 108 | // SD & USB |
dkato | 0:a1daffd30b6d | 109 | SdUsbConnect storage(MOUNT_NAME); |
dkato | 0:a1daffd30b6d | 110 | |
dkato | 0:a1daffd30b6d | 111 | while (1) { |
dkato | 0:a1daffd30b6d | 112 | storage.wait_connect(); |
dkato | 0:a1daffd30b6d | 113 | if (button0 == 0) { |
dkato | 0:a1daffd30b6d | 114 | wait_new_image(); // wait for image input |
dkato | 0:a1daffd30b6d | 115 | led1 = 1; |
dkato | 0:a1daffd30b6d | 116 | save_image_jpg(); // save as jpeg |
dkato | 0:a1daffd30b6d | 117 | led1 = 0; |
dkato | 0:a1daffd30b6d | 118 | } |
dkato | 0:a1daffd30b6d | 119 | } |
dkato | 0:a1daffd30b6d | 120 | } |