Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed-os-lychee DisplayApp_Base
Diff: main.cpp
- Revision:
- 0:78f7f7683a42
- Child:
- 2:cd21785b6654
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Mon Oct 30 06:52:18 2017 +0000
@@ -0,0 +1,127 @@
+#include "mbed.h"
+#include "EasyAttach_CameraAndLCD.h"
+#include "JPEG_Converter.h"
+#include "dcache-control.h"
+#include "DisplayApp.h"
+
+/**** User Selection *********/
+/** JPEG out setting **/
+#define JPEG_ENCODE_QUALITY (75) /* JPEG encode quality (min:1, max:75 (Considering the size of JpegBuffer, about 75 is the upper limit.)) */
+#define VFIELD_INT_SKIP_CNT (0) /* A guide for GR-LYCHEE. 0:60fps, 1:30fps, 2:20fps, 3:15fps, 4:12fps, 5:10fps */
+/*****************************/
+
+/*! Frame buffer stride: Frame buffer stride should be set to a multiple of 32 or 128
+ in accordance with the frame buffer burst transfer mode. */
+#define VIDEO_PIXEL_HW (640u) /* VGA */
+#define VIDEO_PIXEL_VW (480u) /* VGA */
+
+#define FRAME_BUFFER_STRIDE (((VIDEO_PIXEL_HW * 2) + 31u) & ~31u)
+#define FRAME_BUFFER_HEIGHT (VIDEO_PIXEL_VW)
+
+DisplayBase Display;
+
+#if defined(__ICCARM__)
+#pragma data_alignment=32
+static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * FRAME_BUFFER_HEIGHT]@ ".mirrorram";
+#pragma data_alignment=32
+static uint8_t JpegBuffer[2][1024 * 64];
+#else
+static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * FRAME_BUFFER_HEIGHT]__attribute((section("NC_BSS"),aligned(32)));
+static uint8_t JpegBuffer[2][1024 * 64]__attribute((aligned(32)));
+#endif
+static size_t jcu_encode_size[2];
+static JPEG_Converter Jcu;
+static int jcu_buf_index_write = 0;
+static int jcu_buf_index_write_done = 0;
+static int jcu_buf_index_read = 0;
+static volatile int jcu_encoding = 0;
+static volatile int image_change = 0;
+static DisplayApp display_app;
+static int Vfield_Int_Cnt = 0;
+
+static void JcuEncodeCallBackFunc(JPEG_Converter::jpeg_conv_error_t err_code) {
+ if (err_code == JPEG_Converter::JPEG_CONV_OK) {
+ jcu_buf_index_write_done = jcu_buf_index_write;
+ image_change = 1;
+ }
+ jcu_encoding = 0;
+}
+
+static void snapshot(void) {
+ while ((jcu_encoding == 1) || (image_change == 0)) {
+ Thread::wait(1);
+ }
+ jcu_buf_index_read = jcu_buf_index_write_done;
+ image_change = 0;
+ display_app.SendJpeg(JpegBuffer[jcu_buf_index_read], (int)jcu_encode_size[jcu_buf_index_read]);
+}
+
+static void IntCallbackFunc_Vfield(DisplayBase::int_type_t int_type) {
+ if (Vfield_Int_Cnt < VFIELD_INT_SKIP_CNT) {
+ Vfield_Int_Cnt++;
+ return;
+ }
+ Vfield_Int_Cnt = 0;
+
+ //Interrupt callback function
+ if (jcu_encoding == 0) {
+ JPEG_Converter::bitmap_buff_info_t bitmap_buff_info;
+ JPEG_Converter::encode_options_t encode_options;
+
+ bitmap_buff_info.width = VIDEO_PIXEL_HW;
+ bitmap_buff_info.height = VIDEO_PIXEL_VW;
+ bitmap_buff_info.format = JPEG_Converter::WR_RD_YCbCr422;
+ bitmap_buff_info.buffer_address = (void *)user_frame_buffer0;
+
+ encode_options.encode_buff_size = sizeof(JpegBuffer[0]);
+ encode_options.p_EncodeCallBackFunc = &JcuEncodeCallBackFunc;
+ encode_options.input_swapsetting = JPEG_Converter::WR_RD_WRSWA_32_16_8BIT;
+
+ jcu_encoding = 1;
+ if (jcu_buf_index_read == jcu_buf_index_write) {
+ jcu_buf_index_write ^= 1; // toggle
+ }
+ jcu_encode_size[jcu_buf_index_write] = 0;
+ dcache_invalid(JpegBuffer[jcu_buf_index_write], sizeof(JpegBuffer[0]));
+ if (Jcu.encode(&bitmap_buff_info, JpegBuffer[jcu_buf_index_write],
+ &jcu_encode_size[jcu_buf_index_write], &encode_options) != JPEG_Converter::JPEG_CONV_OK) {
+ jcu_encode_size[jcu_buf_index_write] = 0;
+ jcu_encoding = 0;
+ }
+ }
+}
+
+static void Start_Video_Camera(void) {
+ // Initialize the background to black
+ for (uint32_t i = 0; i < sizeof(user_frame_buffer0); i += 2) {
+ user_frame_buffer0[i + 0] = 0x10;
+ user_frame_buffer0[i + 1] = 0x80;
+ }
+
+ // Interrupt callback function setting (Field end signal for recording function in scaler 0)
+ Display.Graphics_Irq_Handler_Set(DisplayBase::INT_TYPE_S0_VFIELD, 0, IntCallbackFunc_Vfield);
+
+ // Video capture setting (progressive form fixed)
+ Display.Video_Write_Setting(
+ DisplayBase::VIDEO_INPUT_CHANNEL_0,
+ DisplayBase::COL_SYS_NTSC_358,
+ (void *)user_frame_buffer0,
+ FRAME_BUFFER_STRIDE,
+ DisplayBase::VIDEO_FORMAT_YCBCR422,
+ DisplayBase::WR_RD_WRSWA_32_16BIT,
+ VIDEO_PIXEL_VW,
+ VIDEO_PIXEL_HW
+ );
+ EasyAttach_CameraStart(Display, DisplayBase::VIDEO_INPUT_CHANNEL_0);
+}
+
+int main(void) {
+ Jcu.SetQuality(JPEG_ENCODE_QUALITY);
+
+ EasyAttach_Init(Display);
+ Start_Video_Camera();
+
+ while (1) {
+ snapshot();
+ }
+}