Library for "I2C 8x8 LED matrix board" from Switch Science https://www.switch-science.com/catalog/2071/
Dependents: PCA9622_LED8x8_Demo PCA9622_LED8x8_Hello PCA9622_LED8x8_x6_Demo shake-shake-machine
PCA9622_LED8x8.cpp
00001 /** 00002 * PCA9622 LED 8x8 library 00003 * 00004 * @author Tedd OKANO 00005 * @version 1.1.1 00006 * @date 26-Feb-2015 00007 * 00008 * Library for "I2C 8x8 LED matrix board" from Switch Science 00009 * https://www.switch-science.com/catalog/2071/ 00010 * 00011 * The I2C LED controller PCA9622 is used on this module 00012 * that ebables to control the LEDs with PWM brightness control. 00013 * 00014 * For more information about the PCA9622: 00015 * http://www.nxp.com/documents/data_sheet/PCA9622.pdf 00016 */ 00017 00018 #include "mbed.h" 00019 #include "PCA9622_LED8x8.h" 00020 00021 PCA9622_LED8x8::PCA9622_LED8x8( PinName sda, PinName scl, char slave_adr, float fr ) 00022 : 00023 i2c_p( new I2C( sda, scl ) ), 00024 i2c( *i2c_p ), 00025 address( slave_adr ), 00026 framerate( fr ), 00027 in_operation( false ), 00028 line_counter( 0 ), 00029 frame_counter( 0 ), 00030 buffer_switch_request( false ), 00031 outgoing_buffer( 0 ) 00032 { 00033 initialize(); 00034 } 00035 00036 PCA9622_LED8x8::PCA9622_LED8x8( I2C &i2c_obj, char slave_adr, float fr ) 00037 : 00038 i2c_p( NULL ), 00039 i2c( i2c_obj ), 00040 address( slave_adr ), 00041 framerate( fr ), 00042 in_operation( false ), 00043 line_counter( 0 ), 00044 frame_counter( 0 ), 00045 buffer_switch_request( false ), 00046 outgoing_buffer( 0 ) 00047 { 00048 initialize(); 00049 } 00050 00051 PCA9622_LED8x8::~PCA9622_LED8x8() 00052 { 00053 if ( NULL != i2c_p ) 00054 delete i2c_p; 00055 } 00056 00057 void PCA9622_LED8x8::initialize( void ) 00058 { 00059 char init[ 2 ][ 3 ] = { 00060 { 0x80, 0x00, 0x05 }, // initialize MODE1 and MODE2 registers 00061 { 0x96, 0xAA, 0xAA } // initialize LEDOUT2 and LEDOUT3 registers 00062 }; 00063 00064 i2c.frequency( 400 * 1000 ); 00065 i2c.write( address, init[ 0 ], sizeof( init[ 0 ] ) ); 00066 i2c.write( address, init[ 1 ], sizeof( init[ 1 ] ) ); 00067 00068 start(); 00069 } 00070 00071 void PCA9622_LED8x8::frame_rate( float rate ) 00072 { 00073 int previous_state; 00074 00075 previous_state = in_operation; 00076 00077 stop(); 00078 framerate = rate; 00079 00080 if ( previous_state ) 00081 start(); 00082 } 00083 00084 void PCA9622_LED8x8::start( void ) 00085 { 00086 t.attach( this, &PCA9622_LED8x8::draw_a_line, 1.0 / (framerate * 8.0) ); 00087 in_operation = true; 00088 } 00089 00090 void PCA9622_LED8x8::stop( void ) 00091 { 00092 t.detach(); 00093 in_operation = false; 00094 } 00095 00096 void PCA9622_LED8x8::draw_a_line( void ) 00097 { 00098 char write_data[ 13 ]; 00099 00100 if ( buffer_switch_request && !line_counter ) { 00101 // when the scan start, and if the buffer switching is requested ping-pong bufer will be switched 00102 outgoing_buffer = !outgoing_buffer; 00103 buffer_switch_request = false; 00104 } 00105 00106 write_data[ 0 ] = 0x80 | 0xA; // pointing PWM8 register with increment flag 00107 // write_data[ 9 ] = 0x00; // don't need to stuff any data because this register will be ignored (because global PWM setting is not used) 00108 // write_data[ 10 ] = 0x00; // don't need to stuff any data because this register will be ignored (because global PWM setting is not used) 00109 00110 for ( int i = 0; i < 8; i++ ) 00111 write_data[ i + 1 ] = pattern[ outgoing_buffer ][ line_counter ][ i ]; // PWM data are set to PWM8..PWM15 registers (driving ROW) 00112 00113 // A line below works fine on Cortex-M3 but not on Cortex-M0. So I needed to rewrite it 00114 // *((unsigned short *)(write_data + 11)) = 0x0001 << (line_counter << 1); // channel 0 to 7 are used to ON/OFF the column 00115 00116 // A line above is rewritten as next 3 lines 00117 unsigned short tmp = 0x0001 << (line_counter << 1); 00118 write_data[ 11 ] = tmp & 0xFF; 00119 write_data[ 12 ] = tmp >> 8; 00120 00121 i2c.write( address, write_data, sizeof( write_data ) ); // I2C transfer 00122 00123 line_counter = (line_counter + 1) & 0x7; 00124 00125 if ( line_counter ) 00126 frame_counter++; 00127 } 00128 00129 void PCA9622_LED8x8::set_data( float p[ 8 ][ 8 ] ) 00130 { 00131 for ( int i = 0; i < 8; i++ ) 00132 for ( int j = 0; j < 8; j++ ) 00133 pattern[ !outgoing_buffer /* store image to in-active side */ ][ i ][ 7 - j ] = (char)(p[ i ][ j ] * 255.0); 00134 00135 buffer_switch_request = true; // when the buffer filling done, raise this flag to switch the pin-pong buffer 00136 }
Generated on Wed Jul 13 2022 20:20:15 by 1.7.2