DisplayApp-Base

Dependencies:   mbed-os-lychee DisplayApp_Base

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "EasyAttach_CameraAndLCD.h"
00003 #include "JPEG_Converter.h"
00004 #include "dcache-control.h"
00005 #include "DisplayApp.h"
00006 #include "FATFileSystem.h"
00007 
00008 /**** User Selection *********/
00009 /** JPEG out setting **/
00010 #define JPEG_ENCODE_QUALITY    (55)    /* JPEG encode quality (min:1, max:75 (Considering the size of JpegBuffer, about 75 is the upper limit.)) */
00011 #define VFIELD_INT_SKIP_CNT    (1)     /* A guide for GR-LYCHEE.  0:60fps, 1:30fps, 2:20fps, 3:15fps, 4:12fps, 5:10fps */
00012 /*****************************/
00013 
00014 /*! Frame buffer stride: Frame buffer stride should be set to a multiple of 32 or 128
00015     in accordance with the frame buffer burst transfer mode. */
00016 #define VIDEO_PIXEL_HW         (640u)  /* VGA */
00017 #define VIDEO_PIXEL_VW         (480u)  /* VGA */
00018 
00019 #define FRAME_BUFFER_STRIDE    (((VIDEO_PIXEL_HW * 2) + 31u) & ~31u)
00020 #define FRAME_BUFFER_HEIGHT    (VIDEO_PIXEL_VW)
00021 
00022 DisplayBase Display;
00023 
00024 #if defined(__ICCARM__)
00025 #pragma data_alignment=32
00026 static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * FRAME_BUFFER_HEIGHT]@ ".mirrorram";
00027 #pragma data_alignment=32
00028 static uint8_t JpegBuffer[2][1024 * 64];
00029 static uint8_t JpegBuffer_Send[1024 * 64];
00030 #else
00031 static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * FRAME_BUFFER_HEIGHT]__attribute((section("NC_BSS"),aligned(32)));
00032 static uint8_t JpegBuffer[2][1024 * 64]__attribute((aligned(32)));
00033 static uint8_t JpegBuffer_Send[1024 * 64]__attribute((aligned(32)));
00034 #endif
00035 static size_t jcu_encode_size[2];
00036 static JPEG_Converter Jcu;
00037 static int jcu_buf_index_write = 0;
00038 static int jcu_buf_index_write_done = 0;
00039 static int jcu_buf_index_read = 0;
00040 static volatile int jcu_encoding = 0;
00041 static volatile int image_change = 0;
00042 static DisplayApp  display_app;
00043 static int Vfield_Int_Cnt = 0;
00044 
00045 static void JcuEncodeCallBackFunc(JPEG_Converter::jpeg_conv_error_t err_code)
00046 {
00047     if (err_code == JPEG_Converter::JPEG_CONV_OK) {
00048         jcu_buf_index_write_done = jcu_buf_index_write;
00049         image_change = 1;
00050     }
00051     jcu_encoding = 0;
00052 }
00053 
00054 static void snapshot(void)
00055 {
00056 
00057     while ((jcu_encoding == 1) || (image_change == 0)) {
00058         Thread::wait(1);
00059     }
00060     jcu_buf_index_read = jcu_buf_index_write_done;
00061     memcpy(JpegBuffer_Send, JpegBuffer[jcu_buf_index_read],1024 * 64);
00062     image_change = 0;
00063 
00064     display_app.SendJpeg(JpegBuffer_Send, (uint32_t)jcu_encode_size[jcu_buf_index_read]);
00065 }
00066 
00067 static void WaitGetCommand(void)
00068 {
00069     char command;    
00070     command = display_app.Getgetc();
00071            
00072     if(command=='c'){
00073         snapshot();
00074     }
00075 
00076 }
00077 
00078 static void IntCallbackFunc_Vfield(DisplayBase::int_type_t int_type)
00079 {
00080     if (Vfield_Int_Cnt < VFIELD_INT_SKIP_CNT) {
00081         Vfield_Int_Cnt++;
00082         return;
00083     }
00084     Vfield_Int_Cnt = 0;
00085 
00086     //Interrupt callback function
00087     if (jcu_encoding == 0) {
00088         JPEG_Converter::bitmap_buff_info_t bitmap_buff_info;
00089         JPEG_Converter::encode_options_t   encode_options;
00090 
00091         bitmap_buff_info.width              = VIDEO_PIXEL_HW;
00092         bitmap_buff_info.height             = VIDEO_PIXEL_VW;
00093         bitmap_buff_info.format             = JPEG_Converter::WR_RD_YCbCr422;
00094         bitmap_buff_info.buffer_address     = (void *)user_frame_buffer0;
00095 
00096         encode_options.encode_buff_size     = sizeof(JpegBuffer[0]);
00097         encode_options.p_EncodeCallBackFunc = &JcuEncodeCallBackFunc;
00098         encode_options.input_swapsetting    = JPEG_Converter::WR_RD_WRSWA_32_16_8BIT;
00099 
00100         jcu_encoding = 1;
00101         if (jcu_buf_index_read == jcu_buf_index_write) {
00102             jcu_buf_index_write ^= 1;  // toggle
00103         }
00104         jcu_encode_size[jcu_buf_index_write] = 0;
00105         dcache_invalid(JpegBuffer[jcu_buf_index_write], sizeof(JpegBuffer[0]));
00106         if (Jcu.encode(&bitmap_buff_info, JpegBuffer[jcu_buf_index_write],
00107                        &jcu_encode_size[jcu_buf_index_write], &encode_options) != JPEG_Converter::JPEG_CONV_OK) {
00108             jcu_encode_size[jcu_buf_index_write] = 0;
00109             jcu_encoding = 0;
00110         }
00111     }
00112 }
00113 
00114 static void Start_Video_Camera(void)
00115 {
00116     // Initialize the background to black
00117     for (uint32_t i = 0; i < sizeof(user_frame_buffer0); i += 2) {
00118         user_frame_buffer0[i + 0] = 0x10;
00119         user_frame_buffer0[i + 1] = 0x80;
00120     }
00121 
00122     // Interrupt callback function setting (Field end signal for recording function in scaler 0)
00123     Display.Graphics_Irq_Handler_Set(DisplayBase::INT_TYPE_S0_VFIELD, 0, IntCallbackFunc_Vfield);
00124 
00125     // Video capture setting (progressive form fixed)
00126     Display.Video_Write_Setting(
00127         DisplayBase::VIDEO_INPUT_CHANNEL_0,
00128         DisplayBase::COL_SYS_NTSC_358,
00129         (void *)user_frame_buffer0,
00130         FRAME_BUFFER_STRIDE,
00131         DisplayBase::VIDEO_FORMAT_YCBCR422,
00132         DisplayBase::WR_RD_WRSWA_32_16BIT,
00133         VIDEO_PIXEL_VW,
00134         VIDEO_PIXEL_HW
00135     );
00136     EasyAttach_CameraStart(Display, DisplayBase::VIDEO_INPUT_CHANNEL_0);
00137 }
00138 
00139 int main(void)
00140 {
00141     Jcu.SetQuality(JPEG_ENCODE_QUALITY);
00142 
00143     EasyAttach_Init(Display);
00144     Start_Video_Camera();
00145 
00146     while (1) {
00147         WaitGetCommand();  
00148     }
00149 }