Fm+ I2C-bus advanced stepper motor controller

Dependencies:   mbed

PCA9629A.cpp

Committer:
wataaki
Date:
2015-02-04
Revision:
0:6607b5b5fd68

File content as of revision 0:6607b5b5fd68:

#include "mbed.h"
#include "PCA9629A.h"
 
I2C i2c(p28,p27);        // sda, scl
Serial pc(USBTX, USBRX); // tx, rx
char cmd[32];
int sw, swp;
long dum;
int i, j;
 
void set_ch(char sel)
{    // PCA9541のサンプル
        // MST_0側の自分にスレーブ側の制御権を得る場合
    cmd[0] = 1;                     // PCA9541 コマンドコード Cont Reg
    i2c.write( 0xe2, cmd, 1);       // Cont Regを指定
    i2c.read( 0xe2, cmd, 1);        // Cont Regを読込み
    wait(0.1);                      // 0.1s待つ
    switch(cmd[0] & 0xf)
    {
    case 0:                         // bus off, has control
    case 1:                         // bus off, no control
    case 5:                         // bus on, no control
        cmd[0] = 1;                 // PCA9541 コマンドコード Cont Reg
        cmd[1] = 4;                 // bus on, has control
        i2c.write( 0xe2, cmd, 2);   // Cont Regにcmd[1]を書込み
        i2c.read( 0xe2, cmd, 1);    // Cont Regを読込み
        break;
    case 2:                         // bus off, no control
    case 3:                         // bus off, has control
    case 6:                         // bus on, no control
        cmd[0] = 1;                 // PCA9541 コマンドコード Cont Reg
        cmd[1] = 5;                 // bus on, has control
        i2c.write( 0xe2, cmd, 2);   // Cont Regにcmd[1]を書込み
        i2c.read( 0xe2, cmd, 1);    // Cont Regを読込み
        break;
    case 9:                         // bus on, no control
    case 0xc:                       // bus on, no control
    case 0xd:                       // bus off, no control
        cmd[0] = 1;                 // PCA9541 コマンドコード Cont Reg
        cmd[1] = 0;                 // bus on, has control
        i2c.write( 0xe2, cmd, 2);   // Cont Regにcmd[1]を書込み
        i2c.read( 0xe2, cmd, 1);    // Cont Regを読込み
        break;
    case 0xa:                       // bus on, no control
    case 0xe:                       // bus off, no control
    case 0xf:                       // bus on, has control
        cmd[0] = 1;                 // PCA9541 コマンドコード Cont Reg
        cmd[1] = 1;                 // bus on, has control
        i2c.write( 0xe2, cmd, 2);   // Cont Regにcmd[1]を書込み
        i2c.read( 0xe2, cmd, 1);    // Cont Regを読込み
        break;
    default:
        break;
    }

    cmd[0] = sel;                   // PCA9546 Cont Reg sel channel enabled
    i2c.write( 0xe8, cmd, 1);       // Send command string
}

void wdt_rst(void)          // WDT
{
    cmd[0] = WDTOI;
    cmd[1] = 0x1;           // 1s
    i2c.write(PCA9629A_ADDR, cmd, 2);

    cmd[0] = WDCNTL;
    cmd[1] = 0x2 + 0x1;     // WDMOD = Reset & int WDEN = 1 
    i2c.write(PCA9629A_ADDR, cmd, 2);

    wait(1.1);
}

int main ()
{
    i2c.frequency(100000);
    pc.printf("PCA9629A Sample Program\r\n");
     
    set_ch(1);              // PCA9629Aはch0に接続
  // PCA9629A

    while(1)
    {
        wdt_rst();          // reset
        pc.printf("CW->CCW .. 1,  Ramp .. 2,  Phase .. 3 ? \r\n");
        pc.scanf("%d", &sw);
        switch (sw)
        {
        case 1:
            pc.printf("CW->CCW Sample Start\r\n");
  
            cmd[0] = MODE;
            cmd[1] = 0x0;           // Normal
            i2c.write(PCA9629A_ADDR, cmd, 2);

            cmd[0] = OP_CFG_PHS;
            cmd[1] = 0x10;          // 1Phase, OUT[3:0]
            i2c.write(PCA9629A_ADDR, cmd, 2);

            cmd[0] = CWPWL + 0x80;  // Auto Increment
            cmd[1] = 0x0;           // 24us * 4096 = 98.304ms 
            cmd[2] = (0x3 << 5) + 0x10;     // Prescaler = 3 
            i2c.write(PCA9629A_ADDR, cmd, 3);

            cmd[0] = CCWPWL + 0x80; // Auto Increment
            cmd[1] = 0x0;           // 24us * 2048 = 49.152ms 
            cmd[2] = (0x3 << 5) + 0x8;     // Prescaler = 3
            i2c.write(PCA9629A_ADDR, cmd, 3);

            cmd[0] = CWSCOUNTL + 0x80;  // Auto Increment
            cmd[1] = 0x00;          // 
            cmd[2] = 0x1;           // 256 steps
            i2c.write(PCA9629A_ADDR, cmd, 3);

            cmd[0] = CCWSCOUNTL + 0x80;
            cmd[1] = 0x80;          // 128 steps 
            cmd[2] = 0x0;           // 
            i2c.write(PCA9629A_ADDR, cmd, 3);

            cmd[0] = PMA;
            cmd[1] = 2;           // One time
            i2c.write(PCA9629A_ADDR, cmd, 2);

            cmd[0] = MCNTL;
            cmd[1] = 0x80 + 0x2;    // Start, CW->CCW 
            i2c.write(PCA9629A_ADDR, cmd, 2);   // cmd[0]Regにcmd[1]を書込み

            while(1)
            {
                wait(1);
                cmd[0] = 0x80 + STEPCOUNT0;
                i2c.write(PCA9629A_ADDR, cmd, 1, true);
                i2c.read(PCA9629A_ADDR, cmd, 4);    // STEPCOUNT 4byteを読込み
                dum = cmd[0] + (cmd[1] << 8) + (cmd[2] << 16) + (cmd[3] << 24);
                if (dum == 0) break;
            }        
            pc.printf("CW->CCW Sample End\r\n");
            break;
            
        case 2:
            pc.printf("Ramp Sample Start\r\n");

            cmd[0] = MODE;
            cmd[1] = 0x0;           // Normal
            i2c.write(PCA9629A_ADDR, cmd, 2);

            cmd[0] = OP_CFG_PHS;
            cmd[1] = 0x10;          // 1Phase, OUT[3:0]
            i2c.write(PCA9629A_ADDR, cmd, 2);

            cmd[0] = CWPWL + 0x80;  // Auto Increment
            cmd[1] = 0x0;           // 48us * 256 = 12.288ms 
            cmd[2] = (0x4 << 5) + 0x1;     // Prescaler = 4 
            i2c.write(PCA9629A_ADDR, cmd, 3);

            cmd[0] = CWSCOUNTL + 0x80;  // Auto Increment
            cmd[1] = 0x40;          // 
            cmd[2] = 0x1;           // 320 steps
            i2c.write(PCA9629A_ADDR, cmd, 3);

            cmd[0] = RUCNTL;
            cmd[1] = 0x37;           // 48us x 128 = 6.144ms
            i2c.write(PCA9629A_ADDR, cmd, 2);   //

            cmd[0] = RDCNTL;
            cmd[1] = 0x38;           // 48us x 256 = 12.288ms 
            i2c.write(PCA9629A_ADDR, cmd, 2);   //

            cmd[0] = PMA;
            cmd[1] = 2;           // One time
            i2c.write(PCA9629A_ADDR, cmd, 2);

            cmd[0] = MCNTL;
            cmd[1] = 0x80 + 0x0;    // Start, CW 
            i2c.write(PCA9629A_ADDR, cmd, 2);   // cmd[0]Regにcmd[1]を書込み

            while(1)
            {
                wait(1);
                cmd[0] = 0x80 + STEPCOUNT0;
                i2c.write(PCA9629A_ADDR, cmd, 1, true);
                i2c.read(PCA9629A_ADDR, cmd, 4);    // STEPCOUNT 4byteを読込み
                dum = cmd[0] + (cmd[1] << 8) + (cmd[2] << 16) + (cmd[3] << 24);
                if (dum == 0) break;
            }        
            pc.printf("Ramp Sample End\r\n");

            break;
           
        case 3:
            pc.printf("Phase Sample Start\r\n");
            pc.printf("1相 .. 1,  2相 .. 2,  1-2相 .. 3 ? \r\n");
            pc.scanf("%d", &swp);
  
            cmd[0] = MODE;
            cmd[1] = 0x0;           // Normal
            i2c.write(PCA9629A_ADDR, cmd, 2);

            cmd[0] = OP_CFG_PHS;
            cmd[1] = ((swp - 1) << 6) + 0x10;          // ?Phase, OUT[3:0]
            i2c.write(PCA9629A_ADDR, cmd, 2);

            cmd[0] = CWPWL + 0x80;  // Auto Increment
            cmd[1] = 0x0;           // 48us * 4096 = 196.6ms 
            cmd[2] = (0x4 << 5) + 0x10;     // Prescaler = 4 
            i2c.write(PCA9629A_ADDR, cmd, 3);

            cmd[0] = CWSCOUNTL + 0x80;  // Auto Increment
            cmd[1] = 0x40;          // 
            cmd[2] = 0x0;           // 256 steps
            i2c.write(PCA9629A_ADDR, cmd, 3);

            cmd[0] = PMA;
            cmd[1] = 2;           // One time
            i2c.write(PCA9629A_ADDR, cmd, 2);

            cmd[0] = MCNTL;
            cmd[1] = 0x80 + 0x0;    // Start, CW 
            i2c.write(PCA9629A_ADDR, cmd, 2);   // cmd[0]Regにcmd[1]を書込み

            while(1)
            {
                wait(1);
                cmd[0] = 0x80 + STEPCOUNT0;
                i2c.write(PCA9629A_ADDR, cmd, 1, true);
                i2c.read(PCA9629A_ADDR, cmd, 4);    // STEPCOUNT 4byteを読込み
                dum = cmd[0] + (cmd[1] << 8) + (cmd[2] << 16) + (cmd[3] << 24);
                if (dum == 0) break;
            }        
            pc.printf("Phase Sample End\r\n");
            break;
        default:
            break;
        }    
    }
}