demo sample to drive PCU9955 and PCA9629
Dependencies: mbed I2C_slaves PCU9669 parallel_bus
Fork of mini_board_PCU9669 by
What is this?
This is a sample code to operate PCU9955 (16ch constant-current LED controller) and PCA9629 (intelligent stepper motor controller) through PCU9669 (3 channels (UltraFast mode * 2ch, FastModePlus *1ch) I2C bus controller).
This demo is written based on mini_board_PCU9669 sample code library and its API.
http://mbed.org/users/nxp_ip/code/mini_board_PCU9669/
Demo will shows how the LED controllers and stepper motor controllers works.
It uses a mini_board_PCU9669 board with mbed, 8 of PCU9955s and 5 PCA9629s.
Demo setup
(left-top: PCU9955 boards, left-bottom: mini-board PCU9669 with mbed, right: PCA9629 x5 board)
Board connections and device addresses
Reference:
User manual of PCU9669 demo board: Mini board PCU9669
http://www.nxp.com/documents/user_manual/UM10580.pdf
sample code : mbed programs
Import programmini_board_PCU9669
mini board PCU9669 (and PCA9665) sample code
Import programPCA9955_Hello
PCA9955 16 channel current drive(sink) LED driver sample code
Import programPCA9955_simple
very simple sample code for PCA9955 (16 channel current control LED driver)
Import programPCA9629_Hello
Sample code for PCA9629 operation
device infomation
PCU9669 (Parallel bus to 1 channel Fm+ and 2 channel UFm I2C-bus controller)
PCU9955 (16-channel UFm I²C-bus 57 mA constant current LED driver)
PCA9955 (16-channel Fm+ I²C-bus 57 mA constant current LED driver)
PCU9629 (Fm+ I2C-bus stepper motor controller)
demo_patterns.cpp
- Committer:
- nxp_ip
- Date:
- 2012-10-26
- Revision:
- 20:a266fa588bd8
- Child:
- 21:3b75b545ecfb
File content as of revision 20:a266fa588bd8:
#include "demo_patterns.h" #include "transfer_manager.h" #include "PCx9955_reg.h" #include "PCA9629_reg.h" #include "PCU9669_access.h" // PCU9669 chip access interface #include "mbed.h" typedef struct pattern_st { int duration; void (*pattern_func)( int count ); } pattern; char gLEDs[ N_OF_LEDS ] = { 0 }; int gCount = 0; char nine_step_intensity[] = { 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF }; char sixteen_step_intensity[] = { 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01, 0x00 }; char gMot_cntl_order[ 5 ] = { MOT_ADDR5, MOT_ADDR6, MOT_ADDR7, MOT_ADDR8, MOT_ADDR9 }; char gMot_cntl_order_halfturn[ 10 ] = { MOT_ADDR5, 0, MOT_ADDR6, MOT_ADDR7, MOT_ADDR8, MOT_ADDR9, 0, MOT_ADDR8, MOT_ADDR7, MOT_ADDR6 }; char gMotor_count; typedef enum { RED, GREEN, BLUE, } color; char rgb_mask[ 3 ][ 15 ] = { { 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, { 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, { 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0 } }; char led_init_array[] = { 0x80, // Command 0x00, 0x05, // MODE1, MODE2 0xAA, 0xAA, 0xAA, 0xAA, // LEDOUT[3:0] 0x80, 0x00, // GRPPWM, GRPFREQ PWM_INIT, PWM_INIT, PWM_INIT, PWM_INIT, PWM_INIT, PWM_INIT, PWM_INIT, PWM_INIT, // PWM[7:0] PWM_INIT, PWM_INIT, PWM_INIT, PWM_INIT, PWM_INIT, PWM_INIT, PWM_INIT, PWM_INIT, // PWM[15:8] IREF_INIT, IREF_INIT, IREF_INIT, IREF_INIT, IREF_INIT, IREF_INIT, IREF_INIT, IREF_INIT, // IREF[7:0] IREF_INIT, IREF_INIT, IREF_INIT, IREF_INIT, IREF_INIT, IREF_INIT, IREF_INIT, IREF_INIT, // IREF[15:8] 0x08 // OFFSET: 1uS offsets }; char led_norm_op_array[] = { 0x80 | PWM0, // Command 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // PWM[7:0] 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // PWM[14:8] }; char mot_init_array[] = { 0x80, 0x20, 0xE2, 0xE4, 0xE6, 0xE0, 0x02, 0x10, // for registers MODE - WDCNTL (0x00 - 0x06 0x00, 0x00, // for registers IP and INTSTAT (0x07, 0x08) 0x0F, 0x03, 0x0C, 0x0F, 0x03, 0x01, 0x01, 0x00, 0x01, // for registers OP - INT_AUTO_CLR (0x09 - 0x11) 0x00, 0x00, 0x30, 0x00, 0x82, 0x06, 0x82, 0x06, // for registers SETMODE - CCWPWH (0x12 - 0x19) 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, // for registers CWSCOUNTL - CCWRCOUNTH (0x1A - 0x21) 0x00, 0x00, // for registers EXTRASTEPS0 and EXTRASTEPS1 (0x22, 0x23) 0x00, 0x00, 0x84 // for registers RMPCNTL - MCNTL (0x24 - 0x26) }; char mot_all_stop[] = { 0x26, 0x00 }; char mot_all_start[] = { 0x26, 0xBA }; char mot_ramp_array[] = { 0x80, 0x20, 0xE2, 0xE4, 0xE6, 0xE0, 0xFF, 0x10, // for registers MODE - WDCNTL (0x00 - 0x06 0x00, 0x00, // for registers IP and INTSTAT (0x07, 0x08) 0x0F, 0x03, 0x0C, 0x0F, 0x03, 0x00, 0x03, 0x03, 0x01, // for registers OP - INT_AUTO_CLR (0x09 - 0x11) 0x00, 0x00, 0x30, 0x00, 0x97, 0x04, 0x97, 0x04, // for registers SETMODE - CCWPWH (0x12 - 0x19) 0x23, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // for registers CWSCOUNTL - CCWRCOUNTH (0x1A - 0x21) 0x0C, 0x0C, // for registers EXTRASTEPS0 and EXTRASTEPS1 (0x22, 0x23) 0x37, 0x00, 0x88 // for registers RMPCNTL - MCNTL (0x24 - 0x26) }; char mot_vib_array[] = { 0x80, 0x20, 0xE2, 0xE4, 0xE6, 0xE0, 0xFF, 0x10, // for registers MODE - WDCNTL (0x00 - 0x06 0x00, 0x00, // for registers IP and INTSTAT (0x07, 0x08) 0x0F, 0x03, 0x0C, 0x0F, 0x03, 0x00, 0x03, 0x03, 0x01, // for registers OP - INT_AUTO_CLR (0x09 - 0x11) 0x00, 0x00, 0x30, 0x00, 0x82, 0x06, 0x82, 0x06, // for registers SETMODE - CCWPWH (0x12 - 0x19) 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, // for registers CWSCOUNTL - CCWRCOUNTH (0x1A - 0x21) 0x0C, 0x0C, // for registers EXTRASTEPS0 and EXTRASTEPS1 (0x22, 0x23) 0x00, 0x00, 0xBA // for registers RMPCNTL - MCNTL (0x24 - 0x26) }; //#define INTERVAL128MS #ifdef INTERVAL128MS char mot_norm_op_array[] = { 0x80, 0x20, 0xE2, 0xE4, 0xE6, 0xE0, 0x02, 0x10, // for registers MODE - WDCNTL (0x00 - 0x06 0x00, 0x00, // for registers IP and INTSTAT (0x07, 0x08) 0x0F, 0x03, 0x0C, 0x0F, 0x03, 0x00, 0x01, 0x00, 0x01, // for registers OP - INT_AUTO_CLR (0x09 - 0x11) 0x00, 0x00, 0x30, 0x00, 0xF2, 0x06, 0xF2, 0x06, // for registers SETMODE - CCWPWH (0x12 - 0x19) 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, // for registers CWSCOUNTL - CCWRCOUNTH (0x1A - 0x21) 0x00, 0x00, // for registers EXTRASTEPS0 and EXTRASTEPS1 (0x22, 0x23) 0x00, 0x00, 0x00 // for registers RMPCNTL - MCNTL (0x24 - 0x26) }; char mot_half_array[] = { 0x80, 0x20, 0xE2, 0xE4, 0xE6, 0xE0, 0x02, 0x10, // for registers MODE - WDCNTL (0x00 - 0x06 0x00, 0x00, // for registers IP and INTSTAT (0x07, 0x08) 0x0F, 0x03, 0x0C, 0x0F, 0x03, 0x00, 0x01, 0x00, 0x01, // for registers OP - INT_AUTO_CLR (0x09 - 0x11) 0x00, 0x00, 0x30, 0x00, 0xF2, 0x06, 0xF2, 0x06, // for registers SETMODE - CCWPWH (0x12 - 0x19) 0x18, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, // for registers CWSCOUNTL - CCWRCOUNTH (0x1A - 0x21) 0x00, 0x00, // for registers EXTRASTEPS0 and EXTRASTEPS1 (0x22, 0x23) 0x00, 0x00, 0x00 // for registers RMPCNTL - MCNTL (0x24 - 0x26) }; #else char mot_norm_op_array[] = { 0x80, 0x20, 0xE2, 0xE4, 0xE6, 0xE0, 0x02, 0x10, // for registers MODE - WDCNTL (0x00 - 0x06 0x00, 0x00, // for registers IP and INTSTAT (0x07, 0x08) 0x0F, 0x03, 0x0C, 0x0F, 0x03, 0x00, 0x01, 0x00, 0x01, // for registers OP - INT_AUTO_CLR (0x09 - 0x11) 0x00, 0x00, 0x30, 0x00, 0xE4, 0x0D, 0xE4, 0x0D, // for registers SETMODE - CCWPWH (0x12 - 0x19) 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, // for registers CWSCOUNTL - CCWRCOUNTH (0x1A - 0x21) 0x00, 0x00, // for registers EXTRASTEPS0 and EXTRASTEPS1 (0x22, 0x23) 0x00, 0x00, 0x00 // for registers RMPCNTL - MCNTL (0x24 - 0x26) }; char mot_half_array[] = { 0x80, 0x20, 0xE2, 0xE4, 0xE6, 0xE0, 0x02, 0x10, // for registers MODE - WDCNTL (0x00 - 0x06 0x00, 0x00, // for registers IP and INTSTAT (0x07, 0x08) 0x0F, 0x03, 0x0C, 0x0F, 0x03, 0x00, 0x01, 0x00, 0x01, // for registers OP - INT_AUTO_CLR (0x09 - 0x11) 0x00, 0x00, 0x30, 0x00, 0xE4, 0x0D, 0xE4, 0x0D, // for registers SETMODE - CCWPWH (0x12 - 0x19) 0x18, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, // for registers CWSCOUNTL - CCWRCOUNTH (0x1A - 0x21) 0x00, 0x00, // for registers EXTRASTEPS0 and EXTRASTEPS1 (0x22, 0x23) 0x00, 0x00, 0x00 // for registers RMPCNTL - MCNTL (0x24 - 0x26) }; #endif transaction led_init_transfer[] = { { PCx9955_ADDR0, led_init_array, sizeof( led_init_array ) }, { PCx9955_ADDR1, led_init_array, sizeof( led_init_array ) }, { PCx9955_ADDR2, led_init_array, sizeof( led_init_array ) }, { PCx9955_ADDR3, led_init_array, sizeof( led_init_array ) }, }; transaction led_norm_op_transfer[] = { { PCx9955_ADDR0, led_norm_op_array, sizeof( led_norm_op_array ) }, { PCx9955_ADDR1, led_norm_op_array, sizeof( led_norm_op_array ) }, { PCx9955_ADDR2, led_norm_op_array, sizeof( led_norm_op_array ) }, { PCx9955_ADDR3, led_norm_op_array, sizeof( led_norm_op_array ) }, }; transaction mot_init_transfer[] = { { MOT_ADDR5, mot_init_array, sizeof( mot_init_array ) }, { MOT_ADDR6, mot_init_array, sizeof( mot_init_array ) }, { MOT_ADDR7, mot_init_array, sizeof( mot_init_array ) }, { MOT_ADDR8, mot_init_array, sizeof( mot_init_array ) }, { MOT_ADDR9, mot_init_array, sizeof( mot_init_array ) }, }; transaction mot_norm_op_transfer[] = { { MOT_ADDR5, mot_norm_op_array, sizeof( mot_norm_op_array ) }, { MOT_ADDR6, mot_norm_op_array, sizeof( mot_norm_op_array ) }, { MOT_ADDR7, mot_norm_op_array, sizeof( mot_norm_op_array ) }, { MOT_ADDR8, mot_norm_op_array, sizeof( mot_norm_op_array ) }, { MOT_ADDR9, mot_norm_op_array, sizeof( mot_norm_op_array ) }, }; transaction mot_half_transfer[] = { { MOT_ADDR5, mot_norm_op_array, sizeof( mot_norm_op_array ) }, { MOT_ADDR6, mot_half_array, sizeof( mot_half_array ) }, { MOT_ADDR7, mot_half_array, sizeof( mot_half_array ) }, { MOT_ADDR8, mot_half_array, sizeof( mot_half_array ) }, { MOT_ADDR9, mot_norm_op_array, sizeof( mot_norm_op_array ) }, }; transaction mot_half_setup_transfer[] = { { MOT_ADDR5, mot_half_array, sizeof( mot_half_array ) }, { MOT_ADDR6, mot_half_array, sizeof( mot_half_array ) }, { MOT_ADDR7, mot_half_array, sizeof( mot_half_array ) }, { MOT_ADDR8, mot_half_array, sizeof( mot_half_array ) }, { MOT_ADDR9, mot_half_array, sizeof( mot_half_array ) }, }; transaction mot_all_stop_transfer[] = { { MOT_ADDR5, mot_all_stop, sizeof( mot_all_stop ) }, { MOT_ADDR6, mot_all_stop, sizeof( mot_all_stop ) }, { MOT_ADDR7, mot_all_stop, sizeof( mot_all_stop ) }, { MOT_ADDR8, mot_all_stop, sizeof( mot_all_stop ) }, { MOT_ADDR9, mot_all_stop, sizeof( mot_all_stop ) }, }; transaction mot_all_start_transfer[] = { { MOT_ADDR5, mot_all_start, sizeof( mot_all_start ) }, { MOT_ADDR6, mot_all_start, sizeof( mot_all_start ) }, { MOT_ADDR7, mot_all_start, sizeof( mot_all_start ) }, { MOT_ADDR8, mot_all_start, sizeof( mot_all_start ) }, { MOT_ADDR9, mot_all_start, sizeof( mot_all_start ) }, }; transaction mot_all_vib_transfer[] = { { MOT_ADDR5, mot_vib_array, sizeof( mot_vib_array ) }, { MOT_ADDR6, mot_vib_array, sizeof( mot_vib_array ) }, { MOT_ADDR7, mot_vib_array, sizeof( mot_vib_array ) }, { MOT_ADDR8, mot_vib_array, sizeof( mot_vib_array ) }, { MOT_ADDR9, mot_vib_array, sizeof( mot_vib_array ) }, }; transaction mot_all_ramp_transfer[] = { { MOT_ADDR5, mot_ramp_array, sizeof( mot_ramp_array ) }, { MOT_ADDR6, mot_ramp_array, sizeof( mot_ramp_array ) }, { MOT_ADDR7, mot_ramp_array, sizeof( mot_ramp_array ) }, { MOT_ADDR8, mot_ramp_array, sizeof( mot_ramp_array ) }, { MOT_ADDR9, mot_ramp_array, sizeof( mot_ramp_array ) }, }; void init_slave_devices( void ) { // init all slave's registers setup_transfer( CH_FM_PLUS, mot_init_transfer, sizeof( mot_init_transfer ) / sizeof( transaction ) ); setup_transfer( CH_UFM1, led_init_transfer, sizeof( led_init_transfer ) / sizeof( transaction ) ); setup_transfer( CH_UFM2, led_init_transfer, sizeof( led_init_transfer ) / sizeof( transaction ) ); start( CH_FM_PLUS ); // motors are aligned using interrupt input of PCA9629 start( CH_UFM1 ); start( CH_UFM2 ); wait_sec( 0.5 ); // update motor control buffer configuration setup_transfer( CH_FM_PLUS, mot_norm_op_transfer, sizeof( mot_norm_op_transfer ) / sizeof( transaction ) ); setup_transfer( CH_UFM1, led_norm_op_transfer, sizeof( led_norm_op_transfer ) / sizeof( transaction ) ); setup_transfer( CH_UFM2, led_norm_op_transfer, sizeof( led_norm_op_transfer ) / sizeof( transaction ) ); start( CH_FM_PLUS ); // just update PCA9629 registers. no motor action start( CH_UFM1 ); start( CH_UFM2 ); } void single_byte_write_into_a_PCA9629( char ch, char i2c_addr, char reg_addr, char val ) { transaction t; char data[ 2 ]; data[ 0 ] = reg_addr; data[ 1 ] = val; t.i2c_address = i2c_addr; t.data = data; t.length = 2; setup_transfer( ch, &t, 1 ); start( CH_FM_PLUS ); } void ramp_all_PCA9629( void ) { setup_transfer( CH_FM_PLUS, mot_all_ramp_transfer, sizeof( mot_all_ramp_transfer ) / sizeof( transaction ) ); start( CH_FM_PLUS ); } void vib_all_PCA9629( void ) { setup_transfer( CH_FM_PLUS, mot_all_vib_transfer, sizeof( mot_all_vib_transfer ) / sizeof( transaction ) ); start( CH_FM_PLUS ); } void start_all_PCA9629( void ) { setup_transfer( CH_FM_PLUS, mot_all_start_transfer, sizeof( mot_all_start_transfer ) / sizeof( transaction ) ); start( CH_FM_PLUS ); } void stop_all_PCA9629( void ) { setup_transfer( CH_FM_PLUS, mot_all_stop_transfer, sizeof( mot_all_stop_transfer ) / sizeof( transaction ) ); start( CH_FM_PLUS ); } void align_all_PCA9629( void ) { setup_transfer( CH_FM_PLUS, mot_init_transfer, sizeof( mot_init_transfer ) / sizeof( transaction ) ); start( CH_FM_PLUS ); } void all_LEDs_value( char v ) { for ( int i = 0; i < N_OF_LEDS; i++ ) gLEDs[ i ] = v; } void all_LEDs_turn_off() { all_LEDs_value( 0x00 ); } void all_LEDs_turn_on() { all_LEDs_value( 0xFF ); } void pattern_rampup( int count ) { if ( count == 0 ) { all_LEDs_turn_off(); return; } for ( int i = 0; i < N_OF_LEDS; i++ ) gLEDs[ i ] = count & 0xFF; } void pattern_rampup_and_down( int count ) { if ( !(count & 0xFF) ) { ramp_all_PCA9629(); all_LEDs_turn_off(); return; } for ( int i = 0; i < N_OF_LEDS; i++ ) gLEDs[ i ] = (((count & 0x80) ? ~count : count) << 1) & 0xFF; } void pattern_rampup_and_down_w_color( int count ) { static int color; color = (!count || (3 <= color)) ? 0 : color; if ( !(count & 0xFF) ) { ramp_all_PCA9629(); all_LEDs_turn_off(); color++; return; } for ( int i = 0; i < N_OF_LEDS; i++ ) gLEDs[ i ] = (rgb_mask[ color ][ i % N_LED_PER_BOARD ]) ? (((count & 0x80) ? ~count : count) << 1) & 0xFF : 0x00; } void pattern_colors2( int count ) { if ( !count ) { gMotor_count = 0; setup_transfer( CH_FM_PLUS, mot_norm_op_transfer, sizeof( mot_norm_op_transfer ) / sizeof( transaction ) ); start( CH_FM_PLUS ); // just update PCA9629 registers. no motor action } if ( !((count + 20) & 0x3F) ) { single_byte_write_into_a_PCA9629( CH_FM_PLUS, gMot_cntl_order[ gMotor_count % 5 ], 0x26, 0x80 | ((gMotor_count / 5) & 0x1) ); gMotor_count++; } #define PI 3.14159265358979323846 float r; float g; float b; float k; float c; k = (2 * PI) / 300.0; c = count; #if 0 r = sin( k * (c + 0.0) ); g = sin( k * (c + 100.0) ); b = sin( k * (c + 200.0) ); r = (0 < r) ? r * 255.0 : 0; g = (0 < g) ? g * 255.0 : 0; b = (0 < b) ? b * 255.0 : 0; #else r = (sin( k * (c + 0.0) ) + 1) * (127.5 * ((count < 500) ? (float)count / 500.0 : 1.0)); g = (sin( k * (c + 100.0) ) + 1) * (127.5 * ((count < 500) ? (float)count / 500.0 : 1.0)); b = (sin( k * (c + 200.0) ) + 1) * (127.5 * ((count < 500) ? (float)count / 500.0 : 1.0)); #endif for ( int i = 0; i < N_OF_LEDS; i += N_LED_PER_BOARD ) { for ( int j = 0; j < 12; j += 3 ) { gLEDs[ i + j + 0 ] = (char)r; gLEDs[ i + j + 1 ] = (char)g; gLEDs[ i + j + 2 ] = (char)b; } for ( int j = 12; j < 15; j ++ ) gLEDs[ i + j ] = (char)((((2500 <= count) && (count < 3000)) ? ((float)(count - 2500) / 500.0) : 0.0) * 255.0); } } //void pattern_color_phase( int count ) { void pattern_colors( int count ) { if ( !count ) { gMotor_count = 0; setup_transfer( CH_FM_PLUS, mot_norm_op_transfer, sizeof( mot_norm_op_transfer ) / sizeof( transaction ) ); start( CH_FM_PLUS ); // just update PCA9629 registers. no motor action } if ( !((count + 20) & 0x3F) ) { single_byte_write_into_a_PCA9629( CH_FM_PLUS, gMot_cntl_order[ gMotor_count % 5 ], 0x26, 0x80 | ((gMotor_count / 5) & 0x1) ); gMotor_count++; } #define PI 3.14159265358979323846 float p; float k; float c; k = (2 * PI) / 300.0; p = 300.0 / N_OF_LEDS; c = count; for ( int i = 0; i < N_OF_LEDS; i += N_LED_PER_BOARD ) { for ( int j = 0; j < 12; j += 3 ) { gLEDs[ i + j + 0 ] = (char)((sin( k * (c + 0.0) + p * (i + j) ) + 1) * (127.5 * ((count < 500) ? (float)count / 500.0 : 1.0))); gLEDs[ i + j + 1 ] = (char)((sin( k * (c + 100.0) + p * (i + j) ) + 1) * (127.5 * ((count < 500) ? (float)count / 500.0 : 1.0))); gLEDs[ i + j + 2 ] = (char)((sin( k * (c + 200.0) + p * (i + j) ) + 1) * (127.5 * ((count < 500) ? (float)count / 500.0 : 1.0))); } for ( int j = 12; j < 15; j ++ ) gLEDs[ i + j ] = (char)((((2500 <= count) && (count < 3000)) ? ((float)(count - 2500) / 500.0) : 0.0) * 255.0); } } void pattern_one_by_one( int count ) { if ( count == 0 ) { all_LEDs_turn_off(); return; } gLEDs[ (count / 9) % N_OF_LEDS ] = nine_step_intensity[ count % 9 ]; } void pattern_random( int count ) { if ( count == 0 ) { all_LEDs_turn_off(); return; } gLEDs[ rand() % N_OF_LEDS ] = rand() % 0xFF; } void pattern_random_with_decay0( int count ) { if ( count == 0 ) { all_LEDs_turn_off(); return; } gLEDs[ rand() % N_OF_LEDS ] = 0xFF; for ( int i = 0; i < N_OF_LEDS; i++ ) gLEDs[ i ] = (char)((float)gLEDs[ i ] * 0.90); } void pattern_random_with_decay1( int count ) { if ( count == 0 ) { all_LEDs_turn_off(); return; } gLEDs[ rand() % N_OF_LEDS ] = 0xFF; for ( int i = 0; i < N_OF_LEDS; i++ ) gLEDs[ i ] = (char)((float)gLEDs[ i ] * 0.7); } void pattern_flashing( int count ) { #define SUSTAIN_DURATION 10 static float interval; static int timing; static int sustain; if ( count == 0 ) { interval = 100.0; timing = 0; sustain = SUSTAIN_DURATION; vib_all_PCA9629(); } if ( (timing == count) || !((int)interval) ) { sustain = SUSTAIN_DURATION; all_LEDs_turn_on(); start_all_PCA9629(); timing += (int)interval; interval *= 0.96; } else { for ( int i = 0; i < N_OF_LEDS; i++ ) gLEDs[ i ] = (char)((float)gLEDs[ i ] * 0.90); if ( sustain-- < 0 ) stop_all_PCA9629(); } } void stop( int count ) { if ( !count ) { all_LEDs_turn_off(); stop_all_PCA9629(); } } void pattern_init( int count ) { if ( !count ) align_all_PCA9629(); } void pattern_scan( int count ) { static char gMotor_count; if ( !count ) { gMotor_count = 0; setup_transfer( CH_FM_PLUS, mot_norm_op_transfer, sizeof( mot_norm_op_transfer ) / sizeof( transaction ) ); start( CH_FM_PLUS ); // just update PCA9629 registers. no motor action } if ( !(count & 0x1F) ) { single_byte_write_into_a_PCA9629( CH_FM_PLUS, gMot_cntl_order[ gMotor_count % 5 ], 0x26, 0x80 | ((gMotor_count / 5) & 0x1) ); gMotor_count++; } all_LEDs_turn_off(); gLEDs[ (count >> 3) % N_OF_LEDS ] = 0xFF; } void pattern_setup_half_turns( int count ) { if ( !count ) { align_all_PCA9629(); gMotor_count = 0; } else if ( count == 50 ) { setup_transfer( CH_FM_PLUS, mot_half_setup_transfer, sizeof( mot_half_transfer ) / sizeof( transaction ) ); start( CH_FM_PLUS ); } else if ( count == 60 ) { single_byte_write_into_a_PCA9629( CH_FM_PLUS, gMot_cntl_order[ 4 ], 0x26, 0x80 ); } else if ( count == 75 ) { single_byte_write_into_a_PCA9629( CH_FM_PLUS, gMot_cntl_order[ 3 ], 0x26, 0x80 ); } else if ( count == 90 ) { single_byte_write_into_a_PCA9629( CH_FM_PLUS, gMot_cntl_order[ 2 ], 0x26, 0x80 ); } else if ( count == 115 ) { single_byte_write_into_a_PCA9629( CH_FM_PLUS, gMot_cntl_order[ 1 ], 0x26, 0x80 ); } else if ( count == 150 ) { setup_transfer( CH_FM_PLUS, mot_half_transfer, sizeof( mot_half_transfer ) / sizeof( transaction ) ); start( CH_FM_PLUS ); } } void pattern_half_turns( int count ) { #ifdef INTERVAL128MS if ( !(count & 0x0F) ) { #else if ( !(count & 0x1F) ) { #endif if ( gMot_cntl_order_halfturn[ gMotor_count ] ) 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) ); gMotor_count++; gMotor_count = (gMotor_count == 10) ? 0 : gMotor_count; } // all_LEDs_turn_off(); // gLEDs[ (count >> 3) % N_OF_LEDS ] = 0xFF; } void pattern_fadeout300( int count ) { if ( !count ) stop_all_PCA9629(); else if ( count == 100 ) align_all_PCA9629(); for ( int i = 0; i < N_OF_LEDS; i++ ) 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. } void pattern_speed_variations( int count ) { char data[ 4 ]; int v; if ( !count ) { setup_transfer( CH_FM_PLUS, mot_norm_op_transfer, sizeof( mot_norm_op_transfer ) / sizeof( transaction ) ); data[ 0 ] = 0x2; for ( int i = 0; i < 5; i++ ) buffer_overwrite( CH_FM_PLUS, i, 20, data, 1 ); // Set half step operation for ( int i = 0; i < 5; i++ ) { v = 833;// 400pps for halfstep data[ 0 ] = data[ 2 ] = v & 0xFF; data[ 1 ] = data[ 3 ] = (i << 5) | (v >> 8); buffer_overwrite( CH_FM_PLUS, i, 23, data, 4 ); } for ( int i = 0; i < 5; i++ ) { v = (0x1 << (5 - i)); data[ 0 ] = data[ 2 ] = v & 0xFF; data[ 1 ] = data[ 3 ] = v >> 8; buffer_overwrite( CH_FM_PLUS, i, 31, data, 4 ); } } if ( !(count % 500) ) { data[ 0 ] = 0x84 | ((count / 500) & 0x1); for ( int i = 0; i < 5; i++ ) buffer_overwrite( CH_FM_PLUS, i, 39, data, 1 ); start( CH_FM_PLUS ); } } void pattern_mot_ramp_variations( int count ) { char ramp_var[5][17] = { { 0x5D, 0x03, 0x5D, 0x03, 0x0B, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x88 }, { 0x4B, 0x05, 0x4B, 0x05, 0x25, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x00, 0x88 }, { 0x15, 0x06, 0x15, 0x06, 0x2D, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x88 }, { 0x71, 0x06, 0x71, 0x06, 0x17, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x88 }, { 0x9C, 0x06, 0x9C, 0x06, 0x23, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x88 }, }; if ( !count ) { setup_transfer( CH_FM_PLUS, mot_norm_op_transfer, sizeof( mot_norm_op_transfer ) / sizeof( transaction ) ); for ( int i = 0; i < 5; i++ ) buffer_overwrite( CH_FM_PLUS, i, 23, ramp_var[ i ], 17 ); start( CH_FM_PLUS ); } all_LEDs_turn_off(); gLEDs[ count % N_OF_LEDS ] = 0xFF; } void pattern_knightrider( int count ) { short led_pat[ 12 ] = { 0x7000, 0x0004, 0x0E00, 0x0002, 0x01C0, 0x0001, 0x0038, 0x0001, 0x01C0, 0x0002, 0x0E00, 0x0004 }; short led_bits; #if 0 //if ( !(count && 0x7) ) { led_bits = led_pat[ (count >> 4) % 12 ]; for ( int i = 0; i < N_OF_LEDS; i += N_LED_PER_BOARD ) { for ( int j = 0; j < N_LED_PER_BOARD; j ++ ) { gLEDs[ i + j ] = ((led_bits << j) & 0x4000) ? 0xFF : gLEDs[ i + j ]; } } } for ( int i = 0; i < N_OF_LEDS; i++ ) gLEDs[ i ] = (char)((float)gLEDs[ i ] * 0.90 * ((700 < count) ? (float)(1000 - count) / 300.0 : 1.0)); #else //if ( !(count && 0x7) ) { led_bits = led_pat[ (count >> 4) % 12 ]; for ( int i = 0; i < N_OF_LEDS; i += N_LED_PER_BOARD ) { for ( int j = 0; j < N_LED_PER_BOARD; j ++ ) { gLEDs[ i + j ] = ((led_bits << j) & 0x4000) ? ((744 < count) ? (1000 - count) : 255) : gLEDs[ i + j ]; // gLEDs[ i + j ] = ((led_bits << j) & 0x4000) ? 0xFF : gLEDs[ i + j ]; } } } for ( int i = 0; i < N_OF_LEDS; i++ ) gLEDs[ i ] = (char)((float)gLEDs[ i ] * 0.90); #endif } pattern _gPt[] = { // { 256, pattern_rampup }, { 3000, pattern_colors }, }; pattern gPt[] = { // { 256, pattern_rampup }, { 20, stop }, { 120, pattern_init }, { 3000, pattern_colors }, { 300, pattern_fadeout300 }, { 3000, pattern_speed_variations }, { 250, pattern_setup_half_turns }, { 3000, pattern_half_turns }, { 20, stop }, { 120, pattern_init }, { 960, pattern_rampup_and_down_w_color }, { 960, pattern_scan }, { 20, stop }, { 120, pattern_init }, { 1024, pattern_rampup_and_down }, { 700, pattern_mot_ramp_variations }, { 700, pattern_mot_ramp_variations }, { 700, pattern_mot_ramp_variations }, { 700, pattern_mot_ramp_variations }, { 3000, pattern_flashing }, { 300, pattern_fadeout300 }, { 512, pattern_random }, { 512, pattern_random_with_decay1 }, { 512, pattern_random_with_decay0 }, { 9 * 120, pattern_one_by_one }, { 1000, pattern_knightrider }, }; void pattern_update( int count ) { static int next_pattern_change = 0; static int local_count = 0; static int pattern_index = -1; if ( next_pattern_change == count ) { local_count = 0; pattern_index++; pattern_index = (pattern_index == (sizeof( gPt ) / sizeof( pattern )) ) ? 0 : pattern_index; next_pattern_change += gPt[ pattern_index ].duration; } (*gPt[ pattern_index ].pattern_func)( local_count++ ); }