MARMEX-VB : "Mary Camera module" library
Dependents: MARMEX_VB_test MARMEX_VB_Hello
MARMEX-VB (MARY-VB) camera module library for mbed. (This module may be available in Japan only.)
Kown problem / 既知の問題
The read data may have contouring. In this case, it may require reset or changing order of data reading. The order change API is available as "read_order_change()" function.
カメラから読み出したデータに擬似輪郭が発生することがあります.この問題にはシステム全体のリセットを行うか,または読み出し順の変更を行うことで対処して下さい.読み出し順の変更はAPIの"read_order_change()"関数を使うことができます.
Revision 5:84e6c89a9a6d, committed 2014-06-20
- Comitter:
- nxpfan
- Date:
- Fri Jun 20 09:05:19 2014 +0000
- Parent:
- 4:8ef31b67c0ab
- Commit message:
- SPI-FIFO operation option added
Changed in this revision
MARMEX_VB.cpp | Show annotated file Show diff for this revision Revisions of this file |
MARMEX_VB.h | Show annotated file Show diff for this revision Revisions of this file |
diff -r 8ef31b67c0ab -r 84e6c89a9a6d MARMEX_VB.cpp --- a/MARMEX_VB.cpp Thu Jun 19 12:21:43 2014 +0000 +++ b/MARMEX_VB.cpp Fri Jun 20 09:05:19 2014 +0000 @@ -1,8 +1,8 @@ /** MARMEX_VB Camera control library * * @class MARMEX_VB - * @version 0.4 - * @date 19-Jun-2014 + * @version 0.5 + * @date 20-Jun-2014 * * Released under the Apache License, Version 2.0 : http://mbed.org/handbook/Apache-Licence * @@ -14,6 +14,51 @@ #define SPI_FREQUENCY (12 * 1000 * 1000) +/* + * Followings are 3 types of line read routines. + * Choose one of next 3 methods for reading camera data trough SPI interface + * + * Type0: "LINE_READ_OPT" is define as "NO_OPTIMIZATION" + * Most basic loop to explain how the MCU reading the line data. + * But this routine is slow, because the loop does 1 byte read + * with ChipSelect signal assertion/deassertion by DigitalOut + * + * Type1: "LINE_READ_OPT" is define as "LOOP_UNROLL" + * Faster. And keeping compatibility on mbed-SDK. + * Data reading speed improvement has been done in two ways. + * * The ChipSelect signal is kept asserted for whole line data transfer. + * because the MARMEX-VB module does not need deassertion at each end of byte transfer. + * * Loop unrolled. minimized loop overhead + * + * Type2: "LINE_READ_OPT" is define as "USING_SSP_FIFO" + * Fastest but no compatibility with mbed-SDK. + * The optimization has been done to use FIFO of SSP block. + * This code makes data transfer efficiency maximum. + * However, since this optimization is done in very low level (by register accessing), + * it works on some MCU's only (test has been done on LPC1768, LPC11U24 and LPC11U35). + * + * And user need to care about which SSP block is used. For instance, if the SPI pins + * of p5, p6 and p7 are used, those are connected to SSP1 in LPC1768. In case of + * LPC11U24 and LPC11U35, those pins are routed to SSP0. + * These settings should be done manually + */ + +//#define LINE_READ_OPT NO_OPTIMIZATION +#define LINE_READ_OPT LOOP_UNROLL +//#define LINE_READ_OPT USING_SSP_FIFO + + +/* Setting for "LINE_READ_OPT == USING_SSP_FIFO" + * Choose one line from next 3 lines when the FIFO option is taken + */ + +#define SSP_AUTO_SELECTION // for demo setup on "MAPLE mini type-B (MARM03-BASE)" baseboard (slot2) with a MARMEX_OB module (on slot1) +//#define SSP_USE_SSP0 +//#define SSP_USE_SSP1 + + + + MARMEX_VB::MARMEX_VB( PinName SPI_mosi, PinName SPI_miso, @@ -227,30 +272,11 @@ extern int read_order_change; void MARMEX_VB::read_a_line( short *p, int line_number, int x_offset, int n_of_pixels ) -{ -#if 0 - - char tmp; - - if ( line_number < 0 ) - return; - - // set camera module's buffer address - set_address( line_number * get_horizontal_size() * BYTE_PER_PIXEL + x_offset * BYTE_PER_PIXEL ); - - // put a read command, first return byte should be ignored - read_register( CAMERA_DATA_REGISTER ); - - for( int x = 0; x < n_of_pixels; x++ ) { - // perform 2 bytes read. a pixel data is in RGB565 format (16bits) - tmp = read_register( CAMERA_DATA_REGISTER ); // read lower byte - *p++ = (read_register( CAMERA_DATA_REGISTER ) << 8) | tmp; // read upper byte - } - -#else - - - short tmp; +{ + // OPTION REFERENCE NUMBER (DO NOT EDIT) + #define NO_OPTIMIZATION 0 + #define LOOP_UNROLL 1 + #define USING_SSP_FIFO 2 if ( line_number < 0 ) return; @@ -262,7 +288,23 @@ read_register( CAMERA_DATA_REGISTER ); +/* + * Type0: "LINE_READ_OPT" is define as "NO_OPTIMIZATION" + * Most basic loop to explain how the MCU reading the line data. + * But this routine is slow, because the loop does 1 byte read + * with ChipSelect signal assertion/deassertion by DigitalOut + */ +#if ( LINE_READ_OPT == NO_OPTIMIZATION ) + + short tmp; + if ( _read_order_change ) { + for( int x = 0; x < n_of_pixels; x++ ) { + // perform 2 bytes read. a pixel data is in RGB565 format (16bits) + tmp = read_register( CAMERA_DATA_REGISTER ); // read lower byte + *p++ = (read_register( CAMERA_DATA_REGISTER ) << 8) | tmp; // read upper byte + } + } else { read_register( CAMERA_DATA_REGISTER ); @@ -271,91 +313,131 @@ tmp = read_register( CAMERA_DATA_REGISTER ) << 8; // read lower byte *p++ = (read_register( CAMERA_DATA_REGISTER ) << 0) | tmp; // read upper byte } + } +#endif // ( LINE_READ_OPT == NO_OPTIMIZATION ) - } else { -#define OPTIMIZE_KEEP_ASSERTING_CS_DURING_LINE_DATA_TRANSFER -#ifdef OPTIMIZE_KEEP_ASSERTING_CS_DURING_LINE_DATA_TRANSFER - // optimized by IO register access and loop unroll +/* + * Type1: "LINE_READ_OPT" is define as "LOOP_UNROLL" + * Faster. And keeping compatibility on mbed-SDK. + * Data reading speed improvement has been done in two ways. + * * The ChipSelect signal is kept asserted for whole line data transfer. + * because the MARMEX-VB module does not need deassertion at each end of byte transfer. + * * Loop unrolled. minimized loop overhead + */ +#if ( LINE_READ_OPT == LOOP_UNROLL ) + + char reg = COMMAND_READ | CAMERA_DATA_REGISTER | COMMAND_ADDR_INCREMENT; + + if ( _read_order_change ) { + _cs = 0; - - char reg = COMMAND_READ | CAMERA_DATA_REGISTER | COMMAND_ADDR_INCREMENT; - + for( int x = 0; x < n_of_pixels; x += 8 ) { // perform 2 bytes read. a pixel data is in RGB565 format (16bits) - - *p = _spi.write( reg ); - *p++ |= _spi.write( reg ) << 8; - - *p = _spi.write( reg ); - *p++ |= _spi.write( reg ) << 8; - - *p = _spi.write( reg ); - *p++ |= _spi.write( reg ) << 8; - - *p = _spi.write( reg ); - *p++ |= _spi.write( reg ) << 8; - - *p = _spi.write( reg ); - *p++ |= _spi.write( reg ) << 8; - - *p = _spi.write( reg ); - *p++ |= _spi.write( reg ) << 8; - - *p = _spi.write( reg ); - *p++ |= _spi.write( reg ) << 8; - - *p = _spi.write( reg ); - *p++ |= _spi.write( reg ) << 8; + + *p = _spi.write( reg ); + *p++ |= _spi.write( reg ) << 8; + + *p = _spi.write( reg ); + *p++ |= _spi.write( reg ) << 8; + + *p = _spi.write( reg ); + *p++ |= _spi.write( reg ) << 8; + + *p = _spi.write( reg ); + *p++ |= _spi.write( reg ) << 8; + + *p = _spi.write( reg ); + *p++ |= _spi.write( reg ) << 8; + + *p = _spi.write( reg ); + *p++ |= _spi.write( reg ) << 8; + + *p = _spi.write( reg ); + *p++ |= _spi.write( reg ) << 8; + + *p = _spi.write( reg ); + *p++ |= _spi.write( reg ) << 8; + } _cs = 1; -#else - for( int x = 0; x < n_of_pixels; x++ ) { + + } else { + + read_register( CAMERA_DATA_REGISTER ); + + _cs = 0; + + for( int x = 0; x < n_of_pixels; x += 8 ) { // perform 2 bytes read. a pixel data is in RGB565 format (16bits) - tmp = read_register( CAMERA_DATA_REGISTER ); // read lower byte - *p++ = (read_register( CAMERA_DATA_REGISTER ) << 8) | tmp; // read upper byte + + *p = _spi.write( reg ) << 8; + *p++ |= _spi.write( reg ); + + *p = _spi.write( reg ) << 8; + *p++ |= _spi.write( reg ); + + *p = _spi.write( reg ) << 8; + *p++ |= _spi.write( reg ); + + *p = _spi.write( reg ) << 8; + *p++ |= _spi.write( reg ); + + *p = _spi.write( reg ) << 8; + *p++ |= _spi.write( reg ); + + *p = _spi.write( reg ) << 8; + *p++ |= _spi.write( reg ); + + *p = _spi.write( reg ) << 8; + *p++ |= _spi.write( reg ); + + *p = _spi.write( reg ) << 8; + *p++ |= _spi.write( reg ); + } -#endif + _cs = 1; } - -#endif -} - - +#endif // ( LINE_READ_OPT == LOOP_UNROLL ) -void MARMEX_VB::read_a_line_SPI_FIFO_READ( short *p, int line_number, int x_offset, int n_of_pixels ) -{ -#define FIFO_DEPTH 4 +/* + * Type2: "LINE_READ_OPT" is define as "USING_SSP_FIFO" + * Fastest but no compatibility with mbed-SDK. + * The optimization has been done to use FIFO of SSP block. + * This code makes data transfer efficiency maximum. + * However, since this optimization is done in very low level (by register accessing), + * it works on some MCU's only (test has been done on LPC1768, LPC11U24 and LPC11U35). + * + * And user need to care about which SSP block is used. For instance, if the SPI pins + * of p5, p6 and p7 are used, those are connected to SSP1 in LPC1768. In case of + * LPC11U24 and LPC11U35, those pins are routed to SSP0. + * These settings should be done manually + */ +#if ( LINE_READ_OPT == USING_SSP_FIFO ) -#ifdef TARGET_MBED_LPC1768 -#define SPI_PORT_SELECTOR LPC_SSP1 -#endif - -#ifdef TARGET_LPC11U35_501 -#define SPI_PORT_SELECTOR LPC_SSP0 -#endif + #define FIFO_DEPTH 4 -#ifdef TARGET_LPC11U24_401 -#define SPI_PORT_SELECTOR LPC_SSP0 -#endif - - char reg = COMMAND_READ | CAMERA_DATA_REGISTER | COMMAND_ADDR_INCREMENT; - int n; + #if defined( SSP_AUTO_SELECTION ) + #if defined( TARGET_MBED_LPC1768 ) + #define SPI_PORT_SELECTOR LPC_SSP1 + #elif defined( TARGET_LPC11U35_501 ) || defined( TARGET_LPC11U24_401 ) + #define SPI_PORT_SELECTOR LPC_SSP0 + #endif + #elif defined( SSP_USE_SSP0 ) + #define SPI_PORT_SELECTOR LPC_SSP0 + #elif defined( SSP_USE_SSP1 ) + #define SPI_PORT_SELECTOR LPC_SSP1 + #else + #error when using FIFO option for the optimization, choose one of definition from SSP_AUTO_SELECTION, SSP_USE_SSP0 or SSP_USE_SSP1 + #endif // #if defined( SSP_AUTO_SELECTION ) - if ( line_number < 0 ) - return; - - // set camera module's buffer address - set_address( line_number * get_horizontal_size() * BYTE_PER_PIXEL + x_offset * BYTE_PER_PIXEL ); - - // put a read command, first return byte should be ignored - read_register( CAMERA_DATA_REGISTER ); - - - // optimized by SPI-FIFO access + char reg = COMMAND_READ | CAMERA_DATA_REGISTER | COMMAND_ADDR_INCREMENT; + int n; if ( _read_order_change ) { + _cs = 0; for(n = FIFO_DEPTH; n > 0; n--) { @@ -378,7 +460,9 @@ } while(n < (n_of_pixels << 1)); _cs = 1; + } else { + read_register( CAMERA_DATA_REGISTER ); _cs = 0; @@ -404,6 +488,8 @@ _cs = 1; } + +#endif // ( LINE_READ_OPT == USING_SSP_FIFO ) } void MARMEX_VB::open_transfer( void )
diff -r 8ef31b67c0ab -r 84e6c89a9a6d MARMEX_VB.h --- a/MARMEX_VB.h Thu Jun 19 12:21:43 2014 +0000 +++ b/MARMEX_VB.h Fri Jun 20 09:05:19 2014 +0000 @@ -185,22 +185,6 @@ * @param n_of_pixels pixels to be read */ void read_a_line( short *p, int line_number, int x_offset, int n_of_pixels ); - - /** Read one line data - * - * Reads 1 line data from MARMEX_VB - * This function should be called when the data transfer done to resume the buffer update by camera - * - * This function is highly optimized for LPC1768 and LPC11U35 with a specific SPI port - * LPC1768 : LPC_SSP1 - * LPC11U35 : LPC_SSP0 - * - * @param *p pointer to array of short - * @param line_number to select which line want to read - * @param x_offset holizontal offset (from left) to start the read - * @param n_of_pixels pixels to be read - */ - void read_a_line_SPI_FIFO_READ( short *p, int line_number, int x_offset, int n_of_pixels ); /** Read order change *