PCA9629 a stepper motor controller class library

Dependents:   PCA9629_Hello

Class library for PCA9629.

A sample program available on http://mbed.org/users/nxp_ip/code/PCA9629_Hello/

Committer:
nxp_ip
Date:
Thu Feb 02 05:10:19 2012 +0000
Revision:
0:77dbce152406
Child:
2:2d07f1c46eb3
first release

Who changed what in which revision?

UserRevisionLine numberNew 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 int error_code;
nxp_ip 0:77dbce152406 40 char init_array[] = { 0x80, // register access start address (0x00) with incremental access flag (MSB)
nxp_ip 0:77dbce152406 41 0x30, 0xE2, 0xE4, 0xE6, 0xE0, 0x02, 0x10, // for registers MODE - WDCNTL (0x00 - 0x06
nxp_ip 0:77dbce152406 42 0x00, 0x00, // for registers IP and INTSTAT (0x07, 0x08)
nxp_ip 0:77dbce152406 43 0x07, 0x0F, 0x00, 0x0F, 0x0F, 0x00, 0x03, 0x02, 0x01, // for registers OP - INT_AUTO_CLR (0x09 - 0x11)
nxp_ip 0:77dbce152406 44 0x00, 0x00, 0x30, 0x00, 0x82, 0x66, 0x82, 0x06, // for registers SETMODE - CCWPWH (0x12 - 0x19)
nxp_ip 0:77dbce152406 45 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, // for registers CWSCOUNTL - CCWRCOUNTH (0x1A - 0x21)
nxp_ip 0:77dbce152406 46 0x00, 0x00, // for registers EXTRASTEPS0 and EXTRASTEPS1 (0x22, 0x23)
nxp_ip 0:77dbce152406 47 0x00, 0x00, 0x94 // for registers RMPCNTL - MCNTL (0x24 - 0x26)
nxp_ip 0:77dbce152406 48 };
nxp_ip 0:77dbce152406 49
nxp_ip 0:77dbce152406 50 error_code = i2c.write( i2c_addr, init_array, sizeof( init_array ) );
nxp_ip 0:77dbce152406 51
nxp_ip 0:77dbce152406 52 if ( error_code )
nxp_ip 0:77dbce152406 53 error( "error @ initializing PCA9629" );
nxp_ip 0:77dbce152406 54
nxp_ip 0:77dbce152406 55 }
nxp_ip 0:77dbce152406 56
nxp_ip 0:77dbce152406 57 void PCA9629::write( RegisterName register_name, char value ) {
nxp_ip 0:77dbce152406 58 int error_code;
nxp_ip 0:77dbce152406 59 char cmd[ 2 ];
nxp_ip 0:77dbce152406 60
nxp_ip 0:77dbce152406 61 cmd[ 0 ] = register_name;
nxp_ip 0:77dbce152406 62 cmd[ 1 ] = value;
nxp_ip 0:77dbce152406 63
nxp_ip 0:77dbce152406 64 error_code = i2c.write( i2c_addr, cmd, 2 );
nxp_ip 0:77dbce152406 65
nxp_ip 0:77dbce152406 66 if ( error_code )
nxp_ip 0:77dbce152406 67 error( "PCA9629 writing failed\r\n" );
nxp_ip 0:77dbce152406 68 }
nxp_ip 0:77dbce152406 69
nxp_ip 0:77dbce152406 70 void PCA9629::write( Register16bits register_name, short value ) {
nxp_ip 0:77dbce152406 71 int error_code;
nxp_ip 0:77dbce152406 72 char cmd[ 3 ];
nxp_ip 0:77dbce152406 73
nxp_ip 0:77dbce152406 74 cmd[ 0 ] = register_name;
nxp_ip 0:77dbce152406 75 cmd[ 1 ] = value & 0xFF;
nxp_ip 0:77dbce152406 76 cmd[ 2 ] = value >> 8;
nxp_ip 0:77dbce152406 77
nxp_ip 0:77dbce152406 78 error_code = i2c.write( i2c_addr, cmd, 3 );
nxp_ip 0:77dbce152406 79
nxp_ip 0:77dbce152406 80 if ( error_code )
nxp_ip 0:77dbce152406 81 error( "PCA9629 writing failed\r\n" );
nxp_ip 0:77dbce152406 82 }
nxp_ip 0:77dbce152406 83
nxp_ip 0:77dbce152406 84 char PCA9629::read( RegisterName register_name ) {
nxp_ip 0:77dbce152406 85 int error_code;
nxp_ip 0:77dbce152406 86 char cmd;
nxp_ip 0:77dbce152406 87 char data;
nxp_ip 0:77dbce152406 88
nxp_ip 0:77dbce152406 89 cmd = register_name;
nxp_ip 0:77dbce152406 90
nxp_ip 0:77dbce152406 91 error_code = i2c.write( i2c_addr, &cmd, 1, false );
nxp_ip 0:77dbce152406 92
nxp_ip 0:77dbce152406 93 if ( error_code )
nxp_ip 0:77dbce152406 94 error( "PCA9629 reading (command phase) failed\r\n" );
nxp_ip 0:77dbce152406 95
nxp_ip 0:77dbce152406 96 error_code = i2c.read( i2c_addr, &data, 1 );
nxp_ip 0:77dbce152406 97
nxp_ip 0:77dbce152406 98 if ( error_code )
nxp_ip 0:77dbce152406 99 error( "PCA9629 reading (data phase) failed\r\n" );
nxp_ip 0:77dbce152406 100
nxp_ip 0:77dbce152406 101 return ( data );
nxp_ip 0:77dbce152406 102 }
nxp_ip 0:77dbce152406 103
nxp_ip 0:77dbce152406 104 short PCA9629::read( Register16bits register_name ) {
nxp_ip 0:77dbce152406 105 int error_code;
nxp_ip 0:77dbce152406 106 char cmd;
nxp_ip 0:77dbce152406 107 char data[ 2 ];
nxp_ip 0:77dbce152406 108
nxp_ip 0:77dbce152406 109 cmd = register_name;
nxp_ip 0:77dbce152406 110
nxp_ip 0:77dbce152406 111 error_code = i2c.write( i2c_addr, &cmd, 1, false );
nxp_ip 0:77dbce152406 112
nxp_ip 0:77dbce152406 113 if ( error_code )
nxp_ip 0:77dbce152406 114 error( "PCA9629 reading (command phase) failed\r\n" );
nxp_ip 0:77dbce152406 115
nxp_ip 0:77dbce152406 116 error_code = i2c.read( i2c_addr, data, 2 );
nxp_ip 0:77dbce152406 117
nxp_ip 0:77dbce152406 118 if ( error_code )
nxp_ip 0:77dbce152406 119 error( "PCA9629 reading (data phase) failed\r\n" );
nxp_ip 0:77dbce152406 120
nxp_ip 0:77dbce152406 121 return ( data[ 1 ] << 8 | data[ 0 ] );
nxp_ip 0:77dbce152406 122 }
nxp_ip 0:77dbce152406 123
nxp_ip 0:77dbce152406 124 void PCA9629::stop( void ) {
nxp_ip 0:77dbce152406 125 write( MCNTL, 0x00 );
nxp_ip 0:77dbce152406 126 }
nxp_ip 0:77dbce152406 127
nxp_ip 0:77dbce152406 128 short PCA9629::pps( Direction dir, PrescalerRange prescaler, int pps ) {
nxp_ip 0:77dbce152406 129 int step_pulse_width;
nxp_ip 0:77dbce152406 130
nxp_ip 0:77dbce152406 131 step_pulse_width = STEP_RESOLUTION / ((1 << prescaler) * pps);
nxp_ip 0:77dbce152406 132
nxp_ip 0:77dbce152406 133 if ( step_pulse_width & 0xE000 ) { //error( "pps setting: out of range" );
nxp_ip 0:77dbce152406 134 step_pulse_width = 0x1FFF;
nxp_ip 0:77dbce152406 135 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 136 }
nxp_ip 0:77dbce152406 137 if ( !step_pulse_width ) { //error( "pps setting: out of range" );
nxp_ip 0:77dbce152406 138 step_pulse_width = 0x1;
nxp_ip 0:77dbce152406 139 printf( "the pps forced in to the range that user specified.. %fpps\r\n", (float)STEP_RESOLUTION / (float)(1 << prescaler) );
nxp_ip 0:77dbce152406 140 }
nxp_ip 0:77dbce152406 141
nxp_ip 0:77dbce152406 142 step_pulse_width |= (prescaler << 13);
nxp_ip 0:77dbce152406 143
nxp_ip 0:77dbce152406 144 write( (dir == CW) ? CWPW_ : CCWPW_, step_pulse_width );
nxp_ip 0:77dbce152406 145
nxp_ip 0:77dbce152406 146 return ( step_pulse_width );
nxp_ip 0:77dbce152406 147 }
nxp_ip 0:77dbce152406 148
nxp_ip 0:77dbce152406 149 void PCA9629::rotations( Direction dir, int rotations ) {
nxp_ip 0:77dbce152406 150 write( (dir == CW) ? CWRCOUNT_ : CCWRCOUNT_, rotations );
nxp_ip 0:77dbce152406 151 }
nxp_ip 0:77dbce152406 152
nxp_ip 0:77dbce152406 153 void PCA9629::steps( Direction dir, int steps ) {
nxp_ip 0:77dbce152406 154 write( (dir == CW) ? CWSCOUNT_ : CCWSCOUNT_, steps );
nxp_ip 0:77dbce152406 155 }
nxp_ip 0:77dbce152406 156
nxp_ip 0:77dbce152406 157
nxp_ip 0:77dbce152406 158 void PCA9629::register_dump( void ) {
nxp_ip 0:77dbce152406 159 char data[ 0x27 ];
nxp_ip 0:77dbce152406 160 char cmd = 0x80;
nxp_ip 0:77dbce152406 161 int i;
nxp_ip 0:77dbce152406 162 int j;
nxp_ip 0:77dbce152406 163
nxp_ip 0:77dbce152406 164 i2c.write( i2c_addr, &cmd, 1 );
nxp_ip 0:77dbce152406 165 i2c.read( i2c_addr, data, sizeof( data ) );
nxp_ip 0:77dbce152406 166
nxp_ip 0:77dbce152406 167 printf( "PCA9629 register dump\r\n" );
nxp_ip 0:77dbce152406 168
nxp_ip 0:77dbce152406 169 for ( i = 0, j = 0x14; i <= 0x12; i++, j++ )
nxp_ip 0:77dbce152406 170 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 171
nxp_ip 0:77dbce152406 172 printf( " %-13s (0x%02X): 0x%02X\r\n", reg_name[ 0x13 ], 0x13, data[ 0x13 ] );
nxp_ip 0:77dbce152406 173 }
nxp_ip 0:77dbce152406 174
nxp_ip 0:77dbce152406 175
nxp_ip 0:77dbce152406 176 void PCA9629::speed_change( unsigned short pw ) {
nxp_ip 0:77dbce152406 177 char cmd0[] = { PCA9629::MCNTL, 0x00}; // data for stop the motor
nxp_ip 0:77dbce152406 178 char cmd1[] = { PCA9629::CW__STEP_WIDTH, pw & 0xFF, pw >> 8 }; // data for rewrite pulse width
nxp_ip 0:77dbce152406 179 char cmd2[] = { PCA9629::MCNTL, 0xB4}; // start // data for start again
nxp_ip 0:77dbce152406 180 wait_us(10);
nxp_ip 0:77dbce152406 181
nxp_ip 0:77dbce152406 182 i2c.write( i2c_addr, cmd0, sizeof( cmd0 ), true ); // stop the motor
nxp_ip 0:77dbce152406 183 wait_us(50);
nxp_ip 0:77dbce152406 184 i2c.write( i2c_addr, cmd1, sizeof( cmd1 ), true ); // rewrite pulse width
nxp_ip 0:77dbce152406 185 i2c.write( i2c_addr, cmd2, sizeof( cmd2 ), false ); // start again
nxp_ip 0:77dbce152406 186 }
nxp_ip 0:77dbce152406 187
nxp_ip 0:77dbce152406 188
nxp_ip 0:77dbce152406 189