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
main.cpp
- Committer:
- yagyag
- Date:
- 2018-11-16
- Revision:
- 3:6289f0adb6c9
- Parent:
- 2:cd21785b6654
- Child:
- 4:b75d4cd51099
File content as of revision 3:6289f0adb6c9:
#include "mbed.h"
#include "EasyAttach_CameraAndLCD.h"
#include "JPEG_Converter.h"
#include "dcache-control.h"
#include "DisplayApp.h"
#include "FATFileSystem.h"
/**** User Selection *********/
/** JPEG out setting **/
#define JPEG_ENCODE_QUALITY (55) /* JPEG encode quality (min:1, max:75 (Considering the size of JpegBuffer, about 75 is the upper limit.)) */
#define VFIELD_INT_SKIP_CNT (1) /* 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];
static uint8_t JpegBuffer_Send[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)));
static uint8_t JpegBuffer_Send[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;
Ticker flipper;
static int interCnt = 0; //割り込み発生回数
static int sendCnt = 0; //画像データを送信した回数
DigitalOut led1(LED1);
DigitalOut led2(LED2);
static void incrementInterCnt()
{
interCnt++;
}
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)
{
//JPEGにエンコード中 or エンコード未完了
while ((jcu_encoding == 1) || (image_change == 0)) {
Thread::wait(1);
}
jcu_buf_index_read = jcu_buf_index_write_done;
//画像データをコピー(JpegBufferは他から書き換えられる可能性があるため)
memcpy(JpegBuffer_Send, JpegBuffer[jcu_buf_index_read],1024 * 64);
image_change = 0;
if(interCnt != sendCnt) {
led2 = !led2;
sendCnt = interCnt;
//撮影した画像データ(JPEG)をPCにUSBシリアル通信で転送
display_app.SendJpeg(JpegBuffer_Send, (uint32_t)jcu_encode_size[jcu_buf_index_read]);
led2 = !led2;
}
}
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)
{
led1 = !led1;
//JPEGのエンコード設定
Jcu.SetQuality(JPEG_ENCODE_QUALITY);
//カメラの初期化処理
EasyAttach_Init(Display);
//カメラ画像 取得開始
Start_Video_Camera();
//割り込み処理※デバッグの為、5秒
flipper.attach(&incrementInterCnt, 5.0);
while (1) {
snapshot();
}
}