demo sample to drive PCU9955 and PCA9629

Dependencies:   mbed I2C_slaves PCU9669 parallel_bus

Fork of mini_board_PCU9669 by InetrfaceProducts NXP

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers demo_patterns.cpp Source File

demo_patterns.cpp

00001 #include "demo_patterns.h"
00002 #include "transfer_manager.h"
00003 #include "PCx9955_reg.h"
00004 #include "PCA9629_reg.h"
00005 #include "PCU9669_access.h" //  PCU9669 chip access interface
00006 
00007 #include "mbed.h"
00008 
00009 typedef struct  pattern_st {
00010     int     duration;
00011     void    (*pattern_func)( int count );
00012 }
00013 pattern;
00014 
00015 char    gLEDs[ N_OF_LEDS ]  = { 0 };
00016 int     gCount              = 0;
00017 
00018 char    nine_step_intensity[]  = { 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF };
00019 char    sixteen_step_intensity[]  = { 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01, 0x00 };
00020 
00021 char     gMot_cntl_order[ 5 ]    = { MOT_ADDR5, MOT_ADDR6, MOT_ADDR7, MOT_ADDR8, MOT_ADDR9 };
00022 char     gMot_cntl_order_halfturn[ 10 ]    = { MOT_ADDR5, 0, MOT_ADDR6, MOT_ADDR7, MOT_ADDR8, MOT_ADDR9, 0, MOT_ADDR8,  MOT_ADDR7, MOT_ADDR6 };
00023 char     gMotor_count;
00024 
00025 typedef enum {
00026     RED,
00027     GREEN,
00028     BLUE,
00029 }
00030 color;
00031 
00032 char rgb_mask[ 3 ][ 15 ]  = {
00033     { 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 },
00034     { 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 },
00035     { 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0 }
00036 };
00037 
00038 char  led_init_array[] = {
00039     0x80,                //  Command
00040     0x00, 0x05,                                     //  MODE1, MODE2
00041     0xAA, 0xAA, 0xAA, 0xAA,                         //  LEDOUT[3:0]
00042     0x80, 0x00,                                     //  GRPPWM, GRPFREQ
00043     PWM_INIT,  PWM_INIT,  PWM_INIT,  PWM_INIT,  PWM_INIT,  PWM_INIT,  PWM_INIT,  PWM_INIT, //  PWM[7:0]
00044     PWM_INIT,  PWM_INIT,  PWM_INIT,  PWM_INIT,  PWM_INIT,  PWM_INIT,  PWM_INIT,  PWM_INIT, //  PWM[15:8]
00045     IREF_INIT, IREF_INIT, IREF_INIT, IREF_INIT, IREF_INIT, IREF_INIT, IREF_INIT, IREF_INIT, //  IREF[7:0]
00046     IREF_INIT, IREF_INIT, IREF_INIT, IREF_INIT, IREF_INIT, IREF_INIT, IREF_INIT, IREF_INIT, //  IREF[15:8]
00047     0x08                                            //  OFFSET: 1uS offsets
00048 };
00049 
00050 char  led_norm_op_array[] = {
00051     0x80 | PWM0,                //  Command
00052     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     //  PWM[7:0]
00053     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     //  PWM[14:8]
00054 };
00055 
00056 char    mot_init_array[] = {
00057     0x80,
00058     0x20, 0xE2, 0xE4, 0xE6, 0xE0, 0x02, 0x10,             //  for registers MODE - WDCNTL (0x00 - 0x06
00059     0x00, 0x00,                                           //  for registers IP and INTSTAT (0x07, 0x08)
00060     0x0F, 0x03, 0x0C, 0x0F, 0x03, 0x01, 0x01, 0x00, 0x01, //  for registers OP - INT_AUTO_CLR (0x09 - 0x11)
00061     0x00, 0x00, 0x30, 0x00, 0x82, 0x06, 0x82, 0x06,       //  for registers SETMODE - CCWPWH (0x12 - 0x19)
00062     0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,       //  for registers CWSCOUNTL - CCWRCOUNTH (0x1A - 0x21)
00063     0x00, 0x00,                                           //  for registers EXTRASTEPS0 and EXTRASTEPS1 (0x22, 0x23)
00064     0x00, 0x00, 0x84                                      //  for registers RMPCNTL - MCNTL (0x24 - 0x26)
00065 };
00066 
00067 char    mot_all_stop[] = {
00068     0x26, 0x00
00069 };
00070 
00071 char    mot_all_start[] = {
00072     0x26, 0xBA
00073 };
00074 
00075 char    mot_ramp_array[] = {
00076     0x80,
00077     0x20, 0xE2, 0xE4, 0xE6, 0xE0, 0xFF, 0x10,             //  for registers MODE - WDCNTL (0x00 - 0x06
00078     0x00, 0x00,                                           //  for registers IP and INTSTAT (0x07, 0x08)
00079     0x0F, 0x03, 0x0C, 0x0F, 0x03, 0x00, 0x03, 0x03, 0x01, //  for registers OP - INT_AUTO_CLR (0x09 - 0x11)
00080     0x00, 0x00, 0x30, 0x00, 0x97, 0x04, 0x97, 0x04,       //  for registers SETMODE - CCWPWH (0x12 - 0x19)
00081     0x23, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,       //  for registers CWSCOUNTL - CCWRCOUNTH (0x1A - 0x21)
00082     0x0C, 0x0C,                                           //  for registers EXTRASTEPS0 and EXTRASTEPS1 (0x22, 0x23)
00083     0x37, 0x00, 0x88                                      //  for registers RMPCNTL - MCNTL (0x24 - 0x26)
00084 };
00085 
00086 char    mot_vib_array[] = {
00087     0x80,
00088     0x20, 0xE2, 0xE4, 0xE6, 0xE0, 0xFF, 0x10,             //  for registers MODE - WDCNTL (0x00 - 0x06
00089     0x00, 0x00,                                           //  for registers IP and INTSTAT (0x07, 0x08)
00090     0x0F, 0x03, 0x0C, 0x0F, 0x03, 0x00, 0x03, 0x03, 0x01, //  for registers OP - INT_AUTO_CLR (0x09 - 0x11)
00091     0x00, 0x00, 0x30, 0x00, 0x82, 0x06, 0x82, 0x06,       //  for registers SETMODE - CCWPWH (0x12 - 0x19)
00092     0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,       //  for registers CWSCOUNTL - CCWRCOUNTH (0x1A - 0x21)
00093     0x0C, 0x0C,                                           //  for registers EXTRASTEPS0 and EXTRASTEPS1 (0x22, 0x23)
00094     0x00, 0x00, 0xBA                                      //  for registers RMPCNTL - MCNTL (0x24 - 0x26)
00095 };
00096 
00097 //#define INTERVAL128MS
00098 #ifdef INTERVAL128MS
00099 char    mot_norm_op_array[] = {
00100     0x80,
00101     0x20, 0xE2, 0xE4, 0xE6, 0xE0, 0x02, 0x10,             //  for registers MODE - WDCNTL (0x00 - 0x06
00102     0x00, 0x00,                                           //  for registers IP and INTSTAT (0x07, 0x08)
00103     0x0F, 0x03, 0x0C, 0x0F, 0x03, 0x00, 0x01, 0x00, 0x01, //  for registers OP - INT_AUTO_CLR (0x09 - 0x11)
00104     0x00, 0x00, 0x30, 0x00, 0xF2, 0x06, 0xF2, 0x06,       //  for registers SETMODE - CCWPWH (0x12 - 0x19)
00105     0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,       //  for registers CWSCOUNTL - CCWRCOUNTH (0x1A - 0x21)
00106     0x00, 0x00,                                           //  for registers EXTRASTEPS0 and EXTRASTEPS1 (0x22, 0x23)
00107     0x00, 0x00, 0x00                                      //  for registers RMPCNTL - MCNTL (0x24 - 0x26)
00108 };
00109 
00110 char    mot_half_array[] = {
00111     0x80,
00112     0x20, 0xE2, 0xE4, 0xE6, 0xE0, 0x02, 0x10,             //  for registers MODE - WDCNTL (0x00 - 0x06
00113     0x00, 0x00,                                           //  for registers IP and INTSTAT (0x07, 0x08)
00114     0x0F, 0x03, 0x0C, 0x0F, 0x03, 0x00, 0x01, 0x00, 0x01, //  for registers OP - INT_AUTO_CLR (0x09 - 0x11)
00115     0x00, 0x00, 0x30, 0x00, 0xF2, 0x06, 0xF2, 0x06,       //  for registers SETMODE - CCWPWH (0x12 - 0x19)
00116     0x18, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,       //  for registers CWSCOUNTL - CCWRCOUNTH (0x1A - 0x21)
00117     0x00, 0x00,                                           //  for registers EXTRASTEPS0 and EXTRASTEPS1 (0x22, 0x23)
00118     0x00, 0x00, 0x00                                      //  for registers RMPCNTL - MCNTL (0x24 - 0x26)
00119 };
00120 #else
00121 char    mot_norm_op_array[] = {
00122     0x80,
00123     0x20, 0xE2, 0xE4, 0xE6, 0xE0, 0x02, 0x10,             //  for registers MODE - WDCNTL (0x00 - 0x06
00124     0x00, 0x00,                                           //  for registers IP and INTSTAT (0x07, 0x08)
00125     0x0F, 0x03, 0x0C, 0x0F, 0x03, 0x00, 0x01, 0x00, 0x01, //  for registers OP - INT_AUTO_CLR (0x09 - 0x11)
00126     0x00, 0x00, 0x30, 0x00, 0xE4, 0x0D, 0xE4, 0x0D,       //  for registers SETMODE - CCWPWH (0x12 - 0x19)
00127     0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,       //  for registers CWSCOUNTL - CCWRCOUNTH (0x1A - 0x21)
00128     0x00, 0x00,                                           //  for registers EXTRASTEPS0 and EXTRASTEPS1 (0x22, 0x23)
00129     0x00, 0x00, 0x00                                      //  for registers RMPCNTL - MCNTL (0x24 - 0x26)
00130 };
00131 
00132 char    mot_half_array[] = {
00133     0x80,
00134     0x20, 0xE2, 0xE4, 0xE6, 0xE0, 0x02, 0x10,             //  for registers MODE - WDCNTL (0x00 - 0x06
00135     0x00, 0x00,                                           //  for registers IP and INTSTAT (0x07, 0x08)
00136     0x0F, 0x03, 0x0C, 0x0F, 0x03, 0x00, 0x01, 0x00, 0x01, //  for registers OP - INT_AUTO_CLR (0x09 - 0x11)
00137     0x00, 0x00, 0x30, 0x00, 0xE4, 0x0D, 0xE4, 0x0D,       //  for registers SETMODE - CCWPWH (0x12 - 0x19)
00138     0x18, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,       //  for registers CWSCOUNTL - CCWRCOUNTH (0x1A - 0x21)
00139     0x00, 0x00,                                           //  for registers EXTRASTEPS0 and EXTRASTEPS1 (0x22, 0x23)
00140     0x00, 0x00, 0x00                                      //  for registers RMPCNTL - MCNTL (0x24 - 0x26)
00141 };
00142 #endif
00143 
00144 
00145 transaction     led_init_transfer[]   =   {
00146     { PCx9955_ADDR0, led_init_array, sizeof( led_init_array ) },
00147     { PCx9955_ADDR1, led_init_array, sizeof( led_init_array ) },
00148     { PCx9955_ADDR2, led_init_array, sizeof( led_init_array ) },
00149     { PCx9955_ADDR3, led_init_array, sizeof( led_init_array ) },
00150 };
00151 
00152 transaction     led_norm_op_transfer[]   =   {
00153     { PCx9955_ADDR0, led_norm_op_array, sizeof( led_norm_op_array ) },
00154     { PCx9955_ADDR1, led_norm_op_array, sizeof( led_norm_op_array ) },
00155     { PCx9955_ADDR2, led_norm_op_array, sizeof( led_norm_op_array ) },
00156     { PCx9955_ADDR3, led_norm_op_array, sizeof( led_norm_op_array ) },
00157 };
00158 
00159 transaction     mot_init_transfer[]   =   {
00160     { MOT_ADDR5, mot_init_array, sizeof( mot_init_array ) },
00161     { MOT_ADDR6, mot_init_array, sizeof( mot_init_array ) },
00162     { MOT_ADDR7, mot_init_array, sizeof( mot_init_array ) },
00163     { MOT_ADDR8, mot_init_array, sizeof( mot_init_array ) },
00164     { MOT_ADDR9, mot_init_array, sizeof( mot_init_array ) },
00165 };
00166 
00167 transaction     mot_norm_op_transfer[]   =   {
00168     { MOT_ADDR5, mot_norm_op_array, sizeof( mot_norm_op_array ) },
00169     { MOT_ADDR6, mot_norm_op_array, sizeof( mot_norm_op_array ) },
00170     { MOT_ADDR7, mot_norm_op_array, sizeof( mot_norm_op_array ) },
00171     { MOT_ADDR8, mot_norm_op_array, sizeof( mot_norm_op_array ) },
00172     { MOT_ADDR9, mot_norm_op_array, sizeof( mot_norm_op_array ) },
00173 };
00174 
00175 transaction     mot_half_transfer[]   =   {
00176     { MOT_ADDR5, mot_norm_op_array, sizeof( mot_norm_op_array ) },
00177     { MOT_ADDR6, mot_half_array, sizeof( mot_half_array ) },
00178     { MOT_ADDR7, mot_half_array, sizeof( mot_half_array ) },
00179     { MOT_ADDR8, mot_half_array, sizeof( mot_half_array ) },
00180     { MOT_ADDR9, mot_norm_op_array, sizeof( mot_norm_op_array ) },
00181 };
00182 
00183 transaction     mot_half_setup_transfer[]   =   {
00184     { MOT_ADDR5, mot_half_array, sizeof( mot_half_array ) },
00185     { MOT_ADDR6, mot_half_array, sizeof( mot_half_array ) },
00186     { MOT_ADDR7, mot_half_array, sizeof( mot_half_array ) },
00187     { MOT_ADDR8, mot_half_array, sizeof( mot_half_array ) },
00188     { MOT_ADDR9, mot_half_array, sizeof( mot_half_array ) },
00189 };
00190 
00191 transaction     mot_all_stop_transfer[]   =   {
00192     { MOT_ADDR5, mot_all_stop, sizeof( mot_all_stop ) },
00193     { MOT_ADDR6, mot_all_stop, sizeof( mot_all_stop ) },
00194     { MOT_ADDR7, mot_all_stop, sizeof( mot_all_stop ) },
00195     { MOT_ADDR8, mot_all_stop, sizeof( mot_all_stop ) },
00196     { MOT_ADDR9, mot_all_stop, sizeof( mot_all_stop ) },
00197 };
00198 
00199 transaction     mot_all_start_transfer[]   =   {
00200     { MOT_ADDR5, mot_all_start, sizeof( mot_all_start ) },
00201     { MOT_ADDR6, mot_all_start, sizeof( mot_all_start ) },
00202     { MOT_ADDR7, mot_all_start, sizeof( mot_all_start ) },
00203     { MOT_ADDR8, mot_all_start, sizeof( mot_all_start ) },
00204     { MOT_ADDR9, mot_all_start, sizeof( mot_all_start ) },
00205 };
00206 
00207 transaction     mot_all_vib_transfer[]   =   {
00208     { MOT_ADDR5, mot_vib_array, sizeof( mot_vib_array ) },
00209     { MOT_ADDR6, mot_vib_array, sizeof( mot_vib_array ) },
00210     { MOT_ADDR7, mot_vib_array, sizeof( mot_vib_array ) },
00211     { MOT_ADDR8, mot_vib_array, sizeof( mot_vib_array ) },
00212     { MOT_ADDR9, mot_vib_array, sizeof( mot_vib_array ) },
00213 };
00214 
00215 transaction     mot_all_ramp_transfer[]   =   {
00216     { MOT_ADDR5, mot_ramp_array, sizeof( mot_ramp_array ) },
00217     { MOT_ADDR6, mot_ramp_array, sizeof( mot_ramp_array ) },
00218     { MOT_ADDR7, mot_ramp_array, sizeof( mot_ramp_array ) },
00219     { MOT_ADDR8, mot_ramp_array, sizeof( mot_ramp_array ) },
00220     { MOT_ADDR9, mot_ramp_array, sizeof( mot_ramp_array ) },
00221 };
00222 
00223 void init_slave_devices( void )
00224 {
00225     //  init all slave's registers
00226     setup_transfer( CH_FM_PLUS, mot_init_transfer, sizeof( mot_init_transfer ) / sizeof( transaction ) );
00227     setup_transfer( CH_UFM1, led_init_transfer, sizeof( led_init_transfer ) / sizeof( transaction ) );
00228     setup_transfer( CH_UFM2, led_init_transfer, sizeof( led_init_transfer ) / sizeof( transaction ) );
00229     start( CH_FM_PLUS );    //  motors are aligned using interrupt input of PCA9629
00230     start( CH_UFM1 );
00231     start( CH_UFM2 );
00232 
00233     wait_sec( 0.5 );
00234 
00235     //  update motor control buffer configuration
00236 
00237     setup_transfer( CH_FM_PLUS, mot_norm_op_transfer, sizeof( mot_norm_op_transfer ) / sizeof( transaction ) );
00238     setup_transfer( CH_UFM1, led_norm_op_transfer, sizeof( led_norm_op_transfer ) / sizeof( transaction ) );
00239     setup_transfer( CH_UFM2, led_norm_op_transfer, sizeof( led_norm_op_transfer ) / sizeof( transaction ) );
00240     start( CH_FM_PLUS );    //  just update PCA9629 registers. no motor action
00241     start( CH_UFM1 );
00242     start( CH_UFM2 );
00243 }
00244 
00245 void single_byte_write_into_a_PCA9629( char ch, char i2c_addr, char reg_addr, char val )
00246 {
00247     transaction     t;
00248     char            data[ 2 ];
00249 
00250     data[ 0 ]   = reg_addr;
00251     data[ 1 ]   = val;
00252 
00253     t.i2c_address   = i2c_addr;
00254     t.data          = data;
00255     t.length        = 2;
00256 
00257     setup_transfer( ch, &t, 1 );
00258     start( CH_FM_PLUS );
00259 }
00260 
00261 void ramp_all_PCA9629( void )
00262 {
00263     setup_transfer( CH_FM_PLUS, mot_all_ramp_transfer, sizeof( mot_all_ramp_transfer ) / sizeof( transaction ) );
00264     start( CH_FM_PLUS );
00265 }
00266 void vib_all_PCA9629( void )
00267 {
00268     setup_transfer( CH_FM_PLUS, mot_all_vib_transfer, sizeof( mot_all_vib_transfer ) / sizeof( transaction ) );
00269     start( CH_FM_PLUS );
00270 }
00271 void start_all_PCA9629( void )
00272 {
00273     setup_transfer( CH_FM_PLUS, mot_all_start_transfer, sizeof( mot_all_start_transfer ) / sizeof( transaction ) );
00274     start( CH_FM_PLUS );
00275 }
00276 void stop_all_PCA9629( void )
00277 {
00278     setup_transfer( CH_FM_PLUS, mot_all_stop_transfer, sizeof( mot_all_stop_transfer ) / sizeof( transaction ) );
00279     start( CH_FM_PLUS );
00280 }
00281 void align_all_PCA9629( void )
00282 {
00283     setup_transfer( CH_FM_PLUS, mot_init_transfer, sizeof( mot_init_transfer ) / sizeof( transaction ) );
00284     start( CH_FM_PLUS );
00285 }
00286 
00287 void all_LEDs_value( char v )
00288 {
00289     for ( int i = 0; i < N_OF_LEDS; i++ )
00290         gLEDs[ i ]  = v;
00291 }
00292 
00293 void all_LEDs_turn_off()
00294 {
00295     all_LEDs_value( 0x00 );
00296 }
00297 
00298 void all_LEDs_turn_on()
00299 {
00300     all_LEDs_value( 0xFF );
00301 }
00302 
00303 void pattern_rampup( int count )
00304 {
00305     if ( count == 0 ) {
00306         all_LEDs_turn_off();
00307         return;
00308     }
00309 
00310     for ( int i = 0; i < N_OF_LEDS; i++ )
00311         gLEDs[ i ] = count & 0xFF;
00312 }
00313 
00314 void pattern_rampup_and_down( int count )
00315 {
00316     if ( !(count & 0xFF) ) {
00317         ramp_all_PCA9629();
00318         all_LEDs_turn_off();
00319         return;
00320     }
00321 
00322     for ( int i = 0; i < N_OF_LEDS; i++ )
00323         gLEDs[ i ] = (((count & 0x80) ? ~count : count) << 1) & 0xFF;
00324 }
00325 
00326 void pattern_rampup_and_down_w_color( int count )
00327 {
00328     static int color;
00329 
00330     color   = (!count || (3 <= color)) ? 0 : color;
00331 
00332     if ( !(count & 0xFF) ) {
00333         ramp_all_PCA9629();
00334         all_LEDs_turn_off();
00335         color++;
00336         return;
00337     }
00338 
00339     for ( int i = 0; i < N_OF_LEDS; i++ )
00340         gLEDs[ i ] = (rgb_mask[ color ][ i % N_LED_PER_BOARD ]) ? (((count & 0x80) ? ~count : count) << 1) & 0xFF : 0x00;
00341 }
00342 
00343 
00344 void pattern_colors2( int count )
00345 {
00346 
00347     if ( !count ) {
00348         gMotor_count     = 0;
00349         setup_transfer( CH_FM_PLUS, mot_norm_op_transfer, sizeof( mot_norm_op_transfer ) / sizeof( transaction ) );
00350         start( CH_FM_PLUS );    //  just update PCA9629 registers. no motor action
00351     }
00352 
00353     if ( !((count + 20) & 0x3F) ) {
00354         single_byte_write_into_a_PCA9629( CH_FM_PLUS, gMot_cntl_order[ gMotor_count % 5 ], 0x26, 0x80 | ((gMotor_count / 5) & 0x1) );
00355         gMotor_count++;
00356     }
00357 
00358 #define PI 3.14159265358979323846
00359 
00360     float   r;
00361     float   g;
00362     float   b;
00363     float   k;
00364     float   c;
00365     float   f;
00366 
00367     k   = (2 * PI) / 300.0;
00368     c   = count;
00369     f   = 127.5 * ((count < 500) ? (float)count / 500.0 : 1.0);
00370 
00371 #if 0
00372     r   = sin( k * (c +   0.0) );
00373     g   = sin( k * (c + 100.0) );
00374     b   = sin( k * (c + 200.0) );
00375     r   = (0 < r) ? r  * 255.0 : 0;
00376     g   = (0 < g) ? g  * 255.0 : 0;
00377     b   = (0 < b) ? b  * 255.0 : 0;
00378 #else
00379     r   = (sin( k * (c +   0.0) ) + 1) * f;
00380     g   = (sin( k * (c + 100.0) ) + 1) * f;
00381     b   = (sin( k * (c + 200.0) ) + 1) * f;
00382 #endif
00383     for ( int i = 0; i < N_OF_LEDS; i += N_LED_PER_BOARD ) {
00384         for ( int j = 0; j < 12; j += 3 ) {
00385             gLEDs[ i + j + 0 ] = (char)r;
00386             gLEDs[ i + j + 1 ] = (char)g;
00387             gLEDs[ i + j + 2 ] = (char)b;
00388         }
00389         for ( int j = 12; j < 15; j ++ )
00390             gLEDs[ i + j ] = (char)((((2500 <= count) && (count < 3000)) ? ((float)(count - 2500) / 500.0) : 0.0) * 255.0);
00391     }
00392 }
00393 
00394 //void pattern_color_phase( int count ) {
00395 void pattern_colors( int count )
00396 {
00397 
00398     if ( !count ) {
00399         gMotor_count     = 0;
00400         setup_transfer( CH_FM_PLUS, mot_norm_op_transfer, sizeof( mot_norm_op_transfer ) / sizeof( transaction ) );
00401         start( CH_FM_PLUS );    //  just update PCA9629 registers. no motor action
00402     }
00403 
00404     if ( !((count + 20) & 0x3F) ) {
00405         single_byte_write_into_a_PCA9629( CH_FM_PLUS, gMot_cntl_order[ gMotor_count % 5 ], 0x26, 0x80 | ((gMotor_count / 5) & 0x1) );
00406         gMotor_count++;
00407     }
00408 
00409 #define     PI 3.14159265358979323846
00410 
00411     float   p;
00412     float   k;
00413     float   c;
00414     float   f;
00415 
00416     k   = (2 * PI) / 300.0;
00417     p   = 300.0 / N_OF_LEDS;
00418     c   = count;
00419     f   = 127.5 * ((count < 500) ? c / 500.0 : 1.0);
00420 
00421     for ( int i = 0; i < N_OF_LEDS; i += N_LED_PER_BOARD ) {
00422         for ( int j = 0; j < 12; j += 3 ) {
00423             gLEDs[ i + j + 0 ] = (char)((sin( k * (c +   0.0) + p * (i + j) ) + 1) * f);
00424             gLEDs[ i + j + 1 ] = (char)((sin( k * (c + 100.0) + p * (i + j) ) + 1) * f);
00425             gLEDs[ i + j + 2 ] = (char)((sin( k * (c + 200.0) + p * (i + j) ) + 1) * f);
00426         }
00427         for ( int j = 12; j < 15; j ++ )
00428             gLEDs[ i + j ] = (char)((((2500 <= count) && (count < 3000)) ? ((float)(count - 2500) / 500.0) : 0.0) * 255.0);
00429     }
00430 }
00431 
00432 
00433 
00434 
00435 
00436 void pattern_one_by_one( int count )
00437 {
00438     if ( count == 0 ) {
00439         all_LEDs_turn_off();
00440         return;
00441     }
00442 
00443     gLEDs[ (count / 9) % N_OF_LEDS ] = nine_step_intensity[ count % 9 ];
00444 }
00445 
00446 void pattern_random( int count )
00447 {
00448     if ( count == 0 ) {
00449         all_LEDs_turn_off();
00450         return;
00451     }
00452     gLEDs[ rand() % N_OF_LEDS ] = rand() % 0xFF;
00453 }
00454 
00455 void pattern_random_with_decay0( int count )
00456 {
00457     if ( count == 0 ) {
00458         all_LEDs_turn_off();
00459         return;
00460     }
00461     gLEDs[ rand() % N_OF_LEDS ] = 0xFF;
00462 
00463     for ( int i = 0; i < N_OF_LEDS; i++ )
00464         gLEDs[ i ] = (char)((float)gLEDs[ i ] * 0.90);
00465 }
00466 
00467 void pattern_random_with_decay1( int count )
00468 {
00469     if ( count == 0 ) {
00470         all_LEDs_turn_off();
00471         return;
00472     }
00473     gLEDs[ rand() % N_OF_LEDS ] = 0xFF;
00474 
00475     for ( int i = 0; i < N_OF_LEDS; i++ )
00476         gLEDs[ i ] = (char)((float)gLEDs[ i ] * 0.7);
00477 }
00478 
00479 void pattern_flashing( int count )
00480 {
00481 #define SUSTAIN_DURATION    10
00482     static float    interval;
00483     static int      timing;
00484     static int      sustain;
00485 
00486     if ( count == 0 ) {
00487         interval    = 100.0;
00488         timing      = 0;
00489         sustain     = SUSTAIN_DURATION;
00490         vib_all_PCA9629();
00491     }
00492     if ( (timing == count) || !((int)interval) ) {
00493         sustain     = SUSTAIN_DURATION;
00494         all_LEDs_turn_on();
00495         start_all_PCA9629();
00496 
00497         timing      += (int)interval;
00498         interval    *= 0.96;
00499     } else {
00500         for ( int i = 0; i < N_OF_LEDS; i++ )
00501             gLEDs[ i ] = (char)((float)gLEDs[ i ] * 0.90);
00502 
00503         if ( sustain-- < 0 )
00504             stop_all_PCA9629();
00505     }
00506 }
00507 
00508 void stop( int count )
00509 {
00510     if ( !count ) {
00511         all_LEDs_turn_off();
00512         stop_all_PCA9629();
00513     }
00514 }
00515 
00516 void pattern_init( int count )
00517 {
00518 
00519     if ( !count )
00520         align_all_PCA9629();
00521 }
00522 
00523 
00524 void pattern_scan( int count )
00525 {
00526     static char     gMotor_count;
00527 
00528     if ( !count ) {
00529         gMotor_count     = 0;
00530         setup_transfer( CH_FM_PLUS, mot_norm_op_transfer, sizeof( mot_norm_op_transfer ) / sizeof( transaction ) );
00531         start( CH_FM_PLUS );    //  just update PCA9629 registers. no motor action
00532     }
00533 
00534     if ( !(count & 0x1F) ) {
00535         single_byte_write_into_a_PCA9629( CH_FM_PLUS, gMot_cntl_order[ gMotor_count % 5 ], 0x26, 0x80 | ((gMotor_count / 5) & 0x1) );
00536         gMotor_count++;
00537     }
00538 
00539     all_LEDs_turn_off();
00540     gLEDs[ (count >> 3) % N_OF_LEDS ] = 0xFF;
00541 }
00542 
00543 void pattern_setup_half_turns( int count )
00544 {
00545 
00546     if ( !count ) {
00547         align_all_PCA9629();
00548         gMotor_count    = 0;
00549     } else if ( count == 50 ) {
00550         setup_transfer( CH_FM_PLUS, mot_half_setup_transfer, sizeof( mot_half_transfer ) / sizeof( transaction ) );
00551         start( CH_FM_PLUS );
00552     } else if ( count == 60 ) {
00553         single_byte_write_into_a_PCA9629( CH_FM_PLUS, gMot_cntl_order[ 4 ], 0x26, 0x80 );
00554     } else if ( count == 75 ) {
00555         single_byte_write_into_a_PCA9629( CH_FM_PLUS, gMot_cntl_order[ 3 ], 0x26, 0x80 );
00556     } else if ( count == 90 ) {
00557         single_byte_write_into_a_PCA9629( CH_FM_PLUS, gMot_cntl_order[ 2 ], 0x26, 0x80 );
00558     } else if ( count == 115 ) {
00559         single_byte_write_into_a_PCA9629( CH_FM_PLUS, gMot_cntl_order[ 1 ], 0x26, 0x80 );
00560     } else if ( count == 150 ) {
00561         setup_transfer( CH_FM_PLUS, mot_half_transfer, sizeof( mot_half_transfer ) / sizeof( transaction ) );
00562         start( CH_FM_PLUS );
00563     }
00564 }
00565 
00566 
00567 
00568 void pattern_half_turns( int count )
00569 {
00570 
00571 #ifdef INTERVAL128MS
00572     if ( !(count & 0x0F) ) {
00573 #else
00574     if ( !(count & 0x1F) ) {
00575 #endif
00576         if ( gMot_cntl_order_halfturn[ gMotor_count ] )
00577             single_byte_write_into_a_PCA9629( CH_FM_PLUS, gMot_cntl_order_halfturn[ gMotor_count ], 0x26, 0x80 | ((gMot_cntl_order_halfturn[ gMotor_count ] >> 1) & 0x1) );
00578         gMotor_count++;
00579 
00580         gMotor_count = (gMotor_count == 10) ? 0 : gMotor_count;
00581     }
00582 
00583 
00584 //    all_LEDs_turn_off();
00585 //    gLEDs[ (count >> 3) % N_OF_LEDS ] = 0xFF;
00586 }
00587 
00588 
00589 
00590 void pattern_fadeout300( int count )
00591 {
00592 
00593     if ( !count )
00594         stop_all_PCA9629();
00595     else if ( count == 100 )
00596         align_all_PCA9629();
00597 
00598     for ( int i = 0; i < N_OF_LEDS; i++ )
00599         gLEDs[ i ] = (char)((float)gLEDs[ i ] * 0.994469);  //  (0.994469 = 1/(255^(1/999))) BUT VALUE IS TRANCATED IN THE LOOP. IT DECALYS FASTER THAN FLOAT CALC.
00600 }
00601 
00602 void pattern_speed_variations( int count )
00603 {
00604 
00605     char    data[ 4 ];
00606     int     v;
00607 
00608     if ( !count ) {
00609         setup_transfer( CH_FM_PLUS, mot_norm_op_transfer, sizeof( mot_norm_op_transfer ) / sizeof( transaction ) );
00610 
00611         data[ 0 ]   = 0x2;
00612         for ( int i = 0;  i < 5; i++ )
00613             buffer_overwrite( CH_FM_PLUS, i, 20, data, 1 );     //  Set half step operation
00614 
00615         for ( int i = 0;  i < 5; i++ ) {
00616             v   = 833;// 400pps for halfstep
00617             data[ 0 ]   = data[ 2 ]   = v & 0xFF;
00618             data[ 1 ]   = data[ 3 ]   = (i << 5) | (v >> 8);
00619             buffer_overwrite( CH_FM_PLUS, i, 23, data, 4 );
00620         }
00621 
00622         for ( int i = 0;  i < 5; i++ ) {
00623             v   = (0x1 << (5 - i));
00624             data[ 0 ]   = data[ 2 ]   = v & 0xFF;
00625             data[ 1 ]   = data[ 3 ]   = v >> 8;
00626             buffer_overwrite( CH_FM_PLUS, i, 31, data, 4 );
00627         }
00628 
00629 
00630     }
00631 
00632     if ( !(count % 500) ) {
00633         data[ 0 ]   = 0x84 | ((count / 500) & 0x1);
00634         for ( int i = 0;  i < 5; i++ )
00635             buffer_overwrite( CH_FM_PLUS, i, 39, data, 1 );
00636         start( CH_FM_PLUS );
00637     }
00638 }
00639 
00640 void pattern_mot_ramp_variations( int count )
00641 {
00642 
00643     char    ramp_var[5][17] = {
00644         { 0x5D, 0x03, 0x5D, 0x03,   0x0B, 0x00, 0x00, 0x00,   0x0F, 0x00, 0x00, 0x00,   0x00, 0x00, 0x36, 0x00,   0x88 },
00645         { 0x4B, 0x05, 0x4B, 0x05,   0x25, 0x00, 0x00, 0x00,   0x11, 0x00, 0x00, 0x00,   0x00, 0x00, 0x37, 0x00,   0x88 },
00646         { 0x15, 0x06, 0x15, 0x06,   0x2D, 0x00, 0x00, 0x00,   0x12, 0x00, 0x00, 0x00,   0x00, 0x00, 0x38, 0x00,   0x88 },
00647         { 0x71, 0x06, 0x71, 0x06,   0x17, 0x00, 0x00, 0x00,   0x13, 0x00, 0x00, 0x00,   0x00, 0x00, 0x39, 0x00,   0x88 },
00648         { 0x9C, 0x06, 0x9C, 0x06,   0x23, 0x00, 0x00, 0x00,   0x13, 0x00, 0x00, 0x00,   0x00, 0x00, 0x3A, 0x00,   0x88 },
00649     };
00650 
00651     if ( !count ) {
00652         setup_transfer( CH_FM_PLUS, mot_norm_op_transfer, sizeof( mot_norm_op_transfer ) / sizeof( transaction ) );
00653 
00654         for ( int i = 0;  i < 5; i++ )
00655             buffer_overwrite( CH_FM_PLUS, i, 23, ramp_var[ i ], 17 );
00656 
00657         start( CH_FM_PLUS );
00658     }
00659 
00660     all_LEDs_turn_off();
00661     gLEDs[ count % N_OF_LEDS ] = 0xFF;
00662 
00663 }
00664 
00665 void pattern_knightrider( int count )
00666 {
00667     short   led_pat[ 12 ] = { 0x7000, 0x0004, 0x0E00, 0x0002, 0x01C0, 0x0001, 0x0038, 0x0001, 0x01C0, 0x0002, 0x0E00, 0x0004 };
00668     short   led_bits;
00669 
00670 #if 0
00671     //if ( !(count && 0x7) )
00672     {
00673         led_bits    = led_pat[ (count >> 4) % 12 ];
00674         for ( int i = 0; i < N_OF_LEDS; i += N_LED_PER_BOARD ) {
00675             for ( int j = 0; j < N_LED_PER_BOARD; j ++ ) {
00676                 gLEDs[ i + j ] = ((led_bits << j) & 0x4000) ? 0xFF : gLEDs[ i + j ];
00677             }
00678         }
00679     }
00680     for ( int i = 0; i < N_OF_LEDS; i++ )
00681         gLEDs[ i ] = (char)((float)gLEDs[ i ] * 0.90 * ((700 < count) ? (float)(1000 - count) / 300.0 : 1.0));
00682 #else
00683     //if ( !(count && 0x7) )
00684     {
00685         led_bits    = led_pat[ (count >> 4) % 12 ];
00686         for ( int i = 0; i < N_OF_LEDS; i += N_LED_PER_BOARD ) {
00687             for ( int j = 0; j < N_LED_PER_BOARD; j ++ ) {
00688                 gLEDs[ i + j ] = ((led_bits << j) & 0x4000) ? ((744 < count) ? (1000 - count) : 255) : gLEDs[ i + j ];
00689 //              gLEDs[ i + j ] = ((led_bits << j) & 0x4000) ? 0xFF : gLEDs[ i + j ];
00690             }
00691         }
00692     }
00693     for ( int i = 0; i < N_OF_LEDS; i++ )
00694         gLEDs[ i ] = (char)((float)gLEDs[ i ] * 0.90);
00695 #endif
00696 
00697 }
00698 pattern _gPt[]    = {
00699 //    { 256,      pattern_rampup },
00700     { 3000,      pattern_colors },
00701 };
00702 pattern gPt[]    = {
00703 //    { 256,      pattern_rampup },
00704     { 20,       stop },
00705     { 120,      pattern_init },
00706     { 3000,     pattern_colors },
00707     { 300,      pattern_fadeout300 },
00708     { 3000,     pattern_speed_variations },
00709     { 250,      pattern_setup_half_turns },
00710     { 3000,     pattern_half_turns },
00711     { 20,       stop },
00712     { 120,      pattern_init },
00713     { 960,      pattern_rampup_and_down_w_color },
00714     { 960,      pattern_scan },
00715     { 20,       stop },
00716     { 120,      pattern_init },
00717     { 1024,     pattern_rampup_and_down },
00718     { 700,      pattern_mot_ramp_variations },
00719     { 700,      pattern_mot_ramp_variations },
00720     { 700,      pattern_mot_ramp_variations },
00721     { 700,      pattern_mot_ramp_variations },
00722 
00723     { 3000,     pattern_flashing },
00724     { 300,      pattern_fadeout300 },
00725     { 512,      pattern_random },
00726     { 512,      pattern_random_with_decay1 },
00727     { 512,      pattern_random_with_decay0 },
00728     { 9 * 120,  pattern_one_by_one },
00729     { 1000,     pattern_knightrider },
00730 
00731 };
00732 
00733 
00734 
00735 void pattern_update( int count )
00736 {
00737     static int  next_pattern_change = 0;
00738     static int  local_count         = 0;
00739     static int  pattern_index      = -1;
00740 
00741     if ( next_pattern_change == count ) {
00742         local_count = 0;
00743         pattern_index++;
00744         pattern_index   = (pattern_index == (sizeof( gPt ) / sizeof( pattern )) ) ? 0 : pattern_index;
00745         next_pattern_change += gPt[ pattern_index ].duration;
00746     }
00747 
00748     (*gPt[ pattern_index ].pattern_func)( local_count++ );
00749 }
00750