PCA9629A component library

Dependents:   PCA9629A_Hello

Revision:
0:0c797805233b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PCA9629A.h	Fri Sep 12 08:10:19 2014 +0000
@@ -0,0 +1,340 @@
+/** A sample code for PCA9629A
+ *
+ *  @author  Akifumi (Tedd) OKANO, NXP Semiconductors
+ *  @version 1.1
+ *  @date    12-Sep-2012
+ *
+ *  revision history (PCA9629A)
+ *      version 0.1 (05-Jun-2013) : PCA9629"A" initial version
+ *      version 0.2 (05-Jun-2013) : register name fix, register description added
+ *      version 1.0 (23-Apr-2014) : unnecessary parameter for constructor has been removed
+ *      version 1.1 (12-Sep-2014) : constructor variation added. ramp parameter API added
+ *
+ *  Released under the Apache 2 license License
+ *
+ *  An operation sample of PCA9629A stepper motor controller.
+ *  The mbed accesses the PCA9629A registers through I2C.
+ *
+ *  About PCA9629A:
+ *    http://www.nxp.com/products/interface_and_connectivity/i2c/i2c_bus_controller_and_bridge_ics/PCA9629APW.html
+ */
+
+#ifndef     MBED_PCA9629A
+#define     MBED_PCA9629A
+
+#define     DEFAULT_PCA9629A_ADDR       0x42
+#define     I2C_SCL_FREQUENCY           (400 * 1000)    //  I2C SCL clock frequency (for when the cunstructor with pin names is used)
+#define     ALLCALL_ADDR                0xE0
+
+
+/** PCA9629A class
+ *
+ *  This is a driver code for the PCA9629A stepper motor controller.
+ *  This class provides interface for PCA9629A operation and accessing its registers.
+ *  Detail information is available on next URL.
+ *    http://www.nxp.com/products/interface_and_connectivity/i2c/i2c_bus_controller_and_bridge_ics/PCA9629APW.html
+ *
+ *  Example:
+ *  @code
+ * #include "mbed.h"
+ * #include "PCA9629A.h"
+ *
+ * PCA9629A motor( p28, p27, 0x42 );  //  SDA, SCL, I2C_address (option)
+ *
+ * int main() {
+ *
+ *     //  Speed setting 200pps for clockwise (CW) rotation
+ *     motor.pps( PCA9629A::CW, 200 );
+ *
+ *     //  Set 24 steps for CW
+ *     motor.steps( PCA9629A::CW, 24 );
+ *
+ *     //  Speed setting 100pps for counterclockwise (CCW) rotation
+ *     motor.pps( PCA9629A::CCW, 100 );
+ *
+ *     //  Set 48 steps for CCW
+ *     motor.steps( PCA9629A::CCW, 24 );
+ *
+ *     while ( 1 ) {
+ *         motor.start( PCA9629A::CW ); //  Motor start for CW
+ *         wait( 1.0 );
+ *
+ *         motor.start( PCA9629A::CCW ); //  Motor start for CCW
+ *         wait( 1.0 );
+ *     }
+ * }
+ *  @endcode
+ */
+
+
+class PCA9629A
+{
+public:
+    /** name of the PCA9629A registers */
+    typedef enum {
+        MODE,           /**< 0x00   Mode register                                           */
+        WDTOI,          /**< 0x01   WatchDog Time-Out Interval register                     */
+        WDCNTL,         /**< 0x02   WatchDog Control register                               */
+        IO_CFG,         /**< 0x03   I/O Configuration register                              */
+        INTMODE,        /**< 0x04   Interrupt Mode register                                 */
+        MSK,            /**< 0x05   Mask interrupt register                                 */
+        INTSTAT,        /**< 0x06   Interrupt Status register                               */
+        IP,             /**< 0x07   Input Port register                                     */
+        INT_MTR_ACT,    /**< 0x08   Interrupt motor action control register                 */
+        EXTRASTEPS0,    /**< 0x09   Extra steps count for INTP0 control register            */
+        EXTRASTEPS1,    /**< 0x0A   Extra steps count for INTP1 control register            */
+        OP_CFG_PHS,     /**< 0x0B   Output Port Configuration and Phase control register    */
+        OP_STAT_TO,     /**< 0x0C   Output state and time-out control register              */
+        RUCNTL,         /**< 0x0D   Ramp-up control register                                */
+        RDCNTL,         /**< 0x0E   Ramp-down control register                              */
+        PMA,            /**< 0x0F   Perform multiple of actions control register            */
+        LOOPDLY_CW,     /**< 0x10   Loop delay timer for CW to CCW control register         */
+        LOOPDLY_CCW,    /**< 0x11   Loop delay timer for CCW to CW control register         */
+        CWSCOUNTL,      /**< 0x12   Number of clockwise steps register (low byte)           */
+        CWSCOUNTH,      /**< 0x13   Number of clockwise steps register (high byte)          */
+        CCWSCOUNTL,     /**< 0x14   Number of counter-clockwise steps register (low byte)   */
+        CCWSCOUNTH,     /**< 0x15   Number of counter-clockwise steps register (high byte)  */
+        CWPWL,          /**< 0x16   Clockwise step pulse width register (low byte)          */
+        CWPWH,          /**< 0x17   Clockwise step pulse width register (high byte)         */
+        CCWPWL,         /**< 0x18   Counter-clockwise step pulse width register (low byte)  */
+        CCWPWH,         /**< 0x19   Counter-clockwise step pulse width register (high byte) */
+        MCNTL,          /**< 0x1A   Motor control register                                  */
+        SUBADR1,        /**< 0x1B   I2C-bus subaddress 1                                    */
+        SUBADR2,        /**< 0x1C   I2C-bus subaddress 2                                    */
+        SUBADR3,        /**< 0x1D   I2C-bus subaddress 3                                    */
+        ALLCALLADR,     /**< 0x1E   All Call I2C-bus address                                */
+        STEPCOUNT0,     /**< 0x1F   Step counter registers: STEPCOUNT0                      */
+        STEPCOUNT1,     /**< 0x20   Step counter registers: STEPCOUNT1                      */
+        STEPCOUNT2,     /**< 0x21   Step counter registers: STEPCOUNT2                      */
+        STEPCOUNT3      /**< 0x22   Step counter registers: STEPCOUNT3                      */
+    } RegisterName;
+
+private:
+    /* register names for 2 bytes accessing */
+    typedef enum {
+        CWPW_       = CWPWL      | 0x80,    /**< Step pulse width for CW rotation */
+        CCWPW_      = CCWPWL     | 0x80,    /**< Step pulse width for CCW rotation */
+        CWSCOUNT_   = CWSCOUNTL  | 0x80,    /**< Number of steps CW */
+        CCWSCOUNT_  = CCWSCOUNTL | 0x80,    /**< Number of steps CCW */
+
+    } _RegisterNameFor16bitAccess;
+
+public:
+    /** register names for 2 bytes accessing */
+    typedef enum {
+        CW__STEP_WIDTH      = CWPW_,
+        CCW_STEP_WIDTH      = CCWPW_,
+        CW__STEP_COUNT      = CWSCOUNT_,
+        CCW_STEP_COUNT      = CCWSCOUNT_,
+    } RegisterNameFor16bitAccess;
+
+    /** register names for 4 bytes accessing */
+    typedef enum {
+        STEPCOUNT           = STEPCOUNT0,
+    } RegisterNameFor32bitAccess;
+
+    /** keyword to select direction of rotation */
+    typedef enum {
+        CW      = 0,    /**< Clockwise direction */
+        CCW             /**< ConterClockwise direction */
+    } Direction;
+
+    /** Create a PCA9629A instance connected to specified I2C pins with specified address
+     *
+     * @param I2C_sda I2C-bus SDA pin
+     * @param I2C_scl I2C-bus SCL pin
+     * @param I2C_address I2C-bus address (default: 0x42)
+     */
+    PCA9629A(
+        PinName I2C_sda,
+        PinName I2C_scl,
+        char    I2C_address         = DEFAULT_PCA9629A_ADDR
+    );
+
+    /** Create a PCA9629A instance connected to specified I2C pins with specified address
+     *
+     * @param I2C object (instance)
+     * @param I2C_address I2C-bus address (default: 0x42)
+     */
+    PCA9629A(
+        I2C     &i2c_,
+        char    I2C_address         = DEFAULT_PCA9629A_ADDR
+    );
+
+    /** Destractor
+     *
+     *
+     *
+     */
+    ~PCA9629A();
+
+    /** Software reset
+     *
+     *  Performs software reset through I2C bus
+     */
+    void software_reset( void );
+
+    /** Initialize all registers
+     *
+     *  The initializing values are defined in the function
+     */
+    void init_registers( void );
+
+    /** Initialize all registers
+     *
+     *  The initializing values are defined in the function
+     */
+    void set_all_registers( char *a, char size );
+
+    /** Write 1 byte data into a register
+     *
+     *  Setting 8 bits data into a register
+     *
+     *  @param register_name the register name: data writing into
+     *  @param value 8 bits writing data
+     */
+    void write( RegisterName register_name, char value );
+
+    /** Write 2 bytes data into a register
+     *
+     *  Setting 16 bits data into registers
+     *
+     *  @param register_name the register name: data writing into (it can be "SROTN_", "CWPW_", "CCWPW_", "CWRCOUNT_", "CCWSCOUNT_", "CWRCOUNT_" or "CCWRCOUNT_" )
+     *  @param value 16 bits writing data
+     */
+    void write( RegisterNameFor16bitAccess register_name, short value );
+
+    /** Read 1 byte data from a register
+     *
+     *  Setting data into a register
+     *
+     *  @param register_name the register name: data reading from
+     *  @return read 8 bits data from the register
+     */
+    char read( RegisterName register_name );
+
+    /** Read 2 byte data from registers
+     *
+     *  Setting data into a register
+     *
+     *  @param register_name the register name: data writing into (it can be "SROTN_", "CWPW_", "CCWPW_", "CWRCOUNT_", "CCWSCOUNT_", "CWRCOUNT_" or "CCWRCOUNT_" )
+     *  @return read 16 bits data from the registers
+     */
+    short read( RegisterNameFor16bitAccess register_name );
+
+    /** Read 4 byte data from registers
+     *
+     *  Setting data into a register
+     *
+     *  @param register_name the register name: data writing into (it can be "STEPCOUNT")
+     *  @return read 32 bits data from the registers
+     */
+    long read( RegisterNameFor32bitAccess register_name );
+
+    /** Motor start
+     *
+     *  Start command
+     *  This function starts motor operation with hard-stop flag and rotation+step enabled, no repeat will be performed
+     *  If custom start is required, use "write( PCA9629A::MCNTL, 0xXX  )" to control each bits.
+     *
+     *  @param dir rotate direction ("CW" or "CCW")
+     */
+    void start( Direction dir );
+
+    /** Motor stop
+     *
+     *  Stop command
+     *
+     */
+    void stop( void );
+
+    /** Set PPS
+     *
+     *  Setting PulsePerSecond
+     *  This interface can be used to set CWPWx or CCWPWx registers
+     *
+     *  @param dir rotate direction ("CW" or "CCW")
+     *  @param pulse_per_second pps defineds pulse width for the motor. The pulse width will be 1/pps
+     *  @return 16 bit data that what set to the CWPWx or CCWPWx registers
+     */
+    short pps( Direction dir, float pulse_per_second );
+
+    /** Set steps count
+     *
+     *  Setting step count
+     *  This interfaces CWSCOUNTx and CCWSCOUNTx registers
+     *
+     *  @param dir rotate direction ("CW" or "CCW")
+     *  @param step_count sets number of steps with 16 bit value
+     */
+    void steps( Direction dir, int step_count );
+
+    /** Ramp-up rate
+     *
+     *  Setting ramp-up rate
+     *
+     *  @param rate set acceleration ratio. From 0 to 13. 0 for disable. Bigger valure accelerate faster.
+     */
+    void ramp_up( char rate );
+
+    /** Ramp-down rate
+     *
+     *  Setting ramp-down rate
+     *
+     *  @param rate set deceleration ratio. From 0 to 13. 0 for disable. Bigger valure decelerate faster.
+     */
+    void ramp_down( char rate );
+
+    /** Register dump
+     *
+     *  Dumping all register data to serial console
+     *
+     */
+    void register_dump( void );
+
+    /** Register dump
+     *
+     *  Dumping all register data to serial console
+     *
+     */
+    void speed_change( unsigned short pw );
+
+    /** Register dump
+     *
+     *  Dumping all register data to serial console
+     *
+     */
+    void calibration( float coefficient );
+
+
+private:
+    /* plescaler range setting */
+    typedef enum {
+        PRESCALER_FROM_40_TO_333333,    /*< Prescaler range from   3us(333333pps) to   24.576ms(40   pps) */
+        PRESCALER_FROM_20_TO_166667,    /*< Prescaler range from   6us(166667pps) to   49.152ms(20   pps) */
+        PRESCALER_FROM_10_TO_83333,     /*< Prescaler range from  12us( 83333pps) to   98.304ms(10   pps) */
+        PRESCALER_FROM_5_TO_41667,      /*< Prescaler range from  24us( 41667pps) to  196.608ms( 5   pps) */
+        PRESCALER_FROM_2_5_TO_20833,    /*< Prescaler range from  48us( 20833pps) to  393.216ms( 2.5 pps) */
+        PRESCALER_FROM_1_27_TO_10416,   /*< Prescaler range from  96us( 10416pps) to  786.432ms( 1.27pps) */
+        PRESCALER_FROM_0_64_TO_5208,    /*< Prescaler range from 192us(  5208pps) to 1572.864ms( 0.64pps) */
+        PRESCALER_FROM_0_32_TO_2604,    /*< Prescaler range from 384us(  2604pps) to 3145.728ms( 0.32pps) */
+    } PrescalerRange;
+
+    /* Set PPS
+     *
+     *  Setting PulsePerSecond
+     *  This interface can be used to set CWPWx or CCWPWx registers
+     *
+     *  @param dir rotate direction ("CW" or "CCW")
+     *  @param prescaler prescaler setting (for 3 bits setting range from 0 to 0x7. See datasheet)
+     *  @param pulse_per_second pps defineds pulse width for the motor. The pulse width will be 1/pps
+     *  @return 16 bit data that what set to the CWPWx or CCWPWx registers
+     */
+    short pps( Direction dir, PrescalerRange prescaler, int pulse_per_second );
+
+    I2C     *i2c_p;
+    I2C     &i2c;
+    char    i2c_addr;
+};
+
+#endif  //  MBED_PCA9629A