gfdgd

Dependencies:   CompLedDvrCC

Fork of PCA995xA by InetrfaceProducts NXP

Committer:
okano
Date:
Sat Oct 31 06:07:15 2015 +0000
Revision:
6:1c6e1af61981
Parent:
0:a624e2eeccac
Child:
7:56a45c690801
fix for single shot gradation start

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nxp_ip 0:a624e2eeccac 1 #include "mbed.h"
nxp_ip 0:a624e2eeccac 2 #include "PCA9955A.h"
nxp_ip 0:a624e2eeccac 3
nxp_ip 0:a624e2eeccac 4 PCA9955A::PCA9955A( PinName i2c_sda, PinName i2c_scl, char i2c_address )
nxp_ip 0:a624e2eeccac 5 : PCA995xA( i2c_sda, i2c_scl, i2c_address ), n_of_ports( 16 )
nxp_ip 0:a624e2eeccac 6 {
nxp_ip 0:a624e2eeccac 7 initialize();
nxp_ip 0:a624e2eeccac 8 }
nxp_ip 0:a624e2eeccac 9
nxp_ip 0:a624e2eeccac 10 PCA9955A::PCA9955A( I2C &i2c_obj, char i2c_address )
nxp_ip 0:a624e2eeccac 11 : PCA995xA( i2c_obj, i2c_address ), n_of_ports( 16 )
nxp_ip 0:a624e2eeccac 12 {
nxp_ip 0:a624e2eeccac 13 initialize();
nxp_ip 0:a624e2eeccac 14 }
nxp_ip 0:a624e2eeccac 15
nxp_ip 0:a624e2eeccac 16 PCA9955A::~PCA9955A()
nxp_ip 0:a624e2eeccac 17 {
nxp_ip 0:a624e2eeccac 18 }
nxp_ip 0:a624e2eeccac 19
nxp_ip 0:a624e2eeccac 20 void PCA9955A::initialize( void )
nxp_ip 0:a624e2eeccac 21 {
nxp_ip 0:a624e2eeccac 22 char init_array[] = {
nxp_ip 0:a624e2eeccac 23 PCA995xA::AUTO_INCREMENT | REGISTER_START, // Command
nxp_ip 0:a624e2eeccac 24 0x00, 0x00, // MODE1, MODE2
nxp_ip 0:a624e2eeccac 25 0xAA, 0xAA, 0xAA, 0xAA, // LEDOUT[3:0]
nxp_ip 0:a624e2eeccac 26 0x80, 0x00, // GRPPWM, GRPFREQ
nxp_ip 0:a624e2eeccac 27 };
nxp_ip 0:a624e2eeccac 28
nxp_ip 0:a624e2eeccac 29 pwm( ALLPORTS, 0.0 );
nxp_ip 0:a624e2eeccac 30 current( ALLPORTS, 0.1 );
nxp_ip 0:a624e2eeccac 31
nxp_ip 0:a624e2eeccac 32 write( init_array, sizeof( init_array ) );
nxp_ip 0:a624e2eeccac 33 gradation_group_clear();
nxp_ip 0:a624e2eeccac 34 }
nxp_ip 0:a624e2eeccac 35
nxp_ip 0:a624e2eeccac 36 char PCA9955A::pwm_register_access( int port )
nxp_ip 0:a624e2eeccac 37 {
nxp_ip 0:a624e2eeccac 38 if ( port < n_of_ports )
nxp_ip 0:a624e2eeccac 39 return ( PWM_REGISTER_START + port );
nxp_ip 0:a624e2eeccac 40
nxp_ip 0:a624e2eeccac 41 return ( PWMALL );
nxp_ip 0:a624e2eeccac 42 }
nxp_ip 0:a624e2eeccac 43
nxp_ip 0:a624e2eeccac 44 char PCA9955A::current_register_access( int port )
nxp_ip 0:a624e2eeccac 45 {
nxp_ip 0:a624e2eeccac 46 if ( port < n_of_ports )
nxp_ip 0:a624e2eeccac 47 return ( IREF_REGISTER_START + port );
nxp_ip 0:a624e2eeccac 48
nxp_ip 0:a624e2eeccac 49 return ( IREFALL );
nxp_ip 0:a624e2eeccac 50 }
nxp_ip 0:a624e2eeccac 51
nxp_ip 0:a624e2eeccac 52 int PCA9955A::number_of_ports( void )
nxp_ip 0:a624e2eeccac 53 {
nxp_ip 0:a624e2eeccac 54 return ( n_of_ports );
nxp_ip 0:a624e2eeccac 55 }
nxp_ip 0:a624e2eeccac 56
nxp_ip 0:a624e2eeccac 57
nxp_ip 0:a624e2eeccac 58 char PCA9955A::gradation_group[ 16 ] = { 0xFF };
nxp_ip 0:a624e2eeccac 59
nxp_ip 0:a624e2eeccac 60 void PCA9955A::gradation_setting( int group, char ramp_rate, char step_time, char hold_cntl, char iref )
nxp_ip 0:a624e2eeccac 61 {
nxp_ip 0:a624e2eeccac 62 char data[ 5 ] = { (RAMP_RATE_GRP0 + (group * GRAD_GROUP_OFFSET)) | AUTO_INCREMENT,
nxp_ip 0:a624e2eeccac 63 ramp_rate,
nxp_ip 0:a624e2eeccac 64 step_time,
nxp_ip 0:a624e2eeccac 65 hold_cntl,
nxp_ip 0:a624e2eeccac 66 iref
nxp_ip 0:a624e2eeccac 67 };
nxp_ip 0:a624e2eeccac 68
nxp_ip 0:a624e2eeccac 69 write( data, sizeof( data ) );
nxp_ip 0:a624e2eeccac 70 }
nxp_ip 0:a624e2eeccac 71
nxp_ip 0:a624e2eeccac 72 void PCA9955A::gradation_start( char group, char continuous_flag )
nxp_ip 0:a624e2eeccac 73 {
nxp_ip 0:a624e2eeccac 74 static char v[] = { GRAD_CNTL, 0 };
okano 6:1c6e1af61981 75 char rd;
okano 6:1c6e1af61981 76
okano 6:1c6e1af61981 77 rd = read( GRAD_CNTL ) & ~(0x3 << (group * 2));
okano 6:1c6e1af61981 78
okano 6:1c6e1af61981 79 printf( "rd = 0x%02X\r\n", rd );
okano 6:1c6e1af61981 80 v[ 1 ] = rd | ((0x02 | continuous_flag) << (group * 2));
nxp_ip 0:a624e2eeccac 81 // v[ 1 ] = ((0x02 | continuous_flag) << (group * 2));
nxp_ip 0:a624e2eeccac 82 write( v, sizeof( v ) );
nxp_ip 0:a624e2eeccac 83 }
nxp_ip 0:a624e2eeccac 84
nxp_ip 0:a624e2eeccac 85 void PCA9955A::gradation_stop( void )
nxp_ip 0:a624e2eeccac 86 {
nxp_ip 0:a624e2eeccac 87 char v[] = { GRAD_CNTL, 0 };
nxp_ip 0:a624e2eeccac 88
nxp_ip 0:a624e2eeccac 89 write( v, sizeof( v ) );
nxp_ip 0:a624e2eeccac 90 }
nxp_ip 0:a624e2eeccac 91
nxp_ip 0:a624e2eeccac 92 void PCA9955A::group_selector( short g0, short g1, short g2, short g3 )
nxp_ip 0:a624e2eeccac 93 {
nxp_ip 0:a624e2eeccac 94 unsigned int pattern = 0x00000000;
nxp_ip 0:a624e2eeccac 95 short src[ 4 ];
nxp_ip 0:a624e2eeccac 96 short port_select;
nxp_ip 0:a624e2eeccac 97 char v[ 7 ];
nxp_ip 0:a624e2eeccac 98 int i;
nxp_ip 0:a624e2eeccac 99 int grp;
nxp_ip 0:a624e2eeccac 100
nxp_ip 0:a624e2eeccac 101 v[ 0 ] = GRAD_MODE_SEL0 | AUTO_INCREMENT;
nxp_ip 0:a624e2eeccac 102
nxp_ip 0:a624e2eeccac 103 port_select = g0 | g1 | g2 | g3;
nxp_ip 0:a624e2eeccac 104 v[ 1 ] = (port_select >> 0) & 0xFF;
nxp_ip 0:a624e2eeccac 105 v[ 2 ] = (port_select >> 8) & 0xFF;
nxp_ip 0:a624e2eeccac 106
nxp_ip 0:a624e2eeccac 107 if ( 0x0000 == port_select ) {
nxp_ip 0:a624e2eeccac 108 write( v, 3 );
nxp_ip 0:a624e2eeccac 109 return;
nxp_ip 0:a624e2eeccac 110 }
nxp_ip 0:a624e2eeccac 111
nxp_ip 0:a624e2eeccac 112 src[ 0 ] = g0;
nxp_ip 0:a624e2eeccac 113 src[ 1 ] = g1;
nxp_ip 0:a624e2eeccac 114 src[ 2 ] = g2;
nxp_ip 0:a624e2eeccac 115 src[ 3 ] = g3;
nxp_ip 0:a624e2eeccac 116
nxp_ip 0:a624e2eeccac 117 for ( i = 0; i < 16; i++ ) {
nxp_ip 0:a624e2eeccac 118 for ( grp = 0; grp < 4; grp++ ) {
nxp_ip 0:a624e2eeccac 119 if ( src[ grp ] & (0x1 << i) )
nxp_ip 0:a624e2eeccac 120 pattern |= grp << (i * 2);
nxp_ip 0:a624e2eeccac 121 }
nxp_ip 0:a624e2eeccac 122 }
nxp_ip 0:a624e2eeccac 123
nxp_ip 0:a624e2eeccac 124 for ( i = 0; i < 4; i++ )
nxp_ip 0:a624e2eeccac 125 v[ i + 3 ] = 0xFF & (pattern >> (i * 8));
nxp_ip 0:a624e2eeccac 126
nxp_ip 0:a624e2eeccac 127 write( v, sizeof( v ) );
nxp_ip 0:a624e2eeccac 128 }
nxp_ip 0:a624e2eeccac 129
nxp_ip 0:a624e2eeccac 130 void PCA9955A::gradation_group_setting( char group, char port )
nxp_ip 0:a624e2eeccac 131 {
nxp_ip 0:a624e2eeccac 132 short g[ 4 ] = { 0x0000 };
nxp_ip 0:a624e2eeccac 133
nxp_ip 0:a624e2eeccac 134 port &= 0xF;
nxp_ip 0:a624e2eeccac 135 gradation_group[ port ] = (group < 4) ? group : NOGROUP;
nxp_ip 0:a624e2eeccac 136
nxp_ip 0:a624e2eeccac 137 for ( int i = 0; i < 16; i++ ) {
nxp_ip 0:a624e2eeccac 138 if ( gradation_group[ i ] != NOGROUP )
nxp_ip 0:a624e2eeccac 139 g[ gradation_group[ i ] ] |= 0x0001 << i;
nxp_ip 0:a624e2eeccac 140 }
nxp_ip 0:a624e2eeccac 141
nxp_ip 0:a624e2eeccac 142 group_selector( g[ 0 ], g[ 1 ], g[ 2 ], g[ 3 ] );
nxp_ip 0:a624e2eeccac 143 // pwm( port, 1.0 );
nxp_ip 0:a624e2eeccac 144 pwm( port, 0.3 );
nxp_ip 0:a624e2eeccac 145 }
nxp_ip 0:a624e2eeccac 146
nxp_ip 0:a624e2eeccac 147 void PCA9955A::gradation_group_clear( void )
nxp_ip 0:a624e2eeccac 148 {
nxp_ip 0:a624e2eeccac 149 for ( int i = 0; i < 16; i++ ) {
nxp_ip 0:a624e2eeccac 150 gradation_group[ i ] = NOGROUP;
nxp_ip 0:a624e2eeccac 151 }
nxp_ip 0:a624e2eeccac 152
nxp_ip 0:a624e2eeccac 153 group_selector( 0, 0, 0, 0 );
nxp_ip 0:a624e2eeccac 154 }
nxp_ip 0:a624e2eeccac 155
nxp_ip 0:a624e2eeccac 156 float PCA9955A::gradation_ramp_setting( char group, float cycle, char flag_on, char flag_off, int ramp_flag )
nxp_ip 0:a624e2eeccac 157 {
nxp_ip 0:a624e2eeccac 158 int ramp_time;
nxp_ip 0:a624e2eeccac 159 char prescaler;
nxp_ip 0:a624e2eeccac 160 int required_steps;
nxp_ip 0:a624e2eeccac 161 char mult_factor;
nxp_ip 0:a624e2eeccac 162 char iref_inc;
nxp_ip 0:a624e2eeccac 163 int iref = 255;
nxp_ip 0:a624e2eeccac 164
nxp_ip 0:a624e2eeccac 165 #define RAMP_RATE_GRP 1
nxp_ip 0:a624e2eeccac 166 #define STEP_TIME_GRP 2
nxp_ip 0:a624e2eeccac 167 #define HOLD_CNTL_GRP 3
nxp_ip 0:a624e2eeccac 168 #define IREF_GRP 4
nxp_ip 0:a624e2eeccac 169
nxp_ip 0:a624e2eeccac 170 char regs[ 5 ];
nxp_ip 0:a624e2eeccac 171
nxp_ip 0:a624e2eeccac 172 float hold_time[] = {
nxp_ip 0:a624e2eeccac 173 0.00,
nxp_ip 0:a624e2eeccac 174 0.25,
nxp_ip 0:a624e2eeccac 175 0.50,
nxp_ip 0:a624e2eeccac 176 0.75,
nxp_ip 0:a624e2eeccac 177 1.00,
nxp_ip 0:a624e2eeccac 178 2.00,
nxp_ip 0:a624e2eeccac 179 4.00,
nxp_ip 0:a624e2eeccac 180 6.00
nxp_ip 0:a624e2eeccac 181 };
nxp_ip 0:a624e2eeccac 182
nxp_ip 0:a624e2eeccac 183
nxp_ip 0:a624e2eeccac 184 if ( ramp_flag == NO_RAMP ) {
nxp_ip 0:a624e2eeccac 185 iref_inc = 1;
nxp_ip 0:a624e2eeccac 186 ramp_time = 0;
nxp_ip 0:a624e2eeccac 187 prescaler = 0;
nxp_ip 0:a624e2eeccac 188 required_steps = 0;
nxp_ip 0:a624e2eeccac 189 mult_factor = 0;
nxp_ip 0:a624e2eeccac 190 } else {
nxp_ip 0:a624e2eeccac 191 ramp_time = (int)((cycle - (hold_time[ flag_on ] + hold_time[ flag_off ])) / ((ramp_flag == RAMP_UP_DOWN) ? 2.0 : 1.0) * 1000);
nxp_ip 0:a624e2eeccac 192
nxp_ip 0:a624e2eeccac 193 prescaler = ( ramp_time <= 32 * (iref + 1)) ? 0 : 1;
nxp_ip 0:a624e2eeccac 194
nxp_ip 0:a624e2eeccac 195 if ( prescaler )
nxp_ip 0:a624e2eeccac 196 required_steps = ramp_time / 8;
nxp_ip 0:a624e2eeccac 197 else
nxp_ip 0:a624e2eeccac 198 required_steps = ramp_time * 2;
nxp_ip 0:a624e2eeccac 199
nxp_ip 0:a624e2eeccac 200 if ( iref < required_steps ) {
nxp_ip 0:a624e2eeccac 201 iref_inc = 1;
nxp_ip 0:a624e2eeccac 202 mult_factor = required_steps / (iref + 1);
nxp_ip 0:a624e2eeccac 203 mult_factor = (mult_factor <= 0) ? 1 : mult_factor;
nxp_ip 0:a624e2eeccac 204 mult_factor = (64 < mult_factor) ? 64 : mult_factor;
nxp_ip 0:a624e2eeccac 205 } else {
nxp_ip 0:a624e2eeccac 206 iref_inc = (iref + 1) / required_steps;
nxp_ip 0:a624e2eeccac 207 iref_inc = (iref_inc <= 0) ? 1 : iref_inc;
nxp_ip 0:a624e2eeccac 208 iref_inc = (64 < iref_inc) ? 64 : iref_inc;
nxp_ip 0:a624e2eeccac 209 mult_factor = 1;
nxp_ip 0:a624e2eeccac 210 }
nxp_ip 0:a624e2eeccac 211 }
nxp_ip 0:a624e2eeccac 212
nxp_ip 0:a624e2eeccac 213 // printf( "ramp_time=%d, required_steps=%d, iref=%d\r\n", ramp_time, required_steps, iref );
nxp_ip 0:a624e2eeccac 214 // printf( "prescaler = %d, mult_factor=%d, iref_inc=%d\r\n", prescaler, mult_factor, iref_inc );
nxp_ip 0:a624e2eeccac 215 // printf( "\r\n" );
nxp_ip 0:a624e2eeccac 216
nxp_ip 0:a624e2eeccac 217 regs[ 0 ] = 0x80 | (RAMP_RATE_GRP0 + (group * 4));
nxp_ip 0:a624e2eeccac 218 regs[ RAMP_RATE_GRP ] = (ramp_flag << 6) | (iref_inc - 1);
nxp_ip 0:a624e2eeccac 219 regs[ STEP_TIME_GRP ] = (prescaler << 6) | (mult_factor - 1);
nxp_ip 0:a624e2eeccac 220 regs[ HOLD_CNTL_GRP ] = 0xC0 | (flag_on << 3) | flag_off;
nxp_ip 0:a624e2eeccac 221 regs[ IREF_GRP ] = iref;
nxp_ip 0:a624e2eeccac 222
nxp_ip 0:a624e2eeccac 223 write( regs, sizeof( regs ) );
nxp_ip 0:a624e2eeccac 224
nxp_ip 0:a624e2eeccac 225 #if 0
nxp_ip 0:a624e2eeccac 226 float n_of_steps;
nxp_ip 0:a624e2eeccac 227 float single_ramp_time;
nxp_ip 0:a624e2eeccac 228 float total_ramp_time;
nxp_ip 0:a624e2eeccac 229
nxp_ip 0:a624e2eeccac 230 n_of_steps = (float)(((iref + 1) / iref_inc) * mult_factor);
nxp_ip 0:a624e2eeccac 231 single_ramp_time = n_of_steps * (prescaler ? 8.0 : 0.5);
nxp_ip 0:a624e2eeccac 232 total_ramp_time = single_ramp_time * ((ramp_flag == RAMP_UP_DOWN) ? 2.0 : 1.0);
nxp_ip 0:a624e2eeccac 233 printf( "n_of_steps = %f, single_ramp_time=%f, total_ramp_time=%f\r\n", n_of_steps, single_ramp_time, total_ramp_time );
nxp_ip 0:a624e2eeccac 234 printf( "hold_time[ flag_on ] = %f, hold_time[ flag_off ]=%f\r\n", hold_time[ flag_on ], hold_time[ flag_off ] );
nxp_ip 0:a624e2eeccac 235 #endif
nxp_ip 0:a624e2eeccac 236
nxp_ip 0:a624e2eeccac 237 return ( (((((float)(((iref + 1) / iref_inc) * mult_factor)) * (prescaler ? 8.0 : 0.5)) * ((ramp_flag == RAMP_UP_DOWN) ? 2.0 : 1.0)) ) * 0.001 + (hold_time[ flag_on ] + hold_time[ flag_off ]) );
nxp_ip 0:a624e2eeccac 238 }
nxp_ip 0:a624e2eeccac 239
nxp_ip 0:a624e2eeccac 240
nxp_ip 0:a624e2eeccac 241 void PCA9955A::dump_gradation_registers( void )
nxp_ip 0:a624e2eeccac 242 {
nxp_ip 0:a624e2eeccac 243 char data[ 23 ];
nxp_ip 0:a624e2eeccac 244
nxp_ip 0:a624e2eeccac 245 read( RAMP_RATE_GRP0, data, sizeof( data ) );
nxp_ip 0:a624e2eeccac 246
nxp_ip 0:a624e2eeccac 247 printf( "GRAD_MODE_SEL[1|0] = 0x%02X%02X\r\n", data[ 17 ], data[ 16 ] );
nxp_ip 0:a624e2eeccac 248 printf( "GRAD_GRP_SEL[3|2|1|0] = 0x%02X%02X%02X%02X\r\n", data[ 21 ], data[ 20 ], data[ 19 ], data[ 18 ] );
nxp_ip 0:a624e2eeccac 249 printf( "GRAD_CNTL = 0x%02X\r\n", data[ 22 ] );
nxp_ip 0:a624e2eeccac 250 printf( "RAMP_RATE = 0x%02X 0x%02X 0x%02X 0x%02X\r\n", data[ 0 ], data[ 4 ], data[ 8 ], data[ 12 ] );
nxp_ip 0:a624e2eeccac 251 printf( "STEP_TIME = 0x%02X 0x%02X 0x%02X 0x%02X\r\n", data[ 1 ], data[ 5 ], data[ 9 ], data[ 13 ] );
nxp_ip 0:a624e2eeccac 252 printf( "HOLD_CNTL = 0x%02X 0x%02X 0x%02X 0x%02X\r\n", data[ 2 ], data[ 6 ], data[ 10 ], data[ 14 ] );
nxp_ip 0:a624e2eeccac 253 printf( "IREF = 0x%02X 0x%02X 0x%02X 0x%02X\r\n", data[ 3 ], data[ 7 ], data[ 11 ], data[ 15 ] );
nxp_ip 0:a624e2eeccac 254 printf( "\r\n" );
nxp_ip 0:a624e2eeccac 255 }