PCA9629 a stepper motor controller class library
Class library for PCA9629.
A sample program available on http://mbed.org/users/nxp_ip/code/PCA9629_Hello/
PCA9629.cpp@2:2d07f1c46eb3, 2012-02-03 (annotated)
- Committer:
- nxp_ip
- Date:
- Fri Feb 03 03:44:06 2012 +0000
- Revision:
- 2:2d07f1c46eb3
- Parent:
- 0:77dbce152406
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
nxp_ip | 0:77dbce152406 | 1 | /** A sample code for PCA9629 |
nxp_ip | 0:77dbce152406 | 2 | * |
nxp_ip | 0:77dbce152406 | 3 | * @author Tedd OKANO, NXP Semiconductors |
nxp_ip | 0:77dbce152406 | 4 | * @version 1.0 |
nxp_ip | 0:77dbce152406 | 5 | * @date 03-Feb-2011 |
nxp_ip | 0:77dbce152406 | 6 | * |
nxp_ip | 0:77dbce152406 | 7 | * Released under the MIT License: http://mbed.org/license/mit |
nxp_ip | 0:77dbce152406 | 8 | * |
nxp_ip | 0:77dbce152406 | 9 | * An operation sample of PCU9629 stepper motor controller. |
nxp_ip | 0:77dbce152406 | 10 | * The mbed accesses the PCU9629 registers through I2C. |
nxp_ip | 0:77dbce152406 | 11 | */ |
nxp_ip | 0:77dbce152406 | 12 | |
nxp_ip | 0:77dbce152406 | 13 | #include "mbed.h" |
nxp_ip | 0:77dbce152406 | 14 | #include "PCA9629.h" |
nxp_ip | 0:77dbce152406 | 15 | |
nxp_ip | 0:77dbce152406 | 16 | #define STEP_RESOLUTION 333333 // 1/(3e-6) = 333333 |
nxp_ip | 0:77dbce152406 | 17 | |
nxp_ip | 0:77dbce152406 | 18 | char *reg_name[] = { |
nxp_ip | 0:77dbce152406 | 19 | "MODE", "SUBADR1", "SUBADR2", "SUBADR3", "ALLCALLADR", "WDTC", "WDMOD", "IP", |
nxp_ip | 0:77dbce152406 | 20 | "INTSTAT", "OP", "IOC", "MSK", "CLRINT", "INTMODE1", "INTMODE2", "INT_ACT_SETUP", |
nxp_ip | 0:77dbce152406 | 21 | "INT_MRT_SETUP", "INT_ES_SETUP", "SETMODE", "PHCNTL", "SROTNL", "SROTNH", |
nxp_ip | 0:77dbce152406 | 22 | "CWPWL", "CWPWH", "CCWPWL", "CCWPWH", |
nxp_ip | 0:77dbce152406 | 23 | "CWSCOUNTL", "CWSCOUNTH", "CCWSCOUNTL", "CCWSCOUNTH", |
nxp_ip | 0:77dbce152406 | 24 | "CWRCOUNTL", "CWRCOUNTH", "CCWRCOUNTL", "CCWRCOUNTH", |
nxp_ip | 0:77dbce152406 | 25 | "EXTRASTEPS0", "EXTRASTEPS1", "RAMPX", "LOOPDLY", "MCNTL" |
nxp_ip | 0:77dbce152406 | 26 | }; |
nxp_ip | 0:77dbce152406 | 27 | |
nxp_ip | 0:77dbce152406 | 28 | PCA9629::PCA9629( |
nxp_ip | 0:77dbce152406 | 29 | PinName I2C_sda, |
nxp_ip | 0:77dbce152406 | 30 | PinName I2C_scl, |
nxp_ip | 0:77dbce152406 | 31 | char I2C_address |
nxp_ip | 0:77dbce152406 | 32 | ) : i2c( I2C_sda, I2C_scl ), i2c_addr( I2C_address ) { |
nxp_ip | 0:77dbce152406 | 33 | |
nxp_ip | 0:77dbce152406 | 34 | i2c.frequency( 400 * 1000 ); |
nxp_ip | 0:77dbce152406 | 35 | init_registers(); |
nxp_ip | 0:77dbce152406 | 36 | } |
nxp_ip | 0:77dbce152406 | 37 | |
nxp_ip | 0:77dbce152406 | 38 | void PCA9629::init_registers( void ) { |
nxp_ip | 0:77dbce152406 | 39 | char init_array[] = { 0x80, // register access start address (0x00) with incremental access flag (MSB) |
nxp_ip | 0:77dbce152406 | 40 | 0x30, 0xE2, 0xE4, 0xE6, 0xE0, 0x02, 0x10, // for registers MODE - WDCNTL (0x00 - 0x06 |
nxp_ip | 0:77dbce152406 | 41 | 0x00, 0x00, // for registers IP and INTSTAT (0x07, 0x08) |
nxp_ip | 0:77dbce152406 | 42 | 0x07, 0x0F, 0x00, 0x0F, 0x0F, 0x00, 0x03, 0x02, 0x01, // for registers OP - INT_AUTO_CLR (0x09 - 0x11) |
nxp_ip | 0:77dbce152406 | 43 | 0x00, 0x00, 0x30, 0x00, 0x82, 0x66, 0x82, 0x06, // for registers SETMODE - CCWPWH (0x12 - 0x19) |
nxp_ip | 0:77dbce152406 | 44 | 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, // for registers CWSCOUNTL - CCWRCOUNTH (0x1A - 0x21) |
nxp_ip | 0:77dbce152406 | 45 | 0x00, 0x00, // for registers EXTRASTEPS0 and EXTRASTEPS1 (0x22, 0x23) |
nxp_ip | 2:2d07f1c46eb3 | 46 | 0x00, 0x00, 0x00 // for registers RMPCNTL - MCNTL (0x24 - 0x26) |
nxp_ip | 0:77dbce152406 | 47 | }; |
nxp_ip | 0:77dbce152406 | 48 | |
nxp_ip | 2:2d07f1c46eb3 | 49 | set_all_registers( init_array, sizeof( init_array ) ); |
nxp_ip | 2:2d07f1c46eb3 | 50 | } |
nxp_ip | 2:2d07f1c46eb3 | 51 | |
nxp_ip | 2:2d07f1c46eb3 | 52 | void PCA9629::set_all_registers( char *a, char size ) |
nxp_ip | 2:2d07f1c46eb3 | 53 | { |
nxp_ip | 2:2d07f1c46eb3 | 54 | int error_code; |
nxp_ip | 2:2d07f1c46eb3 | 55 | |
nxp_ip | 2:2d07f1c46eb3 | 56 | error_code = i2c.write( i2c_addr, a, size ); |
nxp_ip | 0:77dbce152406 | 57 | |
nxp_ip | 0:77dbce152406 | 58 | if ( error_code ) |
nxp_ip | 0:77dbce152406 | 59 | error( "error @ initializing PCA9629" ); |
nxp_ip | 0:77dbce152406 | 60 | } |
nxp_ip | 0:77dbce152406 | 61 | |
nxp_ip | 0:77dbce152406 | 62 | void PCA9629::write( RegisterName register_name, char value ) { |
nxp_ip | 0:77dbce152406 | 63 | int error_code; |
nxp_ip | 0:77dbce152406 | 64 | char cmd[ 2 ]; |
nxp_ip | 0:77dbce152406 | 65 | |
nxp_ip | 0:77dbce152406 | 66 | cmd[ 0 ] = register_name; |
nxp_ip | 0:77dbce152406 | 67 | cmd[ 1 ] = value; |
nxp_ip | 0:77dbce152406 | 68 | |
nxp_ip | 0:77dbce152406 | 69 | error_code = i2c.write( i2c_addr, cmd, 2 ); |
nxp_ip | 0:77dbce152406 | 70 | |
nxp_ip | 0:77dbce152406 | 71 | if ( error_code ) |
nxp_ip | 0:77dbce152406 | 72 | error( "PCA9629 writing failed\r\n" ); |
nxp_ip | 0:77dbce152406 | 73 | } |
nxp_ip | 0:77dbce152406 | 74 | |
nxp_ip | 0:77dbce152406 | 75 | void PCA9629::write( Register16bits register_name, short value ) { |
nxp_ip | 0:77dbce152406 | 76 | int error_code; |
nxp_ip | 0:77dbce152406 | 77 | char cmd[ 3 ]; |
nxp_ip | 0:77dbce152406 | 78 | |
nxp_ip | 0:77dbce152406 | 79 | cmd[ 0 ] = register_name; |
nxp_ip | 0:77dbce152406 | 80 | cmd[ 1 ] = value & 0xFF; |
nxp_ip | 0:77dbce152406 | 81 | cmd[ 2 ] = value >> 8; |
nxp_ip | 0:77dbce152406 | 82 | |
nxp_ip | 0:77dbce152406 | 83 | error_code = i2c.write( i2c_addr, cmd, 3 ); |
nxp_ip | 0:77dbce152406 | 84 | |
nxp_ip | 0:77dbce152406 | 85 | if ( error_code ) |
nxp_ip | 0:77dbce152406 | 86 | error( "PCA9629 writing failed\r\n" ); |
nxp_ip | 0:77dbce152406 | 87 | } |
nxp_ip | 0:77dbce152406 | 88 | |
nxp_ip | 0:77dbce152406 | 89 | char PCA9629::read( RegisterName register_name ) { |
nxp_ip | 0:77dbce152406 | 90 | int error_code; |
nxp_ip | 0:77dbce152406 | 91 | char cmd; |
nxp_ip | 0:77dbce152406 | 92 | char data; |
nxp_ip | 0:77dbce152406 | 93 | |
nxp_ip | 0:77dbce152406 | 94 | cmd = register_name; |
nxp_ip | 0:77dbce152406 | 95 | |
nxp_ip | 0:77dbce152406 | 96 | error_code = i2c.write( i2c_addr, &cmd, 1, false ); |
nxp_ip | 0:77dbce152406 | 97 | |
nxp_ip | 0:77dbce152406 | 98 | if ( error_code ) |
nxp_ip | 0:77dbce152406 | 99 | error( "PCA9629 reading (command phase) failed\r\n" ); |
nxp_ip | 0:77dbce152406 | 100 | |
nxp_ip | 0:77dbce152406 | 101 | error_code = i2c.read( i2c_addr, &data, 1 ); |
nxp_ip | 0:77dbce152406 | 102 | |
nxp_ip | 0:77dbce152406 | 103 | if ( error_code ) |
nxp_ip | 0:77dbce152406 | 104 | error( "PCA9629 reading (data phase) failed\r\n" ); |
nxp_ip | 0:77dbce152406 | 105 | |
nxp_ip | 0:77dbce152406 | 106 | return ( data ); |
nxp_ip | 0:77dbce152406 | 107 | } |
nxp_ip | 0:77dbce152406 | 108 | |
nxp_ip | 0:77dbce152406 | 109 | short PCA9629::read( Register16bits register_name ) { |
nxp_ip | 0:77dbce152406 | 110 | int error_code; |
nxp_ip | 0:77dbce152406 | 111 | char cmd; |
nxp_ip | 0:77dbce152406 | 112 | char data[ 2 ]; |
nxp_ip | 0:77dbce152406 | 113 | |
nxp_ip | 0:77dbce152406 | 114 | cmd = register_name; |
nxp_ip | 0:77dbce152406 | 115 | |
nxp_ip | 0:77dbce152406 | 116 | error_code = i2c.write( i2c_addr, &cmd, 1, false ); |
nxp_ip | 0:77dbce152406 | 117 | |
nxp_ip | 0:77dbce152406 | 118 | if ( error_code ) |
nxp_ip | 0:77dbce152406 | 119 | error( "PCA9629 reading (command phase) failed\r\n" ); |
nxp_ip | 0:77dbce152406 | 120 | |
nxp_ip | 0:77dbce152406 | 121 | error_code = i2c.read( i2c_addr, data, 2 ); |
nxp_ip | 0:77dbce152406 | 122 | |
nxp_ip | 0:77dbce152406 | 123 | if ( error_code ) |
nxp_ip | 0:77dbce152406 | 124 | error( "PCA9629 reading (data phase) failed\r\n" ); |
nxp_ip | 0:77dbce152406 | 125 | |
nxp_ip | 0:77dbce152406 | 126 | return ( data[ 1 ] << 8 | data[ 0 ] ); |
nxp_ip | 0:77dbce152406 | 127 | } |
nxp_ip | 0:77dbce152406 | 128 | |
nxp_ip | 2:2d07f1c46eb3 | 129 | void PCA9629::start( Direction dir ) { |
nxp_ip | 2:2d07f1c46eb3 | 130 | write( MCNTL, 0xA8 | dir ); |
nxp_ip | 2:2d07f1c46eb3 | 131 | } |
nxp_ip | 2:2d07f1c46eb3 | 132 | |
nxp_ip | 0:77dbce152406 | 133 | void PCA9629::stop( void ) { |
nxp_ip | 0:77dbce152406 | 134 | write( MCNTL, 0x00 ); |
nxp_ip | 0:77dbce152406 | 135 | } |
nxp_ip | 0:77dbce152406 | 136 | |
nxp_ip | 0:77dbce152406 | 137 | short PCA9629::pps( Direction dir, PrescalerRange prescaler, int pps ) { |
nxp_ip | 0:77dbce152406 | 138 | int step_pulse_width; |
nxp_ip | 0:77dbce152406 | 139 | |
nxp_ip | 0:77dbce152406 | 140 | step_pulse_width = STEP_RESOLUTION / ((1 << prescaler) * pps); |
nxp_ip | 0:77dbce152406 | 141 | |
nxp_ip | 0:77dbce152406 | 142 | if ( step_pulse_width & 0xE000 ) { //error( "pps setting: out of range" ); |
nxp_ip | 0:77dbce152406 | 143 | step_pulse_width = 0x1FFF; |
nxp_ip | 0:77dbce152406 | 144 | printf( "the pps forced in to the range that user specified.. %fpps\r\n", (float)STEP_RESOLUTION / ((float)0x1FFF * (float)(1 << prescaler)) ); |
nxp_ip | 0:77dbce152406 | 145 | } |
nxp_ip | 0:77dbce152406 | 146 | if ( !step_pulse_width ) { //error( "pps setting: out of range" ); |
nxp_ip | 0:77dbce152406 | 147 | step_pulse_width = 0x1; |
nxp_ip | 0:77dbce152406 | 148 | printf( "the pps forced in to the range that user specified.. %fpps\r\n", (float)STEP_RESOLUTION / (float)(1 << prescaler) ); |
nxp_ip | 0:77dbce152406 | 149 | } |
nxp_ip | 0:77dbce152406 | 150 | |
nxp_ip | 0:77dbce152406 | 151 | step_pulse_width |= (prescaler << 13); |
nxp_ip | 0:77dbce152406 | 152 | |
nxp_ip | 0:77dbce152406 | 153 | write( (dir == CW) ? CWPW_ : CCWPW_, step_pulse_width ); |
nxp_ip | 0:77dbce152406 | 154 | |
nxp_ip | 0:77dbce152406 | 155 | return ( step_pulse_width ); |
nxp_ip | 0:77dbce152406 | 156 | } |
nxp_ip | 0:77dbce152406 | 157 | |
nxp_ip | 0:77dbce152406 | 158 | void PCA9629::rotations( Direction dir, int rotations ) { |
nxp_ip | 0:77dbce152406 | 159 | write( (dir == CW) ? CWRCOUNT_ : CCWRCOUNT_, rotations ); |
nxp_ip | 0:77dbce152406 | 160 | } |
nxp_ip | 0:77dbce152406 | 161 | |
nxp_ip | 0:77dbce152406 | 162 | void PCA9629::steps( Direction dir, int steps ) { |
nxp_ip | 0:77dbce152406 | 163 | write( (dir == CW) ? CWSCOUNT_ : CCWSCOUNT_, steps ); |
nxp_ip | 0:77dbce152406 | 164 | } |
nxp_ip | 0:77dbce152406 | 165 | |
nxp_ip | 0:77dbce152406 | 166 | |
nxp_ip | 0:77dbce152406 | 167 | void PCA9629::register_dump( void ) { |
nxp_ip | 0:77dbce152406 | 168 | char data[ 0x27 ]; |
nxp_ip | 0:77dbce152406 | 169 | char cmd = 0x80; |
nxp_ip | 0:77dbce152406 | 170 | int i; |
nxp_ip | 0:77dbce152406 | 171 | int j; |
nxp_ip | 0:77dbce152406 | 172 | |
nxp_ip | 0:77dbce152406 | 173 | i2c.write( i2c_addr, &cmd, 1 ); |
nxp_ip | 0:77dbce152406 | 174 | i2c.read( i2c_addr, data, sizeof( data ) ); |
nxp_ip | 0:77dbce152406 | 175 | |
nxp_ip | 0:77dbce152406 | 176 | printf( "PCA9629 register dump\r\n" ); |
nxp_ip | 0:77dbce152406 | 177 | |
nxp_ip | 0:77dbce152406 | 178 | for ( i = 0, j = 0x14; i <= 0x12; i++, j++ ) |
nxp_ip | 0:77dbce152406 | 179 | printf( " %-13s (0x%02X): 0x%02X %-13s (0x%02X): 0x%02X\r\n", reg_name[ i ], i, data[ i ], reg_name[ j ], j, data[ j ] ); |
nxp_ip | 0:77dbce152406 | 180 | |
nxp_ip | 0:77dbce152406 | 181 | printf( " %-13s (0x%02X): 0x%02X\r\n", reg_name[ 0x13 ], 0x13, data[ 0x13 ] ); |
nxp_ip | 0:77dbce152406 | 182 | } |
nxp_ip | 0:77dbce152406 | 183 | |
nxp_ip | 0:77dbce152406 | 184 | |
nxp_ip | 0:77dbce152406 | 185 | void PCA9629::speed_change( unsigned short pw ) { |
nxp_ip | 0:77dbce152406 | 186 | char cmd0[] = { PCA9629::MCNTL, 0x00}; // data for stop the motor |
nxp_ip | 0:77dbce152406 | 187 | char cmd1[] = { PCA9629::CW__STEP_WIDTH, pw & 0xFF, pw >> 8 }; // data for rewrite pulse width |
nxp_ip | 0:77dbce152406 | 188 | char cmd2[] = { PCA9629::MCNTL, 0xB4}; // start // data for start again |
nxp_ip | 0:77dbce152406 | 189 | wait_us(10); |
nxp_ip | 0:77dbce152406 | 190 | |
nxp_ip | 0:77dbce152406 | 191 | i2c.write( i2c_addr, cmd0, sizeof( cmd0 ), true ); // stop the motor |
nxp_ip | 0:77dbce152406 | 192 | wait_us(50); |
nxp_ip | 0:77dbce152406 | 193 | i2c.write( i2c_addr, cmd1, sizeof( cmd1 ), true ); // rewrite pulse width |
nxp_ip | 0:77dbce152406 | 194 | i2c.write( i2c_addr, cmd2, sizeof( cmd2 ), false ); // start again |
nxp_ip | 0:77dbce152406 | 195 | } |
nxp_ip | 0:77dbce152406 | 196 | |
nxp_ip | 0:77dbce152406 | 197 | |
nxp_ip | 0:77dbce152406 | 198 |