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.
Dependents: MARMEX_VB_test MARMEX_VB_Hello
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 |
--- 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 )
--- 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
*
MARMEX-VB (MARY-VB) Camera module