MARMEX_VB test application program. This application works on "mbed NXP LPC1768" only. This application expects to have the MARMEX_VB module on a "MAPLE mini type-B (MARM03-BASE)" baseboard (slot2) with MARMEX_OB module (on slot1)

Dependencies:   MARMEX_VB NokiaLCD mbed

This is the library test program.
The program can test features of the library (refer to MARMEX-VB's API document) and can save captured data into BMP file.

Warning!

This test program can run on "mbed NXP LPC1768" only.

/media/uploads/nxpfan/dsc_0506_-1-.jpg
Picture : sample of test program operation
The modules of MARMEX-VB and MARMEX-OB are set on the "MAPLE mini type-B (MARM03-BASE)" baseboard.
The image data from camera is mirrored and alpha graphics added by software.

main.cpp

Committer:
nxpfan
Date:
2014-06-20
Revision:
8:86aae677a68b
Parent:
7:125538c50c22

File content as of revision 8:86aae677a68b:

/** Test program for MARMEX_VB Camera control library
 *
 *  @version 0.4
 *  @date    20-Jun-2014
 *
 *  Released under the Apache License, Version 2.0 : http://mbed.org/handbook/Apache-Licence
 *
 *  Test program for MARMEX_VB Camera control library
 *
 *      ** This program runs on mbed_NXP_LPC1768 only **
 */


#include    "mbed.h"
#include    "MARMEX_OB_oled.h"
#include    "MARMEX_VB.h"
#include    "bmp_handler.h"

//  Baseboard type selection
#define BASEBOARD_MAPLE_MINI_TYPE_B
//#define BASEBOARD_MAPLE_ORIGINAL

#ifdef  BASEBOARD_MAPLE_MINI_TYPE_B
MARMEX_OB_oled  oled1( p5, p7,  p20, p16, p15 );
// mosi, sclk, cs, rst, power_control               -- maple-mini-type-b-board-slot1
MARMEX_VB       camera( p5, p6, p7, p22, p26, p28, p27 );
// mosi, miso, sclk, cs, reset, sda, scl    -- maple-mini-type-b-board-slot2
#endif

#ifdef  BASEBOARD_MAPLE_ORIGINAL
MARMEX_OB_oled  oled1( p5, p7,  p8, p30, p11 );
// mosi, sclk, cs, rst, power_control               -- maple-board-slot1
MARMEX_VB       camera( p5, p6, p7, p26, p17, p28, p27 );
// mosi, miso, sclk, cs, reset, sda, scl    -- maple-board-slot2
#endif

BusOut          led( LED4, LED3, LED2, LED1 );
Timer           timer;
Timer           looptimer;


void test_camera( void );
void test_camera_resolution_change( void );

void copy_image_from_camera_to_oled( void );
void copy_image_from_camera_to_oled_small( void );
void copy_image_from_camera_to_oled_interlaced( void );
void line_mirroring( short *buf );
void save_still_image( char *file_name );
void oled_test_screen( void );
void capture_to_bmp( void );

//#define     SAVE_EACH_SIZES_OF_STILL_IMAGE

alpha_param ap;


int main()
{
    printf( "\r\n\r\nMARY-CAMERA test program\r\n\r\n" );

    read_alpha_BMP( "alpha.bmp", &ap );


    led    = 0x3;

    oled1.cls();
    oled_test_screen();
    oled1.cls();

#ifdef  SAVE_EACH_SIZES_OF_STILL_IMAGE
    led    = 0x1;
    camera.resolution( MARMEX_VB::QCIF );
    save_still_image( "i_qcif.bmp" );

    led    = 0x2;
    camera.resolution( MARMEX_VB::QQVGA );
    save_still_image( "i_qqvga.bmp" );

    led    = 0x4;
    camera.resolution( MARMEX_VB::QVGA );
    save_still_image( "i_qvga.bmp" );

    led    = 0x8;
    camera.resolution( MARMEX_VB::VGA );
    save_still_image( "i_vga.bmp" );

    camera.resolution( MARMEX_VB::QCIF );
#endif

    printf( "  camera operation started\r\n" );
    printf( "    hit key [c] for saving data into BMP (for blue-mbed only)\r\n" );
    printf( "    hit key [o] to change data reading order\r\n" );
    printf( "    hit key [i] to toggle interlace mode\r\n" );
    printf( "    hit key [1], [2], [3] or [4] to change resolution QCIF, QQVGA, QVGA, VGA\r\n" );

    looptimer.start();

    timer.start();  //  timer for measureing frame rate
    test_camera();  //  this function doesn't return
}

#if defined( TARGET_MBED_LPC1768 )
Serial      pc(USBTX, USBRX);    // tx, rx
#endif

int     disp  = 1;


void test_camera( void )
{
    int     interlace           = 1;
    int     frame_count         = 0;

    float   t;

    while ( 1 ) {

#ifdef TARGET_MBED_LPC1768
        if ( pc.readable() ) {
            switch ( pc.getc() ) {
                case 'c' :
                    capture_to_bmp();
                    printf( "  [c] : capture started\r\n" );
                    break;
                case 'o' :
                    printf( "  [o] read order change : %s\r\n", camera.read_order_change() ? "ENABLED" : "DISABLED" );
                    break;
                case 'i' :
                    interlace   = !interlace;
                    printf( "  [i] : interlace setting : %s\r\n", interlace ? "ENABLED" : "DISABLED" );
                    /*  FALL THROUGH  */
                case 'f' :
                    if ( frame_count ) {
                        timer.stop();
                        t   = timer.read();
                        printf( "  [f] : %s rate : %5.3f\r\n", interlace ? "field" : "frame", (float)frame_count / t );
                        frame_count = 0;
                        timer.reset();
                        timer.start();
                    } else {
                        printf( "  [f] : no frame drawn yet. try again later\r\n" );
                    }
                    break;
                case '1' :
                    printf( "  [1] resolution change : QCIF\r\n" );
                    camera.init( MARMEX_VB::QCIF );
                    break;
                case '2' :
                    printf( "  [2] resolution change : QQVGA\r\n" );
                    camera.init( MARMEX_VB::QQVGA );
                    break;
                case '3' :
                    printf( "  [3] resolution change : QVGA\r\n" );
                    camera.init( MARMEX_VB::QVGA );
                    break;
                case '4' :
                    printf( "  [4] resolution change : VGA\r\n" );
                    camera.init( MARMEX_VB::VGA );
                    break;
            }
        }
#endif

        led    = 0x1;

        if ( interlace )
            copy_image_from_camera_to_oled_interlaced();
        else
            copy_image_from_camera_to_oled();

//        camera.colorbar( ((count++ >> 2) & 0x1) ? MARMEX_VB::ON : MARMEX_VB::OFF );

#if 0
        #define SCREEN_TOP  9

        t   = looptimer.read();
        looptimer.reset();
        oled1.locate( 0, 0 );
        oled1.printf( " %.2f %s/s", 1.0 / t, interlace ? "field" : "frame" );
#else
       #define SCREEN_TOP  0
#endif
        led    = 0x2;

        frame_count++;
    }
}


void test_camera_resolution_change( void )
{
    int     count   = (3 << 3);
    int     setting;

    while ( 1 ) {

        if ( !(count & 0x7) ) {
            setting     = (count >> 3) & 0x3;
            camera.init( (MARMEX_VB::CameraResolution)(setting + 1) );
            led    = 0x1 << setting;
        }

        count++;

        copy_image_from_camera_to_oled();
    }
}


void alpha( int line_num, short *bf, int offset_x, int offset_y, alpha_param *app )
{
    short   r, g, b;
    int     y_pos;

    if ( (line_num < offset_y) || (offset_y + app->v) <= line_num || (app->buffer == NULL) )
        return;

    bf     += offset_x;
    y_pos   = ((app->v - (line_num - offset_y + 1)) * (app->h * app->byte_per_pixel));

    for ( int i = 0; i < 60; i++ ) {
        r   = ((*bf >>  1) & 0x0F) + (*(app->buffer + i * 3 + 0 + y_pos ) >> 4);
        g   = ((*bf >>  6) & 0x1F) + (*(app->buffer + i * 3 + 1 + y_pos ) >> 3);
        b   = ((*bf >> 12) & 0x0F) + (*(app->buffer + i * 3 + 2 + y_pos ) >> 4);

        *bf++ = (b << 11) | (g << 5) | (r << 0);
    }
}

void copy_image_from_camera_to_oled( void )
{
    short   buf[ MARMEX_OB_oled::WIDTH ];   //  array size should be multiple of 8 for "mbed LPC1768" optimization
    static int  count   = 0;

    camera.open_transfer();

    for ( int line = SCREEN_TOP; line < MARMEX_OB_oled::HEIGHT; line++  ) {
        camera.read_a_line( buf, line + (camera.get_vertical_size() - (int)MARMEX_OB_oled::HEIGHT) / 2, (camera.get_horizontal_size() - (int)MARMEX_OB_oled::WIDTH ) / 2, MARMEX_OB_oled::WIDTH );
        line_mirroring( buf );
        alpha( line, buf, ((count >> 4) & 1) ? 60 : 8, ((count >> 4) & 1) ^ ((count >> 3) & 1) ? ((int)MARMEX_OB_oled::HEIGHT - (ap.v + 4)) : 4 + SCREEN_TOP, &ap );
        oled1.blit565( 0, line, MARMEX_OB_oled::WIDTH, 1, buf );
    }

    count++;
    camera.close_transfer();
}


void copy_image_from_camera_to_oled_interlaced( void )
{
    short       buf[ MARMEX_OB_oled::WIDTH ];
    static int  count   = 0;

    camera.open_transfer();

    for ( int line = ((count++) & 1) + SCREEN_TOP; line < MARMEX_OB_oled::HEIGHT; line += 2 ) {
        camera.read_a_line( buf, line + (camera.get_vertical_size() - (int)MARMEX_OB_oled::HEIGHT) / 2, (camera.get_horizontal_size() - (int)MARMEX_OB_oled::WIDTH ) / 2, MARMEX_OB_oled::WIDTH );
        line_mirroring( buf );
        alpha( line, buf, ((count >> 4) & 1) ? 60 : 8, ((count >> 4) & 1) ^ ((count >> 3) & 1) ? ((int)MARMEX_OB_oled::HEIGHT - (ap.v + 4)) : 4 + SCREEN_TOP, &ap );
        oled1.blit565( 0, line, MARMEX_OB_oled::WIDTH, 1, buf );
    }

    camera.close_transfer();
}


void copy_image_from_camera_to_oled_small( void )
{
    short   buf[ 64 ];
    static int  count   = 0;

    camera.open_transfer();

    for ( int line = 0; line < 64; line++  ) {
        camera.read_a_line( buf, line, 0, 64 );
        oled1.blit565( 0, line, 64, 1, buf );
    }

    count++;
    camera.close_transfer();
}


void line_mirroring( short *buf )
{
    short   tmp;

    for ( int i = 0; i < (MARMEX_OB_oled::WIDTH / 2); i++ ) {
        tmp         = buf[ i ];
        buf[ i ]    = buf[ (MARMEX_OB_oled::WIDTH - 1) - i ];
        buf[ (MARMEX_OB_oled::WIDTH - 1) - i ]  = tmp;
    }
}


void oled_test_screen( void )
{
    oled1.background( 0x000000 );
    oled1.cls();

    int colorbar_width  = MARMEX_OB_oled::WIDTH / 8;

    for ( int i = 0; i < 8; i++ )
        oled1.fill( colorbar_width * i, 0, colorbar_width, MARMEX_OB_oled::HEIGHT, ((i & 0x4) ? 0xFF0000 : 0x000000) | ((i & 0x2) ? 0x00FF00 : 0x000000) | ((i & 0x1) ? 0x0000FF : 0x000000) );

    oled1.fill(  50,  50,  64,  64, 0xCCCCCC );;

    oled1.locate( 0, 2 );
    oled1.printf( "MaryCemara test" );
    oled1.locate( 0, 3 );
    oled1.printf( "%s", (MARMEX_VB::NO_ERROR == camera.ready()) ? "Camera is ready" : "No Camera found" );
    oled1.locate( 0, 4 );
    //oled1.printf( "%s", "saving into BMP" );
    oled1.locate( 0, 5 );
    oled1.printf( "%d", camera.get_horizontal_size() );
    oled1.locate( 0, 6 );
    oled1.printf( "%d", camera.get_vertical_size() );

    for (int i = 0; i < MARMEX_OB_oled::WIDTH; i++ )
        oled1.pixel( i, 80 + sin( (float)i / 5.0 ) * 10, 0x000000 );
}


#include    "bmp_handler.h"

void save_still_image( char *file_name )
{
    short   buf[ camera.get_horizontal_size() ];

    if ( open_BMP( file_name, camera.get_horizontal_size(), camera.get_vertical_size() ) )
        return;

    camera.open_transfer();

    for ( int line = (camera.get_vertical_size() - 1); 0 <= line; line--  ) {
        camera.read_a_line( buf, line, 0, camera.get_horizontal_size() );
        write_BMP( buf, camera.get_horizontal_size() );
    }
    camera.close_transfer();

    close_BMP();
}

void capture_to_bmp( void )
{
    short   buf[ camera.get_horizontal_size() ];
    camera.open_transfer();

    if ( open_BMP( "RGB.bmp", camera.get_horizontal_size(), camera.get_vertical_size() ) )
        return;

    for ( int line = (camera.get_vertical_size() - 1); 0 <= line; line--  ) {
        camera.read_a_line( buf, line, 0, camera.get_horizontal_size() );
//        write_BMP( buf, camera.get_horizontal_size(), 0x7 );
        write_BMP( buf, camera.get_horizontal_size() );
    }

    close_BMP();

#if 0

    if ( open_BMP( "R.bmp", camera.get_horizontal_size(), camera.get_vertical_size() ) )
        return;

    for ( int line = (camera.get_vertical_size() - 1); 0 <= line; line--  ) {
        camera.read_a_line( buf, line, 0, camera.get_horizontal_size() );
        write_BMP( buf, camera.get_horizontal_size(), 0x4 );
    }

    close_BMP();


    if ( open_BMP( "G.bmp", camera.get_horizontal_size(), camera.get_vertical_size() ) )
        return;

    for ( int line = (camera.get_vertical_size() - 1); 0 <= line; line--  ) {
        camera.read_a_line( buf, line, 0, camera.get_horizontal_size() );
        write_BMP( buf, camera.get_horizontal_size(), 0x2 );
    }

    close_BMP();


    if ( open_BMP( "B.bmp", camera.get_horizontal_size(), camera.get_vertical_size() ) )
        return;

    for ( int line = (camera.get_vertical_size() - 1); 0 <= line; line--  ) {
        camera.read_a_line( buf, line, 0, camera.get_horizontal_size() );
        write_BMP( buf, camera.get_horizontal_size(), 0x1 );
    }

    close_BMP();

#endif
    camera.close_transfer();
}