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 04:03:34 2012 +0000
Revision:
4:9a80b6d63005
Child:
5:aff87a1c8bd6

        

Who changed what in which revision?

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