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:
Fri Feb 03 03:44:06 2012 +0000
Revision:
2:2d07f1c46eb3
Parent:
0:77dbce152406

        

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 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